简体   繁体   中英

pull request from develop to master, how to keep branches "even/sync"

I use git-flow and from the Github protection rules I have branches master and develop protected, both with the option Require linear history .

All works fine, but now I would like to instead of just merging from develop to master , start using "pull requests" ( develop -- PR --> master ) I would like to know if it is possible to keep the branches even/sync while keeping the history linear, without out need to do a force push on the develop branch.

Currently, If I create a pull request PR from develop to master and because the Require linear history option is checked, I can't merge but only squash and merge or rebase and merge because of this if I modify the develop branch and make another commit it becomes N times ahead but it can never be "even".

The only way I have found to make develop even with master is with

git pull origin master --rebase

But this then later implies force push:

git push -f

When not using PR I simply merge develop into master (FastForward) and keeps history linear, I could merge the pull requests and prevent the force push by disabling the Require linear history , but history will not be linear. (I think the PR's are not being merged using FastForward)

The reason for me to use git-flow is that the develop branch is used by the CI/CD and deploys to staging and master to production, I am aware that partially this could be solved by using tags so that everything merged into master without tag could be deployed to "staging" and only tags to "production" but for now having this constraint of branches master and develop what could be the best way to keep branches as sync as possible?

tl;dr: If you wish to have a linear history, then you cannot use Git Flow. That being said, regardless of whether or not you call it "Git Flow", you can complete a GitHub Pull Request with a fast-forward merge if you do it from the command line.

Details :

GitHub is an outlier compared to most popular Git SCM tools in the respect that, as you point out, even the "rebase and merge" strategy uses rebase -f which forces a rewrite of the commits even if it's already up to date with the target branch. So unfortunately that's not an option for you. GitHub simply doesn't support a fast-forward merge using their UI, but you can achieve the desired outcome without re-writing your commits on the develop branch by performing the merge from the command line and pushing it while the PR is open. The key here is that it will still work with branch protection.

That should achieve your goal, but I do think it's important to point out that you probably shouldn't be using Git Flow in your scenario. Of course you may call it that if you wish, but there are multiple reasons why a linear history is incompatible with Git Flow:

  1. Perhaps the most obvious reason is that Git Flow recommends (or arguably requires ) that you merge all of your branches with --no-ff . By definition, if you follow this advice you will not have a linear history. My personal preference is to use a semi-linear merge (aka "rebase then merge with no-ff") strategy for merging feature branches into shared branches such as develop and release . The resulting graph is still "pretty", but contains small linear bubbles of commits rather than a purely straight line of commits. Note I only recommend rebasing personal feature branches. You should not be rebasing a shared branch such as develop or master as that leads to pain and suffering. (It seems you know this which is why you asked the question.) Additionally, I always use --no-ff for shared branch merges into each other as Git Flow recommends, even if it could have been a fast forward merge.
  2. Even if you don't force a merge commit when one isn't needed, one of the primary reasons to use Git Flow (and even Git in general) is to enable simultaneous development by different people at the same time. In Git Flow, new work on develop can continue while you are hardening a release as it awaits deployment. If you have simultaneous development, then when it comes time to merge changes made on a release or master back into develop , you won't need to force a merge commit because it will be necessary- you don't have a choice. As you've noticed, the only alternative to having a merge commit in this case would be to rebase a shared branch, and again, we can't do that because of the pain and suffering issue.
  3. For the sake of argument, let's assume that you never will have simultaneous development, and you decide not to force the merge commits. This means develop will always be ahead of master and you can always merge develop cleanly into master with a fast forward merge. If you can achieve this, that's fine, but then you're not really using the majority of Git Flow features. You can still call it Git Flow if you'd like, but in this case I'd probably just rename develop to main , and merge my feature branches directly into main , and then tag it when I release it to production. By the way, this strategy has many different names, so I probably wouldn't call it Git Flow, but instead "Feature Branch Workflow", or "GitHub Flow", or "Trunk Based Development with named branches", or "GitLab Flow with Production branch", etc. My point here is you'd be deviating from Git Flow so much that you might as well call it something else that's closer to what you're doing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM