Subject: [PATCH 3/3] checkout: rearrange update_refs_for_switch for clarity

From: Jonathan Nieder <[email-masked]>
Date: Tue, 8 Feb 2011 04:34:34 -0600

Take care of simple, exceptional cases before the meat of the "check
out by branch name" code begins.  After this change, the function
vaguely follows the following pseudocode:

	if (-B or -b)
		create branch;
	if (plain "git checkout" or "git checkout HEAD")
		;
	else if (--detach or checking out by non-branch commit name)
		detach HEAD;
	else if (checking out by branch name)
		attach HEAD;

One nice side benefit is to make it possible to remove handling of
the --detach option from outside switch_branches.

Signed-off-by: Jonathan Nieder <[email-masked]>
---
That's the end of the series.  Thoughts welcome, as always.

'night,
Jonathan

 builtin/checkout.c |   27 +++++++++++++--------------
 1 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 51ec977..179d047 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -542,7 +542,17 @@ static void update_refs_for_switch(struct checkout_opts *opts,
 	strbuf_addf(&msg, "checkout: moving from %s to %s",
 		    old_desc ? old_desc : "(invalid)", new->name);
 
-	if (new->path) {
+	if (!strcmp(new->name, "HEAD") && !new->path && !opts->force_detach) {
+		/* Nothing to do. */
+	} else if (opts->force_detach || !new->path) {	/* No longer on any branch. */
+		update_ref(msg.buf, "HEAD", new->commit->object.sha1, NULL,
+			   REF_NODEREF, DIE_ON_ERR);
+		if (!opts->quiet) {
+			if (old->path && advice_detached_head)
+				detach_advice(old->path, new->name);
+			describe_detached_head("HEAD is now at", new->commit);
+		}
+	} else if (new->path) {	/* Switch branches. */
 		create_symref("HEAD", new->path, msg.buf);
 		if (!opts->quiet) {
 			if (old->path && !strcmp(new->path, old->path))
@@ -564,14 +574,6 @@ static void update_refs_for_switch(struct checkout_opts *opts,
 			if (!file_exists(ref_file) && file_exists(log_file))
 				remove_path(log_file);
 		}
-	} else if (opts->force_detach || strcmp(new->name, "HEAD")) {
-		update_ref(msg.buf, "HEAD", new->commit->object.sha1, NULL,
-			   REF_NODEREF, DIE_ON_ERR);
-		if (!opts->quiet) {
-			if (old->path && advice_detached_head)
-				detach_advice(old->path, new->name);
-			describe_detached_head("HEAD is now at", new->commit);
-		}
 	}
 	remove_branch_state();
 	strbuf_release(&msg);
@@ -679,7 +681,6 @@ static const char *unique_tracking_name(const char *name)
 
 static int parse_branchname_arg(int argc, const char **argv,
 				int dwim_new_local_branch_ok,
-				int force_detach,
 				struct branch_info *new,
 				struct tree **source_tree,
 				unsigned char rev[20],
@@ -756,8 +757,7 @@ static int parse_branchname_arg(int argc, const char **argv,
 	new->name = arg;
 	setup_branch_path(new);
 
-	if (!force_detach &&
-	    check_ref_format(new->path) == CHECK_REF_FORMAT_OK &&
+	if (check_ref_format(new->path) == CHECK_REF_FORMAT_OK &&
 	    resolve_ref(new->path, branch_rev, 1, NULL))
 		hashcpy(rev, branch_rev);
 	else
@@ -906,8 +906,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 			dwim_new_local_branch &&
 			opts.track == BRANCH_TRACK_UNSPECIFIED &&
 			!opts.new_branch;
-		int n = parse_branchname_arg(argc, argv,
-				dwim_ok, opts.force_detach,
+		int n = parse_branchname_arg(argc, argv, dwim_ok,
 				&new, &source_tree, rev, &opts.new_branch);
 		argv += n;
 		argc -= n;
-- 
1.7.4