commit 819f385b2053664dbfd5c1d0201fb84bc7e3c5a6 from: Stefan Sperling date: Fri May 10 15:16:09 2019 UTC ensure that commits use intended base blobs for changes commit - e75eb4dad0d15e60680bf15c957ccd6099a9e22c commit + 819f385b2053664dbfd5c1d0201fb84bc7e3c5a6 blob - 640ad150c74800a6bd02833ddf62dbb7d2c07004 blob + 785766a030c1661d6a5e8806b18a277e3aebef8a --- include/got_error.h +++ include/got_error.h @@ -86,6 +86,7 @@ #define GOT_ERR_BAD_REF_TYPE 70 #define GOT_ERR_COMMIT_NO_AUTHOR 71 #define GOT_ERR_COMMIT_HEAD_CHANGED 72 +#define GOT_ERR_COMMIT_OUT_OF_DATE 73 static const struct got_error { int code; @@ -164,6 +165,8 @@ static const struct got_error { { GOT_ERR_COMMIT_NO_AUTHOR,"GOT_AUTHOR environment variable is not set" }, { GOT_ERR_COMMIT_HEAD_CHANGED, "branch head in repository has changed " "while commit was in progress" }, + { GOT_ERR_COMMIT_OUT_OF_DATE, "work tree must be updated before these " + "changes can be committed" }, }; /* blob - 51b188522dd96824bcdaad18e24bde7c84c81179 blob + d29a9bd8996f361ceba6c402b9cc22d20f7c0938 --- lib/worktree.c +++ lib/worktree.c @@ -2833,7 +2833,29 @@ got_worktree_commit(struct got_object_id **new_commit_ if (err) goto done; - /* TODO: out-of-dateness check */ + /* Out-of-dateness check against branch head. */ + TAILQ_FOREACH(pe, &commitable_paths, entry) { + struct commitable *ct = pe->data; + struct got_object_id *id_in_head; + + err = got_object_id_by_path(&id_in_head, repo, + head_commit_id, ct->in_repo_path); + if (err) { + if (err->code == GOT_ERR_NO_TREE_ENTRY && + ct->status == GOT_STATUS_ADD) { + err = NULL; + id_in_head = NULL; + } else + goto done; + } + if (id_in_head && + got_object_id_cmp(id_in_head, ct->base_id) != 0) { + err = got_error(GOT_ERR_COMMIT_OUT_OF_DATE); + free(id_in_head); + goto done; + } + free(id_in_head); + } err = got_object_open_as_tree(&head_tree, repo, head_commit->tree_id); if (err) blob - a69fc89299a34873881a00b21a3b20c1af9d65a2 blob + d9093b3371894b4a89fc9a496e26459e0e75f09f --- regress/cmdline/commit.sh +++ regress/cmdline/commit.sh @@ -138,7 +138,47 @@ function test_commit_single_file { test_done "$testroot" "$ret" } +function test_commit_out_of_date { + local testroot=`test_init commit_out_of_date` + + got checkout $testroot/repo $testroot/wt > /dev/null + ret="$?" + if [ "$ret" != "0" ]; then + test_done "$testroot" "$ret" + return 1 + fi + + echo "modified alpha" > $testroot/repo/alpha + git_commit $testroot/repo -m "modified alpha" + + echo "modified alpha" > $testroot/wt/alpha + + (cd $testroot/wt && got commit -m 'test commit_out_of_date' \ + > $testroot/stdout 2> $testroot/stderr) + + local head_rev=`git_show_head $testroot/repo` + echo -n > $testroot/stdout.expected + echo "got: work tree must be updated before these" \ + "changes can be committed" > $testroot/stderr.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 + + cmp $testroot/stderr.expected $testroot/stderr + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stderr.expected $testroot/stderr + fi + test_done "$testroot" "$ret" +} + run_test test_commit_basic run_test test_commit_new_subdir run_test test_commit_subdir run_test test_commit_single_file +run_test test_commit_out_of_date