diff --git a/branch.c b/branch.c
index 2020dedf6..9dda336a0 100644
--- a/branch.c
+++ b/branch.c
@@ -178,28 +178,40 @@ int read_branch_desc(struct strbuf *buf, const char *branch_name)
return 0;
}
-int validate_branch_update(const char *name, struct strbuf *ref,
- int could_exist, int clobber_head)
+int validate_branch_update(const char *name, struct strbuf *ref, int could_exist,
+ int clobber_head, unsigned dont_fail)
{
- if (strbuf_check_branch_ref(ref, name))
- die(_("'%s' is not a valid branch name."), name);
+ if (strbuf_check_branch_ref(ref, name)) {
+ if (dont_fail)
+ return INVALID_BRANCH_NAME;
+ else
+ die(_("'%s' is not a valid branch name."), name);
+ }
if (!ref_exists(ref->buf))
- return 0;
+ return VALID_BRANCH_NAME;
- if (!could_exist)
- die(_("A branch named '%s' already exists."), ref->buf + strlen("refs/heads/"));
+ if (!could_exist) {
+ if (dont_fail)
+ return BRANCH_EXISTS;
+ else
+ die(_("A branch named '%s' already exists."), ref->buf + strlen("refs/heads/"));
+ }
if (!clobber_head) {
const char *head;
struct object_id oid;
head = resolve_ref_unsafe("HEAD", 0, oid.hash, NULL);
- if (!is_bare_repository() && head && !strcmp(head, ref->buf))
- die(_("Cannot force update the current branch."));
+ if (!is_bare_repository() && head && !strcmp(head, ref->buf)) {
+ if (dont_fail)
+ return CANNOT_FORCE_UPDATE_CURRENT_BRANCH;
+ else
+ die(_("Cannot force update the current branch."));
+ }
}
- return 1;
+ return FORCE_UPDATING_BRANCH;
}
/*@@ -268,7 +280,7 @@ void create_branch(const char *name, const char *start_name,
validate_existing_branch(name, &ref);
dont_change_ref = 1;
} else {
- forcing = validate_branch_update(name, &ref, force, clobber_head);
+ forcing = validate_branch_update(name, &ref, force, clobber_head, 0);
}
real_ref = NULL;diff --git a/branch.h b/branch.h
index 6ada7af59..c6a8a75bb 100644
--- a/branch.h
+++ b/branch.h
@@ -27,6 +27,16 @@ void create_branch(const char *name, const char *start_name,
int force, int reflog,
int clobber_head, int quiet, enum branch_track track);
+enum branch_validation_result {
+ /* Flags that say it's NOT OK to update */
+ BRANCH_EXISTS = -3,
+ CANNOT_FORCE_UPDATE_CURRENT_BRANCH,
+ INVALID_BRANCH_NAME,
+ /* Flags that say it's OK to update */
+ VALID_BRANCH_NAME = 0,
+ FORCE_UPDATING_BRANCH = 1
+};
+
/*
* Validates whether the branch with the given name may be updated (created, renamed etc.,)
* with respect to the given conditions. It returns the interpreted ref in ref.@@ -36,10 +46,19 @@ void create_branch(const char *name, const char *start_name,
* if 'could_exist' is true, clobber_head indicates whether the branch could be the
* current branch else it has no effect.
*
- * A non-zero return value indicates that a branch already exists and can be force updated.
+ * The return values have the following meaning,
+ *
+ * - If dont_fail is 0, the function dies in case of failure and returns flags of
+ * 'validate_result' that specify it is OK to update the branch. The positive
+ * non-zero flag implies that the branch can be force updated.
+ *
+ * - If dont_fail is 1, the function doesn't die in case of failure but returns flags
+ * of 'validate_result' that specify the reason for failure. The behaviour in case of
+ * success is same as above.
*
*/
-int validate_branch_update(const char *name, struct strbuf *ref, int could_exist, int clobber_head);
+int validate_branch_update(const char *name, struct strbuf *ref, int could_exist,
+ int clobber_head, unsigned dont_fail);
/*
* Remove information about the state of working on the current
diff --git a/builtin/branch.c b/builtin/branch.c
index 27ddcad97..205c12a11 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -483,7 +483,7 @@ static void rename_branch(const char *oldname, const char *newname, int force)
*/
clobber_head_ok = !strcmp(oldname, newname);
- validate_branch_update(newname, &newref, force, clobber_head_ok);
+ validate_branch_update(newname, &newref, force, clobber_head_ok, 0);
reject_rebase_or_bisect_branch(oldref.buf);
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 2e870ab4b..c7e11c352 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -1284,7 +1284,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
int force = opts.new_branch_force != NULL;
opts.branch_exists = validate_branch_update(opts.new_branch, &buf,
- force, force);
+ force, force, 0);
strbuf_release(&buf);
}
--
2.14.1.868.g66c78774b