9

I am working in my local branch in PHP Storm. After the task is done, I commit my branch and push to git.

On Github page I create a Pull request DEV <- my branch. Dev is the base branch, to which I will merge my branch.

This is ok till now. But in case there are conflicts in some files - according to this article https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github

In my case the same file was updated in other branch and merged to DEV before. Now in my branch is the same file with other changes.

When I resolve the conflict (can be even one line), I Mark it as resolved and the commit merge.

And now it happens, that the whole DEV base branch is merged to my own branch, and this is not good.

Because I am merging my branch to DEV, not vice versa. How is it possible to avoid this?

I tried to recreate the same branch, but the once the dev was merged here, it is always there. It is nonsense that this happens on each conflict - as the 8. point of above mentioned web says:

Once you've resolved all your merge conflicts, click Commit merge. This merges the entire base branch into your head branch.

enter image description here

Darksymphony
  • 2,155
  • 30
  • 54
  • "*that the whole DEV base branch is merged to my own branch*" that should not happen. Are you *sure* you're merging your branch into dev, and not dev into your branch? Can you show us the commands you're running to cause this? And also `git log --graph --decorate --oneline --all` which shows dev and your branch after the merge. – Schwern Nov 05 '20 at 18:34
  • 1
    I am doing it on the github webpage, not in console. As I wrote DEV <- mybranch. Also in Pull request it says merging mybranch to DEV. There was only my branch in the Pullrequest, but after I solved the conflict and committed, a new line appeared in Pull request saying Merge branch 'dev' to mybranch. It is similar to steps in the link provided in my question (3 - 8). In that conflict resolving page I just remove <<<<<<<, =======, >>>>>>> characters and leave just necessary code. – Darksymphony Nov 05 '20 at 18:42
  • as you see in my screenshot, it says wants to merge 2 commits into DEV from 825. However the second commit appeared there only after I resolved the conflict file. And it merged the dev to my branch for some reason. It happens every time when I am resolving conflicts there. As I mentioned the sentence from the link I provided, they say: Once you've resolved all your merge conflicts, click Commit merge. This merges the entire base branch into your head branch. – Darksymphony Nov 05 '20 at 19:03
  • and here is also an anwer: so this is normal, but then I can't solve conflict on git https://github.community/t/why-does-github-merge-base-into-feature-branch-after-conflict/1027 – Darksymphony Nov 05 '20 at 19:34
  • Ok, I see what Github is doing now. – Schwern Nov 05 '20 at 22:29

2 Answers2

2

tl;dr

the whole DEV base branch is merged to my own branch

This is a feature of Github's conflict resolution process.

From Resolving a merge conflict on Github: "8. Once you've resolved all your merge conflicts, click Commit merge. This merges the entire base branch into your head branch." But they don't explain why.

and this is not good

It is surprising, but it is good. I'll explain below.

How is it possible to avoid this?

Don't avoid it. But it is possible to make the process more smooth.

Bring your branch up to date with dev and resolve any conflicts. Then submit the PR.

To do this on Github: Submit your PR as a draft; resolve the conflict on Github; mark it ready for review. By beginning with a draft you avoid people reviewing your code before the conflict resolution is complete.

To do this on the command line:

# Bring dev up to date
$ git checkout dev
$ git pull

# Update your branch with the latest dev
$ git checkout <your branch>
$ git rebase dev       # or git merge dev

Note that yes, you merge dev into your branch before submitting your branch to be merged into dev. This is the normal process of bringing a branch up to date.

You should be bringing your branch up to date habitually to reduce the amount of drift between your branch and dev. This will make the conflict resolutions smaller and easier to manage.


Y U Do This, Github?

The Github PR process, like any review process, is about checking the resulting merge will work. This can involve automated checks, running the branch's tests, and manual review.

Let's consider if it worked like you want. Your PR passes all checks. You click the merge button and there are conflicts. You resolve the conflicts and merge straight into dev.

What if you made a mistake resolving the conflict?

The resolved code is not the code that was reviewed. A merge conflict indicates something changed in dev that you were unaware of and did not account for. You just edited your branch to fix that, and that work has not been checked. If merged immediately into dev there's nothing stopping your PR from breaking dev for everyone.

Instead, a Github PR needs to treat manual conflict resolution like any other edit. As with any other edit, it must be rechecked. The resolved code must live somewhere in the repository. So Github merges dev into your branch along with the conflict resolution, just like if you'd updated your branch before submitting a PR. Now your branch can be rechecked for mistakes. The resolved code passes checks it can safely be merged.

So Github is doing the same thing you should be doing on the command line. Update your branch from dev, resolve any conflicts, check the result, then merge.

Note: this is an educated guess on my part. I don't have any special insights into Github.


In the end, feature branches are ephemeral. Once merged they should be deleted. The exact merging process isn't too important so long as the result is correct.

Schwern
  • 153,029
  • 25
  • 195
  • 336
  • 1
    thank you very much for explaining. The problem is, if we are doing Release, and creating Release branch from master. To this branch we are merging all remote branches ready to release. But IF the whole dev was merged to my branch, it means it contains also other commits from users and changes on dev and some of them may not be ready for release. But if I want to release only my branch, it already contains all the changes from dev and everything will be released to production and this is very bad. We need to release ONLY the selected branches, that's why merging the whole dev to branch is bad – Darksymphony Nov 06 '20 at 09:59
  • @Darksymphony The fundamental problem is that your feature branches must be branched from something which is ready for release. The simplest thing is to not merge things into dev until they're ready for release. I can't say more without more detail. If you ask it as another question link it here and I'll have a look. But I think adopting [Gitflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) will likely solve your problem. – Schwern Nov 16 '20 at 22:00
  • 1
    To provide a reference to the comment by @Schwern, the guide says *There's only one rule: anything in the main branch is always deployable.* (source: https://guides.github.com/introduction/flow). – Mihai Aug 30 '21 at 13:08
  • 3
    @Schwern this is troubling to me. I was merging Main -> Feature today to bring the latest into the feature branch, I did a PR on Github vs doing it locally. Had single line conflict I resolved, I should have stopped there when I saw it wanted to "commit to main" but I proceeded. End result is my entire feature branch was merged into main when the intent of my PR was to merge main to the feature. The troubling part of this is that my main branch has branch protection, must be PR, must have approver/CodeOwner review, yet somehow can bypass all of that by fixing a conflict? How can that be? – Josh Aug 25 '22 at 19:23
  • 1
    @Josh I had a very similar problem (I want to merge Main -> Feature but resolving a conflict would translate in "commit to main", which I find absurd): did you find a solution on his? – user17788510 Mar 16 '23 at 20:24
  • 1
    Nope never got an answer to this, I do suspect the merge went through because I had admin rights on the repo though and it did an auto admin override. – Josh Mar 16 '23 at 20:53
  • 1
    @Josh I found a solution: if you want to merge main into Feature (and there are conflicts) just use the command line (git checkout Feature; git pull; git merge main; #resolve conflicts in editor; git add . ; git commit -m "updated main into feature"; git push). In this way the Main branch remain untouched and the Feature branch is updated with commits from Main, as it should be – user17788510 Mar 17 '23 at 09:56
  • 1
    @user17788510 Correct doing it by pulling locally and resolving conflicts works fine, it's resolving in the github tool that causes issue. – Josh Mar 20 '23 at 16:02
  • Just chiming in here to say that, I too, have been baffled and flummoxed by this very unintuitive behavior by the GitHub UI merge conflict resolution process. It's not good... I have also come to the conclusion that merges into a staging branch (or release branch) should never be done via the GitHub UI, and only done via the command line to achieve the desired behavior. – Brian FitzGerald Apr 07 '23 at 02:47
0

Firstly, it is good practice to stay up to date with DEV branch in the feature branches since you will have to merge the changes anyway at some point. I have never been in the situation where it is bad to be up to date with DEV branch, but I can imagine some scenarios.

One workaround for the above is to continue with the merging on the web and allow the remote DEV branch be merged into your remote feature branch. Your local feature branch, however, is still at the place before DEV was merged.

At this point you can force push the local changes to the remote branch, thereby resetting the remote feature branch to where you want it to be.

$ git fetch
$ git checkout feature-825
$ git push --force 
Shell Code
  • 682
  • 4
  • 9
  • Each branch should contain only the people's work, and these branches are merged to dev. It is strange to merge dev into each branch. And then if I fetch the remote branch locally, it will pull also all files from dev into my branch, where only my files should be. And also then we are creating a release branch, which should contains only branches ready to production (without merged dev), as we should only publish those branches, not the whole dev as there may be also branches not ready to publish. The official answer from git is to resolve conflicts locally - see link from my last post – Darksymphony Nov 05 '20 at 20:53
  • 1
    @Darksymphony git fetch only gets the status and files from the server. It does not pull it changes into the current branch. I think I'm using my dev branch as you use the release branch, as something which is ready for production usually residing on the QA server. And yes that's a great idea! Resolving conflicts locally. I must have missed that last link. – Shell Code Nov 05 '20 at 20:59
  • Definitely I will try to study how to resolve conflict via command line or locally, but I know that there is a conflict only after creating a pull request on git. Not sure how it can be solved via command line if I can't see the differences in the file. – Darksymphony Nov 05 '20 at 22:34