Commit Diff


commit - bfce7f836563143b27bfa24b645f65198c0298f8
commit + a9fa2909b9b3f681373c249f42a233d89335fc4c
blob - 59a5e820c09d0781286104cfdf959335e2b09099
blob + 4f7c0c9163165aa66b3dd1e012f624ba40726cff
--- lib/worktree.c
+++ lib/worktree.c
@@ -2643,31 +2643,34 @@ revert_file(struct got_worktree *worktree, struct got_
 				goto done;
 			}
 		}
-	}
-
-	err = got_object_id_by_path(&tree_id, repo, worktree->base_commit_id,
-	    tree_path);
-	if (err)
-		goto done;
-
-	err = got_object_open_as_tree(&tree, repo, tree_id);
-	if (err)
-		goto done;
-
-	te_name = basename(ie->path);
-	if (te_name == NULL) {
-		err = got_error_from_errno2("basename", ie->path);
-		goto done;
 	}
 
 	err = get_file_status(&status, &sb, ie, ondisk_path, repo);
 	if (err)
 		goto done;
 
-	te = got_object_tree_find_entry(tree, te_name);
-	if (te == NULL && status != GOT_STATUS_ADD) {
-		err = got_error(GOT_ERR_NO_TREE_ENTRY);
-		goto done;
+	err = got_object_id_by_path(&tree_id, repo, worktree->base_commit_id,
+	    tree_path);
+	if (err) {
+		if (!(err->code == GOT_ERR_NO_TREE_ENTRY &&
+		    status == GOT_STATUS_ADD))
+			goto done;
+	} else {
+		err = got_object_open_as_tree(&tree, repo, tree_id);
+		if (err)
+			goto done;
+
+		te_name = basename(ie->path);
+		if (te_name == NULL) {
+			err = got_error_from_errno2("basename", ie->path);
+			goto done;
+		}
+
+		te = got_object_tree_find_entry(tree, te_name);
+		if (te == NULL && status != GOT_STATUS_ADD) {
+			err = got_error(GOT_ERR_NO_TREE_ENTRY);
+			goto done;
+		}
 	}
 
 	switch (status) {
blob - da716a3db5a59725b149f466b4ee42fbe4b82d12
blob + 727c09da472e4766f3af6666d38bfef4fa9d78d8
--- regress/cmdline/add.sh
+++ regress/cmdline/add.sh
@@ -96,6 +96,31 @@ function test_add_multiple {
 	test_done "$testroot" "$ret"
 }
 
+function test_add_file_in_new_subdir {
+	local testroot=`test_init add_file_in_new_subdir`
+
+	got checkout $testroot/repo $testroot/wt > /dev/null
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	mkdir -p $testroot/wt/new
+	echo "new file" > $testroot/wt/new/foo
+
+	echo 'A  new/foo' > $testroot/stdout.expected
+	(cd $testroot/wt && got add new/foo > $testroot/stdout)
+
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+	fi
+	test_done "$testroot" "$ret"
+}
+
 run_test test_add_basic
 run_test test_double_add
 run_test test_add_multiple
+run_test test_add_file_in_new_subdir
blob - 65ebe13e039ee7595a78c264b154f9aa130bc661
blob + 63d1e5e120931fc5ccd7f3455bce2b26c72418ff
--- regress/cmdline/revert.sh
+++ regress/cmdline/revert.sh
@@ -183,7 +183,46 @@ function test_revert_multiple {
 	test_done "$testroot" "$ret"
 }
 
+function test_revert_file_in_new_subdir {
+	local testroot=`test_init revert_file_in_new_subdir`
+
+	got checkout $testroot/repo $testroot/wt > /dev/null
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+
+	mkdir -p $testroot/wt/newdir
+	echo new > $testroot/wt/newdir/new
+	(cd $testroot/wt && got add newdir/new > /dev/null)
+
+	(cd $testroot/wt && got revert newdir/new > $testroot/stdout)
+
+	echo "R  newdir/new" > $testroot/stdout.expected
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	(cd $testroot/wt && got status > $testroot/stdout)
+
+	echo "?  newdir/new" > $testroot/stdout.expected
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+	fi
+	test_done "$testroot" "$ret"
+
+}
+
 run_test test_revert_basic
 run_test test_revert_rm
 run_test test_revert_add
 run_test test_revert_multiple
+run_test test_revert_file_in_new_subdir