The <rev> argument in git reset --hard <rev> git reset --soft <rev> needs to be a commit to be sensible. But in git reset <rev> -- <path> <path> ... using other trees can be useful. For example, to apply changes from a branch that has the current branch merged as a subtree: git reset master:gitk-git -- . Signed-off-by: Jonathan Nieder <jrnieder@xxxxxxxxx> --- builtin/reset.c | 11 ++++++----- t/t7102-reset.sh | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/builtin/reset.c b/builtin/reset.c index a52e6f8..2375472 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -306,15 +306,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix) } if (get_sha1(rev, sha1)) die("Failed to resolve '%s' as a valid ref.", rev); - commit = lookup_commit_reference(sha1); - if (!commit) - die("Could not parse object '%s'.", rev); - hashcpy(sha1, commit->object.sha1); - /* git reset tree [--] paths... can be used to * load chosen paths from the tree into the index without * affecting the working tree nor HEAD. */ if (i < argc) { if (reset_type == MIXED) @@ -323,10 +318,16 @@ int cmd_reset(int argc, const char **argv, const char *prefix) die("Cannot do %s reset with paths.", reset_type_names[reset_type]); return read_from_tree(prefix, argv + i, sha1, quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN); } + + commit = lookup_commit_reference(sha1); + if (!commit) + die("Could not parse object '%s'.", rev); + hashcpy(sha1, commit->object.sha1); + if (reset_type == NONE) reset_type = MIXED; /* by default */ if (reset_type != SOFT && reset_type != MIXED) setup_work_tree(); diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh index b8cf260..3e95da3 100755 --- a/t/t7102-reset.sh +++ b/t/t7102-reset.sh @@ -7,10 +7,18 @@ test_description='git reset Documented tests for git reset' . ./test-lib.sh +test_exit_code () { + echo $1 >expect.code && + shift && + "$@" + echo $? >actual.code && + test_cmp expect.code actual.code +} + test_expect_success 'creating initial files and commits' ' test_tick && echo "1st file" >first && git add first && git commit -m "create 1st file" && @@ -409,17 +417,40 @@ test_expect_success 'test resetting the index at give paths' ' test_must_fail git diff-index --cached --exit-code "$T" && test "$T" != "$U" ' +test_expect_success 'reset modified path from tree' ' + echo hello >other && + git reset --hard && + git add other && + T=$(git write-tree) && + git rm -f other && + test_exit_code 1 git reset $T other && + git diff-index --cached --exit-code "$T" +' + +test_expect_success 'try to reset from blob' ' + git reset --hard && + B=$(git rev-parse --verify HEAD:file1) && + test_exit_code 128 git reset $B -- . +' + test_expect_success 'resetting an unmodified path is a no-op' ' git reset --hard && git reset -- file1 && git diff-files --exit-code && git diff-index --cached --exit-code HEAD ' +test_expect_success 'reset unmodified path from tree' ' + git reset --hard && + git reset HEAD^{tree} -- file1 && + git diff-files --exit-code && + git diff-index --cached --exit-code HEAD +' + cat > expect << EOF Unstaged changes after reset: M file2 EOF -- 1.7.2.3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html