[PATCH v3][Outreachy] branch -D: allow - as abbreviation of @{-1}

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Elena Petrashen <elena.petrashen@xxxxxxxxx>
---
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

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]