Skip to content

Instantly share code, notes, and snippets.

@barijaona
Last active August 31, 2025 01:29
Show Gist options
  • Select an option

  • Save barijaona/32c590ae180e197bd439a8a5b48c103b to your computer and use it in GitHub Desktop.

Select an option

Save barijaona/32c590ae180e197bd439a8a5b48c103b to your computer and use it in GitHub Desktop.
Git power tricks

Git power tricks

These commands may help when dealing with complicated Git repositories. I used them to build a new branch to streamline a more readable history for a very old project.

Compare two directories at different times of history

git difftool -d <commit-a>:path/to/dir1 <commit-b>:path/to/dir2

Have a quick view of differences

git diff --stat <commit-a> <commit-b>

Compare two directories, with at least one of them not being Git-managed

git diff --no-index <path1> <path2>

Find initial commit of current head

git cherry master -v | head -n 1

Get the date of a commit…

Committer date

git show -s --format="%cd" <commit>

or

git show -s --format="%ci" <commit>

Author date

git show -s --format="%ad" <commit>

or

git show -s --format="%ai" <commit>

Modify last commit (dates and author)

GIT_COMMITTER_DATE="<committer-date>" git commit --amend --author="Author Name <email@example.com>" --date "<author-date>"

Merge branches when Git is unable to find a common ancestor

git merge --allow-unrelated-histories <other-branch>

Rebase keeping initial author date

git rebase --committer-date-is-author-date --onto <newbase>

Cherry-pick a series of commits

git cherry-pick <start>..<end>

If you want to pick the range A through B (including B) that would be git cherry-pick A~..B

Personally, I prefer getting a list of commits:

git log --reverse --format=%h%x20 <start>..<end>

… then copy and paste it into a text editor, remove linefeeds, review the list and possibly amend it. Afterwards, I can submit git cherry-pick with the list of commits:

git cherry-pick <commit-a> <commit-b> <commit-c> …

Rebuild current head after rebase or cherry picks, resetting author names and dates

Replace <startbase> here with SHA or short SHA of the commit that should be considered as a stable foundation.

git filter-branch --commit-filter 'export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; git commit-tree "$@"' -- <startbase>..HEAD

Once you've inspected the results, and you're really sure that you have what you want, you can remove the backed up ref:

git update-ref -d refs/original/refs/heads/<branchname>

… or you can add the -f option in your next invocation of the git filter-branch command:

git filter-branch -f --commit-filter ...

Replace a problematic parent with a "foster parent" having a more streamlined history

git replace --graft <current-parent> <new-parent>

Afterwards, push to your remote:

git push origin refs/replace/<current-parent>

or (to push all replacements you defined):

git push origin 'refs/replace/*:refs/replace/*'

Note that there is no way to force other users of a repository to use the rewritten history. They will have to issue the following command in order to fetch the replacements you pushed and adopt them:

git fetch <your-remote> '+refs/replace/*:refs/replace/*'

Date back a tag

GIT_COMMITTER_DATE="<committer-date>" git tag -s <tag-name>

or

GIT_COMMITTER_DATE="<committer-date>" git tag -a <tag-name>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment