commit f5c49f82371af261622c0db5fea60e6558d32c6c from: Stefan Sperling date: Sun Jan 06 11:12:16 2019 UTC make 'got update' remove empty directories commit - 4b0bb32784eb980751dcc4bc4cf3c8ffe40ef88d commit + f5c49f82371af261622c0db5fea60e6558d32c6c blob - 6e5fc2e147fc218200cc9d247d6cb75a9009faec blob + 82b3c5fb16d76861d57253af15621fd81e41d392 --- lib/worktree.c +++ lib/worktree.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -747,22 +748,29 @@ static const struct got_error * collect_missing_file(void *args, struct got_fileindex_entry *entry) { struct collect_missing_entry_args *a = args; - char *name; + char *start, *end; + ptrdiff_t len; struct got_tree_entry *te; int found = 0; - if (a->path_prefix[0] == '\0' && strchr(entry->path, '/') != NULL) - return NULL; if (a->path_prefix[0] != '\0' && strncmp(a->path_prefix, entry->path, strlen(a->path_prefix)) != 0) return NULL; - name = basename(entry->path); - if (name == NULL) - return got_error_from_errno(); + start = entry->path + strlen(a->path_prefix); + while (start[0] == '/') + start++; + end = strchr(start, '/'); + if (end == NULL) { + end = strchr(start, '\0'); + if (end == NULL) + return got_error(GOT_ERR_BAD_PATH); + } + len = end - start; SIMPLEQ_FOREACH(te, &a->entries->head, entry) { - if (strcmp(te->name, name) == 0) { + if (strncmp(start, te->name, len) == 0 && + te->name[len] == '\0') { found = 1; break; } @@ -816,6 +824,11 @@ remove_missing_files(struct got_worktree *worktree, co if (unlink(ondisk_path) == -1) err = got_error_from_errno(); + else { + char *parent = dirname(ondisk_path); + if (rmdir(parent) == -1 && errno != ENOTEMPTY) + err = got_error_from_errno(); + } free(ondisk_path); if (err) break; blob - 67fd42633b02f58a3db6754e107a8896d4eb1974 blob + cc23e638e0aa3f1fd81b5d6f7aae10193faec62f --- regress/cmdline/update.sh +++ regress/cmdline/update.sh @@ -145,6 +145,52 @@ function test_update_deletes_file { test_done "$testroot" "$ret" } +function test_update_deletes_dir { + local testroot=`test_init update_deletes_dir` + + got checkout $testroot/repo $testroot/wt > /dev/null + if [ "$?" != "0" ]; then + test_done "$testroot" "$?" + return 1 + fi + + (cd $testroot/repo && git_rm $testroot/repo -r epsilon) + git_commit $testroot/repo -m "deleting a directory" + + echo "D epsilon/zeta" > $testroot/stdout.expected + echo -n "Updated to commit " >> $testroot/stdout.expected + git_show_head $testroot/repo >> $testroot/stdout.expected + echo >> $testroot/stdout.expected + + (cd $testroot/wt && got update > $testroot/stdout) + + cmp $testroot/stdout.expected $testroot/stdout + if [ "$?" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$?" + return 1 + fi + + if [ -e $testroot/wt/epsilon ]; then + echo "removed dir epsilon still exists on disk" >&2 + return 1 + fi + + echo "alpha" >> $testroot/content.expected + echo "beta" >> $testroot/content.expected + echo "delta" >> $testroot/content.expected + cat $testroot/wt/alpha $testroot/wt/beta \ + $testroot/wt/gamma/delta > $testroot/content + + cmp $testroot/content.expected $testroot/content + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/content.expected $testroot/content + fi + test_done "$testroot" "$ret" +} + run_test test_update_basic run_test test_update_adds_file run_test test_update_deletes_file +run_test test_update_deletes_dir