commit 2b496619daecc1f25b1bc0c53e01685030dc2c74 from: Stefan Sperling date: Wed Jul 10 20:42:31 2019 UTC fix bug exposed by test_commit_added_and_modified_in_same_dir commit - 4866d0842a2b34812818685aaa31d3e0a966412d commit + 2b496619daecc1f25b1bc0c53e01685030dc2c74 blob - c68ca743bd5ba681fe40b097c08f23d275540824 blob + 6c06691116548c4c4bf246510416f6568ebfdb71 --- lib/worktree.c +++ lib/worktree.c @@ -2870,7 +2870,46 @@ match_deleted_or_modified_ct(struct got_commitable **c *ctp = ct; break; } + + return err; +} + +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; } @@ -2919,38 +2958,25 @@ write_tree(struct got_object_id **new_tree_id, if (err) goto done; ct->flags |= GOT_COMMITABLE_ADDED; - } 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"); + err = insert_tree_entry(new_te, &paths); + if (err) 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; + } else { + *slash = '\0'; /* trim trailing path components */ + 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) { blob - 3a97ed55c77d90d9576fa91da49828518da37c33 blob + fa62e4aace284747229f3636273843d3bf884f9a --- regress/cmdline/commit.sh +++ 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" }