indicate non-existent paths in 'got status' and make 'got diff' error for them
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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
diff --git a/got/got.1 b/got/got.1
index bc24b56..45c8c5c 100644
--- a/got/got.1
+++ b/got/got.1
@@ -243,6 +243,9 @@ using the following status codes:
.It \(a~ Ta versioned file is obstructed by a non-regular file
.It ? Ta unversioned item not tracked by
.Nm
+.It N Ta non-existent
+.Ar path
+specified on the command line
.El
.Pp
If no
diff --git a/got/got.c b/got/got.c
index 9ae1a22..34e0719 100644
--- a/got/got.c
+++ b/got/got.c
@@ -1823,6 +1823,8 @@ print_diff(void *arg, unsigned char status, unsigned char staged_status,
} else {
if (staged_status == GOT_STATUS_DELETE)
return NULL;
+ if (status == GOT_STATUS_NONEXISTENT)
+ return got_error_set_errno(ENOENT, path);
if (status != GOT_STATUS_MODIFY &&
status != GOT_STATUS_ADD &&
status != GOT_STATUS_DELETE &&
@@ -3847,6 +3849,20 @@ usage_remove(void)
}
static const struct got_error *
+print_remove_status(void *arg, unsigned char status,
+ unsigned char staged_status, const char *path,
+ struct got_object_id *blob_id, struct got_object_id *staged_blob_id,
+ struct got_object_id *commit_id)
+{
+ if (status == GOT_STATUS_NONEXISTENT)
+ return NULL;
+ if (status == staged_status && (status == GOT_STATUS_DELETE))
+ status = GOT_STATUS_NO_CHANGE;
+ printf("%c%c %s\n", status, staged_status, path);
+ return NULL;
+}
+
+static const struct got_error *
cmd_remove(int argc, char *argv[])
{
const struct got_error *error = NULL;
@@ -3904,7 +3920,7 @@ cmd_remove(int argc, char *argv[])
goto done;
error = got_worktree_schedule_delete(worktree, &paths,
- delete_local_mods, print_status, NULL, repo);
+ delete_local_mods, print_remove_status, NULL, repo);
if (error)
goto done;
done:
diff --git a/include/got_worktree.h b/include/got_worktree.h
index 1bd4eff..096c4e4 100644
--- a/include/got_worktree.h
+++ b/include/got_worktree.h
@@ -31,6 +31,7 @@ struct got_fileindex;
#define GOT_STATUS_MISSING '!'
#define GOT_STATUS_UNVERSIONED '?'
#define GOT_STATUS_OBSTRUCTED '~'
+#define GOT_STATUS_NONEXISTENT 'N'
#define GOT_STATUS_REVERT 'R'
#define GOT_STATUS_CANNOT_DELETE 'd'
#define GOT_STATUS_BUMP_BASE 'b'
diff --git a/lib/worktree.c b/lib/worktree.c
index 30b65e9..9a7c693 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -2508,6 +2508,8 @@ void *status_arg, struct got_repository *repo)
if (lstat(ondisk_path, &sb) == -1) {
if (errno != ENOENT)
return got_error_from_errno2("lstat", ondisk_path);
+ return (*status_cb)(status_arg, GOT_STATUS_NONEXISTENT,
+ GOT_STATUS_NO_CHANGE, path, NULL, NULL, NULL);
return NULL;
}
@@ -5560,6 +5562,8 @@ check_stage_ok(void *arg, unsigned char status,
if (status == GOT_STATUS_UNVERSIONED)
return NULL;
+ if (status == GOT_STATUS_NONEXISTENT)
+ return got_error_set_errno(ENOENT, relpath);
ie = got_fileindex_entry_get(a->fileindex, relpath, strlen(relpath));
if (ie == NULL)
@@ -5703,6 +5707,9 @@ stage_path(void *arg, unsigned char status,
case GOT_STATUS_CONFLICT:
err = got_error_path(relpath, GOT_ERR_STAGE_CONFLICT);
break;
+ case GOT_STATUS_NONEXISTENT:
+ err = got_error_set_errno(ENOENT, relpath);
+ break;
default:
err = got_error_path(relpath, GOT_ERR_FILE_STATUS);
break;
diff --git a/regress/cmdline/diff.sh b/regress/cmdline/diff.sh
index e7cea61..455469c 100755
--- a/regress/cmdline/diff.sh
+++ b/regress/cmdline/diff.sh
@@ -62,6 +62,29 @@ function test_diff_basic {
ret="$?"
if [ "$ret" != "0" ]; then
diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ # diff non-existent path
+ (cd $testroot/wt && got diff nonexistent > $testroot/stdout \
+ 2> $testroot/stderr)
+
+ echo -n > $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
+
+ echo "got: nonexistent: No such file or directory" \
+ > $testroot/stderr.expected
+ cmp -s $testroot/stderr.expected $testroot/stderr
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stderr.expected $testroot/stderr
fi
test_done "$testroot" "$ret"
}
diff --git a/regress/cmdline/stage.sh b/regress/cmdline/stage.sh
index e7fb40f..abe3641 100755
--- a/regress/cmdline/stage.sh
+++ b/regress/cmdline/stage.sh
@@ -156,7 +156,8 @@ function test_stage_nonexistent {
(cd $testroot/wt && got stage nonexistent-file \
> $testroot/stdout 2> $testroot/stderr)
- echo "got: no changes to stage" > $testroot/stderr.expected
+ echo "got: nonexistent-file: No such file or directory" \
+ > $testroot/stderr.expected
cmp -s $testroot/stderr.expected $testroot/stderr
ret="$?"
if [ "$ret" != "0" ]; then
diff --git a/regress/cmdline/update.sh b/regress/cmdline/update.sh
index ec4a92d..1cdd633 100755
--- a/regress/cmdline/update.sh
+++ b/regress/cmdline/update.sh
@@ -1052,7 +1052,7 @@ function test_update_conflict_wt_rm_vs_repo_rm {
fi
# beta is now gone... we don't flag tree conflicts yet
- echo -n > $testroot/stdout.expected
+ echo "N beta" > $testroot/stdout.expected
echo -n > $testroot/stderr.expected
(cd $testroot/wt && got status beta > $testroot/stdout \
2> $testroot/stderr)