git/list[1] front-page[2] threads[3] people[4] search[5] about
 

commit-graph: change in "best" merge-base when ambiguous

From
Derrick Stolee <stolee@gmail.com>
Date
May 21, 2018, 18:10 UTC
Message-ID
<e78a115a-a5ea-3c0a-5437-51ba0bcc56e1@gmail.com>
Hello all,

While working on the commit-graph feature, I made a test commit that sets core.commitGraph and gc.commitGraph to true by default AND runs 'git commit-graph write --reachable' after each 'git commit' command. This helped me find instances in the test suite where the commit-graph feature changes existing functionality. Most of these were in regards to grafts, replace-objects, and shallow-clones (as expected) or when trying to find a corrupt or hidden commit (the commit-graph hides this corrupt/missing data). However, there was one interesting case that I'd like to mention on-list.

In t6024-recursive-merge.sh, we have the following commit structure:
     # 1 - A - D - F
     #   \   X   /
     #     B   X
     #       X   \
     # 2 - C - E - G

When merging F to G, there are two "best" merge-bases, A and C. With core.commitGraph=false, 'git merge-base F G' returns A, while it returns C when core.commitGraph=true. This is due to the new walk order when using generation numbers, although I have not dug deep into the code to point out exactly where the choice between A and C is made. Likely it's just whatever order they are inserted into a list.

In the Discussion section of the `git merge-base` docs [1], we have the following:

     When the history involves criss-cross merges, there can be more 
than one best common ancestor for two commits. For example, with this 
topology:
     ---1---o---A
         \ /
          X
         / \
     ---2---o---o---B
     both 1 and 2 are merge-bases of A and B. Neither one is better than 
the other (both are best merge bases). When the --all option is not 
given,     it is unspecified which best one is output.

This means our official documentation mentions that we do not have a concrete way to differentiate between these choices. This makes me think that this change in behavior is not a bug, but it _is_ a change in behavior. It's worth mentioning, but I don't think there is any value in making sure `git merge-base` returns the same output.

Does anyone disagree? Is this something we should solidify so we always have a "definitive" merge-base?

The biggest reason I think we should avoid sticking to the existing behavior is that the current behavior depends on the walk order. That means we would not be able to concretely define a tie-breaker without changing the existing behavior anyway.

Thanks, -Stolee

[1] https://git-scm.com/docs/git-merge-base#_discussion
Next: Elijah Newren
Message 1 of 10 in “commit-graph: change in "best" merge-base when ambiguous”
  1. Derrick StoleeMay 21, 2018
  2. Elijah NewrenMay 21, 2018
  3. Jeff KingMay 21, 2018
  4. Stefan BellerMay 21, 2018
  5. Jeff KingMay 21, 2018
  6. Jacob KellerMay 21, 2018
  7. Michael HaggertyMay 22, 2018
  8. Derrick StoleeMay 22, 2018
  9. Jakub NarebskiMay 24, 2018
  10. Michael HaggertyMay 25, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.