From: "Alexandr Miloslavskiy via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>,
Junio C Hamano <gitster@pobox.com>,
Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>
Subject: [PATCH 4/5] parse_branchname_arg(): refactor the decision making
Date: Thu, 28 Nov 2019 19:32:17 +0000 [thread overview]
Message-ID: <45db345304d5771017026a32d96251c5c5c47f11.1574969538.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.479.git.1574969538.gitgitgadget@gmail.com>
From: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>
Make it easier to understand which branches handle which cases.
Drop obfuscated variable `has_dash_dash` which also took
`opts->accept_pathspec` into account, making it pretty hard to reason
about code, especially when used together with `argc` and
`opts->accept_pathspec` here:
if (!(argc == 1 && !has_dash_dash) &&
!(argc == 2 && has_dash_dash) &&
opts->accept_pathspec)
recover_with_dwim = 0;
Avoid double-negation in the code mentioned above ("it is not OK to
proceed if it's not one of those cases").
Avoid hard-to-understand condition `opts->accept_pathspec` in the code
mentioned above.
There are some minor die() message changes for:
`git switch <commit> <unexpected>`
`git switch <commit> -- <unexpected>`
Signed-off-by: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>
---
builtin/checkout.c | 71 +++++++++++++++++++++++++++-------------------
1 file changed, 42 insertions(+), 29 deletions(-)
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 723aaca0ef..8f679d1b6a 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -1122,9 +1122,8 @@ static int parse_branchname_arg(int argc, const char **argv,
{
const char **new_branch = &opts->new_branch;
const char *arg;
- int dash_dash_pos;
- int has_dash_dash = 0, expect_commit_only = 0;
- int i;
+ int dash_dash_pos, i;
+ int recover_with_dwim, expect_commit_only;
/*
* Resolve ambiguity where argv[0] may be <pathspec> or <commit>.
@@ -1143,15 +1142,7 @@ static int parse_branchname_arg(int argc, const char **argv,
* do that and proceed with (2)(3).
* 5) Otherwise, let caller proceed with <pathspec> interpretation.
*/
- if (!argc)
- return 0;
-
- if (!opts->accept_pathspec) {
- if (argc > 1)
- die(_("only one reference expected"));
- has_dash_dash = 1; /* helps disambiguate */
- }
-
+
arg = argv[0];
dash_dash_pos = -1;
for (i = 0; i < argc; i++) {
@@ -1161,17 +1152,46 @@ static int parse_branchname_arg(int argc, const char **argv,
}
}
- if (opts->accept_pathspec) {
- if (dash_dash_pos == 0)
- return 1;
- else if (dash_dash_pos == 1)
- has_dash_dash = 1;
- else if (dash_dash_pos >= 2)
- die(_("only one reference expected, %d given."), dash_dash_pos);
- }
+ if (dash_dash_pos == -1) {
+ if (argc == 0) {
+ /* 'git checkout/switch/restore' */
+ return 0;
+ } else if (argc == 1) {
+ /* 'git checkout/switch/restore <something>' */
+ recover_with_dwim = dwim_new_local_branch_ok;
+ } else if (!opts->accept_pathspec) {
+ /* 'git switch <commit> <unexpected> [...]' */
+ die(_("only one reference expected, %d given."), argc);
+ } else {
+ /* 'git checkout/restore <something> <pathspec> [...]' */
+ recover_with_dwim = 0;
+ }
+
+ /* Absence of '--' leaves <pathspec>/<commit> ambiguity */
+ expect_commit_only = !opts->accept_pathspec;
+ } else if (dash_dash_pos == 0) {
+ /* 'git checkout/switch/restore -- [...]' */
+ return 1; /* Eat '--' */
+ } else if (dash_dash_pos == 1) {
+ if (!opts->accept_pathspec) {
+ /* 'git switch <commit> -- [...]' */
+ die(_("incompatible with pathspec arguments"));
+ }
- if (has_dash_dash)
- expect_commit_only = 1;
+ if (argc == 2) {
+ /* 'git checkout/restore <commit> --' */
+ recover_with_dwim = dwim_new_local_branch_ok;
+ } else {
+ /* 'git checkout/restore <commit> -- <pathspec> [...]' */
+ recover_with_dwim = 0;
+ }
+
+ /* Presence of '--' makes it certain that arg is <commit> */
+ expect_commit_only = 1;
+ } else {
+ /* 'git checkout/switch/restore <commit> <unxpected> [...] -- [...]' */
+ die(_("only one reference expected, %d given."), dash_dash_pos);
+ }
opts->count_checkout_paths = !opts->quiet && !expect_commit_only;
@@ -1179,19 +1199,12 @@ static int parse_branchname_arg(int argc, const char **argv,
arg = "@{-1}";
if (get_oid_mb(arg, rev)) {
- int recover_with_dwim = dwim_new_local_branch_ok;
-
int could_be_checkout_paths = !expect_commit_only &&
check_filename(opts->prefix, arg);
if (!expect_commit_only && !no_wildcard(arg))
recover_with_dwim = 0;
- if (!(argc == 1 && !has_dash_dash) &&
- !(argc == 2 && has_dash_dash) &&
- opts->accept_pathspec)
- recover_with_dwim = 0;
-
if (recover_with_dwim) {
const char *remote = unique_tracking_name(arg, rev,
dwim_remotes_matched);
--
gitgitgadget
next prev parent reply other threads:[~2019-11-28 19:32 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-28 19:32 [PATCH 0/5] parse_branchname_arg(): make code easier to understand Alexandr Miloslavskiy via GitGitGadget
2019-11-28 19:32 ` [PATCH 1/5] parse_branchname_arg(): fix dash_dash_pos, drop argcount Alexandr Miloslavskiy via GitGitGadget
2019-12-18 18:52 ` Junio C Hamano
2019-12-19 18:03 ` Alexandr Miloslavskiy
2019-11-28 19:32 ` [PATCH 2/5] parse_branchname_arg(): introduce expect_commit_only Alexandr Miloslavskiy via GitGitGadget
2019-12-18 19:18 ` Junio C Hamano
2019-12-19 18:03 ` Alexandr Miloslavskiy
2019-11-28 19:32 ` [PATCH 3/5] parse_branchname_arg(): update code comments Alexandr Miloslavskiy via GitGitGadget
2019-11-28 19:32 ` Alexandr Miloslavskiy via GitGitGadget [this message]
2019-11-28 19:32 ` [PATCH 5/5] t2024: cover more cases Alexandr Miloslavskiy via GitGitGadget
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
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=45db345304d5771017026a32d96251c5c5c47f11.1574969538.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=alexandr.miloslavskiy@syntevo.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/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.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).