{"thread":{"id":"6925","subject":"git-push hook to update remote working copy safely","startedAt":"2007-02-23T08:51:49Z","lastAt":"2007-02-23T18:32:39Z","messageCount":7,"participants":["Sam Watkins","Junio C Hamano","Johannes Schindelin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"35310","messageId":"1172220709.10221.1176113191@webmail.messagingengine.com","threadId":"6925","inReplyTo":null,"subject":"git-push hook to update remote working copy safely","fromName":"Sam Watkins","fromEmail":"swatkins@fastmail.fm","sentAt":"2007-02-23T08:51:49Z","receivedAt":"2007-02-23T08:51:49Z","isPatch":false,"sender":{"key":"swatkins@fastmail.fm","avatar":"https://gravatar.com/avatar/0fb645f099104372935d69ee3eea754c24e0319875f5fdb9df04f4da8eb006c6?d=mp&s=160"},"body":"peace,\n\nI'm looking for a command that will update the remote working copy after\na \"git push\", without damaging any changes that may have been made to\nthe working copy.\nI haven't used git barely at all, hoping this is an okay place to ask\nabout this.  I can put the command into the push hook myself, I just\ndon't know what command does that!\n\nThis is one of the last \"pieces\" needed for a hopefully useful\napplication I'm working on with a friend, which uses git for storage and\nfile transfer.\n\n\nSam\n"},{"id":"35318","messageId":"7v649t5ebq.fsf@assigned-by-dhcp.cox.net","threadId":"6925","inReplyTo":"1172220709.10221.1176113191@webmail.messagingengine.com","subject":"Re: git-push hook to update remote working copy safely","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-23T11:00:09Z","receivedAt":"2007-02-23T11:00:09Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Sam Watkins\" <swatkins@fastmail.fm> writes:\n\n> I'm looking for a command that will update the remote working copy after\n> a \"git push\", without damaging any changes that may have been made to\n> the working copy.\n\nDefine \"without damaging\".  If there are changes to paths that\nare modified by the pushed commit since the current HEAD, what\nshould your \"update the remote working copy\" procedure would\ndo?\n\n * Abort the push and refuse to update branch head?\n\n * Run file-level merge and leave the conflicted results on the\n   working tree, in the $GIT_DIR/index and leave the pushed\n   commit object name in $GIT_DIR/MERGE_HEAD?\n\nI think the latter is just crazy, as you would then have to\nthink about cases where you already have $GIT_DIR/MERGE_HEAD\nwhen you attempt to push.\n\nWhy in the first place does checking out need to perform a\npossibly conflicting update?  Unless it is _also_ modified by\nsomething other than push (i.e. some human user modifies it in\nthe editor, iow active development happening in the repository),\nyou can assume that when a push tries to update the working\ntree, the working tree is clean (i.e. the index matches HEAD and\nthe working tree files match the index).  And in such a case,\nyou can set receive.denyNonFastForwards, and push will not even\ncall the update hook unless it is fast-forward.  And checking\nout a fast-forward in a clean working tree should always succeed\nwithout conflicts.  So I am puzzled what you are really trying\nto achieve here.\n\nThe only thing you need to protect against is simultaneous push,\nand I think that can be solved by holding a lock file while your\nupdate hook runs a checkout.\n\nSo it might be just the matter of something like this totally\nuntested script:\n\n\t#!/bin/sh\n        # Assumes that the repository has its own working tree and\n\t# $GIT_DIR is \"/path/to/repository/.git\".  update hook\n        # is always called with `pwd` the same as $GIT_DIR.\n\n        GIT_DIR=`pwd`\n\n\tcd .. ;# to the top of working tree\n        BRANCH=\"$1\"\n        OLDREV=\"$2\"\n        NEWREV=\"$3\"\n\n\t# Do not bother with non branch push.\n        case \"$BRANCH\" in refs/heads/*) ;; *) exit 0 ;; esac\n\n\t# Make sure it is a fast-forward, unless totally new.\n\tif test \"0000000000000000000000000000000000000000\" = \"$OLDREV\"\n\tthen\n\t\tMB=$(git merge-base \"$OLDREV\" \"$NEWREV\") &&\n\t        test \"$OLDREV\" = \"$NEWREV\" || exit 1\n\tfi\n\n\t# Pushing into a non-checked-out branch -- no need to\n        # do anything.\n        HEAD_BRANCH=`git symbolic-ref HEAD`\n        test \"z$HEAD_BRANCH\" = \"z$BRANCH\" || exit 0\n\n\t# Could we have a lock please?\n\tlock=\"$GIT_DIR/push-update.lock\"\n        lockfile \"$lock\"\n        trap 'rm -f \"$lock\"' 0\n\n        # Make sure the index, working tree and HEAD all match.\n\tHEAD=`git rev-parse --verify HEAD` &&\n        test \"z$HEAD\" = \"z$OLDREV\" &&\n        git update-index --refresh &&\n        test -z \"`git diff-files --name-only`\" &&\n        test -z \"`git diff-index --cached --name-only $HEAD`\" ||\n\texit 1\n\n\t# Update the working tree -- we do not do git-checkout\n        # because updating the ref in 'update' hook is a big\n        # No-no.  It would screw up the lockless update in\n        # receive-pack that happens after update hook returns.\n        git read-tree -m -u \"$OLDREV\" \"$NEWREV\"\n"},{"id":"35329","messageId":"1172248500.32514.1176151445@webmail.messagingengine.com","threadId":"6925","inReplyTo":"7v649t5ebq.fsf@assigned-by-dhcp.cox.net","subject":"Re: git-push hook to update remote working copy safely","fromName":"Sam Watkins","fromEmail":"swatkins@fastmail.fm","sentAt":"2007-02-23T16:35:00Z","receivedAt":"2007-02-23T16:35:00Z","isPatch":false,"sender":{"key":"swatkins@fastmail.fm","avatar":"https://gravatar.com/avatar/0fb645f099104372935d69ee3eea754c24e0319875f5fdb9df04f4da8eb006c6?d=mp&s=160"},"body":"On Fri, 23 Feb 2007 03:00:09 -0800, \"Junio C Hamano\" <junkio@cox.net>\nsaid:\n> \"Sam Watkins\" <swatkins@fastmail.fm> writes:\n> \n> > I'm looking for a command that will update the remote working copy after\n> > a \"git push\", without damaging any changes that may have been made to\n> > the working copy.\n> \n> Define \"without damaging\".  If there are changes to paths that\n> are modified by the pushed commit since the current HEAD, what\n> should your \"update the remote working copy\" procedure would\n> do?\n\nhi Junio,\n\nit should merge the changes as if I'd run git-pull on the remote box,\nand handle conflicts in the same way.\n\nIf possible I want to get exactly the effect of having run on box B\n\"git-pull A\", by running a command like \"git-push B\" on box A.  I think\nmaybe that's not possible without commiting all changes to the working\ncopy on B first, but for our app it's fine to do that it's meant to do\nthat automatically and frequently anyway.\nso I will just do that then run checkout -f from the hook.\n\nI don't understand git very well yet but that will work I think.  I\nthought \"push\" would be symmetrical to \"pull\" more or less, maybe it is\nsymmetrical to \"fetch\" ?\n\nthank-you for your help, I am reading some more of the git manual\nbecause I understand only some of your reply and very little about git\nyet!\n\nThe app \"arcs\" we are writing, it is peer to peer, not necessarily using\na central repository, it commits pulls and pushes all changes made to\nworking copies automatically or when asked to.  currently I'm\nimplementing push as a remote pull because of this problem, but that\ncan't connect back through firewalls and suchlike.\n\n\nSam\n"},{"id":"35330","messageId":"Pine.LNX.4.63.0702231737300.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6925","inReplyTo":"1172248500.32514.1176151445@webmail.messagingengine.com","subject":"Re: git-push hook to update remote working copy safely","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-23T16:40:02Z","receivedAt":"2007-02-23T16:40:02Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 24 Feb 2007, Sam Watkins wrote:\n\n> it should merge the changes as if I'd run git-pull on the remote box, \n> and handle conflicts in the same way.\n\nBut that leaves conflicts in the working directory! You _have_ to resolve \nthem (or reset) before proceding.\n\n> I don't understand git very well yet but that will work I think.  I \n> thought \"push\" would be symmetrical to \"pull\" more or less, maybe it is \n> symmetrical to \"fetch\" ?\n\nYes, that was the idea of the naming.\n\n> The app \"arcs\" we are writing, it is peer to peer, not necessarily using \n> a central repository, it commits pulls and pushes all changes made to \n> working copies automatically or when asked to.  currently I'm \n> implementing push as a remote pull because of this problem, but that \n> can't connect back through firewalls and suchlike.\n\nDon't you have any user interaction? I.e. if the remote working directory \nis only ever changed by your hook, you can use what Junio sent. It is even \noverkill for that purpose.\n\nHth,\nDscho\n"},{"id":"35333","messageId":"1172250283.5505.1176180417@webmail.messagingengine.com","threadId":"6925","inReplyTo":"Pine.LNX.4.63.0702231737300.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: git-push hook to update remote working copy safely","fromName":"Sam Watkins","fromEmail":"swatkins@fastmail.fm","sentAt":"2007-02-23T17:04:43Z","receivedAt":"2007-02-23T17:04:43Z","isPatch":false,"sender":{"key":"swatkins@fastmail.fm","avatar":"https://gravatar.com/avatar/0fb645f099104372935d69ee3eea754c24e0319875f5fdb9df04f4da8eb006c6?d=mp&s=160"},"body":"\nOn Fri, 23 Feb 2007 17:40:02 +0100 (CET), \"Johannes Schindelin\"\n<Johannes.Schindelin@gmx.de> said:\n> Hi,\n>\n> On Sat, 24 Feb 2007, Sam Watkins wrote:\n>\n> > it should merge the changes as if I'd run git-pull on the remote\n> > box, and handle conflicts in the same way.\n>\n> But that leaves conflicts in the working directory! You _have_ to\n> resolve them (or reset) before proceding.\n\nhi Johannes,\n\nI think it's ok for our application if the push+hook leaves conflicts in\nthe working directory, I just want to replicate the effect of running\ngit-pull remotely without actually having to go through ssh contortions\nto achieve that. It might not be such a good idea to do that in the\nnormal usage of git, but we are using it in not a normal way, and that\nis what I am trying to do, replicate the effect of running git-pull\nremotely using git-push plus (unknown attempt-to-merge command or\nwhatever in the hook).\n\n> Don't you have any user interaction? I.e. if the remote working\n> directory is only ever changed by your hook, you can use what Junio\n> sent. It is even overkill for that purpose.\n\nno, the remote working directory can be edited just like the local\nworking directory. there's user interaction in the form of editing on\nboth ends. otherwise, the committing/syncing process is intended to be\nnon-interactive.\n\nIf we were using a central non-editable repository, we could use\n\"checkout -f\" in the hook we did try that before.\n\nthanks for your help :)\n\n\nSam\n"},{"id":"35337","messageId":"Pine.LNX.4.63.0702231910270.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6925","inReplyTo":"1172250283.5505.1176180417@webmail.messagingengine.com","subject":"Re: git-push hook to update remote working copy safely","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-23T18:13:35Z","receivedAt":"2007-02-23T18:13:35Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 24 Feb 2007, Sam Watkins wrote:\n\n> On Fri, 23 Feb 2007 17:40:02 +0100 (CET), \"Johannes Schindelin\"\n> <Johannes.Schindelin@gmx.de> said:\n> >\n> > On Sat, 24 Feb 2007, Sam Watkins wrote:\n> >\n> > > it should merge the changes as if I'd run git-pull on the remote\n> > > box, and handle conflicts in the same way.\n> >\n> > But that leaves conflicts in the working directory! You _have_ to\n> > resolve them (or reset) before proceding.\n> \n> I think it's ok for our application if the push+hook leaves conflicts in \n> the working directory, I just want to replicate the effect of running \n> git-pull remotely without actually having to go through ssh contortions \n> to achieve that.\n\nI don't really see what you want to do there (and you don't want to tell \nme:-)). Nevertheless, it seems that Junio's script would help you. You \ncannot run a pull sanely when the working directory is dirty, and \ntherefore the hook does not allow that.\n\nBTW the easiest way to do what you apparently want is to push to a \n\"remotely tracking\" branch, i.e. a branch in the remotes/ hierarchy, and \n_then_ make an update hook which says \"git merge remotes/<uploadbranch>\".\n\nCiao,\nDscho\n"},{"id":"35341","messageId":"7v649s4tdk.fsf@assigned-by-dhcp.cox.net","threadId":"6925","inReplyTo":"Pine.LNX.4.63.0702231737300.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: git-push hook to update remote working copy safely","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-23T18:32:39Z","receivedAt":"2007-02-23T18:32:39Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Don't you have any user interaction? I.e. if the remote working directory \n> is only ever changed by your hook, you can use what Junio sent. It is even \n> overkill for that purpose.\n\nAnd it even has a bug (perhaps more, but I know of at least\none).\n\nThe comparison after running merge-base should compare the merge\nbase and the old commit object name.\n"}]}