[PATCH v6] branch: support for shortcuts like @{-1}, completed

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

 



branch command with options "edit-description", "set-upstream-to" and
"unset-upstream" expects a branch name.  Since ae5a6c3684 (checkout:
implement "@{-N}" shortcut name for N-th last branch, 2009-01-17) a
branch can be specified using shortcuts like @{-1}.  Those shortcuts
need to be resolved when considering the arguments.

We can modify the description of the previously checked out branch with:

$ git branch --edit--description @{-1}

We can modify the upstream of the previously checked out branch with:

$ git branch --set-upstream-to upstream @{-1}
$ git branch --unset-upstream @{-1}

Signed-off-by: Rubén Justo <rjusto@xxxxxxxxx>
Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx>
---

This is the v5 with your fix squashed, but with one change to maintain
the -1 on error.

    -			error(!argc
    +			ret = error(!argc
    			      ? _("No commit on branch '%s' yet.")
    			      : _("No branch named '%s'."),
    			      branch_name);


We discussed to keep this and other things like the capitalized error
messages, to be sorted out in next series, when the dust settles after
this and the other patch about errors on unborn branches.

ref:
<xmqqlepp8smc.fsf@gitster.g>
<xmqqmtajosek.fsf@gitster.g>


Range-diff:
1:  00ca255874 ! 1:  11650c6340 branch: support for shortcuts like @{-1}, completed
    @@ builtin/branch.c: int cmd_branch(int argc, const char **argv, const char *prefix
      		const char *branch_name;
      		struct strbuf branch_ref = STRBUF_INIT;
     +		struct strbuf buf = STRBUF_INIT;
    ++		int ret = 1; /* assume failure */
      
      		if (!argc) {
      			if (filter.detached)
    @@ builtin/branch.c: int cmd_branch(int argc, const char **argv, const char *prefix
      			branch_name = head;
     -		} else if (argc == 1)
     -			branch_name = argv[0];
    +-		else
     +		} else if (argc == 1) {
     +			strbuf_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
     +			branch_name = buf.buf;
    -+		}
    - 		else
    ++		} else {
      			die(_("cannot edit description of more than one branch"));
    ++		}
      
      		strbuf_addf(&branch_ref, "refs/heads/%s", branch_name);
    - 		if (!ref_exists(branch_ref.buf)) {
    - 			strbuf_release(&branch_ref);
    -+			strbuf_release(&buf);
    - 
    - 			if (!argc)
    - 				return error(_("No commit on branch '%s' yet."),
    -@@ builtin/branch.c: int cmd_branch(int argc, const char **argv, const char *prefix)
    - 		}
    +-		if (!ref_exists(branch_ref.buf)) {
    +-			strbuf_release(&branch_ref);
    +-
    +-			if (!argc)
    +-				return error(_("No commit on branch '%s' yet."),
    +-					     branch_name);
    +-			else
    +-				return error(_("No branch named '%s'."),
    +-					     branch_name);
    +-		}
    ++		if (!ref_exists(branch_ref.buf))
    ++			ret = error(!argc
    ++			      ? _("No commit on branch '%s' yet.")
    ++			      : _("No branch named '%s'."),
    ++			      branch_name);
    ++		else if (!edit_branch_description(branch_name))
    ++			ret = 0; /* happy */
    ++
      		strbuf_release(&branch_ref);
    ++		strbuf_release(&buf);
      
     -		if (edit_branch_description(branch_name))
    -+		if (edit_branch_description(branch_name)) {
    -+			strbuf_release(&buf);
    - 			return 1;
    -+		}
    -+		strbuf_release(&buf);
    +-			return 1;
    ++		return ret;
      	} else if (copy) {
      		if (!argc)
      			die(_("branch name required"));

 builtin/branch.c                      | 53 +++++++++++++++++----------
 t/t3204-branch-name-interpretation.sh | 24 ++++++++++++
 2 files changed, 58 insertions(+), 19 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index 55cd9a6e99..658c9f8741 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -791,31 +791,33 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 	} else if (edit_description) {
 		const char *branch_name;
 		struct strbuf branch_ref = STRBUF_INIT;
+		struct strbuf buf = STRBUF_INIT;
+		int ret = 1; /* assume failure */
 
 		if (!argc) {
 			if (filter.detached)
 				die(_("Cannot give description to detached HEAD"));
 			branch_name = head;
-		} else if (argc == 1)
-			branch_name = argv[0];
-		else
+		} else if (argc == 1) {
+			strbuf_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
+			branch_name = buf.buf;
+		} else {
 			die(_("cannot edit description of more than one branch"));
+		}
 
 		strbuf_addf(&branch_ref, "refs/heads/%s", branch_name);
-		if (!ref_exists(branch_ref.buf)) {
-			strbuf_release(&branch_ref);
-
-			if (!argc)
-				return error(_("No commit on branch '%s' yet."),
-					     branch_name);
-			else
-				return error(_("No branch named '%s'."),
-					     branch_name);
-		}
+		if (!ref_exists(branch_ref.buf))
+			ret = error(!argc
+			      ? _("No commit on branch '%s' yet.")
+			      : _("No branch named '%s'."),
+			      branch_name);
+		else if (!edit_branch_description(branch_name))
+			ret = 0; /* happy */
+
 		strbuf_release(&branch_ref);
+		strbuf_release(&buf);
 
-		if (edit_branch_description(branch_name))
-			return 1;
+		return ret;
 	} else if (copy) {
 		if (!argc)
 			die(_("branch name required"));
@@ -835,9 +837,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		else
 			die(_("too many arguments for a rename operation"));
 	} else if (new_upstream) {
-		struct branch *branch = branch_get(argv[0]);
+		struct branch *branch;
+		struct strbuf buf = STRBUF_INIT;
 
-		if (argc > 1)
+		if (!argc)
+			branch = branch_get(NULL);
+		else if (argc == 1) {
+			strbuf_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
+			branch = branch_get(buf.buf);
+		} else
 			die(_("too many arguments to set new upstream"));
 
 		if (!branch) {
@@ -854,11 +862,17 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		dwim_and_setup_tracking(the_repository, branch->name,
 					new_upstream, BRANCH_TRACK_OVERRIDE,
 					quiet);
+		strbuf_release(&buf);
 	} else if (unset_upstream) {
-		struct branch *branch = branch_get(argv[0]);
+		struct branch *branch;
 		struct strbuf buf = STRBUF_INIT;
 
-		if (argc > 1)
+		if (!argc)
+			branch = branch_get(NULL);
+		else if (argc == 1) {
+			strbuf_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
+			branch = branch_get(buf.buf);
+		} else
 			die(_("too many arguments to unset upstream"));
 
 		if (!branch) {
@@ -871,6 +885,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		if (!branch_has_merge_config(branch))
 			die(_("Branch '%s' has no upstream information"), branch->name);
 
+		strbuf_reset(&buf);
 		strbuf_addf(&buf, "branch.%s.remote", branch->name);
 		git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE);
 		strbuf_reset(&buf);
diff --git a/t/t3204-branch-name-interpretation.sh b/t/t3204-branch-name-interpretation.sh
index 993a6b5eff..793bf4d269 100755
--- a/t/t3204-branch-name-interpretation.sh
+++ b/t/t3204-branch-name-interpretation.sh
@@ -133,4 +133,28 @@ test_expect_success 'checkout does not treat remote @{upstream} as a branch' '
 	expect_branch HEAD one
 '
 
+test_expect_success 'edit-description via @{-1}' '
+	git checkout -b desc-branch &&
+	git checkout -b non-desc-branch &&
+	write_script editor <<-\EOF &&
+		echo "Branch description" >"$1"
+	EOF
+	EDITOR=./editor git branch --edit-description @{-1} &&
+	test_must_fail git config branch.non-desc-branch.description &&
+	git config branch.desc-branch.description >actual &&
+	printf "Branch description\n\n" >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'modify branch upstream via "@{-1}" and "@{-1}@{upstream}"' '
+	git checkout -b upstream-branch &&
+	git checkout -b upstream-other -t upstream-branch &&
+	git branch --set-upstream-to upstream-other @{-1} &&
+	git config branch.upstream-branch.merge >actual &&
+	echo "refs/heads/upstream-other" >expect &&
+	test_cmp expect actual &&
+	git branch --unset-upstream @{-1}@{upstream} &&
+	test_must_fail git config branch.upstream-other.merge
+'
+
 test_done
-- 
2.36.1



[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]

  Powered by Linux