Wow, nearly a year since my last post. I was sort of thinking it would be something more profound, but here goes: Git recently (with version 2.3) introduced a way of easily pushing changes into a remote non-bare repository, a.k.a. push-to-deploy. The old way would be to have a post-receive hook run some update logic which would do some procedure to update a non-bare repository. There now is a simple way of configuring the target repository to update its work tree instead upon being pushed to.
Now, pushing to the target repo may fail in cases where it has been modified, so soon after, a new push-to-checkout hook was introduced to deal with this, but it will only take effect in Git 2.4. I'll show how to set up both below.
Surprisingly, when searching for "push-to-checkout", I found very few articles about this, even though it was loudly mentioned on the GitHub blog (twice, and on StackOverflow, of course). So here's another one for the googles. Besides, I just wrote this whole example on the Git Users Mailing list and figured I'd repeat it here.
Note that as it happens, I've never found myself in the sorry position of having to deploy this way in real life (real developers package their distributables), so don't take my word this being the way to do it on production systems.
Note that Git version must be >= 2.3 for this to work at all, and must be 2.4 in order for the push-to-checkout hook to take effect.
Take some random repo and clone it to a "remote" location:
So, let's pretend that this non-bare repository is on our web-host:
Configure to update on incoming pushes:
Create the hook:
Contents of the push-to-checkout hook, as exemplified in the test here:
/bin/sh
echo >&2 updating from $(git rev-parse HEAD)
echo >&2 updating to "$1"
git update-index -q --refresh && git read-tree -u -m HEAD "$1" || {
status=$?
echo >&2 read-tree failed
exit $status
}
Make the hook executable
Now let's take it for a spin. Go back to the original repo:
OK, that wasn't very impressive. Make some changes first, a new file heya.txt for example:
Away we go:
Tada!
Now, pushing to the target repo may fail in cases where it has been modified, so soon after, a new push-to-checkout hook was introduced to deal with this, but it will only take effect in Git 2.4. I'll show how to set up both below.
Surprisingly, when searching for "push-to-checkout", I found very few articles about this, even though it was loudly mentioned on the GitHub blog (twice, and on StackOverflow, of course). So here's another one for the googles. Besides, I just wrote this whole example on the Git Users Mailing list and figured I'd repeat it here.
Note that as it happens, I've never found myself in the sorry position of having to deploy this way in real life (real developers package their distributables), so don't take my word this being the way to do it on production systems.
Note that Git version must be >= 2.3 for this to work at all, and must be 2.4 in order for the push-to-checkout hook to take effect.
[master][~/temp/foo-web]$ git --version
git version 2.3.6
Take some random repo and clone it to a "remote" location:
[~/temp]$ git clone foo foo-web
Cloning into 'foo-web'...done.
So, let's pretend that this non-bare repository is on our web-host:
[~/temp]$ cd foo-web
Configure to update on incoming pushes:
[master][~/temp/foo-web]$ git config receive.denyCurrentBranch updateInstead
Create the hook:
[master][~/temp/foo-web]$ vim .git/hooks/push-to-checkout
Contents of the push-to-checkout hook, as exemplified in the test here:
/bin/sh
echo >&2 updating from $(git rev-parse HEAD)
echo >&2 updating to "$1"
git update-index -q --refresh && git read-tree -u -m HEAD "$1" || {
status=$?
echo >&2 read-tree failed
exit $status
}
Make the hook executable
[master][~/temp/foo-web]$ chmod +x .git/hooks/push-to-checkout
Now let's take it for a spin. Go back to the original repo:
[master][~/temp/foo-web]$ cd ..
[~/temp]$ cd foo
[master][~/temp/foo]$ git remote add web ../foo-web
[master][~/temp/foo]$ git push web master
Everything up-to-date
OK, that wasn't very impressive. Make some changes first, a new file heya.txt for example:
[master][~/temp/foo]$ echo `random_word` > heya.txt; git add .;git commit -m `random_word`
[master b6765e2] overpaint 1 file changed, 1 insertion(+) create mode 100644 heya.txt
Away we go:
[master][~/temp/foo]$ git push web master
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 322 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ../foo-web
eb2711a..b6765e2 master -> masterPush succeeded! Now, let's see if our new file arrived OK:
[master][~/temp/foo]$ cd ..
[~/temp]$ cd foo-web
Tada!
[master][~/temp/foo-web]$ ls
README foo heya.txt
Comments
Post a Comment