GitHub has refused to implement fast-forward merges for years, insisting that you can only have rebases or merge commits (including squash merge commits). I have no idea why. However, on projects where you have enough control over the merge flow, you can have your fast forward cake and eat it too:
-
Check out the branch locally (including, if you like with
gh pr checkoutusing theghCLI tool). -
Fast forward the trunk branch to the commit that is the tip of that PR.
The “correct” way: 1. Check out your trunk branch again. 2. Do a fast-forward-only merge.
git checkout main git merge --ff-only target-branch git branch --delete target-branch git pushThe “why isn’t this easier” way: forcibly move your trunk branch to the tip of the checked out branch (which is what a fast-forward merge is anyway).1
git branch --force main target-branch git branch --delete target-branch git push
On GitHub, this will mark the PR for target-branch as merged. Neat!
Caveats:
- This only works if you don’t protect your default branch (
main/trunk/master/etc.) from pushes, because you won’t be able to push to it if you do. - Nothing will stop you from merging something which did not pass your continuous integration this way.
Net, you may not want to do this in certain repos. (It sure would be nice if GitHub supported it nicely, wouldn’t it?) However, it is totally the kind of thing you could automate if you wanted to: a GitHub Action “bot” could do this. On small repos where you find PRs useful but also would like a linear history where “merges” aren’t relevant, I highly recommend it.
Notes
Moving the branch is just
jj bookmark move --to targetin Jujutsu. No--forceneeded! There is no “fast forward merge” or indeed any other formal notion of merging in jj, because merges are just changes which happen to have multiple parents. ↩︎