On Mon, Nov 12, 2018 at 7:44 AM Junio C Hamano <[email protected]> wrote:
>
> Nguyễn Thái Ngọc Duy <[email protected]> writes:
>
> > @@ -1079,9 +1079,15 @@ static int parse_branchname_arg(int argc, const char
> > **argv,
> > */
> > int recover_with_dwim = dwim_new_local_branch_ok;
> >
> > - if (!has_dash_dash &&
> > - (check_filename(opts->prefix, arg) || !no_wildcard(arg)))
> > - recover_with_dwim = 0;
> > + /*
> > + * If both refs/remotes/origin/master and the file
> > + * 'master'. Don't blindly go for 'master' file
> > + * because it's ambiguous. Leave it for the user to
> > + * decide.
> > + */
> > + int disambi_local_file = !has_dash_dash &&
> > + (check_filename(opts->prefix, arg) ||
> > !no_wildcard(arg));
>
> What you are computing on the right hand side is if the arg is
> ambiguous. And the code that looks at this variable does not
> disambiguate, but it just punts and makes it responsibility to the
> user (which is by the way the correct thing to do).
>
> When a file with exact name is in the working tree, we do not
> declare it is a pathspec and not a rev, as we may be allowed to dwim
> and create a rev with that name and at that point we'd be in an
> ambigous situation. If the arg _has_ wildcard, however, it is a
> strong sign that it *is* a pathspec, isn't it? It is iffy that a
> single variable that cannot be used to distinguish these two cases
> is introduced---one of these cases will be mishandled.
Is it that different between an exact path name and a pathspec?
Suppose it is a pathspec (with wildcards) that matches some paths, and
we happen to have the remote branch origin/<that-pathspec>, then it is
still ambiguous whether we should go create branch
"<that-pathspec>" or go check out the paths matched by the pathspec.
> Also how does the patch ensures that this new logic does not kick in
> for those who refuse to let the command dwim to create a new branch?
I would hope that it would be "--" to settle all disputes. But it
looks like "git checkout foo --" is explicitly a candidate for dwim.
We have a hidden option --no-guess to disable dwim. Maybe it's a good
idea to make that one visible. It's at least clearer than using "--"
even if "--" worked on this case.
>
> > /*
> > * Accept "git checkout foo" and "git checkout foo --"
> > * as candidates for dwim.
> > @@ -1094,6 +1100,9 @@ static int parse_branchname_arg(int argc, const char
> > **argv,
> > const char *remote = unique_tracking_name(arg, rev,
> >
> > dwim_remotes_matched);
> > if (remote) {
> > + if (disambi_local_file)
> > + die(_("'%s' could be both a local
> > file and a tracking branch.\n"
> > + "Please use -- to
> > disambiguate"), arg);
>
> Ah, the only user of this variable triggers when recover_with_dwim
> is true, so that is how dwim-less case is handled, OK.
>
> That still leaves the question if it is OK to handle these two cases
> the same way in a repository without 'next' branch whose origin has
> one:
>
> $ >next; git checkout --guess next
> $ >next; git checkout --guess 'n??t'
>
> Perhaps the variable should be named "local_file_crashes_with_rev"
> and its the scope narrowed to the same block as "remote" is
> computed. Or just remove the variable and check the condition right
> there where you need to. I.e.
>
> if (remote) {
> if (!has_dash_dash &&
> check_filename(opts->prefix, arg))
> die("did you mean a branch or path?: '%s'", arg);
> ...
>
I still think handing both cases the same way is right. In the second
case we would not find 'origin/n??t' so we fall back to checking out
pathspec 'n??t' anyway (expected from you, I think). But just in case
the remote branch 'origin/n??t' exists, we kick and scream.
I think you see 'n??t' as a pathspec, but I'm thinking about a user
who sees 'n??t' as a branch name, not pathspec and he would have a
different expectation.
--
Duy