[PATCH v3][Outreachy] branch -D: allow - as abbreviation of @{-1}
From: Elena Petrashen <hidden>
Date: 2016-06-15 23:09:08
Signed-off-by: Elena Petrashen <redacted>
---
This micro-patch is meant to allow “-“ as a short-hand for
“@{-1} for branch -d (Cf. $gmane/230828). Based on feedback
for v2:
* suppressable advice on restoring if a user deletes a branch
via @{-x} or - reference (to ensure safety: if a user deleted
the wrong branch instead what she thought is @{-1}, which seems
to be more likely compared with the situation when branch name
has to be typed in)
* if not enough switches exist to delete branch via @{-x} or -
reference, a corresponding warning is displayed
Thank you! Looking forward to any feedback.
Documentation/git-branch.txt | 2 ++
advice.c | 10 ++++++++++
advice.h | 2 ++
builtin/branch.c | 22 +++++++++++++++++++---
t/t3200-branch.sh | 10 ++++++++++
5 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 4a7037f..42b96ed 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt@@ -65,6 +65,8 @@ to happen. With a `-d` or `-D` option, `<branchname>` will be deleted. You may specify more than one branch for deletion. If the branch currently has a reflog then the reflog will also be deleted. +The "@{-N}" syntax for the N-th last branch deletes the specified branch. +You may also specify - which is synonymous with "@{-1}". Use `-r` together with `-d` to delete remote-tracking branches. Note, that it only makes sense to delete remote-tracking branches if they no longer exist
diff --git a/advice.c b/advice.c
index 4dc5cf1..f14eb68 100644
--- a/advice.c
+++ b/advice.c@@ -15,6 +15,7 @@ int advice_detached_head = 1; int advice_set_upstream_failure = 1; int advice_object_name_warning = 1; int advice_rm_hints = 1; +int advice_delete_branch_via_at_ref = 1; static struct { const char *name;
@@ -35,6 +36,7 @@ static struct { { "setupstreamfailure", &advice_set_upstream_failure }, { "objectnamewarning", &advice_object_name_warning }, { "rmhints", &advice_rm_hints }, + { "deletebranchviaatref", &advice_delete_branch_via_at_ref }, /* make this an alias for backward compatibility */ { "pushnonfastforward", &advice_push_update_rejected }
@@ -117,3 +119,11 @@ void detach_advice(const char *new_name) fprintf(stderr, fmt, new_name); } + +void delete_branch_advice(const char *name, const char *ref) +{ + const char fmt[] = + "\nNote: to restore the deleted branch:\n\ngit branch %s %s\n"; + + fprintf(stderr, fmt, name, ref); +}
diff --git a/advice.h b/advice.h
index b341a55..192eef7 100644
--- a/advice.h
+++ b/advice.h@@ -18,6 +18,7 @@ extern int advice_detached_head; extern int advice_set_upstream_failure; extern int advice_object_name_warning; extern int advice_rm_hints; +extern int advice_delete_branch_via_at_ref; int git_default_advice_config(const char *var, const char *value); __attribute__((format (printf, 1, 2)))
@@ -26,5 +27,6 @@ int error_resolve_conflict(const char *me); extern void NORETURN die_resolve_conflict(const char *me); void NORETURN die_conclude_merge(void); void detach_advice(const char *new_name); +void delete_branch_advice(const char *name, const char *ref); #endif /* ADVICE_H */
diff --git a/builtin/branch.c b/builtin/branch.c
index 7b45b6b..4f5ec72 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c@@ -178,6 +178,12 @@ static void delete_branch_config(const char *branchname) strbuf_release(&buf); } +static void expand_dash_shortcut(const char **argv, int dash_position) +{ + if (!strcmp(argv[dash_position], "-")) + argv[dash_position] = "@{-1}"; +} + static int delete_branches(int argc, const char **argv, int force, int kinds, int quiet) {
@@ -187,6 +193,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds, const char *fmt; int i; int ret = 0; + int at_shortcut = 0; int remote_branch = 0; struct strbuf bname = STRBUF_INIT;
@@ -214,6 +221,9 @@ static int delete_branches(int argc, const char **argv, int force, int kinds, const char *target; int flags = 0; + expand_dash_shortcut (argv, i); + if(!strncmp(argv[i], "@{-", strlen("@{-"))) + at_shortcut = 1; strbuf_branchname(&bname, argv[i]); if (kinds == FILTER_REFS_BRANCHES && !strcmp(head, bname.buf)) { error(_("Cannot delete the branch '%s' "
@@ -231,9 +241,12 @@ static int delete_branches(int argc, const char **argv, int force, int kinds, | RESOLVE_REF_ALLOW_BAD_NAME, sha1, &flags); if (!target) { - error(remote_branch - ? _("remote-tracking branch '%s' not found.") - : _("branch '%s' not found."), bname.buf); + error((!strncmp(bname.buf, "@{-", strlen("@{-"))) + ? _("There is not enough branch switches to" + " delete '%s'.") + : remote_branch + ? _("remote-tracking branch '%s' not found.") + : _("branch '%s' not found."), bname.buf); ret = 1; continue; }
@@ -262,6 +275,9 @@ static int delete_branches(int argc, const char **argv, int force, int kinds, (flags & REF_ISBROKEN) ? "broken" : (flags & REF_ISSYMREF) ? target : find_unique_abbrev(sha1, DEFAULT_ABBREV)); + if (at_shortcut && advice_delete_branch_via_at_ref) + delete_branch_advice (bname.buf, + find_unique_abbrev(sha1, DEFAULT_ABBREV)); } delete_branch_config(bname.buf); }
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index a897248..0b59c94 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh@@ -372,6 +372,16 @@ test_expect_success 'test overriding tracking setup via --no-track' ' ! test "$(git config branch.my2.merge)" = refs/heads/master ' +test_expect_success 'test deleting "-" deletes previous branch' ' + git checkout -b prev && + test_commit prev && + git checkout master && + git branch -D - >actual && + sha1=$(git rev-parse prev | cut -c 1-7) && + echo "Deleted branch prev (was $sha1)." >expect && + test_cmp expect actual +' + test_expect_success 'no tracking without .fetch entries' ' git config branch.autosetupmerge true && git branch my6 s &&
--
2.8.0.dirty