Coverage Report

Created: 2023-11-27 06:56

/src/git/branch.c
Line
Count
Source (jump to first uncovered line)
1
#include "git-compat-util.h"
2
#include "advice.h"
3
#include "config.h"
4
#include "branch.h"
5
#include "environment.h"
6
#include "gettext.h"
7
#include "hex.h"
8
#include "object-name.h"
9
#include "path.h"
10
#include "refs.h"
11
#include "refspec.h"
12
#include "remote.h"
13
#include "repository.h"
14
#include "sequencer.h"
15
#include "commit.h"
16
#include "worktree.h"
17
#include "submodule-config.h"
18
#include "run-command.h"
19
#include "strmap.h"
20
21
struct tracking {
22
  struct refspec_item spec;
23
  struct string_list *srcs;
24
  const char *remote;
25
  int matches;
26
};
27
28
struct find_tracked_branch_cb {
29
  struct tracking *tracking;
30
  struct string_list ambiguous_remotes;
31
};
32
33
static int find_tracked_branch(struct remote *remote, void *priv)
34
0
{
35
0
  struct find_tracked_branch_cb *ftb = priv;
36
0
  struct tracking *tracking = ftb->tracking;
37
38
0
  if (!remote_find_tracking(remote, &tracking->spec)) {
39
0
    switch (++tracking->matches) {
40
0
    case 1:
41
0
      string_list_append_nodup(tracking->srcs, tracking->spec.src);
42
0
      tracking->remote = remote->name;
43
0
      break;
44
0
    case 2:
45
      /* there are at least two remotes; backfill the first one */
46
0
      string_list_append(&ftb->ambiguous_remotes, tracking->remote);
47
      /* fall through */
48
0
    default:
49
0
      string_list_append(&ftb->ambiguous_remotes, remote->name);
50
0
      free(tracking->spec.src);
51
0
      string_list_clear(tracking->srcs, 0);
52
0
    break;
53
0
    }
54
    /* remote_find_tracking() searches by src if present */
55
0
    tracking->spec.src = NULL;
56
0
  }
57
0
  return 0;
58
0
}
59
60
static int should_setup_rebase(const char *origin)
61
0
{
62
0
  switch (autorebase) {
63
0
  case AUTOREBASE_NEVER:
64
0
    return 0;
65
0
  case AUTOREBASE_LOCAL:
66
0
    return origin == NULL;
67
0
  case AUTOREBASE_REMOTE:
68
0
    return origin != NULL;
69
0
  case AUTOREBASE_ALWAYS:
70
0
    return 1;
71
0
  }
72
0
  return 0;
73
0
}
74
75
/**
76
 * Install upstream tracking configuration for a branch; specifically, add
77
 * `branch.<name>.remote` and `branch.<name>.merge` entries.
78
 *
79
 * `flag` contains integer flags for options; currently only
80
 * BRANCH_CONFIG_VERBOSE is checked.
81
 *
82
 * `local` is the name of the branch whose configuration we're installing.
83
 *
84
 * `origin` is the name of the remote owning the upstream branches. NULL means
85
 * the upstream branches are local to this repo.
86
 *
87
 * `remotes` is a list of refs that are upstream of local
88
 */
89
static int install_branch_config_multiple_remotes(int flag, const char *local,
90
    const char *origin, struct string_list *remotes)
91
0
{
92
0
  const char *shortname = NULL;
93
0
  struct strbuf key = STRBUF_INIT;
94
0
  struct string_list_item *item;
95
0
  int rebasing = should_setup_rebase(origin);
96
97
0
  if (!remotes->nr)
98
0
    BUG("must provide at least one remote for branch config");
99
0
  if (rebasing && remotes->nr > 1)
100
0
    die(_("cannot inherit upstream tracking configuration of "
101
0
          "multiple refs when rebasing is requested"));
102
103
  /*
104
   * If the new branch is trying to track itself, something has gone
105
   * wrong. Warn the user and don't proceed any further.
106
   */
107
0
  if (!origin)
108
0
    for_each_string_list_item(item, remotes)
109
0
      if (skip_prefix(item->string, "refs/heads/", &shortname)
110
0
          && !strcmp(local, shortname)) {
111
0
        warning(_("not setting branch '%s' as its own upstream"),
112
0
          local);
113
0
        return 0;
114
0
      }
115
116
0
  strbuf_addf(&key, "branch.%s.remote", local);
117
0
  if (git_config_set_gently(key.buf, origin ? origin : ".") < 0)
118
0
    goto out_err;
119
120
0
  strbuf_reset(&key);
121
0
  strbuf_addf(&key, "branch.%s.merge", local);
122
  /*
123
   * We want to overwrite any existing config with all the branches in
124
   * "remotes". Override any existing config, then write our branches. If
125
   * more than one is provided, use CONFIG_REGEX_NONE to preserve what
126
   * we've written so far.
127
   */
128
0
  if (git_config_set_gently(key.buf, NULL) < 0)
129
0
    goto out_err;
130
0
  for_each_string_list_item(item, remotes)
131
0
    if (git_config_set_multivar_gently(key.buf, item->string, CONFIG_REGEX_NONE, 0) < 0)
132
0
      goto out_err;
133
134
0
  if (rebasing) {
135
0
    strbuf_reset(&key);
136
0
    strbuf_addf(&key, "branch.%s.rebase", local);
137
0
    if (git_config_set_gently(key.buf, "true") < 0)
138
0
      goto out_err;
139
0
  }
140
0
  strbuf_release(&key);
141
142
0
  if (flag & BRANCH_CONFIG_VERBOSE) {
143
0
    struct strbuf tmp_ref_name = STRBUF_INIT;
144
0
    struct string_list friendly_ref_names = STRING_LIST_INIT_DUP;
145
146
0
    for_each_string_list_item(item, remotes) {
147
0
      shortname = item->string;
148
0
      skip_prefix(shortname, "refs/heads/", &shortname);
149
0
      if (origin) {
150
0
        strbuf_addf(&tmp_ref_name, "%s/%s",
151
0
              origin, shortname);
152
0
        string_list_append_nodup(
153
0
          &friendly_ref_names,
154
0
          strbuf_detach(&tmp_ref_name, NULL));
155
0
      } else {
156
0
        string_list_append(
157
0
          &friendly_ref_names, shortname);
158
0
      }
159
0
    }
160
161
0
    if (remotes->nr == 1) {
162
      /*
163
       * Rebasing is only allowed in the case of a single
164
       * upstream branch.
165
       */
166
0
      printf_ln(rebasing ?
167
0
        _("branch '%s' set up to track '%s' by rebasing.") :
168
0
        _("branch '%s' set up to track '%s'."),
169
0
        local, friendly_ref_names.items[0].string);
170
0
    } else {
171
0
      printf_ln(_("branch '%s' set up to track:"), local);
172
0
      for_each_string_list_item(item, &friendly_ref_names)
173
0
        printf_ln("  %s", item->string);
174
0
    }
175
176
0
    string_list_clear(&friendly_ref_names, 0);
177
0
  }
178
179
0
  return 0;
180
181
0
out_err:
182
0
  strbuf_release(&key);
183
0
  error(_("unable to write upstream branch configuration"));
184
185
0
  advise(_("\nAfter fixing the error cause you may try to fix up\n"
186
0
    "the remote tracking information by invoking:"));
187
0
  if (remotes->nr == 1)
188
0
    advise("  git branch --set-upstream-to=%s%s%s",
189
0
      origin ? origin : "",
190
0
      origin ? "/" : "",
191
0
      remotes->items[0].string);
192
0
  else {
193
0
    advise("  git config --add branch.\"%s\".remote %s",
194
0
      local, origin ? origin : ".");
195
0
    for_each_string_list_item(item, remotes)
196
0
      advise("  git config --add branch.\"%s\".merge %s",
197
0
        local, item->string);
198
0
  }
199
200
0
  return -1;
201
0
}
202
203
int install_branch_config(int flag, const char *local, const char *origin,
204
    const char *remote)
205
0
{
206
0
  int ret;
207
0
  struct string_list remotes = STRING_LIST_INIT_DUP;
208
209
0
  string_list_append(&remotes, remote);
210
0
  ret = install_branch_config_multiple_remotes(flag, local, origin, &remotes);
211
0
  string_list_clear(&remotes, 0);
212
0
  return ret;
213
0
}
214
215
static int inherit_tracking(struct tracking *tracking, const char *orig_ref)
216
0
{
217
0
  const char *bare_ref;
218
0
  struct branch *branch;
219
0
  int i;
220
221
0
  bare_ref = orig_ref;
222
0
  skip_prefix(orig_ref, "refs/heads/", &bare_ref);
223
224
0
  branch = branch_get(bare_ref);
225
0
  if (!branch->remote_name) {
226
0
    warning(_("asked to inherit tracking from '%s', but no remote is set"),
227
0
      bare_ref);
228
0
    return -1;
229
0
  }
230
231
0
  if (branch->merge_nr < 1 || !branch->merge_name || !branch->merge_name[0]) {
232
0
    warning(_("asked to inherit tracking from '%s', but no merge configuration is set"),
233
0
      bare_ref);
234
0
    return -1;
235
0
  }
236
237
0
  tracking->remote = branch->remote_name;
238
0
  for (i = 0; i < branch->merge_nr; i++)
239
0
    string_list_append(tracking->srcs, branch->merge_name[i]);
240
0
  return 0;
241
0
}
242
243
/*
244
 * Used internally to set the branch.<new_ref>.{remote,merge} config
245
 * settings so that branch 'new_ref' tracks 'orig_ref'. Unlike
246
 * dwim_and_setup_tracking(), this does not do DWIM, i.e. "origin/main"
247
 * will not be expanded to "refs/remotes/origin/main", so it is not safe
248
 * for 'orig_ref' to be raw user input.
249
 */
250
static void setup_tracking(const char *new_ref, const char *orig_ref,
251
         enum branch_track track, int quiet)
252
1.13k
{
253
1.13k
  struct tracking tracking;
254
1.13k
  struct string_list tracking_srcs = STRING_LIST_INIT_DUP;
255
1.13k
  int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE;
256
1.13k
  struct find_tracked_branch_cb ftb_cb = {
257
1.13k
    .tracking = &tracking,
258
1.13k
    .ambiguous_remotes = STRING_LIST_INIT_DUP,
259
1.13k
  };
260
261
1.13k
  if (!track)
262
0
    BUG("asked to set up tracking, but tracking is disallowed");
263
264
1.13k
  memset(&tracking, 0, sizeof(tracking));
265
1.13k
  tracking.spec.dst = (char *)orig_ref;
266
1.13k
  tracking.srcs = &tracking_srcs;
267
1.13k
  if (track != BRANCH_TRACK_INHERIT)
268
1.13k
    for_each_remote(find_tracked_branch, &ftb_cb);
269
0
  else if (inherit_tracking(&tracking, orig_ref))
270
0
    goto cleanup;
271
272
1.13k
  if (!tracking.matches)
273
1.13k
    switch (track) {
274
    /* If ref is not remote, still use local */
275
0
    case BRANCH_TRACK_ALWAYS:
276
0
    case BRANCH_TRACK_EXPLICIT:
277
0
    case BRANCH_TRACK_OVERRIDE:
278
    /* Remote matches not evaluated */
279
0
    case BRANCH_TRACK_INHERIT:
280
0
      break;
281
    /* Otherwise, if no remote don't track */
282
1.13k
    default:
283
1.13k
      goto cleanup;
284
1.13k
    }
285
286
  /*
287
   * This check does not apply to BRANCH_TRACK_INHERIT;
288
   * that supports multiple entries in tracking_srcs but
289
   * leaves tracking.matches at 0.
290
   */
291
0
  if (tracking.matches > 1) {
292
0
    int status = die_message(_("not tracking: ambiguous information for ref '%s'"),
293
0
              orig_ref);
294
0
    if (advice_enabled(ADVICE_AMBIGUOUS_FETCH_REFSPEC)) {
295
0
      struct strbuf remotes_advice = STRBUF_INIT;
296
0
      struct string_list_item *item;
297
298
0
      for_each_string_list_item(item, &ftb_cb.ambiguous_remotes)
299
        /*
300
         * TRANSLATORS: This is a line listing a remote with duplicate
301
         * refspecs in the advice message below. For RTL languages you'll
302
         * probably want to swap the "%s" and leading "  " space around.
303
         */
304
0
        strbuf_addf(&remotes_advice, _("  %s\n"), item->string);
305
306
      /*
307
       * TRANSLATORS: The second argument is a \n-delimited list of
308
       * duplicate refspecs, composed above.
309
       */
310
0
      advise(_("There are multiple remotes whose fetch refspecs map to the remote\n"
311
0
         "tracking ref '%s':\n"
312
0
         "%s"
313
0
         "\n"
314
0
         "This is typically a configuration error.\n"
315
0
         "\n"
316
0
         "To support setting up tracking branches, ensure that\n"
317
0
         "different remotes' fetch refspecs map into different\n"
318
0
         "tracking namespaces."), orig_ref,
319
0
             remotes_advice.buf);
320
0
      strbuf_release(&remotes_advice);
321
0
    }
322
0
    exit(status);
323
0
  }
324
325
0
  if (track == BRANCH_TRACK_SIMPLE) {
326
    /*
327
     * Only track if remote branch name matches.
328
     * Reaching into items[0].string is safe because
329
     * we know there is at least one and not more than
330
     * one entry (because only BRANCH_TRACK_INHERIT can
331
     * produce more than one entry).
332
     */
333
0
    const char *tracked_branch;
334
0
    if (!skip_prefix(tracking.srcs->items[0].string,
335
0
         "refs/heads/", &tracked_branch) ||
336
0
        strcmp(tracked_branch, new_ref))
337
0
      goto cleanup;
338
0
  }
339
340
0
  if (tracking.srcs->nr < 1)
341
0
    string_list_append(tracking.srcs, orig_ref);
342
0
  if (install_branch_config_multiple_remotes(config_flags, new_ref,
343
0
        tracking.remote, tracking.srcs) < 0)
344
0
    exit(1);
345
346
1.13k
cleanup:
347
1.13k
  string_list_clear(&tracking_srcs, 0);
348
1.13k
  string_list_clear(&ftb_cb.ambiguous_remotes, 0);
349
1.13k
}
350
351
int read_branch_desc(struct strbuf *buf, const char *branch_name)
352
0
{
353
0
  char *v = NULL;
354
0
  struct strbuf name = STRBUF_INIT;
355
0
  strbuf_addf(&name, "branch.%s.description", branch_name);
356
0
  if (git_config_get_string(name.buf, &v)) {
357
0
    strbuf_release(&name);
358
0
    return -1;
359
0
  }
360
0
  strbuf_addstr(buf, v);
361
0
  free(v);
362
0
  strbuf_release(&name);
363
0
  return 0;
364
0
}
365
366
/*
367
 * Check if 'name' can be a valid name for a branch; die otherwise.
368
 * Return 1 if the named branch already exists; return 0 otherwise.
369
 * Fill ref with the full refname for the branch.
370
 */
371
int validate_branchname(const char *name, struct strbuf *ref)
372
1.13k
{
373
1.13k
  if (strbuf_check_branch_ref(ref, name))
374
0
    die(_("'%s' is not a valid branch name"), name);
375
376
1.13k
  return ref_exists(ref->buf);
377
1.13k
}
378
379
static int initialized_checked_out_branches;
380
static struct strmap current_checked_out_branches = STRMAP_INIT;
381
382
static void prepare_checked_out_branches(void)
383
0
{
384
0
  int i = 0;
385
0
  struct worktree **worktrees;
386
387
0
  if (initialized_checked_out_branches)
388
0
    return;
389
0
  initialized_checked_out_branches = 1;
390
391
0
  worktrees = get_worktrees();
392
393
0
  while (worktrees[i]) {
394
0
    char *old;
395
0
    struct wt_status_state state = { 0 };
396
0
    struct worktree *wt = worktrees[i++];
397
0
    struct string_list update_refs = STRING_LIST_INIT_DUP;
398
399
0
    if (wt->is_bare)
400
0
      continue;
401
402
0
    if (wt->head_ref) {
403
0
      old = strmap_put(&current_checked_out_branches,
404
0
           wt->head_ref,
405
0
           xstrdup(wt->path));
406
0
      free(old);
407
0
    }
408
409
0
    if (wt_status_check_rebase(wt, &state) &&
410
0
        (state.rebase_in_progress || state.rebase_interactive_in_progress) &&
411
0
        state.branch) {
412
0
      struct strbuf ref = STRBUF_INIT;
413
0
      strbuf_addf(&ref, "refs/heads/%s", state.branch);
414
0
      old = strmap_put(&current_checked_out_branches,
415
0
           ref.buf,
416
0
           xstrdup(wt->path));
417
0
      free(old);
418
0
      strbuf_release(&ref);
419
0
    }
420
0
    wt_status_state_free_buffers(&state);
421
422
0
    if (wt_status_check_bisect(wt, &state) &&
423
0
        state.branch) {
424
0
      struct strbuf ref = STRBUF_INIT;
425
0
      strbuf_addf(&ref, "refs/heads/%s", state.branch);
426
0
      old = strmap_put(&current_checked_out_branches,
427
0
           ref.buf,
428
0
           xstrdup(wt->path));
429
0
      free(old);
430
0
      strbuf_release(&ref);
431
0
    }
432
0
    wt_status_state_free_buffers(&state);
433
434
0
    if (!sequencer_get_update_refs_state(get_worktree_git_dir(wt),
435
0
                 &update_refs)) {
436
0
      struct string_list_item *item;
437
0
      for_each_string_list_item(item, &update_refs) {
438
0
        old = strmap_put(&current_checked_out_branches,
439
0
             item->string,
440
0
             xstrdup(wt->path));
441
0
        free(old);
442
0
      }
443
0
      string_list_clear(&update_refs, 1);
444
0
    }
445
0
  }
446
447
0
  free_worktrees(worktrees);
448
0
}
449
450
const char *branch_checked_out(const char *refname)
451
0
{
452
0
  prepare_checked_out_branches();
453
0
  return strmap_get(&current_checked_out_branches, refname);
454
0
}
455
456
/*
457
 * Check if a branch 'name' can be created as a new branch; die otherwise.
458
 * 'force' can be used when it is OK for the named branch already exists.
459
 * Return 1 if the named branch already exists; return 0 otherwise.
460
 * Fill ref with the full refname for the branch.
461
 */
462
int validate_new_branchname(const char *name, struct strbuf *ref, int force)
463
1.13k
{
464
1.13k
  const char *path;
465
1.13k
  if (!validate_branchname(name, ref))
466
1.13k
    return 0;
467
468
0
  if (!force)
469
0
    die(_("a branch named '%s' already exists"),
470
0
        ref->buf + strlen("refs/heads/"));
471
472
0
  if ((path = branch_checked_out(ref->buf)))
473
0
    die(_("cannot force update the branch '%s' "
474
0
          "used by worktree at '%s'"),
475
0
        ref->buf + strlen("refs/heads/"), path);
476
477
0
  return 1;
478
0
}
479
480
static int check_tracking_branch(struct remote *remote, void *cb_data)
481
0
{
482
0
  char *tracking_branch = cb_data;
483
0
  struct refspec_item query;
484
0
  int res;
485
0
  memset(&query, 0, sizeof(struct refspec_item));
486
0
  query.dst = tracking_branch;
487
0
  res = !remote_find_tracking(remote, &query);
488
0
  free(query.src);
489
0
  return res;
490
0
}
491
492
static int validate_remote_tracking_branch(char *ref)
493
0
{
494
0
  return !for_each_remote(check_tracking_branch, ref);
495
0
}
496
497
static const char upstream_not_branch[] =
498
N_("cannot set up tracking information; starting point '%s' is not a branch");
499
static const char upstream_missing[] =
500
N_("the requested upstream branch '%s' does not exist");
501
static const char upstream_advice[] =
502
N_("\n"
503
"If you are planning on basing your work on an upstream\n"
504
"branch that already exists at the remote, you may need to\n"
505
"run \"git fetch\" to retrieve it.\n"
506
"\n"
507
"If you are planning to push out a new local branch that\n"
508
"will track its remote counterpart, you may want to use\n"
509
"\"git push -u\" to set the upstream config as you push.");
510
511
/**
512
 * DWIMs a user-provided ref to determine the starting point for a
513
 * branch and validates it, where:
514
 *
515
 *   - r is the repository to validate the branch for
516
 *
517
 *   - start_name is the ref that we would like to test. This is
518
 *     expanded with DWIM and assigned to out_real_ref.
519
 *
520
 *   - track is the tracking mode of the new branch. If tracking is
521
 *     explicitly requested, start_name must be a branch (because
522
 *     otherwise start_name cannot be tracked)
523
 *
524
 *   - out_oid is an out parameter containing the object_id of start_name
525
 *
526
 *   - out_real_ref is an out parameter containing the full, 'real' form
527
 *     of start_name e.g. refs/heads/main instead of main
528
 *
529
 */
530
static void dwim_branch_start(struct repository *r, const char *start_name,
531
         enum branch_track track, char **out_real_ref,
532
         struct object_id *out_oid)
533
1.13k
{
534
1.13k
  struct commit *commit;
535
1.13k
  struct object_id oid;
536
1.13k
  char *real_ref;
537
1.13k
  int explicit_tracking = 0;
538
539
1.13k
  if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
540
0
    explicit_tracking = 1;
541
542
1.13k
  real_ref = NULL;
543
1.13k
  if (repo_get_oid_mb(r, start_name, &oid)) {
544
0
    if (explicit_tracking) {
545
0
      int code = die_message(_(upstream_missing), start_name);
546
0
      advise_if_enabled(ADVICE_SET_UPSTREAM_FAILURE,
547
0
            _(upstream_advice));
548
0
      exit(code);
549
0
    }
550
0
    die(_("not a valid object name: '%s'"), start_name);
551
0
  }
552
553
1.13k
  switch (repo_dwim_ref(r, start_name, strlen(start_name), &oid,
554
1.13k
            &real_ref, 0)) {
555
0
  case 0:
556
    /* Not branching from any existing branch */
557
0
    if (explicit_tracking)
558
0
      die(_(upstream_not_branch), start_name);
559
0
    break;
560
1.13k
  case 1:
561
    /* Unique completion -- good, only if it is a real branch */
562
1.13k
    if (!starts_with(real_ref, "refs/heads/") &&
563
1.13k
        validate_remote_tracking_branch(real_ref)) {
564
0
      if (explicit_tracking)
565
0
        die(_(upstream_not_branch), start_name);
566
0
      else
567
0
        FREE_AND_NULL(real_ref);
568
0
    }
569
1.13k
    break;
570
1.13k
  default:
571
0
    die(_("ambiguous object name: '%s'"), start_name);
572
0
    break;
573
1.13k
  }
574
575
1.13k
  if (!(commit = lookup_commit_reference(r, &oid)))
576
0
    die(_("not a valid branch point: '%s'"), start_name);
577
1.13k
  if (out_real_ref) {
578
1.13k
    *out_real_ref = real_ref;
579
1.13k
    real_ref = NULL;
580
1.13k
  }
581
1.13k
  if (out_oid)
582
1.13k
    oidcpy(out_oid, &commit->object.oid);
583
584
1.13k
  FREE_AND_NULL(real_ref);
585
1.13k
}
586
587
void create_branch(struct repository *r,
588
       const char *name, const char *start_name,
589
       int force, int clobber_head_ok, int reflog,
590
       int quiet, enum branch_track track, int dry_run)
591
1.13k
{
592
1.13k
  struct object_id oid;
593
1.13k
  char *real_ref;
594
1.13k
  struct strbuf ref = STRBUF_INIT;
595
1.13k
  int forcing = 0;
596
1.13k
  struct ref_transaction *transaction;
597
1.13k
  struct strbuf err = STRBUF_INIT;
598
1.13k
  char *msg;
599
600
1.13k
  if (track == BRANCH_TRACK_OVERRIDE)
601
0
    BUG("'track' cannot be BRANCH_TRACK_OVERRIDE. Did you mean to call dwim_and_setup_tracking()?");
602
1.13k
  if (clobber_head_ok && !force)
603
0
    BUG("'clobber_head_ok' can only be used with 'force'");
604
605
1.13k
  if (clobber_head_ok ?
606
0
        validate_branchname(name, &ref) :
607
1.13k
        validate_new_branchname(name, &ref, force)) {
608
0
    forcing = 1;
609
0
  }
610
611
1.13k
  dwim_branch_start(r, start_name, track, &real_ref, &oid);
612
1.13k
  if (dry_run)
613
0
    goto cleanup;
614
615
1.13k
  if (reflog)
616
0
    log_all_ref_updates = LOG_REFS_NORMAL;
617
618
1.13k
  if (forcing)
619
0
    msg = xstrfmt("branch: Reset to %s", start_name);
620
1.13k
  else
621
1.13k
    msg = xstrfmt("branch: Created from %s", start_name);
622
1.13k
  transaction = ref_transaction_begin(&err);
623
1.13k
  if (!transaction ||
624
1.13k
    ref_transaction_update(transaction, ref.buf,
625
1.13k
          &oid, forcing ? NULL : null_oid(),
626
1.13k
          0, msg, &err) ||
627
1.13k
    ref_transaction_commit(transaction, &err))
628
0
    die("%s", err.buf);
629
1.13k
  ref_transaction_free(transaction);
630
1.13k
  strbuf_release(&err);
631
1.13k
  free(msg);
632
633
1.13k
  if (real_ref && track)
634
1.13k
    setup_tracking(ref.buf + 11, real_ref, track, quiet);
635
636
1.13k
cleanup:
637
1.13k
  strbuf_release(&ref);
638
1.13k
  free(real_ref);
639
1.13k
}
640
641
void dwim_and_setup_tracking(struct repository *r, const char *new_ref,
642
           const char *orig_ref, enum branch_track track,
643
           int quiet)
644
0
{
645
0
  char *real_orig_ref = NULL;
646
0
  dwim_branch_start(r, orig_ref, track, &real_orig_ref, NULL);
647
0
  setup_tracking(new_ref, real_orig_ref, track, quiet);
648
0
  free(real_orig_ref);
649
0
}
650
651
/**
652
 * Creates a branch in a submodule by calling
653
 * create_branches_recursively() in a child process. The child process
654
 * is necessary because install_branch_config_multiple_remotes() (which
655
 * is called by setup_tracking()) does not support writing configs to
656
 * submodules.
657
 */
658
static int submodule_create_branch(struct repository *r,
659
           const struct submodule *submodule,
660
           const char *name, const char *start_oid,
661
           const char *tracking_name, int force,
662
           int reflog, int quiet,
663
           enum branch_track track, int dry_run)
664
0
{
665
0
  int ret = 0;
666
0
  struct child_process child = CHILD_PROCESS_INIT;
667
0
  struct strbuf child_err = STRBUF_INIT;
668
0
  struct strbuf out_buf = STRBUF_INIT;
669
0
  char *out_prefix = xstrfmt("submodule '%s': ", submodule->name);
670
0
  child.git_cmd = 1;
671
0
  child.err = -1;
672
0
  child.stdout_to_stderr = 1;
673
674
0
  prepare_other_repo_env(&child.env, r->gitdir);
675
  /*
676
   * submodule_create_branch() is indirectly invoked by "git
677
   * branch", but we cannot invoke "git branch" in the child
678
   * process. "git branch" accepts a branch name and start point,
679
   * where the start point is assumed to provide both the OID
680
   * (start_oid) and the branch to use for tracking
681
   * (tracking_name). But when recursing through submodules,
682
   * start_oid and tracking name need to be specified separately
683
   * (see create_branches_recursively()).
684
   */
685
0
  strvec_pushl(&child.args, "submodule--helper", "create-branch", NULL);
686
0
  if (dry_run)
687
0
    strvec_push(&child.args, "--dry-run");
688
0
  if (force)
689
0
    strvec_push(&child.args, "--force");
690
0
  if (quiet)
691
0
    strvec_push(&child.args, "--quiet");
692
0
  if (reflog)
693
0
    strvec_push(&child.args, "--create-reflog");
694
695
0
  switch (track) {
696
0
  case BRANCH_TRACK_NEVER:
697
0
    strvec_push(&child.args, "--no-track");
698
0
    break;
699
0
  case BRANCH_TRACK_ALWAYS:
700
0
  case BRANCH_TRACK_EXPLICIT:
701
0
    strvec_push(&child.args, "--track=direct");
702
0
    break;
703
0
  case BRANCH_TRACK_OVERRIDE:
704
0
    BUG("BRANCH_TRACK_OVERRIDE cannot be used when creating a branch.");
705
0
    break;
706
0
  case BRANCH_TRACK_INHERIT:
707
0
    strvec_push(&child.args, "--track=inherit");
708
0
    break;
709
0
  case BRANCH_TRACK_UNSPECIFIED:
710
    /* Default for "git checkout". Do not pass --track. */
711
0
  case BRANCH_TRACK_REMOTE:
712
    /* Default for "git branch". Do not pass --track. */
713
0
  case BRANCH_TRACK_SIMPLE:
714
    /* Config-driven only. Do not pass --track. */
715
0
    break;
716
0
  }
717
718
0
  strvec_pushl(&child.args, name, start_oid, tracking_name, NULL);
719
720
0
  if ((ret = start_command(&child)))
721
0
    return ret;
722
0
  ret = finish_command(&child);
723
0
  strbuf_read(&child_err, child.err, 0);
724
0
  strbuf_add_lines(&out_buf, out_prefix, child_err.buf, child_err.len);
725
726
0
  if (ret)
727
0
    fprintf(stderr, "%s", out_buf.buf);
728
0
  else
729
0
    printf("%s", out_buf.buf);
730
731
0
  strbuf_release(&child_err);
732
0
  strbuf_release(&out_buf);
733
0
  return ret;
734
0
}
735
736
void create_branches_recursively(struct repository *r, const char *name,
737
         const char *start_commitish,
738
         const char *tracking_name, int force,
739
         int reflog, int quiet, enum branch_track track,
740
         int dry_run)
741
0
{
742
0
  int i = 0;
743
0
  char *branch_point = NULL;
744
0
  struct object_id super_oid;
745
0
  struct submodule_entry_list submodule_entry_list;
746
747
  /* Perform dwim on start_commitish to get super_oid and branch_point. */
748
0
  dwim_branch_start(r, start_commitish, BRANCH_TRACK_NEVER,
749
0
        &branch_point, &super_oid);
750
751
  /*
752
   * If we were not given an explicit name to track, then assume we are at
753
   * the top level and, just like the non-recursive case, the tracking
754
   * name is the branch point.
755
   */
756
0
  if (!tracking_name)
757
0
    tracking_name = branch_point;
758
759
0
  submodules_of_tree(r, &super_oid, &submodule_entry_list);
760
  /*
761
   * Before creating any branches, first check that the branch can
762
   * be created in every submodule.
763
   */
764
0
  for (i = 0; i < submodule_entry_list.entry_nr; i++) {
765
0
    if (!submodule_entry_list.entries[i].repo) {
766
0
      int code = die_message(
767
0
        _("submodule '%s': unable to find submodule"),
768
0
        submodule_entry_list.entries[i].submodule->name);
769
0
      if (advice_enabled(ADVICE_SUBMODULES_NOT_UPDATED))
770
0
        advise(_("You may try updating the submodules using 'git checkout --no-recurse-submodules %s && git submodule update --init'"),
771
0
               start_commitish);
772
0
      exit(code);
773
0
    }
774
775
0
    if (submodule_create_branch(
776
0
          submodule_entry_list.entries[i].repo,
777
0
          submodule_entry_list.entries[i].submodule, name,
778
0
          oid_to_hex(&submodule_entry_list.entries[i]
779
0
            .name_entry->oid),
780
0
          tracking_name, force, reflog, quiet, track, 1))
781
0
      die(_("submodule '%s': cannot create branch '%s'"),
782
0
          submodule_entry_list.entries[i].submodule->name,
783
0
          name);
784
0
  }
785
786
0
  create_branch(r, name, start_commitish, force, 0, reflog, quiet,
787
0
          BRANCH_TRACK_NEVER, dry_run);
788
0
  if (dry_run)
789
0
    return;
790
  /*
791
   * NEEDSWORK If tracking was set up in the superproject but not the
792
   * submodule, users might expect "git branch --recurse-submodules" to
793
   * fail or give a warning, but this is not yet implemented because it is
794
   * tedious to determine whether or not tracking was set up in the
795
   * superproject.
796
   */
797
0
  if (track)
798
0
    setup_tracking(name, tracking_name, track, quiet);
799
800
0
  for (i = 0; i < submodule_entry_list.entry_nr; i++) {
801
0
    if (submodule_create_branch(
802
0
          submodule_entry_list.entries[i].repo,
803
0
          submodule_entry_list.entries[i].submodule, name,
804
0
          oid_to_hex(&submodule_entry_list.entries[i]
805
0
            .name_entry->oid),
806
0
          tracking_name, force, reflog, quiet, track, 0))
807
0
      die(_("submodule '%s': cannot create branch '%s'"),
808
0
          submodule_entry_list.entries[i].submodule->name,
809
0
          name);
810
0
    repo_clear(submodule_entry_list.entries[i].repo);
811
0
  }
812
0
}
813
814
void remove_merge_branch_state(struct repository *r)
815
0
{
816
0
  unlink(git_path_merge_head(r));
817
0
  unlink(git_path_merge_rr(r));
818
0
  unlink(git_path_merge_msg(r));
819
0
  unlink(git_path_merge_mode(r));
820
0
  unlink(git_path_auto_merge(r));
821
0
  save_autostash(git_path_merge_autostash(r));
822
0
}
823
824
void remove_branch_state(struct repository *r, int verbose)
825
0
{
826
0
  sequencer_post_commit_cleanup(r, verbose);
827
0
  unlink(git_path_squash_msg(r));
828
0
  remove_merge_branch_state(r);
829
0
}
830
831
void die_if_checked_out(const char *branch, int ignore_current_worktree)
832
0
{
833
0
  struct worktree **worktrees = get_worktrees();
834
835
0
  for (int i = 0; worktrees[i]; i++) {
836
0
    if (worktrees[i]->is_current && ignore_current_worktree)
837
0
      continue;
838
839
0
    if (is_shared_symref(worktrees[i], "HEAD", branch)) {
840
0
      skip_prefix(branch, "refs/heads/", &branch);
841
0
      die(_("'%s' is already used by worktree at '%s'"),
842
0
        branch, worktrees[i]->path);
843
0
    }
844
0
  }
845
846
0
  free_worktrees(worktrees);
847
0
}