Git
Difference between ^ and ~
commit^n choose the nth parent of the commit. HEAD^ is equivalent to HEAD^1, HEAD~, HEAD~1.
G H I J
\ / \ /
D E F
\ | / \
\ | / |
\|/ |
B C
\ /
\ /
A
A = = A^0
B = A^ = A^1 = A~1
C = A^2
D = A^^ = A^1^1 = A~2
E = B^2 = A^^2
F = B^3 = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2 = B^^2 = A^^^2 = A~2^2
I = F^ = B^3^ = A^^3^
J = F^2 = B^3^2 = A^^3^2
Clone
Clone a repository with its submodules:
$ git clone --recurse-submodules git@domain.tld:repo.git`
Add & Move & Remove
Add file in a interactive patch way
$ git add -p/--patch <file>
- Move (Rename) file and stage:
git mv <filename1> <filename2>; - Remove file:
git rm <file>; - Remove file in index only:
git rm --cached <file>.
Commit
- Automatically stage changes, add sign-off, GPG-sign the commit:
git commit -asS - Fast modify last commit:
git commit --amend
Log
- Show log in a friendly format:
$ git -P log --pretty='format:%C(auto)%G?%d %h %an %ar %s' --graph --all` - Show commits with diff patch (
-p,-u,--patch;--ccdense):$ git log -cc # Or $ git log --cc -1 # Shows for HEAD only - Show commits for a user (
--author=/--committer=):$ git log --author=<pattern> - Grep in commit logs:
$ git log --grep=<pattern> Show discarded commits:
$ git log --reflog--author=<pattern>,--committer=<pattern>-p,-u,--patchGenerate patch--ccProduce dense combined diff output for merge commits. Shortcut for--diff-merges=dense-combined -p.--reflogPretend as if all objects mentioned by reflogs are listed on the command line as<commit>.
The
reflog(reference log) is your local repository's private diary. It records a breadcrumb trail of every commit yourHEADor branches have pointed to recently, even if you abandoned them. Every time you commit, reset, rebase, or merge, the reflog jots down the commit hash.
Diff
- Show a summary:
git -P diff --stat - Show diff of the last commit:
$ git -P diff HEAD HEAD~1
Blame
Show modification information on each line with last commit hash and author:
$ git blame --color-by-age --color-lines <file>
Stash
git stash, git stash pop
Branch & Remove
- Create a branch and inherit its upstream:
$ git branch <old-branch> <new-branch>-t,--trackInherit "upstream" tracking for the new branch. - Delete a branch:
$ git branch -d/--delete <branch> - Delete a remote branch:
$ git push <remote> -d/--delete <branch> # Or $ git push <remote> :<branch> - Rename a branch:
$ git branch -m/--move <old-branch> <new-branch> - To rename a remote branch, first delete the remote branch, then push a branch with new name:
$ git push <remote> :<old-branch> $ git push <remote> <new-branch> - Add remote and track:
$ git remote add -t/--track <remote-branch> <remote-name> <url>
Tag
- Tag current HEAD:
git tag <tag-name> - Push tags (under
refs/tags):git push --tags
Rebase
Modify last 10 commits: git rebase -i HEAD~10
Operations:
pickDoesn't change this commitdropDrop this commiteditEdit this commitsquashMerge this commit with one commit above
Reset & Clean
Reset work tree and delete untracked files: git reset --hard HEAD && git clean -fdx
Reset options explanation:
--softOnly change pointerHEADto<commit>;--mixedReset index only;--hardReset both index and working tree;--keepReset working tree only (If a file differs between<commit>andHEAD, and also has modified copy in index, this reset will be aborted)
Clean options explanation:
-f,--forceAllowgit-cleanto delete files or directories.-dNormally, when no<path>is set,git cleanwill not recurse into untracked directories to removing too much. Specify-dto have it recurse into such directories as well.-xRemove ignored files and directories mentioned in.gitignore.
Restore
Restore a file from specify commit: git restore -s <commit> <file>
Options explanation:
-s <tree>,--source=<tree>Restore the working tree files with the content from the given tree.
Rvert
Create a revert commit (Useful when in a team): git revert <commit>
Submodule
- Show submodule status:
git submodule status - Add a submodule:
$ git submodule add -b <remote-branch> [--name <name>] <url> - Initialize and pin the submodule to a specific commit of super project:
$ git submodule update --init # or $ git submodule init && git submodule update - Update submodule to its remote-tracking branch:
$ git submodule update --remote <submodule-name> - Specify how differences the submodule are shown when using
git diff:$ git diff --submodule=[diff|log|short] - Only Push when submodules' commits are available on remote-tracking branch:
$ git push --recurse-submodules=check - Also Push submodules' commits:
$ git push --recurse-submodules=on-demand` - Run command on each submodule:
$ git submodule foreach <command>
Better Submodule for Git
Use git-subrepo, then simply run git subrepo as prefix each time.
git-subrepo could convert a subdirectory into a sub repo as well
$ git subrepo init <subdir> [-r <remote>] [-b <branch>] [--method <merge|rebase>]
Git Cherry-pick
git-cherry-pick are used to apply a commit in another branch into current branch.
Assume that the branch dev has a commit 38361a68:
$ git checkout master
$ git cherry-pick 38361a68
Git Format-patch
- Create patch files between two commit
$ git format-patch <r1>..<r2> - Single commit patch
$ git format-patch -1 <r1> - Create patch file since commit r1 (Not inclusive)
$ git format-patch <r1> - Apply a series of patches
$ git am *.patch
Limit the Memory Usage of git-gc
$ git config --global pack.windowMemory "100m"
$ git config --global pack.packSizeLimit "100m"
$ git config --global pack.threads "1"