Git

Table of Contents

Version control system that tracks every change in a repository (a directory with .git in it).

Git was initially created by Linus Benedict Torvalds to manage the Linux kernel.

1. Nomenclature

1.1. Working Tree

  • Or worktree
  • The entire file including the files under the .git/, which means all its history and current state.

2. Subcommands

2.1. clone

--depth DEPTH clone the number of recent commits specified.

2.2. status

  • Show status.

2.3. log

  • It shows commits reachable from HEAD, which means past commits.
  • log [([^]<ref>)*] To control the scope, one can specify which commit to start logging.
    • <ref>=(HEAD|<hash>|<tag>|<branch>)(^N|~N)* where ^N means N=th parent when current commit is a merge of multiple commits, and =~N means N parents back.
  • --graph: Show graph
  • --oneline: One line per commit
  • --decorate:

2.4. add

  • Stage diffs so that it can be readily committed. Add path at the end
  • -p --patch: Add /hunks/(blocks of changes) individually.

Use reset <file> or restore --staged <file> to undo.

2.5. checkout

  • Move HEAD.
$ git checkout <hash|name>

            HEAD
             v
        <branchname>
             v
---O----O----O

======V======

  HEAD   <branchname>
   v         v
---O----O----O

2.6. switch

  • Switch branch.

2.7. commit

  • Add commit, move branch reference and HEAD.
  • -a to add the changes of the tracked files before commiting.
  • -C or -c=(edit the message) to use the existing commit object, probably there because of =git reset.
  • --amend to replace the tip of the commit with a new one, effectively amending it.
    • --no-edit to keep the commit message.
  • --fixup, --squash: Marks the commit that it is to be squashed when git rebase --autosquash
$ git commit

    <branchname> <- HEAD
        v
---O----O

======V======

        <branchname> <- HEAD
             v
---O----O----O

2.8. tag

  • Tag is a immovable identifier.
$ git tag <tagname>

        <branchname>
             v
---O----O----O
    ^
HEAD

======V======

        <branchname>
             v
---O----O----O
   ^
<tagname> <- HEAD

2.9. branch

  • Branch is a identifier that moves along as one commits.
$ git branch <branchname>

     <main>
        v
---O----O
   ^
  HEAD

======V======

     <main>
        v
---O----O
   ^
<branchname> <- HEAD

2.10. merge

  • Git does three-way merging which analyzes base, local, remote and produces best result.
$ git merge <feature>

    <main> <- HEAD
        v
---O----O
    \---O
        ^
    <feature>

======V======

          <main> <- HEAD
             v
---O----O----O
    \---O---/
        ^
    <feature>
  • --squash
    • Change current working tree into the merged state, but not committed. Therefore, git commit is required.
    • This enables creating a single commit with single parent.

2.11. fetch

  • Local branch is created when one checkout the remote branch, and the local branch has an upstream pointer that is connected to the remote branch.
$ git fetch <remote/origin/main>

      HEAD
        v
    <main> ~> <remote/origin/main>
        |_______/
        v
---O----O

======V======

      HEAD
        v
    <main> ~> <remote/origin/main>
        |         |
        v         v
---O----O----O----O

2.12. pull

  • Merge local and remote branch.
$ git pull <remote/origin/main>

      HEAD
        v
    <main> ~> <remote/origin/main>
        |         |
        v         v
---O----O----O----O

======V======

      HEAD
        v
    <main> ~> <remote/origin/main>
        \_________|
                  v
---O----O----O----O

2.13. push

  • Checks if any divergence happened and if it did git refuses to push. To resolve this one needs to merge the remote branch.
  • --force-with-lease: Only force push if the remote is the same as the local.

2.14. diff

  • Changes of working tree (the current state) from the HEAD, Or diff X Y for diff between X and Y.
  • git diff <ref> [<ref>=HEAD] > <patchfile> stores the diff that can be applied by git apply <patchfile>.

2.15. reset

  • Uncommit or Unstage or hard reset.
  • --soft: only moves the HEAD, --hard: moves the HEAD and reset the index and working tree.
  • The current HEAD gets stored to ORIG_HEAD.

2.16. restore

  • Restore files to a specific state. Add path at the end. It does not affect the index unless --staged
  • -s <tree> --source=<tree>: Specify commit, branch to restore from. Restore from index if unspecified.
  • --staged: Unstage

2.17. revert

  • Commit the inverse of previous commits.

2.18. cherry-pick

  • Commit just one commit within other branch onto the current branch.

2.19. rebase

  • Commit current branch on top of another branch.
  • git rebase -i <ref>: Perform rebase on <ref>. This means the commits after <ref> will be available for rebasing.
    • fixup: append to the previous commit.
    • squash: append the previous commit to itself.
    • reword: change the commit message.
    • edit: perform git commit --amend on the commit.

2.20. reflog

It tracks every single move of HEAD pointer, even hard reset and branch deletion.

git reset --hard can reset to one of the reference point.

2.21. stash

  • Temporarily stores diffs in a separate area.
  • Name of stash looks like stash@{n} which can be referenced by only the n. The latest stash is 0.
  • git stash push
    • -k --keep-index: Stash only the changes.
    • -S --staged: Stash only the index.
  • git stash pop: Apply the stash and drop it. They must match the index.
  • git stash list, git stash drop <stash>

2.22. notes

  • Add notes to commits. It does not affect the commit at all.

2.23. worktree

  • add <path> <commit-ish>: copy the entire repository into the <path> (except the per-worktree files, like HEAD, index, …) and link it to the current one. It is a linked worktree.

2.24. submodule

  • If a git repository is inside a git repository, then the outer repository only tracks the HEAD of the inner repository.

2.25. bisect

  • Track down a bug by bisecting the commits.

2.26. instaweb

  • Open a GUI in the browser

2.27. gc

  • Garbage collection for tidying up the git files.

2.28. blame

  • See who wrote certain code

2.29. clean

  • Remove unnecessary files.

2.30. maintenance

  • start

2.31. =format-patch

3. Configuration

Global configuration is in ~/.gitconfig or $XDG_CONFIG_HOME/git/config. The latter is only used when .gitconfig does not exist and git/config does.

Local configuration is in .git/config within the repository. It will shadow the global one.

Set configuration by git config <options> <section>.<key> <value>.

  • Use --global option for the global configurations.

3.1. Structure

  • user
    • name
    • email
  • credential
    • helper: store and cache is provided by default.
  • alias
    • Short string to be used as a subcommand.
  • {{video https://youtu.be/aolI_Rz0ZqY?si=ZFHkS8qCT6Uh5GrA}}
  • gpg
    • Sign your commit
  • maintenance
    • Automatically maintain your repository

3.2. gitignore

$XDG_CONFIG_HOME/git/ignore, $GIT_DIR/info/exclude, .gitignore are searched for the files to ignore.

Each line is a pattern for the files.

  • ! prefix: negate the pattern
  • / suffix: match directory only
  • *, ?, ** wildcards
  • # prefix: comment

4. Hook

  • Within the .git/hooks

5. Credential

Configured in the [credential] section.

There are helpers that fills the password automatically. Set helper to one of the following.

6. Under the Hood

6.1. Objects

  • git cat-file to inspect objects
  • Every object is hashed and stored in the same way within the .git/objects/ directory.
  • They are referenced by their hash.
  • Commit
    • Contains the reference to the root tree.
  • Tree
    • Correspond to the directory in the file structure.
    • Contains the reference to trees and blobs within the directory.
  • Blob
    • Correspond to a file.

7. Reference

Author: Jeemin Kim

Created: 2026-07-12 Sun 14:28