summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/add.c2
-rw-r--r--builtin/checkout-index.c6
-rw-r--r--builtin/checkout.c42
-rw-r--r--builtin/commit.c3
-rw-r--r--builtin/config.c5
-rw-r--r--builtin/difftool.c2
-rw-r--r--builtin/fetch-pack.c9
-rw-r--r--builtin/fetch.c17
-rw-r--r--builtin/gc.c6
-rw-r--r--builtin/grep.c20
-rw-r--r--builtin/init-db.c6
-rw-r--r--builtin/log.c5
-rw-r--r--builtin/ls-files.c14
-rw-r--r--builtin/ls-tree.c3
-rw-r--r--builtin/merge-recursive.c15
-rw-r--r--builtin/merge-tree.c2
-rw-r--r--builtin/pack-objects.c6
-rw-r--r--builtin/prune.c1
-rw-r--r--builtin/push.c4
-rw-r--r--builtin/rebase--interactive.c2
-rw-r--r--builtin/rebase.c54
-rw-r--r--builtin/repack.c2
-rw-r--r--builtin/rev-list.c6
-rw-r--r--builtin/stripspace.c3
-rw-r--r--builtin/submodule--helper.c8
-rw-r--r--builtin/worktree.c29
26 files changed, 196 insertions, 76 deletions
diff --git a/builtin/add.c b/builtin/add.c
index f65c172299..12247b48fd 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -176,7 +176,7 @@ static void refresh(int verbose, const struct pathspec *pathspec)
die(_("pathspec '%s' did not match any files"),
pathspec->items[i].match);
}
- free(seen);
+ free(seen);
}
int run_add_interactive(const char *revision, const char *patch_mode,
diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c
index eb74774cbc..a2a726ad8d 100644
--- a/builtin/checkout-index.c
+++ b/builtin/checkout-index.c
@@ -67,7 +67,8 @@ static int checkout_file(const char *name, const char *prefix)
continue;
did_checkout = 1;
if (checkout_entry(ce, &state,
- to_tempfile ? topath[ce_stage(ce)] : NULL) < 0)
+ to_tempfile ? topath[ce_stage(ce)] : NULL,
+ NULL) < 0)
errs++;
}
@@ -111,7 +112,8 @@ static void checkout_all(const char *prefix, int prefix_length)
write_tempfile_record(last_ce->name, prefix);
}
if (checkout_entry(ce, &state,
- to_tempfile ? topath[ce_stage(ce)] : NULL) < 0)
+ to_tempfile ? topath[ce_stage(ce)] : NULL,
+ NULL) < 0)
errs++;
last_ce = ce;
}
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 08b0ac48f3..6fadf412e8 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -44,6 +44,7 @@ struct checkout_opts {
int ignore_skipworktree;
int ignore_other_worktrees;
int show_progress;
+ int count_checkout_paths;
/*
* If new checkout options are added, skip_merge_working_tree
* should be updated accordingly.
@@ -115,7 +116,8 @@ static int update_some(const struct object_id *oid, struct strbuf *base,
static int read_tree_some(struct tree *tree, const struct pathspec *pathspec)
{
- read_tree_recursive(tree, "", 0, 0, pathspec, update_some, NULL);
+ read_tree_recursive(the_repository, tree, "", 0, 0,
+ pathspec, update_some, NULL);
/* update the index with the given tree's info
* for all args, expanding wildcards, and exit
@@ -165,12 +167,13 @@ static int check_stages(unsigned stages, const struct cache_entry *ce, int pos)
}
static int checkout_stage(int stage, const struct cache_entry *ce, int pos,
- const struct checkout *state)
+ const struct checkout *state, int *nr_checkouts)
{
while (pos < active_nr &&
!strcmp(active_cache[pos]->name, ce->name)) {
if (ce_stage(active_cache[pos]) == stage)
- return checkout_entry(active_cache[pos], state, NULL);
+ return checkout_entry(active_cache[pos], state,
+ NULL, nr_checkouts);
pos++;
}
if (stage == 2)
@@ -179,7 +182,7 @@ static int checkout_stage(int stage, const struct cache_entry *ce, int pos,
return error(_("path '%s' does not have their version"), ce->name);
}
-static int checkout_merged(int pos, const struct checkout *state)
+static int checkout_merged(int pos, const struct checkout *state, int *nr_checkouts)
{
struct cache_entry *ce = active_cache[pos];
const char *path = ce->name;
@@ -242,7 +245,7 @@ static int checkout_merged(int pos, const struct checkout *state)
ce = make_transient_cache_entry(mode, &oid, path, 2);
if (!ce)
die(_("make_cache_entry failed for path '%s'"), path);
- status = checkout_entry(ce, state, NULL);
+ status = checkout_entry(ce, state, NULL, nr_checkouts);
discard_cache_entry(ce);
return status;
}
@@ -257,6 +260,7 @@ static int checkout_paths(const struct checkout_opts *opts,
struct commit *head;
int errs = 0;
struct lock_file lock_file = LOCK_INIT;
+ int nr_checkouts = 0;
if (opts->track != BRANCH_TRACK_UNSPECIFIED)
die(_("'%s' cannot be used with updating paths"), "--track");
@@ -371,17 +375,36 @@ static int checkout_paths(const struct checkout_opts *opts,
struct cache_entry *ce = active_cache[pos];
if (ce->ce_flags & CE_MATCHED) {
if (!ce_stage(ce)) {
- errs |= checkout_entry(ce, &state, NULL);
+ errs |= checkout_entry(ce, &state,
+ NULL, &nr_checkouts);
continue;
}
if (opts->writeout_stage)
- errs |= checkout_stage(opts->writeout_stage, ce, pos, &state);
+ errs |= checkout_stage(opts->writeout_stage,
+ ce, pos,
+ &state, &nr_checkouts);
else if (opts->merge)
- errs |= checkout_merged(pos, &state);
+ errs |= checkout_merged(pos, &state,
+ &nr_checkouts);
pos = skip_same_name(ce, pos) - 1;
}
}
- errs |= finish_delayed_checkout(&state);
+ errs |= finish_delayed_checkout(&state, &nr_checkouts);
+
+ if (opts->count_checkout_paths) {
+ if (opts->source_tree)
+ fprintf_ln(stderr, Q_("Checked out %d path out of %s",
+ "Checked out %d paths out of %s",
+ nr_checkouts),
+ nr_checkouts,
+ find_unique_abbrev(&opts->source_tree->object.oid,
+ DEFAULT_ABBREV));
+ else
+ fprintf_ln(stderr, Q_("Checked out %d path out of the index",
+ "Checked out %d paths out of the index",
+ nr_checkouts),
+ nr_checkouts);
+ }
if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
die(_("unable to write new index file"));
@@ -1065,6 +1088,7 @@ static int parse_branchname_arg(int argc, const char **argv,
has_dash_dash = 1; /* case (3) or (1) */
else if (dash_dash_pos >= 2)
die(_("only one reference expected, %d given."), dash_dash_pos);
+ opts->count_checkout_paths = !opts->quiet && !has_dash_dash;
if (!strcmp(arg, "-"))
arg = "@{-1}";
diff --git a/builtin/commit.c b/builtin/commit.c
index 004b816635..7d2e0b61e5 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -351,7 +351,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
if (write_locked_index(&the_index, &index_lock, 0))
die(_("unable to create temporary index"));
- old_index_env = getenv(INDEX_ENVIRONMENT);
+ old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT));
setenv(INDEX_ENVIRONMENT, get_lock_file_path(&index_lock), 1);
if (interactive_add(argc, argv, prefix, patch_interactive) != 0)
@@ -361,6 +361,7 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
setenv(INDEX_ENVIRONMENT, old_index_env, 1);
else
unsetenv(INDEX_ENVIRONMENT);
+ FREE_AND_NULL(old_index_env);
discard_cache();
read_cache_from(get_lock_file_path(&index_lock));
diff --git a/builtin/config.c b/builtin/config.c
index 84385ef165..98d65bc0ad 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -164,7 +164,8 @@ static NORETURN void usage_builtin_config(void)
usage_with_options(builtin_config_usage, builtin_config_options);
}
-static void check_argc(int argc, int min, int max) {
+static void check_argc(int argc, int min, int max)
+{
if (argc >= min && argc <= max)
return;
if (min == max)
@@ -598,7 +599,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
int nongit = !startup_info->have_repository;
char *value;
- given_config_source.file = getenv(CONFIG_ENVIRONMENT);
+ given_config_source.file = xstrdup_or_null(getenv(CONFIG_ENVIRONMENT));
argc = parse_options(argc, argv, prefix, builtin_config_options,
builtin_config_usage,
diff --git a/builtin/difftool.c b/builtin/difftool.c
index 544b0e8639..71318c26e1 100644
--- a/builtin/difftool.c
+++ b/builtin/difftool.c
@@ -323,7 +323,7 @@ static int checkout_path(unsigned mode, struct object_id *oid,
int ret;
ce = make_transient_cache_entry(mode, oid, path, 0);
- ret = checkout_entry(ce, state, NULL);
+ ret = checkout_entry(ce, state, NULL, NULL);
discard_cache_entry(ce);
return ret;
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 63e69a5801..f6a513495e 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -55,6 +55,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
struct oid_array shallow = OID_ARRAY_INIT;
struct string_list deepen_not = STRING_LIST_INIT_DUP;
struct packet_reader reader;
+ enum protocol_version version;
fetch_if_missing = 0;
@@ -219,9 +220,11 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
PACKET_READ_CHOMP_NEWLINE |
PACKET_READ_GENTLE_ON_EOF);
- switch (discover_version(&reader)) {
+ version = discover_version(&reader);
+ switch (version) {
case protocol_v2:
- die("support for protocol v2 not implemented yet");
+ get_remote_refs(fd[1], &reader, &ref, 0, NULL, NULL);
+ break;
case protocol_v1:
case protocol_v0:
get_remote_heads(&reader, &ref, 0, NULL, &shallow);
@@ -231,7 +234,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
}
ref = fetch_pack(&args, fd, conn, ref, dest, sought, nr_sought,
- &shallow, pack_lockfile_ptr, protocol_v0);
+ &shallow, pack_lockfile_ptr, version);
if (pack_lockfile) {
printf("lock %s\n", pack_lockfile);
fflush(stdout);
diff --git a/builtin/fetch.c b/builtin/fetch.c
index e0140327aa..c316c03ba2 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -763,9 +763,6 @@ static int update_local_ref(struct ref *ref,
what = _("[new 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);
format_display(display, r ? '!' : '*', what,
r ? _("unable to update local ref") : NULL,
@@ -779,9 +776,6 @@ static int update_local_ref(struct ref *ref,
strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
strbuf_addstr(&quickref, "..");
strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
- 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);
format_display(display, r ? '!' : ' ', quickref.buf,
r ? _("unable to update local ref") : NULL,
@@ -794,9 +788,6 @@ static int update_local_ref(struct ref *ref,
strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
strbuf_addstr(&quickref, "...");
strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
- 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);
format_display(display, r ? '!' : '+', quickref.buf,
r ? _("unable to update local ref") : _("forced update"),
@@ -892,6 +883,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
ref->force = rm->peer_ref->force;
}
+ if (recurse_submodules != RECURSE_SUBMODULES_OFF)
+ check_for_new_submodule_commits(&rm->old_oid);
if (!strcmp(rm->name, "HEAD")) {
kind = "";
@@ -1478,7 +1471,8 @@ static inline void fetch_one_setup_partial(struct remote *remote)
*/
if (strcmp(remote->name, repository_format_partial_clone)) {
if (filter_options.choice)
- die(_("--filter can only be used with the remote configured in core.partialClone"));
+ die(_("--filter can only be used with the remote "
+ "configured in extensions.partialclone"));
return;
}
@@ -1646,7 +1640,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
result = fetch_one(remote, argc, argv, prune_tags_ok);
} else {
if (filter_options.choice)
- die(_("--filter can only be used with the remote configured in core.partialClone"));
+ die(_("--filter can only be used with the remote "
+ "configured in extensions.partialclone"));
/* TODO should this also die if we have a previous partial-clone? */
result = fetch_multiple(&list);
}
diff --git a/builtin/gc.c b/builtin/gc.c
index 871a56f1c5..020f725acc 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -317,7 +317,7 @@ static void add_repack_all_option(struct string_list *keep_pack)
static void add_repack_incremental_option(void)
{
- argv_array_push(&repack, "--no-write-bitmap-index");
+ argv_array_push(&repack, "--no-write-bitmap-index");
}
static int need_to_gc(void)
@@ -659,8 +659,10 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
report_garbage = report_pack_garbage;
reprepare_packed_git(the_repository);
- if (pack_garbage.nr > 0)
+ if (pack_garbage.nr > 0) {
+ close_all_packs(the_repository->objects);
clean_pack_garbage();
+ }
if (gc_write_commit_graph)
write_commit_graph_reachable(get_object_directory(), 0,
diff --git a/builtin/grep.c b/builtin/grep.c
index bad9c0a3d5..dc91838764 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -404,7 +404,10 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
const struct object_id *oid,
const char *filename, const char *path)
{
- struct repository submodule;
+ struct repository subrepo;
+ const struct submodule *sub = submodule_from_path(superproject,
+ &null_oid, path);
+
int hit;
/*
@@ -420,12 +423,12 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
return 0;
}
- if (repo_submodule_init(&submodule, superproject, path)) {
+ if (repo_submodule_init(&subrepo, superproject, sub)) {
grep_read_unlock();
return 0;
}
- repo_read_gitmodules(&submodule);
+ repo_read_gitmodules(&subrepo);
/*
* NEEDSWORK: This adds the submodule's object directory to the list of
@@ -437,7 +440,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
* store is no longer global and instead is a member of the repository
* object.
*/
- add_to_alternates_memory(submodule.objects->odb->path);
+ add_to_alternates_memory(subrepo.objects->odb->path);
grep_read_unlock();
if (oid) {
@@ -462,14 +465,14 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
init_tree_desc(&tree, data, size);
hit = grep_tree(opt, pathspec, &tree, &base, base.len,
- object->type == OBJ_COMMIT, &submodule);
+ object->type == OBJ_COMMIT, &subrepo);
strbuf_release(&base);
free(data);
} else {
- hit = grep_cache(opt, &submodule, pathspec, 1);
+ hit = grep_cache(opt, &subrepo, pathspec, 1);
}
- repo_clear(&submodule);
+ repo_clear(&subrepo);
return hit;
}
@@ -553,7 +556,8 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
if (match != all_entries_interesting) {
strbuf_addstr(&name, base->buf + tn_len);
- match = tree_entry_interesting(&entry, &name,
+ match = tree_entry_interesting(repo->index,
+ &entry, &name,
0, pathspec);
strbuf_setlen(&name, name_base_len);
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 41faffd28d..93eff7618c 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -542,8 +542,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
* GIT_WORK_TREE makes sense only in conjunction with GIT_DIR
* without --bare. Catch the error early.
*/
- git_dir = getenv(GIT_DIR_ENVIRONMENT);
- work_tree = getenv(GIT_WORK_TREE_ENVIRONMENT);
+ git_dir = xstrdup_or_null(getenv(GIT_DIR_ENVIRONMENT));
+ work_tree = xstrdup_or_null(getenv(GIT_WORK_TREE_ENVIRONMENT));
if ((!git_dir || is_bare_repository_cfg == 1) && work_tree)
die(_("%s (or --work-tree=<directory>) not allowed without "
"specifying %s (or --git-dir=<directory>)"),
@@ -582,6 +582,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
}
UNLEAK(real_git_dir);
+ UNLEAK(git_dir);
+ UNLEAK(work_tree);
flags |= INIT_DB_EXIST_OK;
return init_db(git_dir, real_git_dir, template_dir, flags);
diff --git a/builtin/log.c b/builtin/log.c
index e8e51068bd..3e145fe502 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -641,8 +641,9 @@ int cmd_show(int argc, const char **argv, const char *prefix)
diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
name,
diff_get_color_opt(&rev.diffopt, DIFF_RESET));
- read_tree_recursive((struct tree *)o, "", 0, 0, &match_all,
- show_tree_object, rev.diffopt.file);
+ read_tree_recursive(the_repository, (struct tree *)o, "",
+ 0, 0, &match_all, show_tree_object,
+ rev.diffopt.file);
rev.shown_one = 1;
break;
case OBJ_COMMIT:
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index c70a9c7158..cde87cbeeb 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -206,17 +206,19 @@ static void show_files(struct repository *repo, struct dir_struct *dir);
static void show_submodule(struct repository *superproject,
struct dir_struct *dir, const char *path)
{
- struct repository submodule;
+ struct repository subrepo;
+ const struct submodule *sub = submodule_from_path(superproject,
+ &null_oid, path);
- if (repo_submodule_init(&submodule, superproject, path))
+ if (repo_submodule_init(&subrepo, superproject, sub))
return;
- if (repo_read_index(&submodule) < 0)
+ if (repo_read_index(&subrepo) < 0)
die("index file corrupt");
- show_files(&submodule, dir);
+ show_files(&subrepo, dir);
- repo_clear(&submodule);
+ repo_clear(&subrepo);
}
static void show_ce(struct repository *repo, struct dir_struct *dir,
@@ -441,7 +443,7 @@ void overlay_tree_on_index(struct index_state *istate,
PATHSPEC_PREFER_CWD, prefix, matchbuf);
} else
memset(&pathspec, 0, sizeof(pathspec));
- if (read_tree(tree, 1, &pathspec, istate))
+ if (read_tree(the_repository, tree, 1, &pathspec, istate))
die("unable to read tree entries %s", tree_name);
for (i = 0; i < istate->cache_nr; i++) {
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 7d581d6463..7cad3f24eb 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -185,5 +185,6 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
tree = parse_tree_indirect(&oid);
if (!tree)
die("not a tree object");
- return !!read_tree_recursive(tree, "", 0, 0, &pathspec, show_tree, NULL);
+ return !!read_tree_recursive(the_repository, tree, "", 0, 0,
+ &pathspec, show_tree, NULL);
}
diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c
index 9b2f707c29..7545136c2a 100644
--- a/builtin/merge-recursive.c
+++ b/builtin/merge-recursive.c
@@ -7,16 +7,16 @@
static const char builtin_merge_recursive_usage[] =
"git %s <base>... -- <head> <remote> ...";
-static const char *better_branch_name(const char *branch)
+static char *better_branch_name(const char *branch)
{
static char githead_env[8 + GIT_MAX_HEXSZ + 1];
char *name;
if (strlen(branch) != the_hash_algo->hexsz)
- return branch;
+ return xstrdup(branch);
xsnprintf(githead_env, sizeof(githead_env), "GITHEAD_%s", branch);
name = getenv(githead_env);
- return name ? name : branch;
+ return xstrdup(name ? name : branch);
}
int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
@@ -26,6 +26,7 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
int i, failed;
struct object_id h1, h2;
struct merge_options o;
+ char *better1, *better2;
struct commit *result;
init_merge_options(&o);
@@ -70,13 +71,17 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
if (get_oid(o.branch2, &h2))
die(_("could not resolve ref '%s'"), o.branch2);
- o.branch1 = better_branch_name(o.branch1);
- o.branch2 = better_branch_name(o.branch2);
+ o.branch1 = better1 = better_branch_name(o.branch1);
+ o.branch2 = better2 = better_branch_name(o.branch2);
if (o.verbosity >= 3)
printf(_("Merging %s with %s\n"), o.branch1, o.branch2);
failed = merge_recursive_generic(&o, &h1, &h2, bases_count, bases, &result);
+
+ free(better1);
+ free(better2);
+
if (failed < 0)
return 128; /* die() error code */
return failed;
diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c
index 70f6fc9167..4984b7e12e 100644
--- a/builtin/merge-tree.c
+++ b/builtin/merge-tree.c
@@ -346,7 +346,7 @@ static void merge_trees(struct tree_desc t[3], const char *base)
setup_traverse_info(&info, base);
info.fn = threeway_callback;
- traverse_trees(3, t, &info);
+ traverse_trees(&the_index, 3, t, &info);
}
static void *get_tree_descriptor(struct tree_desc *desc, const char *rev)
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 24bba8147f..889df2c755 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -3084,14 +3084,16 @@ static void record_recent_commit(struct commit *commit, void *data)
static void get_object_list(int ac, const char **av)
{
struct rev_info revs;
+ struct setup_revision_opt s_r_opt = {
+ .allow_exclude_promisor_objects = 1,
+ };
char line[1000];
int flags = 0;
int save_warning;
repo_init_revisions(the_repository, &revs, NULL);
save_commit_buffer = 0;
- revs.allow_exclude_promisor_objects_opt = 1;
- setup_revisions(ac, av, &revs, NULL);
+ setup_revisions(ac, av, &revs, &s_r_opt);
/* make sure shallows are read */
is_repository_shallow(the_repository);
diff --git a/builtin/prune.c b/builtin/prune.c
index e42653b99c..1ec9ddd751 100644
--- a/builtin/prune.c
+++ b/builtin/prune.c
@@ -120,7 +120,6 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
save_commit_buffer = 0;
read_replace_refs = 0;
ref_paranoia = 1;
- revs.allow_exclude_promisor_objects_opt = 1;
repo_init_revisions(the_repository, &revs, prefix);
argc = parse_options(argc, argv, prefix, options, prune_usage, 0);
diff --git a/builtin/push.c b/builtin/push.c
index ee1e842027..021dd3b1e4 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -143,7 +143,9 @@ static int push_url_of_remote(struct remote *remote, const char ***url_p)
return remote->url_nr;
}
-static NORETURN int die_push_simple(struct branch *branch, struct remote *remote) {
+static NORETURN int die_push_simple(struct branch *branch,
+ struct remote *remote)
+{
/*
* There's no point in using shorten_unambiguous_ref here,
* as the ambiguity would be on the remote side, not what
diff --git a/builtin/rebase--interactive.c b/builtin/rebase--interactive.c
index dd2a55ab1d..c2c2d51a3b 100644
--- a/builtin/rebase--interactive.c
+++ b/builtin/rebase--interactive.c
@@ -193,6 +193,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
OPT_STRING(0, "onto-name", &onto_name, N_("onto-name"), N_("onto name")),
OPT_STRING(0, "cmd", &cmd, N_("cmd"), N_("the command to run")),
OPT_RERERE_AUTOUPDATE(&opts.allow_rerere_auto),
+ OPT_BOOL(0, "reschedule-failed-exec", &opts.reschedule_failed_exec,
+ N_("automatically re-schedule any `exec` that fails")),
OPT_END()
};
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 00de70365e..774264bae8 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -104,6 +104,7 @@ struct rebase_options {
int rebase_merges, rebase_cousins;
char *strategy, *strategy_opts;
struct strbuf git_format_patch_opt;
+ int reschedule_failed_exec;
};
static int is_interactive(struct rebase_options *opts)
@@ -415,6 +416,8 @@ static int run_specific_rebase(struct rebase_options *opts)
argv_array_push(&child.args, opts->gpg_sign_opt);
if (opts->signoff)
argv_array_push(&child.args, "--signoff");
+ if (opts->reschedule_failed_exec)
+ argv_array_push(&child.args, "--reschedule-failed-exec");
status = run_command(&child);
goto finished_rebase;
@@ -530,6 +533,7 @@ finished_rebase:
#define RESET_HEAD_DETACH (1<<0)
#define RESET_HEAD_HARD (1<<1)
+#define RESET_HEAD_RUN_POST_CHECKOUT_HOOK (1<<2)
static int reset_head(struct object_id *oid, const char *action,
const char *switch_to_branch, unsigned flags,
@@ -537,6 +541,7 @@ static int reset_head(struct object_id *oid, const char *action,
{
unsigned detach_head = flags & RESET_HEAD_DETACH;
unsigned reset_hard = flags & RESET_HEAD_HARD;
+ unsigned run_hook = flags & RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
struct object_id head_oid;
struct tree_desc desc[2] = { { NULL }, { NULL } };
struct lock_file lock = LOCK_INIT;
@@ -636,6 +641,10 @@ static int reset_head(struct object_id *oid, const char *action,
ret = update_ref(reflog_head, "HEAD", oid, NULL, 0,
UPDATE_REFS_MSG_ON_ERR);
}
+ if (run_hook)
+ run_hook_le(NULL, "post-checkout",
+ oid_to_hex(orig ? orig : &null_oid),
+ oid_to_hex(oid), "1", NULL);
leave_reset_head:
strbuf_release(&msg);
@@ -674,6 +683,11 @@ static int rebase_config(const char *var, const char *value, void *data)
return 0;
}
+ if (!strcmp(var, "rebase.reschedulefailedexec")) {
+ opts->reschedule_failed_exec = git_config_bool(var, value);
+ return 0;
+ }
+
return git_default_config(var, value, data);
}
@@ -746,6 +760,23 @@ static int parse_opt_interactive(const struct option *opt, const char *arg,
return 0;
}
+struct opt_y {
+ struct string_list *list;
+ struct rebase_options *options;
+};
+
+static int parse_opt_y(const struct option *opt, const char *arg, int unset)
+{
+ struct opt_y *o = opt->value;
+
+ if (unset || !arg)
+ return -1;
+
+ o->options->reschedule_failed_exec = 1;
+ string_list_append(o->list, arg);
+ return 0;
+}
+
static void NORETURN error_on_missing_default_upstream(void)
{
struct branch *current_branch = branch_get(NULL);
@@ -826,6 +857,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
struct string_list strategy_options = STRING_LIST_INIT_NODUP;
struct object_id squash_onto;
char *squash_onto_name = NULL;
+ struct opt_y opt_y = { .list = &exec, .options = &options };
struct option builtin_rebase_options[] = {
OPT_STRING(0, "onto", &options.onto_name,
N_("revision"),
@@ -903,6 +935,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
OPT_STRING_LIST('x', "exec", &exec, N_("exec"),
N_("add exec lines after each commit of the "
"editable list")),
+ { OPTION_CALLBACK, 'y', NULL, &opt_y, N_("<cmd>"),
+ N_("same as --reschedule-failed-exec -x <cmd>"),
+ PARSE_OPT_NONEG, parse_opt_y },
OPT_BOOL(0, "allow-empty-message",
&options.allow_empty_message,
N_("allow rebasing commits with empty messages")),
@@ -920,6 +955,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
"strategy")),
OPT_BOOL(0, "root", &options.root,
N_("rebase all reachable commits up to the root(s)")),
+ OPT_BOOL(0, "reschedule-failed-exec",
+ &options.reschedule_failed_exec,
+ N_("automatically re-schedule any `exec` that fails")),
OPT_END(),
};
int i;
@@ -1216,6 +1254,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
break;
}
+ if (options.reschedule_failed_exec && !is_interactive(&options))
+ die(_("--reschedule-failed-exec requires an interactive rebase"));
+
if (options.git_am_opts.argc) {
/* all am options except -q are compatible only with --am */
for (i = options.git_am_opts.argc - 1; i >= 0; i--)
@@ -1241,7 +1282,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
options.flags |= REBASE_FORCE;
}
- if (options.type == REBASE_PRESERVE_MERGES)
+ if (options.type == REBASE_PRESERVE_MERGES) {
/*
* Note: incompatibility with --signoff handled in signoff block above
* Note: incompatibility with --interactive is just a strong warning;
@@ -1251,6 +1292,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
die(_("error: cannot combine '--preserve-merges' with "
"'--rebase-merges'"));
+ if (options.reschedule_failed_exec)
+ die(_("error: cannot combine '--preserve-merges' with "
+ "'--reschedule-failed-exec'"));
+ }
+
if (options.rebase_merges) {
if (strategy_options.nr)
die(_("error: cannot combine '--rebase-merges' with "
@@ -1466,7 +1512,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
getenv(GIT_REFLOG_ACTION_ENVIRONMENT),
options.switch_to);
if (reset_head(&oid, "checkout",
- options.head_name, 0,
+ options.head_name,
+ RESET_HEAD_RUN_POST_CHECKOUT_HOOK,
NULL, buf.buf) < 0) {
ret = !!error(_("could not switch to "
"%s"),
@@ -1540,7 +1587,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
strbuf_addf(&msg, "%s: checkout %s",
getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);
if (reset_head(&options.onto->object.oid, "checkout", NULL,
- RESET_HEAD_DETACH, NULL, msg.buf))
+ RESET_HEAD_DETACH | RESET_HEAD_RUN_POST_CHECKOUT_HOOK,
+ NULL, msg.buf))
die(_("Could not detach HEAD"));
strbuf_release(&msg);
diff --git a/builtin/repack.c b/builtin/repack.c
index 2a1c7b21c5..67f8978043 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -419,6 +419,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
if (!names.nr && !po_args.quiet)
printf_ln(_("Nothing new to pack."));
+ close_all_packs(the_repository->objects);
+
/*
* Ok we have prepared all new packfiles.
* First see if there are packs of the same name and if so
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index 2880ed37e3..51e9e1267e 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -361,6 +361,9 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
{
struct rev_info revs;
struct rev_list_info info;
+ struct setup_revision_opt s_r_opt = {
+ .allow_exclude_promisor_objects = 1,
+ };
int i;
int bisect_list = 0;
int bisect_show_vars = 0;
@@ -374,7 +377,6 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
git_config(git_default_config, NULL);
repo_init_revisions(the_repository, &revs, prefix);
revs.abbrev = DEFAULT_ABBREV;
- revs.allow_exclude_promisor_objects_opt = 1;
revs.commit_format = CMIT_FMT_UNSPECIFIED;
revs.do_not_die_on_missing_tree = 1;
@@ -406,7 +408,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
}
}
- argc = setup_revisions(argc, argv, &revs, NULL);
+ argc = setup_revisions(argc, argv, &revs, &s_r_opt);
memset(&info, 0, sizeof(info));
info.revs = &revs;
diff --git a/builtin/stripspace.c b/builtin/stripspace.c
index bdf0328869..be33eb83c1 100644
--- a/builtin/stripspace.c
+++ b/builtin/stripspace.c
@@ -30,6 +30,7 @@ int cmd_stripspace(int argc, const char **argv, const char *prefix)
{
struct strbuf buf = STRBUF_INIT;
enum stripspace_mode mode = STRIP_DEFAULT;
+ int nongit;
const struct option options[] = {
OPT_CMDMODE('s', "strip-comments", &mode,
@@ -46,7 +47,7 @@ int cmd_stripspace(int argc, const char **argv, const char *prefix)
usage_with_options(stripspace_usage, options);
if (mode == STRIP_COMMENTS || mode == COMMENT_LINES) {
- setup_git_directory_gently(NULL);
+ setup_git_directory_gently(&nongit);
git_config(git_default_config, NULL);
}
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index b45514be31..0e140f176c 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1131,6 +1131,8 @@ static void deinit_submodule(const char *path, const char *prefix,
if (!(flags & OPT_QUIET))
printf(format, displaypath);
+ submodule_unset_core_worktree(sub);
+
strbuf_release(&sb_rm);
}
@@ -1552,7 +1554,7 @@ struct submodule_update_clone {
#define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
SUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, 0, \
NULL, NULL, NULL, \
- NULL, 0, 0, 0, NULL, 0, 0, 0}
+ NULL, 0, 0, 0, NULL, 0, 0, 1}
static void next_submodule_warn_missing(struct submodule_update_clone *suc,
@@ -2046,7 +2048,7 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
struct repository subrepo;
if (argc != 2)
- BUG("submodule--helper connect-gitdir-workingtree <name> <path>");
+ BUG("submodule--helper ensure-core-worktree <path>");
path = argv[1];
@@ -2054,7 +2056,7 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
if (!sub)
BUG("We could get the submodule handle before?");
- if (repo_submodule_init(&subrepo, the_repository, path))
+ if (repo_submodule_init(&subrepo, the_repository, sub))
die(_("could not get a repository handle for submodule '%s'"), path);
if (!repo_config_get_string(&subrepo, "core.worktree", &cw)) {
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 5e84026177..3f9907fcc9 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -9,6 +9,7 @@
#include "refs.h"
#include "run-command.h"
#include "sigchain.h"
+#include "submodule.h"
#include "refs.h"
#include "utf8.h"
#include "worktree.h"
@@ -724,20 +725,36 @@ static int unlock_worktree(int ac, const char **av, const char *prefix)
static void validate_no_submodules(const struct worktree *wt)
{
struct index_state istate = { NULL };
+ struct strbuf path = STRBUF_INIT;
int i, found_submodules = 0;
- if (read_index_from(&istate, worktree_git_path(wt, "index"),
- get_worktree_git_dir(wt)) > 0) {
+ if (is_directory(worktree_git_path(wt, "modules"))) {
+ /*
+ * There could be false positives, e.g. the "modules"
+ * directory exists but is empty. But it's a rare case and
+ * this simpler check is probably good enough for now.
+ */
+ found_submodules = 1;
+ } else if (read_index_from(&istate, worktree_git_path(wt, "index"),
+ get_worktree_git_dir(wt)) > 0) {
for (i = 0; i < istate.cache_nr; i++) {
struct cache_entry *ce = istate.cache[i];
+ int err;
- if (S_ISGITLINK(ce->ce_mode)) {
- found_submodules = 1;
- break;
- }
+ if (!S_ISGITLINK(ce->ce_mode))
+ continue;
+
+ strbuf_reset(&path);
+ strbuf_addf(&path, "%s/%s", wt->path, ce->name);
+ if (!is_submodule_populated_gently(path.buf, &err))
+ continue;
+
+ found_submodules = 1;
+ break;
}
}
discard_index(&istate);
+ strbuf_release(&path);
if (found_submodules)
die(_("working trees containing submodules cannot be moved or removed"));