Raw
1 #define USE_THE_REPOSITORY_VARIABLE
2
3 #include "builtin.h"
4 #include "config.h"
5 #include "environment.h"
6 #include "gettext.h"
7 #include "parse-options.h"
8 #include "path.h"
9 #include "run-command.h"
10 #include "string-list.h"
11
12 static const char * const for_each_repo_usage[] = {
13 N_("git for-each-repo --config=<config> [--] <arguments>"),
14 NULL
15 };
16
17 static int run_command_on_repo(const char *path, const char **argv)
18 {
19 struct child_process child = CHILD_PROCESS_INIT;
20 char *abspath = interpolate_path(path, 0);
21
22 sanitize_repo_env(&child.env);
23
24 child.git_cmd = 1;
25 strvec_pushl(&child.args, "-C", abspath, NULL);
26 strvec_pushv(&child.args, argv);
27
28 free(abspath);
29
30 return run_command(&child);
31 }
32
33 int cmd_for_each_repo(int argc,
34 const char **argv,
35 const char *prefix,
36 struct repository *repo UNUSED)
37 {
38 static const char *config_key = NULL;
39 int keep_going = 0;
40 int result = 0;
41 const struct string_list *values;
42 int err;
43
44 const struct option options[] = {
45 OPT_STRING(0, "config", &config_key, N_("config"),
46 N_("config key storing a list of repository paths")),
47 OPT_BOOL(0, "keep-going", &keep_going,
48 N_("keep going even if command fails in a repository")),
49 OPT_END()
50 };
51
52 argc = parse_options(argc, argv, prefix, options, for_each_repo_usage,
53 PARSE_OPT_STOP_AT_NON_OPTION);
54
55 if (!config_key)
56 die(_("missing --config=<config>"));
57
58 err = repo_config_get_string_multi(the_repository, config_key, &values);
59 if (err < 0)
60 usage_msg_optf(_("got bad config --config=%s"),
61 for_each_repo_usage, options, config_key);
62 else if (err)
63 return 0;
64
65 for (size_t i = 0; i < values->nr; i++) {
66 int ret = run_command_on_repo(values->items[i].string, argv);
67 if (ret) {
68 if (!keep_going)
69 return ret;
70 result = 1;
71 }
72 }
73
74 return result;
75 }