On Tue, 14 Jan 2014 02:13:18 -0800 (PST)
Gabby Romano <omerik...@gmail.com> wrote:

> I am looking for a way to check for the existence in an exact format
> of some string in xml files, and if this string is changing in *any
> way*, to reject the push. 
> I was thinking of checking the diff to check if this string is 
> participating in it, and to verify it is not out of the file. there
> is also the case of new files, in which there is no previous version
> but a real content check needs to be done.
> 
> I will appreciate your opinion on it - am I in the right direction
> here or there is a much better way to handle this.

In a post-receive or update hook you get the SHA-1 names of the commits
to which the refs participating in the push are about to be updated
(unless the hook prevents this).  So you might just call

    if \! git show ${sha1name}:path/to/file/to/check \
        | grep $whatever >/dev/null ]; then
      echo 'Missing blah...' >&2
      exit 1
    fi

This is too simplistic though: you should be prepared for `git show`
to fail due to missing file, and this one is tough as in
POSIX-compliant shells the pipeline only fails if the last command in
it fails.  With bash, you might do

    set -o pipefail

to combat this; with other shells either resort to temporary files like
in

    TMPFILE=`mktemp`
    trap "rm -f '$TMPFILE'" TERM INT QUIT EXIT
    git show ... >"$TMPFILE" || it failed, handle...
    if \! grep $whatever <"$TMPFILE"; then
      echo 'Missing blah...' >&2
      exit 1
    fi

or just rely on `grep` failing to find your string because it will see
early EOF on its input stream due to `git show` quit.  Note that
this won't allow you to see the case of the file being missing in the
commit as special.

You should also understand that this approach only checks the
prospective *tip* commits of the refs being updated -- the file might
well have been deleted (and hence missing) in any intermediate commits
between the current and the prospective tips of a ref.  It might also
had that particular string modified in these intermediate commits.
So if you want to make sure *any* commit in the graph maintained in the
repository you're pushing to is correct in that it contains both the
file and the correct string in it you'll have to traverse the whole
subgraph of commits between the current and prospective tips of all the
refs about to be updated.  To do that, you might use the

    git rev-list $(git merge-base $currentTipSha1 $newSha1)..$newSha1

and feed the resulting list of revisions to a loop which would do the
check outlined above, like in

    git rev-list ... | while read rev; do
        if \! git show ${rev}:path/to/file | grep ...; then
            ...
        fi
    done

See this thread [1] for more info, especially [2] and later.

Note that merely grepping an XML document for a string is obviously a
path to failure since XML is formatted data.  Consider using a
specialized tool like xmlstarlet [3] or xsltproc [4] to verify your XML
file contains the expected contents.

1. https://groups.google.com/d/msg/git-users/DzxY0wkyJPE/O4p95Whf-3IJ
2. https://groups.google.com/d/msg/git-users/DzxY0wkyJPE/mFFL83Lm6wsJ
3. http://packages.debian.org/wheezy/xmlstarlet
4. http://packages.debian.org/wheezy/xsltproc

-- 
You received this message because you are subscribed to the Google Groups "Git 
for human beings" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to git-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to