<p>Git is like a blockchain: it only keeps the &quot;best-commit-chain&quot;. A <code>git push -f</code> &quot;reorgs&quot; the prior chain of commits to a new &quot;best chain&quot;.</p>
<p>If you checked out the PR before the force-push, your local git repository retains a copy of the commits from before the force-push. You can then use <code>git fetch</code> and <code>git range-diff &lt;branch&gt; &lt;upstream/branch&gt;</code> to compare the state prior and posterior of the force-push. If you have already checked out the updated branch after the force-push, your local repository still retains a copy of the prior commits (even if it doesn't show up in <code>git log</code>) and you can compare by calling <code>git range-diff &lt;old-commit-hash&gt; &lt;branch&gt;</code>. If you don't remember the old stale commit-chain-tip, you can look it up via <code>git reflog</code>.</p>
<p>Similarly to a Bitcoin node either having seen an extinct chain-tip when it was relevant or there being no (easy) way to get it, you cannot easily get an overwritten commit unless you created a local copy of the upstream branch before the force-push since overwritten commits are discarded by GitHub. In that case, just start reviewing from scratch.</p>
<hr />
<p>TIL that GitHub meanwhile apparently does keep old commits around for a while. So, if you're lucky and it hasn't been cleaned up yet, you may be able to retrieve the &quot;stale commit-chain-tip&quot; via: <code>git fetch upstream &lt;commit-hash&gt;</code></p>

CC BY-SA 4.0
2022-07-25T22:31:00.850Z
2022-07-26T19:32:56.923Z
2022-07-26T19:32:56.923Z
Murch
<p>theStack and Jon Atack answered this on <a href="https://gnusha.org/bitcoin-core-pr-reviews/2022-07-07.log" rel="nofollow noreferrer">IRC</a>.</p>
<blockquote>
<p>What i usually do for reviewing is to give each revision of a PR another branch name locally, e.g. for a hypothetical PR #123456:</p>
<p><code>git fetch origin pull/123456/head:pr123456</code></p>
<p>Now the PR author force-pushes: <code>git fetch origin pull/123456/head:pr123456_2</code></p>
<p>There are now two branches <code>pr12346</code> and <code>pr123456_2</code>, and the differences can be shown with <code>git range-diff pr123456...pr123456_2</code>. This works on a repository that just cloned from the original Github repo without any changes to the configuration)</p>
</blockquote>
<blockquote>
<p>My Git update workflow runs something like <code>git checkout master &amp;&amp; git pull</code> (this pulls down all the updated branches) <code>&amp;&amp; git checkout origin/pr/12345</code> (open gitk and/or run <code>git range-diff</code>, and then if I intend to build the PR I usually run <code>git rebase origin/master</code> before building, not only to check for merge conflicts but also to build more quickly from cache as it is usually up to date with latest master. I probably use <code>git range-diff</code> more often than <code>git diff</code>, as it provides the diff commit by commit. I customize my <code>.gitconfig</code> somewhat (e.g. for <code>git diff</code>, <code>git fetch</code>, <code>git pull</code> etc.)  theStack's version might work better out of the box.</p>
</blockquote>
<p>(achow101 uses <code>git worktree</code> when reviewing PRs on his <a href="https://www.twitch.tv/achow101" rel="nofollow noreferrer">Twitch stream</a>.)</p>
<p>For more guidance on reviewing pull requests in Bitcoin Core see Jon Atack's <a href="https://jonatack.github.io/articles/how-to-review-pull-requests-in-bitcoin-core#pull-down-the-code-locally" rel="nofollow noreferrer">blog post</a>.</p>

CC BY-SA 4.0
2022-07-25T18:33:29.633Z
If I'm interpreting "But I'm not sure how to get Git to store the branch before the force push (the previous commit isn't in the Git history anymore) and compare to the latest version of the branch." as the main question, the second quote is a poor match to the question, and it is not clear what worktrees have to do with the question at all. This answer could be improved by explaining what the underlying issue is and how the quoted approaches help solve it.
Murch
CC BY-SA 4.0
2022-07-25T19:04:05.593Z
@Murch: I've never used git worktree. Isn't it an alternative Git workflow for working on different branches and comparing different branches? There isn't much out there on git worktree (e.g. in Pro Git book)
Michael Folkson
CC BY-SA 4.0
2022-07-25T22:27:26.673Z
No, `git worktree` allows you to have multiple instances of the same repository on your hard drive in parallel but only keeping one copy of the branch references.
Murch
CC BY-SA 4.0
2022-07-25T16:37:57.660Z
2022-07-25T16:37:57.660Z
Michael Folkson
<p>This is more of a Git question but it is particularly relevant to Bitcoin Core PR review (or other open source projects with stringent review requirements).</p>
<p>You've done a review of a PR, the PR author force pushes and you want to compare the PR branch before the force push and after the force push. I've read you should use <code>git range-diff</code> in this scenario. But I'm not sure how to get Git to store the branch before the force push (the previous commit isn't in the Git history anymore) and compare to the latest version of the branch.</p>

<bitcoincore-review>
What Git workflow do I need to use to be able to compare a PR branch before and after an author's force push?
Michael Folkson
# What Git workflow do I need to use to be able to compare a PR branch before and after an author's force push?

(Asked by: username_0 on 2022-07-25)

This is more of a Git question but it is particularly relevant to Bitcoin Core PR review (or other open source projects with stringent review requirements).

You've done a review of a PR, the PR author force pushes and you want to compare the PR branch before the force push and after the force push. I've read you should use `git range-diff` in this scenario. But I'm not sure how to get Git to store the branch before the force push (the previous commit isn't in the Git history anymore) and compare to the latest version of the branch.

**Tags:** bitcoincore-review


---

## 2 answers

### Answer by username_1 on 2022-07-25. Score: 1 | Accepted answer

Git is like a blockchain: it only keeps the "best-commit-chain". A `git push -f` "reorgs" the prior chain of commits to a new "best chain".

If you checked out the PR before the force-push, your local git repository retains a copy of the commits from before the force-push. You can then use `git fetch` and `git range-diff <branch> <upstream/branch>` to compare the state prior and posterior of the force-push. If you have already checked out the updated branch after the force-push, your local repository still retains a copy of the prior commits (even if it doesn't show up in `git log`) and you can compare by calling `git range-diff <old-commit-hash> <branch>`. If you don't remember the old stale commit-chain-tip, you can look it up via `git reflog`.

Similarly to a Bitcoin node either having seen an extinct chain-tip when it was relevant or there being no (easy) way to get it, you cannot easily get an overwritten commit unless you created a local copy of the upstream branch before the force-push since overwritten commits are discarded by GitHub. In that case, just start reviewing from scratch.

---

TIL that GitHub meanwhile apparently does keep old commits around for a while. So, if you're lucky and it hasn't been cleaned up yet, you may be able to retrieve the "stale commit-chain-tip" via: `git fetch upstream <commit-hash>`


---

### Answer by username_0 on 2022-07-25. Score: -1

theStack and Jon Atack answered this on [IRC](https://gnusha.org/bitcoin-core-pr-reviews/2022-07-07.log).

> What i usually do for reviewing is to give each revision of a PR another branch name locally, e.g. for a hypothetical PR #123456:
>
> `git fetch origin pull/123456/head:pr123456`
>
> Now the PR author force-pushes: `git fetch origin pull/123456/head:pr123456_2`
>
> There are now two branches `pr12346` and `pr123456_2`, and the differences can be shown with `git range-diff pr123456...pr123456_2`. This works on a repository that just cloned from the original Github repo without any changes to the configuration)

> My Git update workflow runs something like `git checkout master && git pull` (this pulls down all the updated branches) `&& git checkout origin/pr/12345` (open gitk and/or run `git range-diff`, and then if I intend to build the PR I usually run `git rebase origin/master` before building, not only to check for merge conflicts but also to build more quickly from cache as it is usually up to date with latest master. I probably use `git range-diff` more often than `git diff`, as it provides the diff commit by commit. I customize my `.gitconfig` somewhat (e.g. for `git diff`, `git fetch`, `git pull` etc.) theStack's version might work better out of the box.

(achow101 uses `git worktree` when reviewing PRs on his [Twitch stream](https://www.twitch.tv/achow101).)

For more guidance on reviewing pull requests in Bitcoin Core see Jon Atack's [blog post](https://jonatack.github.io/articles/how-to-review-pull-requests-in-bitcoin-core#pull-down-the-code-locally).

> **Comments:**
> **username_1**: If I'm interpreting "But I'm not sure how to get Git to store the branch before the force push (the previous commit isn't in the Git history anymore) and compare to the latest version of the branch." as the main question, the second quote is a poor match to the question, and it is not clear what worktrees have to do with the question at all. This answer could be improved by explaining what the underlying issue is and how the quoted approaches help solve it.  
> **username_0**: @username_1: I've never used git worktree. Isn't it an alternative Git workflow for working on different branches and comparing different branches? There isn't much out there on git worktree (e.g. in Pro Git book)  
> **username_1**: No, `git worktree` allows you to have multiple instances of the same repository on your hard drive in parallel but only keeping one copy of the branch references.  

---

