38

I am doing a big merge. A lot of files have been removed from the repo in my branch, and in doing the merge I want to keep this change for all of those files. There are also some files that will need explicit merging and I'm intending to use git mergetool to merge them.

I wish to keep the "deleted by us" change (ie. the files should remain deleted) for all deleted files. Other merge conflicts I want to resolve myself.
Is there a way I can tell git to keep the deleted files deleted?

kris
  • 11,868
  • 9
  • 88
  • 110
  • 4
    `git rm` while a merge is in process should do the trick. – Amber Jun 10 '15 at 02:25
  • How many files are deleted locally but not on the remote? – Tim Biegeleisen Jun 10 '15 at 02:38
  • 1
    @Amber: git rm gives the output "(filename): needs merge" for every single file. – kris Jun 10 '15 at 02:41
  • @TimBiegeleisen : 1082 files – kris Jun 10 '15 at 02:42
  • @user1290746 you could see if `git checkout --ours ` works. – Amber Jun 10 '15 at 02:47
  • @Amber: `git checkout --ours ` gives the output "error: path '(filename)' does not have our version" for each file. – kris Jun 10 '15 at 02:49
  • @user1290746 I suspect `git rm` did what you wanted, and you really need to just commit the result. – Amber Jun 10 '15 at 02:51
  • Possible duplicate of [Git merge strategy to ignore deleted files](http://stackoverflow.com/questions/11331494/git-merge-strategy-to-ignore-deleted-files) – javabrett Feb 16 '16 at 05:26
  • @Amber can you point to the where in the documentation I can make sense of the result of `git rm` and `git add` on a "deleted by us" unmerged path? It was very surprising to me that `git add [path]` puts the path on the stage as a "new file" rather than deleting it. Trying to wrap my head around the intended semantics here. – topher217 Nov 17 '21 at 01:23

6 Answers6

21

Here is a partial solution:

  1. Resolve all non deleted merge conflicts by hand, which you have to do anyway

  2. Type git diff --name-only --diff-filter=U to get a list of all remaining files in conflict. These files must be the ones you want deleted. Save the list of removed files as filesToRemove.txt

  3. Then do cat filesToRemove.txt | xargs git rm to remove all the files.

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • 6
    If you're confident that the list from the git diff command is right, you can skip the temporary file and just run `git diff --name-only --diff-filter=U | xargs git rm` – Ryan Pavlik Aug 05 '16 at 15:37
18

One line fix:

git diff --name-only --diff-filter=U | xargs git rm

Explanation:

Resolve the conflicting modified files first and add them to the staging area, then use the diff-filter to delete remaining unmerged files. Here the documentation (man git-diff):

   --diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]

Select only files that are Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have their type (i.e. regular file, symlink, submodule, ...) changed (T), are Unmerged (U), are Unknown (X), or have had their pairing Broken (B). Any combination of the filter characters (including none) can be used. When * (All-or-none) is added to the combination, all paths are selected if there is any file that matches other criteria in the comparison; if there is no file that matches other criteria, nothing is selected.

Also, these upper-case letters can be downcased to exclude. E.g. --diff-filter=ad excludes added and deleted paths.

Note that not all diffs can feature all types. For instance, diffs from the index to the working tree can never have Added entries (because the set of paths included in the diff is limited by what is in the index). Similarly, copied and renamed entries cannot appear if detection for those types is disabled.

Shubham Chaudhary
  • 47,722
  • 9
  • 78
  • 80
  • 3
    Whenever you have to press the same key a lot of times, you can pipe output from `yes d` into `git rm`. – Gunchars May 23 '16 at 17:01
  • 2
    This is incorrect because it will remove all files that conflict - not just deleted by us, but also both modified, etc. – Ders Oct 01 '21 at 18:05
  • Ideally, you'd like to resolve the conflicts first before deleting the files in the diff. Helps you catch error and see what's required. You can always read the manual and modify as needed: --diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]: Select only files that are Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have their type (i.e. regular file, symlink, submodule, ...) changed (T), are Unmerged (U), are Unknown (X), or have had their pairing Broken (B). Any combination of the filter characters (including none) can be used. – Shubham Chaudhary Oct 05 '21 at 21:18
9

You can resolve this by keeping the edited files by adding them back, and committing them once more:

git add .

or

git add -A

Then commit

git commit

If you want to resolve the confict by removing the files, you have to run git rm instead of git add.

See: Resolving a merge conflict from the command line

androidevil
  • 9,011
  • 14
  • 41
  • 79
2

First, initiate the merge to get into a conflicted state.

Then try this:

git status | grep 'deleted by us' | sed 's/deleted by us: //' | xargs git rm

If you are curious as to how it works, you can build it up command-wise beforehand:

git status
git status | grep 'deleted by us'
git status | grep 'deleted by us' | sed 's/deleted by us: //'

See also the man pages for git status, grep, sed, and xargs.

Ders
  • 1,068
  • 13
  • 16
1

I'll leave the question - because I'm sure there is a good answer - this is what I have done in the mean time:

  1. Do git status to see the list of deleted files (1082) and the number that had merge conflicts (3)
  2. In a text editor manually edit the 3 files that had merge conflicts, and then do git add on them
  3. Create a text file with a line with the letter "d" on each line and nothing else for each of the (1082) files that had been deleted (d.txt)
  4. run git mergetool < d.txt

Not elegant, but faster than pressing the letter "d" and enter 1082 times

kris
  • 11,868
  • 9
  • 88
  • 110
  • 1
    I'm struggling with something totally different right now and chuckled when i realized you counted the number of times you pressed enter before writing this answer. I would have given you a gold if this was on reddit – Irfan Harun Oct 01 '20 at 14:39
0

I also observed

abc.txt: needs merge

when attempting

git rm abc.txt

after cherry-picking and seeing the file in "deleted by us" status.

I ended up with a resolved delete by doing the following:

git add abc.txt
rm abc.txt
git add abc.txt

this adds abc.txt to the staging area (essentially recreating the "deleted by us" file. (which resolves the conflict status)

then deletes the files from the file system

then adds to the stating area the fact that the file is now gone.

there are probably shell tricks to run these 3 commands on your set of 1000+ files without much headache.

there are probably better ways to handle this, but since git rm abc.txt did not work as we expected for our situation(s) i thought i would share an alternative set of commands that seem to have worked without using the mergetool.

Brian Davis
  • 345
  • 4
  • 9