/* * This is called when new_ref is branched off of orig_ref, and tries * to infer the settings for branch.<new_ref>.{remote,merge} from the * config. */ static int setup_tracking(const char *new_ref, const char *orig_ref, enum branch_track track, int quiet) { struct tracking tracking; int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE; memset(&tracking, 0, sizeof(tracking)); tracking.spec.dst = (char *)orig_ref; if (for_each_remote(find_tracked_branch, &tracking)) return 1; if (!tracking.matches) switch (track) { case BRANCH_TRACK_ALWAYS: case BRANCH_TRACK_EXPLICIT: case BRANCH_TRACK_OVERRIDE: break; default: return 1; } if (tracking.matches > 1) return error(_("Not tracking: ambiguous information for ref %s"), orig_ref); install_branch_config(config_flags, new_ref, tracking.remote, tracking.src ? tracking.src : orig_ref); free(tracking.src); return 0; }
const char *unique_tracking_name(const char *name, struct object_id *oid) { struct tracking_name_data cb_data = { NULL, NULL, NULL, 1 }; cb_data.src_ref = xstrfmt("refs/heads/%s", name); cb_data.dst_oid = oid; for_each_remote(check_tracking_name, &cb_data); free(cb_data.src_ref); if (cb_data.unique) return cb_data.dst_ref; free(cb_data.dst_ref); return NULL; }
int cmd_fetch(int argc, const char **argv, const char *prefix) { int i; struct string_list list = { NULL, 0, 0, 0 }; struct remote *remote; int result = 0; /* Record the command line for the reflog */ strbuf_addstr(&default_rla, "fetch"); for (i = 1; i < argc; i++) strbuf_addf(&default_rla, " %s", argv[i]); argc = parse_options(argc, argv, prefix, builtin_fetch_options, builtin_fetch_usage, 0); if (all) { if (argc == 1) die("fetch --all does not take a repository argument"); else if (argc > 1) die("fetch --all does not make sense with refspecs"); (void) for_each_remote(get_one_remote_for_fetch, &list); result = fetch_multiple(&list); } else if (argc == 0) { /* No arguments -- use default remote */ remote = remote_get(NULL); result = fetch_one(remote, argc, argv); } else if (multiple) { /* All arguments are assumed to be remotes or groups */ for (i = 0; i < argc; i++) if (!add_remote_or_group(argv[i], &list)) die("No such remote or remote group: %s", argv[i]); result = fetch_multiple(&list); } else { /* Single remote or group */ (void) add_remote_or_group(argv[0], &list); if (list.nr > 1) { /* More than one remote */ if (argc > 1) die("Fetching a group and specifying refspecs does not make sense"); result = fetch_multiple(&list); } else { /* Zero or one remotes */ remote = remote_get(argv[0]); result = fetch_one(remote, argc-1, argv+1); } } /* All names were strdup()ed or strndup()ed */ list.strdup_strings = 1; string_list_clear(&list, 0); return result; }
/** * Dies with the appropriate reason for why there are no merge candidates: * * 1. We fetched from a specific remote, and a refspec was given, but it ended * up not fetching anything. This is usually because the user provided a * wildcard refspec which had no matches on the remote end. * * 2. We fetched from a non-default remote, but didn't specify a branch to * merge. We can't use the configured one because it applies to the default * remote, thus the user must specify the branches to merge. * * 3. We fetched from the branch's or repo's default remote, but: * * a. We are not on a branch, so there will never be a configured branch to * merge with. * * b. We are on a branch, but there is no configured branch to merge with. * * 4. We fetched from the branch's or repo's default remote, but the configured * branch to merge didn't get fetched. (Either it doesn't exist, or wasn't * part of the configured fetch refspec.) */ static void NORETURN die_no_merge_candidates(const char *repo, const char **refspecs) { struct branch *curr_branch = branch_get("HEAD"); const char *remote = curr_branch ? curr_branch->remote_name : NULL; if (*refspecs) { if (opt_rebase) fprintf_ln(stderr, _("There is no candidate for rebasing against among the refs that you just fetched.")); else fprintf_ln(stderr, _("There are no candidates for merging among the refs that you just fetched.")); fprintf_ln(stderr, _("Generally this means that you provided a wildcard refspec which had no\n" "matches on the remote end.")); } else if (repo && curr_branch && (!remote || strcmp(repo, remote))) { fprintf_ln(stderr, _("You asked to pull from the remote '%s', but did not specify\n" "a branch. Because this is not the default configured remote\n" "for your current branch, you must specify a branch on the command line."), repo); } else if (!curr_branch) { fprintf_ln(stderr, _("You are not currently on a branch.")); if (opt_rebase) fprintf_ln(stderr, _("Please specify which branch you want to rebase against.")); else fprintf_ln(stderr, _("Please specify which branch you want to merge with.")); fprintf_ln(stderr, _("See git-pull(1) for details.")); fprintf(stderr, "\n"); fprintf_ln(stderr, " git pull %s %s", _("<remote>"), _("<branch>")); fprintf(stderr, "\n"); } else if (!curr_branch->merge_nr) { const char *remote_name = NULL; if (for_each_remote(get_only_remote, &remote_name) || !remote_name) remote_name = _("<remote>"); fprintf_ln(stderr, _("There is no tracking information for the current branch.")); if (opt_rebase) fprintf_ln(stderr, _("Please specify which branch you want to rebase against.")); else fprintf_ln(stderr, _("Please specify which branch you want to merge with.")); fprintf_ln(stderr, _("See git-pull(1) for details.")); fprintf(stderr, "\n"); fprintf_ln(stderr, " git pull %s %s", _("<remote>"), _("<branch>")); fprintf(stderr, "\n"); fprintf_ln(stderr, _("If you wish to set tracking information for this branch you can do so with:")); fprintf(stderr, "\n"); fprintf_ln(stderr, " git branch --set-upstream-to=%s/%s %s\n", remote_name, _("<branch>"), curr_branch->name); } else fprintf_ln(stderr, _("Your configuration specifies to merge with the ref '%s'\n" "from the remote, but no such ref was fetched."), *curr_branch->merge_name); exit(1); }
/* * This is called when new_ref is branched off of orig_ref, and tries * to infer the settings for branch.<new_ref>.{remote,merge} from the * config. */ static int setup_tracking(const char *new_ref, const char *orig_ref, enum branch_track track) { char key[1024]; struct tracking tracking; if (strlen(new_ref) > 1024 - 7 - 7 - 1) return error("Tracking not set up: name too long: %s", new_ref); memset(&tracking, 0, sizeof(tracking)); tracking.spec.dst = (char *)orig_ref; if (for_each_remote(find_tracked_branch, &tracking)) return 1; if (!tracking.matches) switch (track) { case BRANCH_TRACK_ALWAYS: case BRANCH_TRACK_EXPLICIT: break; default: return 1; } if (tracking.matches > 1) return error("Not tracking: ambiguous information for ref %s", orig_ref); sprintf(key, "branch.%s.remote", new_ref); git_config_set(key, tracking.remote ? tracking.remote : "."); sprintf(key, "branch.%s.merge", new_ref); git_config_set(key, tracking.src ? tracking.src : orig_ref); printf("Branch %s set up to track %s branch %s.\n", new_ref, tracking.remote ? "remote" : "local", orig_ref); if (should_setup_rebase(&tracking)) { sprintf(key, "branch.%s.rebase", new_ref); git_config_set(key, "true"); printf("This branch will rebase on pull.\n"); } free(tracking.src); return 0; }
int setup_publish(const char *name, const char *ref) { struct tracking tracking; const char *remote, *remote_ref; memset(&tracking, 0, sizeof(tracking)); tracking.spec.dst = (char *)ref; if (for_each_remote(find_tracked_branch, &tracking)) return 1; if (tracking.matches > 1) return error(_("Not tracking: ambiguous information for ref %s"), ref); remote = tracking.remote; remote_ref = tracking.src ? tracking.src : ref; install_branch_publish(name, remote, remote_ref); free(tracking.src); return 0; }
static int validate_remote_tracking_branch(char *ref) { return !for_each_remote(check_tracking_branch, ref); }