From: Stefan Sperling Subject: fix 'got log -p path' bug To: gameoftrees@openbsd.org Date: Mon, 4 May 2020 15:06:22 +0200 I noticed that this command in got's own Git repository will error out on the commit which added .gitignore: got log -p .gitignore The unexpected error is "got: no such entry found in tree". This is a legitimate condition: The path does not exist in the parent commit of the commit which added the .gitignore file. What is going wrong is that our code doesn't gracefully handle this error condition. Below is a fix and a test which reproduces the problem. ok? diff 010fe6f0ea0a54c2bc1f5eb998afd8d44e235b05 /home/stsp/src/got blob - 7bf94578ea43d411c5be1b07496fbc6ab378c4c1 file + got/got.c --- got/got.c +++ got/got.c @@ -2923,13 +2923,16 @@ print_patch(struct got_commit_object *commit, struct g err = got_object_id_by_path(&obj_id1, repo, qid->id, path); if (err) { - free(obj_id2); - goto done; - } - err = got_object_id_str(&id_str1, obj_id1); - if (err) { - free(obj_id2); - goto done; + if (err->code != GOT_ERR_NO_TREE_ENTRY) { + free(obj_id2); + goto done; + } + } else { + err = got_object_id_str(&id_str1, obj_id1); + if (err) { + free(obj_id2); + goto done; + } } } err = got_object_get_type(&obj_type, repo, obj_id2); blob - ea958f5ec1a9401d85234c78905402873c196e81 file + regress/cmdline/log.sh --- regress/cmdline/log.sh +++ regress/cmdline/log.sh @@ -283,6 +283,40 @@ function test_log_limit { test_done "$testroot" "0" } +function test_log_patch_added_file { + local testroot=`test_init log_patch_added_file` + local commit_id0=`git_show_head $testroot/repo` + + got checkout $testroot/repo $testroot/wt > /dev/null + ret="$?" + if [ "$ret" != "0" ]; then + test_done "$testroot" "$ret" + return 1 + fi + + echo "new file" > $testroot/wt/new + (cd $testroot/wt && got add new >/dev/null) + (cd $testroot/wt && got commit -m 'test log_limit' > /dev/null) + local commit_id1=`git_show_head $testroot/repo` + + echo "commit $commit_id1 (master)" > $testroot/stdout.expected + # This used to fail with 'got: no such entry found in tree' + (cd $testroot/wt && got log -l1 -p new > $testroot/stdout.patch) + ret="$?" + if [ "$ret" != "0" ]; then + echo "got log command failed unexpectedly" >&2 + test_done "$testroot" "$ret" + return 1 + fi + grep ^commit $testroot/stdout.patch > $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_log_nonexistent_path { local testroot=`test_init log_nonexistent_path` local head_rev=`git_show_head $testroot/repo` @@ -618,6 +652,7 @@ run_test test_log_in_worktree run_test test_log_in_worktree_with_path_prefix run_test test_log_tag run_test test_log_limit +run_test test_log_patch_added_file run_test test_log_nonexistent_path run_test test_log_end_at_commit run_test test_log_reverse_display