Git
Table of Contents
- 1. Nomenclature
- 2. Subcommands
- 2.1.
clone - 2.2.
status - 2.3.
log - 2.4.
add - 2.5.
checkout - 2.6.
switch - 2.7.
commit - 2.8.
tag - 2.9.
branch - 2.10.
merge - 2.11.
fetch - 2.12.
pull - 2.13.
push - 2.14.
diff - 2.15.
reset - 2.16.
restore - 2.17.
revert - 2.18.
cherry-pick - 2.19.
rebase - 2.20.
reflog - 2.21.
stash - 2.22.
notes - 2.23.
worktree - 2.24.
submodule - 2.25.
bisect - 2.26.
instaweb - 2.27.
gc - 2.28.
blame - 2.29.
clean - 2.30.
maintenance - 2.31. =format-patch
- 2.1.
- 3. Configuration
- 4. Hook
- 5. Credential
- 6. Under the Hood
- 7. Reference
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^NmeansN=th parent when current commit is a merge of multiple commits, and =~NmeansNparents 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. -ato add the changes of the tracked files before commiting.-Cor-c=(edit the message) to use the existing commit object, probably there because of =git reset.--amendto replace the tip of the commit with a new one, effectively amending it.--no-editto keep the commit message.
--fixup,--squash: Marks the commit that it is to be squashed whengit 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 commitis required. - This enables creating a single commit with single parent.
- Change current working tree into the merged state, but not
committed. Therefore,
2.11. fetch
- Local branch is created when one
checkoutthe 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, Ordiff X Yfor diff betweenXandY. git diff <ref> [<ref>=HEAD] > <patchfile>stores the diff that can be applied bygit apply <patchfile>.
2.15. reset
- Uncommit or Unstage or hard reset.
--soft: only moves theHEAD,--hard: moves theHEADand reset the index and working tree.- The current
HEADgets stored toORIG_HEAD.
2.16. restore
- Restore files to a specific state. Add path at the end. It does
not affect the
indexunless--staged -s <tree>--source=<tree>: Specify commit, branch to restore from. Restore fromindexif 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: performgit commit --amendon 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 then. The latest stash is0. 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, likeHEAD,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
HEADof 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
--globaloption for the global configurations.
3.1. Structure
usernameemail
credentialhelper:storeandcacheis 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.
cachecache to the memory once enteredstorestore to the disk (in~/.git-credentialor$XDG_CONFIG_HOME/git/credentialsby default) once password is enterednetrcUse netrc file. It is not maintained and does not work.- https://git-scm.com/docs/gitcredentials
- https://git-scm.com/docs/git-credential-store
- https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage
6. Under the Hood
- https://youtu.be/reacnJArQXc?si=YdDC5LmtrIlhJZlh
git addcreates the blob objects for the changed files.git commitcreates the commit object, and the tree objects that are affected.
6.1. Objects
git cat-fileto 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.