How could I modify git status output to treat each path as a variable which I can use to perform other commands on?
Example:
$ git status
# On branch master
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# {1} modified: path/to/some/file.txt
# {2} modified: path/to/some/other/file.txt
# {3} modified: some/really/long/path/to/some/file.txt
$ git add {2}
$ git status
# On branch master
#
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: path/to/some/other/file.txt
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# {1} modified: path/to/some/file.txt
# {2} modified: some/really/long/path/to/some/file.txt
This might be useful when 开发者_如何学Cdealing with lots of files or long file paths. I suspect it's very tricky (or impossible) to do though?
That looks like a git add --interactive
with the update mode
From the git add
man page:
update
This shows the status information and issues an "
Update>>
" prompt.
When the prompt ends with double>>
, you can make more than one selection, concatenated with whitespace or comma.
Also you can say ranges. E.g. "2-5 7,9
" to choose 2,3,4,5,7,9 from the list. If the second number in a range is omitted, all remaining patches are taken. E.g. "7-
" to choose 7,8,9 from the list. You can say * to choose everything.What you chose are then highlighted with
*
, like this:
staged unstaged path
1: binary nothing foo.png
* 2: +403/-35 +1/-1 git-add--interactive.perl
If you usually change some file type, or a specific path, use ls-files then grep them:
git ls-files -o | grep some-part-of-the-path-or-extension | xargs git add
More on this here: http://www.kernel.org/pub/software/scm/git/docs/git-ls-files.html
You can alias that as a command if you like. This will be much faster than having to read what add --interactive
gives you and then making sure you punch in the corresponding ones.
Then there is git gui
as well if you've got a terrible amount of them.
Hope this helps.
Please clarify?
You still have to type {1} or {2} which is clumsy and very error prone.
You might wish to implement a kind of fuzzy/incremental lookup in your own favourite language. Or just make sure that all the 'cruft' that you are apparently never interested in updating isn't in the list in the first place (.gitignore)
Here is a rough stab at a quick bash function named 'scommit' (smart commit ?):
#!/bin/bash
function scommit()
{
set -e
local PS3='add (or Ctrl-D)? '
local arguments
if [[ $# -lt 1 ]];
then arguments='.*'
else arguments=( "$@" )
fi
function grepmodified() { git ls-files -m | egrep "${arguments[@]}"; }
function pickone()
{
if [[ $# -ge 1 ]]; then
select path in "$@";
do git add -- "$path"; break;
done;
else
return 1;
fi
}
while pickone $(grepmodified); do continue; done
}
You can use it as follows (note how the -i flag is passed to egrep making it case-insensitive):
$ scommit -i bi
1) main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Gui.OptionPanels.KeyBindingsPanel.cs
2) main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Projects.OptionPanels.CombineBuildOptionsWidget.cs
add (or Ctrl-D)? 1
1) main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Projects.OptionPanels.CombineBuildOptionsWidget.cs
add (or Ctrl-D)? 1
I had the same itch as yours a while back and I wrote git-number to scratch it. It does exactly what you want. Do read the "Caveat" section in the README though.
Quick tutorial:
$ alias gn='git number'
$ alias ga='git number add'
$ gn
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
#1 .README.swp
#2 README
$ ga 2
git add README # <- It does this in the background
You can run arbitrary command on the files too:
$ gn -c ls -l 1 2
That will run ls -l .README.swp README
精彩评论