1

So I am trying to clean up a script I have that gets the list of currently staged files using git status to return the relative file path of each staged file. I have looked at the documentation for git status to see if there was a way to get it to return the absolute path of each staged file, but there doesn't seem to be an option for that and git ls files nor git diff will work for this since the specific use case is during a merge.

During the merge, using git diff returns nothing, while git status does show all of the staged files, so I am stuck using git status.

From this list I have, I want to then grep through the list of files to extract any line(s) that contain the string "Path: " and output it. Basically, I have a list of staged .yml files and I want to extract all changes to the Path property in those ymls. Heres what I have so far:

IFS=$'\n'
for file in `git status -s -uno | sed s/^..//`
    do
        relativePath=$(echo $file | sed 's/^[ \t]*//;s/[ \t]*$//' | tr -d '"')
        startPath=`pwd`
        grep "Path: " "$startPath/$relativePath"
    done
unset IFS

Explanation:

git status -s -uno | sed s/^..//

  • I am piping the result of git status into sed to remove any extra whitespace

relativePath=$(echo $file | sed 's/^[ \t]*//;s/[ \t]*$//' | tr -d '"')

  • I echo the file path and pipe it into sed to remove any extra spaces that weren't removed from the initial sed call in the start of the for loop. I then pipe that into tr to remove the first and last double quotes from the string since I need to combine that relative path with my starting path in order to get the complete path.

startPath=`pwd`

grep "Path: " "$startPath/$relativePath"

  • Store the current working directory in a variable, then combine it with our relative path and pass that into grep

This script works and extracts the data that I need, but I feel like there is a much cleaner way I could be doing this. Is there a way I can get git status to return the full path of each staged file so I don't have to have my second $startPath variable that I combine with my $relativePath thats passed into grep?

Oninaig
  • 91
  • 10
  • Here is a question about getting the full paths from git status. https://stackoverflow.com/questions/5237605/how-can-i-run-git-status-and-just-get-the-filenames – Nick Ellis Nov 06 '18 at 16:54
  • `git diff-index --cached --name-only @` – jthill Nov 06 '18 at 17:45

2 Answers2

3

The simplest (correct) way to do this is by using git grep combined with git ls-files. The latter is used as a selector for grep.

Recursive search of modified tracked files using a pattern:

git grep -r 'pattern' -- `git ls-files -m`

Recursive search of all tracked files using a pattern:

git grep -r "pattern" .

Note that this grep search doesn't cover untracked files. You must add them first so that git can see them.

Isaak Eriksson
  • 633
  • 1
  • 7
  • 16
  • Even though this answer doesn't answer the question directly I think that it's the better answer because it solves the problem in a simpler way. – Iker Aug 31 '21 at 13:01
1

Since you probably call git status from inside the repo, all paths will be relative to $PWD, so you can just add it in place, yes?

$: git status -s | sed "s@^[^ ]* @$PWD/@"
Paul Hodges
  • 13,382
  • 1
  • 17
  • 36