commit 50952927133492b33519e6b09474d9a9ae77abb6 from: Stefan Sperling date: Sat Jan 12 20:00:42 2019 UTC fix various issues in new update implementation commit - 1c11b35cd62a3d95ca80329b5edb14875c18fa6a commit + 50952927133492b33519e6b09474d9a9ae77abb6 blob - b3b7b356254d4d7892f5ebfce76f811fbccf2813 blob + afdeab746035bdafbbd04d8bf67736896f49b640 --- lib/fileindex.c +++ lib/fileindex.c @@ -100,9 +100,8 @@ got_fileindex_entry_free(struct got_fileindex_entry *e free(entry); } -const struct got_error * -got_fileindex_entry_add(struct got_fileindex *fileindex, - struct got_fileindex_entry *entry) +static const struct got_error * +add_entry(struct got_fileindex *fileindex, struct got_fileindex_entry *entry) { if (fileindex->nentries >= GOT_FILEIDX_MAX_ENTRIES) return got_error(GOT_ERR_NO_SPACE); @@ -110,6 +109,16 @@ got_fileindex_entry_add(struct got_fileindex *fileinde RB_INSERT(got_fileindex_tree, &fileindex->entries, entry); fileindex->nentries++; return NULL; +} + +const struct got_error * +got_fileindex_entry_add(struct got_fileindex *fileindex, + struct got_fileindex_entry *entry) +{ + /* Flag this entry until it gets written out to disk. */ + entry->flags |= GOT_INDEX_ENTRY_F_INTENT_TO_ADD; + + return add_entry(fileindex, entry); } void @@ -309,6 +318,7 @@ got_fileindex_write(struct got_fileindex *fileindex, F return got_ferror(outfile, GOT_ERR_IO); RB_FOREACH(entry, got_fileindex_tree, &fileindex->entries) { + entry->flags &= ~GOT_INDEX_ENTRY_F_INTENT_TO_ADD; err = write_fileindex_entry(&ctx, entry, outfile); if (err) return err; @@ -505,7 +515,7 @@ got_fileindex_read(struct got_fileindex *fileindex, FI err = read_fileindex_entry(&entry, &ctx, infile); if (err) return err; - err = got_fileindex_entry_add(fileindex, entry); + err = add_entry(fileindex, entry); if (err) return err; } @@ -525,7 +535,6 @@ in_same_subdir(struct got_fileindex_entry *ie, const c struct got_tree_entry *te) { size_t parent_len = strlen(parent_path); - size_t te_name_len = strlen(te->name); char *ie_name; if (!got_path_is_child(ie->path, parent_path, parent_len)) @@ -534,12 +543,8 @@ in_same_subdir(struct got_fileindex_entry *ie, const c ie_name = ie->path + parent_len; while (ie_name[0] == '/') ie_name++; - if (strncmp(ie_name, te->name, te_name_len) != 0) - return 0; - if (ie_name[te_name_len] == '/') - return 0; - return 1; + return strchr(ie_name, '/') == NULL; } static int @@ -551,15 +556,15 @@ cmp_entries(struct got_fileindex_entry *ie, const char if (!in_same_subdir(ie, parent_path, te)) { if (parent_path[0]) - return got_compare_paths(ie->path, parent_path); - return got_compare_paths(ie->path, te->name); + return strcmp(ie->path, parent_path); + return strcmp(ie->path, te->name); } ie_name = ie->path + parent_len; while (ie_name[0] == '/') ie_name++; - return got_compare_paths(ie_name, te->name); + return strcmp(ie_name, te->name); } static const struct got_error * @@ -567,6 +572,20 @@ diff_fileindex_tree(struct got_fileindex *, struct got struct got_tree_object *, const char *, struct got_repository *, struct got_fileindex_diff_cb *, void *); +struct got_fileindex_entry * +walk_fileindex(struct got_fileindex *fileindex, struct got_fileindex_entry *ie) +{ + struct got_fileindex_entry *next; + + next = RB_NEXT(got_fileindex_tree, &fileindex->entries, ie); + + /* Skip entries which were newly added by diff callbacks. */ + while (next && (next->flags & GOT_INDEX_ENTRY_F_INTENT_TO_ADD)) + next = RB_NEXT(got_fileindex_tree, &fileindex->entries, next); + + return next; +} + static const struct got_error * walk_tree(struct got_tree_entry **next, struct got_fileindex *fileindex, struct got_fileindex_entry **ie, struct got_tree_entry *te, @@ -635,13 +654,11 @@ diff_fileindex_tree(struct got_fileindex *fileindex, path); if (err) break; - *ie = RB_NEXT(got_fileindex_tree, - &fileindex->entries, *ie); + *ie = walk_fileindex(fileindex, *ie); err = walk_tree(&te, fileindex, ie, te, path, repo, cb, cb_arg); - } else if (cmp < 0) { - next = RB_NEXT(got_fileindex_tree, - &fileindex->entries, *ie); + } else if (cmp < 0 ) { + next = walk_fileindex(fileindex, *ie); err = cb->diff_old(cb_arg, *ie, path); if (err) break; @@ -656,8 +673,7 @@ diff_fileindex_tree(struct got_fileindex *fileindex, if (err) break; } else if (*ie) { - next = RB_NEXT(got_fileindex_tree, - &fileindex->entries, *ie); + next = walk_fileindex(fileindex, *ie); err = cb->diff_old(cb_arg, *ie, path); if (err) break; blob - 791dba0cf4be882a105d7d91c47c94691d177dc5 blob + 3aee1d309fe36ea2dc730b4d5680e7f97930541a --- lib/got_lib_fileindex.h +++ lib/got_lib_fileindex.h @@ -53,6 +53,7 @@ struct got_fileindex_entry { #define GOT_INDEX_ENTRY_F_STAGE 0x00003000 #define GOT_INDEX_ENTRY_F_EXTENDED 0x00004000 #define GOT_INDEX_ENTRY_F_ASSUME_VALID 0x00008000 +#define GOT_INDEX_ENTRY_F_INTENT_TO_ADD 0x20000000 /* * UNIX-style path, relative to work tree root. @@ -77,7 +78,7 @@ static inline int got_fileindex_cmp(const struct got_fileindex_entry *e1, const struct got_fileindex_entry *e2) { - return got_compare_paths(e1->path, e2->path); + return strcmp(e1->path, e2->path); } RB_PROTOTYPE(got_fileindex_tree, got_fileindex_entry, entry, got_fileindex_cmp); blob - 1572dea6554f51a02a91ac2c15fe1024352791c9 blob + e28a3564b901a2fcd6f09d3552139ff4fb2dee1b --- regress/cmdline/update.sh +++ regress/cmdline/update.sh @@ -283,6 +283,46 @@ function test_update_sibling_dirs_with_common_prefix { # U epsilon/zeta # D epsilon2/mu <--- not intended # A epsilon2/mu <--- not intended + (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 + + cmp $testroot/stdout.expected $testroot/stdout + if [ "$?" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$?" + return 1 + fi + + test_done "$testroot" "0" +} + +function test_update_dir_with_dot_sibling { + local testroot=`test_init update_dir_with_dot_sibling` + + got checkout $testroot/repo $testroot/wt > /dev/null + if [ "$?" != "0" ]; then + test_done "$testroot" "$?" + return 1 + fi + + echo text > $testroot/repo/epsilon.txt + (cd $testroot/repo && git add epsilon.txt) + git_commit $testroot/repo -m "adding sibling of epsilon" + echo change > $testroot/repo/epsilon/zeta + git_commit $testroot/repo -m "changing epsilon/zeta" + + echo "A epsilon.txt" > $testroot/stdout.expected + echo "U 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 @@ -292,6 +332,16 @@ function test_update_sibling_dirs_with_common_prefix { return 1 fi + echo "another change" > $testroot/repo/epsilon/zeta + git_commit $testroot/repo -m "changing epsilon/zeta again" + + echo "U 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 @@ -299,6 +349,13 @@ function test_update_sibling_dirs_with_common_prefix { return 1 fi + cmp $testroot/stdout.expected $testroot/stdout + if [ "$?" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$?" + return 1 + fi + test_done "$testroot" "0" } @@ -309,3 +366,4 @@ run_test test_update_deletes_dir run_test test_update_deletes_dir_with_path_prefix run_test test_update_deletes_dir_recursively run_test test_update_sibling_dirs_with_common_prefix +run_test test_update_dir_with_dot_sibling