tests: introduce test_must_fail
[gitweb.git] / builtin-checkout.c
index e89b8f8ee0114deda761b66848c17be301f8e287..9579ff4ab12dfc1c48d6e530a93d0d18e07c2ebb 100644 (file)
@@ -186,7 +186,7 @@ struct checkout_opts {
 
        char *new_branch;
        int new_branch_log;
-       int track;
+       enum branch_track track;
 };
 
 struct branch_info {
@@ -226,23 +226,25 @@ static int merge_working_tree(struct checkout_opts *opts,
                refresh_cache(REFRESH_QUIET);
 
                if (unmerged_cache()) {
-                       ret = opts->merge ? -1 :
-                               error("you need to resolve your current index first");
-               } else {
-                       topts.update = 1;
-                       topts.merge = 1;
-                       topts.gently = opts->merge;
-                       topts.fn = twoway_merge;
-                       topts.dir = xcalloc(1, sizeof(*topts.dir));
-                       topts.dir->show_ignored = 1;
-                       topts.dir->exclude_per_dir = ".gitignore";
-                       tree = parse_tree_indirect(old->commit->object.sha1);
-                       init_tree_desc(&trees[0], tree->buffer, tree->size);
-                       tree = parse_tree_indirect(new->commit->object.sha1);
-                       init_tree_desc(&trees[1], tree->buffer, tree->size);
-                       ret = unpack_trees(2, trees, &topts);
+                       error("you need to resolve your current index first");
+                       return 1;
                }
-               if (ret) {
+
+               /* 2-way merge to the new branch */
+               topts.update = 1;
+               topts.merge = 1;
+               topts.gently = opts->merge;
+               topts.verbose_update = !opts->quiet;
+               topts.fn = twoway_merge;
+               topts.dir = xcalloc(1, sizeof(*topts.dir));
+               topts.dir->show_ignored = 1;
+               topts.dir->exclude_per_dir = ".gitignore";
+               tree = parse_tree_indirect(old->commit->object.sha1);
+               init_tree_desc(&trees[0], tree->buffer, tree->size);
+               tree = parse_tree_indirect(new->commit->object.sha1);
+               init_tree_desc(&trees[1], tree->buffer, tree->size);
+
+               if (unpack_trees(2, trees, &topts)) {
                        /*
                         * Unpack couldn't do a trivial merge; either
                         * give up or do a real merge, depending on
@@ -289,7 +291,7 @@ static int merge_working_tree(struct checkout_opts *opts,
        return 0;
 }
 
-static void adjust_to_tracking(struct branch_info *new, struct checkout_opts *opts)
+static void report_tracking(struct branch_info *new, struct checkout_opts *opts)
 {
        /*
         * We have switched to a new branch; is it building on
@@ -305,13 +307,13 @@ static void adjust_to_tracking(struct branch_info *new, struct checkout_opts *op
        int rev_argc;
        int num_ours, num_theirs;
        const char *remote_msg;
-       struct branch *branch = branch_get(NULL);
+       struct branch *branch = branch_get(new->name);
 
        /*
         * Nothing to report unless we are marked to build on top of
         * somebody else.
         */
-       if (!branch || !branch->merge)
+       if (!branch || !branch->merge || !branch->merge[0] || !branch->merge[0]->dst)
                return;
 
        /*
@@ -369,7 +371,7 @@ static void adjust_to_tracking(struct branch_info *new, struct checkout_opts *op
                       remote_msg, base,
                       num_ours, (num_ours == 1) ? "" : "s");
        else if (!num_ours)
-               printf("Your branch is behind of the tracked%s branch '%s' "
+               printf("Your branch is behind the tracked%s branch '%s' "
                       "by %d commit%s,\n"
                       "and can be fast-forwarded.\n",
                       remote_msg, base,
@@ -425,7 +427,7 @@ static void update_refs_for_switch(struct checkout_opts *opts,
        remove_branch_state();
        strbuf_release(&msg);
        if (!opts->quiet && (new->path || !strcmp(new->name, "HEAD")))
-               adjust_to_tracking(new, opts);
+               report_tracking(new, opts);
 }
 
 static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
@@ -478,13 +480,8 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
        return post_checkout_hook(old.commit, new->commit, 1);
 }
 
-static int branch_track = 0;
-
 static int git_checkout_config(const char *var, const char *value)
 {
-       if (!strcmp(var, "branch.autosetupmerge"))
-               branch_track = git_config_bool(var, value);
-
        return git_default_config(var, value);
 }
 
@@ -499,7 +496,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
                OPT__QUIET(&opts.quiet),
                OPT_STRING('b', NULL, &opts.new_branch, "new branch", "branch"),
                OPT_BOOLEAN('l', NULL, &opts.new_branch_log, "log for new branch"),
-               OPT_BOOLEAN( 0 , "track", &opts.track, "track"),
+               OPT_SET_INT( 0 , "track",  &opts.track, "track",
+                       BRANCH_TRACK_EXPLICIT),
                OPT_BOOLEAN('f', NULL, &opts.force, "force"),
                OPT_BOOLEAN('m', NULL, &opts.merge, "merge"),
                OPT_END(),
@@ -510,7 +508,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 
        git_config(git_checkout_config);
 
-       opts.track = branch_track;
+       opts.track = git_branch_track;
 
        argc = parse_options(argc, argv, options, checkout_usage, 0);
        if (argc) {
@@ -539,7 +537,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
                argc--;
        }
 
-       if (!opts.new_branch && (opts.track != branch_track))
+       if (!opts.new_branch && (opts.track != git_branch_track))
                die("git checkout: --track and --no-track require -b");
 
        if (opts.force && opts.merge)
@@ -547,6 +545,10 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 
        if (argc) {
                const char **pathspec = get_pathspec(prefix, argv);
+
+               if (!pathspec)
+                       die("invalid path specification");
+
                /* Checkout paths */
                if (opts.new_branch || opts.force || opts.merge) {
                        if (argc == 1) {