3

I started to use git cherrypick; and as a result of that I am now (very often) facing situations that give me a lot of files marked as "deleted by us".

I saw this other question, that mentioned how can use git ls-files --deleted to get a flat file list; which can then be piped to xargs rm.

Problem is: --deleted doesn't list those "deleted by us" files.

So, long story short: what is the easiest/straight forward way of removing the "deleted by us" files?

( I really liked the git ls-files approach; as that doesn't require sed/awk magic; so there is also no worrying about getting quotes right ...)

Update; just to explain why this not some "XY problem" situation:

  • actually I am using git svn; to connect to some backend SVN server
  • SVN trunk contains directories A, B, C
  • I am making changes on trunk that affect all three directories
  • But: the git where I run the cherry-pick ... actually resembles "product branches" created on the SVN server. These "product" branches do only contain subsets (so one has A and B; the other has B and C).
  • I tried hard; but I really couldn't get to create a git svn clone that contains SVN trunk AND SVN product branches at the same time
Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248

2 Answers2

1

I don't know of a "simple" command like that for this but you can use git status itself for this.

while read -d '' status file; do
    case "$status" in
        (D?)
            echo "Removing $file that was deleted by us."
            #rm "./$file"
            ;;
    esac
    #printf 'status: %q\nfilename: %q\n' "$status" "$file"
done < <(git status -sz)

To match only DU and not D? (D single-character) change the case pattern appropriately.

To run rm only once use files+=("$file") in the if block and then rm "${files[@]}" at the end.

Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
  • Doesn't work. When I run the command, I get output like: `filename: /some/real/file \n File was deleted by us.\n status: DU` (\n inserted by mself to indicate the line break). – GhostCat Mar 23 '16 at 20:05
  • What about that didn't work? (Assuming you reported the output out of order.) This snippet should just output each file with a difference and *also* output `File ... was deleted by us.` for each file that was deleted by us. – Etan Reisner Mar 23 '16 at 20:12
  • The point is: it prints "File was deleted by us". The $filename seems to be empty. And, i found a nice solution in the meantime; that is good enough for the filesets we are using `git status --porcelain | grep "DU " | cut -d " " -f2 | xargs git rm` ( based on the fact that git status actually delivers different output (D vs DU) when called with that option) – GhostCat Mar 23 '16 at 20:21
  • Oh, that's because I typo'd the variable name. Use `$file` in the message instead and it'll work. – Etan Reisner Mar 23 '16 at 20:23
  • `-z` is `--porcelain -z` and yes, you can use `grep` and `cut` and `xargs` to do this or you could use a shell loop and either call `rm` N times or collect the filenames in an array and call `rm` once at the end. – Etan Reisner Mar 23 '16 at 20:24
  • So, if you update your answer, I am still inclined to accept it ;-) – GhostCat Mar 23 '16 at 20:28
0

To list unmerged files marked as "deleted by us" the following command can be used:

git status --porcelain --untracked-files=no | sed --silent 's/^DU //p'

or a slightly shorter variant:

git status --porcelain -uno | sed -n 's/^DU //p'

In the output of the command git status --porcelain the unmerged "deleted by us" files are marked with DU.

In sed, the option -n suppresses printing unless explicit requested, the command s/X/Y/ substitute X (a regexp) by Y, and due to the flag p the modified line is printed.

ruvim
  • 7,151
  • 2
  • 27
  • 36