ChatGPT解决这个技术问题 Extra ChatGPT

How to do a fast-forward merge on GitHub?

So one of my colleagues attempted to merge a branch using GitHub's "merge via fast-forward" option in the web-interface, to keep the history clean from bogus merge commits (the master branch into which they merged, had not progressed since the to-be merged feature-branch was started).

Funnily enough, this didn't work as expected: all the commits got new commit-hashes.

On closer inspection, it seems that merge-option is actually called "Rebase and Merge" and it really seems to do the equivalent of git rebase --force, changing the Committer information (both the person who did the merge, and the time when the merge happened).

It took me quite a while to confirm my suspicion that this is indeed the case, as I couldn't make the cmdline tools to show me the difference between the original commits on the feature branch and the seemingly-identical commits (with different hashes) on the master branch. (In the end, I found that gitk shows both Committer and Author of a commit; in the very end I found that I can also get this information via git log --pretty=raw)

So:

Is there a way to do a "proper" fast-forward merge (git rebase without the --force option) via GitHub's web-interface?

If not: why? (I can see merits in accountability; e.g. it answers the question who is responsible that a given piece of code ended up in master)


P
Pang

Looks like GitHub does not support this – and this is a TERRIBLE affair. You basically CANNOT run an atomic, linear commit strategy (the best there is) using the GitHub UI.

Note that Bitbucket DOES support this, and has much more fine-grained options for setting up the PR landing/integration strategy. Namely the 'Rebase, fast-forward' option which does a --ff-only update of the target/mainline branch. It also has a 'Rebase, merge' option which lets you run a rebase on target (so that your commits are linear) but integrates using a merge commit (if you want to track that the commits are all part of one logical unit/PR).

Both of these options seem superior to GitHub's limited options of either using non-linear merge commits (GitHub's 'Merge pull request' option) or linear rebase ('Rebase and merge' option), which does achieve linearity but creates duplicate commits on the source branch, thus always requiring manual Hard Resets locally if you want to keep things clean and in sync.

So... time to switch your repo provider it seems!


"thus always requiring manual Hard Resets locally if you want to keep things clean and in sync" <- could you explain this part in more detail, please? Thank you!
Okay I just understood the issue. This is horrible!
i bet they do this so github actions re-runs consuming your free minutes
I can't believe github doesn't allow this, its crazy. Does anyone know if there are plans of implementing this in the near future?
b
bain

It's possible to do a fast-forward merge via the command line and then push it to Github. The Github pull request CLI instructions do explicitly say to use git merge --no-ff, but it also appears to work with a fast-forward, which preserves the git commit hash and closes the open pull request:

$ git checkout master
$ git merge your-branch # the branch which has an open pull request
$ git push

At this point, Github will automatically detect that the branch was merged and the pull request will be closed. If you have the "pull request" page open in your web browser you will see it asynchronously change the state to: "X merged commit into master", "Pull request successfully merged and closed".


well, i was explicitely asking for how to do it "via GitHub's web-interface". (for completeness sake, it's good you mentioned that github explicitely acknowledges such merges)
Indeed, and when the master branch is protected this is not even possible. So it is more than a nuisance of having to perform these steps manually, sometimes these steps are not even possible.
@m-d i, too, feared that branch protection would prevent me from using the suggestion in this answer. However, after some experimentation I have found that branch protection can coexist with this.
@bain i'm glad you provided this answer for completeness. It made me try this CLI approach which I otherwise had assumed would be blocked by my branch protection. But it coexists with branch protection! My protection settings are: Require status checks to pass before merging, Require branches to be up to date before merging, and Include administrators ... yet I can push directly to the protected branch as long as the commit(s) that I am pushing are part of a PR where the status checks did indeed already pass. This is very good news for me.
This solution works coexist with branch protection. To make it work, you must create a pull request first.
A
Antoine

Based on GitHub's documentation and my own testing, it is not possible to do a fast-forward with the same commit hash.

The rebase and merge behavior on GitHub deviates slightly from git rebase. Rebase and merge on GitHub will always update the committer information and create new commit SHAs, whereas git rebase outside of GitHub does not change the committer information when the rebase happens on top of an ancestor commit. For more information about git rebase, see the "Git rebase" chapter from the Pro Git book.

https://docs.github.com/en/github/administering-a-repository/about-merge-methods-on-github


worth mentioning that you can open the pull-request and merge it from the command line and push it and github will close the PR as merged
S
Sergey Geron

An alternative could be to setup a Fast Forward PR GitHub Action:

Merge pull request using fast forward only, if possible, moving base branch (target branch) to head branch (source branch). Comment success or failure messages on the pull request issue. The goal is to keep branches equal at the end of the merge.


as of 2021-11-15 i tried this and doesn't seem to work github.com/endre-spotlab/fast-forward-js-action/issues/…
P
Peter Šurda

Based on what others wrote, it doesn't look like GitHub supports this through their web UI. I haven't figured out how to do it either. It works for command line, like others mentioned (git merge --ff-only ...), but there doesn't appear to be a UI equivalent.

I apologise for mentioning a competing product, Gitea. Gitea has a very similar UI to GitHub, and the UI has the same three methods for merging a PR. However, the third one, labeled ("Rebase and merge"), unlike GitHub's, will automatically do a fast-forward merge if there is no need for rebasing. It just works. That's why it's not clear to my why you can't do it on GitHub.