7404597678d46b7321c86b9d7239ef672b44fa60
   1#include "git-compat-util.h"
   2#include "cache.h"
   3#include "config.h"
   4#include "branch.h"
   5#include "refs.h"
   6#include "remote.h"
   7#include "commit.h"
   8#include "worktree.h"
   9
  10struct tracking {
  11        struct refspec spec;
  12        char *src;
  13        const char *remote;
  14        int matches;
  15};
  16
  17static int find_tracked_branch(struct remote *remote, void *priv)
  18{
  19        struct tracking *tracking = priv;
  20
  21        if (!remote_find_tracking(remote, &tracking->spec)) {
  22                if (++tracking->matches == 1) {
  23                        tracking->src = tracking->spec.src;
  24                        tracking->remote = remote->name;
  25                } else {
  26                        free(tracking->spec.src);
  27                        if (tracking->src) {
  28                                FREE_AND_NULL(tracking->src);
  29                        }
  30                }
  31                tracking->spec.src = NULL;
  32        }
  33
  34        return 0;
  35}
  36
  37static int should_setup_rebase(const char *origin)
  38{
  39        switch (autorebase) {
  40        case AUTOREBASE_NEVER:
  41                return 0;
  42        case AUTOREBASE_LOCAL:
  43                return origin == NULL;
  44        case AUTOREBASE_REMOTE:
  45                return origin != NULL;
  46        case AUTOREBASE_ALWAYS:
  47                return 1;
  48        }
  49        return 0;
  50}
  51
  52static const char tracking_advice[] =
  53N_("\n"
  54"After fixing the error cause you may try to fix up\n"
  55"the remote tracking information by invoking\n"
  56"\"git branch --set-upstream-to=%s%s%s\".");
  57
  58int install_branch_config(int flag, const char *local, const char *origin, const char *remote)
  59{
  60        const char *shortname = NULL;
  61        struct strbuf key = STRBUF_INIT;
  62        int rebasing = should_setup_rebase(origin);
  63
  64        if (skip_prefix(remote, "refs/heads/", &shortname)
  65            && !strcmp(local, shortname)
  66            && !origin) {
  67                warning(_("Not setting branch %s as its own upstream."),
  68                        local);
  69                return 0;
  70        }
  71
  72        strbuf_addf(&key, "branch.%s.remote", local);
  73        if (git_config_set_gently(key.buf, origin ? origin : ".") < 0)
  74                goto out_err;
  75
  76        strbuf_reset(&key);
  77        strbuf_addf(&key, "branch.%s.merge", local);
  78        if (git_config_set_gently(key.buf, remote) < 0)
  79                goto out_err;
  80
  81        if (rebasing) {
  82                strbuf_reset(&key);
  83                strbuf_addf(&key, "branch.%s.rebase", local);
  84                if (git_config_set_gently(key.buf, "true") < 0)
  85                        goto out_err;
  86        }
  87        strbuf_release(&key);
  88
  89        if (flag & BRANCH_CONFIG_VERBOSE) {
  90                if (shortname) {
  91                        if (origin)
  92                                printf_ln(rebasing ?
  93                                          _("Branch '%s' set up to track remote branch '%s' from '%s' by rebasing.") :
  94                                          _("Branch '%s' set up to track remote branch '%s' from '%s'."),
  95                                          local, shortname, origin);
  96                        else
  97                                printf_ln(rebasing ?
  98                                          _("Branch '%s' set up to track local branch '%s' by rebasing.") :
  99                                          _("Branch '%s' set up to track local branch '%s'."),
 100                                          local, shortname);
 101                } else {
 102                        if (origin)
 103                                printf_ln(rebasing ?
 104                                          _("Branch '%s' set up to track remote ref '%s' by rebasing.") :
 105                                          _("Branch '%s' set up to track remote ref '%s'."),
 106                                          local, remote);
 107                        else
 108                                printf_ln(rebasing ?
 109                                          _("Branch '%s' set up to track local ref '%s' by rebasing.") :
 110                                          _("Branch '%s' set up to track local ref '%s'."),
 111                                          local, remote);
 112                }
 113        }
 114
 115        return 0;
 116
 117out_err:
 118        strbuf_release(&key);
 119        error(_("Unable to write upstream branch configuration"));
 120
 121        advise(_(tracking_advice),
 122               origin ? origin : "",
 123               origin ? "/" : "",
 124               shortname ? shortname : remote);
 125
 126        return -1;
 127}
 128
 129/*
 130 * This is called when new_ref is branched off of orig_ref, and tries
 131 * to infer the settings for branch.<new_ref>.{remote,merge} from the
 132 * config.
 133 */
 134static void setup_tracking(const char *new_ref, const char *orig_ref,
 135                           enum branch_track track, int quiet)
 136{
 137        struct tracking tracking;
 138        int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE;
 139
 140        memset(&tracking, 0, sizeof(tracking));
 141        tracking.spec.dst = (char *)orig_ref;
 142        if (for_each_remote(find_tracked_branch, &tracking))
 143                return;
 144
 145        if (!tracking.matches)
 146                switch (track) {
 147                case BRANCH_TRACK_ALWAYS:
 148                case BRANCH_TRACK_EXPLICIT:
 149                case BRANCH_TRACK_OVERRIDE:
 150                        break;
 151                default:
 152                        return;
 153                }
 154
 155        if (tracking.matches > 1)
 156                die(_("Not tracking: ambiguous information for ref %s"),
 157                    orig_ref);
 158
 159        if (install_branch_config(config_flags, new_ref, tracking.remote,
 160                              tracking.src ? tracking.src : orig_ref) < 0)
 161                exit(-1);
 162
 163        free(tracking.src);
 164}
 165
 166int read_branch_desc(struct strbuf *buf, const char *branch_name)
 167{
 168        char *v = NULL;
 169        struct strbuf name = STRBUF_INIT;
 170        strbuf_addf(&name, "branch.%s.description", branch_name);
 171        if (git_config_get_string(name.buf, &v)) {
 172                strbuf_release(&name);
 173                return -1;
 174        }
 175        strbuf_addstr(buf, v);
 176        free(v);
 177        strbuf_release(&name);
 178        return 0;
 179}
 180
 181int validate_new_branchname(const char *name, struct strbuf *ref,
 182                            int force, int attr_only)
 183{
 184        const char *head;
 185
 186        if (strbuf_check_branch_ref(ref, name))
 187                die(_("'%s' is not a valid branch name."), name);
 188
 189        if (!ref_exists(ref->buf))
 190                return 0;
 191
 192        if (attr_only)
 193                return 1;
 194
 195        if (!force)
 196                die(_("A branch named '%s' already exists."),
 197                    ref->buf + strlen("refs/heads/"));
 198
 199        head = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
 200        if (!is_bare_repository() && head && !strcmp(head, ref->buf))
 201                die(_("Cannot force update the current branch."));
 202
 203        return 1;
 204}
 205
 206static int check_tracking_branch(struct remote *remote, void *cb_data)
 207{
 208        char *tracking_branch = cb_data;
 209        struct refspec query;
 210        memset(&query, 0, sizeof(struct refspec));
 211        query.dst = tracking_branch;
 212        return !remote_find_tracking(remote, &query);
 213}
 214
 215static int validate_remote_tracking_branch(char *ref)
 216{
 217        return !for_each_remote(check_tracking_branch, ref);
 218}
 219
 220static const char upstream_not_branch[] =
 221N_("Cannot setup tracking information; starting point '%s' is not a branch.");
 222static const char upstream_missing[] =
 223N_("the requested upstream branch '%s' does not exist");
 224static const char upstream_advice[] =
 225N_("\n"
 226"If you are planning on basing your work on an upstream\n"
 227"branch that already exists at the remote, you may need to\n"
 228"run \"git fetch\" to retrieve it.\n"
 229"\n"
 230"If you are planning to push out a new local branch that\n"
 231"will track its remote counterpart, you may want to use\n"
 232"\"git push -u\" to set the upstream config as you push.");
 233
 234void create_branch(const char *name, const char *start_name,
 235                   int force, int reflog, int clobber_head,
 236                   int quiet, enum branch_track track)
 237{
 238        struct commit *commit;
 239        struct object_id oid;
 240        char *real_ref;
 241        struct strbuf ref = STRBUF_INIT;
 242        int forcing = 0;
 243        int dont_change_ref = 0;
 244        int explicit_tracking = 0;
 245
 246        if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
 247                explicit_tracking = 1;
 248
 249        if (validate_new_branchname(name, &ref, force,
 250                                    track == BRANCH_TRACK_OVERRIDE ||
 251                                    clobber_head)) {
 252                if (!force)
 253                        dont_change_ref = 1;
 254                else
 255                        forcing = 1;
 256        }
 257
 258        real_ref = NULL;
 259        if (get_oid(start_name, &oid)) {
 260                if (explicit_tracking) {
 261                        if (advice_set_upstream_failure) {
 262                                error(_(upstream_missing), start_name);
 263                                advise(_(upstream_advice));
 264                                exit(1);
 265                        }
 266                        die(_(upstream_missing), start_name);
 267                }
 268                die(_("Not a valid object name: '%s'."), start_name);
 269        }
 270
 271        switch (dwim_ref(start_name, strlen(start_name), oid.hash, &real_ref)) {
 272        case 0:
 273                /* Not branching from any existing branch */
 274                if (explicit_tracking)
 275                        die(_(upstream_not_branch), start_name);
 276                break;
 277        case 1:
 278                /* Unique completion -- good, only if it is a real branch */
 279                if (!starts_with(real_ref, "refs/heads/") &&
 280                    validate_remote_tracking_branch(real_ref)) {
 281                        if (explicit_tracking)
 282                                die(_(upstream_not_branch), start_name);
 283                        else
 284                                real_ref = NULL;
 285                }
 286                break;
 287        default:
 288                die(_("Ambiguous object name: '%s'."), start_name);
 289                break;
 290        }
 291
 292        if ((commit = lookup_commit_reference(&oid)) == NULL)
 293                die(_("Not a valid branch point: '%s'."), start_name);
 294        oidcpy(&oid, &commit->object.oid);
 295
 296        if (reflog)
 297                log_all_ref_updates = LOG_REFS_NORMAL;
 298
 299        if (!dont_change_ref) {
 300                struct ref_transaction *transaction;
 301                struct strbuf err = STRBUF_INIT;
 302                char *msg;
 303
 304                if (forcing)
 305                        msg = xstrfmt("branch: Reset to %s", start_name);
 306                else
 307                        msg = xstrfmt("branch: Created from %s", start_name);
 308
 309                transaction = ref_transaction_begin(&err);
 310                if (!transaction ||
 311                    ref_transaction_update(transaction, ref.buf,
 312                                           oid.hash, forcing ? NULL : null_sha1,
 313                                           0, msg, &err) ||
 314                    ref_transaction_commit(transaction, &err))
 315                        die("%s", err.buf);
 316                ref_transaction_free(transaction);
 317                strbuf_release(&err);
 318                free(msg);
 319        }
 320
 321        if (real_ref && track)
 322                setup_tracking(ref.buf + 11, real_ref, track, quiet);
 323
 324        strbuf_release(&ref);
 325        free(real_ref);
 326}
 327
 328void remove_branch_state(void)
 329{
 330        unlink(git_path_cherry_pick_head());
 331        unlink(git_path_revert_head());
 332        unlink(git_path_merge_head());
 333        unlink(git_path_merge_rr());
 334        unlink(git_path_merge_msg());
 335        unlink(git_path_merge_mode());
 336        unlink(git_path_squash_msg());
 337}
 338
 339void die_if_checked_out(const char *branch, int ignore_current_worktree)
 340{
 341        const struct worktree *wt;
 342
 343        wt = find_shared_symref("HEAD", branch);
 344        if (!wt || (ignore_current_worktree && wt->is_current))
 345                return;
 346        skip_prefix(branch, "refs/heads/", &branch);
 347        die(_("'%s' is already checked out at '%s'"),
 348            branch, wt->path);
 349}
 350
 351int replace_each_worktree_head_symref(const char *oldref, const char *newref,
 352                                      const char *logmsg)
 353{
 354        int ret = 0;
 355        struct worktree **worktrees = get_worktrees(0);
 356        int i;
 357
 358        for (i = 0; worktrees[i]; i++) {
 359                struct ref_store *refs;
 360
 361                if (worktrees[i]->is_detached)
 362                        continue;
 363                if (!worktrees[i]->head_ref)
 364                        continue;
 365                if (strcmp(oldref, worktrees[i]->head_ref))
 366                        continue;
 367
 368                refs = get_worktree_ref_store(worktrees[i]);
 369                if (refs_create_symref(refs, "HEAD", newref, logmsg))
 370                        ret = error(_("HEAD of working tree %s is not updated"),
 371                                    worktrees[i]->path);
 372        }
 373
 374        free_worktrees(worktrees);
 375        return ret;
 376}