1

Suppose I've removed the text 'foo' from a lot of files in my repository, and I want to commit that change.

But there are also lots of unrelated changes.

How do I find just those files and stage them?

SwissCodeMen
  • 4,222
  • 8
  • 24
  • 34
joachim
  • 28,554
  • 13
  • 41
  • 44
  • For bonus points: is there a way to stage JUST those diff chunks which have that change? – joachim Aug 02 '22 at 10:39
  • 1
    Getting just the diff hunks is a lot more difficult. You've provided an answer that works for the entire files. Consider also `git diff-files` to compare index (staged copy) to working copy, as a plumbing command; you should be able to combine this with `-S foo` to find places where the count of `foo`s has changed, and post-process that to get just removals. – torek Aug 02 '22 at 11:04

1 Answers1

1

git grep's --cached option appears to search in changes that are UNstaged (which looks like a bug, as it's not what its docs say, and it's not how git diff treats its --cached option).

Doing git grep --cached foo gets:

somefile.txt: foo: true

To stage these, use cut to extract just the filenames: git grep --cached foo | cut -d : -f 1:

somefile.txt

and then xargs to stage that list: git grep --cached foo | cut -d : -f 1 | xargs git add.

joachim
  • 28,554
  • 13
  • 41
  • 44
  • 1
    Use `git grep -l` to list just the file names. (Note that they're relative to the current subdirectory within the repository, by default.) You are in fact searching the *staged* blobs, which *do* have the `foo: true` line here. It's the diff from staged to unstaged where `foo` has been removed, and searching the working tree, you won't find `foo`. – torek Aug 02 '22 at 11:00