diff --git a/builtin/reset.c b/builtin/reset.c
index 2375472..ff57764 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -234,12 +234,14 @@ static void die_if_unmerged_cache(int reset_type)
}
int cmd_reset(int argc, const char **argv, const char *prefix)
{
int i = 0, reset_type = NONE, update_ref_status = 0, quiet = 0;
+ int unborn_branch = 0;
int patch_mode = 0;
- const char *rev = "HEAD";
+ const char *implicit_HEAD = "HEAD";
+ const char *rev = implicit_HEAD;
unsigned char sha1[20], *orig = NULL, sha1_orig[20],
*old_orig = NULL, sha1_old_orig[20];
struct commit *commit;
char *reflog_action, msg[1024];
const struct option options[] = {@@ -303,11 +305,18 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
if (reset_type != NONE)
die("--patch is incompatible with --{hard,mixed,soft}");
return interactive_reset(rev, argv + i, prefix);
}
- if (get_sha1(rev, sha1))
+ if (rev == implicit_HEAD) {
+ /* We may be on a branch yet to be born. */
+ resolve_ref("HEAD", sha1, 0, NULL);
+ if (is_null_sha1(sha1)) {
+ unborn_branch = 1;
+ hashcpy(sha1, (const unsigned char *) EMPTY_TREE_SHA1_BIN);
+ }
+ } else if (get_sha1(rev, sha1))
die("Failed to resolve '%s' as a valid ref.", rev);
/* git reset tree [--] paths... can be used to
* load chosen paths from the tree into the index without
* affecting the working tree nor HEAD. */@@ -319,10 +328,12 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
reset_type_names[reset_type]);
return read_from_tree(prefix, argv + i, sha1,
quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
}
+ if (unborn_branch)
+ die("Failed to resolve 'HEAD' as a valid ref.");
commit = lookup_commit_reference(sha1);
if (!commit)
die("Could not parse object '%s'.", rev);
hashcpy(sha1, commit->object.sha1);
diff --git a/t/t7106-reset-unborn.sh b/t/t7106-reset-unborn.sh
new file mode 100755
index 0000000..7baaffd
--- /dev/null
+++ b/t/t7106-reset-unborn.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+test_description='git reset from a branch yet to be born'
+. ./test-lib.sh
+
+>empty
+
+index_is_empty () {
+ git ls-files >actual &&
+ test_cmp empty actual
+}
+
+test_expect_success 'reset to remove file' '
+ echo one >file &&
+ git add file &&
+ git reset file &&
+ index_is_empty
+'
+
+test_expect_success 'reset after rm to remove file' '
+ echo one >file &&
+ git add file &&
+ rm file &&
+ git reset -- file &&
+ index_is_empty
+'
+
+test_expect_success 'reset file that does not match index' '
+ echo one >file &&
+ git add file &&
+ echo two >file &&
+ git reset -- file &&
+ index_is_empty
+'
+
+test_expect_success 'reset absent file' '
+ git reset -- file &&
+ index_is_empty
+'
+
+test_expect_success 'reset HEAD <files> from unborn branch' '
+ test_must_fail git reset HEAD -- .
+'
+
+test_expect_success 'reset HEAD from unborn branch' '
+ test_must_fail git reset HEAD &&
+ test_must_fail git reset HEAD --
+'
+
+test_done--
1.7.2.3