summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/cat-file.c29
-rw-r--r--builtin/clone.c13
-rw-r--r--builtin/fast-import.c2
-rw-r--r--builtin/fetch.c14
-rw-r--r--builtin/gc.c1
-rw-r--r--builtin/index-pack.c4
-rw-r--r--builtin/name-rev.c71
-rw-r--r--builtin/pack-objects.c33
-rw-r--r--builtin/rebase.c2
-rw-r--r--builtin/repack.c12
-rw-r--r--builtin/reset.c13
-rw-r--r--builtin/rev-list.c29
-rw-r--r--builtin/sparse-checkout.c1
-rw-r--r--builtin/stash.c6
-rw-r--r--builtin/submodule--helper.c248
15 files changed, 293 insertions, 185 deletions
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 0663661c0b..50cf38999d 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -360,6 +360,13 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
}
}
+static void print_default_format(struct strbuf *scratch, struct expand_data *data)
+{
+ strbuf_addf(scratch, "%s %s %"PRIuMAX"\n", oid_to_hex(&data->oid),
+ type_name(data->type),
+ (uintmax_t)data->size);
+}
+
/*
* If "pack" is non-NULL, then "offset" is the byte offset within the pack from
* which the object may be accessed (though note that we may also rely on
@@ -391,8 +398,14 @@ static void batch_object_write(const char *obj_name,
}
strbuf_reset(scratch);
- strbuf_expand(scratch, opt->format, expand_format, data);
- strbuf_addch(scratch, '\n');
+
+ if (!opt->format) {
+ print_default_format(scratch, data);
+ } else {
+ strbuf_expand(scratch, opt->format, expand_format, data);
+ strbuf_addch(scratch, '\n');
+ }
+
batch_write(opt, scratch->buf, scratch->len);
if (opt->batch_mode == BATCH_MODE_CONTENTS) {
@@ -646,6 +659,8 @@ static void batch_objects_command(struct batch_options *opt,
strbuf_release(&input);
}
+#define DEFAULT_FORMAT "%(objectname) %(objecttype) %(objectsize)"
+
static int batch_objects(struct batch_options *opt)
{
struct strbuf input = STRBUF_INIT;
@@ -654,9 +669,6 @@ static int batch_objects(struct batch_options *opt)
int save_warning;
int retval = 0;
- if (!opt->format)
- opt->format = "%(objectname) %(objecttype) %(objectsize)";
-
/*
* Expand once with our special mark_query flag, which will prime the
* object_info to be handed to oid_object_info_extended for each
@@ -664,12 +676,17 @@ static int batch_objects(struct batch_options *opt)
*/
memset(&data, 0, sizeof(data));
data.mark_query = 1;
- strbuf_expand(&output, opt->format, expand_format, &data);
+ strbuf_expand(&output,
+ opt->format ? opt->format : DEFAULT_FORMAT,
+ expand_format,
+ &data);
data.mark_query = 0;
strbuf_release(&output);
if (opt->transform_mode)
data.split_on_whitespace = 1;
+ if (opt->format && !strcmp(opt->format, DEFAULT_FORMAT))
+ opt->format = NULL;
/*
* If we are printing out the object, then always fill in the type,
* since we will want to decide whether or not to stream.
diff --git a/builtin/clone.c b/builtin/clone.c
index 0aea177660..5231656379 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -33,6 +33,7 @@
#include "packfile.h"
#include "list-objects-filter-options.h"
#include "hook.h"
+#include "bundle.h"
/*
* Overall FIXMEs:
@@ -1172,6 +1173,18 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
warning(_("--local is ignored"));
transport->cloning = 1;
+ if (is_bundle) {
+ struct bundle_header header = BUNDLE_HEADER_INIT;
+ int fd = read_bundle_header(path, &header);
+ int has_filter = header.filter.choice != LOFC_DISABLED;
+
+ if (fd > 0)
+ close(fd);
+ bundle_header_release(&header);
+ if (has_filter)
+ die(_("cannot clone from filtered bundle"));
+ }
+
transport_set_option(transport, TRANS_OPT_KEEP, "yes");
if (reject_shallow)
diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index ad045c7c2d..28d3193c38 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -865,7 +865,7 @@ static void end_packfile(void)
struct tag *t;
close_pack_windows(pack_data);
- finalize_hashfile(pack_file, cur_pack_oid.hash, 0);
+ finalize_hashfile(pack_file, cur_pack_oid.hash, FSYNC_COMPONENT_PACK, 0);
fixup_pack_header_footer(pack_data->pack_fd, pack_data->hash,
pack_data->pack_name, object_count,
cur_pack_oid.hash, pack_size);
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 4d12c2fd4d..9b4018f62c 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -2258,13 +2258,13 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
max_children = fetch_parallel_config;
add_options_to_argv(&options);
- result = fetch_populated_submodules(the_repository,
- &options,
- submodule_prefix,
- recurse_submodules,
- recurse_submodules_default,
- verbosity < 0,
- max_children);
+ result = fetch_submodules(the_repository,
+ &options,
+ submodule_prefix,
+ recurse_submodules,
+ recurse_submodules_default,
+ verbosity < 0,
+ max_children);
strvec_clear(&options);
}
diff --git a/builtin/gc.c b/builtin/gc.c
index ffaf0daf5d..b335cffa33 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -30,7 +30,6 @@
#include "promisor-remote.h"
#include "refs.h"
#include "remote.h"
-#include "object-store.h"
#include "exec-cmd.h"
#include "hook.h"
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 8a5a644744..680b66b063 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1291,7 +1291,7 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha
nr_objects - nr_objects_initial);
stop_progress_msg(&progress, msg.buf);
strbuf_release(&msg);
- finalize_hashfile(f, tail_hash, 0);
+ finalize_hashfile(f, tail_hash, FSYNC_COMPONENT_PACK, 0);
hashcpy(read_hash, pack_hash);
fixup_pack_header_footer(output_fd, pack_hash,
curr_pack, nr_objects,
@@ -1513,7 +1513,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
if (!from_stdin) {
close(input_fd);
} else {
- fsync_or_die(output_fd, curr_pack_name);
+ fsync_component_or_die(FSYNC_COMPONENT_PACK, output_fd, curr_pack_name);
err = close(output_fd);
if (err)
die_errno(_("error while closing pack file"));
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 929591269d..c59b5699fe 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -9,6 +9,7 @@
#include "prio-queue.h"
#include "hash-lookup.h"
#include "commit-slab.h"
+#include "commit-graph.h"
/*
* One day. See the 'name a rev shortly after epoch' test in t6120 when
@@ -26,9 +27,58 @@ struct rev_name {
define_commit_slab(commit_rev_name, struct rev_name);
+static timestamp_t generation_cutoff = GENERATION_NUMBER_INFINITY;
static timestamp_t cutoff = TIME_MAX;
static struct commit_rev_name rev_names;
+/* Disable the cutoff checks entirely */
+static void disable_cutoff(void)
+{
+ generation_cutoff = 0;
+ cutoff = 0;
+}
+
+/* Cutoff searching any commits older than this one */
+static void set_commit_cutoff(struct commit *commit)
+{
+
+ if (cutoff > commit->date)
+ cutoff = commit->date;
+
+ if (generation_cutoff) {
+ timestamp_t generation = commit_graph_generation(commit);
+
+ if (generation_cutoff > generation)
+ generation_cutoff = generation;
+ }
+}
+
+/* adjust the commit date cutoff with a slop to allow for slightly incorrect
+ * commit timestamps in case of clock skew.
+ */
+static void adjust_cutoff_timestamp_for_slop(void)
+{
+ if (cutoff) {
+ /* check for undeflow */
+ if (cutoff > TIME_MIN + CUTOFF_DATE_SLOP)
+ cutoff = cutoff - CUTOFF_DATE_SLOP;
+ else
+ cutoff = TIME_MIN;
+ }
+}
+
+/* Check if a commit is before the cutoff. Prioritize generation numbers
+ * first, but use the commit timestamp if we lack generation data.
+ */
+static int commit_is_before_cutoff(struct commit *commit)
+{
+ if (generation_cutoff < GENERATION_NUMBER_INFINITY)
+ return generation_cutoff &&
+ commit_graph_generation(commit) < generation_cutoff;
+
+ return commit->date < cutoff;
+}
+
/* How many generations are maximally preferred over _one_ merge traversal? */
#define MERGE_TRAVERSAL_WEIGHT 65535
@@ -151,7 +201,7 @@ static void name_rev(struct commit *start_commit,
struct rev_name *start_name;
parse_commit(start_commit);
- if (start_commit->date < cutoff)
+ if (commit_is_before_cutoff(start_commit))
return;
start_name = create_or_update_name(start_commit, taggerdate, 0, 0,
@@ -181,7 +231,7 @@ static void name_rev(struct commit *start_commit,
int generation, distance;
parse_commit(parent);
- if (parent->date < cutoff)
+ if (commit_is_before_cutoff(parent))
continue;
if (parent_number > 1) {
@@ -568,7 +618,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
usage_with_options(name_rev_usage, opts);
}
if (all || annotate_stdin)
- cutoff = 0;
+ disable_cutoff();
for (; argc; argc--, argv++) {
struct object_id oid;
@@ -596,10 +646,8 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
continue;
}
- if (commit) {
- if (cutoff > commit->date)
- cutoff = commit->date;
- }
+ if (commit)
+ set_commit_cutoff(commit);
if (peel_tag) {
if (!commit) {
@@ -612,13 +660,8 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
add_object_array(object, *argv, &revs);
}
- if (cutoff) {
- /* check for undeflow */
- if (cutoff > TIME_MIN + CUTOFF_DATE_SLOP)
- cutoff = cutoff - CUTOFF_DATE_SLOP;
- else
- cutoff = TIME_MIN;
- }
+ adjust_cutoff_timestamp_for_slop();
+
for_each_ref(name_ref, &data);
name_tips();
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 47b0e1da7d..c23b788ac8 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1199,16 +1199,26 @@ static void write_pack_file(void)
display_progress(progress_state, written);
}
- /*
- * Did we write the wrong # entries in the header?
- * If so, rewrite it like in fast-import
- */
if (pack_to_stdout) {
- finalize_hashfile(f, hash, CSUM_HASH_IN_STREAM | CSUM_CLOSE);
+ /*
+ * We never fsync when writing to stdout since we may
+ * not be writing to an actual pack file. For instance,
+ * the upload-pack code passes a pipe here. Calling
+ * fsync on a pipe results in unnecessary
+ * synchronization with the reader on some platforms.
+ */
+ finalize_hashfile(f, hash, FSYNC_COMPONENT_NONE,
+ CSUM_HASH_IN_STREAM | CSUM_CLOSE);
} else if (nr_written == nr_remaining) {
- finalize_hashfile(f, hash, CSUM_HASH_IN_STREAM | CSUM_FSYNC | CSUM_CLOSE);
+ finalize_hashfile(f, hash, FSYNC_COMPONENT_PACK,
+ CSUM_HASH_IN_STREAM | CSUM_FSYNC | CSUM_CLOSE);
} else {
- int fd = finalize_hashfile(f, hash, 0);
+ /*
+ * If we wrote the wrong number of entries in the
+ * header, rewrite it like in fast-import.
+ */
+
+ int fd = finalize_hashfile(f, hash, FSYNC_COMPONENT_PACK, 0);
fixup_pack_header_footer(fd, hash, pack_tmp_name,
nr_written, hash, offset);
close(fd);
@@ -3651,7 +3661,7 @@ static int pack_options_allow_reuse(void)
static int get_object_list_from_bitmap(struct rev_info *revs)
{
- if (!(bitmap_git = prepare_bitmap_walk(revs, &filter_options, 0)))
+ if (!(bitmap_git = prepare_bitmap_walk(revs, 0)))
return -1;
if (pack_options_allow_reuse() &&
@@ -3727,6 +3737,7 @@ static void get_object_list(int ac, const char **av)
repo_init_revisions(the_repository, &revs, NULL);
save_commit_buffer = 0;
setup_revisions(ac, av, &revs, &s_r_opt);
+ list_objects_filter_copy(&revs.filter, &filter_options);
/* make sure shallows are read */
is_repository_shallow(the_repository);
@@ -3777,9 +3788,9 @@ static void get_object_list(int ac, const char **av)
if (!fn_show_object)
fn_show_object = show_object;
- traverse_commit_list_filtered(&filter_options, &revs,
- show_commit, fn_show_object, NULL,
- NULL);
+ traverse_commit_list(&revs,
+ show_commit, fn_show_object,
+ NULL);
if (unpack_unreachable_expiration) {
revs.ignore_missing_links = 1;
diff --git a/builtin/rebase.c b/builtin/rebase.c
index b29ad2b65e..27fde7bf28 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -829,6 +829,8 @@ static int checkout_up_to_date(struct rebase_options *options)
ropts.oid = &options->orig_head;
ropts.branch = options->head_name;
ropts.flags = RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
+ if (!ropts.branch)
+ ropts.flags |= RESET_HEAD_DETACH;
ropts.head_msg = buf.buf;
if (reset_head(the_repository, &ropts) < 0)
ret = error(_("could not switch to %s"), options->switch_to);
diff --git a/builtin/repack.c b/builtin/repack.c
index da1e364a75..d1a563d5b6 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -22,6 +22,7 @@ static int delta_base_offset = 1;
static int pack_kept_objects = -1;
static int write_bitmaps = -1;
static int use_delta_islands;
+static int run_update_server_info = 1;
static char *packdir, *packtmp_name, *packtmp;
static const char *const git_repack_usage[] = {
@@ -54,6 +55,10 @@ static int repack_config(const char *var, const char *value, void *cb)
use_delta_islands = git_config_bool(var, value);
return 0;
}
+ if (strcmp(var, "repack.updateserverinfo") == 0) {
+ run_update_server_info = git_config_bool(var, value);
+ return 0;
+ }
return git_default_config(var, value, cb);
}
@@ -620,7 +625,6 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
const char *unpack_unreachable = NULL;
int keep_unreachable = 0;
struct string_list keep_pack_list = STRING_LIST_INIT_NODUP;
- int no_update_server_info = 0;
struct pack_objects_args po_args = {NULL};
int geometric_factor = 0;
int write_midx = 0;
@@ -637,8 +641,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
N_("pass --no-reuse-delta to git-pack-objects")),
OPT_BOOL('F', NULL, &po_args.no_reuse_object,
N_("pass --no-reuse-object to git-pack-objects")),
- OPT_BOOL('n', NULL, &no_update_server_info,
- N_("do not run git-update-server-info")),
+ OPT_NEGBIT('n', NULL, &run_update_server_info,
+ N_("do not run git-update-server-info"), 1),
OPT__QUIET(&po_args.quiet, N_("be quiet")),
OPT_BOOL('l', "local", &po_args.local,
N_("pass --local to git-pack-objects")),
@@ -939,7 +943,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
prune_shallow(PRUNE_QUICK);
}
- if (!no_update_server_info)
+ if (run_update_server_info)
update_server_info(0);
remove_temporary_files();
diff --git a/builtin/reset.c b/builtin/reset.c
index 6e65e90c5d..344fff8f3a 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -392,6 +392,7 @@ static int git_reset_config(const char *var, const char *value, void *cb)
int cmd_reset(int argc, const char **argv, const char *prefix)
{
int reset_type = NONE, update_ref_status = 0, quiet = 0;
+ int no_refresh = 0;
int patch_mode = 0, pathspec_file_nul = 0, unborn;
const char *rev, *pathspec_from_file = NULL;
struct object_id oid;
@@ -399,6 +400,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
int intent_to_add = 0;
const struct option options[] = {
OPT__QUIET(&quiet, N_("be quiet, only report errors")),
+ OPT_BOOL(0, "no-refresh", &no_refresh,
+ N_("skip refreshing the index after reset")),
OPT_SET_INT(0, "mixed", &reset_type,
N_("reset HEAD and index"), MIXED),
OPT_SET_INT(0, "soft", &reset_type, N_("reset only HEAD"), SOFT),
@@ -420,7 +423,6 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
};
git_config(git_reset_config, NULL);
- git_config_get_bool("reset.quiet", &quiet);
argc = parse_options(argc, argv, prefix, options, git_reset_usage,
PARSE_OPT_KEEP_DASHDASH);
@@ -517,17 +519,16 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
if (read_from_tree(&pathspec, &oid, intent_to_add))
return 1;
the_index.updated_skipworktree = 1;
- if (!quiet && get_git_work_tree()) {
+ if (!no_refresh && get_git_work_tree()) {
uint64_t t_begin, t_delta_in_ms;
t_begin = getnanotime();
refresh_index(&the_index, flags, NULL, NULL,
_("Unstaged changes after reset:"));
t_delta_in_ms = (getnanotime() - t_begin) / 1000000;
- if (advice_enabled(ADVICE_RESET_QUIET_WARNING) && t_delta_in_ms > REFRESH_INDEX_DELAY_WARNING_IN_MS) {
- printf(_("\nIt took %.2f seconds to enumerate unstaged changes after reset. You can\n"
- "use '--quiet' to avoid this. Set the config setting reset.quiet to true\n"
- "to make this the default.\n"), t_delta_in_ms / 1000.0);
+ if (!quiet && advice_enabled(ADVICE_RESET_NO_REFRESH_WARNING) && t_delta_in_ms > REFRESH_INDEX_DELAY_WARNING_IN_MS) {
+ advise(_("It took %.2f seconds to refresh the index after reset. You can use\n"
+ "'--no-refresh' to avoid this."), t_delta_in_ms / 1000.0);
}
}
} else {
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index 38528c7f15..572da1472e 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -62,7 +62,6 @@ static const char rev_list_usage[] =
static struct progress *progress;
static unsigned progress_counter;
-static struct list_objects_filter_options filter_options;
static struct oidset omitted_objects;
static int arg_print_omitted; /* print objects omitted by filter */
@@ -400,7 +399,6 @@ static inline int parse_missing_action_value(const char *value)
}
static int try_bitmap_count(struct rev_info *revs,
- struct list_objects_filter_options *filter,
int filter_provided_objects)
{
uint32_t commit_count = 0,
@@ -436,7 +434,7 @@ static int try_bitmap_count(struct rev_info *revs,
*/
max_count = revs->max_count;
- bitmap_git = prepare_bitmap_walk(revs, filter, filter_provided_objects);
+ bitmap_git = prepare_bitmap_walk(revs, filter_provided_objects);
if (!bitmap_git)
return -1;
@@ -453,7 +451,6 @@ static int try_bitmap_count(struct rev_info *revs,
}
static int try_bitmap_traversal(struct rev_info *revs,
- struct list_objects_filter_options *filter,
int filter_provided_objects)
{
struct bitmap_index *bitmap_git;
@@ -465,7 +462,7 @@ static int try_bitmap_traversal(struct rev_info *revs,
if (revs->max_count >= 0)
return -1;
- bitmap_git = prepare_bitmap_walk(revs, filter, filter_provided_objects);
+ bitmap_git = prepare_bitmap_walk(revs, filter_provided_objects);
if (!bitmap_git)
return -1;
@@ -475,7 +472,6 @@ static int try_bitmap_traversal(struct rev_info *revs,
}
static int try_bitmap_disk_usage(struct rev_info *revs,
- struct list_objects_filter_options *filter,
int filter_provided_objects)
{
struct bitmap_index *bitmap_git;
@@ -483,7 +479,7 @@ static int try_bitmap_disk_usage(struct rev_info *revs,
if (!show_disk_usage)
return -1;
- bitmap_git = prepare_bitmap_walk(revs, filter, filter_provided_objects);
+ bitmap_git = prepare_bitmap_walk(revs, filter_provided_objects);
if (!bitmap_git)
return -1;
@@ -595,17 +591,6 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
show_progress = arg;
continue;
}
-
- if (skip_prefix(arg, ("--" CL_ARG__FILTER "="), &arg)) {
- parse_list_objects_filter(&filter_options, arg);
- if (filter_options.choice && !revs.blob_objects)
- die(_("object filtering requires --objects"));
- continue;
- }
- if (!strcmp(arg, ("--no-" CL_ARG__FILTER))) {
- list_objects_filter_set_no_filter(&filter_options);
- continue;
- }
if (!strcmp(arg, "--filter-provided-objects")) {
filter_provided_objects = 1;
continue;
@@ -688,11 +673,11 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
progress = start_delayed_progress(show_progress, 0);
if (use_bitmap_index) {
- if (!try_bitmap_count(&revs, &filter_options, filter_provided_objects))
+ if (!try_bitmap_count(&revs, filter_provided_objects))
return 0;
- if (!try_bitmap_disk_usage(&revs, &filter_options, filter_provided_objects))
+ if (!try_bitmap_disk_usage(&revs, filter_provided_objects))
return 0;
- if (!try_bitmap_traversal(&revs, &filter_options, filter_provided_objects))
+ if (!try_bitmap_traversal(&revs, filter_provided_objects))
return 0;
}
@@ -733,7 +718,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
oidset_init(&missing_objects, DEFAULT_OIDSET_SIZE);
traverse_commit_list_filtered(
- &filter_options, &revs, show_commit, show_object, &info,
+ &revs, show_commit, show_object, &info,
(arg_print_omitted ? &omitted_objects : NULL));
if (arg_print_omitted) {
diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
index 7f02e4352a..0217d44c5b 100644
--- a/builtin/sparse-checkout.c
+++ b/builtin/sparse-checkout.c
@@ -8,7 +8,6 @@
#include "run-command.h"
#include "strbuf.h"
#include "string-list.h"
-#include "cache.h"
#include "cache-tree.h"
#include "lockfile.h"
#include "resolve-undo.h"
diff --git a/builtin/stash.c b/builtin/stash.c
index 242e73cbb0..0c7b6a9588 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -16,7 +16,6 @@
#include "log-tree.h"
#include "diffcore.h"
#include "exec-cmd.h"
-#include "entry.h"
#include "reflog.h"
#define INCLUDE_ALL_FILES 2
@@ -311,7 +310,7 @@ static int reset_head(void)
* API for resetting.
*/
cp.git_cmd = 1;
- strvec_push(&cp.args, "reset");
+ strvec_pushl(&cp.args, "reset", "--quiet", "--refresh", NULL);
return run_command(&cp);
}
@@ -1623,7 +1622,8 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
struct child_process cp = CHILD_PROCESS_INIT;
cp.git_cmd = 1;
- strvec_pushl(&cp.args, "reset", "-q", "--", NULL);
+ strvec_pushl(&cp.args, "reset", "-q", "--refresh", "--",
+ NULL);
add_pathspecs(&cp.args, ps);
if (run_command(&cp)) {
ret = -1;
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 2f7c58362b..5301612d24 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -31,11 +31,13 @@
typedef void (*each_submodule_fn)(const struct cache_entry *list_item,
void *cb_data);
-static char *get_default_remote(void)
+static char *repo_get_default_remote(struct repository *repo)
{
char *dest = NULL, *ret;
struct strbuf sb = STRBUF_INIT;
- const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
+ struct ref_store *store = get_main_ref_store(repo);
+ const char *refname = refs_resolve_ref_unsafe(store, "HEAD", 0, NULL,
+ NULL);
if (!refname)
die(_("No such ref: %s"), "HEAD");
@@ -48,7 +50,7 @@ static char *get_default_remote(void)
die(_("Expecting a full ref name, got %s"), refname);
strbuf_addf(&sb, "branch.%s.remote", refname);
- if (git_config_get_string(sb.buf, &dest))
+ if (repo_config_get_string(repo, sb.buf, &dest))
ret = xstrdup("origin");
else
ret = dest;
@@ -57,19 +59,17 @@ static char *get_default_remote(void)
return ret;
}
-static int print_default_remote(int argc, const char **argv, const char *prefix)
+static char *get_default_remote_submodule(const char *module_path)
{
- char *remote;
-
- if (argc != 1)
- die(_("submodule--helper print-default-remote takes no arguments"));
+ struct repository subrepo;
- remote = get_default_remote();
- if (remote)
- printf("%s\n", remote);
+ repo_submodule_init(&subrepo, the_repository, module_path, null_oid());
+ return repo_get_default_remote(&subrepo);
+}
- free(remote);
- return 0;
+static char *get_default_remote(void)
+{
+ return repo_get_default_remote(the_repository);
}
static int starts_with_dot_slash(const char *str)
@@ -247,11 +247,10 @@ static int resolve_relative_url_test(int argc, const char **argv, const char *pr
return 0;
}
-/* the result should be freed by the caller. */
-static char *get_submodule_displaypath(const char *path, const char *prefix)
+static char *do_get_submodule_displaypath(const char *path,
+ const char *prefix,
+ const char *super_prefix)
{
- const char *super_prefix = get_super_prefix();
-
if (prefix && super_prefix) {
BUG("cannot have prefix '%s' and superprefix '%s'",
prefix, super_prefix);
@@ -267,6 +266,13 @@ static char *get_submodule_displaypath(const char *path, const char *prefix)
}
}
+/* the result should be freed by the caller. */
+static char *get_submodule_displaypath(const char *path, const char *prefix)
+{
+ const char *super_prefix = get_super_prefix();
+ return do_get_submodule_displaypath(path, prefix, super_prefix);
+}
+
static char *compute_rev_name(const char *sub_path, const char* object_id)
{
struct strbuf sb = STRBUF_INIT;
@@ -588,18 +594,22 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
struct init_cb {
const char *prefix;
+ const char *superprefix;
unsigned int flags;
};
#define INIT_CB_INIT { 0 }
static void init_submodule(const char *path, const char *prefix,
- unsigned int flags)
+ const char *superprefix, unsigned int flags)
{
const struct submodule *sub;
struct strbuf sb = STRBUF_INIT;
char *upd = NULL, *url = NULL, *displaypath;
- displaypath = get_submodule_displaypath(path, prefix);
+ /* try superprefix from the environment, if it is not passed explicitly */
+ if (!superprefix)
+ superprefix = get_super_prefix();
+ displaypath = do_get_submodule_displaypath(path, prefix, superprefix);
sub = submodule_from_path(the_repository, null_oid(), path);
@@ -673,7 +683,7 @@ static void init_submodule(const char *path, const char *prefix,
static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data)
{
struct init_cb *info = cb_data;
- init_submodule(list_item->name, info->prefix, info->flags);
+ init_submodule(list_item->name, info->prefix, info->superprefix, info->flags);
}
static int module_init(int argc, const char **argv, const char *prefix)
@@ -1343,9 +1353,8 @@ static void sync_submodule(const char *path, const char *prefix,
{
const struct submodule *sub;
char *remote_key = NULL;
- char *sub_origin_url, *super_config_url, *displaypath;
+ char *sub_origin_url, *super_config_url, *displaypath, *default_remote;
struct strbuf sb = STRBUF_INIT;
- struct child_process cp = CHILD_PROCESS_INIT;
char *sub_config_path = NULL;
if (!is_submodule_active(the_repository, path))
@@ -1384,21 +1393,15 @@ static void sync_submodule(const char *path, const char *prefix,
if (!is_submodule_populated_gently(path, NULL))
goto cleanup;
- prepare_submodule_repo_env(&cp.env_array);
- cp.git_cmd = 1;
- cp.dir = path;
- strvec_pushl(&cp.args, "submodule--helper",
- "print-default-remote", NULL);
-
strbuf_reset(&sb);
- if (capture_command(&cp, &sb, 0))
+ default_remote = get_default_remote_submodule(path);
+ if (!default_remote)
die(_("failed to get the default remote for submodule '%s'"),
path);
- strbuf_strip_suffix(&sb, "\n");
- remote_key = xstrfmt("remote.%s.url", sb.buf);
+ remote_key = xstrfmt("remote.%s.url", default_remote);
+ free(default_remote);
- strbuf_reset(&sb);
submodule_to_gitdir(&sb, path);
strbuf_addstr(&sb, "/config");
@@ -1957,29 +1960,6 @@ static void determine_submodule_update_strategy(struct repository *r,
free(key);
}
-static int module_update_module_mode(int argc, const char **argv, const char *prefix)
-{
- const char *path, *update = NULL;
- int just_cloned;
- struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT };
-
- if (argc < 3 || argc > 4)
- die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]");
-
- just_cloned = git_config_int("just_cloned", argv[1]);
- path = argv[2];
-
- if (argc == 4)
- update = argv[3];
-
- determine_submodule_update_strategy(the_repository,
- just_cloned, path, update,
- &update_strategy);
- fputs(submodule_strategy_to_string(&update_strategy), stdout);
-
- return 0;
-}
-
struct update_clone_data {
const struct submodule *sub;
struct object_id oid;
@@ -2020,6 +2000,7 @@ struct submodule_update_clone {
int failed_clones_nr, failed_clones_alloc;
int max_jobs;
+ unsigned int init;
};
#define SUBMODULE_UPDATE_CLONE_INIT { \
.list = MODULE_LIST_INIT, \
@@ -2038,10 +2019,11 @@ struct update_data {
struct object_id suboid;
struct submodule_update_strategy update_strategy;
int depth;
- unsigned int force: 1;
- unsigned int quiet: 1;
- unsigned int nofetch: 1;
- unsigned int just_cloned: 1;
+ unsigned int force;
+ unsigned int quiet;
+ unsigned int nofetch;
+ unsigned int just_cloned;
+ unsigned int remote;
};
#define UPDATE_DATA_INIT { .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT }
@@ -2475,6 +2457,16 @@ static int do_run_update_procedure(struct update_data *ud)
return run_update_command(ud, subforce);
}
+/*
+ * NEEDSWORK: As we convert "git submodule update" to C,
+ * update_submodule2() will invoke more and more functions, making it
+ * difficult to preserve the function ordering without forward
+ * declarations.
+ *
+ * When the conversion is complete, this forward declaration will be
+ * unnecessary and should be removed.
+ */
+static int update_submodule2(struct update_data *update_data);
static void update_submodule(struct update_clone_data *ucd)
{
fprintf(stdout, "dummy %s %d\t%s\n",
@@ -2518,6 +2510,8 @@ static int update_clone(int argc, const char **argv, const char *prefix)
int ret;
struct option module_update_clone_options[] = {
+ OPT_BOOL(0, "init", &suc.init,
+ N_("initialize uninitialized submodules before update")),
OPT_STRING(0, "prefix", &prefix,
N_("path"),
N_("path into the working tree")),
@@ -2551,7 +2545,12 @@ static int update_clone(int argc, const char **argv, const char *prefix)
};
const char *const git_submodule_helper_usage[] = {
- N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"),
+ N_("git submodule [--quiet] update"
+ " [--init [--filter=<filter-spec>]] [--remote]"
+ " [-N|--no-fetch] [-f|--force]"
+ " [--checkout|--merge|--rebase]"
+ " [--[no-]recommend-shallow] [--reference <repository>]"
+ " [--recursive] [--[no-]single-branch] [--] [<path>...]"),
NULL
};
suc.prefix = prefix;
@@ -2562,6 +2561,19 @@ static int update_clone(int argc, const char **argv, const char *prefix)
memset(&filter_options, 0, sizeof(filter_options));
argc = parse_options(argc, argv, prefix, module_update_clone_options,
git_submodule_helper_usage, 0);
+
+ if (filter_options.choice && !suc.init) {
+ /*
+ * NEEDSWORK: Don't use usage_with_options() because the
+ * usage string is for "git submodule update", but the
+ * options are for "git submodule--helper update-clone".
+ *
+ * This will no longer be an issue when "update-clone"
+ * is replaced by "git submodule--helper update".
+ */
+ usage(git_submodule_helper_usage[0]);
+ }
+
suc.filter_options = &filter_options;
if (update)
@@ -2576,6 +2588,29 @@ static int update_clone(int argc, const char **argv, const char *prefix)
if (pathspec.nr)
suc.warn_if_uninitialized = 1;
+ if (suc.init) {
+ struct module_list list = MODULE_LIST_INIT;
+ struct init_cb info = INIT_CB_INIT;
+
+ if (module_list_compute(argc, argv, suc.prefix,
+ &pathspec, &list) < 0)
+ return 1;
+
+ /*
+ * If there are no path args and submodule.active is set then,
+ * by default, only initialize 'active' modules.
+ */
+ if (!argc && git_config_get_value_multi("submodule.active"))
+ module_list_active(&list);
+
+ info.prefix = suc.prefix;
+ info.superprefix = suc.recursive_prefix;
+ if (suc.quiet)
+ info.flags |= OPT_QUIET;
+
+ for_each_listed_submodule(&list, init_submodule_cb, &info);
+ }
+
ret = update_submodules(&suc);
list_objects_filter_release(&filter_options);
return ret;
@@ -2583,16 +2618,17 @@ static int update_clone(int argc, const char **argv, const char *prefix)
static int run_update_procedure(int argc, const char **argv, const char *prefix)
{
- int force = 0, quiet = 0, nofetch = 0, just_cloned = 0;
char *prefixed_path, *update = NULL;
struct update_data update_data = UPDATE_DATA_INIT;
struct option options[] = {
- OPT__QUIET(&quiet, N_("suppress output for update by rebase or merge")),
- OPT__FORCE(&force, N_("force checkout updates"), 0),
- OPT_BOOL('N', "no-fetch", &nofetch,
+ OPT__QUIET(&update_data.quiet,
+ N_("suppress output for update by rebase or merge")),
+ OPT__FORCE(&update_data.force, N_("force checkout updates"),
+ 0),
+ OPT_BOOL('N', "no-fetch", &update_data.nofetch,
N_("don't fetch new objects from the remote site")),
- OPT_BOOL(0, "just-cloned", &just_cloned,
+ OPT_BOOL(0, "just-cloned", &update_data.just_cloned,
N_("overrides update mode in case the repository is a fresh clone")),
OPT_INTEGER(0, "depth", &update_data.depth, N_("depth for shallow fetch")),
OPT_STRING(0, "prefix", &prefix,
@@ -2607,9 +2643,8 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)
OPT_CALLBACK_F(0, "oid", &update_data.oid, N_("sha1"),
N_("SHA1 expected by superproject"), PARSE_OPT_NONEG,
parse_opt_object_id),
- OPT_CALLBACK_F(0, "suboid", &update_data.suboid, N_("subsha1"),
- N_("SHA1 of submodule's HEAD"), PARSE_OPT_NONEG,
- parse_opt_object_id),
+ OPT_BOOL(0, "remote", &update_data.remote,
+ N_("use SHA-1 of submodule's remote tracking branch")),
OPT_END()
};
@@ -2623,10 +2658,6 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)
if (argc != 1)
usage_with_options(usage, options);
- update_data.force = !!force;
- update_data.quiet = !!quiet;
- update_data.nofetch = !!nofetch;
- update_data.just_cloned = !!just_cloned;
update_data.sm_path = argv[0];
if (update_data.recursive_prefix)
@@ -2641,11 +2672,7 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix)
&update_data.update_strategy);
free(prefixed_path);
-
- if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force)
- return do_run_update_procedure(&update_data);
-
- return 3;
+ return update_submodule2(&update_data);
}
static int resolve_relative_path(int argc, const char **argv, const char *prefix)
@@ -2697,23 +2724,6 @@ static const char *remote_submodule_branch(const char *path)
return branch;
}
-static int resolve_remote_submodule_branch(int argc, const char **argv,
- const char *prefix)
-{
- const char *ret;
- struct strbuf sb = STRBUF_INIT;
- if (argc != 2)
- die("submodule--helper remote-branch takes exactly one arguments, got %d", argc);
-
- ret = remote_submodule_branch(argv[1]);
- if (!ret)
- die("submodule %s doesn't exist", argv[1]);
-
- printf("%s", ret);
- strbuf_release(&sb);
- return 0;
-}
-
static int push_check(int argc, const char **argv, const char *prefix)
{
struct remote *remote;
@@ -2791,17 +2801,11 @@ static int push_check(int argc, const char **argv, const char *prefix)
return 0;
}
-static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
+static void ensure_core_worktree(const char *path)
{
- const char *path;
const char *cw;
struct repository subrepo;
- if (argc != 2)
- BUG("submodule--helper ensure-core-worktree <path>");
-
- path = argv[1];
-
if (repo_submodule_init(&subrepo, the_repository, path, null_oid()))
die(_("could not get a repository handle for submodule '%s'"), path);
@@ -2821,8 +2825,6 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
free(abs_path);
strbuf_release(&sb);
}
-
- return 0;
}
static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
@@ -3045,6 +3047,42 @@ static int module_create_branch(int argc, const char **argv, const char *prefix)
force, reflog, quiet, track, dry_run);
return 0;
}
+
+/* NEEDSWORK: this is a temporary name until we delete update_submodule() */
+static int update_submodule2(struct update_data *update_data)
+{
+ ensure_core_worktree(update_data->sm_path);
+ if (update_data->just_cloned)
+ oidcpy(&update_data->suboid, null_oid());
+ else if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid))
+ die(_("Unable to find current revision in submodule path '%s'"),
+ update_data->displaypath);
+
+ if (update_data->remote) {
+ char *remote_name = get_default_remote_submodule(update_data->sm_path);
+ const char *branch = remote_submodule_branch(update_data->sm_path);
+ char *remote_ref = xstrfmt("refs/remotes/%s/%s", remote_name, branch);
+
+ if (!update_data->nofetch) {
+ if (fetch_in_submodule(update_data->sm_path, update_data->depth,
+ 0, NULL))
+ die(_("Unable to fetch in submodule path '%s'"),
+ update_data->sm_path);
+ }
+
+ if (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid))
+ die(_("Unable to find %s revision in submodule path '%s'"),
+ remote_ref, update_data->sm_path);
+
+ free(remote_ref);
+ }
+
+ if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force)
+ return do_run_update_procedure(update_data);
+
+ return 3;
+}
+
struct add_data {
const char *prefix;
const char *branch;
@@ -3433,20 +3471,16 @@ static struct cmd_struct commands[] = {
{"name", module_name, 0},
{"clone", module_clone, 0},
{"add", module_add, SUPPORT_SUPER_PREFIX},
- {"update-module-mode", module_update_module_mode, 0},
{"update-clone", update_clone, 0},
{"run-update-procedure", run_update_procedure, 0},
- {"ensure-core-worktree", ensure_core_worktree, 0},
{"relative-path", resolve_relative_path, 0},
{"resolve-relative-url-test", resolve_relative_url_test, 0},
{"foreach", module_foreach, SUPPORT_SUPER_PREFIX},
{"init", module_init, SUPPORT_SUPER_PREFIX},
{"status", module_status, SUPPORT_SUPER_PREFIX},
- {"print-default-remote", print_default_remote, 0},
{"sync", module_sync, SUPPORT_SUPER_PREFIX},
{"deinit", module_deinit, 0},
{"summary", module_summary, SUPPORT_SUPER_PREFIX},
- {"remote-branch", resolve_remote_submodule_branch, 0},
{"push-check", push_check, 0},
{"absorb-git-dirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX},
{"is-active", is_active, 0},