Download raw body.
got log -b path gets confused by merge commits
On Mon, Jan 29, 2024 at 03:07:43PM +0100, Stefan Sperling wrote: >On Sun, Jan 28, 2024 at 06:34:17PM +0000, James Cook wrote: >> I've managed to trigger the error >> >> got: //d/g: no such entry found in tree >> >> by running got log -b d/g or tog log -b d/g in a specially crafted repo. > >Thanks! This is an edge case I had overlooked. >Below is a fix which I tested manually. Does it work for you? > >The patch repeats an if-condition in a slightly awkward way because the >diff becomes easier to read, avoiding indentation of a lot of lines by >one more level. Essentially we need to guard the STAILQ_FOREACH loop >with if (merged_id != NULL). > >> I have a script (at bottom) to reproduce and am happy to turn that into a >> patch for regress/cmdline. > >Yes, please do turn it into a regression test if you have time. Thanks, your patch fixes the problem for me, including in the original private repo where I discovered it. Comparing the output of "got log -b path" with "git log path", I notice got likes to show some merge commits that git skips over, but that doesn't seem like a big problem. Below is a patch adding a test case to log.sh based on my repro script. I named the test ..._corner_case because it's pretty specific. I followed the pattern I see of using git commands instead of got commands to set up the repo. -- James diff fc9b745fd3b1a01f7e89f269600db36ad5222b3e 88456a98463ce990d4f4df3c98274b43fd148eda commit - fc9b745fd3b1a01f7e89f269600db36ad5222b3e commit + 88456a98463ce990d4f4df3c98274b43fd148eda blob - 4721d314c761fef6ff7f1dfe3ff55d52e6d39216 blob + 2382dfe2d37e40510f2213eafd7c5177407f3df6 --- regress/cmdline/log.sh +++ regress/cmdline/log.sh @@ -769,6 +769,60 @@ test_log_changed_paths() { test_done "$testroot" "$ret" } +test_log_merge_commit_corner_case() { + local testroot=`test_init log_merge_commit_corner_case 1` + + # Create the following commit graph (most recent commit shown first): + # + # o create dir/beta + # | + # o merge (does not touch dir) + # / \ + # o o changes which don't touch the directory "dir" + # \ / + # o initial commit, which includes directory "dir" but not dir/beta + + + mkdir $testroot/repo/dir + touch $testroot/repo/dir/alpha + git -C $testroot/repo add dir/alpha + git_commit $testroot/repo -m "initial commit" + + git -C $testroot/repo checkout -q -b aux + touch $testroot/repo/gamma + git -C $testroot/repo add gamma + git_commit $testroot/repo -m "change on aux" + + git -C $testroot/repo checkout -q master + touch $testroot/repo/delta + git -C $testroot/repo add delta + git_commit $testroot/repo -m "change on master" + + git -C $testroot/repo merge -q -m "merge" aux + + touch $testroot/repo/dir/beta + git -C $testroot/repo add dir/beta + git_commit $testroot/repo -m "add beta" + + head_commit=`git_show_head $testroot/repo` + + got log -r $testroot/repo -b dir/beta | grep ^commit > $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + echo "log command failed unexpectedly" >&2 + test_done "$testroot" "1" + return 1 + fi + + echo "commit $head_commit (master)" > $testroot/stdout.expected + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + fi + test_done "$testroot" "$ret" +} + test_log_submodule() { local testroot=`test_init log_submodule` @@ -1201,6 +1255,7 @@ run_test test_log_end_at_commit run_test test_log_reverse_display run_test test_log_in_worktree_different_repo run_test test_log_changed_paths +run_test test_log_merge_commit_corner_case run_test test_log_submodule run_test test_log_diffstat run_test test_log_commit_keywords
got log -b path gets confused by merge commits