commit - 9c2e8939ca5f2599eac9d215a6e7747b3dbfe482
commit + ba580f687cd7280a6d7bffb1693077693c486056
blob - 34717c9e490a24f071ea53b060842a699b03a543
blob + f43056690320ca4d0531a3f1ae2b4550a70b31db
--- lib/worktree.c
+++ lib/worktree.c
return err;
}
-static const struct got_error *write_tree(struct got_object_id **,
+static const struct got_error *write_tree(struct got_object_id **, int *,
struct got_tree_object *, const char *, struct got_pathlist_head *,
got_worktree_status_cb status_cb, void *status_arg,
struct got_repository *);
static const struct got_error *
-write_subtree(struct got_object_id **new_subtree_id,
+write_subtree(struct got_object_id **new_subtree_id, int *nentries,
struct got_tree_entry *te, const char *parent_path,
struct got_pathlist_head *commitable_paths,
got_worktree_status_cb status_cb, void *status_arg,
if (err)
return err;
- err = write_tree(new_subtree_id, subtree, subpath, commitable_paths,
- status_cb, status_arg, repo);
+ err = write_tree(new_subtree_id, nentries, subtree, subpath,
+ commitable_paths, status_cb, status_arg, repo);
got_object_tree_close(subtree);
free(subpath);
return err;
struct got_tree_entry *new_te;
char *subtree_path;
struct got_object_id *id = NULL;
+ int nentries;
*new_tep = NULL;
err = got_error(GOT_ERR_NO_SPACE);
goto done;
}
- err = write_tree(&id, NULL, subtree_path,
+ err = write_tree(&id, &nentries, NULL, subtree_path,
commitable_paths, status_cb, status_arg, repo);
if (err) {
free(new_te);
}
static const struct got_error *
-write_tree(struct got_object_id **new_tree_id,
+write_tree(struct got_object_id **new_tree_id, int *nentries,
struct got_tree_object *base_tree, const char *path_base_tree,
struct got_pathlist_head *commitable_paths,
got_worktree_status_cb status_cb, void *status_arg,
struct got_pathlist_head paths;
struct got_tree_entry *te, *new_te = NULL;
struct got_pathlist_entry *pe;
- int nentries = 0;
TAILQ_INIT(&paths);
+ *nentries = 0;
/* Insert, and recurse into, newly added entries first. */
TAILQ_FOREACH(pe, commitable_paths, entry) {
err = insert_tree_entry(new_te, &paths);
if (err)
goto done;
- nentries++;
+ (*nentries)++;
} else {
*slash = '\0'; /* trim trailing path components */
if (base_tree == NULL ||
err = insert_tree_entry(new_te, &paths);
if (err)
goto done;
- nentries++;
+ (*nentries)++;
}
}
}
err = insert_tree_entry(new_te, &paths);
if (err)
goto done;
- nentries++;
+ (*nentries)++;
continue;
}
/* Avoid recursion into unmodified subtrees. */
if (modified) {
struct got_object_id *new_id;
- err = write_subtree(&new_id, te,
+ int nsubentries;
+ err = write_subtree(&new_id,
+ &nsubentries, te,
path_base_tree, commitable_paths,
status_cb, status_arg, repo);
if (err)
goto done;
+ if (nsubentries == 0) {
+ /* All entries were deleted. */
+ free(new_id);
+ continue;
+ }
memcpy(&new_te->id, new_id,
sizeof(new_te->id));
free(new_id);
err = insert_tree_entry(new_te, &paths);
if (err)
goto done;
- nentries++;
+ (*nentries)++;
continue;
}
err = insert_tree_entry(new_te, &paths);
if (err)
goto done;
- nentries++;
+ (*nentries)++;
}
err = report_ct_status(ct, status_cb,
status_arg);
err = insert_tree_entry(new_te, &paths);
if (err)
goto done;
- nentries++;
+ (*nentries)++;
}
}
}
/* Write new list of entries; deleted entries have been dropped. */
- err = got_object_tree_create(new_tree_id, &paths, nentries, repo);
+ err = got_object_tree_create(new_tree_id, &paths, *nentries, repo);
done:
got_pathlist_free(&paths);
return err;
struct got_object_id *head_commit_id2 = NULL;
struct got_tree_object *head_tree = NULL;
struct got_object_id *new_tree_id = NULL;
+ int nentries;
struct got_object_id_queue parent_ids;
struct got_object_qid *pid = NULL;
char *logmsg = NULL;
}
/* Recursively write new tree objects. */
- err = write_tree(&new_tree_id, head_tree, "/", commitable_paths,
- status_cb, status_arg, repo);
+ err = write_tree(&new_tree_id, &nentries, head_tree, "/",
+ commitable_paths, status_cb, status_arg, repo);
if (err)
goto done;
blob - a131681c03b7c5c023fa5603baf9b704a0bc4779
blob + 270ee1fe177e6657aa51f55d0f13dae24a800402
--- regress/cmdline/commit.sh
+++ regress/cmdline/commit.sh
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
+
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ fi
+ test_done "$testroot" "$ret"
+}
+
+function test_commit_deleted_subdirs {
+ local testroot=`test_init commit_deleted_subdirs`
+
+ got checkout $testroot/repo $testroot/wt > /dev/null
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && got rm -R $testroot/wt/{epsilon,gamma} >/dev/null)
+
+ (cd $testroot/wt && got commit -m 'test commit_deleted_subdirs' \
+ > $testroot/stdout 2> $testroot/stderr)
+
+ local head_rev=`git_show_head $testroot/repo`
+ echo "D epsilon/zeta" > $testroot/stdout.expected
+ echo "D gamma/delta" >> $testroot/stdout.expected
echo "Created commit $head_rev" >> $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
+ got tree -r $testroot/repo > $testroot/stdout
+
+ echo "alpha" > $testroot/stdout.expected
+ echo "beta" >> $testroot/stdout.expected
+
cmp -s $testroot/stdout.expected $testroot/stdout
ret="$?"
if [ "$ret" != "0" ]; then
run_test test_commit_single_file
run_test test_commit_out_of_date
run_test test_commit_added_subdirs
+run_test test_commit_deleted_subdirs
run_test test_commit_rejects_conflicted_file
run_test test_commit_single_file_multiple
run_test test_commit_added_and_modified_in_same_dir