branch.con commit diff.c: convert -U|--unified (d473e2e)
   1#include "git-compat-util.h"
   2#include "cache.h"
   3#include "config.h"
   4#include "branch.h"
   5#include "refs.h"
   6#include "refspec.h"
   7#include "remote.h"
   8#include "commit.h"
   9#include "worktree.h"
  10
  11struct tracking {
  12        struct refspec_item spec;
  13        char *src;
  14        const char *remote;
  15        int matches;
  16};
  17
  18static int find_tracked_branch(struct remote *remote, void *priv)
  19{
  20        struct tracking *tracking = priv;
  21
  22        if (!remote_find_tracking(remote, &tracking->spec)) {
  23                if (++tracking->matches == 1) {
  24                        tracking->src = tracking->spec.src;
  25                        tracking->remote = remote->name;
  26                } else {
  27                        free(tracking->spec.src);
  28                        FREE_AND_NULL(tracking->src);
  29                }
  30                tracking->spec.src = NULL;
  31        }
  32
  33        return 0;
  34}
  35
  36static int should_setup_rebase(const char *origin)
  37{
  38        switch (autorebase) {
  39        case AUTOREBASE_NEVER:
  40                return 0;
  41        case AUTOREBASE_LOCAL:
  42                return origin == NULL;
  43        case AUTOREBASE_REMOTE:
  44                return origin != NULL;
  45        case AUTOREBASE_ALWAYS:
  46                return 1;
  47        }
  48        return 0;
  49}
  50
  51static const char tracking_advice[] =
  52N_("\n"
  53"After fixing the error cause you may try to fix up\n"
  54"the remote tracking information by invoking\n"
  55"\"git branch --set-upstream-to=%s%s%s\".");
  56
  57int install_branch_config(int flag, const char *local, const char *origin, const char *remote)
  58{
  59        const char *shortname = NULL;
  60        struct strbuf key = STRBUF_INIT;
  61        int rebasing = should_setup_rebase(origin);
  62
  63        if (skip_prefix(remote, "refs/heads/", &shortname)
  64            && !strcmp(local, shortname)
  65            && !origin) {
  66                warning(_("Not setting branch %s as its own upstream."),
  67                        local);
  68                return 0;
  69        }
  70
  71        strbuf_addf(&key, "branch.%s.remote", local);
  72        if (git_config_set_gently(key.buf, origin ? origin : ".") < 0)
  73                goto out_err;
  74
  75        strbuf_reset(&key);
  76        strbuf_addf(&key, "branch.%s.merge", local);
  77        if (git_config_set_gently(key.buf, remote) < 0)
  78                goto out_err;
  79
  80        if (rebasing) {
  81                strbuf_reset(&key);
  82                strbuf_addf(&key, "branch.%s.rebase", local);
  83                if (git_config_set_gently(key.buf, "true") < 0)
  84                        goto out_err;
  85        }
  86        strbuf_release(&key);
  87
  88        if (flag & BRANCH_CONFIG_VERBOSE) {
  89                if (shortname) {
  90                        if (origin)
  91                                printf_ln(rebasing ?
  92                                          _("Branch '%s' set up to track remote branch '%s' from '%s' by rebasing.") :
  93                                          _("Branch '%s' set up to track remote branch '%s' from '%s'."),
  94                                          local, shortname, origin);
  95                        else
  96                                printf_ln(rebasing ?
  97                                          _("Branch '%s' set up to track local branch '%s' by rebasing.") :
  98                                          _("Branch '%s' set up to track local branch '%s'."),
  99                                          local, shortname);
 100                } else {
 101                        if (origin)
 102                                printf_ln(rebasing ?
 103                                          _("Branch '%s' set up to track remote ref '%s' by rebasing.") :
 104                                          _("Branch '%s' set up to track remote ref '%s'."),
 105                                          local, remote);
 106                        else
 107                                printf_ln(rebasing ?
 108                                          _("Branch '%s' set up to track local ref '%s' by rebasing.") :
 109                                          _("Branch '%s' set up to track local ref '%s'."),
 110                                          local, remote);
 111                }
 112        }
 113
 114        return 0;
 115
 116out_err:
 117        strbuf_release(&key);
 118        error(_("Unable to write upstream branch configuration"));
 119
 120        advise(_(tracking_advice),
 121               origin ? origin : "",
 122               origin ? "/" : "",
 123               shortname ? shortname : remote);
 124
 125        return -1;
 126}
 127
 128/*
 129 * This is called when new_ref is branched off of orig_ref, and tries
 130 * to infer the settings for branch.<new_ref>.{remote,merge} from the
 131 * config.
 132 */
 133static void setup_tracking(const char *new_ref, const char *orig_ref,
 134                           enum branch_track track, int quiet)
 135{
 136        struct tracking tracking;
 137        int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE;
 138
 139        memset(&tracking, 0, sizeof(tracking));
 140        tracking.spec.dst = (char *)orig_ref;
 141        if (for_each_remote(find_tracked_branch, &tracking))
 142                return;
 143
 144        if (!tracking.matches)
 145                switch (track) {
 146                case BRANCH_TRACK_ALWAYS:
 147                case BRANCH_TRACK_EXPLICIT:
 148                case BRANCH_TRACK_OVERRIDE:
 149                        break;
 150                default:
 151                        return;
 152                }
 153
 154        if (tracking.matches > 1)
 155                die(_("Not tracking: ambiguous information for ref %s"),
 156                    orig_ref);
 157
 158        if (install_branch_config(config_flags, new_ref, tracking.remote,
 159                              tracking.src ? tracking.src : orig_ref) < 0)
 160                exit(-1);
 161
 162        free(tracking.src);
 163}
 164
 165int read_branch_desc(struct strbuf *buf, const char *branch_name)
 166{
 167        char *v = NULL;
 168        struct strbuf name = STRBUF_INIT;
 169        strbuf_addf(&name, "branch.%s.description", branch_name);
 170        if (git_config_get_string(name.buf, &v)) {
 171                strbuf_release(&name);
 172                return -1;
 173        }
 174        strbuf_addstr(buf, v);
 175        free(v);
 176        strbuf_release(&name);
 177        return 0;
 178}
 179
 180/*
 181 * Check if 'name' can be a valid name for a branch; die otherwise.
 182 * Return 1 if the named branch already exists; return 0 otherwise.
 183 * Fill ref with the full refname for the branch.
 184 */
 185int validate_branchname(const char *name, struct strbuf *ref)
 186{
 187        if (strbuf_check_branch_ref(ref, name))
 188                die(_("'%s' is not a valid branch name."), name);
 189
 190        return ref_exists(ref->buf);
 191}
 192
 193/*
 194 * Check if a branch 'name' can be created as a new branch; die otherwise.
 195 * 'force' can be used when it is OK for the named branch already exists.
 196 * Return 1 if the named branch already exists; return 0 otherwise.
 197 * Fill ref with the full refname for the branch.
 198 */
 199int validate_new_branchname(const char *name, struct strbuf *ref, int force)
 200{
 201        const char *head;
 202
 203        if (!validate_branchname(name, ref))
 204                return 0;
 205
 206        if (!force)
 207                die(_("A branch named '%s' already exists."),
 208                    ref->buf + strlen("refs/heads/"));
 209
 210        head = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
 211        if (!is_bare_repository() && head && !strcmp(head, ref->buf))
 212                die(_("Cannot force update the current branch."));
 213
 214        return 1;
 215}
 216
 217static int check_tracking_branch(struct remote *remote, void *cb_data)
 218{
 219        char *tracking_branch = cb_data;
 220        struct refspec_item query;
 221        memset(&query, 0, sizeof(struct refspec_item));
 222        query.dst = tracking_branch;
 223        return !remote_find_tracking(remote, &query);
 224}
 225
 226static int validate_remote_tracking_branch(char *ref)
 227{
 228        return !for_each_remote(check_tracking_branch, ref);
 229}
 230
 231static const char upstream_not_branch[] =
 232N_("Cannot setup tracking information; starting point '%s' is not a branch.");
 233static const char upstream_missing[] =
 234N_("the requested upstream branch '%s' does not exist");
 235static const char upstream_advice[] =
 236N_("\n"
 237"If you are planning on basing your work on an upstream\n"
 238"branch that already exists at the remote, you may need to\n"
 239"run \"git fetch\" to retrieve it.\n"
 240"\n"
 241"If you are planning to push out a new local branch that\n"
 242"will track its remote counterpart, you may want to use\n"
 243"\"git push -u\" to set the upstream config as you push.");
 244
 245void create_branch(struct repository *r,
 246                   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(r, &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(struct repository *r)
 341{
 342        unlink(git_path_cherry_pick_head(r));
 343        unlink(git_path_revert_head(r));
 344        unlink(git_path_merge_head(r));
 345        unlink(git_path_merge_rr(r));
 346        unlink(git_path_merge_msg(r));
 347        unlink(git_path_merge_mode(r));
 348        unlink(git_path_squash_msg(r));
 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}