diff options
Diffstat (limited to 'builtin/reset.c')
-rw-r--r-- | builtin/reset.c | 79 |
1 files changed, 47 insertions, 32 deletions
diff --git a/builtin/reset.c b/builtin/reset.c index 9400acce07..7aeaea2737 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -8,6 +8,7 @@ * Copyright (c) 2005, 2006 Linus Torvalds and Junio C Hamano */ #include "builtin.h" +#include "config.h" #include "lockfile.h" #include "tag.h" #include "object.h" @@ -21,6 +22,8 @@ #include "parse-options.h" #include "unpack-trees.h" #include "cache-tree.h" +#include "submodule.h" +#include "submodule-config.h" static const char * const git_reset_usage[] = { N_("git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"), @@ -39,7 +42,7 @@ static inline int is_merge(void) return !access(git_path_merge_head(), F_OK); } -static int reset_index(const unsigned char *sha1, int reset_type, int quiet) +static int reset_index(const struct object_id *oid, int reset_type, int quiet) { int nr = 1; struct tree_desc desc[2]; @@ -69,22 +72,22 @@ static int reset_index(const unsigned char *sha1, int reset_type, int quiet) read_cache_unmerged(); if (reset_type == KEEP) { - unsigned char head_sha1[20]; - if (get_sha1("HEAD", head_sha1)) + struct object_id head_oid; + if (get_oid("HEAD", &head_oid)) return error(_("You do not have a valid HEAD.")); - if (!fill_tree_descriptor(desc, head_sha1)) + if (!fill_tree_descriptor(desc, head_oid.hash)) return error(_("Failed to find tree of HEAD.")); nr++; opts.fn = twoway_merge; } - if (!fill_tree_descriptor(desc + nr - 1, sha1)) - return error(_("Failed to find tree of %s."), sha1_to_hex(sha1)); + if (!fill_tree_descriptor(desc + nr - 1, oid->hash)) + return error(_("Failed to find tree of %s."), oid_to_hex(oid)); if (unpack_trees(nr, desc, &opts)) return -1; if (reset_type == MIXED || reset_type == HARD) { - tree = parse_tree_indirect(sha1); + tree = parse_tree_indirect(oid); prime_cache_tree(&the_index, tree); } @@ -143,7 +146,7 @@ static void update_index_from_diff(struct diff_queue_struct *q, } static int read_from_tree(const struct pathspec *pathspec, - unsigned char *tree_sha1, + struct object_id *tree_oid, int intent_to_add) { struct diff_options opt; @@ -154,7 +157,7 @@ static int read_from_tree(const struct pathspec *pathspec, opt.format_callback = update_index_from_diff; opt.format_callback_data = &intent_to_add; - if (do_diff_cache(tree_sha1, &opt)) + if (do_diff_cache(tree_oid, &opt)) return 1; diffcore_std(&opt); diff_flush(&opt); @@ -191,7 +194,7 @@ static void parse_args(struct pathspec *pathspec, const char **rev_ret) { const char *rev = "HEAD"; - unsigned char unused[20]; + struct object_id unused; /* * Possible arguments are: * @@ -216,8 +219,8 @@ static void parse_args(struct pathspec *pathspec, * has to be unambiguous. If there is a single argument, it * can not be a tree */ - else if ((!argv[1] && !get_sha1_committish(argv[0], unused)) || - (argv[1] && !get_sha1_treeish(argv[0], unused))) { + else if ((!argv[1] && !get_sha1_committish(argv[0], unused.hash)) || + (argv[1] && !get_sha1_treeish(argv[0], unused.hash))) { /* * Ok, argv[0] looks like a commit/tree; it should not * be a filename. @@ -236,34 +239,41 @@ static void parse_args(struct pathspec *pathspec, parse_pathspec(pathspec, 0, PATHSPEC_PREFER_FULL | - PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP | (patch_mode ? PATHSPEC_PREFIX_ORIGIN : 0), prefix, argv); } -static int reset_refs(const char *rev, const unsigned char *sha1) +static int reset_refs(const char *rev, const struct object_id *oid) { int update_ref_status; struct strbuf msg = STRBUF_INIT; - unsigned char *orig = NULL, sha1_orig[20], - *old_orig = NULL, sha1_old_orig[20]; + struct object_id *orig = NULL, oid_orig, + *old_orig = NULL, oid_old_orig; - if (!get_sha1("ORIG_HEAD", sha1_old_orig)) - old_orig = sha1_old_orig; - if (!get_sha1("HEAD", sha1_orig)) { - orig = sha1_orig; + if (!get_oid("ORIG_HEAD", &oid_old_orig)) + old_orig = &oid_old_orig; + if (!get_oid("HEAD", &oid_orig)) { + orig = &oid_orig; set_reflog_message(&msg, "updating ORIG_HEAD", NULL); - update_ref(msg.buf, "ORIG_HEAD", orig, old_orig, 0, + update_ref_oid(msg.buf, "ORIG_HEAD", orig, old_orig, 0, UPDATE_REFS_MSG_ON_ERR); } else if (old_orig) - delete_ref("ORIG_HEAD", old_orig, 0); + delete_ref(NULL, "ORIG_HEAD", old_orig->hash, 0); set_reflog_message(&msg, "updating HEAD", rev); - update_ref_status = update_ref(msg.buf, "HEAD", sha1, orig, 0, + update_ref_status = update_ref_oid(msg.buf, "HEAD", oid, orig, 0, UPDATE_REFS_MSG_ON_ERR); strbuf_release(&msg); return update_ref_status; } +static int git_reset_config(const char *var, const char *value, void *cb) +{ + if (!strcmp(var, "submodule.recurse")) + return git_default_submodule_config(var, value, cb); + + return git_default_config(var, value, cb); +} + int cmd_reset(int argc, const char **argv, const char *prefix) { int reset_type = NONE, update_ref_status = 0, quiet = 0; @@ -283,18 +293,23 @@ int cmd_reset(int argc, const char **argv, const char *prefix) N_("reset HEAD, index and working tree"), MERGE), OPT_SET_INT(0, "keep", &reset_type, N_("reset HEAD but keep local changes"), KEEP), + { OPTION_CALLBACK, 0, "recurse-submodules", NULL, + "reset", "control recursive updating of submodules", + PARSE_OPT_OPTARG, option_parse_recurse_submodules_worktree_updater }, OPT_BOOL('p', "patch", &patch_mode, N_("select hunks interactively")), OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that removed paths will be added later")), OPT_END() }; - git_config(git_default_config, NULL); + git_config(git_reset_config, NULL); argc = parse_options(argc, argv, prefix, options, git_reset_usage, PARSE_OPT_KEEP_DASHDASH); parse_args(&pathspec, argv, prefix, patch_mode, &rev); + load_submodule_cache(); + unborn = !strcmp(rev, "HEAD") && get_sha1("HEAD", oid.hash); if (unborn) { /* reset on unborn branch: treat as reset to empty tree */ @@ -303,7 +318,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) struct commit *commit; if (get_sha1_committish(rev, oid.hash)) die(_("Failed to resolve '%s' as a valid revision."), rev); - commit = lookup_commit_reference(oid.hash); + commit = lookup_commit_reference(&oid); if (!commit) die(_("Could not parse object '%s'."), rev); oidcpy(&oid, &commit->object.oid); @@ -311,7 +326,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) struct tree *tree; if (get_sha1_treeish(rev, oid.hash)) die(_("Failed to resolve '%s' as a valid tree."), rev); - tree = parse_tree_indirect(oid.hash); + tree = parse_tree_indirect(&oid); if (!tree) die(_("Could not parse object '%s'."), rev); oidcpy(&oid, &tree->object.oid); @@ -354,18 +369,18 @@ int cmd_reset(int argc, const char **argv, const char *prefix) if (reset_type != SOFT) { struct lock_file *lock = xcalloc(1, sizeof(*lock)); - hold_locked_index(lock, 1); + hold_locked_index(lock, LOCK_DIE_ON_ERROR); if (reset_type == MIXED) { int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN; - if (read_from_tree(&pathspec, oid.hash, intent_to_add)) + if (read_from_tree(&pathspec, &oid, intent_to_add)) return 1; if (get_git_work_tree()) refresh_index(&the_index, flags, NULL, NULL, _("Unstaged changes after reset:")); } else { - int err = reset_index(oid.hash, reset_type, quiet); + int err = reset_index(&oid, reset_type, quiet); if (reset_type == KEEP && !err) - err = reset_index(oid.hash, MIXED, quiet); + err = reset_index(&oid, MIXED, quiet); if (err) die(_("Could not reset index file to revision '%s'."), rev); } @@ -377,10 +392,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix) if (!pathspec.nr && !unborn) { /* Any resets without paths update HEAD to the head being * switched to, saving the previous head in ORIG_HEAD before. */ - update_ref_status = reset_refs(rev, oid.hash); + update_ref_status = reset_refs(rev, &oid); if (reset_type == HARD && !update_ref_status && !quiet) - print_new_head_line(lookup_commit_reference(oid.hash)); + print_new_head_line(lookup_commit_reference(&oid)); } if (!pathspec.nr) remove_branch_state(); |