commit baa7dcfad48fd8812ab361d99e8a4de476f107ec from: Stefan Sperling date: Thu May 09 19:36:10 2019 UTC don't visit added subtrees reundantly commit - afa376bfb3ca51475b12811e7f07c512f6a9267e commit + baa7dcfad48fd8812ab361d99e8a4de476f107ec blob - bcc5c7aa4f76642065bbbfe9080e3e5bb9110f12 blob + 367285570255edf571c519d2dd91ba9aa47bd314 --- lib/worktree.c +++ lib/worktree.c @@ -2205,7 +2205,6 @@ struct commitable { unsigned char status; struct got_object_id *id; struct got_object_id *base_id; - struct got_object_id *tree_id; }; static void @@ -2214,7 +2213,6 @@ free_commitable(struct commitable *ct) free(ct->path); free(ct->id); free(ct->base_id); - free(ct->tree_id); free(ct); } @@ -2270,10 +2268,6 @@ collect_commitables(void *arg, unsigned char status, c goto done; } } - err = got_object_id_by_path(&ct->tree_id, a->repo, - a->worktree->base_commit_id, parent_path); - if (err) - goto done; ct->path = strdup(path); if (ct->path == NULL) { err = got_error_from_errno(); @@ -2305,7 +2299,7 @@ write_subtree(struct got_object_id **new_subtree_id, char *subpath; if (asprintf(&subpath, "%s%s%s", parent_path, - parent_path[0] == '\0' ? "" : "/", te->name) == -1) + got_path_is_root_dir(parent_path) ? "" : "/", te->name) == -1) return got_error_from_errno(); err = got_object_open_as_tree(&subtree, repo, te->id); @@ -2523,6 +2517,8 @@ write_tree(struct got_object_id **new_tree_id, goto done; } else { char *subtree_path; + struct got_pathlist_entry *pe2; + int visited = 0; *slash = '\0'; /* trim trailing path components */ @@ -2534,18 +2530,27 @@ write_tree(struct got_object_id **new_tree_id, err = got_error_from_errno(); goto done; } - if (asprintf(&subtree_path, "%s/%s", path_base_tree, + 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(); goto done; } - err = write_subtree(&new_te->id, NULL, subtree_path, + TAILQ_FOREACH(pe2, &paths, entry) { + if (got_path_cmp(subtree_path, pe2->path) != 0) + continue; + visited = 1; + break; + } + if (visited) + continue; + + err = write_tree(&new_te->id, NULL, subtree_path, commitable_paths, status_cb, status_arg, repo); free(subtree_path); if (err) goto done; } - err = insert_tree_entry(new_te, &paths); if (err) goto done; blob - 54f8171b420b631a1444a245b17606223c0c0385 blob + 3d14f7883d45723781ebc9a73bfad4daa355d840 --- regress/cmdline/commit.sh +++ regress/cmdline/commit.sh @@ -50,4 +50,37 @@ function test_commit_basic { test_done "$testroot" "$ret" } +function test_commit_new_subdir { + local testroot=`test_init commit_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/d + echo "new file" > $testroot/wt/d/new + echo "another new file" > $testroot/wt/d/new2 + (cd $testroot/wt && got add d/new >/dev/null) + (cd $testroot/wt && got add d/new2 >/dev/null) + + (cd $testroot/wt && \ + got commit -m 'test commit_new_subdir' > $testroot/stdout) + + local head_rev=`git_show_head $testroot/repo` + echo "A d/new" > $testroot/stdout.expected + echo "A d/new2" >> $testroot/stdout.expected + echo "created commit $head_rev" >> $testroot/stdout.expected + + cmp $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_commit_basic +run_test test_commit_new_subdir