#include "builtin.h"
+#include "config.h"
#include "lockfile.h"
#include "parse-options.h"
#include "refs.h"
#include "submodule-config.h"
#include "submodule.h"
-static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
-
static const char * const checkout_usage[] = {
N_("git checkout [<options>] <branch>"),
N_("git checkout [<options>] [<branch>] -- <file>..."),
NULL,
};
-static int option_parse_recurse_submodules(const struct option *opt,
- const char *arg, int unset)
-{
- if (unset) {
- recurse_submodules = RECURSE_SUBMODULES_OFF;
- return 0;
- }
- if (arg)
- recurse_submodules =
- parse_update_recurse_submodules_arg(opt->long_name,
- arg);
- else
- recurse_submodules = RECURSE_SUBMODULES_ON;
-
- return 0;
-}
-
struct checkout_opts {
int patch_mode;
int quiet;
state.force = 1;
state.refresh_cache = 1;
state.istate = &the_index;
+
+ enable_delayed_checkout(&state);
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
if (ce->ce_flags & CE_MATCHED) {
pos = skip_same_name(ce, pos) - 1;
}
}
+ errs |= finish_delayed_checkout(&state);
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
die(_("unable to write new index file"));
- read_ref_full("HEAD", 0, rev.hash, NULL);
- head = lookup_commit_reference_gently(rev.hash, 1);
+ read_ref_full("HEAD", 0, &rev, NULL);
+ head = lookup_commit_reference_gently(&rev, 1);
errs |= post_checkout_hook(head, head, 0);
return errs;
* update paths in the work tree, and we cannot revert
* them.
*/
+ /* fallthrough */
case 0:
return 0;
default:
setup_standard_excludes(topts.dir);
}
tree = parse_tree_indirect(old->commit ?
- old->commit->object.oid.hash :
- EMPTY_TREE_SHA1_BIN);
+ &old->commit->object.oid :
+ &empty_tree_oid);
init_tree_desc(&trees[0], tree->buffer, tree->size);
- tree = parse_tree_indirect(new->commit->object.oid.hash);
+ tree = parse_tree_indirect(&new->commit->object.oid);
init_tree_desc(&trees[1], tree->buffer, tree->size);
ret = unpack_trees(2, trees, &topts);
if (!strcmp(new->name, "HEAD") && !new->path && !opts->force_detach) {
/* Nothing to do. */
} else if (opts->force_detach || !new->path) { /* No longer on any branch. */
- update_ref(msg.buf, "HEAD", new->commit->object.oid.hash, NULL,
+ update_ref(msg.buf, "HEAD", &new->commit->object.oid, NULL,
REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
if (!opts->quiet) {
if (old->path &&
const struct object_id *oid,
int flags, void *cb_data)
{
- add_pending_sha1(cb_data, refname, oid->hash, UNINTERESTING);
+ add_pending_oid(cb_data, refname, oid, UNINTERESTING);
return 0;
}
add_pending_object(&revs, object, oid_to_hex(&object->oid));
for_each_ref(add_pending_uninteresting_ref, &revs);
- add_pending_sha1(&revs, "HEAD", new->object.oid.hash, UNINTERESTING);
+ add_pending_oid(&revs, "HEAD", &new->object.oid, UNINTERESTING);
+ /* Save pending objects, so they can be cleaned up later. */
refs = revs.pending;
revs.leak_pending = 1;
+ /*
+ * prepare_revision_walk (together with .leak_pending = 1) makes us
+ * the sole owner of the list of pending objects.
+ */
if (prepare_revision_walk(&revs))
die(_("internal error in revision walk"));
if (!(old->object.flags & UNINTERESTING))
else
describe_detached_head(_("Previous HEAD position was"), old);
+ /* Clean up objects used, as they will be reused. */
clear_commit_marks_for_object_array(&refs, ALL_REV_FLAGS);
- free(refs.objects);
+
+ object_array_clear(&refs);
}
static int switch_branches(const struct checkout_opts *opts,
struct object_id rev;
int flag, writeout_error = 0;
memset(&old, 0, sizeof(old));
- old.path = path_to_free = resolve_refdup("HEAD", 0, rev.hash, &flag);
+ old.path = path_to_free = resolve_refdup("HEAD", 0, &rev, &flag);
if (old.path)
- old.commit = lookup_commit_reference_gently(rev.hash, 1);
+ old.commit = lookup_commit_reference_gently(&rev, 1);
if (!(flag & REF_ISSYMREF))
old.path = NULL;
}
if (starts_with(var, "submodule."))
- return parse_submodule_config_option(var, value);
+ return git_default_submodule_config(var, value, NULL);
return git_xmerge_config(var, value, NULL);
}
setup_branch_path(new);
if (!check_refname_format(new->path, 0) &&
- !read_ref(new->path, branch_rev.hash))
+ !read_ref(new->path, &branch_rev))
oidcpy(rev, &branch_rev);
else
new->path = NULL; /* not an existing branch */
- new->commit = lookup_commit_reference_gently(rev->hash, 1);
+ new->commit = lookup_commit_reference_gently(rev, 1);
if (!new->commit) {
/* not a commit */
- *source_tree = parse_tree_indirect(rev->hash);
+ *source_tree = parse_tree_indirect(rev);
} else {
parse_commit_or_die(new->commit);
*source_tree = new->commit->tree;
if (new->path && !opts->force_detach && !opts->new_branch &&
!opts->ignore_other_worktrees) {
- struct object_id oid;
int flag;
- char *head_ref = resolve_refdup("HEAD", 0, oid.hash, &flag);
+ char *head_ref = resolve_refdup("HEAD", 0, NULL, &flag);
if (head_ref &&
(!(flag & REF_ISSYMREF) || strcmp(head_ref, new->path)))
die_if_checked_out(new->path, 1);
struct object_id rev;
int flag;
- if (!read_ref_full("HEAD", 0, rev.hash, &flag) &&
+ if (!read_ref_full("HEAD", 0, &rev, &flag) &&
(flag & REF_ISSYMREF) && is_null_oid(&rev))
return switch_unborn_to_new_branch(opts);
}
N_("second guess 'git checkout <no-such-branch>'")),
OPT_BOOL(0, "ignore-other-worktrees", &opts.ignore_other_worktrees,
N_("do not check if another worktree is holding the given ref")),
- { OPTION_CALLBACK, 0, "recurse-submodules", &recurse_submodules,
+ { OPTION_CALLBACK, 0, "recurse-submodules", NULL,
"checkout", "control recursive updating of submodules",
- PARSE_OPT_OPTARG, option_parse_recurse_submodules },
+ PARSE_OPT_OPTARG, option_parse_recurse_submodules_worktree_updater },
OPT_BOOL(0, "progress", &opts.show_progress, N_("force progress reporting")),
OPT_END(),
};
opts.prefix = prefix;
opts.show_progress = -1;
- gitmodules_config();
git_config(git_checkout_config, &opts);
opts.track = BRANCH_TRACK_UNSPECIFIED;
git_xmerge_config("merge.conflictstyle", conflict_style, NULL);
}
- if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
- git_config(submodule_config, NULL);
- if (recurse_submodules != RECURSE_SUBMODULES_DEFAULT)
- set_config_update_recurse_submodules(recurse_submodules);
- }
-
if ((!!opts.new_branch + !!opts.new_branch_force + !!opts.new_orphan_branch) > 1)
die(_("-b, -B and --orphan are mutually exclusive"));
strbuf_release(&buf);
}
+ UNLEAK(opts);
if (opts.patch_mode || opts.pathspec.nr)
return checkout_paths(&opts, new.name);
else