X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=builtin%2Fcheckout.c;h=e79003f5bffc8806ea6cfd67f866c3ee4e2f5c7d;hb=dbdc07fcbe3a951df8a3869b42edb6fffd466486;hp=2a8077242500d54ac50d5829a86b14803fc69126;hpb=10dd3b2bf1444695416c0dac951297acf7d4e5e4;p=git.git diff --git a/builtin/checkout.c b/builtin/checkout.c index 2a8077242..e79003f5b 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -114,16 +114,21 @@ static int check_stage(int stage, struct cache_entry *ce, int pos) return error(_("path '%s' does not have their version"), ce->name); } -static int check_all_stages(struct cache_entry *ce, int pos) +static int check_stages(unsigned stages, struct cache_entry *ce, int pos) { - if (ce_stage(ce) != 1 || - active_nr <= pos + 2 || - strcmp(active_cache[pos+1]->name, ce->name) || - ce_stage(active_cache[pos+1]) != 2 || - strcmp(active_cache[pos+2]->name, ce->name) || - ce_stage(active_cache[pos+2]) != 3) - return error(_("path '%s' does not have all three versions"), - ce->name); + unsigned seen = 0; + const char *name = ce->name; + + while (pos < active_nr) { + ce = active_cache[pos]; + if (strcmp(name, ce->name)) + break; + seen |= (1 << ce_stage(ce)); + pos++; + } + if ((stages & seen) != stages) + return error(_("path '%s' does not have all necessary versions"), + name); return 0; } @@ -150,18 +155,27 @@ static int checkout_merged(int pos, struct checkout *state) int status; unsigned char sha1[20]; mmbuffer_t result_buf; + unsigned char threeway[3][20]; + unsigned mode = 0; + + memset(threeway, 0, sizeof(threeway)); + while (pos < active_nr) { + int stage; + stage = ce_stage(ce); + if (!stage || strcmp(path, ce->name)) + break; + hashcpy(threeway[stage - 1], ce->sha1); + if (stage == 2) + mode = create_ce_mode(ce->ce_mode); + pos++; + ce = active_cache[pos]; + } + if (is_null_sha1(threeway[1]) || is_null_sha1(threeway[2])) + return error(_("path '%s' does not have necessary versions"), path); - if (ce_stage(ce) != 1 || - active_nr <= pos + 2 || - strcmp(active_cache[pos+1]->name, path) || - ce_stage(active_cache[pos+1]) != 2 || - strcmp(active_cache[pos+2]->name, path) || - ce_stage(active_cache[pos+2]) != 3) - return error(_("path '%s' does not have all 3 versions"), path); - - read_mmblob(&ancestor, active_cache[pos]->sha1); - read_mmblob(&ours, active_cache[pos+1]->sha1); - read_mmblob(&theirs, active_cache[pos+2]->sha1); + read_mmblob(&ancestor, threeway[0]); + read_mmblob(&ours, threeway[1]); + read_mmblob(&theirs, threeway[2]); /* * NEEDSWORK: re-create conflicts from merges with @@ -192,9 +206,7 @@ static int checkout_merged(int pos, struct checkout *state) if (write_sha1_file(result_buf.ptr, result_buf.size, blob_type, sha1)) die(_("Unable to add merge result for '%s'"), path); - ce = make_cache_entry(create_ce_mode(active_cache[pos+1]->ce_mode), - sha1, - path, 2, 0); + ce = make_cache_entry(mode, sha1, path, 2, 0); if (!ce) die(_("make_cache_entry failed for path '%s'"), path); status = checkout_entry(ce, state, NULL); @@ -252,7 +264,7 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec, } else if (stage) { errs |= check_stage(stage, ce, pos); } else if (opts->merge) { - errs |= check_all_stages(ce, pos); + errs |= check_stages((1<<2) | (1<<3), ce, pos); } else { errs = 1; error(_("path '%s' is unmerged"), ce->name); @@ -411,7 +423,7 @@ static int merge_working_tree(struct checkout_opts *opts, topts.fn = twoway_merge; topts.dir = xcalloc(1, sizeof(*topts.dir)); topts.dir->flags |= DIR_SHOW_IGNORED; - topts.dir->exclude_per_dir = ".gitignore"; + setup_standard_excludes(topts.dir); tree = parse_tree_indirect(old->commit ? old->commit->object.sha1 : EMPTY_TREE_SHA1_BIN); @@ -540,7 +552,9 @@ static void update_refs_for_switch(struct checkout_opts *opts, else create_branch(old->name, opts->new_branch, new->name, opts->new_branch_force ? 1 : 0, - opts->new_branch_log, opts->track); + opts->new_branch_log, + opts->new_branch_force ? 1 : 0, + opts->track); new->name = opts->new_branch; setup_branch_path(new); } @@ -565,8 +579,12 @@ static void update_refs_for_switch(struct checkout_opts *opts, create_symref("HEAD", new->path, msg.buf); if (!opts->quiet) { if (old->path && !strcmp(new->path, old->path)) { - fprintf(stderr, _("Already on '%s'\n"), - new->name); + if (opts->new_branch_force) + fprintf(stderr, _("Reset branch '%s'\n"), + new->name); + else + fprintf(stderr, _("Already on '%s'\n"), + new->name); } else if (opts->new_branch) { if (opts->branch_exists) fprintf(stderr, _("Switched to and reset branch '%s'\n"), new->name); @@ -1057,7 +1075,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) struct strbuf buf = STRBUF_INIT; opts.branch_exists = validate_new_branchname(opts.new_branch, &buf, - !!opts.new_branch_force, 0); + !!opts.new_branch_force, + !!opts.new_branch_force); strbuf_release(&buf); }