git@vger.kernel.org list mirror (unofficial, one of many)
 help / color / mirror / code / Atom feed
f4084e33c868593e7a4866ab3e9d8d6e1bc96f6a blob 4014 bytes (raw)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
 
#include "cache.h"

#include "hook.h"
#include "config.h"
#include "run-command.h"

void free_hook(struct hook *ptr)
{
	if (ptr) {
		strbuf_release(&ptr->command);
		free(ptr);
	}
}

static struct hook* find_hook_by_command(struct list_head *head, const char *command)
{
	struct list_head *pos = NULL, *tmp = NULL;
	struct hook *found = NULL;

	list_for_each_safe(pos, tmp, head) {
		struct hook *it = list_entry(pos, struct hook, list);
		if (!strcmp(it->command.buf, command)) {
		    list_del(pos);
		    found = it;
		}
	}
	return found;
}

static void append_or_move_hook(struct list_head *head, const char *command)
{
	struct hook *to_add = find_hook_by_command(head, command);

	if (!to_add) {
		/* adding a new hook, not moving an old one */
		to_add = xmalloc(sizeof(struct hook));
		strbuf_init(&to_add->command, 0);
		strbuf_addstr(&to_add->command, command);
		to_add->from_hookdir = 0;
	}

	/* re-set the scope so we show where an override was specified */
	to_add->origin = current_config_scope();

	list_add_tail(&to_add->list, head);
}

static void remove_hook(struct list_head *to_remove)
{
	struct hook *hook_to_remove = list_entry(to_remove, struct hook, list);
	list_del(to_remove);
	free_hook(hook_to_remove);
}

void clear_hook_list(struct list_head *head)
{
	struct list_head *pos, *tmp;
	list_for_each_safe(pos, tmp, head)
		remove_hook(pos);
}

struct hook_config_cb
{
	struct strbuf *hookname;
	struct list_head *list;
};

static int hook_config_lookup(const char *key, const char *value, void *cb_data)
{
	struct hook_config_cb *data = cb_data;
	const char *hook_key = data->hookname->buf;
	struct list_head *head = data->list;

	if (!strcmp(key, hook_key)) {
		const char *command = value;
		struct strbuf hookcmd_name = STRBUF_INIT;
		int skip = 0;

		/*
		 * Check if we're removing that hook instead. Hookcmds are
		 * removed by name, and inlined hooks are removed by command
		 * content.
		 */
		strbuf_addf(&hookcmd_name, "hookcmd.%s.skip", command);
		git_config_get_bool(hookcmd_name.buf, &skip);

		/* Check if a hookcmd with that name exists. */
		strbuf_reset(&hookcmd_name);
		strbuf_addf(&hookcmd_name, "hookcmd.%s.command", command);
		git_config_get_value(hookcmd_name.buf, &command);

		if (!command) {
			strbuf_release(&hookcmd_name);
			BUG("git_config_get_value overwrote a string it shouldn't have");
		}

		/*
		 * TODO: implement an option-getting callback, e.g.
		 *   get configs by pattern hookcmd.$value.*
		 *   for each key+value, do_callback(key, value, cb_data)
		 */

		if (skip) {
			struct hook *to_remove = find_hook_by_command(head, command);
			if (to_remove)
				remove_hook(&(to_remove->list));
		} else {
			append_or_move_hook(head, command);
		}

		strbuf_release(&hookcmd_name);
	}

	return 0;
}

enum hookdir_opt configured_hookdir_opt(void)
{
	const char *key;
	if (git_config_get_value("hook.runhookdir", &key))
		return hookdir_yes; /* by default, just run it. */

	if (!strcmp(key, "no"))
		return hookdir_no;

	if (!strcmp(key, "yes"))
		return hookdir_yes;

	if (!strcmp(key, "warn"))
		return hookdir_warn;

	if (!strcmp(key, "interactive"))
		return hookdir_interactive;

	return hookdir_unknown;
}

struct list_head* hook_list(const struct strbuf* hookname)
{
	struct strbuf hook_key = STRBUF_INIT;
	struct list_head *hook_head = xmalloc(sizeof(struct list_head));
	struct hook_config_cb cb_data = { &hook_key, hook_head };
	const char *legacy_hook_path = NULL;

	INIT_LIST_HEAD(hook_head);

	if (!hookname)
		return NULL;

	strbuf_addf(&hook_key, "hook.%s.command", hookname->buf);

	git_config(hook_config_lookup, (void*)&cb_data);

	if (have_git_dir())
		legacy_hook_path = find_hook(hookname->buf);

	/* Unconditionally add legacy hook, but annotate it. */
	if (legacy_hook_path) {
		struct hook *legacy_hook;

		append_or_move_hook(hook_head, absolute_path(legacy_hook_path));
		legacy_hook = list_entry(hook_head->prev, struct hook, list);
		legacy_hook->from_hookdir = 1;
	}

	strbuf_release(&hook_key);
	return hook_head;
}
debug log:

solving f4084e33c8 ...
found f4084e33c8 in https://public-inbox.org/git/20201014232447.3050579-6-emilyshaffer@google.com/ ||
	https://public-inbox.org/git/20201205014607.1464119-7-emilyshaffer@google.com/
found 340e5a35c8 in https://public-inbox.org/git/20201205014607.1464119-6-emilyshaffer@google.com/ ||
	https://public-inbox.org/git/20201014232447.3050579-5-emilyshaffer@google.com/
found ffbdcfd987 in https://public-inbox.org/git/20201205014607.1464119-5-emilyshaffer@google.com/ ||
	https://public-inbox.org/git/20201222000220.1491091-5-emilyshaffer@google.com/
found 937dc768c8 in https://public-inbox.org/git/20201014232447.3050579-4-emilyshaffer@google.com/ ||
	https://public-inbox.org/git/20201205014607.1464119-4-emilyshaffer@google.com/ ||
	https://public-inbox.org/git/20201222000220.1491091-4-emilyshaffer@google.com/

applying [1/9] https://public-inbox.org/git/20201014232447.3050579-4-emilyshaffer@google.com/
diff --git a/hook.c b/hook.c
new file mode 100644
index 0000000000..937dc768c8

Checking patch hook.c...
Applied patch hook.c cleanly.

skipping https://public-inbox.org/git/20201205014607.1464119-4-emilyshaffer@google.com/ for 937dc768c8
skipping https://public-inbox.org/git/20201222000220.1491091-4-emilyshaffer@google.com/ for 937dc768c8
index at:
100644 937dc768c8e36783306e39ebac59fa4e808ea1e7	hook.c

applying [2/9] https://public-inbox.org/git/20201205014607.1464119-5-emilyshaffer@google.com/
diff --git a/hook.c b/hook.c
index 937dc768c8..ffbdcfd987 100644

Checking patch hook.c...
Applied patch hook.c cleanly.

skipping https://public-inbox.org/git/20201222000220.1491091-5-emilyshaffer@google.com/ for ffbdcfd987
index at:
100644 ffbdcfd9871bf7ac6649ec6bd28ac910ac64e089	hook.c

applying [3/9] https://public-inbox.org/git/20201205014607.1464119-6-emilyshaffer@google.com/
diff --git a/hook.c b/hook.c
index ffbdcfd987..340e5a35c8 100644

Checking patch hook.c...
Applied patch hook.c cleanly.

skipping https://public-inbox.org/git/20201014232447.3050579-5-emilyshaffer@google.com/ for 340e5a35c8
index at:
100644 340e5a35c8117e27b731bc9d3259c733bebb392d	hook.c

applying [4/9] https://public-inbox.org/git/20201014232447.3050579-6-emilyshaffer@google.com/
diff --git a/hook.c b/hook.c
index 340e5a35c8..f4084e33c8 100644

Checking patch hook.c...
Applied patch hook.c cleanly.

skipping https://public-inbox.org/git/20201205014607.1464119-7-emilyshaffer@google.com/ for f4084e33c8
index at:
100644 f4084e33c868593e7a4866ab3e9d8d6e1bc96f6a	hook.c

Code repositories for project(s) associated with this 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).