Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to merge only some files?

I am trying to merge part of a commit from the default branch (not all files and parts of other files) to a named branch. I tried graft, but it just takes the whole commit wthout giving me a chance to choose. How would this be done?

Example:

A---B---C---D
      \
       -E---(G)

G does not exist yet. Lets say C and D each added 5 files and modified 5 files. I want G to have 2 of the 5 files added at C, all the modifications to one of the files and one modification to another file. I would ideally like it to also have something similar from D.

When I selected graft to local..., all I got was the whole C change-set. Same for merge with local...

like image 978
Baruch Avatar asked Jun 11 '13 21:06

Baruch


People also ask

Can you merge just one file in git?

We can use git checkout for far more than simply changing branches. If we supply it with a branch name and a file, we can replace a corrupted or broken file. Instead, if we want to pass some of the changed content we can use the --patch flag to manually merge an individual file.

Can you cherry pick a merge?

Usually you cannot cherry-pick a merge because you do not know which side of the merge should be considered the mainline. This option specifies the parent number (starting from 1) of the mainline and allows cherry-pick to replay the change relative to the specified parent.


1 Answers

The unit of merging is a whole changeset, so C and D should have been committed in smaller pieces. You could now merge the whole thing and revert some files, but this will have the result that you won't be able to merge the rest later-- they're considered merged already.

What I'd do is make a branch parallel to C-D, rooted at B in your example, that contains copies of the changes in C and D but splits them into coherent parts. Then you can merge whole changesets from that, and close (or or perhaps even delete) the original C-D branch.

      C---D
     / 
A---B--C1--D1--C2--D2    (equivalent to C--D)
     \   
      E---(G?)

In the above, C1 and C2 together are equivalent to C. While I was at it I went ahead and reordered the four new changesets (use a history-rewriting tool such as rebase), so that you can then simply merge D1 with E:

      C---D
     / 
A---B--C1--D1--C2--D2
     \      \
      E------G

If reordering the new changesets is not an option, you'd have to do some fancy tapdancing to commit the partial changesets in the order C1, D1, C2, D2; it's probably a lot less trouble to use graft (or transplant) to copy the changes that you're not allowed to merge separately. E.g., in the following you can still merge C1, but then you need a copy of D1 (labeled D1') since there's no way to merge it without pulling C2 along with it.

      C---D
     / 
A---B--C1--C2--D1--D2
     \  \
      E--G1--D1'
like image 114
alexis Avatar answered Sep 28 '22 18:09

alexis