views:

43

answers:

4

Hey guys,

I tried to make an alias for committing several different git projects. I tried something like

cat projectPaths | \
xargs -I project git --git-dir=project/.git --work-tree=project commit -a

where projectPaths is a file containing the paths to all the projects I want to commit. This seems to work for the most part, firing up vi in sequence for each project so that I can write a commit msg for it. I do, however, get a msg:

"Vim: Warning: Input is not from a terminal"

and afterward my terminal is weird: it doesn't show the text I type and doesn't seem to output any newlines. When I enter "reset" things pretty much back to normal, but clearly I'm doing something wrong.

Is there some way to get the same behavior without messing up my shell?

Thanks!

+1  A: 

The problem is that since you're running xargs (and hence git and hence vim) in a pipeline, its stdin is taken from the output of cat projectPaths rather than the terminal; this is confusing vim. Fortunately, the solution is simple: add the -o flag to xargs, and it'll start git (and hence vim) with input from /dev/tty, instead of its own stdin.

Gordon Davisson
awesome this worked great for me (mac), though ole tange mentions below it won't work for all versions of xargs. thanks!
initlaunch
A: 

Interesting! I see the exact same behaviour on Mac as well, doing something as simple as:

ls *.h | xargs vim

Apparently, it is a problem with vim:

http://talideon.com/weblog/2007/03/xargs-vim.cfm

kartheek
A: 

The man page for GNU xargs shows a similar command for emacs:

xargs sh -c 'emacs "$@" < /dev/tty' emacs

and says this:

   Launches  the  minimum  number of copies of Emacs needed, one after the
   other, to edit the files listed on xargs' standard input.  This example
   achieves the same effect as BSD's -o option, but in a more flexible and
   portable way.

Another thing to try is using -a instead of cat:

xargs -a projectPaths -I project git --git-dir=project/.git --work-tree=project commit -a

or some combination of the two.

Dennis Williamson
A: 

If you have GNU Parallel http://www.gnu.org/software/parallel/ installed you should be able to do this:

cat projectPaths |
parallel -uj1 git --git-dir={}/.git --work-tree={} commit -a

In general this works too:

cat filelist | parallel -Xuj1 $EDITOR

in case you want to edit more than one file at a time (and you have set $EDITOR to your favorite editor).

-o for xargs (as mentioned elsewhere) only works for some versions of xargs (notably it does not work for GNU xargs).

Watch the intro video to learn more about GNU Parallel http://www.youtube.com/watch?v=OpaiGYxkSuQ

Ole Tange