* post-update script to update wc - suggestions welcome
@ 2007-06-20 6:21 Sam Vilain
2007-06-20 7:03 ` Sam Vilain
2007-06-20 8:52 ` Junio C Hamano
0 siblings, 2 replies; 6+ messages in thread
From: Sam Vilain @ 2007-06-20 6:21 UTC (permalink / raw)
To: git
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, make this file executable by "chmod +x post-update".
git-update-server-info
ref=$1
active=`git-symbolic-ref HEAD`
if [ "$ref" = "$active" ]
then
echo "Pushing to checked out branch - updating working copy" >&2
export GIT_DIR=`cd $GIT_DIR; pwd`
cd ..
success=
if git-diff-files
then
git-diff-index -z -R --name-status HEAD | perl -n0 -le \
'if ($z^=1) {
$status=$_;
}
else {
$filename=$_;
printf STDERR "$status\t$filename\n";
if($status eq "D"){
unlink($filename)
or die("unlink($filename) failed; $!")
}
}' &&
git-reset --hard HEAD && success=1
fi
if [ -z "$success" ]
then
(
echo "Non-bare repository checkout is not clean - not updating it"
echo "However I AM going to update the index. Any in-progress commit"
echo "happening in that checkout will be thrown away, but on the bright"
echo "side this is probably the least confusing thing for us to do and"
echo "at least we're not throwing any files somebody has changed away"
git-reset --mixed HEAD
echo
echo "This is the new status of the upstream working copy:"
git-status
) >&2
fi
fi
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: post-update script to update wc - suggestions welcome
2007-06-20 6:21 post-update script to update wc - suggestions welcome Sam Vilain
@ 2007-06-20 7:03 ` Sam Vilain
2007-06-20 8:52 ` Junio C Hamano
1 sibling, 0 replies; 6+ messages in thread
From: Sam Vilain @ 2007-06-20 7:03 UTC (permalink / raw)
To: git
Sam Vilain wrote:
> #!/bin/sh
> #
> # An example hook script to prepare a packed repository for use over
> # dumb transports.
> #
> # To enable this hook, make this file executable by "chmod +x post-update".
>
> git-update-server-info
>
> ref=$1
In particular, if anyone can think of a clever and reliable way to
detect whether the repository is bare or not (perhaps the presence of
$GIT_DIR/index ?), then this could conceivably become the default
example hook script, by making the below bit conditional on whether this
looks like a non-bare repository.
Sam.
> active=`git-symbolic-ref HEAD`
> if [ "$ref" = "$active" ]
> then
> echo "Pushing to checked out branch - updating working copy" >&2
> export GIT_DIR=`cd $GIT_DIR; pwd`
> cd ..
> success=
> if git-diff-files
> then
> git-diff-index -z -R --name-status HEAD | perl -n0 -le \
> 'if ($z^=1) {
> $status=$_;
> }
> else {
> $filename=$_;
> printf STDERR "$status\t$filename\n";
> if($status eq "D"){
> unlink($filename)
> or die("unlink($filename) failed; $!")
> }
> }' &&
> git-reset --hard HEAD && success=1
> fi
> if [ -z "$success" ]
> then
> (
> echo "Non-bare repository checkout is not clean - not updating it"
> echo "However I AM going to update the index. Any in-progress commit"
> echo "happening in that checkout will be thrown away, but on the bright"
> echo "side this is probably the least confusing thing for us to do and"
> echo "at least we're not throwing any files somebody has changed away"
> git-reset --mixed HEAD
> echo
> echo "This is the new status of the upstream working copy:"
> git-status
> ) >&2
> fi
> fi
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: post-update script to update wc - suggestions welcome
2007-06-20 6:21 post-update script to update wc - suggestions welcome Sam Vilain
2007-06-20 7:03 ` Sam Vilain
@ 2007-06-20 8:52 ` Junio C Hamano
2007-06-20 20:14 ` Sam Vilain
1 sibling, 1 reply; 6+ messages in thread
From: Junio C Hamano @ 2007-06-20 8:52 UTC (permalink / raw)
To: Sam Vilain; +Cc: git, Matthias Lederhofer
Sam Vilain <samv@utsl.gen.nz> writes:
> #!/bin/sh
> #
> # An example hook script to prepare a packed repository for use over
> # dumb transports.
> #
> # To enable this hook, make this file executable by "chmod +x post-update".
>
> git-update-server-info
>
> ref=$1
> active=`git-symbolic-ref HEAD`
> if [ "$ref" = "$active" ]
post-update hook takes list of refs that have been updated, so
the above check is bogus, I think.
Better do something like:
case " $* " in
*" $active "*)
: current branch was updated...
;;
*)
: do not have to worry about this one
exit 0
;;
esac
# ... rest of the code here ...
Also you would want to see if the thing is bare.
Unfortunately, git-sh-setup's is_bare_repository does a wrong
thing because receive-pack already runs GIT_DIR set to '.' after
chdir to it. Matthias's long set of patches currently parked in
'pu' is supposed to clarify the semantics of bare/non-bare, so
it may help though (it has "rev-parse --is-bare-repository).
I think 80% of the time (because other 20% of bare repositories
are initialized, following an often repeated incorrect procedure
of making a worktree-full repository and moving its .git/ to
another place, $name.git --- that is wrong for at least three
reasons), if $GIT_DIR/index exists, you can treat it as a
non-bare repository.
So in short, I would follow the above quoted one with:
test -f "$GIT_DIR/index" || exit 0
to ignore bare repositories.
Matthias, do you know if your patchset correctly handle this
case? That is:
$ git push site:my.git set of refs
will:
(1) spawn git-receive-pack with my.git as its
argument;
(2) git-receive-pack finds the repository and chdir()'s
to the directory that has refs/ and HEAD in it
(i.e. if my.git is bare, the directory itself, if
my.git has my.git/.git and possibly a checkout in
my.git/{Makefile,README,...}, then it chdir()'s to
my.git/.git);
(3) then it sets GIT_DIR=. and exports it.
and from that environment, post-update hook is called.
I think Matthias's patch series may need to (conditionally) set
GIT_WORK_TREE environment when it finds the repository and see
if there is an associated work tree at its natural place (that
is, if $something/.git is found in (2) and $something/.git/index
exists, then worktree should be rooted at $something/, unless
core.worktree is set) .
> then
> echo "Pushing to checked out branch - updating working copy" >&2
> export GIT_DIR=`cd $GIT_DIR; pwd`
... and Matthias's patch series probably needs to update this
part of your patch as well.
> cd ..
> success=
> if git-diff-files
> then
I would suggest running update-index --refresh before running
diff-files. The user may have cache-dirty file and only that.
> git-diff-index -z -R --name-status HEAD | perl -n0 -le \
> 'if ($z^=1) {
> $status=$_;
> }
> else {
> $filename=$_;
> printf STDERR "$status\t$filename\n";
> if($status eq "D"){
> unlink($filename)
> or die("unlink($filename) failed; $!")
> }
> }' &&
With "--name-only --diff-filter=D" you would not have to do most
of the above ;-) Use --diff-filter=A without -R, perhaps, to
make it even shorter.
> git-reset --hard HEAD && success=1
> fi
Wouldn't "reset --hard HEAD" pretty much unconditionally nuke
your local changes, including added files to the index? For
example, if I do this:
$ >foo && git add foo && git reset --hard HEAD
it would remove the newly added 'foo' from both the index and
the working tree. So I am not quite sure what you are trying to
achieve with "diff-index | perl" magic.
> if [ -z "$success" ]
> then
> (
> echo "Non-bare repository checkout is not clean - not updating it"
> echo "However I AM going to update the index. Any in-progress commit"
> echo "happening in that checkout will be thrown away, but on the bright"
> echo "side this is probably the least confusing thing for us to do and"
> echo "at least we're not throwing any files somebody has changed away"
> git-reset --mixed HEAD
> echo
> echo "This is the new status of the upstream working copy:"
> git-status
> ) >&2
> fi
> fi
I'll cook up an alternative patch perhaps tomorrow.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: post-update script to update wc - suggestions welcome
2007-06-20 8:52 ` Junio C Hamano
@ 2007-06-20 20:14 ` Sam Vilain
2007-06-20 21:02 ` Junio C Hamano
0 siblings, 1 reply; 6+ messages in thread
From: Sam Vilain @ 2007-06-20 20:14 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Matthias Lederhofer
Junio C Hamano wrote:
> Also you would want to see if the thing is bare.
>
> Unfortunately, git-sh-setup's is_bare_repository does a wrong
> thing because receive-pack already runs GIT_DIR set to '.' after
> chdir to it. Matthias's long set of patches currently parked in
> 'pu' is supposed to clarify the semantics of bare/non-bare, so
> it may help though (it has "rev-parse --is-bare-repository).
>
> I think 80% of the time (because other 20% of bare repositories
> are initialized, following an often repeated incorrect procedure
> of making a worktree-full repository and moving its .git/ to
> another place, $name.git --- that is wrong for at least three
> reasons), if $GIT_DIR/index exists, you can treat it as a
> non-bare repository.
>
Great, well in lieu of that, Matthias suggests a reasonable extra
heuristic of whether or not the pathname ends in "/.git" (or "\.git").
Which falls into the "why didn't I think of that" category ;-).
No doubt with those patches the hook can be simplified, especially if it
sets GIT_WORK_TREE.
>> cd ..
>> success=
>> if git-diff-files
>> then
>>
>
> I would suggest running update-index --refresh before running
> diff-files. The user may have cache-dirty file and only that.
>
Ah yes, is that what git-status does that checks the filestamps in the
index and updates them... Handy to know.
>> git-diff-index -z -R --name-status HEAD | perl -n0 -le \
>> 'if ($z^=1) {
>> $status=$_;
>> }
>> else {
>> $filename=$_;
>> printf STDERR "$status\t$filename\n";
>> if($status eq "D"){
>> unlink($filename)
>> or die("unlink($filename) failed; $!")
>> }
>> }' &&
>>
>
> With "--name-only --diff-filter=D" you would not have to do most
> of the above ;-) Use --diff-filter=A without -R, perhaps, to
> make it even shorter.
>
You're right, it was right there!
I think it's a good thing to echo back to the user the output of the
--name-status command, so they can see the changes that were made.
>> git-reset --hard HEAD && success=1
>> fi
>>
>
> Wouldn't "reset --hard HEAD" pretty much unconditionally nuke
> your local changes, including added files to the index? For
> example, if I do this:
>
> $ >foo && git add foo && git reset --hard HEAD
>
> it would remove the newly added 'foo' from both the index and
> the working tree. So I am not quite sure what you are trying to
> achieve with "diff-index | perl" magic.
>
Right, but we've already checked using diff-files that there weren't any
local changes. So all we're saying is "remove all files which won't be
written by git reset --hard, then checkout new versions of files".
Actually there is a slight deficiency in the above script - empty
directories will not be removed, so replacing a directory with a file
will be broken.
> I'll cook up an alternative patch perhaps tomorrow.
>
Cool! I'm sure bzr and darcs users will thank you :-)
Sam.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: post-update script to update wc - suggestions welcome
2007-06-20 20:14 ` Sam Vilain
@ 2007-06-20 21:02 ` Junio C Hamano
2007-06-20 22:28 ` Sam Vilain
0 siblings, 1 reply; 6+ messages in thread
From: Junio C Hamano @ 2007-06-20 21:02 UTC (permalink / raw)
To: Sam Vilain; +Cc: git, Matthias Lederhofer
Sam Vilain <sam@vilain.net> writes:
>>> cd ..
>>> success=
>>> if git-diff-files
>>> then
>>>
>> ...
>>
>>> git-reset --hard HEAD && success=1
>>> fi
>>>
>>
>> Wouldn't "reset --hard HEAD" pretty much unconditionally nuke
>> your local changes, including added files to the index? For
>> example, if I do this:
>>
>> $ >foo && git add foo && git reset --hard HEAD
>>
>> it would remove the newly added 'foo' from both the index and
>> the working tree. So I am not quite sure what you are trying to
>> achieve with "diff-index | perl" magic.
>
> Right, but we've already checked using diff-files that there weren't any
> local changes. So all we're saying is "remove all files which won't be
> written by git reset --hard, then checkout new versions of files".
I am afraid I am not following your logic.
I missed that "if git-diff-files"; it is not checking (you would
have to ask for --exit-code or something --- traditionally we
never used git-diff-xxxx exit code to indicate if there is any
changes).
Suppose we update that "if" to see if diff-files says "no change
in the working tree wrt the index". But then, I think what you
have at the end, "git reset --hard HEAD", where the HEAD is an
arbitrary commit that does not necessarily have to do anything
with what the index is based on, would remove what is known to
the index but not in HEAD. Which was my point about the
"diff-index piped to perl". I do not think that one is
necessary.
Actually, more importantly, why is it justified to remove a file
that is unchanged since the index, if the updated HEAD does not
have it? That is losing information, isn't it?
Or are you assuming that this is used only for a worktree where
there is NO actual development happens, but just kept up to date
to whatever commit comes at HEAD?
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: post-update script to update wc - suggestions welcome
2007-06-20 21:02 ` Junio C Hamano
@ 2007-06-20 22:28 ` Sam Vilain
0 siblings, 0 replies; 6+ messages in thread
From: Sam Vilain @ 2007-06-20 22:28 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Matthias Lederhofer
Junio C Hamano wrote:
> I am afraid I am not following your logic.
>
> I missed that "if git-diff-files"; it is not checking (you would
> have to ask for --exit-code or something --- traditionally we
> never used git-diff-xxxx exit code to indicate if there is any
> changes).
Oh, I expected a diff command to return an error code if differences
were found, like diff does.
> Suppose we update that "if" to see if diff-files says "no change
> in the working tree wrt the index". But then, I think what you
> have at the end, "git reset --hard HEAD", where the HEAD is an
> arbitrary commit that does not necessarily have to do anything
> with what the index is based on, would remove what is known to
> the index but not in HEAD.
Good point. Yes a semi-staged commit would lose information. So we
also need to check that the index matches the previous value of what the
current branch points to.
How about this. We call write-tree and get a tree ID. If we can find
that tree in any of the commits reachable by the reflog or the history
of the current branch then we can be happy that no local changes have
been staged. That will imply that if you want a non-bare repository to
update automatically and use push -f, you need reflog.
> Which was my point about the
> "diff-index piped to perl". I do not think that one is
> necessary.
Sure, I only did that because I didn't think reset --hard would remove
files which were previously in the index but not in the version being
reset to.
> Actually, more importantly, why is it justified to remove a file
> that is unchanged since the index, if the updated HEAD does not
> have it? That is losing information, isn't it?
Well, not if you can confirm that the index matches some previous
version of the branch.
> Or are you assuming that this is used only for a worktree where
> there is NO actual development happens, but just kept up to date
> to whatever commit comes at HEAD?
I was aiming for something safe that people can just chmod +x to get
symmetric push/pull semantics.
Sam.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2007-06-20 22:28 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-20 6:21 post-update script to update wc - suggestions welcome Sam Vilain
2007-06-20 7:03 ` Sam Vilain
2007-06-20 8:52 ` Junio C Hamano
2007-06-20 20:14 ` Sam Vilain
2007-06-20 21:02 ` Junio C Hamano
2007-06-20 22:28 ` Sam Vilain
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).