3

I am trying to practice using xargs. I tried the following, passing the SHA1 via xargs:

$ git show SHA1 --name-only

I also tried:

$ git log --author=jim --grep="patch" |head -n 1|cut -d ' ' -f2|xargs {} git show {} --name-only

It returned xargs: {}: No such file or directory

So, I moved on to this:

$ git log --author=jim --grep="patch" |head -n 1|cut -d ' ' -f2|xargs -0 -I {} git show {} --name-only

Which returned:

fatal: ambiguous argument 'a1237ac27321f2daea365787664e4119b339c483': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

The SHA mentioned is the correct one, but I don't understand why this does not work either

4

xargs -0 means to use only null bytes to separate input records, and include newline characters and other whitespace in the input. You're going to have a newline at the end of the revision output there, which head and cut will leave there, and which will be included in the argument given to git. Git doesn't like that. I think you've edited the newline out of the error message, but it is actually a part of the message here and what's causing your problem.

Removing -0 makes your command work for me. Given the input you're generating, the default newline-separated behaviour of xargs is safe.

You don't really need to use -I {} in this case either — git is quite happy to have the revision as the last argument, but I guess you're using it for practice's sake. By default, xargs just puts the arguments at the very end of the given command (unlike find -exec, which uses the {} substitution).


You're also doing a bit much work, though, with your cut. Git is more than capable of arranging its output in a format you can use with xargs. Using the --pretty=tformat... option we can make it spit out just the SHA1 hashes, one per line:

git log --author=jim --grep="patch" --pretty=tformat:'%H'

will output all the hashes of matching commits in your repository, one per line. --pretty sets the output formatting; tformat means to put a newline at the end of every hash; '%H' means the hash.

You can pipe that into xargs, and since the entire input is "clean" [a-f0-9] you can use it with the default line-separation

  • But why doesn't the first version without -0 and without -I work? – Jim Jul 8 '14 at 12:42
  • xargs doesn't use {} for substitution. That's find. xargs just puts them at the end by default, unless you use -I. – Michael Homer Jul 8 '14 at 19:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.