开发者

Add variables to git status output

开发者 https://www.devze.com 2023-02-17 17:23 出处:网络
How could I modify git status output to treat each path as a variable which I can use to perform other commands on?

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

0

精彩评论

暂无评论...
验证码 换一张
取 消