git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Added hook in git-receive-pack
@ 2005-07-31 19:17 Josef Weidendorfer
  2005-07-31 20:11 ` Linus Torvalds
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Josef Weidendorfer @ 2005-07-31 19:17 UTC (permalink / raw)
  To: git

Added hook in git-receive-pack

After successful update of a ref,

 $GIT_DIR/hooks/update refname old-sha1 new-sha2

is called if present. This allows e.g sending of a mail
with pushed commits on the remote repository.
Documentation update with example hook included.

Signed-off-by: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
------------------------------------------------

diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt
--- a/Documentation/git-receive-pack.txt
+++ b/Documentation/git-receive-pack.txt
@@ -20,10 +20,25 @@ This command is usually not invoked dire
 The UI for the protocol is on the 'git-send-pack' side, and the
 program pair is meant to be used to push updates to remote
 repository.  For pull operations, see 'git-fetch-pack' and
 'git-clone-pack'.

+The command allows for creation and fast forwarding of sha1 refs
+(heads/tags) on the local end. After each successful update, the
+following external hook script is called if it is present:
+
+       $GIT_DIR/hooks/update refname sha1-old sha1-new
+
+It is assured that sha1-old is an ancestor of sha1-new (otherwise,
+the update would have not been allowed). refname is relative to
+$GIT_DIR; e.g. for the master head this is "refs/heads/master".
+Using this hook, it is easy to generate mails on updates to
+the local repository. This example script sends a mail with
+the commits pushed to the repository:
+
+       #!/bin/sh
+       git-rev-list --pretty "$3" "^$2" |
+        mail -r $USER -s "New commits on $1" commit-list@mydomain

 OPTIONS
 -------
 <directory>::
        The repository to sync into.
diff --git a/receive-pack.c b/receive-pack.c
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -53,10 +53,53 @@ static int verify_old_ref(const char *na
        if (memcmp(buffer, hex_contents, 40))
                return -1;
        return 0;
 }

+static const char *update_hook = "hooks/update";
+
+static void updatehook(const char *name, unsigned char *old_sha1, unsigned char *new_sha1)
+{
+        if (access(update_hook, X_OK) < 0) return;
+       fprintf(stderr, "executing update hook for %s\n", name);
+
+       pid_t pid = fork();
+
+       if (pid < 0)
+               die("hook fork failed");
+       if (!pid) {
+               execlp(update_hook, update_hook, name, old_sha1, new_sha1, NULL);
+               die("hook execute failed");
+       }
+
+       for (;;) {
+               int status, code;
+               int retval = waitpid(pid, &status, 0);
+
+               if (retval < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       die("waitpid failed (%s)", strerror(retval));
+               }
+               if (retval != pid)
+                       die("waitpid is confused");
+               if (WIFSIGNALED(status)) {
+                   fprintf(stderr, "%s died of signal %d",
+                           update_hook, WTERMSIG(status));
+                   return;
+               }
+               if (!WIFEXITED(status))
+                       die("%s died out of really strange complications",
+                           update_hook);
+               code = WEXITSTATUS(status);
+               if (code)
+                   fprintf(stderr, "%s exited with error code %d",
+                           update_hook, code);
+               return;
+       }
+}
+
 static void update(const char *name, unsigned char *old_sha1, unsigned char *new_sha1)
 {
        char new_hex[60], *old_hex, *lock_name;
        int newfd, namelen, written;

@@ -93,10 +136,12 @@ static void update(const char *name, uns
        if (rename(lock_name, name) < 0) {
                unlink(lock_name);
                die("unable to replace %s", name);
        }
        fprintf(stderr, "%s: %s -> %s\n", name, old_hex, new_hex);
+
+       updatehook(name, old_hex, new_hex);
 }


 /*
  * This gets called after(if) we've successfully

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2005-08-13 20:40 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-07-31 19:17 [PATCH] Added hook in git-receive-pack Josef Weidendorfer
2005-07-31 20:11 ` Linus Torvalds
2005-07-31 20:33   ` Junio C Hamano
2005-07-31 22:50     ` Linus Torvalds
2005-07-31 23:24       ` Junio C Hamano
2005-07-31 23:31         ` Johannes Schindelin
2005-07-31 23:33         ` Linus Torvalds
2005-08-01  0:11           ` Junio C Hamano
2005-08-01  0:25             ` Linus Torvalds
2005-07-31 20:15 ` Junio C Hamano
2005-07-31 23:17   ` Josef Weidendorfer
2005-08-01  8:14     ` Junio C Hamano
2005-08-13 18:31 ` Josef Weidendorfer
2005-08-13 19:27   ` Junio C Hamano
2005-08-13 20:39     ` Josef Weidendorfer

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