https://git-scm.com/book/en/v2
UPD 2021-01-29: I recently messed up local master branch at work. Not sure what happened but it was just not the same any more as remote one in GitHub. No matter what I did, some commits were kept applying to master thay should not have. Doing git plumbing is just a waste of time. Guess what, I deleted whole local repo and cloned again. And this is after I read whole book about Git. Guess that tells something about this complex monstrosity.
Basics
modified
, staged
, committed
git config --local
to use .git/config
git config --list
git config --show-origin ....
to show where config value is definedgit status -s
for short status.gitignore
uses Glob patterns = simplified Regex.gitignore
use !
to negate pattern.gitignore
use /**/
to match nested directories.gitignore
official examples https://github.com/github/gitignoregit diff --staged
for what has been stagedgit rm --staged
to keep file but remove staged changesgit log --pretty=oneline
git log --pretty=format:"%h - %an, %ar : %s"
git log --graph
to also add graphgit log --since=2.weeks
to select timegit log -S function_name
known as “pickaxe” option, which shows commits that changed that string, useful for functions, argsgit log -- path/to/file
for changes to file or dirgit log --no-merges
to hide merges, useful if there are a lot of themgit log --decorate
to show where branch pointers are pointinggit commit --amend
to update last commit. it pushes away old commit as if it did not exist with a new one. old one will not show up in history.git checkout - <file>
will reset file with version from latest commitgit restore --staged <file>
to un-stage filegit restore <file>
to discard last changesgit remote -v
list remotes with URLgit remote add <name> <URL>
to add remotegit fetch <name>
to load all info from remote, it does not automatically mergegit remote show <name>
to show details on remotegit tag
list all tagsannotated
=”objects in git database, have message, can be signed and verified” or lightweight
=”pointer to specific commit”git tag -a v1.0 -m "my message"
to create annotated taggit show v1.0
to print details on taggit push origin --tags
to push all tags at oncegit push origin --delete <tagname>
to delete tag in remoteDETACHED HEAD
means that if you make commit then it will not belong to any branch or have any parent, it will be reachable only by commit hashgit config --global alias.visual '!gitk'
to invoke shell command from alias use !
git diff --check
show whitespaces in diffBranching
HEAD
= special pointer to where you are right nowgit switch <branch-name>
to checkout to other branch, new “checkout”git switch -c <branch-name>
to create a new branch, new “checkout”git merge <branch-name>
merge other branch into current one, make a merge commitgit branch -vv
list branchesgit branch --merged
list branches merged into current branchgit push origin --delete master
rebel!origin
is not special. just like master
it can be renamed.merge
and rebase
git rebase master
makes an ancestor branch you rebase onto, getting diff of each commit introduced by current branch, and applying it to new branch, moving current branch to last new commit. rebasing makes clean history as if all changes happened sequentially. better not use them it makes collaboration harder for merges.Server
git pull /home/john/project
or git remote add local_proj /srv/git/project.git
post-update
hook. Typically in read only mode.git init --bare --shared
to create serversudo chsh git -s $(which git-shell)
no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty
in authorized_keys
git://
with git daemon --reuseaddr --base-path=/srv/git/ /srv/git/
use systemd
for thisgit instaweb --http=webrick
for simple http frontendDistributed Workflows
git request-pull
to make pull request via fork in GitHub stylegit merge --squash
makes one commit with changesets from all commitsgit format-patch -M origin/master
to make email version of commit, some teams use that.gitconfig
for IMAP for email commitsgit apply <path-to-path.path>
to apply patch sent say over email. for patches made with diff. legacygit am
to apply from format-patch. recommended.git diff master...contrib
show only work introduced since common ancestorgit cherry-pick <hash>
to rebase single commit (apply patch from it with a new commit)git rerere
= “reuse recorded resolution” is a cache of resolutions of conflicts to reuse them and not bother user each timegit describe master
to show human readable commit versiongit archive master --prefix='project/' | gzip > $(git describe master).tar.gz
GitHub
curl ..../1.patch | git am
git ls-remote https://github.com/nikolaydubina/go-featurprocessing
to show list of pull requests with refs. But since PR are not in /head they are not pulled as normal branches..gitconfig
to fetch all pull requests on fetch
Git Tools
git log --abbrev-commit
short SHAgit reflog
git log master..experiment
what is in experiment starting from ancestor with mastergit log master...experiment
what is reachable by both commits but not both of themgit log --left-right master...experiment
for nice formatgit add -i
for interactive modegit stash
for saving staged changesgit stash -u
for stashing untracked files toogit stash -a
for stashing ignored files toogit stash branch <name>
to make a branch from stash instead of apply right away. useful if can not apply.git rebase -i HEAD~3
change history of commitsgit filter-branch -all --tree-filter 'rm -f passwords.txt' HEAD
to remove secrets file from whole historyHEAD
last commitIndex
staging changesworking directory
everythinggit reset
changes: 1) HEAD, branch to point to new hash; 2) index to pointed hash; 3) working directory to hashgit revert -m 1 HEAD
create a new commit that undoes changes from old commitgit blame -C -L 69,82 Makefile
to show how edited last lines from to in file. ^
means that it was unmodified since the beginning. -C
shows which files it come from.git bisect start
git bisect bad
git bisect good v1.0
to run bisect.git bisect run test-error.sh
if your script exists with 0 for good and non-0 for bad state. this will fully automate bisect. can be used with make tests
for example.git bundle create <bundlename> HEAD master
to make archive to create whole branch, then git clone <bundlename>
or git fetch <bundlename> master:other-master
git replace
to make some commits pretend to be other commits, useful for history rewritesSubmodules
git submodule add https://github.com/linux/linux
git clone --resource-submodules https://...
for cloning with submodulesgit pull
+ git submodule update --init --recursive
to update all submodulesgit submodule foreach 'shell here'
to run any shell on each submoduleCredential Storage
git config --global credential.helper cache
Config
help.autocorrect=1
autocorrect.gitattributes
can set which program to run on each file format for diffsHooks
Other
Internals
git hash-object
echo 'test content' | git hash-object -w --stdin
to storegit cat-file -p <SHA-1>
git cat-file -p master^{tree}
list files in commitgit gc
Data Recovery
git reflog
to list SHA-1 of commitsgit log -g
samegit branch recover-branch <hash>
git fsck --full
to check integrity of git database, even if no reflog existsgit gc
+ git count-objects -v
to see how much space usinggit verify-pack -v .git/objects/pack/pack-29…69.idx | sort -k 3 -n | tail -3
to show larges objects in packsgit rev-list --objects --all | grep <object hash>
will show path of objectgit log --oneline --branches -- git.tgz
list commits with objectgit filter-branch --index-filter 'git rm --ignore-unmatch --cached git.tgz' -- <hash first commit with object>^..
to remove it from all commitsrm -Rf .git/refs/original
and ` rm -Rf .git/logs/ and
git gc`git prune --expire now