threads / discuss / 19415

How to check repository/working tree status from a script

Subject: How to check repository/working tree status from a script

## tl;dr

15 messages between May 19, 2009 and May 23, 2009.

replies: 14people: 6as markdown or json

Marc Haber· May 19, 2009, 14:35 UTC · lore
Hi,

I am kind of new to git, and my thinking is still somewhat svn-centric. Please keep this in mind just in case that I have misunderstood some of git's concepts.

I would like to check in a script whether there (a) are uncommitted changes (as in "working tree differs from local repository") and/or whether there (b) are unpulled changes in the "remote origin" repository.

I have to admit that I didn't bother about (b) yet, but for (a) there seems no possibility other than to parse git status' output since it seems to always return exit code 1:

$ GIT_PAGER=cat git status; echo $? # On branch master nothing to commit (working directory clean) 1 $ touch keks $ GIT_PAGER=cat git status; echo $? # On branch master # Untracked files: # (use "git add <file>..." to include in what will be committed) # # bla nothing added to commit but untracked files present (use "git add" to track) 1 $

Am I missing something here? Is there documentation about the exit codes of the different git subcommands or probably a complete solution for my two endeavours?

Any hints will be appreciated.

Greetings Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany  |  lose things."    Winona Ryder | Fon: *49 621 72739834
Nordisch by Nature |  How to make an American Quilt | Fax: *49 3221 2323190
Tony Finch· May 19, 2009, 15:34 UTC · re: Marc Haber · lore

Re: How to check repository/working tree status from a script

On Tue, 19 May 2009, Marc Haber wrote:
Hi Marc.
> I would like to check in a script whether there (a) are uncommitted
> changes (as in "working tree differs from local repository")

# check working tree is not different from the index git diff --quiet # check that the index is not different from the head git diff --quiet --cached

> and/or whether there (b) are unpulled changes in the "remote origin"
> repository.
Dunno, sorry.
Tony.
-- 
f.anthony.n.finch  <dot@dotat.at>  http://dotat.at/
GERMAN BIGHT HUMBER: SOUTHWEST 5 TO 7. MODERATE OR ROUGH. SQUALLY SHOWERS.
MODERATE OR GOOD.
Marc Haber· May 19, 2009, 16:00 UTC · re: Tony Finch · lore

Re: How to check repository/working tree status from a script

Hi Tony,
On Tue, May 19, 2009 at 04:34:47PM +0100, Tony Finch wrote:
Show 8 quoted lines
> On Tue, 19 May 2009, Marc Haber wrote:
> > I would like to check in a script whether there (a) are uncommitted
> > changes (as in "working tree differs from local repository")
> 
> # check working tree is not different from the index
> git diff --quiet
> # check that the index is not different from the head
> git diff --quiet --cached

$ git diff --quiet; echo $? 0 $ git diff --quiet --cached; echo $? 0 $ touch keks $ git diff --quiet; echo $? 0 $ git diff --quiet --cached; echo $? 0 $

Am I missing something?

Greetings Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany  |  lose things."    Winona Ryder | Fon: *49 621 72739834
Nordisch by Nature |  How to make an American Quilt | Fax: *49 3221 2323190
Tony Finch· May 19, 2009, 16:16 UTC · re: Marc Haber · lore

Re: How to check repository/working tree status from a script

On Tue, 19 May 2009, Marc Haber wrote:
>
> Am I missing something?
git-diff won't tell you about untracked files.
Use git ls-files --others --exclude-standard
Tony.
-- 
f.anthony.n.finch  <dot@dotat.at>  http://dotat.at/
GERMAN BIGHT HUMBER: SOUTHWEST 5 TO 7. MODERATE OR ROUGH. SQUALLY SHOWERS.
MODERATE OR GOOD.
Marc Haber· May 20, 2009, 14:28 UTC · re: Tony Finch · lore

Re: How to check repository/working tree status from a script

On Tue, May 19, 2009 at 05:16:36PM +0100, Tony Finch wrote:
> On Tue, 19 May 2009, Marc Haber wrote:
> > Am I missing something?
> 
> git-diff won't tell you about untracked files.
Understood. Now. Thanks. ;)

Greetings Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany  |  lose things."    Winona Ryder | Fon: *49 621 72739834
Nordisch by Nature |  How to make an American Quilt | Fax: *49 3221 2323190
Linus Torvalds· May 19, 2009, 16:18 UTC · re: Marc Haber · lore

Re: How to check repository/working tree status from a script

On Tue, 19 May 2009, Marc Haber wrote:
Show 23 quoted lines
> 
> On Tue, May 19, 2009 at 04:34:47PM +0100, Tony Finch wrote:
> > On Tue, 19 May 2009, Marc Haber wrote:
> > > I would like to check in a script whether there (a) are uncommitted
> > > changes (as in "working tree differs from local repository")
> > 
> > # check working tree is not different from the index
> > git diff --quiet
> > # check that the index is not different from the head
> > git diff --quiet --cached
> 
> $ git diff --quiet; echo $?
> 0
> $ git diff --quiet --cached; echo $?
> 0
> $ touch keks
> $ git diff --quiet; echo $?
> 0
> $ git diff --quiet --cached; echo $?
> 0
> $
> 
> Am I missing something?

If "keks" is already something you know about, then 'touch' wouldn't have changed it, so diff won't show it.

And if what you want to know about is whether there are _new_ files you might want to check, then you need a third check: 'git ls-files'. You won't see it in the error code, but you can do

	others=$(git ls-files -o --exclude-standard)
and then check it 'others' is empty or not.
			Linus
Linus Torvalds· May 19, 2009, 16:29 UTC · re: Linus Torvalds · lore

Re: How to check repository/working tree status from a script

On Tue, 19 May 2009, Linus Torvalds wrote:
Show 8 quoted lines
> 
> And if what you want to know about is whether there are _new_ files you 
> might want to check, then you need a third check: 'git ls-files'. You 
> won't see it in the error code, but you can do
> 
> 	others=$(git ls-files -o --exclude-standard)
> 
> and then check it 'others' is empty or not.

Actually, you can use 'git ls-files' to also list files that are changed wrt the index, so then you can drop the 'git diff' thing.

IOW, something like this:
	# any staged changes (ready to commit)
	git diff --quiet --staged || echo Staged changes
	# any changes wrt the index (not staged)
	others=$(git ls-files --exclude-standard -o -d -m -u)
	[ -z "$others" ] || echo "Other changes"
should do it.

If you want more specificity wrt the "Other changes", you can add the "-t" flag to git ls-files and parse the output to see whether the listed files were just unknown (ie new files): '?', changed: 'C', removed: 'R' or need to be merged: 'M'

Of course, 'git diff [--staged]' is needed if you actually want to know some "deeper" patterns about _how_ things were changed. IOW, if you want to know about renames/copies, you need to use 'git diff -M/C' to get that kind of information.

			Linus
Marc Haber· May 20, 2009, 14:27 UTC · re: Linus Torvalds · lore

Re: How to check repository/working tree status from a script

On Tue, May 19, 2009 at 09:29:08AM -0700, Linus Torvalds wrote:
Show 10 quoted lines
> IOW, something like this:
> 
> 	# any staged changes (ready to commit)
> 	git diff --quiet --staged || echo Staged changes
> 
> 	# any changes wrt the index (not staged)
> 	others=$(git ls-files --exclude-standard -o -d -m -u)
> 	[ -z "$others" ] || echo "Other changes"
> 
> should do it.
This looks good.
Show 9 quoted lines
> If you want more specificity wrt the "Other changes", you can add the "-t" 
> flag to git ls-files and parse the output to see whether the listed files 
> were just unknown (ie new files): '?', changed: 'C', removed: 'R' or need 
> to be merged: 'M'
> 
> Of course, 'git diff [--staged]' is needed if you actually want to know 
> some "deeper" patterns about _how_ things were changed. IOW, if you want 
> to know about renames/copies, you need to use 'git diff -M/C' to get that 
> kind of information.
Thanks. It's ok to just barf if there are any changes.

Background info: the data being version controlled is not source, but configuration for one system which is collaboratively maintained. There is a script which takes the currently checked out working tree, "compiles" it into the actual configuration and rsyncs/activates the actual configuration to the (one) target system. I would like to make sure that if one of the admins runs this script, she has (a) pulled all changes that others may have pushed to the central repository and (b) all her local changes are actually committed to her local repository and (c) pushed to the central repository.

Greetings Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany  |  lose things."    Winona Ryder | Fon: *49 621 72739834
Nordisch by Nature |  How to make an American Quilt | Fax: *49 3221 2323190

Bitte beachten Sie, daß dem [m.E. grundgesetzwidrigen] Gesetz zur
Vorratsdatenspeicherung zufolge, seit dem 1. Januar 2008 jeglicher
elektronische Kontakt (E-Mail, Telefongespräche, SMS, Internet-
Telefonie, Mobilfunk, Fax) mit mir oder anderen Nutzern verdachts-
unabhängig für den automatisierten geheimen Zugriff durch Strafver-
folgungs- u. Polizeivollzugsbehörden, die Bundesanstalt für Finanz-
dienstleistungsaufsicht, Zollkriminal- und Zollfahndungsämter,die
Zollverwaltung zur Schwarzarbeitsbekämpfung, Notrufabfragestellen,
Verfassungsschutzbehörden, den Militärischen Abschirmdienst, Bundes-
nachrichtendienst sowie 52 Staaten wie beispielsweise Aserbeidschan
oder die USA sechs Monate lang gespeichert wird, einschließlich der
Kommunikation mit Berufsgeheimnisträgern wie Ärzten, Journalisten und
Anwälten. Mehr Infos zur totalen Protokollierung Ihrer Kommunikations-
daten auf www.vorratsdatenspeicherung.de. (leicht verändert übernommen
kopiert von www.lawblog.de)
Marc Haber· May 20, 2009, 11:10 UTC · re: Linus Torvalds · lore

Re: How to check repository/working tree status from a script

On Tue, May 19, 2009 at 09:18:12AM -0700, Linus Torvalds wrote:
Show 26 quoted lines
> On Tue, 19 May 2009, Marc Haber wrote:
> > On Tue, May 19, 2009 at 04:34:47PM +0100, Tony Finch wrote:
> > > On Tue, 19 May 2009, Marc Haber wrote:
> > > > I would like to check in a script whether there (a) are uncommitted
> > > > changes (as in "working tree differs from local repository")
> > > 
> > > # check working tree is not different from the index
> > > git diff --quiet
> > > # check that the index is not different from the head
> > > git diff --quiet --cached
> > 
> > $ git diff --quiet; echo $?
> > 0
> > $ git diff --quiet --cached; echo $?
> > 0
> > $ touch keks
> > $ git diff --quiet; echo $?
> > 0
> > $ git diff --quiet --cached; echo $?
> > 0
> > $
> > 
> > Am I missing something?
> 
> If "keks" is already something you know about, then 'touch' wouldn't have 
> changed it, so diff won't show it.

keks didn't exist previously, so the touch generated a new empty 0 byte file.

Show 7 quoted lines
> And if what you want to know about is whether there are _new_ files you 
> might want to check, then you need a third check: 'git ls-files'. You 
> won't see it in the error code, but you can do
> 
> 	others=$(git ls-files -o --exclude-standard)
> 
> and then check it 'others' is empty or not.

So parsing the output is both the canonical and only way to do so since there is no meaningful exit code? Can I assume that the formatting of git output is not subject to change?

Greetings Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany  |  lose things."    Winona Ryder | Fon: *49 621 72739834
Nordisch by Nature |  How to make an American Quilt | Fax: *49 3221 2323190
Santi Béjar· May 20, 2009, 11:19 UTC · re: Marc Haber · lore

Re: How to check repository/working tree status from a script

2009/5/20 Marc Haber <mh+git@zugschlus.de>:
Show 30 quoted lines
> On Tue, May 19, 2009 at 09:18:12AM -0700, Linus Torvalds wrote:
>> On Tue, 19 May 2009, Marc Haber wrote:
>> > On Tue, May 19, 2009 at 04:34:47PM +0100, Tony Finch wrote:
>> > > On Tue, 19 May 2009, Marc Haber wrote:
>> > > > I would like to check in a script whether there (a) are uncommitted
>> > > > changes (as in "working tree differs from local repository")
>> > >
>> > > # check working tree is not different from the index
>> > > git diff --quiet
>> > > # check that the index is not different from the head
>> > > git diff --quiet --cached
>> >
>> > $ git diff --quiet; echo $?
>> > 0
>> > $ git diff --quiet --cached; echo $?
>> > 0
>> > $ touch keks
>> > $ git diff --quiet; echo $?
>> > 0
>> > $ git diff --quiet --cached; echo $?
>> > 0
>> > $
>> >
>> > Am I missing something?
>>
>> If "keks" is already something you know about, then 'touch' wouldn't have
>> changed it, so diff won't show it.
>
> keks didn't exist previously, so the touch generated a new empty 0 byte
> file.
And 'git diff' alone only cares about files it knows.
Show 12 quoted lines
>
>> And if what you want to know about is whether there are _new_ files you
>> might want to check, then you need a third check: 'git ls-files'. You
>> won't see it in the error code, but you can do
>>
>>       others=$(git ls-files -o --exclude-standard)
>>
>> and then check it 'others' is empty or not.
>
> So parsing the output is both the canonical and only way to do so
> since there is no meaningful exit code? Can I assume that the
> formatting of git output is not subject to change?

Git output for the plumbing comands do not change, it is designed for script use. OTOH git output for porcelain commands can change. 'git ls-files' is a plumbing commands, see git's manpage for the complete list.

HTH, Santi

Johannes Sixt· May 20, 2009, 11:32 UTC · re: Marc Haber · lore

Re: How to check repository/working tree status from a script

Marc Haber schrieb:
Show 12 quoted lines
> On Tue, May 19, 2009 at 09:18:12AM -0700, Linus Torvalds wrote:
>> And if what you want to know about is whether there are _new_ files you 
>> might want to check, then you need a third check: 'git ls-files'. You 
>> won't see it in the error code, but you can do
>>
>> 	others=$(git ls-files -o --exclude-standard)
>>
>> and then check it 'others' is empty or not.
> 
> So parsing the output is both the canonical and only way to do so
> since there is no meaningful exit code? Can I assume that the
> formatting of git output is not subject to change?
See 'man git':

"Porcelain" commands are *not* for use in scripts; their output may change. git diff, git status, git commit, git checkout are in this category.

"Plumbing" commands are for use in scripts and their output will not change. git ls-files, git diff-tree, git diff-files are in this category.

-- Hannes
Marc Haber· May 20, 2009, 14:29 UTC · re: Johannes Sixt · lore

Re: How to check repository/working tree status from a script

On Wed, May 20, 2009 at 01:32:30PM +0200, Johannes Sixt wrote:
Show 7 quoted lines
> See 'man git':
> 
> "Porcelain" commands are *not* for use in scripts; their output may
> change. git diff, git status, git commit, git checkout are in this category.
> 
> "Plumbing" commands are for use in scripts and their output will not
> change. git ls-files, git diff-tree, git diff-files are in this category.
Missed that. Sorry. Thanks.

Greetings Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany  |  lose things."    Winona Ryder | Fon: *49 621 72739834
Nordisch by Nature |  How to make an American Quilt | Fax: *49 3221 2323190
Marc Haber· May 21, 2009, 13:24 UTC · re: Marc Haber · lore

Re: How to check repository/working tree status from a script

Hi,
On Tue, May 19, 2009 at 04:35:37PM +0200, Marc Haber wrote:
> I would like to check in a script whether there (a) are uncommitted
> changes (as in "working tree differs from local repository") and/or
> whether there (b) are unpulled changes in the "remote origin"
> repository.
(a) has been solved, thanks for helping.
I am now looking for a solution for (b). I tried 
git log -n1 --pretty=oneline master..origin/master

but that seems to always give empty output even if a later issued git pull will actually pull in changes.

Greetings Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany  |  lose things."    Winona Ryder | Fon: *49 621 72739834
Nordisch by Nature |  How to make an American Quilt | Fax: *49 3221 2323190
Jeff King· May 21, 2009, 15:37 UTC · re: Marc Haber · lore

Re: How to check repository/working tree status from a script

On Thu, May 21, 2009 at 03:24:57PM +0200, Marc Haber wrote:
Show 6 quoted lines
> I am now looking for a solution for (b). I tried 
> 
> git log -n1 --pretty=oneline master..origin/master
> 
> but that seems to always give empty output even if a later issued git
> pull will actually pull in changes.

Try running "git fetch" beforehand, which will actually update origin/master with what is on the remote.

Also, if you are just checking to see whether there is any output, you can use the plumbing "git rev-list" instead of "git log". So something like:

  git fetch origin || { echo >&2 unable to fetch; exit 1; }
  test -z "`git rev-list -1 master..origin/master`"
-Peff
Marc Haber· May 23, 2009, 20:39 UTC · re: Jeff King · lore

Re: How to check repository/working tree status from a script

On Thu, May 21, 2009 at 11:37:45AM -0400, Jeff King wrote:
Show 10 quoted lines
> On Thu, May 21, 2009 at 03:24:57PM +0200, Marc Haber wrote:
> > I am now looking for a solution for (b). I tried 
> > 
> > git log -n1 --pretty=oneline master..origin/master
> > 
> > but that seems to always give empty output even if a later issued git
> > pull will actually pull in changes.
> 
> Try running "git fetch" beforehand, which will actually update
> origin/master with what is on the remote.
I slowly begin to grasp how git works. Thanks for enlightening.
Show 6 quoted lines
> Also, if you are just checking to see whether there is any output, you
> can use the plumbing "git rev-list" instead of "git log". So something
> like:
> 
>   git fetch origin || { echo >&2 unable to fetch; exit 1; }
>   test -z "`git rev-list -1 master..origin/master`"
if ! git fetch origin; then
  echo >&2 "unable to fetch"
  exit 1
fi
if git rev-list -1 master..origin/master | grep -q . ; then
  echo >&2 "unmerged changes on remote repository"
  exit 1
fi
Works fine. Thanks.

Greetings Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany  |  lose things."    Winona Ryder | Fon: *49 621 72739834
Nordisch by Nature |  How to make an American Quilt | Fax: *49 3221 2323190

Bitte beachten Sie, daß dem [m.E. grundgesetzwidrigen] Gesetz zur
Vorratsdatenspeicherung zufolge, seit dem 1. Januar 2008 jeglicher
elektronische Kontakt (E-Mail, Telefongespräche, SMS, Internet-
Telefonie, Mobilfunk, Fax) mit mir oder anderen Nutzern verdachts-
unabhängig für den automatisierten geheimen Zugriff durch Strafver-
folgungs- u. Polizeivollzugsbehörden, die Bundesanstalt für Finanz-
dienstleistungsaufsicht, Zollkriminal- und Zollfahndungsämter,die
Zollverwaltung zur Schwarzarbeitsbekämpfung, Notrufabfragestellen,
Verfassungsschutzbehörden, den Militärischen Abschirmdienst, Bundes-
nachrichtendienst sowie 52 Staaten wie beispielsweise Aserbeidschan
oder die USA sechs Monate lang gespeichert wird, einschließlich der
Kommunikation mit Berufsgeheimnisträgern wie Ärzten, Journalisten und
Anwälten. Mehr Infos zur totalen Protokollierung Ihrer Kommunikations-
daten auf www.vorratsdatenspeicherung.de. (leicht verändert übernommen
kopiert von www.lawblog.de)

← back to recent threads