Frequently, my colleagues will make some changes to an open pull request, rebase their local branch against the base branch - often squashing their changes into previous commits as well - and force-push.
How can I see what changed between the old version of the PR and the new version of the PR?
I guess I could do a git pull
and git checkout $BRANCH_NAME
when the PR was first raised, then git fetch
and then git diff $BRANCH_NAME..origin/$BRANCH_NAME
after the PR was updated - but that will also show changes that have been introduced into the base branch (typically master) and brought into the PR via a rebase. Is it possible to remove that noise and just show what has changed in the PR itself?
The following works, but is inefficient for large repos because the whole repo worktrees are downloaded:
This could be much simpler and leaner if Github would allow
git fetch
ing revs by their SHA1, but that's not the case yet.You can do so directly on GitHub: see "Find committer of a force push on GitHub"
Original answer: 2016
That would be only available in the reflog of the remote repo, which would include the previous HEAD of the branch force-pushed.
Since the remote repo is a GitHub one, you still can infer the old commit by looking at push events: see "Does github remember commit IDs?".
More exactly, you will always have the differences against a common ancestor (which will include commits from the base branch like
master
)See What are the differences between double-dot "
..
" and triple-dot "...
" in Git diff commit ranges?So in your case, your forced-pushed branch looks like this on the remote repo:
A diff old_HEAD..newHEAD would include the few
M
commits from the base branch, as they are part of the common ancestor (M0
) path.So you can compare a force-pushed branch (providing you are monitoring pushEvents and know of the previous HEAD of that branch).
But uou cannot easily compare two branches without their common ancestor path.
Checkout this answer to another question which want to do something very similar to what you are trying to achieve.
It describe your situation like this:
Now do this:
The idea is that commit-tree will fake a merge between
oldcommit
andupstream
producingnewcommit
tree and thus containing exactly the code ofnewcommit
. It does not modify your current branch at all, it create a new headless commit and give you its ID. This meansgit show
will list every modification as a conflict resolution, which is the exact difference between the new PR and the old one.To be able to do that you need to have the previous PR in your git repository somewhere (if a force push has been performed the git history has been rewritten and can't be recovered unless you have it on your pc or you have access to the server reflog). Check VonC answer for details about this.
Assuming:
master
$BRANCH_NAME
origin/$BRANCH_NAME
You can do like this:
the
git merge-base
is used to find the common ancestor between two branches, in this case to find the commit on which the new PR is based on in the base branch, if you prefer you can write the commit ID directly.I believe that this is simply not possible to obtain the old versions of pull requests as suggested by this ticket: https://github.com/isaacs/github/issues/999 Users who post in that repository are advised to contact GitHub support, so likely GitHub support has already replied that it was not possible when that ticket was created.
This is a major missing feature from GitHub pull requests that Gerrit has and which Gerrit users miss badly.