Making sense of Git and GitHub - I [Central vs. Distributed VCS, Git-GitHub, Working-Staging-Repo]

Why do we need Git?

Without Git, modern software development is not possible. Believe this is not an understatement. Today software development has many collaborators and teams, and they work on single source code because software should have a single source code to function and can't have multiple source codes. But we can't build massive software without a single developer, and we need more developers to support us.


The problem is how we maintain a single source if we have multiple collaborators.

We need something at the center to convert multiple to single sources. This is called a Centralized system.

  • All developers must access this centralized.

  • All developers can make changes to the code in the system.

  • At any point, it should give the software a single source of truth.

Let's create scenarios:

Assume Developer A is a team lead, and he first places the code in a centralized system. The remaining developers take the code from this centralized system that has the first code updated by the team lead.

In the git arena,

This centralized system = Repository.

Taking the code from the repository and apply to your code = Updating.

You were applying changes you made in the code and sending your code to the repository = Committing.

Coming back to the scenarios, say Developer C makes some changes in the code and commits the changes to the repository.

Now the repository contains a different code than the first commit by Developer A(Team lead). An additional code than the first commit

Also, note rest of the developers are still working on old code because they didn't update the changes from the repository.


If Developer B wants to commit the changes he made to the repository, what would happen?

Developer B's local code made changes, and the repository's new code, which was updated by Developer C, is different.

An Update must precede any Commit.

All commits are stored in a central repository, and it will always point to the latest commit. Every commit(changes to the code) creates a new version of the code. This is called the Versioning system.

When you follow the above type of versioning in the repository, it is called a Centralized Version Control System(CVCS).


Git is not a Centralized Version Control System(CVCS)!

We create a single central repository to create a single source for the end software.

Therefore who controls the version here? It is the central repository. What if a newbie, say, Developer D, changes a code and commits the change to the central repository.? Any senior developers like B and C need to update the code from developer D before committing their changes to the repository.


What if the Developer D code has some bugs?

What if Developer D accidentally deleted the critical variables in the code?

We can ask many questions like this because we lack a review process before committing the code to the central repository.


We need a version control system, and also we need to make sure only quality code reaches the repository. We need to ensure all developers can change the code.

This results in Distributed Version Control System(DVCS).


Git is a Distributed Version Control System(DVCS).

Let us change CVCS to DVCS.

Observe version control is changing from central to distributed here.


Here version control of the code is distributed to the local repository first, and the final version in the remote repository(central). Local repo is in the local machine of developers.

Now it's time to unveil Git and GitHub.

So,

Git = Local repo on your machine.
GitHub = Repo hosting service on the cloud.
Zoom in to the Local Repo part(Git)!

Remember the newbie(Developer D) and changes to the code are not reviewed by any senior developer before committing to the central repo. How does the problem is solved by Git?


Git creates a layer between your folder and the local repo.

Whatever folder git is initialized, that folder is called the working directory(Directory = Folder).


How to initialize git in your folder?

Type 'git init' from your terminal, where the directory points to the intended folder. (Assuming you have some basic knowledge of using terminals)


When you initialize git from any directory, you will get a .git folder in the same directory.


Before committing any changes to the git repo on your local machine, you have a chance to review it in the staging area.


We will illustrate further,

When you give git status at first, i.e., no add and commits done before.

You get,

on branch master  --> Main branch is master 

No commits yet --> We don't do any commits yet
Untracked files:
(use "git add <file>..." to include what will be committed)

Index.html

Nothing was added to the commit, but untracked files are present (use "git add" to track)

Since Index.html is not tracked by the version control system(Git), it will be under Untracked files.


Let's add the file,

Let's give git status now,

on branch master  --> Main branch is master 

No commits yet --> We don't do any commits yet.

Changes to be committed:
 (use "git rm --cached <file>..." to unstage)
 
 Index.html
 
 

Now the Index.html comes under Changes to be committed.

We will commit the file now,

When we commit, we should always include a message.

The command and flag are git commit -m "Index.html is committed" where -m is the flag followed by the commit message in double quotes.



Note: This post is not about how the '.git' folder(local repo) saves the files internally because that is another topic.


[master (root-commit) 069667a] Index.html is committed --> Ensures file is committed to a local repo

 1 file changed, 5 insertions(+) --> 1 file changed(Index.html), and I've added 5 lines there and hence 5 insertions
 
 create mode 100644 Index.html
 

Let us modify the Index.html,

Remember!

Index.html is already committed (i.e., it is in the local repo, and hence it is tracked by the local repo).


We will give git status now.


On branch master

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   Index.html 

no changes added to commit (use "git add" and/or "git commit -a")

Observe here,

"Changes not staged for commit" is displayed because git already tracks Index.html. Now you change some contents in the file in the working directory and are not moved to the index/staging area; hence, it says changes are unstaged.


We will add these changes now.

git add Index.html



Giving git status,

On branch master

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   Index.html

Observe,

"Changes not staged for commit."

are converted into

"Changes to be committed."

Let us commit now with a message

git commit -m "Index.html is changed, and I want to commit it in the local repo(git)."



Now give git status,

[master e3935b4] Index.html is changed, and I want to commit it in the local repo(git)
 1 file changed, 3 insertions(+)

Recapping as a whole:

git init --> Initializes git repository


Three stages,

Working directory ---> Staging Area --> Local Repo(git)

When nothing is placed in staged and the local repo, no file is tracked by git. Therefore we get,

"Untracked files" in the git status,

"Untracked file" = the Corresponding file is not tracked by git.

When you add a particular file in staging are/Index area, we get,

"Changes to be committed" in the git status.


"Changes to be committed" = the corresponding file is in the staging area/index but not in the local repo.

When you change the file that is already committed in the local repo, we get,

"Changes not staged for commit" in the git status.


"Changes not staged for commit" = the corresponding file is already in the git repo, but now it has some changes in the working directory, and the related changes are not added to the staging area.

When you add changed files to the staging area/index, we get,

"Changes to be committed" in the git status.

So, "Changes to be committed" = Changed file is in the staged area but not committed to local repo.