Commit a3df2849ff6ef714618aee3003e83b56282dbb49

Stefan Sperling 2019-05-20T16:02:16

fix bug reproduced by xfail test 'test_commit_added_subdirs'

diff --git a/TODO b/TODO
index 26f0c87..4cb95bf 100644
--- a/TODO
+++ b/TODO
@@ -5,8 +5,6 @@ lib:
 - allow adding directory paths with 'got add'
 - recursive addition: got add -R
 - recursive removal: got rm -R
-- fix bug reproduced by xfail test 'test_commit_added_subdirs'
-  in regress/cmdline/commit.sh
 
 tog:
 - allow loading new commits in 'tog log' after startup (e.g. via Ctrl-L, 'r')
diff --git a/include/got_worktree.h b/include/got_worktree.h
index 38554a8..153a8c6 100644
--- a/include/got_worktree.h
+++ b/include/got_worktree.h
@@ -30,6 +30,7 @@ struct got_worktree;
 #define GOT_STATUS_OBSTRUCTED	'~'
 #define GOT_STATUS_REVERT	'R'
 
+/* XXX TODO make this opaque */
 struct got_commitable {
 	char *path;
 	char *in_repo_path;
@@ -39,6 +40,8 @@ struct got_commitable {
 	struct got_object_id *base_blob_id;
 	struct got_object_id *base_commit_id;
 	mode_t mode;
+	int flags;
+#define GOT_COMMITABLE_ADDED 0x01
 };
 
 /*
diff --git a/lib/worktree.c b/lib/worktree.c
index 7c7732c..8fe0105 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -2623,7 +2623,8 @@ write_tree(struct got_object_id **new_tree_id,
 		struct got_commitable *ct = pe->data;
 		char *child_path = NULL, *slash;
 
-		if (ct->status != GOT_STATUS_ADD)
+		if (ct->status != GOT_STATUS_ADD ||
+		    (ct->flags & GOT_COMMITABLE_ADDED))
 			continue;
 
 		 if (!got_path_is_child(pe->path, path_base_tree,
@@ -2643,10 +2644,9 @@ write_tree(struct got_object_id **new_tree_id,
 			err = report_ct_status(ct, status_cb, status_arg);
 			if (err)
 				goto done;
+			ct->flags |= GOT_COMMITABLE_ADDED;
 		} else {
 			char *subtree_path;
-			struct got_pathlist_entry *pe2;
-			int visited = 0;
 
 			*slash = '\0'; /* trim trailing path components */
 			if (asprintf(&subtree_path, "%s%s%s", path_base_tree,
@@ -2655,16 +2655,6 @@ write_tree(struct got_object_id **new_tree_id,
 				err = got_error_from_errno("asprintf");
 				goto done;
 			}
-			TAILQ_FOREACH(pe2, &paths, entry) {
-				if (got_path_cmp(subtree_path, pe2->path) != 0)
-					continue;
-				visited = 1;
-				break;
-			}
-			if (visited) {
-				free(subtree_path);
-				continue;
-			}
 
 			new_te = calloc(1, sizeof(*new_te));
 			new_te->mode = S_IFDIR;
diff --git a/regress/cmdline/commit.sh b/regress/cmdline/commit.sh
index 454a290..6ab0147 100755
--- a/regress/cmdline/commit.sh
+++ b/regress/cmdline/commit.sh
@@ -199,8 +199,8 @@ function test_commit_added_subdirs {
 		> $testroot/stdout 2> $testroot/stderr)
 
 	local head_rev=`git_show_head $testroot/repo`
-	echo "A  d/f/new3" > $testroot/stdout.expected
-	echo "A  d/f/g/new4" >> $testroot/stdout.expected
+	echo "A  d/f/g/new4" > $testroot/stdout.expected
+	echo "A  d/f/new3" >> $testroot/stdout.expected
 	echo "A  d/new" >> $testroot/stdout.expected
 	echo "A  d/new2" >> $testroot/stdout.expected
 	echo "created commit $head_rev" >> $testroot/stdout.expected
@@ -208,8 +208,7 @@ function test_commit_added_subdirs {
 	cmp -s $testroot/stdout.expected $testroot/stdout
 	ret="$?"
 	if [ "$ret" != "0" ]; then
-		#diff -u $testroot/stdout.expected $testroot/stdout
-		ret="xfail ($(head -n 1 $testroot/stderr))"
+		diff -u $testroot/stdout.expected $testroot/stdout
 	fi
 	test_done "$testroot" "$ret"
 }