git
The list of helpful git commands was growing too large, so compiling into one page.
Branch
git fetch origin <REMOTE_BRANCH>:<LOCAL_BRANCH>
Submodules
Pull all changes:
git pull --recurse-submodules
Reset changes to submodules (including fast-forwards):
git submodule deinit -f . git submodule update --init
Cloning / Fetching / Pulling
Git over mTLS
This SO answer is a good starting point. For initial pull, supply the git config variables in an ad-hoc manner, either via env or config. As of libcurl 8.5.0-2ubuntu10.6, use of encrypted private key does not seem supported:
# These two are equivalent: user:~$ GIT_SSL_CERT=cert.pem GIT_SSL_KEY=privkey.pem git clone ... user:~$ git -c http.sslCert=cert.pem -c http.sslKey=privkey.pem clone ...
Subsequently, add the configuration to the local repository:
user:~$ mkdir -p .git/credentials user:~$ mv cert.pem .git/credentials/cert.pem user:~$ mv privkey.pem .git/credentials/privkey.pem
- .git/config
[http] sslCert = .git/credentials/cert.pem sslKey = .git/credentials/privkey.pem
Bisect
git bisect start
git bisect new
git bisect old {COMMIT}
git bisect {old|new|skip}
...
git bisect reset
Replay bisect:
git bisect log >/tmp/bisect.log git bisect reset git bisect replay /tmp/bisect.log
Bisect can be automated. Error code 0 indicates old/good, 125 for skip, 1-127 for bad/new, and anything else to abort. Hot-fixes can be applied for importing tests or enabling debug flags (e.g. via "cherry-pick" / "rebase" / "merge"):
git bisect run ~/test.sh
- ~/test.sh
#!/bin/sh if git cherry-pick {COMMIT} && make build then ~/check_test_case.sh status=$? else status=125 fi # Undo hotfix and exit git reset --hard exit $status
From old page
Initial setup
- Change local username / email:
git config user.email [EMAIL]oruser.name [NAME] - Change default editor:
git config --global core.editor vim
Small editing and cleanups
- Reset author:
git commit --amend --reset-author --no-edit - Set author:
git commit --amend --author "[NAME] <[EMAIL]>" --no-edit - Clean all:
git reset --hard && git clean -dfx
Patching
- Create a patch:
git diff > [FILE] - Apply a patch:
git apply --whitespace=fix --reject [FILE] - Apply rejected patches:
wiggle --replace [FILE] [FILE.rej]
Changing history
- Interactive add:
git add -p . - Rebase:
git rebase --committer-date-is-author-date --rebase-merges -i [COMMIT]~- Change pick to edit
git addandgit commit --amendgit rebase --continue
- Insert changes to previous commits:
git commit --fixup=[COMMIT]git stashgit rebase -i --autosquash [COMMIT]^git stash pop
- Enable autosquashing by default:
git config --global rebase.autoSquash true - Cherry pick commits:
git switch -c [BRANCH]git cherry-pick -x [COMMIT]git push --set-upstream origin [BRANCH]
Signing
By default, GPG keys are used for signing commits (manually using -S flag).
As of Git 2.34 (Nov 2021), SSH keys can also be used to sign commits.
- Enable commit signing:
git config --global commit.gpgsign true - Use SSH key for signing:
git config --global gpg.format ssh - Specify signing key (GPG/SSH):
git config --global user.signingkey [PUB_KEY] - Verify commit has been signed:
git log --show-signature("No signature" for SSH)
Misc
- Beautify git log:
git config --global alias.adog "log --all --decorate --oneline --graph" - Check branches with latest commits:
git branch -a --sort=-committerdate - Manually delete detached commits (warning! stashes will be deleted):
git reflog expire --expire-unreachable=now --all && git gc --prune=now - Subversion integration:
apt install git-svn - History:
gitk - Push to multiple remotes (and fetch only from one):
git remote add all GITREPO1(sets fetch)git remote set-url --add --push all GITREPO1(overrides push)git remote set-url --add --push all GITREPO2(appends push)git push -u all main(set upstream to all)
- .gitignore
[core] autocrlf = false [alias] adog = log --all --decorate --oneline --graph
- .gitconfig
[core] editor = vim [user] name = pyuxiang signingkey = ... [commit] gpgsign = true [gpg] format = ssh [alias] # Personal adog = log --all --decorate --oneline --graph addw = -c interactive.diffFilter='git diff --color=always --word-diff' add -p diffw = diff --color-words='[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+' diff-staged = diff --cached # Common operations remove = reset --mixed HEAD uncommit = reset --soft HEAD~ recommit = commit --amend # Get lists of stuff branches = branch -a tags = tag -l --sort=v:refname stashes = stash list remotes = remote -v
