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.
git difftool -d <commit-a>:path/to/dir1 <commit-b>:path/to/dir2
git diff --stat <commit-a> <commit-b>
git diff --no-index <path1> <path2>
git cherry master -v | head -n 1
git show -s --format="%cd" <commit>
or
git show -s --format="%ci" <commit>
git show -s --format="%ad" <commit>
or
git show -s --format="%ai" <commit>
GIT_COMMITTER_DATE="<committer-date>" git commit --amend --author="Author Name <email@example.com>" --date "<author-date>"
git merge --allow-unrelated-histories <other-branch>
git rebase --committer-date-is-author-date --onto <newbase>
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> …
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 ...
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/*'
GIT_COMMITTER_DATE="<committer-date>" git tag -s <tag-name>
or
GIT_COMMITTER_DATE="<committer-date>" git tag -a <tag-name>