Welcome to the 88th edition of Git Rev News, a digest of all things Git. For our goals, the archives, the way we work, and how to contribute or to subscribe, see the Git Rev News page on git.github.io.
This edition covers what happened during the months of May and June 2022.
Google Summer of Code contributors working on Git are now in the “Coding Period” (from June 13 to September 19) of the program and have posted at least once on their blogs:
Abhradeep Chakraborty, who works on “Reachability bitmap improvements”, has published his latest post on his Medium blog.
Shaoxuan Yuan, who works on “More Sparse Index Integrations” has published his latest post on his website.
Jaydeep Das, who works on “Unify ref-filters with other pretty formats” has published his latest post on his website.
Bug in merge-ort (rename detection can have collisions?)
Glen Choo reported on the mailing list that git merge
was failing
on certain branches of a repo used at his workplace. As the repo is
a public one, Glen was able to share the full recipe to reproduce the bug.
When following it, this error appears:
Assertion failed: (ci->filemask == 2 || ci->filemask == 4), function apply_directory_rename_modifications, file merge-ort.c, line 2410.
Glen noticed that the bug seemed to be specific to the “ort” merge strategy, which became the default merge strategy in Git 2.34.0 released last November. When using the “recursive” strategy, which used to be the default merge strategy before “ort” took over, the merge seemed to work as expected.
Glen also tried to debug the issue by himself and found that the reason for the assertion failure seemed to be that two files involved in the merge were renames of each other.
Elijah Newren, who developed the new “ort” strategy, thanked Glen for the detailed report, and said that he found a small reproduction recipe to simplify what’s going on. He explained it with the following sequence:
# Commit O: sub1/file, sub2/other
# Commit A: sub3/file, sub2/{other, new_add_add_file_1}
# Commit B: sub1/{file, newfile}, sub1/sub2/{other, new_add_add_file_2}
#
# In words:
# A: sub1/ -> sub3/, add sub2/new_add_add_file_1
# B: sub2/ -> sub1/sub2, add sub1/newfile, add sub1/sub2/new_add_add_file_2
He noted, though, that he can also trigger a different fatal error in the “ort” strategy with a small tweak to the test setup, and can also trigger that same other fatal error in the “recursive” strategy with his test cases.
He then explained that both the “ort” and “recursive” merge strategies have code to avoid “doubly transitive [directory] renames”. Such renames happen when, for example, on one side of the merge a directory named “A” is renamed to “B”, while on the other side “B” is renamed to “C”.
However, the code to avoid “doubly transitive [directory] renames” is fooled when a parent directory of a directory is renamed. For example if on one side a directory named “A” is renamed to “B”, while on the other side a leading directory of “B” is renamed to “C”. That still wouldn’t be quite enough to trigger this bug, though. It also requires adding a file into directory A on one side and a file with the same name into directory B on the other.
Junio Hamano, the Git maintainer, thanked Elijah for his continued support of the merge strategy, and noticed that at least the code was not “making a silent mismerge” in this special case, and that the recursive strategy could be used as a fallback.
Elijah replied that he was glad the recursive strategy worked for Glen but noted that it didn’t work with his minimal reproduction test case, which suggests it’s less reliable as a fallback than one might hope.
Glen then wondered if turning off rename detection could help in case of merges with complex renames like this, but Elijah pointed out that might be more problematic than helpful, particularly since this case had a very large number of renames and users tend to have difficulty correctly resolving the conflicts that result from a lack of rename detection. However, he suggested that if turning off rename detection was really wanted that one could use the “resolve” strategy instead, which “is roughly the recursive strategy minus the renames and the multiple merge base handling”.
Elijah also posted a small patch series that adds test cases demonstrating the bug Glen found and the related ones he found based on it, and fixes the bugs in the ort strategy. (The recursive strategy is deprecated, and the bugs noted here are not security critical.)
Jonathan Tan reviewed the series and verified that it indeed fixes Glen’s test case. Calvin Wan also commented on the patch series. So there is good hope that after a few iterations to polish the series the bugs will be fixed soon.
Events
Various
Light reading
Git tools and sites
git fsck
, which finds problems, but does not fix them.
It is a Haskell program,
developed as a spinoff of git-annex (for large files management).This edition of Git Rev News was curated by Christian Couder <christian.couder@gmail.com>, Jakub Narębski <jnareb@gmail.com>, Markus Jansen <mja@jansen-preisler.de> and Kaartic Sivaraam <kaartic.sivaraam@gmail.com> with help from Bruno Brito, Elijah Newren, Matheus Tavares and Johannes Schindelin.