1

Is there a way to say 'for all remaining merge conflicts', select 'ours' as the merge conflict resolution? In my case 'ours' is also a deletion, not an edit.

I'm using Git Extensions, with a little bit of command line work. When I do a merge, I go through a series of complex processes in order to resolve the merge. For one process there is always going to be a set of files that will be conflicted in the merge, because on my branch, I'm deleting them.

Typically, I run the merge, see that I have conflicts, then go and delete the specific files from my repository, while also appropriately merging some other files that were in conflict.

Then, when I am sure my local file system is correct, I have gone in to Git Extensions, and selected merge on every merge conflicted file, and selected 'ours' (Deleted)...one-by-one.... (Git Extensions doesn't allow me to multi-select). There are a lot of files... so I'm looking for a way that I can essentially do a bulk 'Merge -> Ours' for all remaining merge conflicts once I've finished my other merges.

Sean Holmesby
  • 2,135
  • 3
  • 23
  • 34

1 Answers1

0

I have no idea of how to do this in the GUI, but on the command line:

git checkout HEAD -- path1 path2 path3 path4 ...

(takes the "ours" version) or:

git checkout MERGE_HEAD -- path1 path2 path3 path4 ...

(takes the "theirs" version).

If the "ours" version is a deletion (as in your description), just:

git rm path1 path2 ...

to set up the index with "resolution is to remove file".


Edit (after two comments) to add: git checkout --ours and git checkout --theirs can also be used in place of git checkout HEAD and git checkout MERGE_HEAD. The difference (there is one) is subtle: when you are in the middle of a conflicted merge, the index contains entries in staging slots 1, 2, and/or 3 for each path for which there is a conflict. For unconflicted paths, the index has only a stage-zero entry. Checking out with --ours or --theirs extracts a staged entry, while checking out from HEAD or MERGE_HEAD extracts a file from the specified commit (more precisely, from the tree associated with the commit).

The stage 1 entry is the merge base, stage 2 is --ours, and stage 3 is --theirs. If the conflict is with modifications, all three staging slots are used. If the conflict is delete-vs-modify, staging slot 1 is in use, but one of the remaining slots is not. If the conflict is create-vs-create, slot 1 is empty while slots 2 and 3 are populated.

Doing a git rm or git checkout clears out the conflict staging slots and populates the normal stage-0 entry with the resolved result. Git permits the final merge commit only when there are no conflicted stages left (git ls-files --stage shows nothing but stage-0).

One of many reasons to hate GUIs is that they may refuse to re-check the index, thinking they know what's best (and they never do). If yours is like this, it may ignore all the CLI resolving you do, and require every resolve to go through the GUI itself.

torek
  • 448,244
  • 59
  • 642
  • 775
  • I've seen mention of git checkout --ours, and other methods like yours, but they're all pre-merge (I believe)... whereas I want to still perform the merge.... and after-the-fact (just before committing), I want a 'resolve all remaining conflicts with ours (delete in my case)'. I've tried your answer and it doesn't seem to do this. – Sean Holmesby Apr 13 '16 at 12:57
  • These are all to be done mid-merge (after merging with `--no-commit` or getting a conflict). I've done it (though CLI only, of course) and it works. For modified/deleted conflict cases, you want `git rm`, not just `git rm --cached`, since the work-tree contains the version of the file from whichever side (`HEAD` or `MERGE_HEAD`) kept it. If some GUI does not allow this, the GUI is doing something wrong (e.g., not re-reading the index as needed). – torek Apr 13 '16 at 17:43