branch.con commit l10n: TEAMS: Add ko team members (4b0d6bd)
   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
 181/*
 182 * Check if 'name' can be a valid name for a branch; die otherwise.
 183 * Return 1 if the named branch already exists; return 0 otherwise.
 184 * Fill ref with the full refname for the branch.
 185 */
 186int validate_branchname(const char *name, struct strbuf *ref)
 187{
 188        if (strbuf_check_branch_ref(ref, name))
 189                die(_("'%s' is not a valid branch name."), name);
 190
 191        return ref_exists(ref->buf);
 192}
 193
 194/*
 195 * Check if a branch 'name' can be created as a new branch; die otherwise.
 196 * 'force' can be used when it is OK for the named branch already exists.
 197 * Return 1 if the named branch already exists; return 0 otherwise.
 198 * Fill ref with the full refname for the branch.
 199 */
 200int validate_new_branchname(const char *name, struct strbuf *ref, int force)
 201{
 202        const char *head;
 203
 204        if (!validate_branchname(name, ref))
 205                return 0;
 206
 207        if (!force)
 208                die(_("A branch named '%s' already exists."),
 209                    ref->buf + strlen("refs/heads/"));
 210
 211        head = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
 212        if (!is_bare_repository() && head && !strcmp(head, ref->buf))
 213                die(_("Cannot force update the current branch."));
 214
 215        return 1;
 216}
 217
 218static int check_tracking_branch(struct remote *remote, void *cb_data)
 219{
 220        char *tracking_branch = cb_data;
 221        struct refspec query;
 222        memset(&query, 0, sizeof(struct refspec));
 223        query.dst = tracking_branch;
 224        return !remote_find_tracking(remote, &query);
 225}
 226
 227static int validate_remote_tracking_branch(char *ref)
 228{
 229        return !for_each_remote(check_tracking_branch, ref);
 230}
 231
 232static const char upstream_not_branch[] =
 233N_("Cannot setup tracking information; starting point '%s' is not a branch.");
 234static const char upstream_missing[] =
 235N_("the requested upstream branch '%s' does not exist");
 236static const char upstream_advice[] =
 237N_("\n"
 238"If you are planning on basing your work on an upstream\n"
 239"branch that already exists at the remote, you may need to\n"
 240"run \"git fetch\" to retrieve it.\n"
 241"\n"
 242"If you are planning to push out a new local branch that\n"
 243"will track its remote counterpart, you may want to use\n"
 244"\"git push -u\" to set the upstream config as you push.");
 245
 246void create_branch(const char *name, const char *start_name,
 247                   int force, int clobber_head_ok, int reflog,
 248                   int quiet, enum branch_track track)
 249{
 250        struct commit *commit;
 251        struct object_id oid;
 252        char *real_ref;
 253        struct strbuf ref = STRBUF_INIT;
 254        int forcing = 0;
 255        int dont_change_ref = 0;
 256        int explicit_tracking = 0;
 257
 258        if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
 259                explicit_tracking = 1;
 260
 261        if ((track == BRANCH_TRACK_OVERRIDE || clobber_head_ok)
 262            ? validate_branchname(name, &ref)
 263            : validate_new_branchname(name, &ref, force)) {
 264                if (!force)
 265                        dont_change_ref = 1;
 266                else
 267                        forcing = 1;
 268        }
 269
 270        real_ref = NULL;
 271        if (get_oid(start_name, &oid)) {
 272                if (explicit_tracking) {
 273                        if (advice_set_upstream_failure) {
 274                                error(_(upstream_missing), start_name);
 275                                advise(_(upstream_advice));
 276                                exit(1);
 277                        }
 278                        die(_(upstream_missing), start_name);
 279                }
 280                die(_("Not a valid object name: '%s'."), start_name);
 281        }
 282
 283        switch (dwim_ref(start_name, strlen(start_name), &oid, &real_ref)) {
 284        case 0:
 285                /* Not branching from any existing branch */
 286                if (explicit_tracking)
 287                        die(_(upstream_not_branch), start_name);
 288                break;
 289        case 1:
 290                /* Unique completion -- good, only if it is a real branch */
 291                if (!starts_with(real_ref, "refs/heads/") &&
 292                    validate_remote_tracking_branch(real_ref)) {
 293                        if (explicit_tracking)
 294                                die(_(upstream_not_branch), start_name);
 295                        else
 296                                real_ref = NULL;
 297                }
 298                break;
 299        default:
 300                die(_("Ambiguous object name: '%s'."), start_name);
 301                break;
 302        }
 303
 304        if ((commit = lookup_commit_reference(&oid)) == NULL)
 305                die(_("Not a valid branch point: '%s'."), start_name);
 306        oidcpy(&oid, &commit->object.oid);
 307
 308        if (reflog)
 309                log_all_ref_updates = LOG_REFS_NORMAL;
 310
 311        if (!dont_change_ref) {
 312                struct ref_transaction *transaction;
 313                struct strbuf err = STRBUF_INIT;
 314                char *msg;
 315
 316                if (forcing)
 317                        msg = xstrfmt("branch: Reset to %s", start_name);
 318                else
 319                        msg = xstrfmt("branch: Created from %s", start_name);
 320
 321                transaction = ref_transaction_begin(&err);
 322                if (!transaction ||
 323                    ref_transaction_update(transaction, ref.buf,
 324                                           &oid, forcing ? NULL : &null_oid,
 325                                           0, msg, &err) ||
 326                    ref_transaction_commit(transaction, &err))
 327                        die("%s", err.buf);
 328                ref_transaction_free(transaction);
 329                strbuf_release(&err);
 330                free(msg);
 331        }
 332
 333        if (real_ref && track)
 334                setup_tracking(ref.buf + 11, real_ref, track, quiet);
 335
 336        strbuf_release(&ref);
 337        free(real_ref);
 338}
 339
 340void remove_branch_state(void)
 341{
 342        unlink(git_path_cherry_pick_head());
 343        unlink(git_path_revert_head());
 344        unlink(git_path_merge_head());
 345        unlink(git_path_merge_rr());
 346        unlink(git_path_merge_msg());
 347        unlink(git_path_merge_mode());
 348        unlink(git_path_squash_msg());
 349}
 350
 351void die_if_checked_out(const char *branch, int ignore_current_worktree)
 352{
 353        const struct worktree *wt;
 354
 355        wt = find_shared_symref("HEAD", branch);
 356        if (!wt || (ignore_current_worktree && wt->is_current))
 357                return;
 358        skip_prefix(branch, "refs/heads/", &branch);
 359        die(_("'%s' is already checked out at '%s'"),
 360            branch, wt->path);
 361}
 362
 363int replace_each_worktree_head_symref(const char *oldref, const char *newref,
 364                                      const char *logmsg)
 365{
 366        int ret = 0;
 367        struct worktree **worktrees = get_worktrees(0);
 368        int i;
 369
 370        for (i = 0; worktrees[i]; i++) {
 371                struct ref_store *refs;
 372
 373                if (worktrees[i]->is_detached)
 374                        continue;
 375                if (!worktrees[i]->head_ref)
 376                        continue;
 377                if (strcmp(oldref, worktrees[i]->head_ref))
 378                        continue;
 379
 380                refs = get_worktree_ref_store(worktrees[i]);
 381                if (refs_create_symref(refs, "HEAD", newref, logmsg))
 382                        ret = error(_("HEAD of working tree %s is not updated"),
 383                                    worktrees[i]->path);
 384        }
 385
 386        free_worktrees(worktrees);
 387        return ret;
 388}