summaryrefslogtreecommitdiff
path: root/builtin-fetch.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin-fetch.c')
-rw-r--r--builtin-fetch.c57
1 files changed, 36 insertions, 21 deletions
diff --git a/builtin-fetch.c b/builtin-fetch.c
index 7eec4a0e43..7fb35fca9d 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -10,6 +10,7 @@
#include "transport.h"
#include "run-command.h"
#include "parse-options.h"
+#include "sigchain.h"
static const char * const builtin_fetch_usage[] = {
"git fetch [options] [<repository> <refspec>...]",
@@ -22,7 +23,7 @@ enum {
TAGS_SET = 2
};
-static int append, force, keep, update_head_ok, verbose, quiet;
+static int append, force, keep, update_head_ok, verbosity;
static int tags = TAGS_DEFAULT;
static const char *depth;
static const char *upload_pack;
@@ -30,8 +31,7 @@ static struct strbuf default_rla = STRBUF_INIT;
static struct transport *transport;
static struct option builtin_fetch_options[] = {
- OPT__QUIET(&quiet),
- OPT__VERBOSE(&verbose),
+ OPT__VERBOSITY(&verbosity),
OPT_BOOLEAN('a', "append", &append,
"append to .git/FETCH_HEAD instead of overwriting"),
OPT_STRING(0, "upload-pack", &upload_pack, "PATH",
@@ -59,7 +59,7 @@ static void unlock_pack(void)
static void unlock_pack_on_signal(int signo)
{
unlock_pack();
- signal(SIGINT, SIG_DFL);
+ sigchain_pop(signo);
raise(signo);
}
@@ -86,10 +86,10 @@ static void add_merge_config(struct ref **head,
/*
* Not fetched to a tracking branch? We need to fetch
* it anyway to allow this branch's "branch.$name.merge"
- * to be honored by git-pull, but we do not have to
+ * to be honored by 'git pull', but we do not have to
* fail if branch.$name.merge is misconfigured to point
* at a nonexisting branch. If we were indeed called by
- * git-pull, it will notice the misconfiguration because
+ * 'git pull', it will notice the misconfiguration because
* there is no entry in the resulting FETCH_HEAD marked
* for merging.
*/
@@ -192,7 +192,6 @@ static int s_update_ref(const char *action,
static int update_local_ref(struct ref *ref,
const char *remote,
- int verbose,
char *display)
{
struct commit *current = NULL, *updated;
@@ -210,7 +209,7 @@ static int update_local_ref(struct ref *ref,
die("object %s not found", sha1_to_hex(ref->new_sha1));
if (!hashcmp(ref->old_sha1, ref->new_sha1)) {
- if (verbose)
+ if (verbosity > 0)
sprintf(display, "= %-*s %-*s -> %s", SUMMARY_WIDTH,
"[up to date]", REFCOL_WIDTH, remote,
pretty_ref);
@@ -366,18 +365,19 @@ static int store_updated_refs(const char *url, const char *remote_name,
note);
if (ref)
- rc |= update_local_ref(ref, what, verbose, note);
+ rc |= update_local_ref(ref, what, note);
else
sprintf(note, "* %-*s %-*s -> FETCH_HEAD",
SUMMARY_WIDTH, *kind ? kind : "branch",
REFCOL_WIDTH, *what ? what : "HEAD");
if (*note) {
- if (!shown_url) {
+ if (verbosity >= 0 && !shown_url) {
fprintf(stderr, "From %.*s\n",
url_len, url);
shown_url = 1;
}
- fprintf(stderr, " %s\n", note);
+ if (verbosity >= 0)
+ fprintf(stderr, " %s\n", note);
}
}
fclose(fp);
@@ -396,7 +396,7 @@ static int store_updated_refs(const char *url, const char *remote_name,
* The refs we are going to fetch are in to_fetch (nr_heads in
* total). If running
*
- * $ git-rev-list --objects to_fetch[0] to_fetch[1] ... --not --all
+ * $ git rev-list --objects to_fetch[0] to_fetch[1] ... --not --all
*
* does not error out, that means everything reachable from the
* refs we are going to fetch exists and is connected to some of
@@ -521,8 +521,8 @@ static void find_non_local_tags(struct transport *transport,
will_fetch(head, ref->old_sha1))) {
string_list_insert(ref_name, &new_refs);
- rm = alloc_ref_from_str(ref_name);
- rm->peer_ref = alloc_ref_from_str(ref_name);
+ rm = alloc_ref(ref_name);
+ rm->peer_ref = alloc_ref(ref_name);
hashcpy(rm->old_sha1, ref_sha1);
**tail = rm;
@@ -534,6 +534,19 @@ static void find_non_local_tags(struct transport *transport,
string_list_clear(&new_refs, 0);
}
+static void check_not_current_branch(struct ref *ref_map)
+{
+ struct branch *current_branch = branch_get(NULL);
+
+ if (is_bare_repository() || !current_branch)
+ return;
+
+ for (; ref_map; ref_map = ref_map->next)
+ if (ref_map->peer_ref && !strcmp(current_branch->refname,
+ ref_map->peer_ref->name))
+ die("Refusing to fetch into current branch");
+}
+
static int do_fetch(struct transport *transport,
struct refspec *refs, int ref_count)
{
@@ -558,6 +571,8 @@ static int do_fetch(struct transport *transport,
}
ref_map = get_ref_map(transport, refs, ref_count, tags, &autotags);
+ if (!update_head_ok)
+ check_not_current_branch(ref_map);
for (rm = ref_map; rm; rm = rm->next) {
if (rm->peer_ref)
@@ -593,7 +608,7 @@ static void set_option(const char *name, const char *value)
{
int r = transport_set_option(transport, name, value);
if (r < 0)
- die("Option \"%s\" value \"%s\" is not valid for %s\n",
+ die("Option \"%s\" value \"%s\" is not valid for %s",
name, value, transport->url);
if (r > 0)
warning("Option \"%s\" is ignored for %s\n",
@@ -621,10 +636,13 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
else
remote = remote_get(argv[0]);
+ if (!remote)
+ die("Where do you want to fetch from today?");
+
transport = transport_get(remote, remote->url[0]);
- if (verbose >= 2)
+ if (verbosity >= 2)
transport->verbose = 1;
- if (quiet)
+ if (verbosity < 0)
transport->verbose = -1;
if (upload_pack)
set_option(TRANS_OPT_UPLOADPACK, upload_pack);
@@ -633,9 +651,6 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
if (depth)
set_option(TRANS_OPT_DEPTH, depth);
- if (!transport->url)
- die("Where do you want to fetch from today?");
-
if (argc > 1) {
int j = 0;
refs = xcalloc(argc + 1, sizeof(const char *));
@@ -658,7 +673,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
ref_nr = j;
}
- signal(SIGINT, unlock_pack_on_signal);
+ sigchain_push_common(unlock_pack_on_signal);
atexit(unlock_pack);
exit_code = do_fetch(transport,
parse_fetch_refspec(ref_nr, refs), ref_nr);