fix behaviour when update deletes an edited file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
diff --git a/lib/worktree.c b/lib/worktree.c
index 5d07d5a..4422883 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -1188,6 +1188,38 @@ remove_ondisk_file(const char *root_path, const char *path)
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 *
diff --git a/regress/cmdline/update.sh b/regress/cmdline/update.sh
index bd9f958..a05ab91 100755
--- a/regress/cmdline/update.sh
+++ b/regress/cmdline/update.sh
@@ -909,6 +909,58 @@ function test_update_conflict_add_vs_add {
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