git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: git working tree status

From
MCMike Clarke <clarkema@gmail.com>
Date
Oct 27, 2008, 11:37 UTC
Message-ID
<73f525b90810270437h15479a27j94f45e138449722b@mail.gmail.com>
In-Reply-To
<73f525b90810270412o234bc88by16c67df9df067649@mail.gmail.com>
On Sun, Oct 26, 2008 at 11:23 PM, Miklos Vajna <vmiklos@frugalware.org> wrote:
> On Sun, Oct 26, 2008 at 09:54:03PM +0000, Mike Clarke <clarkema@gmail.com> wrote:
Show 24 quoted lines
>> b) all changes checked in, but there are some stashes; or
>
> git update-index -q --refresh
> test -z "$(git diff-index --name-only HEAD --)" && echo "everything committed"
>
>> c) 'dirty' in some way -- new files, uncommitted changes, etc.
>
> git update-index -q --refresh
> test -z "$(git diff-index --name-only HEAD --)" && echo "dirty"
>
> see GIT-VERSION-GEN in git.git
>
>> 1) Is there already some way of doing this that I've overlooked?
>> 2) Would the preferred approach be an option (git status --is-clean)
>> or a sub-command (git is-clean)?  A sub-command would probably result
>> in cleaner internal code, but would also clutter the interface.
>
> I guess you overlooked the fact that plumbing is supposed to be used
> from scripts and porcelain by the users. git status is porcelain, so
> in general just don't use it from scripts.
>
>> 3) Is a patch for such a feature likely to be accepted?
>
> I don't think so, see above.

Thanks for the pointers! To add a bit of context to the original post, we deal with a lot of small project repositories at work, and we swap between them quite a lot. As a result, management of the repositories can be somewhat burdensome; it's easy to leave a tree in the middle of something, and then forget.

To get around this, I'm writing a Perl script, called git-map, which
a) can be used to apply a given git command (say, 'fetch') to a whole group of
   repositories
b) gives you an overview of the state of all your repos.  For example:
546 clarkema@swiss:~/git> git-map summary
 C /home/clarkema/git/apollo
 C /home/clarkema/git/cerebro
 C /home/clarkema/git/dionysus
 S /home/clarkema/git/dotfiles
 C /home/clarkema/git/packaging/eAccelerator.git
 C /home/clarkema/git/programmes/cleo-vc-doc-version-2_0
 D /home/clarkema/git/programmes/cumbria-libraries/cumbria-libraries-version-1_0.git
 C /home/clarkema/git/services/cleo-service-loadbalancers.git
 C /home/clarkema/git/services/cleo-service-proxypac.git
 C /home/clarkema/git/services/cleo-service-vc.git
 C /home/clarkema/git/services/cleo-service-webgw.git
 C /home/clarkema/git/software/configutils.git
 C /home/clarkema/git/software/listbuilder.git
 C /home/clarkema/git/software/luns-sdp
 C /home/clarkema/git/software/proxy-pac.git
 C /home/clarkema/git/software/sgdsync.git
 D /home/clarkema/git/software/vc-billing
 C /home/clarkema/git/toybox/git-contrib-import

This shows me that most of me repos are clean. 'dotfiles' has a stash on it, and two others have uncommitted changes. The code I'm currently using, based on the comments above, is:

sub cmd_summary
{
   foreach my $tree ( sort @trees ) {
       local $CWD = $tree;
       system( "$GIT update-index -q --refresh" );
       # The redirection is somewhat dirty; but is designed to eat the error
       # message that occurs if there is no HEAD yet.
       system( "$GIT diff-index --quiet HEAD 2> /dev/null" );
       if ( $CHILD_ERROR == -1 ) {
           print STDERR "Failed to execute $GIT: $OS_ERROR\n";
       }
       elsif ( $CHILD_ERROR & 127 ) {
           printf STDERR "Child died with signal %d\n", ( $CHILD_ERROR & 127 );
       }
       else {
           my $exit_code = $CHILD_ERROR >> 8;
           print " ";
           if ( $exit_code == 0 ) {
               if ( have_stash() ) {
                   print colored ['yellow'], "S";
               }
               else {
                   print colored ['green'], "C";
               }
           }
           elsif ( $exit_code == 1 ) {
               print colored ['red'], "D";
           }
           else {
               print colored ['red'], "?";
           }
           print " $tree\n";
       }
   }
}
sub have_stash
{
   my $ref_stash = 'refs/stash';
   system( "$GIT rev-parse --verify $ref_stash > /dev/null 2>&1" );
   if ( $CHILD_ERROR == -1 ) {
       print STDERR "Failed to execute $GIT: $OS_ERROR\n";
   }
   elsif ( $CHILD_ERROR & 127 ) {
       printf STDERR "Child died with signal %d\n", ( $CHILD_ERROR & 127 );
   }
   return ( $CHILD_ERROR >> 8 ) == 0;
}
Any comments or suggestions to improve the above would be gratefully received!
Thanks,

-- Mike Clarke

Previous: Miklos Vajna
Message 4 of 4 in “git working tree status”
  1. Mike ClarkeOct 26, 2008
  2. Miklos VajnaOct 26, 2008
  3. Miklos VajnaOct 26, 2008
  4. Mike ClarkeOct 27, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.