[PATCH] git-clone: Add option --branch to override initial branch

Subsystems: documentation, the rest

DORMANTno replies

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

[PATCH] git-clone: Add option --branch to override initial branch

From: Tor Arne Vestbø <hidden>
Date: 2016-06-15 22:46:19

The options --branch and -b allow the user to override the initial
branch created and checked out by git-clone. Normally this is the
active branch of the remote repository, which is also the fallback
if the selected branch is not found.

Signed-off-by: Tor Arne Vestbø <redacted>
---
 Documentation/git-clone.txt |    5 +++++
 builtin-clone.c             |   33 +++++++++++++++++++++++++++++----
 2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 95f08b9..e7feb4d 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -119,6 +119,11 @@ then the cloned repository will become corrupt.
 	Instead of using the remote name 'origin' to keep track
 	of the upstream repository, use <name> instead.
 
+--branch <name>::
+-b <name>::
+	Instead of using the remote repository's active branch as the
+	initial branch, use <name> instead.
+
 --upload-pack <upload-pack>::
 -u <upload-pack>::
 	When given, and the repository to clone from is accessed
diff --git a/builtin-clone.c b/builtin-clone.c
index c338910..601c2c2 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -38,6 +38,7 @@ static int option_quiet, option_no_checkout, option_bare, option_mirror;
 static int option_local, option_no_hardlinks, option_shared;
 static char *option_template, *option_reference, *option_depth;
 static char *option_origin = NULL;
+static char *option_branch = NULL;
 static char *option_upload_pack = "git-upload-pack";
 static int option_verbose;
 
@@ -66,6 +67,8 @@ static struct option builtin_clone_options[] = {
 		   "path to git-upload-pack on the remote"),
 	OPT_STRING(0, "depth", &option_depth, "depth",
 		    "create a shallow clone of that depth"),
+	OPT_STRING('b', "branch", &option_branch, "branch",
+		    "initial remote branch to check out"),
 
 	OPT_END()
 };
@@ -372,7 +375,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	const char *repo_name, *repo, *work_tree, *git_dir;
 	char *path, *dir;
 	int dest_exists;
-	const struct ref *refs, *head_points_at, *remote_head, *mapped_refs;
+	const struct ref *refs, *mapped_refs;
+	const struct ref *remote_head = NULL;
+	const struct ref *head_points_at = NULL;
 	struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
 	struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
 	struct transport *transport = NULL;
@@ -545,12 +550,32 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
 		mapped_refs = write_remote_refs(refs, &refspec, reflog_msg.buf);
 
-		head_points_at = locate_head(refs, mapped_refs, &remote_head);
+		if (option_branch) {
+		    const int offset = 11;
+		    const char *branch = option_branch;
+		    if (!prefixcmp(branch, "refs/heads/"))
+			branch += offset;
+
+		    const struct ref *r;
+		    for (r = mapped_refs; r; r = r->next) {
+			if (!strcmp(r->name + offset, branch)) {
+			    /* Override initial branch */
+			    head_points_at = r;
+			    remote_head = r;
+			    break;
+			}
+		    }
+
+		    if (!head_points_at)
+			warning("remote has no branch named '%s', "
+				"falling back to default.", option_branch);
+		}
+
+		if (!head_points_at)
+		    head_points_at = locate_head(refs, mapped_refs, &remote_head);
 	}
 	else {
 		warning("You appear to have cloned an empty repository.");
-		head_points_at = NULL;
-		remote_head = NULL;
 		option_no_checkout = 1;
 		if (!option_bare)
 			install_branch_config("master", option_origin,
-- 
1.6.2.rc2.16.gf474c.dirty

Re: [PATCH] git-clone: Add option --branch to override initial branch

From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:46:19

Hi,

On Mon, 2 Mar 2009, Tor Arne Vestbø wrote:
The options --branch and -b allow the user to override the initial 
branch created and checked out by git-clone. Normally this is the active 
branch of the remote repository, which is also the fallback if the 
selected branch is not found.
I do not think that falling back if the selected branch is not found is a 
wise choice.

Besides, the common way to check out something different than the remote's 
HEAD is like this:

	$ git clone -n $URL
	$ cd $DIR
	$ git checkout -t origin/$BRANCH

I am undecided if that is good enough, or your patch is needed.

Ciao,
Dscho

Re: [PATCH] git-clone: Add option --branch to override initial branch

From: Tor Arne Vestbø <hidden>
Date: 2016-06-15 22:46:19

Johannes Schindelin wrote:
On Mon, 2 Mar 2009, Tor Arne Vestbø wrote:
quoted
The options --branch and -b allow the user to override the initial 
branch created and checked out by git-clone. Normally this is the active 
branch of the remote repository, which is also the fallback if the 
selected branch is not found.
I do not think that falling back if the selected branch is not found is a 
wise choice.
Ah, was not sure what the proper response would be. I'll resubmit with a
die() instead.
Besides, the common way to check out something different than the remote's 
HEAD is like this:

	$ git clone -n $URL
	$ cd $DIR
	$ git checkout -t origin/$BRANCH
Yepp, plus removing the original branch:

 $ git branch -D $ORIGINAL_ACTIVE_BRANCH # typically master
I am undecided if that is good enough, or your patch is needed.
The idea was to be able to tell someone "hey, if you want to hack on
some feature for next, do the following:"

 $ git clone git://git.kernel.org/pub/scm/git/git.git -b next

Maybe next is not such a good example, since it does not diverge that
much from master and pu, but imagine a repository with a master, plus
other branches that over time diverge from master (where you would
typically use git-new-workdir to have them in a separate working tree).

In that situation it would be nice to be able to tell someone, hey, if
you want to work on this odd branch which is not master, just do -b.

Tor Arne

[PATCH v2] git-clone: Add option --branch to override initial branch

From: Tor Arne Vestbø <hidden>
Date: 2016-06-15 22:46:19

The options --branch and -b allow the user to override the initial
branch created and checked out by git-clone (normally this is the
active branch of the remote repository).

If the selected branch is not found the operation aborts.

Signed-off-by: Tor Arne Vestbø <redacted>
---

Something like this?

Documentation/git-clone.txt |    5 +++++
 builtin-clone.c             |   32 ++++++++++++++++++++++++++++----
 2 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 95f08b9..e7feb4d 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -119,6 +119,11 @@ then the cloned repository will become corrupt.
 	Instead of using the remote name 'origin' to keep track
 	of the upstream repository, use <name> instead.
 
+--branch <name>::
+-b <name>::
+	Instead of using the remote repository's active branch as the
+	initial branch, use <name> instead.
+
 --upload-pack <upload-pack>::
 -u <upload-pack>::
 	When given, and the repository to clone from is accessed
diff --git a/builtin-clone.c b/builtin-clone.c
index c338910..5fc01ce 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -38,6 +38,7 @@ static int option_quiet, option_no_checkout, option_bare, option_mirror;
 static int option_local, option_no_hardlinks, option_shared;
 static char *option_template, *option_reference, *option_depth;
 static char *option_origin = NULL;
+static char *option_branch = NULL;
 static char *option_upload_pack = "git-upload-pack";
 static int option_verbose;
 
@@ -66,6 +67,8 @@ static struct option builtin_clone_options[] = {
 		   "path to git-upload-pack on the remote"),
 	OPT_STRING(0, "depth", &option_depth, "depth",
 		    "create a shallow clone of that depth"),
+	OPT_STRING('b', "branch", &option_branch, "branch",
+		    "initial remote branch to check out"),
 
 	OPT_END()
 };
@@ -372,7 +375,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	const char *repo_name, *repo, *work_tree, *git_dir;
 	char *path, *dir;
 	int dest_exists;
-	const struct ref *refs, *head_points_at, *remote_head, *mapped_refs;
+	const struct ref *refs, *mapped_refs;
+	const struct ref *remote_head = NULL;
+	const struct ref *head_points_at = NULL;
 	struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
 	struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
 	struct transport *transport = NULL;
@@ -545,12 +550,31 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
 		mapped_refs = write_remote_refs(refs, &refspec, reflog_msg.buf);
 
-		head_points_at = locate_head(refs, mapped_refs, &remote_head);
+		if (option_branch) {
+		    const int offset = 11;
+		    const char *branch = option_branch;
+		    if (!prefixcmp(branch, "refs/heads/"))
+			branch += offset;
+
+		    const struct ref *r;
+		    for (r = mapped_refs; r; r = r->next) {
+			if (!strcmp(r->name + offset, branch)) {
+			    /* Override initial branch */
+			    head_points_at = r;
+			    remote_head = r;
+			    break;
+			}
+		    }
+
+		    if (!head_points_at)
+			die("remote has no branch named '%s'.", option_branch);
+
+		} else {
+		    head_points_at = locate_head(refs, mapped_refs, &remote_head);
+		}
 	}
 	else {
 		warning("You appear to have cloned an empty repository.");
-		head_points_at = NULL;
-		remote_head = NULL;
 		option_no_checkout = 1;
 		if (!option_bare)
 			install_branch_config("master", option_origin,
-- 
1.6.2.rc2.17.g2aa38

Re: [PATCH v2] git-clone: Add option --branch to override initial branch

From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:46:19

Hi,

On Tue, 3 Mar 2009, Tor Arne Vestbø wrote:
Something like this?
Leaving unnecessary initialization and funny indentation aside for a 
moment, what about the objection that it might not be necessary?

Keep in mind: your change (as every change) bears the potential to 
introduce bugs and to complicate the user interface.  The change must be 
worth those risks.

So could you make a case (if you resubmit a patch, in the commit message, 
please) why your change is desirable?

Thanks,
Dscho

Re: [PATCH v2] git-clone: Add option --branch to override initial branch

From: Tor Arne Vestbø <hidden>
Date: 2016-06-15 22:46:19

Johannes Schindelin wrote:
Leaving unnecessary initialization and funny indentation aside for a 
moment,
I do appreciate the feedback though. C is not my primary language, and
I'm happy to learn from my mistakes :-)
Keep in mind: your change (as every change) bears the potential to 
introduce bugs and to complicate the user interface.  The change must be 
worth those risks.
I fully understand. Here is my rationale for why it's worth the risk:

Imagine you have a project called Foo, which has active development on 
the 'master' branch, and not quite so active development on the more 
stable version branch '1.6' (which v1.6.0 and v1.6.1 was tagged from).

Now, you want to put up info on the project web page / wiki on how to 
contribute to project Foo. This information is for new contributors -- 
who may be unfamiliar with git and it's inner workings. You write:

"To get started contributing to project Foo, please clone using:

   $ git clone git://git.foo.com/project.git

"

This looks nice and inviting.

You also want to provide instructions for those who would like to 
contribute to the more stable branch of project Foo, 1.6:

"If you would like to contribute to the stable 1.6 branch, do:

   $ git clone -n git://git.foo.com/project.git
   $ cd project
   $ git checkout -t origin/1.6
   $ git branch -D master

"

Which is not so nice and inviting. At least not compared to:

"If you would like to contribute to the stable 1.6 branch, do:

   $ git clone git://git.foo.com/project.git --branch 1.6

"

Remember these are new contributors, unfamiliar with git. Presenting 
them with a list of four commands that have to be run to get started 
(commands which incidentally also are the first-ones new users mix up), 
is not ideal. "What does -n do?", "What does -t do?", "What's a tracking
branch?", "Origin? What's that?", "What does -D do?", "Delete?! Will I 
delete the main development line!?", etc.. :)

Also, remember that these commands are not something that can be 
scripted or put into an alias, because these users have not cloned 
anything yet.

I know Subversions is perhaps not the best ideal, but to contrast:

   $ svn import http://svn.foo.bar/project/trunk
   $ svn import http://svn.foo.bar/project/branches/1.6

Easy to get to a different branch without having to dive into the full 
feature set of the SCM.

So, to conclude, I see this as a usability-feature of git-clone, which 
outweighs the possible risk of introducing new bugs. It's not a feature 
I will personally use that often, but it's one that I think new users 
will appreciate.


Tor Arne
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help