Reputation:
So, the only hook I use is the post-receive. When I edit this file on my client, I want it to automatically update when I push to the server.
I tried 3 things all of which did not work. In the post-receive hooks I
So, I keep a copy of this file in my repository, but I want it to automatically deploy.
I think the main issue with the methods I try is that the file is being used when I try to update it, that is, it is acting upon itself.
Is there a defacto way to do this?
Upvotes: 2
Views: 5321
Reputation: 1330012
One possibility would be for your post-receive
hook to:
post-receive
script is part of what is pushed.git diff --name-only $1..$2|grep post-receive
).git/hook/post-receive.new
Then you install a pre-receive
hook which simply check for .git/hook/post-receive.new
and rename it as .git/hook/post-receive
.
(Meaning post-receive.new disappear, and the next pre-receive
hook execution will do nothing)
That way, the hook does not update right away, but it will be updated at the next git push
to that same repo.
Note: I thought about detecting and updating the post-receive
file modification directly during the pre-receive
hook execution, but, as explained by torek in "Git pre-receive
hook to check config", this is not trivial:
A
pre-receive
orupdate
hook is called after the new objects (commits, annotated tag objects, trees, and blobs) have been loaded into the repository, but before the references (branch names, tag names, etc) have been changed.
You would need, for each ref pushed, to diff and check for the presence and content of that file.
It is not impossible, as seen in this php script:
function get_changed_files($base, $commit) {
list($code, $stdout, $stderr) = git('diff', '--numstat', '--name-only', '--diff-filter=ACMRTUXB', '--ignore-submodules', "{$base}..{$commit}");
...
return explode("\n", $stdout);
}
function get_new_file($filename, $commit) {
list($code, $stdout, $stderr) = git('show', "{$commit}:{$filename}");
...
return $stdout;
}
...
$line = file_get_contents('php://stdin');
list($base, $commit, $ref) = explode(" ", trim($line));
if ($base == "0000000000000000000000000000000000000000") {
verbose("Initial push received. Expecting everything to be fine");
exit;
}
$modified = get_changed_files($base, $commit);
$result = true;
foreach ($modified as $fname) {
// if fname equals post-receive
$contents = get_new_file($fname, $commit);
// copy it to .git/hooks/post-receive
}
Having a two-step process is easier.
Upvotes: 3