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

  • Thread starter Thread starter Wrichik Basu
  • Start date Start date
  • Tags Tags
    History Linear
Click For Summary
SUMMARY

This discussion focuses on the challenges of merging pull requests (PRs) in GitHub while maintaining a linear history and requiring signed commits. The user has implemented branch protection rules that necessitate separate branches for features and bug fixes, disallowing simple merges and requiring all commits to be signed. The conclusion drawn is that merging PRs under these conditions is nearly impossible without relaxing some rules, particularly the requirement for linear history. The discussion also highlights the complexities of managing commit history and suggests that over-complication may hinder effective collaboration.

PREREQUISITES
  • Understanding of GitHub branch protection rules
  • Familiarity with Git rebase and merge strategies
  • Knowledge of signed commits in Git
  • Experience with GitHub pull request workflows
NEXT STEPS
  • Research "Git rebase vs. merge strategies" for effective branch management
  • Learn about "GitHub branch protection rules" and their implications
  • Explore "Git signed commits" and how to implement them effectively
  • Investigate "GitHub workflows" to optimize collaboration and history management
USEFUL FOR

Developers, team leads, and project managers who are managing GitHub repositories and looking to implement effective branching strategies while maintaining commit integrity and collaboration efficiency.

Wrichik Basu
Science Advisor
Insights Author
Gold Member
Messages
2,180
Reaction score
2,690
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
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.
 
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   Reactions: DavidSnider
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   Reactions: Wrichik Basu
Just browsing thread is enough to give me eye twitches and flashbacks.
 
  • Haha
  • Love
Likes   Reactions: Tom.G, FactChecker and pbuk

Similar threads

  • · Replies 14 ·
Replies
14
Views
3K
Replies
4
Views
3K
  • · Replies 13 ·
Replies
13
Views
3K
  • · Replies 2 ·
Replies
2
Views
3K
  • Sticky
  • · Replies 2 ·
Replies
2
Views
503K