Small information nuggets and recipies about Git
✂️ Git
Table of Contents
- Search for commits that add or delete a string (pickaxe)
- Configure separate Git users for different repos
- Revert changes of a single file of a commit
- Manually ignore changes to a tracked file or directory
- Rebase a topic branch into anywhere you want
- Change the committer and author names
- Fixup commits and autosquash rebases
- Find broken commit
- Detect which folders are affected by the latest commits (monorepo)
- Delete remote branch or tag
- Differences between local and upstream
- The @ sign is an alias for HEAD
- Change a commit original author date
- Rebase commits to reset commit date to the original author date
- Auto stash dirty directory on pull/rebase
- Check lightweight vs. annotated tags
- Set user & email info
- Prepare a patch formatted for email
- Apply a patch received as file
- Show files being ignored
- Choose a new root commit for the repo
- Visualise the entire commit graph
- Rollback the last commit for good
- Undo a rebase
- Recover lost commits
- Show outgoing changes
- Show incoming changes
- git-flow rules of engagement for releases (merge commit) messages
See also:
So here are some bad situations I’ve gotten myself into, and how I eventually got myself out of them in plain english.
(most recent on top)
Search for commits that add or delete a string (pickaxe)
git log -p -S example
-p
Generate patch text
-S<string>
Look for differences that change the number of occurrences of the specified
string (i.e. addition/deletion) in a file.
-G<regex>
Look for differences whose patch text contains added/removed lines that match <regex>.
Configure separate Git users for different repos
… ~/.gitconfig
[user]
name = First Last
email = [email protected]
[includeIf "gitdir:~/work/"]
path = ~/work/.gitconfig
… ~/work/.gitconfig
[user]
email = [email protected]
Revert changes of a single file of a commit
- via Michael Brown
git show <commit> -- some_file.c | git apply -R
Manually ignore changes to a tracked file or directory
… stop tracking
git update-index --assume-unchanged <file>
… resume tracking
git update-index --no-assume-unchanged <file>
Rebase a topic branch into anywhere you want
… topic
info master
(run from any branch)
git rebase master topic # default is HEAD of master
git rebase master topic --onto commit
Change the committer and author names
… set default repo user
git config user.name "User Name"
git config user.email [email protected]
… author = default, committer = default
git commit --amend --no-edit --reset-author
… author = custom, committer = default
git commit --amend --no-edit --author "Author Name <[email protected]>"
… author = same, committer = custom
git -c user.name="Committer Name" -c user.email=[email protected] commit --amend --no-edit
… in many commits
git rebase -i -p
# mark as: edit
# repeat as above
Fixup commits and autosquash rebases
… create
# squash fixed commit; prefixes message with "squash! "
git commit --squash e37dc68
# fixup relative commit; prefixes message with "fixup! "
git commit --fixup @~1
# fixup commit with string; prefixes message with "fixup! "
git commit --fixup :/foobar
… apply
# auto reorganises the squash/fixup and moves them to the right place
git rebase -i --autosquash
# makes it the default for all rebases
git config --global rebase.autosquash true
Find broken commit
git bisect start <bad> <good>
… example
git bisect start @ origin/master
git bisect run bin/test.sh
Detect which folders are affected by the latest commits (monorepo)
- via Equal Experts
git diff-tree --no-commit-id --name-only HEAD tag
Delete remote branch or tag
… as of v1.7
git push origin --delete <branch_name>
git push origin --delete <tag_name>
… before that
git push origin :<branch_name>
Differences between local and upstream
git diff @{u}..@
The @
sign is an alias for HEAD
git show @
git show @~2
Change a commit original author date
- How can one change the timestamp of an old commit in Git? - Stack Overflow
- Update git commit author date when amending - Stack Overflow
… set author date
git commit --amend --no-edit --date="Sun Dec 31 12:34:56 2017"
… set committer date + author date
GIT_COMMITTER_DATE="Sun Dec 31 23:45:00 2017" git commit --amend --no-edit --date="Sun Dec 31 23:45:00 2017"
… set committer date = author date
GIT_COMMITTER_DATE="Mon May 7 23:54:$(echo $((RANDOM % 50 + 10)) | cut -c-2) 2018" bash -c 'git commit --amend --no-edit --date="$GIT_COMMITTER_DATE"'
… random seconds
echo $((RANDOM % 50 + 10)) | cut -c-2
… see also custom function shell git-commit-dates()
Rebase commits to reset commit date to the original author date
git rebase --committer-date-is-author-date @~3
Auto stash dirty directory on pull/rebase
- via Anil Wadghule
… autostash is only available since git version 2.9
git pull --rebase --autostash
… for earlier versions use:
git config --global rebase.autoStash true
Check lightweight vs. annotated tags
… annotated: “You can see the tag data along with the commit that was tagged by using the git show command”
$ git show annotated-tag
tag annotated-tag
Tagger: Hugo Ferreira <[email protected]>
Date: Thu Dec 24 10:54:15 2015 +0000
message text with details
commit 6ec10ad250c8bbbdc42dba51a09c02b456e02187 (tag: annotated-tag)
Author: Hugo Ferreira <[email protected]>
Date: Thu Dec 24 10:23:50 2015 +0000
… lightweight: “This time, if you run git show on the tag, you don’t see the extra tag information. The command just shows the commit”
$ git show light-tag
commit f5d32c57c9612c610dc0c45cc0ff3f0b1d21fd53 (HEAD -> master, tag: light-tag)
Author: Hugo Ferreira <[email protected]>
Date: Thu Dec 24 10:25:44 2015 +000
Set user & email info
… current repo only .git/config
git config user.name "Hugo Ferreira"
git config user.email [email protected]
… default for all repos ~/.gitconfig
git config --global user.name "Hugo Ferreira"
git config --global user.email [email protected]
Prepare a patch formatted for email
git format-patch HEAD~1
git format-patch <sha>..@
Apply a patch received as file
… dry-run
git apply --check --stat 0001-file.patch
… apply and create commits
git am 0001-file.patch
… apply patch to files
# files only
git apply 0001-file.patch
# files + index
git apply --index 0001-file.patch
# index only
git apply --cached 0001-file.patch
Show files being ignored
git clean --dry-run -dX
git clean -ndX
Choose a new root commit for the repo
git rebase -i --root
Visualise the entire commit graph
git log --graph --oneline --all --color --decorate
Rollback the last commit for good
git reset HEAD~1 --hard
Undo a rebase
… show the history of operations (like an “undo” stack)
$ git reflog
b710729 HEAD@{0}: rebase: some commit
5ad7c1c HEAD@{1}: rebase: another commit
deafcbf HEAD@{2}: checkout: moving from master to my-branch
… reset to the commit before the rebase
git reset --hard deafcbf
Recover lost commits
… discover
git fsck --lost-found
git reflog
git show <sha1>
… restore
git cherry-pick <sha1>
git merge <sha1>
Show outgoing changes
git fetch && git whatchanged origin..
Show incoming changes
git fetch && git whatchanged ..origin
git-flow
rules of engagement for releases (merge commit) messages
… setup
git config --global merge.log true
… default message
Merge branch 'release/1.0.0'
* develop:
One commit message
Another commit message
… edit: commit message (merge)
Merge branch 'release/1.0.0'
- One commit message
- Another commit message
… edit: tag message (releases)
release/1.0.0
- One commit message
- Another commit message