commit d3e7c587d4fa8caef61be4b2bbc9c388b95e7bb9 from: Stefan Sperling date: Sat Aug 03 15:42:21 2019 UTC handle double-staging commit - 24278f3006b96a0d8ff909454e8fa5ea4fc73ed3 commit + d3e7c587d4fa8caef61be4b2bbc9c388b95e7bb9 blob - 8450cbba950e2cfad6e7250c3bb2987c2599c8cf blob + 462aba4ce38cf417465bd97d2f372b539d4aed41 --- include/got_error.h +++ include/got_error.h @@ -115,6 +115,7 @@ #define GOT_ERR_NO_MERGED_PATHS 99 #define GOT_ERR_COMMIT_BRANCH 100 #define GOT_ERR_FILE_STAGED 101 +#define GOT_ERR_STAGE_NO_CHANGE 102 static const struct got_error { int code; @@ -232,6 +233,7 @@ static const struct got_error { { GOT_ERR_COMMIT_BRANCH, "will not commit to a branch outside the " "\"refs/heads/\" reference namespace" }, { GOT_ERR_FILE_STAGED, "file is staged" }, + { GOT_ERR_STAGE_NO_CHANGE, "no changes to stage" }, }; /* blob - 08c378a8a6ac617975161686767d71afe16c3550 blob + 67da6f9503e2bf8e19e977686131c7b17312f4b0 --- lib/worktree.c +++ lib/worktree.c @@ -4924,20 +4924,19 @@ stage_path(const char *relpath, const char *ondisk_pat { const struct got_error *err = NULL; struct got_fileindex_entry *ie; - unsigned char status; + unsigned char status, staged_status; struct stat sb; struct got_object_id blob_id, *staged_blob_id = NULL; uint32_t stage; ie = got_fileindex_entry_get(fileindex, relpath, strlen(relpath)); - if (ie == NULL) { - err = got_error_path(relpath, GOT_ERR_FILE_STATUS); - goto done; - } + if (ie == NULL) + return got_error_path(relpath, GOT_ERR_FILE_STATUS); err = get_file_status(&status, &sb, ie, ondisk_path, repo); if (err) - goto done; + return err; + staged_status = get_staged_status(ie); switch (status) { case GOT_STATUS_ADD: @@ -4949,7 +4948,7 @@ stage_path(const char *relpath, const char *ondisk_pat memcpy(&blob_id.sha1, ie->blob_sha1, SHA1_DIGEST_LENGTH); memcpy(ie->staged_blob_sha1, staged_blob_id->sha1, SHA1_DIGEST_LENGTH); - if (status == GOT_STATUS_ADD) + if (status == GOT_STATUS_ADD || staged_status == GOT_STATUS_ADD) stage = GOT_FILEIDX_STAGE_ADD; else stage = GOT_FILEIDX_STAGE_MODIFY; @@ -4959,11 +4958,16 @@ stage_path(const char *relpath, const char *ondisk_pat staged_blob_id, NULL); break; case GOT_STATUS_DELETE: + if (staged_status == GOT_STATUS_DELETE) + break; stage = GOT_FILEIDX_STAGE_DELETE; got_fileindex_entry_stage_set(ie, stage); err = (*status_cb)(status_arg, GOT_STATUS_NO_CHANGE, get_staged_status(ie), relpath, NULL, NULL, NULL); break; + case GOT_STATUS_NO_CHANGE: + err = got_error_path(relpath, GOT_ERR_STAGE_NO_CHANGE); + break; default: err = got_error_path(relpath, GOT_ERR_FILE_STATUS); break; blob - 8cd9094ad29913c485a3282d63f6fa6b048b4879 blob + 9eee79563e1a7280759ad39096b5687b450f2709 --- regress/cmdline/stage.sh +++ regress/cmdline/stage.sh @@ -33,9 +33,86 @@ function test_stage_basic { echo ' M alpha' > $testroot/stdout.expected echo ' D beta' >> $testroot/stdout.expected + echo ' A foo' >> $testroot/stdout.expected + (cd $testroot/wt && got stage alpha beta foo > $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" +} + +function test_double_stage { + local testroot=`test_init double_stage` + + 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) + (cd $testroot/wt && got stage alpha beta foo > /dev/null) + + echo "got: alpha: no changes to stage" > $testroot/stderr.expected + (cd $testroot/wt && got stage alpha 2> $testroot/stderr) + cmp -s $testroot/stderr.expected $testroot/stderr + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stderr.expected $testroot/stderr + test_done "$testroot" "$ret" + return 1 + fi + + (cd $testroot/wt && got stage beta > $testroot/stdout) + if [ "$ret" != "0" ]; then + echo "got stage command failed unexpectedly" >&2 + test_done "$testroot" "1" + return 1 + fi + 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: foo: no changes to stage" > $testroot/stderr.expected + (cd $testroot/wt && got stage foo 2> $testroot/stderr) + cmp -s $testroot/stderr.expected $testroot/stderr + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stderr.expected $testroot/stderr + test_done "$testroot" "$ret" + return 1 + fi + + echo "modified file again" > $testroot/wt/alpha + echo "modified new file" > $testroot/wt/foo + + echo ' M alpha' > $testroot/stdout.expected echo ' A foo' >> $testroot/stdout.expected (cd $testroot/wt && got stage alpha beta foo > $testroot/stdout) + 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 ' M alpha' > $testroot/stdout.expected + echo ' D beta' >> $testroot/stdout.expected + echo ' A foo' >> $testroot/stdout.expected + (cd $testroot/wt && got status > $testroot/stdout) cmp -s $testroot/stdout.expected $testroot/stdout ret="$?" if [ "$ret" != "0" ]; then @@ -440,6 +517,7 @@ function test_stage_revert { } run_test test_stage_basic +run_test test_double_stage run_test test_stage_status run_test test_stage_add_already_staged_file run_test test_stage_rm_already_staged_file