Download raw body.
staging the reverse of the staged diff
found this by chance; i've staged a debug printf somewhere by accident, then removed, staged the removal and... the file was still staged but with an empty diff! (it was the only edit to that file) patch below tries to make stage_path slightly more clever by checking the staged blob and the file blob: if they're the same we've effectively unstaged a file. does this makes sense? am i trying to make 'got stage' too much clever? on the other hand, this 'got stage' trick can be used to make empty commits: $ echo clobber > got/got.c $ got stage got/got.c $ got diff -s | got patch -R $ got stage got/got.c $ got commit -m "I'm an empty commit!" but feels hackish :) (some project sometimes requires the contributor to make an "empty commit" for copyright stuff, see for e.g. https://github.com/mawww/kakoune/blob/master/CONTRIBUTING, but this is probably a separate issue.) diff ce2bf7b7c9058374563c6db8608dbab9df2bba7d /home/op/w/got blob - ca8e4d6a6ba63c5f3e16487196a7a3bf16fa888b file + lib/worktree.c --- lib/worktree.c +++ lib/worktree.c @@ -8068,6 +8068,17 @@ stage_path(void *arg, unsigned char status, err = (*a->status_cb)(a->status_arg, GOT_STATUS_NO_CHANGE, get_staged_status(ie), relpath, blob_id, new_staged_blob_id, NULL, dirfd, de_name); + if (err) + break; + /* + * When staging the reverse of the staged diff, + * implicitly unstage the file. + */ + if (memcmp(ie->staged_blob_sha1, ie->blob_sha1, + sizeof(ie->blob_sha1)) == 0) { + got_fileindex_entry_stage_set(ie, + GOT_FILEIDX_STAGE_NONE); + } break; case GOT_STATUS_DELETE: if (staged_status == GOT_STATUS_DELETE) blob - e16d9854340821bff1be14c3086fbe1a59b26843 file + regress/cmdline/stage.sh --- regress/cmdline/stage.sh +++ regress/cmdline/stage.sh @@ -2154,6 +2154,59 @@ test_stage_patch_removed_twice() { test_done "$testroot" "$ret" } +test_stage_patch_reversed() { + local testroot=`test_init stage_patch_reversed` + + got checkout $testroot/repo $testroot/wt > /dev/null + ret=$? + if [ $ret -ne 0 ]; then + test_done "$testroot" "$ret" + return 1 + fi + + echo 'ALPHA' > $testroot/wt/alpha + (cd $testroot/wt && got stage alpha > $testroot/stdout) + ret=$? + if [ $ret -ne 0 ]; then + test_done "$testroot" "$ret" + return 1 + fi + + echo ' M alpha' > $testroot/stdout.expected + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + echo 'alpha' > $testroot/wt/alpha + (cd $testroot/wt && got stage alpha > $testroot/stdout) + ret=$? + if [ $ret -ne 0 ]; then + test_done "$testroot" "$ret" + return 1 + fi + + echo ' M alpha' > $testroot/stdout.expected + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + (cd $testroot/wt && got status > $testroot/stdout) + cmp -s /dev/null $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u /dev/null $testroot/stdout + fi + test_done "$testroot" "$ret" +} + test_stage_patch_quit() { local testroot=`test_init stage_patch_quit` @@ -2987,6 +3040,7 @@ run_test test_stage_patch_added run_test test_stage_patch_added_twice run_test test_stage_patch_removed run_test test_stage_patch_removed_twice +run_test test_stage_patch_reversed run_test test_stage_patch_quit run_test test_stage_patch_incomplete_script run_test test_stage_symlink
staging the reverse of the staged diff