2

I have a local branch that needs to be merged with the remote. Both remote and local branches have lots of different commits (on various files). Is it possible to identify and merge the files which have only fast-forward type (remote-side) changes? I would like to deal with all the other changes manually. git merge --ff-only does not merge anything when there is any two-sided changes.

Edit: I would like to make the question more clear. Let's say the original files (on parent node) are file1, file2, file3, file4. My local branch, I modified file1, file2, deleted file4, added file5. In their remote branch, they modified file1,file3, deleted file4, added file6. I would like to do the following:

  1. Identify all changes with the information of who made the change (with something like git diff): file1 (both sides) file2, file5 (my side) and file3 and file6 on their side.
  2. Merge only specific one-sided changes (from their side): After I merge my local with the remote, I should have file3 and file6 as modified in their remote branch and file1,file2,file5 as modified in my local branch. I will deal with file1 and file5 vs file6 manually.
Armut
  • 969
  • 8
  • 22
  • Will you please reconcile "After I merge [] I should have [] file1,file2,file5 as modifiied in my local branch" above with "[I want only other side changes not mine](http://stackoverflow.com/questions/24348953/is-it-possible-to-do-a-partial-merge-with-ff-only-changes/24357649?noredirect=1#comment37665629_24357649)" below? – jthill Jun 23 '14 at 06:17
  • My bad. I initially thought about asking two different ways of merging, that is one as stated above and the other one where all my local changes are reverted while all remote changes are accepted. Sorry for the confusion on my side. So, your answer is good for the former one as in item 2 above. Do you have any idea about item 1? – Armut Jun 23 '14 at 06:59

2 Answers2

2

git read-tree is the low-level merge prep, everything short of actual conflict resolution. One easy way is

git merge-s ours --no-commitother# no-op merge, just sets up parents
git read-tree -um $(git merge-baseHEADother) HEADother
#manual resolution here
git commit

which leaves everything with different new content in both branches for manual resolution but accepts all at-most-one-new-version files. You might want read-tree's --aggressive option, to handle whole-file deletion and addition as an ordinary change.

As a safety play for an unlikely case, check the output of git merge-base--all HEADother. If that shows multiple bases (as it will when the most recent merges on each branch have common parents), git's (default) "recursive" merge strategy would have derived base content that produces better automatic resolution results than the actual bases, and you might want to take extra care with your manual resolution.

jthill
  • 55,082
  • 5
  • 77
  • 137
  • Thanks for the hint on `read-tree`. Could you let me know why you use ours and also clarify `other` and `$( git merge-base HEAD other) HEAD other`. I have also updated the question to make it more clear. – Armut Jun 23 '14 at 04:48
  • `other` is just the other branch name. As a favor, can you be more concrete about what's giving you difficulty with the `-s ours` and the `read-tree` args? I'd rather answer concrete questions than blindly paraphrase whole manpage sections. – jthill Jun 23 '14 at 05:26
  • `$(git merge-base HEAD other)` refers to parent, or let's say original where two branches originated.`HEAD` my local branch. `other` remote branch. Is this the right interpretation? I didn't understand why you use `-s ours` when you merge, I want only other side changes not mine. – Armut Jun 23 '14 at 05:38
  • " I didn't understand why you use `-s ours`": it was to create those parents, that are used next in the `git read-tree` merge command. – VonC Jun 23 '14 at 05:42
  • Thanks @VonC. But, doesn't it result in a merge that will include all my one-sided changes? – Armut Jun 23 '14 at 05:51
  • @Armut not if you do a `git read-tree -um` just after the `git merge`. – VonC Jun 23 '14 at 06:07
0

You could declare a merge driver similar to "Git - how to force merge conflict and manual merge on selected file".

That driver would use git merge-file, except you can test its exit value:

The exit value of this program is negative on error, and the number of conflicts otherwise.

If the merge was clean, the exit value is 0.

So if it returns 0, you can let the merge continue (your merge driver exits with status '0')

In any other cases, you will force a manual merge by exiting with a status '1'.

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