1

This sounds like a basic problem, but I can't seem to find a similar question. Maybe I am searching with wrong keywords... Please point me to duplicates if any.

I have 2 branches in my remote reposiroty mybranchX, mybranchY.
Both the branches have a set of separate commits like

mybranchX : commitXA--commitXB--commitXC--commitXD--commitXE--HEAD

mybranchY : commitYP--commitYQ--commitYR--commitYS--HEAD

I want to pull commitXC and earlier into mybranchY

How to do this?

P.S. I know git cherry-pick commitXC will pick the code changes of the particular commit. But I want the entire history till commitXC :

commitXA--commitXB--commitXC

and none after that, i.e. I dont want commitXD--commitXE


Needless to say, the actual number of commits in my case is large(quite a few dozens), and cherry picking each and every commit is going to be a long task.

crashmstr
  • 26,648
  • 8
  • 59
  • 77
A Nice Guy
  • 2,538
  • 3
  • 27
  • 50
  • Possible duplicate of [How do I merge a specific commit from one branch into another in Git?](https://stackoverflow.com/questions/6372044/how-do-i-merge-a-specific-commit-from-one-branch-into-another-in-git) – ephemerr Mar 05 '18 at 12:10
  • Why can't you just `git checkout mybranchX`, `git merge mybranchY`? – Jonathon Reinhart Mar 05 '18 at 12:28
  • Because I don't want commitXD--commitXE, but i want commitYR--commitYS – A Nice Guy Mar 05 '18 at 12:29

2 Answers2

4

I don't think you are using the right terms. pull is syncing with remote repo and merge the changes.

I believe cherry-pick is what you looking for

git checkout mybranchY 
git cherry-pick commitXC

Update To take all the changes commitXA--commitXB--commitXC you can merge them

git checkout mybranchY 
git merge commitXC
Igal S.
  • 9,704
  • 4
  • 28
  • 43
1

For this particular case, you just need git merge.

Let's redraw your graph. Instead of:

mybranchX : commitXA--commitXB--commitXC--commitXD--commitXE--HEAD

mybranchY : commitYP--commitYQ--commitYR--commitYS--HEAD

let's use

       A--B--C--D--E   <-- mybranchX
      /
...--*   [this commit and all earlier commits are on BOTH branches]
      \
       P--Q--R--S   <-- mybranchY (HEAD)

as this is (presumably) an accurate representation of the state of the repository and your current branch after you run git checkout mybranchY, which attaches the name HEAD to mybranchY.

(To verify this, compare this horizontal graph drawing with Git's own vertically-oriented drawing as output by git log --all --decorate --oneline --graph. Note that it is important here that the commit I marked * be the actual merge base, i.e., the point where the two branches split apart.)

Since your HEAD denotes commit S and you wish to merge with all commits up to and including commit C, find a name that identifies commit C, such as its raw hash ID or the string mybranchX~2. The ~2 suffix tells Git to count backwards (leftwards, in this drawing) two commits (following the first parent links, but these commits have only a first parent). Since mybranchX names commit E, if we count back twice, we get to commit C.

Then simply run:

git merge mybranchX~2  # or git merge <hash-id>

which will start the merge process. Git will compare commit *, the merge base, to commit C to see what they did. It will compare commit * to commit S to see what you did:

git diff --find-renames <hash-of-*> HEAD        # what we did: --ours
git diff --find-renames <hash-of-*> <hash-of-C> # what they did: --theirs

Git will now combine these two diffs, applying the changes to commit *. If all goes well, it will make a new merge commit automatically. The two parents of the new merge commit—I will call it T here—will be commit S (as its first parent) and commit C (as its second):

       A---B---C--D--E   <-- mybranchX
      /         \
...--*           \
      \           \
       P--Q--R--S--T   <-- mybranchY (HEAD)

Hence T~1 is S, T~2 is R, and so on. You can now name commit C by either mybranchX~2 (count back two first-parent links) or by mybranchY^2 (take the second parent of commit T). Commits A, B, and C are now on mybranchY as well as still being on mybranchX. Commits D and E are only on mybranchX.

torek
  • 330,127
  • 43
  • 437
  • 552