show staged file status separately in 'got status'
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
diff --git a/got/got.c b/got/got.c
index 982c3c8..37d1d68 100644
--- a/got/got.c
+++ b/got/got.c
@@ -2368,6 +2368,9 @@ print_status(void *arg, unsigned char status, unsigned char staged_status,
const char *path, struct got_object_id *blob_id,
struct got_object_id *commit_id)
{
+ if (status == staged_status &&
+ (status == GOT_STATUS_ADD || status == GOT_STATUS_DELETE))
+ status = GOT_STATUS_NO_CHANGE;
printf("%c%c %s\n", status, staged_status, path);
return NULL;
}
diff --git a/lib/worktree.c b/lib/worktree.c
index 9ca3668..eaffa11 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -1034,6 +1034,21 @@ stat_info_differs(struct got_fileindex_entry *ie, struct stat *sb)
ie->size == (sb->st_size & 0xffffffff));
}
+static unsigned char
+get_staged_status(struct got_fileindex_entry *ie)
+{
+ switch (got_fileindex_entry_stage_get(ie)) {
+ case GOT_FILEIDX_STAGE_ADD:
+ return GOT_STATUS_ADD;
+ case GOT_FILEIDX_STAGE_DELETE:
+ return GOT_STATUS_DELETE;
+ case GOT_FILEIDX_STAGE_MODIFY:
+ return GOT_STATUS_MODIFY;
+ default:
+ return GOT_STATUS_NO_CHANGE;
+ }
+}
+
static const struct got_error *
get_file_status(unsigned char *status, struct stat *sb,
struct got_fileindex_entry *ie, const char *abspath,
@@ -1046,6 +1061,7 @@ get_file_status(unsigned char *status, struct stat *sb,
uint8_t fbuf[8192];
struct got_blob_object *blob = NULL;
size_t flen, blen;
+ unsigned char staged_status = get_staged_status(ie);
*status = GOT_STATUS_NO_CHANGE;
@@ -1076,7 +1092,12 @@ get_file_status(unsigned char *status, struct stat *sb,
if (!stat_info_differs(ie, sb))
return NULL;
- memcpy(id.sha1, ie->blob_sha1, sizeof(id.sha1));
+ if (staged_status == GOT_STATUS_MODIFY ||
+ staged_status == GOT_STATUS_ADD)
+ memcpy(id.sha1, ie->staged_blob_sha1, sizeof(id.sha1));
+ else
+ memcpy(id.sha1, ie->blob_sha1, sizeof(id.sha1));
+
err = got_object_open_as_blob(&blob, repo, &id, sizeof(fbuf));
if (err)
return err;
@@ -2179,21 +2200,6 @@ struct diff_dir_cb_arg {
void *cancel_arg;
};
-static unsigned char
-get_staged_status(struct got_fileindex_entry *ie)
-{
- switch (got_fileindex_entry_stage_get(ie)) {
- case GOT_FILEIDX_STAGE_ADD:
- return GOT_STATUS_ADD;
- case GOT_FILEIDX_STAGE_DELETE:
- return GOT_STATUS_DELETE;
- case GOT_FILEIDX_STAGE_MODIFY:
- return GOT_STATUS_MODIFY;
- default:
- return GOT_STATUS_NO_CHANGE;
- }
-}
-
static const struct got_error *
report_file_status(struct got_fileindex_entry *ie, const char *abspath,
got_worktree_status_cb status_cb, void *status_arg,
@@ -2201,14 +2207,16 @@ report_file_status(struct got_fileindex_entry *ie, const char *abspath,
{
const struct got_error *err = NULL;
unsigned char status = GOT_STATUS_NO_CHANGE;
+ unsigned char staged_status = get_staged_status(ie);
struct stat sb;
struct got_object_id blob_id, commit_id;
err = get_file_status(&status, &sb, ie, abspath, repo);
- if (err == NULL && status != GOT_STATUS_NO_CHANGE) {
+ if (err == NULL && (status != GOT_STATUS_NO_CHANGE ||
+ staged_status != GOT_STATUS_NO_CHANGE)) {
memcpy(blob_id.sha1, ie->blob_sha1, SHA1_DIGEST_LENGTH);
memcpy(commit_id.sha1, ie->commit_sha1, SHA1_DIGEST_LENGTH);
- err = (*status_cb)(status_arg, status, get_staged_status(ie),
+ err = (*status_cb)(status_arg, status, staged_status,
ie->path, &blob_id, &commit_id);
}
return err;
diff --git a/regress/cmdline/stage.sh b/regress/cmdline/stage.sh
index 0a71da3..5aa5444 100755
--- a/regress/cmdline/stage.sh
+++ b/regress/cmdline/stage.sh
@@ -44,4 +44,41 @@ function test_stage_basic {
test_done "$testroot" "$ret"
}
+function test_stage_status {
+ local testroot=`test_init stage_status`
+
+ got checkout $testroot/repo $testroot/wt > /dev/null
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "modified file" > $testroot/wt/alpha
+ (cd $testroot/wt && got rm beta > /dev/null)
+ echo "new file" > $testroot/wt/foo
+ (cd $testroot/wt && got add foo > /dev/null)
+ echo "new file" > $testroot/wt/epsilon/new
+ (cd $testroot/wt && got add epsilon/new > /dev/null)
+ echo "modified file" > $testroot/wt/epsilon/zeta
+ (cd $testroot/wt && got rm gamma/delta > /dev/null)
+
+ echo ' M alpha' > $testroot/stdout.expected
+ echo ' D beta' >> $testroot/stdout.expected
+ echo 'A epsilon/new' >> $testroot/stdout.expected
+ echo 'M epsilon/zeta' >> $testroot/stdout.expected
+ echo ' A foo' >> $testroot/stdout.expected
+ echo 'D gamma/delta' >> $testroot/stdout.expected
+ (cd $testroot/wt && got stage alpha beta foo > /dev/null)
+
+ (cd $testroot/wt && got status > $testroot/stdout)
+ cmp -s $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_stage_basic
+run_test test_stage_status