From: Tejun Heo <tj@kernel.org>
To: git@vger.kernel.org, Junio C Hamano <jch2355@gmail.com>,
Jeff King <peff@peff.net>
Cc: kernel-team@fb.com, Tejun Heo <htejun@fb.com>
Subject: [PATCH 4/5] githooks: Add post-cherry-pick and post-fetch hooks
Date: Tue, 11 Dec 2018 15:49:08 -0800 [thread overview]
Message-ID: <20181211234909.2855638-5-tj@kernel.org> (raw)
In-Reply-To: <20181211234909.2855638-1-tj@kernel.org>
From: Tejun Heo <htejun@fb.com>
* post-cherry-pick: Called after a cherry-pick and given parameters so
that it can tell which are the new cherry-picks.
* post-fetch: Called after a fetch. Each updated ref and sha1 are fed
on stdin.
These two hooks will be used to keep refs/notes/xref-cherry-picks
up-to-date.
Signed-off-by: Tejun Heo <htejun@fb.com>
---
Documentation/git-cherry-pick.txt | 5 +++
Documentation/git-fetch.txt | 5 +++
Documentation/githooks.txt | 23 ++++++++++
builtin/fetch.c | 72 ++++++++++++++++++++++++++++---
builtin/revert.c | 14 ++++++
5 files changed, 114 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt
index d35d771fc..527cb9fea 100644
--- a/Documentation/git-cherry-pick.txt
+++ b/Documentation/git-cherry-pick.txt
@@ -224,6 +224,11 @@ the working tree.
spending extra time to avoid mistakes based on incorrectly matching
context lines.
+HOOKS
+-----
+This command can run `post-cherry-pick` hook. See linkgit:githooks[5]
+for more information.
+
SEE ALSO
--------
linkgit:git-revert[1]
diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt
index e31993559..a04c6079a 100644
--- a/Documentation/git-fetch.txt
+++ b/Documentation/git-fetch.txt
@@ -290,6 +290,11 @@ fetched, making it impossible to check out that submodule later without
having to do a fetch again. This is expected to be fixed in a future Git
version.
+HOOKS
+-----
+This command can run `post-fetch` hook. See linkgit:githooks[5]
+for more information.
+
SEE ALSO
--------
linkgit:git-pull[1]
diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt
index 959044347..24c122343 100644
--- a/Documentation/githooks.txt
+++ b/Documentation/githooks.txt
@@ -149,6 +149,14 @@ invoked after a commit is made.
This hook is meant primarily for notification, and cannot affect
the outcome of `git commit`.
+post-cherry-pick
+~~~~~~~~~~~~~~~~
+
+This hook is invoked by linkgit:git-cherry-pick[1]. This hook is
+called with two parameters. The first is `<old sha1>` and the second
+`<new sha1>`, where `<old sha1>..<new sha1>` describes all new
+cherry-picked commits.
+
pre-rebase
~~~~~~~~~~
@@ -191,6 +199,21 @@ save and restore any form of metadata associated with the working tree
(e.g.: permissions/ownership, ACLS, etc). See contrib/hooks/setgitperms.perl
for an example of how to do this.
+post-fetch
+~~~~~~~~~~
+This hook is called by linkgit:git-fetch[1] and can be used to process
+newly fetched commits and tags.
+
+Information about what was fetched is provided on the hook's standard
+input with lines of the form:
+
+ <local ref> SP <old sha1> SP <remote ref> SP <new sha1> LF
+
+where `<local ref>` got updated from `<old sha1>` to `<new sha1>` as a
+result of fetching `<remote ref>`. If a branch or tag was created,
+`<old_sha1>` will be 40 `0`. If a tag was pruned, `<remote_ref>` will
+be `(delete)` and <new sha1> will be 40 `0`.
+
pre-push
~~~~~~~~
diff --git a/builtin/fetch.c b/builtin/fetch.c
index e0140327a..eac792a33 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -66,6 +66,7 @@ static struct refspec refmap = REFSPEC_INIT_FETCH;
static struct list_objects_filter_options filter_options;
static struct string_list server_options = STRING_LIST_INIT_DUP;
static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP;
+static struct strbuf post_fetch_sb = STRBUF_INIT;
static int git_fetch_config(const char *k, const char *v, void *cb)
{
@@ -510,10 +511,24 @@ static struct ref *get_ref_map(struct remote *remote,
return ref_map;
}
+static void record_post_fetch(const char *name,
+ const struct object_id *old_oid,
+ const char *remote,
+ const struct object_id *new_oid)
+{
+ char old_hex[GIT_MAX_HEXSZ + 1], new_hex[GIT_MAX_HEXSZ + 1];
+
+ oid_to_hex_r(old_hex, old_oid);
+ oid_to_hex_r(new_hex, new_oid);
+ strbuf_addf(&post_fetch_sb, "%s %s %s %s\n",
+ name, old_hex, remote ?: "(delete)", new_hex);
+}
+
#define STORE_REF_ERROR_OTHER 1
#define STORE_REF_ERROR_DF_CONFLICT 2
static int s_update_ref(const char *action,
+ const char *remote,
struct ref *ref,
int check_old)
{
@@ -546,6 +561,7 @@ static int s_update_ref(const char *action,
ref_transaction_free(transaction);
strbuf_release(&err);
free(msg);
+ record_post_fetch(ref->name, &ref->old_oid, remote, &ref->new_oid);
return 0;
fail:
ref_transaction_free(transaction);
@@ -726,7 +742,7 @@ static int update_local_ref(struct ref *ref,
starts_with(ref->name, "refs/tags/")) {
if (force || ref->force) {
int r;
- r = s_update_ref("updating tag", ref, 0);
+ r = s_update_ref("updating tag", remote, ref, 0);
format_display(display, r ? '!' : 't', _("[tag update]"),
r ? _("unable to update local ref") : NULL,
remote, pretty_ref, summary_width);
@@ -766,7 +782,7 @@ static int update_local_ref(struct ref *ref,
if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
(recurse_submodules != RECURSE_SUBMODULES_ON))
check_for_new_submodule_commits(&ref->new_oid);
- r = s_update_ref(msg, ref, 0);
+ r = s_update_ref(msg, remote, ref, 0);
format_display(display, r ? '!' : '*', what,
r ? _("unable to update local ref") : NULL,
remote, pretty_ref, summary_width);
@@ -782,7 +798,7 @@ static int update_local_ref(struct ref *ref,
if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
(recurse_submodules != RECURSE_SUBMODULES_ON))
check_for_new_submodule_commits(&ref->new_oid);
- r = s_update_ref("fast-forward", ref, 1);
+ r = s_update_ref("fast-forward", remote, ref, 1);
format_display(display, r ? '!' : ' ', quickref.buf,
r ? _("unable to update local ref") : NULL,
remote, pretty_ref, summary_width);
@@ -797,7 +813,7 @@ static int update_local_ref(struct ref *ref,
if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
(recurse_submodules != RECURSE_SUBMODULES_ON))
check_for_new_submodule_commits(&ref->new_oid);
- r = s_update_ref("forced-update", ref, 1);
+ r = s_update_ref("forced-update", remote, ref, 1);
format_display(display, r ? '!' : '+', quickref.buf,
r ? _("unable to update local ref") : _("forced update"),
remote, pretty_ref, summary_width);
@@ -1071,8 +1087,11 @@ static int prune_refs(struct refspec *rs, struct ref *ref_map,
if (!dry_run) {
struct string_list refnames = STRING_LIST_INIT_NODUP;
- for (ref = stale_refs; ref; ref = ref->next)
+ for (ref = stale_refs; ref; ref = ref->next) {
string_list_append(&refnames, ref->name);
+ record_post_fetch(ref->name, &ref->old_oid,
+ NULL, &null_oid);
+ }
result = delete_refs("fetch: prune", &refnames, 0);
string_list_clear(&refnames, 0);
@@ -1561,6 +1580,47 @@ static int fetch_one(struct remote *remote, int argc, const char **argv, int pru
return exit_code;
}
+static int run_post_fetch_hook(void)
+{
+ int ret = 0, x;
+ struct child_process proc = CHILD_PROCESS_INIT;
+ const char *argv[2];
+
+ if (!(argv[0] = find_hook("post-fetch")))
+ return 0;
+ argv[1] = NULL;
+
+ proc.argv = argv;
+ proc.in = -1;
+
+ if (start_command(&proc)) {
+ finish_command(&proc);
+ return -1;
+ }
+
+ sigchain_push(SIGPIPE, SIG_IGN);
+
+ if (write_in_full(proc.in, post_fetch_sb.buf, post_fetch_sb.len) < 0) {
+ /* We do not mind if a hook does not read all refs. */
+ if (errno != EPIPE)
+ ret = -1;
+ }
+
+ strbuf_release(&post_fetch_sb);
+
+ x = close(proc.in);
+ if (!ret)
+ ret = x;
+
+ sigchain_pop(SIGPIPE);
+
+ x = finish_command(&proc);
+ if (!ret)
+ ret = x;
+
+ return ret;
+}
+
int cmd_fetch(int argc, const char **argv, const char *prefix)
{
int i;
@@ -1669,6 +1729,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
close_all_packs(the_repository->objects);
+ run_post_fetch_hook();
+
argv_array_pushl(&argv_gc_auto, "gc", "--auto", NULL);
if (verbosity < 0)
argv_array_push(&argv_gc_auto, "--quiet");
diff --git a/builtin/revert.c b/builtin/revert.c
index c93393c89..0b7e578cc 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -8,6 +8,8 @@
#include "dir.h"
#include "sequencer.h"
#include "branch.h"
+#include "refs.h"
+#include "run-command.h"
/*
* This implements the builtins revert and cherry-pick.
@@ -223,12 +225,24 @@ int cmd_revert(int argc, const char **argv, const char *prefix)
int cmd_cherry_pick(int argc, const char **argv, const char *prefix)
{
struct replay_opts opts = REPLAY_OPTS_INIT;
+ struct object_id old_oid, new_oid;
+ char old_hex[GIT_MAX_HEXSZ + 1], new_hex[GIT_MAX_HEXSZ + 1];
int res;
+ if (read_ref("HEAD", &old_oid))
+ die(_("failed to read HEAD, cherry-pick failed"));
+
opts.action = REPLAY_PICK;
sequencer_init_config(&opts);
res = run_sequencer(argc, argv, &opts);
if (res < 0)
die(_("cherry-pick failed"));
+
+ if (read_ref("HEAD", &new_oid))
+ die(_("failed to read HEAD after cherry-pick"));
+
+ oid_to_hex_r(old_hex, &old_oid);
+ oid_to_hex_r(new_hex, &new_oid);
+ run_hook_le(0, "post-cherry-pick", old_hex, new_hex, NULL);
return res;
}
--
2.17.1
next prev parent reply other threads:[~2018-12-11 23:49 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-11 23:49 [PATCHSET] git-reverse-trailer-xrefs: Reverse map cherry-picks and other cross-references Tejun Heo
2018-12-11 23:49 ` [PATCH 1/5] trailer: Implement a helper to reverse-map trailer xrefs Tejun Heo
2018-12-11 23:49 ` [PATCH 2/5] notes: Implement special handlings for refs/notes/xref- Tejun Heo
2018-12-11 23:49 ` [PATCH 3/5] notes: Implement git-reverse-trailer-xrefs Tejun Heo
2018-12-11 23:49 ` Tejun Heo [this message]
2018-12-11 23:49 ` [PATCH 5/5] notes: Implement xref-cherry-picks hooks and tests Tejun Heo
2018-12-12 7:26 ` [PATCHSET] git-reverse-trailer-xrefs: Reverse map cherry-picks and other cross-references Junio C Hamano
2018-12-12 14:54 ` Tejun Heo
2018-12-13 3:01 ` Junio C Hamano
2018-12-13 3:09 ` Junio C Hamano
2018-12-13 3:46 ` Tejun Heo
2018-12-18 14:40 ` Stefan Xenos
2018-12-18 16:48 ` Stefan Xenos
2018-12-18 16:51 ` Tejun Heo
2018-12-13 3:40 ` Tejun Heo
2018-12-13 5:47 ` Junio C Hamano
2018-12-13 16:15 ` Tejun Heo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181211234909.2855638-5-tj@kernel.org \
--to=tj@kernel.org \
--cc=git@vger.kernel.org \
--cc=htejun@fb.com \
--cc=jch2355@gmail.com \
--cc=kernel-team@fb.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
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 read-only IMAP folder(s) and NNTP newsgroup(s).