aboutsummaryrefslogtreecommitdiffstats
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/annotate.c20
-rw-r--r--builtin/checkout.c2
-rw-r--r--builtin/clone.c27
-rw-r--r--builtin/config.c4
-rw-r--r--builtin/difftool.c6
-rw-r--r--builtin/fetch-pack.c14
-rw-r--r--builtin/fetch.c3
-rw-r--r--builtin/fsmonitor--daemon.c7
-rw-r--r--builtin/gc.c189
-rw-r--r--builtin/help.c16
-rw-r--r--builtin/index-pack.c7
-rw-r--r--builtin/ls-remote.c1
-rw-r--r--builtin/pack-redundant.c40
-rw-r--r--builtin/pull.c11
-rw-r--r--builtin/push.c10
-rw-r--r--builtin/receive-pack.c5
-rw-r--r--builtin/repack.c57
-rw-r--r--builtin/revert.c17
-rw-r--r--builtin/send-pack.c3
-rw-r--r--builtin/sparse-checkout.c5
-rw-r--r--builtin/stash.c4
-rw-r--r--builtin/submodule--helper.c41
-rw-r--r--builtin/worktree.c16
23 files changed, 370 insertions, 135 deletions
diff --git a/builtin/annotate.c b/builtin/annotate.c
index ce3dfaafb2..7f754f2309 100644
--- a/builtin/annotate.c
+++ b/builtin/annotate.c
@@ -14,13 +14,23 @@ int cmd_annotate(int argc,
struct repository *repo)
{
struct strvec args = STRVEC_INIT;
- int i;
+ const char **args_copy;
+ int ret;
strvec_pushl(&args, "annotate", "-c", NULL);
-
- for (i = 1; i < argc; i++) {
+ for (int i = 1; i < argc; i++)
strvec_push(&args, argv[i]);
- }
- return cmd_blame(args.nr, args.v, prefix, repo);
+ /*
+ * `cmd_blame()` ends up modifying the array, which causes memory leaks
+ * if we didn't copy the array here.
+ */
+ CALLOC_ARRAY(args_copy, args.nr + 1);
+ COPY_ARRAY(args_copy, args.v, args.nr);
+
+ ret = cmd_blame(args.nr, args_copy, prefix, repo);
+
+ strvec_clear(&args);
+ free(args_copy);
+ return ret;
}
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 9c30000d3a..c449558e66 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -1716,7 +1716,7 @@ static struct option *add_common_switch_branch_options(
N_("update ignored files (default)"),
PARSE_OPT_NOCOMPLETE),
OPT_BOOL(0, "ignore-other-worktrees", &opts->ignore_other_worktrees,
- N_("do not check if another worktree is holding the given ref")),
+ N_("do not check if another worktree is using this branch")),
OPT_END()
};
struct option *newopts = parse_options_concat(prevopts, options);
diff --git a/builtin/clone.c b/builtin/clone.c
index e77339c847..59fcb317a6 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1403,8 +1403,17 @@ int cmd_clone(int argc,
* data from the --bundle-uri option.
*/
if (bundle_uri) {
+ struct remote_state *state;
int has_heuristic = 0;
+ /*
+ * We need to save the remote state as our remote's lifetime is
+ * tied to it.
+ */
+ state = the_repository->remote_state;
+ the_repository->remote_state = NULL;
+ repo_clear(the_repository);
+
/* At this point, we need the_repository to match the cloned repo. */
if (repo_init(the_repository, git_dir, work_tree))
warning(_("failed to initialize the repo, skipping bundle URI"));
@@ -1413,6 +1422,10 @@ int cmd_clone(int argc,
bundle_uri);
else if (has_heuristic)
git_config_set_gently("fetch.bundleuri", bundle_uri);
+
+ remote_state_clear(the_repository->remote_state);
+ free(the_repository->remote_state);
+ the_repository->remote_state = state;
} else {
/*
* Populate transport->got_remote_bundle_uri and
@@ -1422,12 +1435,26 @@ int cmd_clone(int argc,
if (transport->bundles &&
hashmap_get_size(&transport->bundles->bundles)) {
+ struct remote_state *state;
+
+ /*
+ * We need to save the remote state as our remote's
+ * lifetime is tied to it.
+ */
+ state = the_repository->remote_state;
+ the_repository->remote_state = NULL;
+ repo_clear(the_repository);
+
/* At this point, we need the_repository to match the cloned repo. */
if (repo_init(the_repository, git_dir, work_tree))
warning(_("failed to initialize the repo, skipping bundle URI"));
else if (fetch_bundle_list(the_repository,
transport->bundles))
warning(_("failed to fetch advertised bundles"));
+
+ remote_state_clear(the_repository->remote_state);
+ free(the_repository->remote_state);
+ the_repository->remote_state = state;
} else {
clear_bundle_list(transport->bundles);
FREE_AND_NULL(transport->bundles);
diff --git a/builtin/config.c b/builtin/config.c
index d8fd3def0e..cba7022108 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -19,7 +19,7 @@ static const char *const builtin_config_usage[] = {
N_("git config list [<file-option>] [<display-option>] [--includes]"),
N_("git config get [<file-option>] [<display-option>] [--includes] [--all] [--regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>"),
N_("git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--fixed-value] <name> <value>"),
- N_("git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] <name> <value>"),
+ N_("git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] <name>"),
N_("git config rename-section [<file-option>] <old-name> <new-name>"),
N_("git config remove-section [<file-option>] <name>"),
N_("git config edit [<file-option>]"),
@@ -43,7 +43,7 @@ static const char *const builtin_config_set_usage[] = {
};
static const char *const builtin_config_unset_usage[] = {
- N_("git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] <name> <value>"),
+ N_("git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] <name>"),
NULL
};
diff --git a/builtin/difftool.c b/builtin/difftool.c
index 4b416743ff..5772e82106 100644
--- a/builtin/difftool.c
+++ b/builtin/difftool.c
@@ -662,6 +662,12 @@ finish:
if (fp)
fclose(fp);
+ hashmap_clear_and_free(&working_tree_dups, struct working_tree_entry, entry);
+ hashmap_clear_and_free(&wt_modified, struct path_entry, entry);
+ hashmap_clear_and_free(&tmp_modified, struct path_entry, entry);
+ hashmap_clear_and_free(&submodules, struct pair_entry, entry);
+ hashmap_clear_and_free(&symlinks2, struct pair_entry, entry);
+ release_index(&wtindex);
free(lbase_dir);
free(rbase_dir);
strbuf_release(&info);
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 49222a36fa..62e8c3aa6b 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -53,6 +53,7 @@ int cmd_fetch_pack(int argc,
struct ref *fetched_refs = NULL, *remote_refs = NULL;
const char *dest = NULL;
struct ref **sought = NULL;
+ struct ref **sought_to_free = NULL;
int nr_sought = 0, alloc_sought = 0;
int fd[2];
struct string_list pack_lockfiles = STRING_LIST_INIT_DUP;
@@ -243,6 +244,13 @@ int cmd_fetch_pack(int argc,
BUG("unknown protocol version");
}
+ /*
+ * Create a shallow copy of `sought` so that we can free all of its entries.
+ * This is because `fetch_pack()` will modify the array to evict some
+ * entries, but won't free those.
+ */
+ DUP_ARRAY(sought_to_free, sought, nr_sought);
+
fetched_refs = fetch_pack(&args, fd, remote_refs, sought, nr_sought,
&shallow, pack_lockfiles_ptr, version);
@@ -280,9 +288,13 @@ int cmd_fetch_pack(int argc,
oid_to_hex(&ref->old_oid), ref->name);
for (size_t i = 0; i < nr_sought; i++)
- free_one_ref(sought[i]);
+ free_one_ref(sought_to_free[i]);
+ free(sought_to_free);
free(sought);
free_refs(fetched_refs);
free_refs(remote_refs);
+ list_objects_filter_release(&args.filter_options);
+ oid_array_clear(&shallow);
+ string_list_clear(&pack_lockfiles, 0);
return ret;
}
diff --git a/builtin/fetch.c b/builtin/fetch.c
index c900f57721..d9027e4dc9 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -456,6 +456,7 @@ static void filter_prefetch_refspec(struct refspec *rs)
free(rs->items[i].src);
free(rs->items[i].dst);
+ free(rs->raw[i]);
for (j = i + 1; j < rs->nr; j++) {
rs->items[j - 1] = rs->items[j];
@@ -1980,6 +1981,8 @@ static int fetch_multiple(struct string_list *list, int max_children,
strvec_pushl(&argv, "-c", "fetch.bundleURI=",
"fetch", "--append", "--no-auto-gc",
"--no-write-commit-graph", NULL);
+ for (i = 0; i < server_options.nr; i++)
+ strvec_pushf(&argv, "--server-option=%s", server_options.items[i].string);
add_options_to_argv(&argv, config);
if (max_children != 1 && list->nr != 1) {
diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c
index dce8a3b248..f3f6bd330b 100644
--- a/builtin/fsmonitor--daemon.c
+++ b/builtin/fsmonitor--daemon.c
@@ -1208,9 +1208,9 @@ static int fsmonitor_run_daemon_1(struct fsmonitor_daemon_state *state)
* system event listener thread so that we have the IPC handle
* before we need it.
*/
- if (ipc_server_run_async(&state->ipc_server_data,
- state->path_ipc.buf, &ipc_opts,
- handle_client, state))
+ if (ipc_server_init_async(&state->ipc_server_data,
+ state->path_ipc.buf, &ipc_opts,
+ handle_client, state))
return error_errno(
_("could not start IPC thread pool on '%s'"),
state->path_ipc.buf);
@@ -1314,6 +1314,7 @@ static int fsmonitor_run_daemon(void)
strbuf_reset(&state.path_gitdir_watch);
strbuf_addstr(&state.path_gitdir_watch,
absolute_path(repo_get_git_dir(the_repository)));
+ strbuf_strip_suffix(&state.path_gitdir_watch, "/.");
state.nr_paths_watching = 2;
}
diff --git a/builtin/gc.c b/builtin/gc.c
index c3894fb6bd..d52735354c 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -1478,9 +1478,9 @@ static int maintenance_run_tasks(struct maintenance_run_opts *opts,
static void initialize_maintenance_strategy(void)
{
- char *config_str;
+ const char *config_str;
- if (git_config_get_string("maintenance.strategy", &config_str))
+ if (git_config_get_string_tmp("maintenance.strategy", &config_str))
return;
if (!strcasecmp(config_str, "incremental")) {
@@ -1768,6 +1768,42 @@ static const char *get_frequency(enum schedule_priority schedule)
}
}
+static const char *extraconfig[] = {
+ "credential.interactive=false",
+ "core.askPass=true", /* 'true' returns success, but no output. */
+ NULL
+};
+
+static const char *get_extra_config_parameters(void) {
+ static const char *result = NULL;
+ struct strbuf builder = STRBUF_INIT;
+
+ if (result)
+ return result;
+
+ for (const char **s = extraconfig; s && *s; s++)
+ strbuf_addf(&builder, "-c %s ", *s);
+
+ result = strbuf_detach(&builder, NULL);
+ return result;
+}
+
+static const char *get_extra_launchctl_strings(void) {
+ static const char *result = NULL;
+ struct strbuf builder = STRBUF_INIT;
+
+ if (result)
+ return result;
+
+ for (const char **s = extraconfig; s && *s; s++) {
+ strbuf_addstr(&builder, "<string>-c</string>\n");
+ strbuf_addf(&builder, "<string>%s</string>\n", *s);
+ }
+
+ result = strbuf_detach(&builder, NULL);
+ return result;
+}
+
/*
* get_schedule_cmd` reads the GIT_TEST_MAINT_SCHEDULER environment variable
* to mock the schedulers that `git maintenance start` rely on.
@@ -1782,39 +1818,43 @@ static const char *get_frequency(enum schedule_priority schedule)
* * If $GIT_TEST_MAINT_SCHEDULER is set, return true.
* In this case, the *cmd value is read as input.
*
- * * if the input value *cmd is the key of one of the comma-separated list
- * item, then *is_available is set to true and *cmd is modified and becomes
+ * * if the input value cmd is the key of one of the comma-separated list
+ * item, then *is_available is set to true and *out is set to
* the mock command.
*
* * if the input value *cmd isn’t the key of any of the comma-separated list
- * item, then *is_available is set to false.
+ * item, then *is_available is set to false and *out is set to the original
+ * command.
*
* Ex.:
* GIT_TEST_MAINT_SCHEDULER not set
* +-------+-------------------------------------------------+
* | Input | Output |
- * | *cmd | return code | *cmd | *is_available |
+ * | *cmd | return code | *out | *is_available |
* +-------+-------------+-------------------+---------------+
- * | "foo" | false | "foo" (unchanged) | (unchanged) |
+ * | "foo" | false | "foo" (allocated) | (unchanged) |
* +-------+-------------+-------------------+---------------+
*
* GIT_TEST_MAINT_SCHEDULER set to “foo:./mock_foo.sh,bar:./mock_bar.sh”
* +-------+-------------------------------------------------+
* | Input | Output |
- * | *cmd | return code | *cmd | *is_available |
+ * | *cmd | return code | *out | *is_available |
* +-------+-------------+-------------------+---------------+
* | "foo" | true | "./mock.foo.sh" | true |
- * | "qux" | true | "qux" (unchanged) | false |
+ * | "qux" | true | "qux" (allocated) | false |
* +-------+-------------+-------------------+---------------+
*/
-static int get_schedule_cmd(const char **cmd, int *is_available)
+static int get_schedule_cmd(const char *cmd, int *is_available, char **out)
{
char *testing = xstrdup_or_null(getenv("GIT_TEST_MAINT_SCHEDULER"));
struct string_list_item *item;
struct string_list list = STRING_LIST_INIT_NODUP;
- if (!testing)
+ if (!testing) {
+ if (out)
+ *out = xstrdup(cmd);
return 0;
+ }
if (is_available)
*is_available = 0;
@@ -1826,16 +1866,22 @@ static int get_schedule_cmd(const char **cmd, int *is_available)
if (string_list_split_in_place(&pair, item->string, ":", 2) != 2)
continue;
- if (!strcmp(*cmd, pair.items[0].string)) {
- *cmd = pair.items[1].string;
+ if (!strcmp(cmd, pair.items[0].string)) {
+ if (out)
+ *out = xstrdup(pair.items[1].string);
if (is_available)
*is_available = 1;
- string_list_clear(&list, 0);
- UNLEAK(testing);
- return 1;
+ string_list_clear(&pair, 0);
+ goto out;
}
+
+ string_list_clear(&pair, 0);
}
+ if (out)
+ *out = xstrdup(cmd);
+
+out:
string_list_clear(&list, 0);
free(testing);
return 1;
@@ -1852,9 +1898,8 @@ static int get_random_minute(void)
static int is_launchctl_available(void)
{
- const char *cmd = "launchctl";
int is_available;
- if (get_schedule_cmd(&cmd, &is_available))
+ if (get_schedule_cmd("launchctl", &is_available, NULL))
return is_available;
#ifdef __APPLE__
@@ -1892,12 +1937,12 @@ static char *launchctl_get_uid(void)
static int launchctl_boot_plist(int enable, const char *filename)
{
- const char *cmd = "launchctl";
+ char *cmd;
int result;
struct child_process child = CHILD_PROCESS_INIT;
char *uid = launchctl_get_uid();
- get_schedule_cmd(&cmd, NULL);
+ get_schedule_cmd("launchctl", NULL, &cmd);
strvec_split(&child.args, cmd);
strvec_pushl(&child.args, enable ? "bootstrap" : "bootout", uid,
filename, NULL);
@@ -1910,6 +1955,7 @@ static int launchctl_boot_plist(int enable, const char *filename)
result = finish_command(&child);
+ free(cmd);
free(uid);
return result;
}
@@ -1961,10 +2007,10 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
static unsigned long lock_file_timeout_ms = ULONG_MAX;
struct strbuf plist = STRBUF_INIT, plist2 = STRBUF_INIT;
struct stat st;
- const char *cmd = "launchctl";
+ char *cmd;
int minute = get_random_minute();
- get_schedule_cmd(&cmd, NULL);
+ get_schedule_cmd("launchctl", NULL, &cmd);
preamble = "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
"<plist version=\"1.0\">"
@@ -1974,6 +2020,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
"<array>\n"
"<string>%s/git</string>\n"
"<string>--exec-path=%s</string>\n"
+ "%s" /* For extra config parameters. */
"<string>for-each-repo</string>\n"
"<string>--keep-going</string>\n"
"<string>--config=maintenance.repo</string>\n"
@@ -1983,7 +2030,8 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
"</array>\n"
"<key>StartCalendarInterval</key>\n"
"<array>\n";
- strbuf_addf(&plist, preamble, name, exec_path, exec_path, frequency);
+ strbuf_addf(&plist, preamble, name, exec_path, exec_path,
+ get_extra_launchctl_strings(), frequency);
switch (schedule) {
case SCHEDULE_HOURLY:
@@ -2054,6 +2102,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
free(filename);
free(name);
+ free(cmd);
strbuf_release(&plist);
strbuf_release(&plist2);
return 0;
@@ -2078,9 +2127,8 @@ static int launchctl_update_schedule(int run_maintenance, int fd UNUSED)
static int is_schtasks_available(void)
{
- const char *cmd = "schtasks";
int is_available;
- if (get_schedule_cmd(&cmd, &is_available))
+ if (get_schedule_cmd("schtasks", &is_available, NULL))
return is_available;
#ifdef GIT_WINDOWS_NATIVE
@@ -2099,15 +2147,16 @@ static char *schtasks_task_name(const char *frequency)
static int schtasks_remove_task(enum schedule_priority schedule)
{
- const char *cmd = "schtasks";
+ char *cmd;
struct child_process child = CHILD_PROCESS_INIT;
const char *frequency = get_frequency(schedule);
char *name = schtasks_task_name(frequency);
- get_schedule_cmd(&cmd, NULL);
+ get_schedule_cmd("schtasks", NULL, &cmd);
strvec_split(&child.args, cmd);
strvec_pushl(&child.args, "/delete", "/tn", name, "/f", NULL);
free(name);
+ free(cmd);
return run_command(&child);
}
@@ -2121,7 +2170,7 @@ static int schtasks_remove_tasks(void)
static int schtasks_schedule_task(const char *exec_path, enum schedule_priority schedule)
{
- const char *cmd = "schtasks";
+ char *cmd;
int result;
struct child_process child = CHILD_PROCESS_INIT;
const char *xml;
@@ -2131,7 +2180,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority
struct strbuf tfilename = STRBUF_INIT;
int minute = get_random_minute();
- get_schedule_cmd(&cmd, NULL);
+ get_schedule_cmd("schtasks", NULL, &cmd);
strbuf_addf(&tfilename, "%s/schedule_%s_XXXXXX",
repo_get_common_dir(the_repository), frequency);
@@ -2218,11 +2267,12 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority
"<Actions Context=\"Author\">\n"
"<Exec>\n"
"<Command>\"%s\\headless-git.exe\"</Command>\n"
- "<Arguments>--exec-path=\"%s\" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%s</Arguments>\n"
+ "<Arguments>--exec-path=\"%s\" %s for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%s</Arguments>\n"
"</Exec>\n"
"</Actions>\n"
"</Task>\n";
- fprintf(tfile->fp, xml, exec_path, exec_path, frequency);
+ fprintf(tfile->fp, xml, exec_path, exec_path,
+ get_extra_config_parameters(), frequency);
strvec_split(&child.args, cmd);
strvec_pushl(&child.args, "/create", "/tn", name, "/f", "/xml",
get_tempfile_path(tfile), NULL);
@@ -2237,6 +2287,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority
delete_tempfile(&tfile);
free(name);
+ free(cmd);
return result;
}
@@ -2278,21 +2329,28 @@ static int check_crontab_process(const char *cmd)
static int is_crontab_available(void)
{
- const char *cmd = "crontab";
+ char *cmd;
int is_available;
+ int ret;
- if (get_schedule_cmd(&cmd, &is_available))
- return is_available;
+ if (get_schedule_cmd("crontab", &is_available, &cmd)) {
+ ret = is_available;
+ goto out;
+ }
#ifdef __APPLE__
/*
* macOS has cron, but it requires special permissions and will
* create a UI alert when attempting to run this command.
*/
- return 0;
+ ret = 0;
#else
- return check_crontab_process(cmd);
+ ret = check_crontab_process(cmd);
#endif
+
+out:
+ free(cmd);
+ return ret;
}
#define BEGIN_LINE "# BEGIN GIT MAINTENANCE SCHEDULE"
@@ -2300,7 +2358,7 @@ static int is_crontab_available(void)
static int crontab_update_schedule(int run_maintenance, int fd)
{
- const char *cmd = "crontab";
+ char *cmd;
int result = 0;
int in_old_region = 0;
struct child_process crontab_list = CHILD_PROCESS_INIT;
@@ -2310,15 +2368,17 @@ static int crontab_update_schedule(int run_maintenance, int fd)
struct tempfile *tmpedit = NULL;
int minute = get_random_minute();
- get_schedule_cmd(&cmd, NULL);
+ get_schedule_cmd("crontab", NULL, &cmd);
strvec_split(&crontab_list.args, cmd);
strvec_push(&crontab_list.args, "-l");
crontab_list.in = -1;
crontab_list.out = dup(fd);
crontab_list.git_cmd = 0;
- if (start_command(&crontab_list))
- return error(_("failed to run 'crontab -l'; your system might not support 'cron'"));
+ if (start_command(&crontab_list)) {
+ result = error(_("failed to run 'crontab -l'; your system might not support 'cron'"));
+ goto out;
+ }
/* Ignore exit code, as an empty crontab will return error. */
finish_command(&crontab_list);
@@ -2363,8 +2423,8 @@ static int crontab_update_schedule(int run_maintenance, int fd)
"# replaced in the future by a Git command.\n\n");
strbuf_addf(&line_format,
- "%%d %%s * * %%s \"%s/git\" --exec-path=\"%s\" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%%s\n",
- exec_path, exec_path);
+ "%%d %%s * * %%s \"%s/git\" --exec-path=\"%s\" %s for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%%s\n",
+ exec_path, exec_path, get_extra_config_parameters());
fprintf(cron_in, line_format.buf, minute, "1-23", "*", "hourly");
fprintf(cron_in, line_format.buf, minute, "0", "1-6", "daily");
fprintf(cron_in, line_format.buf, minute, "0", "0", "weekly");
@@ -2388,8 +2448,10 @@ static int crontab_update_schedule(int run_maintenance, int fd)
result = error(_("'crontab' died"));
else
fclose(cron_list);
+
out:
delete_tempfile(&tmpedit);
+ free(cmd);
return result;
}
@@ -2412,10 +2474,9 @@ static int real_is_systemd_timer_available(void)
static int is_systemd_timer_available(void)
{
- const char *cmd = "systemctl";
int is_available;
- if (get_schedule_cmd(&cmd, &is_available))
+ if (get_schedule_cmd("systemctl", &is_available, NULL))
return is_available;
return real_is_systemd_timer_available();
@@ -2564,7 +2625,7 @@ static int systemd_timer_write_service_template(const char *exec_path)
"\n"
"[Service]\n"
"Type=oneshot\n"
- "ExecStart=\"%s/git\" --exec-path=\"%s\" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%%i\n"
+ "ExecStart=\"%s/git\" --exec-path=\"%s\" %s for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%%i\n"
"LockPersonality=yes\n"
"MemoryDenyWriteExecute=yes\n"
"NoNewPrivileges=yes\n"
@@ -2574,7 +2635,7 @@ static int systemd_timer_write_service_template(const char *exec_path)
"RestrictSUIDSGID=yes\n"
"SystemCallArchitectures=native\n"
"SystemCallFilter=@system-service\n";
- if (fprintf(file, unit, exec_path, exec_path) < 0) {
+ if (fprintf(file, unit, exec_path, exec_path, get_extra_config_parameters()) < 0) {
error(_("failed to write to '%s'"), filename);
fclose(file);
goto error;
@@ -2596,9 +2657,10 @@ static int systemd_timer_enable_unit(int enable,
enum schedule_priority schedule,
int minute)
{
- const char *cmd = "systemctl";
+ char *cmd = NULL;
struct child_process child = CHILD_PROCESS_INIT;
const char *frequency = get_frequency(schedule);
+ int ret;
/*
* Disabling the systemd unit while it is already disabled makes
@@ -2609,20 +2671,25 @@ static int systemd_timer_enable_unit(int enable,
* On the other hand, enabling a systemd unit which is already enabled
* produces no error.
*/
- if (!enable)
+ if (!enable) {
child.no_stderr = 1;
- else if (systemd_timer_write_timer_file(schedule, minute))
- return -1;
+ } else if (systemd_timer_write_timer_file(schedule, minute)) {
+ ret = -1;
+ goto out;
+ }
- get_schedule_cmd(&cmd, NULL);
+ get_schedule_cmd("systemctl", NULL, &cmd);
strvec_split(&child.args, cmd);
strvec_pushl(&child.args, "--user", enable ? "enable" : "disable",
"--now", NULL);
strvec_pushf(&child.args, SYSTEMD_UNIT_FORMAT, frequency, "timer");
- if (start_command(&child))
- return error(_("failed to start systemctl"));
- if (finish_command(&child))
+ if (start_command(&child)) {
+ ret = error(_("failed to start systemctl"));
+ goto out;
+ }
+
+ if (finish_command(&child)) {
/*
* Disabling an already disabled systemd unit makes
* systemctl fail.
@@ -2630,9 +2697,17 @@ static int systemd_timer_enable_unit(int enable,
*
* Enabling an enabled systemd unit doesn't fail.
*/
- if (enable)
- return error(_("failed to run systemctl"));
- return 0;
+ if (enable) {
+ ret = error(_("failed to run systemctl"));
+ goto out;
+ }
+ }
+
+ ret = 0;
+
+out:
+ free(cmd);
+ return ret;
}
/*
diff --git a/builtin/help.c b/builtin/help.c
index a509241a80..4a5a079070 100644
--- a/builtin/help.c
+++ b/builtin/help.c
@@ -54,7 +54,7 @@ static enum help_action {
HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION,
} cmd_mode;
-static const char *html_path;
+static char *html_path;
static int verbose = 1;
static enum help_format help_format = HELP_FORMAT_NONE;
static int exclude_guides;
@@ -411,6 +411,7 @@ static int git_help_config(const char *var, const char *value,
if (!strcmp(var, "help.htmlpath")) {
if (!value)
return config_error_nonbool(var);
+ free(html_path);
html_path = xstrdup(value);
return 0;
}
@@ -515,23 +516,24 @@ static void show_info_page(const char *page)
static void get_html_page_path(struct strbuf *page_path, const char *page)
{
struct stat st;
+ const char *path = html_path;
char *to_free = NULL;
- if (!html_path)
- html_path = to_free = system_path(GIT_HTML_PATH);
+ if (!path)
+ path = to_free = system_path(GIT_HTML_PATH);
/*
* Check that the page we're looking for exists.
*/
- if (!strstr(html_path, "://")) {
- if (stat(mkpath("%s/%s.html", html_path, page), &st)
+ if (!strstr(path, "://")) {
+ if (stat(mkpath("%s/%s.html", path, page), &st)
|| !S_ISREG(st.st_mode))
die("'%s/%s.html': documentation file not found.",
- html_path, page);
+ path, page);
}
strbuf_init(page_path, 0);
- strbuf_addf(page_path, "%s/%s.html", html_path, page);
+ strbuf_addf(page_path, "%s/%s.html", path, page);
free(to_free);
}
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index e228c56ff2..9d23b41b3a 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1505,7 +1505,7 @@ static void rename_tmp_packfile(const char **final_name,
struct strbuf *name, unsigned char *hash,
const char *ext, int make_read_only_if_same)
{
- if (*final_name != curr_name) {
+ if (!*final_name || strcmp(*final_name, curr_name)) {
if (!*final_name)
*final_name = odb_pack_name(name, hash, ext);
if (finalize_object_file(curr_name, *final_name))
@@ -1726,7 +1726,7 @@ int cmd_index_pack(int argc,
{
int i, fix_thin_pack = 0, verify = 0, stat_only = 0, rev_index;
const char *curr_index;
- const char *curr_rev_index = NULL;
+ char *curr_rev_index = NULL;
const char *index_name = NULL, *pack_name = NULL, *rev_index_name = NULL;
const char *keep_msg = NULL;
const char *promisor_msg = NULL;
@@ -1968,8 +1968,7 @@ int cmd_index_pack(int argc,
free((void *) curr_pack);
if (!index_name)
free((void *) curr_index);
- if (!rev_index_name)
- free((void *) curr_rev_index);
+ free(curr_rev_index);
/*
* Let the caller know this pack is not self contained
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index f723b3bf3b..423318f87e 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -173,5 +173,6 @@ int cmd_ls_remote(int argc,
transport_ls_refs_options_release(&transport_options);
strvec_clear(&pattern);
+ string_list_clear(&server_options, 0);
return status;
}
diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c
index 81f4494d46..5809613002 100644
--- a/builtin/pack-redundant.c
+++ b/builtin/pack-redundant.c
@@ -69,6 +69,15 @@ static inline void llist_init(struct llist **list)
(*list)->size = 0;
}
+static void llist_free(struct llist *list)
+{
+ for (struct llist_item *i = list->front, *next; i; i = next) {
+ next = i->next;
+ llist_item_put(i);
+ }
+ free(list);
+}
+
static struct llist * llist_copy(struct llist *list)
{
struct llist *ret;
@@ -206,6 +215,14 @@ static inline struct pack_list * pack_list_insert(struct pack_list **pl,
return p;
}
+static void pack_list_free(struct pack_list *pl)
+{
+ for (struct pack_list *next; pl; pl = next) {
+ next = pl->next;
+ free(pl);
+ }
+}
+
static inline size_t pack_list_size(struct pack_list *pl)
{
size_t ret = 0;
@@ -419,7 +436,8 @@ static void minimize(struct pack_list **min)
/* return if there are no objects missing from the unique set */
if (missing->size == 0) {
- free(missing);
+ llist_free(missing);
+ pack_list_free(non_unique);
return;
}
@@ -434,6 +452,8 @@ static void minimize(struct pack_list **min)
}
while (non_unique) {
+ struct pack_list *next;
+
/* sort the non_unique packs, greater size of remaining_objects first */
sort_pack_list(&non_unique);
if (non_unique->remaining_objects->size == 0)
@@ -444,8 +464,14 @@ static void minimize(struct pack_list **min)
for (pl = non_unique->next; pl && pl->remaining_objects->size > 0; pl = pl->next)
llist_sorted_difference_inplace(pl->remaining_objects, non_unique->remaining_objects);
- non_unique = non_unique->next;
+ next = non_unique->next;
+ free(non_unique);
+ non_unique = next;
}
+
+ pack_list_free(non_unique);
+ llist_free(unique_pack_objects);
+ llist_free(missing);
}
static void load_all_objects(void)
@@ -565,7 +591,6 @@ static void load_all(void)
int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, struct repository *repo UNUSED) {
int i; int i_still_use_this = 0; struct pack_list *min = NULL, *red, *pl;
struct llist *ignore;
- struct object_id *oid;
char buf[GIT_MAX_HEXSZ + 2]; /* hex hash + \n + \0 */
if (argc == 2 && !strcmp(argv[1], "-h"))
@@ -625,11 +650,11 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s
/* ignore objects given on stdin */
llist_init(&ignore);
if (!isatty(0)) {
+ struct object_id oid;
while (fgets(buf, sizeof(buf), stdin)) {
- oid = xmalloc(sizeof(*oid));
- if (get_oid_hex(buf, oid))
+ if (get_oid_hex(buf, &oid))
die("Bad object ID on stdin: %s", buf);
- llist_insert_sorted_unique(ignore, oid, NULL);
+ llist_insert_sorted_unique(ignore, &oid, NULL);
}
}
llist_sorted_difference_inplace(all_objects, ignore);
@@ -671,5 +696,8 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s
fprintf(stderr, "%luMB of redundant packs in total.\n",
(unsigned long)pack_set_bytecount(red)/(1024*1024));
+ pack_list_free(red);
+ pack_list_free(min);
+ llist_free(ignore);
return 0;
}
diff --git a/builtin/pull.c b/builtin/pull.c
index 149f201320..388ef3d130 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -85,7 +85,7 @@ static const char *opt_squash;
static const char *opt_commit;
static const char *opt_edit;
static const char *cleanup_arg;
-static const char *opt_ff;
+static char *opt_ff;
static const char *opt_verify_signatures;
static const char *opt_verify;
static int opt_autostash = -1;
@@ -1028,8 +1028,10 @@ int cmd_pull(int argc,
* "--rebase" can override a config setting of
* pull.ff=only.
*/
- if (opt_rebase >= 0 && opt_ff && !strcmp(opt_ff, "--ff-only"))
- opt_ff = "--ff";
+ if (opt_rebase >= 0 && opt_ff && !strcmp(opt_ff, "--ff-only")) {
+ free(opt_ff);
+ opt_ff = xstrdup("--ff");
+ }
}
if (opt_rebase < 0)
@@ -1139,7 +1141,8 @@ int cmd_pull(int argc,
if (can_ff) {
/* we can fast-forward this without invoking rebase */
- opt_ff = "--ff-only";
+ free(opt_ff);
+ opt_ff = xstrdup("--ff-only");
ret = run_merge();
} else {
ret = run_rebase(&newbase, &upstream);
diff --git a/builtin/push.c b/builtin/push.c
index e6f48969b8..51c609f208 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -519,14 +519,7 @@ static int git_push_config(const char *k, const char *v,
RECURSE_SUBMODULES_ON_DEMAND : RECURSE_SUBMODULES_OFF;
recurse_submodules = val;
} else if (!strcmp(k, "push.pushoption")) {
- if (!v)
- return config_error_nonbool(k);
- else
- if (!*v)
- string_list_clear(&push_options_config, 0);
- else
- string_list_append(&push_options_config, v);
- return 0;
+ return parse_transport_option(k, v, &push_options_config);
} else if (!strcmp(k, "color.push")) {
push_use_color = git_config_colorbool(k, v);
return 0;
@@ -669,6 +662,7 @@ int cmd_push(int argc,
rc = do_push(flags, push_options, remote);
string_list_clear(&push_options_cmdline, 0);
string_list_clear(&push_options_config, 0);
+ clear_cas_option(&cas);
if (rc == -1)
usage_with_options(push_usage, options);
else
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 536d22761d..ab5b20e39c 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -374,6 +374,7 @@ static void write_head_info(void)
struct command {
struct command *next;
const char *error_string;
+ char *error_string_owned;
struct ref_push_report *report;
unsigned int skip_update:1,
did_not_exist:1,
@@ -1083,7 +1084,7 @@ static int read_proc_receive_report(struct packet_reader *reader,
hint->run_proc_receive |= RUN_PROC_RECEIVE_RETURNED;
if (!strcmp(head, "ng")) {
if (p)
- hint->error_string = xstrdup(p);
+ hint->error_string = hint->error_string_owned = xstrdup(p);
else
hint->error_string = "failed";
code = -1;
@@ -2054,6 +2055,8 @@ static void free_commands(struct command *commands)
while (commands) {
struct command *next = commands->next;
+ ref_push_report_free(commands->report);
+ free(commands->error_string_owned);
free(commands);
commands = next;
}
diff --git a/builtin/repack.c b/builtin/repack.c
index cb4420f085..d6bb37e84a 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -86,17 +86,34 @@ static int repack_config(const char *var, const char *value,
run_update_server_info = git_config_bool(var, value);
return 0;
}
- if (!strcmp(var, "repack.cruftwindow"))
+ if (!strcmp(var, "repack.cruftwindow")) {
+ free(cruft_po_args->window);
return git_config_string(&cruft_po_args->window, var, value);
- if (!strcmp(var, "repack.cruftwindowmemory"))
+ }
+ if (!strcmp(var, "repack.cruftwindowmemory")) {
+ free(cruft_po_args->window_memory);
return git_config_string(&cruft_po_args->window_memory, var, value);
- if (!strcmp(var, "repack.cruftdepth"))
+ }
+ if (!strcmp(var, "repack.cruftdepth")) {
+ free(cruft_po_args->depth);
return git_config_string(&cruft_po_args->depth, var, value);
- if (!strcmp(var, "repack.cruftthreads"))
+ }
+ if (!strcmp(var, "repack.cruftthreads")) {
+ free(cruft_po_args->threads);
return git_config_string(&cruft_po_args->threads, var, value);
+ }
return git_default_config(var, value, ctx, cb);
}
+static void pack_objects_args_release(struct pack_objects_args *args)
+{
+ free(args->window);
+ free(args->window_memory);
+ free(args->depth);
+ free(args->threads);
+ list_objects_filter_release(&args->filter_options);
+}
+
struct existing_packs {
struct string_list kept_packs;
struct string_list non_kept_packs;
@@ -1156,12 +1173,16 @@ int cmd_repack(int argc,
const char *unpack_unreachable = NULL;
int keep_unreachable = 0;
struct string_list keep_pack_list = STRING_LIST_INIT_NODUP;
- struct pack_objects_args po_args = {NULL};
- struct pack_objects_args cruft_po_args = {NULL};
+ struct pack_objects_args po_args = { 0 };
+ struct pack_objects_args cruft_po_args = { 0 };
int write_midx = 0;
const char *cruft_expiration = NULL;
const char *expire_to = NULL;
const char *filter_to = NULL;
+ const char *opt_window = NULL;
+ const char *opt_window_memory = NULL;
+ const char *opt_depth = NULL;
+ const char *opt_threads = NULL;
struct option builtin_repack_options[] = {
OPT_BIT('a', NULL, &pack_everything,
@@ -1195,13 +1216,13 @@ int cmd_repack(int argc,
N_("with -A, do not loosen objects older than this")),
OPT_BOOL('k', "keep-unreachable", &keep_unreachable,
N_("with -a, repack unreachable objects")),
- OPT_STRING(0, "window", &po_args.window, N_("n"),
+ OPT_STRING(0, "window", &opt_window, N_("n"),
N_("size of the window used for delta compression")),
- OPT_STRING(0, "window-memory", &po_args.window_memory, N_("bytes"),
+ OPT_STRING(0, "window-memory", &opt_window_memory, N_("bytes"),
N_("same as the above, but limit memory size instead of entries count")),
- OPT_STRING(0, "depth", &po_args.depth, N_("n"),
+ OPT_STRING(0, "depth", &opt_depth, N_("n"),
N_("limits the maximum delta depth")),
- OPT_STRING(0, "threads", &po_args.threads, N_("n"),
+ OPT_STRING(0, "threads", &opt_threads, N_("n"),
N_("limits the maximum number of threads")),
OPT_MAGNITUDE(0, "max-pack-size", &po_args.max_pack_size,
N_("maximum size of each packfile")),
@@ -1228,6 +1249,11 @@ int cmd_repack(int argc,
argc = parse_options(argc, argv, prefix, builtin_repack_options,
git_repack_usage, 0);
+ po_args.window = xstrdup_or_null(opt_window);
+ po_args.window_memory = xstrdup_or_null(opt_window_memory);
+ po_args.depth = xstrdup_or_null(opt_depth);
+ po_args.threads = xstrdup_or_null(opt_threads);
+
if (delete_redundant && repository_format_precious_objects)
die(_("cannot delete packs in a precious-objects repo"));
@@ -1393,13 +1419,13 @@ int cmd_repack(int argc,
const char *pack_prefix = find_pack_prefix(packdir, packtmp);
if (!cruft_po_args.window)
- cruft_po_args.window = po_args.window;
+ cruft_po_args.window = xstrdup_or_null(po_args.window);
if (!cruft_po_args.window_memory)
- cruft_po_args.window_memory = po_args.window_memory;
+ cruft_po_args.window_memory = xstrdup_or_null(po_args.window_memory);
if (!cruft_po_args.depth)
- cruft_po_args.depth = po_args.depth;
+ cruft_po_args.depth = xstrdup_or_null(po_args.depth);
if (!cruft_po_args.threads)
- cruft_po_args.threads = po_args.threads;
+ cruft_po_args.threads = xstrdup_or_null(po_args.threads);
if (!cruft_po_args.max_pack_size)
cruft_po_args.max_pack_size = po_args.max_pack_size;
@@ -1552,7 +1578,8 @@ cleanup:
string_list_clear(&names, 1);
existing_packs_release(&existing);
free_pack_geometry(&geometry);
- list_objects_filter_release(&po_args.filter_options);
+ pack_objects_args_release(&po_args);
+ pack_objects_args_release(&cruft_po_args);
return ret;
}
diff --git a/builtin/revert.c b/builtin/revert.c
index 55ba1092c5..b7917dddd3 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -110,6 +110,9 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
const char * const * usage_str = revert_or_cherry_pick_usage(opts);
const char *me = action_name(opts);
const char *cleanup_arg = NULL;
+ const char sentinel_value;
+ const char *strategy = &sentinel_value;
+ const char *gpg_sign = &sentinel_value;
enum empty_action empty_opt = EMPTY_COMMIT_UNSPECIFIED;
int cmd = 0;
struct option base_options[] = {
@@ -125,10 +128,10 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
OPT_CALLBACK('m', "mainline", opts, N_("parent-number"),
N_("select mainline parent"), option_parse_m),
OPT_RERERE_AUTOUPDATE(&opts->allow_rerere_auto),
- OPT_STRING(0, "strategy", &opts->strategy, N_("strategy"), N_("merge strategy")),
+ OPT_STRING(0, "strategy", &strategy, N_("strategy"), N_("merge strategy")),
OPT_STRVEC('X', "strategy-option", &opts->xopts, N_("option"),
N_("option for merge strategy")),
- { OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key-id"),
+ { OPTION_STRING, 'S', "gpg-sign", &gpg_sign, N_("key-id"),
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
OPT_END()
};
@@ -240,8 +243,14 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
usage_with_options(usage_str, options);
/* These option values will be free()d */
- opts->gpg_sign = xstrdup_or_null(opts->gpg_sign);
- opts->strategy = xstrdup_or_null(opts->strategy);
+ if (gpg_sign != &sentinel_value) {
+ free(opts->gpg_sign);
+ opts->gpg_sign = xstrdup_or_null(gpg_sign);
+ }
+ if (strategy != &sentinel_value) {
+ free(opts->strategy);
+ opts->strategy = xstrdup_or_null(strategy);
+ }
if (!opts->strategy && getenv("GIT_TEST_MERGE_ALGORITHM"))
opts->strategy = xstrdup(getenv("GIT_TEST_MERGE_ALGORITHM"));
free(options);
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 81fc96d423..59b626aae8 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -340,8 +340,11 @@ int cmd_send_pack(int argc,
/* stable plumbing output; do not modify or localize */
fprintf(stderr, "Everything up-to-date\n");
+ string_list_clear(&push_options, 0);
free_refs(remote_refs);
free_refs(local_refs);
refspec_clear(&rs);
+ oid_array_clear(&shallow);
+ clear_cas_option(&cas);
return ret;
}
diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
index e4e791a4c9..49aedc1de8 100644
--- a/builtin/sparse-checkout.c
+++ b/builtin/sparse-checkout.c
@@ -924,6 +924,11 @@ static int sparse_checkout_disable(int argc, const char **argv,
builtin_sparse_checkout_disable_options,
builtin_sparse_checkout_disable_usage, 0);
+ /*
+ * Disable the advice message for expanding a sparse index, as we
+ * are expecting to do that when disabling sparse-checkout.
+ */
+ give_advice_on_expansion = 0;
repo_read_index(the_repository);
memset(&pl, 0, sizeof(pl));
diff --git a/builtin/stash.c b/builtin/stash.c
index f1acc918d0..1399a1bbe2 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -1759,7 +1759,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,
int quiet = 0;
int pathspec_file_nul = 0;
const char *stash_msg = NULL;
- const char *pathspec_from_file = NULL;
+ char *pathspec_from_file = NULL;
struct pathspec ps;
struct option options[] = {
OPT_BOOL('k', "keep-index", &keep_index,
@@ -1821,7 +1821,9 @@ static int push_stash(int argc, const char **argv, const char *prefix,
ret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,
include_untracked, only_staged);
+
clear_pathspec(&ps);
+ free(pathspec_from_file);
return ret;
}
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index a1ada86952..b6b5f1ebde 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -364,9 +364,13 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
if (!info->quiet)
printf(_("Entering '%s'\n"), displaypath);
- if (info->argv[0] && run_command(&cp))
- die(_("run_command returned non-zero status for %s\n."),
- displaypath);
+ if (info->argv[0]) {
+ if (run_command(&cp))
+ die(_("run_command returned non-zero status for %s\n."),
+ displaypath);
+ } else {
+ child_process_clear(&cp);
+ }
if (info->recursive) {
struct child_process cpr = CHILD_PROCESS_INIT;
@@ -696,6 +700,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
if (flags & OPT_RECURSIVE) {
struct child_process cpr = CHILD_PROCESS_INIT;
+ int res;
cpr.git_cmd = 1;
cpr.dir = path;
@@ -711,7 +716,10 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
if (flags & OPT_QUIET)
strvec_push(&cpr.args, "--quiet");
- if (run_command(&cpr))
+ res = run_command(&cpr);
+ if (res == SIGPIPE + 128)
+ raise(SIGPIPE);
+ else if (res)
die(_("failed to recurse into submodule '%s'"), path);
}
@@ -1618,6 +1626,8 @@ static int add_possible_reference_from_superproject(
; /* nothing */
}
}
+
+ strbuf_release(&err);
strbuf_release(&sb);
}
@@ -2022,6 +2032,7 @@ struct update_data {
static void update_data_release(struct update_data *ud)
{
free(ud->displaypath);
+ submodule_update_strategy_release(&ud->update_strategy);
module_list_release(&ud->list);
}
@@ -2322,7 +2333,14 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet,
strvec_pushf(&cp.args, "--depth=%d", depth);
if (oid) {
char *hex = oid_to_hex(oid);
- char *remote = get_default_remote();
+ char *remote;
+ int code;
+
+ code = get_default_remote_submodule(module_path, &remote);
+ if (code) {
+ child_process_clear(&cp);
+ return code;
+ }
strvec_pushl(&cp.args, remote, hex, NULL);
free(remote);
@@ -2642,15 +2660,20 @@ static int update_submodule(struct update_data *update_data)
if (!update_data->nofetch) {
if (fetch_in_submodule(update_data->sm_path, update_data->depth,
- 0, NULL))
+ 0, NULL)) {
+ free(remote_ref);
return die_message(_("Unable to fetch in submodule path '%s'"),
update_data->sm_path);
+ }
}
if (repo_resolve_gitlink_ref(the_repository, update_data->sm_path,
- remote_ref, &update_data->oid))
- return die_message(_("Unable to find %s revision in submodule path '%s'"),
- remote_ref, update_data->sm_path);
+ remote_ref, &update_data->oid)) {
+ ret = die_message(_("Unable to find %s revision in submodule path '%s'"),
+ remote_ref, update_data->sm_path);
+ free(remote_ref);
+ return ret;
+ }
free(remote_ref);
}
diff --git a/builtin/worktree.c b/builtin/worktree.c
index fc31d072a6..dae63dedf4 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -414,7 +414,8 @@ static int add_worktree(const char *path, const char *refname,
const struct add_opts *opts)
{
struct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;
- struct strbuf sb = STRBUF_INIT, realpath = STRBUF_INIT;
+ struct strbuf sb = STRBUF_INIT, sb_tmp = STRBUF_INIT;
+ struct strbuf sb_path_realpath = STRBUF_INIT, sb_repo_realpath = STRBUF_INIT;
const char *name;
struct strvec child_env = STRVEC_INIT;
unsigned int counter = 0;
@@ -490,11 +491,10 @@ static int add_worktree(const char *path, const char *refname,
strbuf_reset(&sb);
strbuf_addf(&sb, "%s/gitdir", sb_repo.buf);
- strbuf_realpath(&realpath, sb_git.buf, 1);
- write_file(sb.buf, "%s", realpath.buf);
- strbuf_realpath(&realpath, repo_get_common_dir(the_repository), 1);
- write_file(sb_git.buf, "gitdir: %s/worktrees/%s",
- realpath.buf, name);
+ strbuf_realpath(&sb_path_realpath, path, 1);
+ strbuf_realpath(&sb_repo_realpath, sb_repo.buf, 1);
+ write_file(sb.buf, "%s/.git", relative_path(sb_path_realpath.buf, sb_repo_realpath.buf, &sb_tmp));
+ write_file(sb_git.buf, "gitdir: %s", relative_path(sb_repo_realpath.buf, sb_path_realpath.buf, &sb_tmp));
strbuf_reset(&sb);
strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
write_file(sb.buf, "../..");
@@ -578,11 +578,13 @@ done:
strvec_clear(&child_env);
strbuf_release(&sb);
+ strbuf_release(&sb_tmp);
strbuf_release(&symref);
strbuf_release(&sb_repo);
+ strbuf_release(&sb_repo_realpath);
strbuf_release(&sb_git);
+ strbuf_release(&sb_path_realpath);
strbuf_release(&sb_name);
- strbuf_release(&realpath);
free_worktree(wt);
return ret;
}