commit 708d8e672e598275721ee0e9707e5bea2b0435b4 from: Stefan Sperling date: Wed Mar 27 11:00:59 2019 UTC fix behaviour when update deletes an edited file commit - e9b3576faf75d4564e5ed585837da4482e6a9c26 commit + 708d8e672e598275721ee0e9707e5bea2b0435b4 blob - 5d07d5a5961de07dae868ca1e72e47e990d7620d blob + 442288387b7a34120e7bba5f27c9f45dbfc31768 --- lib/worktree.c +++ lib/worktree.c @@ -1188,6 +1188,38 @@ remove_ondisk_file(const char *root_path, const char * return err; } +static const struct got_error * +delete_blob(struct got_worktree *worktree, struct got_fileindex *fileindex, + struct got_fileindex_entry *ie, const char *parent_path, + struct got_repository *repo, + got_worktree_checkout_cb progress_cb, void *progress_arg, + got_worktree_cancel_cb cancel_cb, void *cancel_arg) +{ + const struct got_error *err; + unsigned char status; + struct stat sb; + char *ondisk_path; + + if (asprintf(&ondisk_path, "%s/%s", worktree->root_path, ie->path) + == -1) + return got_error_from_errno(); + + err = get_file_status(&status, &sb, ie, ondisk_path, repo); + if (err) + return err; + + (*progress_cb)(progress_arg, GOT_STATUS_DELETE, ie->path); + + if (status == GOT_STATUS_NO_CHANGE) { + err = remove_ondisk_file(worktree->root_path, ie->path); + if (err) + return err; + } + + got_fileindex_entry_remove(fileindex, ie); + return NULL; +} + struct diff_cb_arg { struct got_fileindex *fileindex; struct got_worktree *worktree; @@ -1212,16 +1244,11 @@ diff_old_new(void *arg, struct got_fileindex_entry *ie static const struct got_error * diff_old(void *arg, struct got_fileindex_entry *ie, const char *parent_path) { - const struct got_error *err; struct diff_cb_arg *a = arg; - (*a->progress_cb)(a->progress_arg, GOT_STATUS_DELETE, ie->path); - - err = remove_ondisk_file(a->worktree->root_path, ie->path); - if (err) - return err; - got_fileindex_entry_remove(a->fileindex, ie); - return NULL; + return delete_blob(a->worktree, a->fileindex, ie, parent_path, + a->repo, a->progress_cb, a->progress_arg, + a->cancel_cb, a->cancel_arg); } static const struct got_error * blob - bd9f958e79f52fe03a9add930fabbdca8726c8cd blob + a05ab91111b4dc3478db7c579fed501b845d275f --- regress/cmdline/update.sh +++ regress/cmdline/update.sh @@ -908,7 +908,59 @@ function test_update_conflict_add_vs_add { fi test_done "$testroot" "$ret" } + +function test_update_conflict_local_edit_vs_rm { + local testroot=`test_init update_conflict_local_edit_vs_rm` + + got checkout $testroot/repo $testroot/wt > /dev/null + ret="$?" + if [ "$ret" != "0" ]; then + test_done "$testroot" "$ret" + return 1 + fi + + (cd $testroot/repo && git rm -q beta) + git_commit $testroot/repo -m "removing a file" + + echo "modified beta" > $testroot/wt/beta + (cd $testroot/wt && got update > $testroot/stdout) + + echo "D beta" > $testroot/stdout.expected + echo -n "Updated to commit " >> $testroot/stdout.expected + git_show_head $testroot/repo >> $testroot/stdout.expected + echo >> $testroot/stdout.expected + cmp $testroot/stdout.expected $testroot/stdout + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + echo "modified beta" > $testroot/content.expected + + cat $testroot/wt/beta > $testroot/content + + cmp $testroot/content.expected $testroot/content + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/content.expected $testroot/content + test_done "$testroot" "$ret" + return 1 + fi + + # beta is now an unversioned file... we don't flag tree conflicts yet + echo '? beta' > $testroot/stdout.expected + (cd $testroot/wt && got status > $testroot/stdout) + 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_update_basic run_test test_update_adds_file run_test test_update_deletes_file @@ -927,3 +979,4 @@ run_test test_update_keeps_xbit run_test test_update_clears_xbit run_test test_update_restores_missing_file run_test test_update_conflict_add_vs_add +run_test test_update_conflict_local_edit_vs_rm