GitHub: How do I merge a PR but maintain linear history + signed commit

In summary, your branch protection rule means that each feature or bugfix must be on separate branches, which will be later merged with main. This will create a problem when merging a PR. Furthermore, linear history is not preserved when merging other branches into main.
  • #1
Wrichik Basu
Science Advisor
Insights Author
Gold Member
2,138
2,713
Suppose, for a certain a repo, I create a branch protection rule for the main branch with the following:
  • Require pull request before merging. This means that each feature or bugfix must be on separate branches, which will be later merged with main.
  • Maintain linear history of the main branch, which implies that simple merges on GitHub are disabled.
  • Ensure all commits to be signed, and reject unsigned commits. This means that Rebase and merge in GitHub will fail, as GitHub cannot automatically sign such commits.
As an additional, unwritten rule, I also want to preserve the commit history when merging other branches into main, unless the commit history is awfully created. Therefore, I hope to avoid using Squash and merge.

As a consequence of the above, all the three merge options in GitHub are practically unavailable.

The following situations will now arise when I am trying to merge a branch that I have created:
  • I push the branch to the remote, with all the commits, and create a pull request. I may add more commits after creating a PR.
  • I locally rebase this branch with main and force-push to remote, if necessary.
  • Since all the three merge options for a PR are practically unavailable, I merge the branch into main locally and push to remote. This will close the PR and delete the remote branch automatically. Thereafter, I can also delete the local branch. Linear history will be preserved.
Now, suppose someone else forks my repo, works on it, and creates a PR. Before merging, I can definitely request that person to do a rebase so that linear history is maintained. Also assume all status checks and deployments have passed. But the question is, how do I merge their branch to main? I don't have any merge option at all!

I know I can checkout PRs locally. Can I somehow merge them locally and then push to main (which will close the PR automatically as merged)?

It seems that merging someone else's PR with the above branch rules enforced is nearly impossible. Am I right in this conclusion?

If yes, and if I relax the linear history rule but ensure that before merging, the fork/branch is rebased with main, then I will end up with a nearly clean history, somewhat as follows:

Code:
main
|
|
|
*   <---------- The PR merge commit on GitHub
|\
| \
|  \
|  *        ---
|  |          |
|  |          |
|  *          |
|  |          |
|  |          |
|  *          |------> The fork that is to be merged, rebased with main
|  |          |
|  |          |
|  *          |
|  |          |
|  |          |
|  *        ---
|  /  
| /
|/
*
|
|
*
|
|
*
|
|

What are your opinions on this?
 
Technology news on Phys.org
  • #3
In general, we would start with the main branch for all dev work. When we were about to release a product, we'd create a branch for it.

Development work would continue on the main for the next release. Defects uncovered by customers in the released edition would either be patched into the release branch (to update the website download) and/or merged back into the main for future releases if it made sense to do that.

Forking off to start some new software strategy and then merging it back at some later date always seemed to lead to madness and increased defects and had to be done with great care.
 
  • #4
jedishrfu said:
In general, we would start with the main branch for all dev work. When we were about to release a product, we'd create a branch for it.
There are different strategies, and teams have their own suitable methods of managing their repos. Your method, for instance, would create a bunch of branches each time a release is created, which may become cumbersome in future.

Another method is to keep two branches: main and dev. Bleeding edge changes will be done on dev, which will be merged later with main. Major bugs or vulnerabilities can be fixed in a hotfix branch, which will then be merged with both main and dev. Releases will be from main, denoted by tags.

Yet another way is to create separate branches for each feature or bug, and then merge it to main. Releases will be denoted by tags.
 
  • Like
Likes DavidSnider
  • #5
Wrichik Basu said:
What are your opinions on this?
I have a few:
  • You are over-complicating things.
  • Branch protection rules are there to help, not to hinder.
  • If you are the only one with commit permission to the repo then you only need rules to stop you making mistakes, not to prevent you from doing something you don't want to do anyway.
  • If you want to grant others commit permission then you can have procedures you agree to follow. Then you still only need rules to stop them making mistakes, not to prevent them from doing something they have agreed they don't want to do anyway.
  • Unless your project is tiny, this
    Wrichik Basu said:
    • As an additional, unwritten rule, I also want to preserve the commit history when merging other branches into main, unless the commit history is awfully created.
    is a bad idea.
  • The objective of having "all commits signed" is incompatible with your other objectives - GitHub can't sign a commit so it can't do a rebase, which means you have to do the rebase which means there is no point in signing it (because only you can do it).
  • You are over-complicating things. If this workflow https://docs.github.com/en/get-started/quickstart/github-flow is good enough for GitHub to use themselves, it should be good enough for you.
 
  • Informative
Likes Wrichik Basu
  • #6
Just browsing thread is enough to give me eye twitches and flashbacks.
 
  • Haha
  • Love
Likes Tom.G, FactChecker and pbuk

FAQ: GitHub: How do I merge a PR but maintain linear history + signed commit

How do I merge a PR on GitHub?

To merge a pull request on GitHub, go to the pull request page and click on the green "Merge" button. This will merge the changes from the pull request into the main branch of the repository.

How do I maintain linear history when merging a PR on GitHub?

To maintain linear history when merging a pull request on GitHub, make sure to use the "Squash and merge" option. This will combine all the commits from the pull request into one commit, creating a linear history.

How do I create a signed commit on GitHub?

To create a signed commit on GitHub, you will need to set up a GPG key and add it to your GitHub account. Once your key is set up, you can use the "-S" flag when committing changes to sign the commit.

What is the benefit of maintaining linear history on GitHub?

Maintaining linear history on GitHub can make it easier to track changes and troubleshoot issues. It also makes the commit history more organized and easier to read.

Can I merge a PR and maintain linear history while also creating a signed commit?

Yes, you can merge a pull request and maintain linear history while also creating a signed commit. Make sure to use the "Squash and merge" option and include the "-S" flag when committing changes. This will create a single signed commit with a linear history.

Similar threads

Replies
13
Views
2K
Replies
2
Views
2K
  • Sticky
Replies
2
Views
497K
Back
Top