4

I'm doing a rebase where I would like to always take the conflicting files as-is from the branch A.

on branch A

git rebase -X theirs branchQ

( According to Is there a "theirs" version of "git merge -s ours"? and Choose Git merge strategy for specific files ("ours", "mine", "theirs") : "theirs" should mean "use the versions from A". In rebase the meaning of theirs and ours are reversed with respect to a merge )

But, I still get conflicts for files that were modified and deleted. I would like to go with the contents for A all the time.

git status

Unmerged paths:
  (use "git reset HEAD <file>..." to unstage)
  (use "git add/rm <file>..." as appropriate to mark resolution)

        deleted by them: A/XB.cs
        deleted by them: A/YB.cs
        deleted by them: B/XD.cs
        deleted by them: B/YD.cs

and MANY more.

I can fix this by git rm A/XB.cs etc, but how can I accept all these deletions (and all other changes from branch A)? (It's a 28 stage rebase, so I'm looking for automation)

With respect to the common parent of branches A and branchQ, branchQ contains only line-ending normalizations, not new or deleted files.

Johan Lundberg
  • 26,184
  • 12
  • 71
  • 97

2 Answers2

1

The short answer is that -X arguments have no effect at all on what I call high level conflicts. See "-X theirs" option does not seem to work with certain Git conflicts and also What are the reasons and cases that cause git merge conflicts?

I do not have a canned script that will do this for you, but experiment with:

git ls-files --stage

Note that files that were "deleted by them" will exist as entries in staging slots 1 and 2 but not in slot 3. These are the names to pass to git rm to tell Git to remove the stage 1 and 2 entries.

For a description of how merge uses the four staging slots allowed for each file entry in the index, see How do contents of git index evolve during a merge (and what's in the index after a failed merge)?

torek
  • 448,244
  • 59
  • 642
  • 775
  • Thank you. What do you mean exactly by stages and slots? I realized, that what and alternative approach would be to get `filter-branch` to call `git add --renormalize .` but I'm not sure how. – Johan Lundberg Feb 16 '19 at 18:46
  • 1
    Ah, I need another link to where I describe how merge works within the index using the various staging slots... – torek Feb 16 '19 at 18:48
  • Perhaps I was just not brave enough? Now trying `git filter-branch --tree-filter 'git add --renormalize .' parentID..HEAD` – Johan Lundberg Feb 16 '19 at 19:09
  • Yikes, don't do that, it's a waste of time. A `--tree-filter` is meant to modify the tree *in place:* filter-branch extracts all the files to a temporary directory, you modify the files in place, and filter-branch constructs a new commit from whatever files and contents you have left behind. `add --renormalize` doesn't touch the work-tree at all! – torek Feb 16 '19 at 19:12
  • You can, if you like, do something equivalent: use `--tree-filter` to run an editor / cleaner over all the extracted files. Note that $PWD during the tree filter points to some sub-directory deep within a temporary directory that `git filter-branch` has created, *not* to the usual work-tree; this is where Git is going to take the new files to make the new commit. – torek Feb 16 '19 at 19:13
  • :-) Yes. But how do I emulate what `git add --renormalize .` does by doing something to the the working tree? I could start to parse and manipulate files myself but, easy to get wrong. Some context: I use autorclf on windows. The repo contains >100000 files with mixed line endings, and a mix of binary files with various names marked by .gitattributes. Perhap's it's easier to write a script that fetches the content of each commit in turn into an empty directory, adds with git add --renormalize and commits. Or, perhaps I should go with your answer and check "git ls-files --stage". Many thanks! – Johan Lundberg Feb 16 '19 at 19:39
  • In general, unless you control *all* the clones of a repository, using filter-branch is a bad idea anyway. I'd suggest going about this differently, unless this is just your own repository or you're in a position to force everyone else to switch to your rewritten commits. – torek Feb 16 '19 at 19:40
  • Yes, that's clear. This is about a not-yet shared branch. In any case I plan to first/also do a single normalize commit shared to master at a coordinated time. Trying to save that work.... We started to move around directories in that branch, and did not realize that it triggered renormalization due to autocrlf... – Johan Lundberg Feb 16 '19 at 19:43
  • 1
    Ah, OK, then it's safe enough. Still, there's that renormalize issue. There may be a way to adapt the trick I outlined [here](https://stackoverflow.com/a/43464164/1256452). – torek Feb 16 '19 at 19:49
0

I had this same problem and found on Linux for filenames without whitespace I can use:

git status --short | grep "^UD"| cut -d " " -f 2|xargs git add

The status "UD" identifies files that are unmerged, deleted by them.

Brent K.
  • 927
  • 1
  • 11
  • 16