fix bug exposed by test_commit_added_and_modified_in_same_dir
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
diff --git a/lib/worktree.c b/lib/worktree.c
index c68ca74..6c06691 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -2875,6 +2875,45 @@ match_deleted_or_modified_ct(struct got_commitable **ctp,
}
static const struct got_error *
+make_subtree_for_added_blob(struct got_tree_entry **new_tep,
+ const char *child_path, const char *path_base_tree,
+ struct got_pathlist_head *commitable_paths,
+ got_worktree_status_cb status_cb, void *status_arg,
+ struct got_repository *repo)
+{
+ const struct got_error *err = NULL;
+ struct got_tree_entry *new_te;
+ char *subtree_path;
+
+ *new_tep = NULL;
+
+ if (asprintf(&subtree_path, "%s%s%s", path_base_tree,
+ got_path_is_root_dir(path_base_tree) ? "" : "/",
+ child_path) == -1)
+ return got_error_from_errno("asprintf");
+
+ new_te = calloc(1, sizeof(*new_te));
+ new_te->mode = S_IFDIR;
+ new_te->name = strdup(child_path);
+ if (new_te->name == NULL) {
+ err = got_error_from_errno("strdup");
+ got_object_tree_entry_close(new_te);
+ goto done;
+ }
+ err = write_tree(&new_te->id, NULL, subtree_path,
+ commitable_paths, status_cb, status_arg, repo);
+ if (err) {
+ got_object_tree_entry_close(new_te);
+ goto done;
+ }
+done:
+ free(subtree_path);
+ if (err == NULL)
+ *new_tep = new_te;
+ return err;
+}
+
+static const struct got_error *
write_tree(struct got_object_id **new_tree_id,
struct got_tree_object *base_tree, const char *path_base_tree,
struct got_pathlist_head *commitable_paths,
@@ -2919,38 +2958,25 @@ write_tree(struct got_object_id **new_tree_id,
if (err)
goto done;
ct->flags |= GOT_COMMITABLE_ADDED;
+ err = insert_tree_entry(new_te, &paths);
+ if (err)
+ goto done;
} else {
- char *subtree_path;
-
*slash = '\0'; /* trim trailing path components */
- if (asprintf(&subtree_path, "%s%s%s", path_base_tree,
- got_path_is_root_dir(path_base_tree) ? "" : "/",
- child_path) == -1) {
- err = got_error_from_errno("asprintf");
- goto done;
- }
-
- new_te = calloc(1, sizeof(*new_te));
- new_te->mode = S_IFDIR;
- new_te->name = strdup(child_path);
- if (new_te->name == NULL) {
- err = got_error_from_errno("strdup");
- got_object_tree_entry_close(new_te);
- new_te = NULL;
- goto done;
- }
- err = write_tree(&new_te->id, NULL, subtree_path,
- commitable_paths, status_cb, status_arg, repo);
- free(subtree_path);
- if (err) {
- got_object_tree_entry_close(new_te);
- new_te = NULL;
- goto done;
+ if (base_tree == NULL ||
+ got_object_tree_find_entry(base_tree, child_path)
+ == NULL) {
+ err = make_subtree_for_added_blob(&new_te,
+ child_path, path_base_tree,
+ commitable_paths, status_cb, status_arg,
+ repo);
+ if (err)
+ goto done;
+ err = insert_tree_entry(new_te, &paths);
+ if (err)
+ goto done;
}
}
- err = insert_tree_entry(new_te, &paths);
- if (err)
- goto done;
}
if (base_tree) {
diff --git a/regress/cmdline/commit.sh b/regress/cmdline/commit.sh
index 3a97ed5..fa62e4a 100755
--- a/regress/cmdline/commit.sh
+++ b/regress/cmdline/commit.sh
@@ -301,8 +301,6 @@ function test_commit_single_file_multiple {
test_done "$testroot" "0"
}
-# This test currently fails because the writing trees during commit does
-# not properly account for trees which contain both added and modified files.
function test_commit_added_and_modified_in_same_dir {
local testroot=`test_init commit_added_and_modified_in_same_dir`
@@ -329,8 +327,7 @@ function test_commit_added_and_modified_in_same_dir {
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"
}