Search code examples
gitancestor

git - get direct descendants of A that connect to B


Is it possible to get the list of revisions that direct descendants of A that are direct ancestors of B? I I try git log A..B I will get the list of revisions that are ancestors of B that are not in the history of A, which is not exactly what I want. I need only revisions that directly connect A and B.


Solution

  • Yes: add --ancestry-path to your revision specification. (This works for any command that uses commit-graph-walking, including git log and git rev-list.) But I will note that I'm not sure what you mean by the adjective "direct" here.

    Note that A..B means B ^A, i.e., use the set ancestors(B) - ancestors(A) (where subtraction here is set-subtraction). Adding --ancestry-path means that after doing the set subtraction (or more accurately, while constructing the subtracted set), Git also subtracts away any commit that is not a descendant of the negated revision A.

    Internally, Git does this by marking negated commit hash IDs (like A in A..B or B ^A) with a flag called BOTTOM. Such commits are collected into a "bottom list" and Git makes sure that each commit C that might be in the A..B range has a bottom-commit as one of its ancestors. This matters if you use git rev-list --ancestry-path X ^Y ^Z for instance: commits can be descendants of Y or Z.\


    Here's an example graph fragment showing which commits are selected () or not-selected () even though they are "in the range" of A..B:

    ...--A--●---●--B--...
       \  \    /
        ○--●--●
    

    Note that commit A is not selected, and commit B is selected, here.