All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [PATCH v2 5/8] checkout: extract branch setup and tracking helpers
Date: Sun, 30 Aug 2026 13:48:32 -0700	[thread overview]
Message-ID: <20260830204835.1040408-6-gitster@pobox.com> (raw)
In-Reply-To: <20260830204835.1040408-1-gitster@pobox.com>

The checkout_main() function validates branch-creation options,
DWIMs tracking branch options, and sets up branch information
directly in its body.

Extract these branch setup operations into static helper functions:

  - validate_branch_options() validates compatibility of '-b', '-B',
    and '--orphan' options.

  - dwim_branch_track_option() infers the branch name when '--track'
    is given without an explicit branch name.

  - setup_branch_name_and_info() drives branch validation and parses
    the branch name argument.

Call the new setup helper from checkout_main().

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/checkout.c | 104 +++++++++++++++++++++++----------------------
 1 file changed, 54 insertions(+), 50 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 8d567def7e..2edaca5539 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -1938,6 +1938,57 @@ static void parse_pathspec_from_file_options(struct checkout_opts *opts,
 	opts->pathspec.recursive = 1;
 }
 
+static void validate_branch_options(struct checkout_opts *opts, char cb_option)
+{
+	if ((!!opts->new_branch + !!opts->new_branch_force + !!opts->new_orphan_branch) > 1)
+		die(_("options '-%c', '-%c', and '%s' cannot be used together"),
+			cb_option, toupper(cb_option), "--orphan");
+
+	if (opts->new_branch_force)
+		opts->new_branch = opts->new_branch_force;
+
+	if (opts->new_orphan_branch)
+		opts->new_branch = opts->new_orphan_branch;
+}
+
+static void dwim_branch_track_option(int argc, const char **argv,
+				     struct checkout_opts *opts, char cb_option)
+{
+	/* --track without -c/-C/-b/-B/--orphan should DWIM */
+	if (opts->track != BRANCH_TRACK_UNSPECIFIED && !opts->new_branch) {
+		const char *argv0 = argv[0];
+		if (!argc || !strcmp(argv0, "--"))
+			die(_("--track needs a branch name"));
+		skip_prefix(argv0, "refs/", &argv0);
+		skip_prefix(argv0, "remotes/", &argv0);
+		argv0 = strchr(argv0, '/');
+		if (!argv0 || !argv0[1])
+			die(_("missing branch name; try -%c"), cb_option);
+		opts->new_branch = argv0 + 1;
+	}
+}
+
+static int setup_branch_name_and_info(int argc, const char **argv,
+				      struct checkout_opts *opts,
+				      struct branch_info *new_branch_info,
+				      char cb_option)
+{
+	validate_branch_options(opts, cb_option);
+	dwim_branch_track_option(argc, argv, opts, cb_option);
+
+	if (argc) {
+		struct object_id rev;
+		int dwim_ok =
+			!opts->patch_mode &&
+			opts->dwim_new_local_branch &&
+			opts->track == BRANCH_TRACK_UNSPECIFIED &&
+			!opts->new_branch;
+		return parse_branchname_arg(argc, argv, dwim_ok, cb_option,
+					    new_branch_info, opts, &rev);
+	}
+	return 0;
+}
+
 static int checkout_main(int argc, const char **argv, const char *prefix,
 			 struct checkout_opts *opts, struct option *options,
 			 enum checkout_command which_command)
@@ -1992,10 +2043,6 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
 	validate_path_options(opts);
 	prepare_common_options(opts);
 
-	if ((!!opts->new_branch + !!opts->new_branch_force + !!opts->new_orphan_branch) > 1)
-		die(_("options '-%c', '-%c', and '%s' cannot be used together"),
-			cb_option, toupper(cb_option), "--orphan");
-
 	/*
 	 * convenient shortcut: "git restore --staged [--worktree]" equals
 	 * "git restore --staged [--worktree] --source HEAD"
@@ -2003,52 +2050,9 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
 	if (!opts->from_treeish && opts->checkout_index)
 		opts->from_treeish = "HEAD";
 
-	/*
-	 * From here on, new_branch will contain the branch to be checked out,
-	 * and new_branch_force and new_orphan_branch will tell us which one of
-	 * -b/-B/-c/-C/--orphan is being used.
-	 */
-	if (opts->new_branch_force)
-		opts->new_branch = opts->new_branch_force;
-
-	if (opts->new_orphan_branch)
-		opts->new_branch = opts->new_orphan_branch;
-
-	/* --track without -c/-C/-b/-B/--orphan should DWIM */
-	if (opts->track != BRANCH_TRACK_UNSPECIFIED && !opts->new_branch) {
-		const char *argv0 = argv[0];
-		if (!argc || !strcmp(argv0, "--"))
-			die(_("--track needs a branch name"));
-		skip_prefix(argv0, "refs/", &argv0);
-		skip_prefix(argv0, "remotes/", &argv0);
-		argv0 = strchr(argv0, '/');
-		if (!argv0 || !argv0[1])
-			die(_("missing branch name; try -%c"), cb_option);
-		opts->new_branch = argv0 + 1;
-	}
-
-	/*
-	 * Extract branch name from command line arguments, so
-	 * all that is left is pathspecs.
-	 *
-	 * Handle
-	 *
-	 *  1) git checkout <tree> -- [<paths>]
-	 *  2) git checkout -- [<paths>]
-	 *  3) git checkout <something> [<paths>]
-	 *
-	 * including "last branch" syntax and DWIM-ery for names of
-	 * remote branches, erroring out for invalid or ambiguous cases.
-	 */
-	if (argc && opts->accept_ref) {
-		struct object_id rev;
-		int dwim_ok =
-			!opts->patch_mode &&
-			opts->dwim_new_local_branch &&
-			opts->track == BRANCH_TRACK_UNSPECIFIED &&
-			!opts->new_branch;
-		int n = parse_branchname_arg(argc, argv, dwim_ok, cb_option,
-					     &new_branch_info, opts, &rev);
+	if (opts->accept_ref) {
+		int n = setup_branch_name_and_info(argc, argv, opts,
+						   &new_branch_info, cb_option);
 		argv += n;
 		argc -= n;
 	} else if (!opts->accept_ref && opts->from_treeish) {
-- 
2.55.0-884-g76cf8659c2


  parent reply	other threads:[~2026-08-30 20:48 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-27 18:29 [PATCH] builtin: replace the_repository parameter in is_bare_repository() Hardik Kumar
2026-08-27 19:09 ` Junio C Hamano
2026-08-27 19:51   ` Junio C Hamano
2026-08-27 20:09     ` Hardik Kumar
2026-08-27 20:28       ` Junio C Hamano
2026-08-27 21:12         ` Ben Knoble
2026-08-27 21:39           ` Junio C Hamano
2026-08-28 11:41             ` D. Ben Knoble
2026-08-28 22:51               ` Junio C Hamano
2026-08-28 22:51                 ` [PATCH 0/8] More sensible checkout/switch/restore code refactoring Junio C Hamano
2026-08-28 22:51                   ` [PATCH 1/8] checkout: pass cb_option explicitly to branch name parsers Junio C Hamano
2026-08-28 22:52                   ` [PATCH 2/8] checkout: validate new branch name in checkout_branch() Junio C Hamano
2026-08-28 22:52                   ` [PATCH 3/8] checkout: validate stage and merge option compatibility in checkout_paths() Junio C Hamano
2026-08-28 22:52                   ` [PATCH 4/8] checkout: extract option validation and pathspec helpers Junio C Hamano
2026-08-28 22:52                   ` [PATCH 5/8] checkout: extract branch setup and tracking helpers Junio C Hamano
2026-08-28 22:52                   ` [PATCH 6/8] checkout: restructure switch, restore, and checkout entrypoints Junio C Hamano
2026-08-28 22:52                   ` [PATCH 7/8] checkout: wrap overly long lines Junio C Hamano
2026-08-28 22:55                     ` Junio C Hamano
2026-08-29  2:06                       ` Junio C Hamano
2026-08-28 22:52                   ` [PATCH 8/8] checkout: move post_checkout_hook() to checkout.c Junio C Hamano
2026-08-28 22:57                     ` Junio C Hamano
2026-08-29  2:05                       ` Junio C Hamano
2026-08-30 20:48                   ` [PATCH v2 0/8] More sensible checkout/switch/restore code refactoring Junio C Hamano
2026-08-30 20:48                     ` [PATCH v2 1/8] checkout: pass cb_option explicitly to branch name parsers Junio C Hamano
2026-08-30 20:48                     ` [PATCH v2 2/8] checkout: validate new branch name in checkout_branch() Junio C Hamano
2026-08-30 20:48                     ` [PATCH v2 3/8] checkout: validate stage and merge option compatibility in checkout_paths() Junio C Hamano
2026-08-30 20:48                     ` [PATCH v2 4/8] checkout: extract option validation and pathspec helpers Junio C Hamano
2026-08-30 20:48                     ` Junio C Hamano [this message]
2026-08-30 20:48                     ` [PATCH v2 6/8] checkout: restructure switch, restore, and checkout entrypoints Junio C Hamano
2026-08-30 20:48                     ` [PATCH v2 7/8] checkout: wrap overly long lines Junio C Hamano
2026-08-30 20:48                     ` [PATCH v2 8/8] checkout: move post_checkout_hook() to checkout.c Junio C Hamano
2026-08-29 13:24                 ` [PATCH] builtin: replace the_repository parameter in is_bare_repository() D. Ben Knoble
2026-08-27 21:35         ` [PATCH] do not pass "repo" to builtin commmand implementations Junio C Hamano
2026-08-28  9:05           ` Hardik Kumar
2026-08-28 20:59             ` Junio C Hamano
2026-08-28  4:01         ` [PATCH] builtin: replace the_repository parameter in is_bare_repository() Hardik Kumar
2026-08-27 19:56   ` Hardik Kumar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260830204835.1040408-6-gitster@pobox.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.