]> git.ipfire.org Git - thirdparty/git.git/commitdiff
branch: make create_branch() always create a branch
authorGlen Choo <chooglen@google.com>
Sat, 29 Jan 2022 00:04:42 +0000 (16:04 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 1 Feb 2022 22:18:49 +0000 (14:18 -0800)
With the previous commit, there are no more invocations of
create_branch() that do not create a branch because:

* BRANCH_TRACK_OVERRIDE is no longer passed
* clobber_head_ok = true and force = false is never passed

Assert these situations, delete dead code and ensure that we're handling
clobber_head_ok and force correctly by introducing tests for `git branch
--force`. As a result, create_branch() now always creates a branch.

Helped-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Glen Choo <chooglen@google.com>
Reviewed-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
branch.c
branch.h
t/t3200-branch.sh

index f3a31930fbfe3b0ea27053f12a6f7d8be1ce524a..df24021f27847de3b739e76b08502de17bcb9fd6 100644 (file)
--- a/branch.c
+++ b/branch.c
@@ -429,15 +429,19 @@ void create_branch(struct repository *r,
        char *real_ref;
        struct strbuf ref = STRBUF_INIT;
        int forcing = 0;
-       int dont_change_ref = 0;
-
-       if ((track == BRANCH_TRACK_OVERRIDE || clobber_head_ok)
-           ? validate_branchname(name, &ref)
-           : validate_new_branchname(name, &ref, force)) {
-               if (!force)
-                       dont_change_ref = 1;
-               else
-                       forcing = 1;
+       struct ref_transaction *transaction;
+       struct strbuf err = STRBUF_INIT;
+       char *msg;
+
+       if (track == BRANCH_TRACK_OVERRIDE)
+               BUG("'track' cannot be BRANCH_TRACK_OVERRIDE. Did you mean to call dwim_and_setup_tracking()?");
+       if (clobber_head_ok && !force)
+               BUG("'clobber_head_ok' can only be used with 'force'");
+
+       if (clobber_head_ok ?
+                         validate_branchname(name, &ref) :
+                         validate_new_branchname(name, &ref, force)) {
+               forcing = 1;
        }
 
        dwim_branch_start(r, start_name, track, &real_ref, &oid);
@@ -445,27 +449,20 @@ void create_branch(struct repository *r,
        if (reflog)
                log_all_ref_updates = LOG_REFS_NORMAL;
 
-       if (!dont_change_ref) {
-               struct ref_transaction *transaction;
-               struct strbuf err = STRBUF_INIT;
-               char *msg;
-
-               if (forcing)
-                       msg = xstrfmt("branch: Reset to %s", start_name);
-               else
-                       msg = xstrfmt("branch: Created from %s", start_name);
-
-               transaction = ref_transaction_begin(&err);
-               if (!transaction ||
-                   ref_transaction_update(transaction, ref.buf,
-                                          &oid, forcing ? NULL : null_oid(),
-                                          0, msg, &err) ||
-                   ref_transaction_commit(transaction, &err))
-                       die("%s", err.buf);
-               ref_transaction_free(transaction);
-               strbuf_release(&err);
-               free(msg);
-       }
+       if (forcing)
+               msg = xstrfmt("branch: Reset to %s", start_name);
+       else
+               msg = xstrfmt("branch: Created from %s", start_name);
+       transaction = ref_transaction_begin(&err);
+       if (!transaction ||
+               ref_transaction_update(transaction, ref.buf,
+                                       &oid, forcing ? NULL : null_oid(),
+                                       0, msg, &err) ||
+               ref_transaction_commit(transaction, &err))
+               die("%s", err.buf);
+       ref_transaction_free(transaction);
+       strbuf_release(&err);
+       free(msg);
 
        if (real_ref && track)
                setup_tracking(ref.buf + 11, real_ref, track, quiet);
index ab2315c611b26aa8fc0bf169610452a6b5b0aa82..cf3a4d3ff3694ab662c0b1fdf12c53017cfe13c0 100644 (file)
--- a/branch.h
+++ b/branch.h
@@ -52,8 +52,8 @@ void dwim_and_setup_tracking(struct repository *r, const char *new_ref,
  *
  *   - force enables overwriting an existing (non-head) branch
  *
- *   - clobber_head_ok allows the currently checked out (hence existing)
- *     branch to be overwritten; without 'force', it has no effect.
+ *   - clobber_head_ok, when enabled with 'force', allows the currently
+ *     checked out (head) branch to be overwritten
  *
  *   - reflog creates a reflog for the branch
  *
index 09ab132377582732949f8ea199edd5a1106f88b2..71a72efcb2474b71042b8cea2b0035097a510d67 100755 (executable)
@@ -42,6 +42,23 @@ test_expect_success 'git branch abc should create a branch' '
        git branch abc && test_path_is_file .git/refs/heads/abc
 '
 
+test_expect_success 'git branch abc should fail when abc exists' '
+       test_must_fail git branch abc
+'
+
+test_expect_success 'git branch --force abc should fail when abc is checked out' '
+       test_when_finished git switch main &&
+       git switch abc &&
+       test_must_fail git branch --force abc HEAD~1
+'
+
+test_expect_success 'git branch --force abc should succeed when abc exists' '
+       git rev-parse HEAD~1 >expect &&
+       git branch --force abc HEAD~1 &&
+       git rev-parse abc >actual &&
+       test_cmp expect actual
+'
+
 test_expect_success 'git branch a/b/c should create a branch' '
        git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c
 '