{"thread":{"id":"16052","subject":"git working tree status","startedAt":"2008-10-26T21:54:03Z","lastAt":"2008-10-27T11:37:59Z","messageCount":4,"participants":["Mike Clarke","Miklos Vajna"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"94000","messageId":"73f525b90810261454wb902edfk3a696c06ef2148d1@mail.gmail.com","threadId":"16052","inReplyTo":null,"subject":"git working tree status","fromName":"Mike Clarke","fromEmail":"clarkema@gmail.com","sentAt":"2008-10-26T21:54:03Z","receivedAt":"2008-10-26T21:54:03Z","isPatch":false,"sender":{"key":"clarkema@gmail.com","avatar":null},"body":"Hi all,\n\nI'd like a way of getting a simple summary of the status of a working\ntree,  for consumption by other programs rather than humans.\n\nSpecifically, I'd like to know whether the working tree is:\n\na) fully 'clean' -- i.e., all changes checked in, no stashes;\nb) all changes checked in, but there are some stashes; or\nc) 'dirty' in some way -- new files, uncommitted changes, etc.\n\nThe logical way to do this seems to be via an exit code, but the exit\ncode of git status is not currently rich enough.  As a result, I'm\nconsidering the addition of an option to git status -- perhaps\n'--is-clean' -- that would provide the required information.\n\nMy questions are:\n\n1) Is there already some way of doing this that I've overlooked?\n2) Would the preferred approach be an option (git status --is-clean)\nor a sub-command (git is-clean)?  A sub-command would probably result\nin cleaner internal code, but would also clutter the interface.\n3) Is a patch for such a feature likely to be accepted?\n\nThanks,\n\n-- \nMike Clarke\n"},{"id":"94007","messageId":"20081026222335.GJ2273@genesis.frugalware.org","threadId":"16052","inReplyTo":"73f525b90810261454wb902edfk3a696c06ef2148d1@mail.gmail.com","subject":"Re: git working tree status","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2008-10-26T22:23:35Z","receivedAt":"2008-10-26T22:23:35Z","isPatch":false,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"On Sun, Oct 26, 2008 at 09:54:03PM +0000, Mike Clarke <clarkema@gmail.com> wrote:\n> a) fully 'clean' -- i.e., all changes checked in, no stashes;\n\nIn case you want to ignore ignores:\n\n$ git ls-files -o\n\notherwise:\n\ngit ls-files -o --exclude-standard\n\nby 'stashes', I guess you mean those extra files, but using that term is\nconfusing, given that stashes can be listed with git stash list and they\nare actually merge commits (so something totally different).\n\n\n> b) all changes checked in, but there are some stashes; or\n\ngit update-index -q --refresh\ntest -z \"$(git diff-index --name-only HEAD --)\" && echo \"everything committed\"\n\n> c) 'dirty' in some way -- new files, uncommitted changes, etc.\n\ngit update-index -q --refresh\ntest -z \"$(git diff-index --name-only HEAD --)\" && echo \"dirty\"\n\nsee GIT-VERSION-GEN in git.git\n\n> 1) Is there already some way of doing this that I've overlooked?\n> 2) Would the preferred approach be an option (git status --is-clean)\n> or a sub-command (git is-clean)?  A sub-command would probably result\n> in cleaner internal code, but would also clutter the interface.\n\nI guess you overlooked the fact that plumbing is supposed to be used\nfrom scripts and porcelain by the users. git status is porcelain, so\nin general just don't use it from scripts.\n\n> 3) Is a patch for such a feature likely to be accepted?\n\nI don't think so, see above.\n"},{"id":"94008","messageId":"20081026222608.GK2273@genesis.frugalware.org","threadId":"16052","inReplyTo":"20081026222335.GJ2273@genesis.frugalware.org","subject":"Re: git working tree status","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2008-10-26T22:26:08Z","receivedAt":"2008-10-26T22:26:08Z","isPatch":false,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"On Sun, Oct 26, 2008 at 11:23:35PM +0100, Miklos Vajna <vmiklos@frugalware.org> wrote:\n> > c) 'dirty' in some way -- new files, uncommitted changes, etc.\n> \n> git update-index -q --refresh\n> test -z \"$(git diff-index --name-only HEAD --)\" && echo \"dirty\"\n\nI wanted to write '|| echo \"dirty\"', sorry.\n"},{"id":"94042","messageId":"73f525b90810270437h15479a27j94f45e138449722b@mail.gmail.com","threadId":"16052","inReplyTo":"73f525b90810270412o234bc88by16c67df9df067649@mail.gmail.com","subject":"Re: git working tree status","fromName":"Mike Clarke","fromEmail":"clarkema@gmail.com","sentAt":"2008-10-27T11:37:59Z","receivedAt":"2008-10-27T11:37:59Z","isPatch":false,"sender":{"key":"clarkema@gmail.com","avatar":null},"body":"On Sun, Oct 26, 2008 at 11:23 PM, Miklos Vajna <vmiklos@frugalware.org> wrote:\n\n> On Sun, Oct 26, 2008 at 09:54:03PM +0000, Mike Clarke <clarkema@gmail.com> wrote:\n\n>> b) all changes checked in, but there are some stashes; or\n>\n> git update-index -q --refresh\n> test -z \"$(git diff-index --name-only HEAD --)\" && echo \"everything committed\"\n>\n>> c) 'dirty' in some way -- new files, uncommitted changes, etc.\n>\n> git update-index -q --refresh\n> test -z \"$(git diff-index --name-only HEAD --)\" && echo \"dirty\"\n>\n> see GIT-VERSION-GEN in git.git\n>\n>> 1) Is there already some way of doing this that I've overlooked?\n>> 2) Would the preferred approach be an option (git status --is-clean)\n>> or a sub-command (git is-clean)?  A sub-command would probably result\n>> in cleaner internal code, but would also clutter the interface.\n>\n> I guess you overlooked the fact that plumbing is supposed to be used\n> from scripts and porcelain by the users. git status is porcelain, so\n> in general just don't use it from scripts.\n>\n>> 3) Is a patch for such a feature likely to be accepted?\n>\n> I don't think so, see above.\n\nThanks for the pointers!  To add a bit of context to the original post, we deal\nwith a lot of small project repositories at work, and we swap between them\nquite a lot.  As a result, management of the repositories can be somewhat\nburdensome; it's easy to leave a tree in the middle of something, and\nthen forget.\n\nTo get around this, I'm writing a Perl script, called git-map, which\n\na) can be used to apply a given git command (say, 'fetch') to a whole group of\n   repositories\nb) gives you an overview of the state of all your repos.  For example:\n\n\n546 clarkema@swiss:~/git> git-map summary\n C /home/clarkema/git/apollo\n C /home/clarkema/git/cerebro\n C /home/clarkema/git/dionysus\n S /home/clarkema/git/dotfiles\n C /home/clarkema/git/packaging/eAccelerator.git\n C /home/clarkema/git/programmes/cleo-vc-doc-version-2_0\n D /home/clarkema/git/programmes/cumbria-libraries/cumbria-libraries-version-1_0.git\n C /home/clarkema/git/services/cleo-service-loadbalancers.git\n C /home/clarkema/git/services/cleo-service-proxypac.git\n C /home/clarkema/git/services/cleo-service-vc.git\n C /home/clarkema/git/services/cleo-service-webgw.git\n C /home/clarkema/git/software/configutils.git\n C /home/clarkema/git/software/listbuilder.git\n C /home/clarkema/git/software/luns-sdp\n C /home/clarkema/git/software/proxy-pac.git\n C /home/clarkema/git/software/sgdsync.git\n D /home/clarkema/git/software/vc-billing\n C /home/clarkema/git/toybox/git-contrib-import\n\nThis shows me that most of me repos are clean. 'dotfiles' has a stash\non it, and two\nothers have uncommitted changes.  The code I'm currently using, based\non the comments\nabove, is:\n\nsub cmd_summary\n{\n   foreach my $tree ( sort @trees ) {\n       local $CWD = $tree;\n\n       system( \"$GIT update-index -q --refresh\" );\n\n       # The redirection is somewhat dirty; but is designed to eat the error\n       # message that occurs if there is no HEAD yet.\n       system( \"$GIT diff-index --quiet HEAD 2> /dev/null\" );\n\n       if ( $CHILD_ERROR == -1 ) {\n           print STDERR \"Failed to execute $GIT: $OS_ERROR\\n\";\n       }\n       elsif ( $CHILD_ERROR & 127 ) {\n           printf STDERR \"Child died with signal %d\\n\", ( $CHILD_ERROR & 127 );\n       }\n       else {\n           my $exit_code = $CHILD_ERROR >> 8;\n\n           print \" \";\n           if ( $exit_code == 0 ) {\n               if ( have_stash() ) {\n                   print colored ['yellow'], \"S\";\n               }\n               else {\n                   print colored ['green'], \"C\";\n               }\n           }\n           elsif ( $exit_code == 1 ) {\n               print colored ['red'], \"D\";\n           }\n           else {\n               print colored ['red'], \"?\";\n           }\n           print \" $tree\\n\";\n       }\n   }\n}\n\nsub have_stash\n{\n   my $ref_stash = 'refs/stash';\n   system( \"$GIT rev-parse --verify $ref_stash > /dev/null 2>&1\" );\n\n   if ( $CHILD_ERROR == -1 ) {\n       print STDERR \"Failed to execute $GIT: $OS_ERROR\\n\";\n   }\n   elsif ( $CHILD_ERROR & 127 ) {\n       printf STDERR \"Child died with signal %d\\n\", ( $CHILD_ERROR & 127 );\n   }\n\n   return ( $CHILD_ERROR >> 8 ) == 0;\n}\n\nAny comments or suggestions to improve the above would be gratefully received!\n\nThanks,\n\n--\nMike Clarke\n"}]}