This parameter allows the branch update validation function to optionally return a flag specifying the reason for failure, when requested. This allows the caller to know why it was about to die. This allows more useful error messages to be given to the user when trying to rename a branch.
The flags are specified in the form of an enum and values for success flags have been assigned explicitly to clearly express that certain callers rely those values and they cannot be arbitrary. Only the logic has been added but no caller has been made to use it, yet. So, no functional changes. Signed-off-by: Kaartic Sivaraam <kaarticsivaraam91...@gmail.com> --- branch.c | 34 +++++++++++++++++++++++----------- branch.h | 23 +++++++++++++++++++++-- builtin/branch.c | 2 +- builtin/checkout.c | 2 +- 4 files changed, 46 insertions(+), 15 deletions(-) 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