gitpull-requestgit-merge-conflict

Git Merge takes all files into the PR after fixing conflicts


I have been looking for this, but not able to find a concrete answer which works.

Say I am working on my branch - branchA and I have a Pull request (PR) ongoing with it. Some updates happen on the master and I need to merge those changes

Scenario 1 - No merge conflicts

git switch master
git pull
git switch branchA
git merge master

No merge conflicts, commit created automatically, all good and I push the commit. With this no files are added to my PR and the PR is clean only with my files.

Scenario 2 - With merge conflicts

git switch master
git pull
git switch branchA
git merge master

I get merge conflicts, I resolve them manually. But now the problem is, I do

git status

And I see all the files from master are green and I have to selectively remove all files except those files that needs to be part of my PR. Even after this I end up with untracked files, which is not good to have since I would get PR comments and I will have to do the selective file handling again when I push.

Question - After manually merging the conflicts, what are the next steps to do to push the changes that only belong to my PR ?


Solution

  • And I see all the files from master are green and I have to selectively remove all files except those files that needs to be part of my PR.

    No, you don't. If that's what you've been doing, it's a terrible mistake and you need to stop it immediately. You're way overthinking this (or, looking at it another way, underthinking it). In fact, almost everything in the question is a misconception, so there's a lot to straighten out here.

    How to merge master

    To merge master into the feature branch branchA, do not switch to master and pull. In fact, I would argue, in a PR-based workflow, you should just about never need to say pull (and you shouldn't even have a local master). Instead, just stay where you are, on branchA, and say:

    git fetch
    get merge origin/master
    

    How to resolve merge conflicts

    Let's say you merge and you get a conflict in file myfile.txt. OK, stop work in Git. Whip out a text editor and open myfile.txt. Edit it to remove the merge conflict markers, resolving the content as desired. Save the file and close your editor. Now, in Git:

    git add path/to/myfile.txt
    

    Do that for every conflicted file. When you've done that, say:

    git merge --continue
    

    The merge will finish; you will probably be called upon to supply a commit message for the merge commit.

    NOTE: Do not mess with the content of the merged files, or of the index, or of the working tree, in any other way during the merge! Doing that is called an "evil merge" and is an incredibly bad idea.

    What to do after the merge is over

    After the merge is over, just push:

    git push origin @
    

    What else to do

    Nothing. That's all. Don't worry; the material from master, which is of course part of what gets merged, will not appear in the PR at the remote site.

    That's because the "content" of the PR is obtained by doing a triple-dot diff. It consists exactly of the state of your feature branch, as a diff since the point where it diverged from master, but without any content that is already in master. All the stuff that comes over from master as part of the merge is thus "erased" from the PR's statement of what's in the PR — which is exactly what you want.

    Last thoughts

    You said:

    what are the next steps to do to push the changes that only belong to my PR

    Again, that's a complete misconception. The remote site, where the PR "lives", will describe the "changes", because that is what humans like to know about in this situation; and it will describe them correctly. But Git does not "push changes". Git knows nothing about "changes". Git knows nothing about PRs. Git traffics in just one thing: commits.

    A commit is not a set of changes. It is not a subset of your files. It is a complete snapshot of the entire state of all the tracked files in the working tree. That is all it is.

    And commits are the basis of everything else you do in Git. When you merge, you merge commits. When you push, you push commits. When you fetch, you fetch commits. When you have a branch, it is the name of a commit. And so on.