Search code examples
gitrevision

how to obtain all commits between two commits in the version tree?


Given that there is a tree depicted as below:

        d1a--d1b---d1c--d1d--d1e     <dev>
       /                /      \
a--b--c---d---e--------f---g----h--i <master>

a is the oldest commit, while i is the latest one, the HEAD d1a is branched off master to a new branch dev, added some new changes and merged changes from master (from f to d1d), and then eventually merged back to 'master' at h.

When doing git log/rev-list, how do I select:

  1. all commits from HEAD to e: i, h, g, f, e, d1e, d1d
  2. all commits from HEAD to g: i, h, g
  3. all commits from HEAD to d1b: i, h, g, f, d1e, d1d, d1c, d1b

Many thanks in advance for any pointers/suggestions/hints!


Solution

  • From man git-rev-parse:

    SPECIFYING RANGES
       History traversing commands such as git log operate on a set of commits, not just a single commit. To these
       commands, specifying a single revision with the notation described in the previous section means the set of commits
       reachable from that commit, following the commit ancestry chain.
    
       To exclude commits reachable from a commit, a prefix ^ notation is used. E.g. ^r1 r2 means commits reachable from r2
       but exclude the ones reachable from r1.
    
       This set operation appears so often that there is a shorthand for it. When you have two commits r1 and r2 (named
       according to the syntax explained in SPECIFYING REVISIONS above), you can ask for commits that are reachable from r2
       excluding those that are reachable from r1 by ^r1 r2 and it can be written as r1..r2.
    
       A similar notation r1...r2 is called symmetric difference of r1 and r2 and is defined as r1 r2 --not $(git
       merge-base --all r1 r2). It is the set of commits that are reachable from either one of r1 or r2 but not from both.
    
       Two other shorthands for naming a set that is formed by a commit and its parent commits exist. The r1^@ notation
       means all parents of r1. r1^! includes commit r1 but excludes all of its parents.
    

    There is even an example, so I'd RTFM ;-)