A deep dive into git

Faruk CEBECI

Before git

What is git?

  • git is a version control system.
  • 😄

What is version?

According to Cambridge Dictionary, version is:

a particular form of something that is slightly different from other forms of the same thing

What is version control system?

Version control system is a system that keeps track of different versions of something.

  • git
  • svn
  • mercurial

Tracking changes

  • The main idea of version control systems is tracking changes.
  • A repository is a place where we store our changes.
  • Each set of changes is called a commit in git.
  • git stores all the data in a directory called .git.

Creating a repository

We can create an empty repository with the following commands:

$ mkdir repo
$ cd repo
$ git init

We can check the status of the repository with the following command:

$ git status

Working directory

  • Working directory is the directory where we make changes.
  • .git directory is not a part of the working directory.
  • We can see the changes we made with the following command:
$ git diff

Making changes on the repository

We can make changes on the repository with the following commands:

$ echo "Hello world" > hello.txt
$ git status

In order to specify the changes we made, we use the staging area.

Staging area

  • Staging area is a place where we specify the changes we made.
  • We can add files to the staging area with the following command:
$ git add hello.txt
  • We can remove files from the staging area with the following command:
$ git reset hello.txt

Commits

  • Commits are the changes we made on the repository.
  • We can create a commit with the following command:
$ git commit -m "Add hello.txt"
  • We need to specify a message for each commit with the -m option.
  • We can see the commits with the following command:
$ git log

Remote repositories

  • Remote repositories are the repositories that are not on our local machine.
  • We can add a remote repository with the following command:
$ git remote add origin <url>
  • We can push our commits to the remote repository with the following command:
$ git push -u origin master

Pulling changes

We can pull the commits from the remote repository with the following command:

$ git pull origin master
# or
$ git fetch origin master

Commit History

  • Each commit has a unique id.
  • Each commit has a parent commit. Parent commit is the commit that the current commit is based on.

Branches

  • Branches are the different versions of the repository.
  • A branch is a pointer to a commit.
  • We can create a branch with the following command:
$ git branch <branch-name>

Switching branches

  • We can switch to a branch with the following command:
$ git checkout <branch-name>
# or
$ git switch <branch-name>
  • We can create a branch and switch to it with the following command:
$ git checkout -b <branch-name>

HEAD

  • HEAD is a pointer to the current branch.
  • Branch is a pointer to a commit.
  • Therefore, it is a pointer to a pointer. 😮

Merging

Rebasing

Cherry-picking

Stashing

How git stores data?

  • Git store all of its data in a directory called .git.

Best practices

.git directory

.git
├── COMMIT_EDITMSG                    The commit message in raw format
├── HEAD                              HEAD points to the current branch (ref: refs/heads/master)
├── config                            git configs specific to this repository
├── description                       Description of the project
├── hooks                             Scripts that are run before or after certain git commands
│   └── ...shell scripts...
├── index                             The staging area
├── info                              Auxiliary files
│   └── exclude                       Exclude patterns (.gitignore)
├── objects                           All the objects in a compressed format (with their hashes as filenames)
│   ├── info                          Stores
│   ├── pack                          All the objects in a compressed format
│   └── 00                            All the objects whose hash starts with 00
│       └── ...rest of the hash...    Object file (compressed)
└── refs                              References to commits. They are pointers. (branches, tags, etc.)
    ├── heads                         Last commit's hash for each branch
    ├── tags                          Commit hashes for each tag
    ├── stash                         Stash commits
    └── remotes                       Last commit's hash for each remote branch
  • New commit will get its parent from current HEAD.