* 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).