1

I have two branches (branch A and B) with different files in each.

I have created new pull request to merge the code from branch A to B.

I expected that those changes which are not present in branch B but present in branch A will be merged and only branch B will updated with all the code.

But I have observed that merge request has even updated branch A with the code that is only present in branch B.
Thus both are holding all the code now. How can this be avoided?

I expect to hold all the code in Branch B but the Branch A should be left as it is.
Is this possible in Git?

user1122
  • 47
  • 1
  • 6
  • 2
    What you are describing is not possible. Merging A into B cannot result in A getting changes from B. You should include the exact steps you have taken here. – Tim Biegeleisen Jul 13 '20 at 04:50
  • 1
    I agree with Tim, that isn't possible as you described it. If you provide us with `git log --graph --decorate --oneline` which shows both A and B and the merge that should help us figure out what happened. Could you also verify that the "base" and "compare" branches on your Pull Request are correct? – Schwern Jul 13 '20 at 05:00
  • You are correct. Have just checked the git log and have observed my bad mistake of placing incorrect base and compare branches. Thank you Tim and Schwern :) – user1122 Jul 13 '20 at 05:41
  • @Raghu Glad you got it worked out. – Schwern Jul 13 '20 at 06:54

2 Answers2

2

This could only happen is somehow the pull request was done from B to A (instead of A to B)

Meaning the base branch for the PR was incorrect.

As you can see in "About pull request merges", only the destination branch is impacted.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
2

It's important to realize that in Git, branches are to some extent an illusion. Git isn't about branches. Git is about commits.

When you use git merge—or GitHub's clicky buttons to achieve a merge—what you get is, in general, a new commit. This new commit does not—and literally can not—change any existing commits at all.1 It is a new commit, so it has a new, never-seen-before hash ID.

Meanwhile, branch names themselves just commit object hash IDs. To put it more precisely, each name holds one hash ID. This commit is the last commit that is considered "on the branch". Other, earlier commits can be on this same branch as well, and any one commit can be—and many are—on many branches at the same time.

The process of making a new commit, in Git, is done either "on a branch"—in a situation in which the special name HEAD contains a branch name—or in "detached HEAD mode", where the special name HEAD contains a raw hash ID. If done "on a branch", the last step of creating a new commit is for Git to write the new commit's hash ID into the current branch name, so that this branch name now identifies the new commit. Since no other branch name is updated at this time, the new commit is only on this branch.

This applies to git merge too.2 So if you are on branch B and run git merge A, the new commit's hash ID is written to the name B. This means that branch B has the new commit as its final commit. The new commit, however, has not just the usual one parent, but instead has two: the first parent is the usual first parent, while the second parent is the tip commit of branch A. So now, all the commits that were only on branch A before, are now on both branches. But the name A is not updated, so the new merge commit is not (yet) present on branch A.

It is now possible to move the name A such that the merge is on both branches—but you must do that as a separate step, if you want to do that.


1This is due to a fundamental property of all Git objects: a Git object's ID is a cryptographic hash of its content. If you take the content out of some existing object, change it, and put it back into Git, what you get is a new and different object with a new and different hash ID. The old object is still there, under its old hash ID, unchanged.

2This paragraph describes true merges as performed by git merge --no-ff or git merge that requires a true merge. With command line Git, git merge --ff-only or git merge that otherwise allows a fast-forward operation does not make a new commit after all.

When using GitHub to merge (but not for "rebase and merge" or "squash and merge"), the GitHub interface makes a true merge even if a fast-forward operation is possible.

torek
  • 448,244
  • 59
  • 642
  • 775