@@ -884,20 +884,30 @@ static int parse_branchname_arg(int argc, const char **argv,
884884 *
885885 * everything after the '--' must be paths.
886886 *
887- * case 3: git checkout <something> [<paths> ]
887+ * case 3: git checkout <something> [-- ]
888888 *
889- * With no paths, if <something> is a commit, that is to
890- * switch to the branch or detach HEAD at it. As a special case,
891- * if <something> is A...B (missing A or B means HEAD but you can
892- * omit at most one side), and if there is a unique merge base
893- * between A and B, A...B names that merge base.
889+ * (a) If <something> is a commit, that is to
890+ * switch to the branch or detach HEAD at it. As a special case,
891+ * if <something> is A...B (missing A or B means HEAD but you can
892+ * omit at most one side), and if there is a unique merge base
893+ * between A and B, A...B names that merge base.
894894 *
895- * With no paths, if <something> is _not_ a commit, no -t nor -b
896- * was given, and there is a tracking branch whose name is
897- * <something> in one and only one remote, then this is a short-hand
898- * to fork local <something> from that remote-tracking branch.
895+ * (b) If <something> is _not_ a commit, either "--" is present
896+ * or <something> is not a path, no -t nor -b was given, and
897+ * and there is a tracking branch whose name is <something>
898+ * in one and only one remote, then this is a short-hand to
899+ * fork local <something> from that remote-tracking branch.
899900 *
900- * Otherwise <something> shall not be ambiguous.
901+ * (c) Otherwise, if "--" is present, treat it like case (1).
902+ *
903+ * (d) Otherwise :
904+ * - if it's a reference, treat it like case (1)
905+ * - else if it's a path, treat it like case (2)
906+ * - else: fail.
907+ *
908+ * case 4: git checkout <something> <paths>
909+ *
910+ * The first argument must not be ambiguous.
901911 * - If it's *only* a reference, treat it like case (1).
902912 * - If it's only a path, treat it like case (2).
903913 * - else: fail.
@@ -916,18 +926,40 @@ static int parse_branchname_arg(int argc, const char **argv,
916926 arg = "@{-1}" ;
917927
918928 if (get_sha1_mb (arg , rev )) {
919- if (has_dash_dash ) /* case (1) */
920- die (_ ("invalid reference: %s" ), arg );
921- if (dwim_new_local_branch_ok &&
922- !check_filename (NULL , arg ) &&
923- argc == 1 ) {
929+ /*
930+ * Either case (3) or (4), with <something> not being
931+ * a commit, or an attempt to use case (1) with an
932+ * invalid ref.
933+ *
934+ * It's likely an error, but we need to find out if
935+ * we should auto-create the branch, case (3).(b).
936+ */
937+ int recover_with_dwim = dwim_new_local_branch_ok ;
938+
939+ if (check_filename (NULL , arg ) && !has_dash_dash )
940+ recover_with_dwim = 0 ;
941+ /*
942+ * Accept "git checkout foo" and "git checkout foo --"
943+ * as candidates for dwim.
944+ */
945+ if (!(argc == 1 && !has_dash_dash ) &&
946+ !(argc == 2 && has_dash_dash ))
947+ recover_with_dwim = 0 ;
948+
949+ if (recover_with_dwim ) {
924950 const char * remote = unique_tracking_name (arg , rev );
925- if (!remote )
926- return argcount ;
927- * new_branch = arg ;
928- arg = remote ;
929- /* DWIMmed to create local branch */
930- } else {
951+ if (remote ) {
952+ * new_branch = arg ;
953+ arg = remote ;
954+ /* DWIMmed to create local branch, case (3).(b) */
955+ } else {
956+ recover_with_dwim = 0 ;
957+ }
958+ }
959+
960+ if (!recover_with_dwim ) {
961+ if (has_dash_dash )
962+ die (_ ("invalid reference: %s" ), arg );
931963 return argcount ;
932964 }
933965 }
@@ -957,7 +989,7 @@ static int parse_branchname_arg(int argc, const char **argv,
957989
958990 if (!* source_tree ) /* case (1): want a tree */
959991 die (_ ("reference is not a tree: %s" ), arg );
960- if (!has_dash_dash ) {/* case (3 -> 1) */
992+ if (!has_dash_dash ) {/* case (3).(d) -> ( 1) */
961993 /*
962994 * Do not complain the most common case
963995 * git checkout branch
0 commit comments