Skip to content
Advertisement

What’s the easiest way to use the output paths from a git command in a subsequent git command?

I far too frequently use the mouse to do things like this:

/home/me-$ git log --name-status -1  
commit a10e63af1f4b1b2c28055fed55d4f2bb3225a541
Author: Me <me@me.com>
Date:   Tue Aug 18 13:04:04 2015 -0400

    XYZ-376 make ctors public

M       x/y/z/Class1.java
M       x/y/z/Class2.java

/home/me-$ git checkout -- x/y/z/Class2.java  # <-- copy/paste with the mouse

I know that some git commands accept wildcards, and this mitigates this problem somewhat, but I’m wondering if there is a way do specifically reference pathspecs, etc. from previous commands.

How can I run commands like this without using the mouse, and without retyping long paths by hand?

Advertisement

Answer

I typically use a subshell ($(<command in subshell here...>)) for this.

For example, sometimes I had many files deleted and I had to git rm every one of them.

There’s the command git ls-files --deleted that returns the names of all the missing files. I can combine it with git rm like this:

git rm $(git ls-files --deleted)

This is somewhat a bad example, because (as I discovered later), this operation can be achieved much easier with git add --all. But I think it illustrates the point.


In your case, if you wanted to checkout all files that have been changed in the previous commit, it would be hard to parse the output of git log --name-status, because it contains additional information, but you could use something like git diff HEAD^ --name-only instead.

So:

git checkout $(git diff HEAD^ --name-only)

will do it in your example.

One nice thing that I noticed using the $(...) syntax is that it works both in Bash and in PowerShell.

Advertisement