summaryrefslogtreecommitdiff
path: root/builtin/fetch.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/fetch.c')
-rw-r--r--builtin/fetch.c50
1 files changed, 41 insertions, 9 deletions
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 0f23dd4..a6d3268 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -80,6 +80,7 @@ static struct list_objects_filter_options filter_options;
static struct string_list server_options = STRING_LIST_INIT_DUP;
static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP;
static int fetch_write_commit_graph = -1;
+static int stdin_refspecs = 0;
static int git_fetch_config(const char *k, const char *v, void *cb)
{
@@ -205,6 +206,8 @@ static struct option builtin_fetch_options[] = {
N_("check for forced-updates on all updated branches")),
OPT_BOOL(0, "write-commit-graph", &fetch_write_commit_graph,
N_("write the commit-graph after fetching")),
+ OPT_BOOL(0, "stdin", &stdin_refspecs,
+ N_("accept refspecs from stdin")),
OPT_END()
};
@@ -442,6 +445,7 @@ static struct ref *get_ref_map(struct remote *remote,
struct ref *orefs = NULL, **oref_tail = &orefs;
struct hashmap existing_refs;
+ int existing_refs_populated = 0;
if (rs->nr) {
struct refspec *fetch_refspec;
@@ -535,15 +539,18 @@ static struct ref *get_ref_map(struct remote *remote,
ref_map = ref_remove_duplicates(ref_map);
- refname_hash_init(&existing_refs);
- for_each_ref(add_one_refname, &existing_refs);
-
for (rm = ref_map; rm; rm = rm->next) {
if (rm->peer_ref) {
const char *refname = rm->peer_ref->name;
struct refname_hash_entry *peer_item;
unsigned int hash = strhash(refname);
+ if (!existing_refs_populated) {
+ refname_hash_init(&existing_refs);
+ for_each_ref(add_one_refname, &existing_refs);
+ existing_refs_populated = 1;
+ }
+
peer_item = hashmap_get_entry_from_hash(&existing_refs,
hash, refname,
struct refname_hash_entry, ent);
@@ -553,7 +560,8 @@ static struct ref *get_ref_map(struct remote *remote,
}
}
}
- hashmap_free_entries(&existing_refs, struct refname_hash_entry, ent);
+ if (existing_refs_populated)
+ hashmap_free_entries(&existing_refs, struct refname_hash_entry, ent);
return ref_map;
}
@@ -1015,11 +1023,17 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
rc |= update_local_ref(ref, what, rm, &note,
summary_width);
free(ref);
- } else
+ } else if (write_fetch_head || dry_run) {
+ /*
+ * Display fetches written to FETCH_HEAD (or
+ * would be written to FETCH_HEAD, if --dry-run
+ * is set).
+ */
format_display(&note, '*',
*kind ? kind : "branch", NULL,
*what ? what : "HEAD",
"FETCH_HEAD", summary_width);
+ }
if (note.len) {
if (verbosity >= 0 && !shown_url) {
fprintf(stderr, _("From %.*s\n"),
@@ -1680,7 +1694,8 @@ static inline void fetch_one_setup_partial(struct remote *remote)
return;
}
-static int fetch_one(struct remote *remote, int argc, const char **argv, int prune_tags_ok)
+static int fetch_one(struct remote *remote, int argc, const char **argv,
+ int prune_tags_ok, int use_stdin_refspecs)
{
struct refspec rs = REFSPEC_INIT_FETCH;
int i;
@@ -1737,6 +1752,13 @@ static int fetch_one(struct remote *remote, int argc, const char **argv, int pru
}
}
+ if (use_stdin_refspecs) {
+ struct strbuf line = STRBUF_INIT;
+ while (strbuf_getline_lf(&line, stdin) != EOF)
+ refspec_append(&rs, line.buf);
+ strbuf_release(&line);
+ }
+
if (server_options.nr)
gtransport->server_options = &server_options;
@@ -1771,12 +1793,18 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
free(anon);
}
- fetch_config_from_gitmodules(&submodule_fetch_jobs_config,
- &recurse_submodules);
git_config(git_fetch_config, NULL);
argc = parse_options(argc, argv, prefix,
builtin_fetch_options, builtin_fetch_usage, 0);
+ if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
+ int *sfjc = submodule_fetch_jobs_config == -1
+ ? &submodule_fetch_jobs_config : NULL;
+ int *rs = recurse_submodules == RECURSE_SUBMODULES_DEFAULT
+ ? &recurse_submodules : NULL;
+
+ fetch_config_from_gitmodules(sfjc, rs);
+ }
if (deepen_relative) {
if (deepen_relative < 0)
@@ -1837,7 +1865,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
if (remote) {
if (filter_options.choice || has_promisor_remote())
fetch_one_setup_partial(remote);
- result = fetch_one(remote, argc, argv, prune_tags_ok);
+ result = fetch_one(remote, argc, argv, prune_tags_ok, stdin_refspecs);
} else {
int max_children = max_jobs;
@@ -1845,6 +1873,10 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
die(_("--filter can only be used with the remote "
"configured in extensions.partialclone"));
+ if (stdin_refspecs)
+ die(_("--stdin can only be used when fetching "
+ "from one remote"));
+
if (max_children < 0)
max_children = fetch_parallel_config;