[PATCH] Extend "checkout --track" DWIM to support more cases

Subsystems: the rest

DORMANTno replies

5 messages, 2 authors, 2016-06-15 · open the first message on its own page

[PATCH] Extend "checkout --track" DWIM to support more cases

From: Alex Riesen <hidden>
Date: 2016-06-15 22:45:11

The code handles additionally "refs/remotes/<something>/name",
"remotes/<something>/name", and "refs/<namespace>/name".
Test cases included.

Signed-off-by: Alex Riesen <redacted>
---

Johannes has likable ideas :)

 builtin-checkout.c |   20 +++++++++++++++-----
 t/t7201-co.sh      |   23 ++++++++++++++++++++++-
 2 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/builtin-checkout.c b/builtin-checkout.c
index e95eab9..20466e2 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -447,11 +447,21 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 		char *slash;
 		if (!argc || !strcmp(argv[0], "--"))
 			die ("--track needs a branch name");
-		slash = strchr(argv[0], '/');
-		if (slash && !prefixcmp(argv[0], "refs/"))
-			slash = strchr(slash + 1, '/');
-		if (slash && !prefixcmp(argv[0], "remotes/"))
-			slash = strchr(slash + 1, '/');
+		if (!prefixcmp(argv[0], "remotes/"))
+			/* skip the name of a remote */
+			slash = strchr(argv[0] + 8, '/');
+		else if (!prefixcmp(argv[0], "refs/")) {
+			/* skip namespaces, try use the names of their
+			 * branches, but for the target namespace
+			 * (heads) demand a new name. Also skip the
+			 * first element in "remotes" namespace */
+			const char *ns = argv[0] + 5;
+			slash = !prefixcmp(ns, "heads/") ? NULL:
+				!prefixcmp(ns, "remotes/") ?
+				strchr(ns + 8, '/'): strchr(ns, '/');
+		} else
+			/* otherwise - just skip the first element */
+			slash = strchr(argv[0], '/');
 		if (!slash || !slash[1])
 			die ("Missing branch name; try -b");
 		opts.new_branch = slash + 1;
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 943dd57..1dff84d 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -340,9 +340,30 @@ test_expect_success \
 test_expect_success \
     'checkout with --track fakes a sensible -b <name>' '
     git update-ref refs/remotes/origin/koala/bear renamer &&
+    git update-ref refs/new/koala/bear renamer &&
+
     git checkout --track origin/koala/bear &&
     test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
-    test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)"'
+    test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
+
+    git checkout master && git branch -D koala/bear &&
+
+    git checkout --track refs/remotes/origin/koala/bear &&
+    test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
+    test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
+
+    git checkout master && git branch -D koala/bear &&
+
+    git checkout --track remotes/origin/koala/bear &&
+    test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
+    test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
+
+    git checkout master && git branch -D koala/bear &&
+
+    git checkout --track refs/new/koala/bear &&
+    test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
+    test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)"
+'
 
 test_expect_success \
     'checkout with --track, but without -b, fails with too short tracked name' '
-- 
1.6.0.22.g09248

Re: [PATCH] Extend "checkout --track" DWIM to support more cases

From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:45:11

Hi,

On Wed, 20 Aug 2008, Alex Riesen wrote:
quoted hunk
The code handles additionally "refs/remotes/<something>/name",
"remotes/<something>/name", and "refs/<namespace>/name".
Test cases included.

Signed-off-by: Alex Riesen <redacted>
---

Johannes has likable ideas :)

 builtin-checkout.c |   20 +++++++++++++++-----
 t/t7201-co.sh      |   23 ++++++++++++++++++++++-
 2 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/builtin-checkout.c b/builtin-checkout.c
index e95eab9..20466e2 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -447,11 +447,21 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 		char *slash;
 		if (!argc || !strcmp(argv[0], "--"))
 			die ("--track needs a branch name");
-		slash = strchr(argv[0], '/');
-		if (slash && !prefixcmp(argv[0], "refs/"))
-			slash = strchr(slash + 1, '/');
-		if (slash && !prefixcmp(argv[0], "remotes/"))
-			slash = strchr(slash + 1, '/');
Why is this not enough?  It strips refs/ if there is one, and remotes/ if 
there is one (possibly after stripping refs/).  No?

Puzzled,
Dscho

Re: [PATCH] Extend "checkout --track" DWIM to support more cases

From: Alex Riesen <hidden>
Date: 2016-06-15 22:45:11

Johannes Schindelin, Wed, Aug 20, 2008 21:52:23 +0200:
On Wed, 20 Aug 2008, Alex Riesen wrote:
quoted
-		slash = strchr(argv[0], '/');
-		if (slash && !prefixcmp(argv[0], "refs/"))
-			slash = strchr(slash + 1, '/');
-		if (slash && !prefixcmp(argv[0], "remotes/"))
-			slash = strchr(slash + 1, '/');
Why is this not enough?  It strips refs/ if there is one, and remotes/ if 
there is one (possibly after stripping refs/).  No?
No. It strips refs/ OR remotes/ (because of prefixcmp with argv[0]).
And I still wanted refs/<namespace>/something...

Re: [PATCH] Extend "checkout --track" DWIM to support more cases

From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:45:11

Hi,

On Wed, 20 Aug 2008, Alex Riesen wrote:
Johannes Schindelin, Wed, Aug 20, 2008 21:52:23 +0200:
quoted
On Wed, 20 Aug 2008, Alex Riesen wrote:
quoted
-		slash = strchr(argv[0], '/');
-		if (slash && !prefixcmp(argv[0], "refs/"))
-			slash = strchr(slash + 1, '/');
-		if (slash && !prefixcmp(argv[0], "remotes/"))
-			slash = strchr(slash + 1, '/');
Why is this not enough?  It strips refs/ if there is one, and remotes/ if 
there is one (possibly after stripping refs/).  No?
No. It strips refs/ OR remotes/ (because of prefixcmp with argv[0]).
And I still wanted refs/<namespace>/something...
Yes, you are correct.  However, to fix my thinko, I deem this preferable:

-- snipsnap --

 builtin-checkout.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/builtin-checkout.c b/builtin-checkout.c
index e95eab9..2a076cf 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -448,8 +448,10 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 		if (!argc || !strcmp(argv[0], "--"))
 			die ("--track needs a branch name");
 		slash = strchr(argv[0], '/');
-		if (slash && !prefixcmp(argv[0], "refs/"))
-			slash = strchr(slash + 1, '/');
+		if (slash && !prefixcmp(argv[0], "refs/")) {
+			argv[0] = slash + 1;
+			slash = strchr(argv[0], '/');
+		}
 		if (slash && !prefixcmp(argv[0], "remotes/"))
 			slash = strchr(slash + 1, '/');
 		if (!slash || !slash[1])

Re: [PATCH] Extend "checkout --track" DWIM to support more cases

From: Alex Riesen <hidden>
Date: 2016-06-15 22:45:11

Johannes Schindelin, Wed, Aug 20, 2008 22:16:19 +0200:
quoted hunk
quoted
No. It strips refs/ OR remotes/ (because of prefixcmp with argv[0]).
And I still wanted refs/<namespace>/something...
Yes, you are correct.  However, to fix my thinko, I deem this preferable:

-- snipsnap --

 builtin-checkout.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/builtin-checkout.c b/builtin-checkout.c
index e95eab9..2a076cf 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -448,8 +448,10 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 		if (!argc || !strcmp(argv[0], "--"))
 			die ("--track needs a branch name");
 		slash = strchr(argv[0], '/');
-		if (slash && !prefixcmp(argv[0], "refs/"))
-			slash = strchr(slash + 1, '/');
+		if (slash && !prefixcmp(argv[0], "refs/")) {
+			argv[0] = slash + 1;
+			slash = strchr(argv[0], '/');
+		}
Yes, I agree (and its shorter). The git-checkout manpage can be
improved, too (no DWIM is obvious, except may be for the implementor).
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help