1

I noticed when I'm on a branch (we'll call it feat-123) that's only a couple commits in, git log shows the whole history of the branch I branched from (develop). Is there some way to show the log only as far back as the point from which feat-123 was created?

CaptSaltyJack
  • 15,283
  • 17
  • 70
  • 99

3 Answers3

2

If you know that feat-123 was branched from develop, you can use double-dot .. syntax to limit git log output to only those commits in feat-123 that aren't also in develop:

git log --oneline --graph develop..feat-123

To learn more about double-dot and other helpful commit filtering syntaxes, see

  1. Revision Selection - Commit Ranges from the **FREE online Pro Git book.
  2. Git Revisions - Specifying Ranges from the official Linux Kernel Git documentation.
2

To see a list of which commits are on one branch but not another, use git log:

   git log oldbranch ^newbranch --no-merges

Show commit logs for all commits on oldbranch that are not on newbranch.

Also, You can list multiple branches to include and exclude, e.g.

   git log oldbranch1 oldbranch2 ^newbranch1 ^newbranch2 --no-merges
D4NI3LS
  • 305
  • 3
  • 9
2

There's no shorthand for "find any point where history rejoins", so you have to use something like what Cupcake and D4NI3LS suggested: explicitly stop logging at-or-before such a point.

There is, however, a way to automate this. It can be encapsulated in a "one line" shell script:

git log HEAD --not $(
    git for-each-ref --format='%(refname:short)' refs/heads/ |
    grep -v "^$(git symbolic-ref -q --short HEAD)$"
) "$@"

How this works:

  • The innermost bit, git symbolic-ref -q --short HEAD, prints the current branch name, or nothing at all if you are not on a branch ("detached HEAD" state).
  • We turn this into a grep pattern by adding ^ (anchor at start-of-line) and $ (anchor at end).
  • We use that to remove the current branch (if any) from git for-each-ref output.
  • The for-each-ref output is the short refname for every branch, i.e., every ref in refs/heads/. Thus, if your complete set of branch names are, for instance, monty, python, flying, and circus and you're on branch flying, this lists monty, python, and circus.
  • Finally, we give all of this to --not, after asking git log to start at HEAD. The log command uses git rev-list to start from wherever you ask it, and keep going backwards until something (in this case, the --not list) makes it stop. And of course we add "$@" so that any other command-line arguments are included.

Since it's a one liner, it can be embedded in ~/.gitconfig, as an alias:

[alias]
        ltf = !git log HEAD --not $(git for-each-ref \
                --format='%(refname:short)' refs/heads | \
                grep -v "^$(git symbolic-ref -q --short HEAD)$")

and now git ltf, git ltf --oneline, etc., all do the trick. (I don't know if I like the name ltf, it stands for "log to fork" but this is more of a "log to join". Maybe lbr for "log branch"?)

Community
  • 1
  • 1
torek
  • 448,244
  • 59
  • 642
  • 775
  • The alias may need a terminating `--` (after the final close bracket) to ensure that the refs are discriminated from possible filenames. to avoid the error fatal: ambiguous argument 'Documentation': both revision and filename Use '--' to separate paths from revisions, like this: 'git [...] -- [...]'. Plus the final `"$@"` hasn't been copied into the alias (but again may conflict with the `--` placement). – Philip Oakley Sep 07 '13 at 22:15
  • The alias has the side effect of acting like the `"$@"` is already in there. I didn't want a terminating `--` as I want to allow more options to `log`, e.g., `--oneline`. On the other hand the `--not` is still in effect, maybe there should be a second `--not` to cancel it out... – torek Sep 07 '13 at 23:31
  • I'll try that (`--not`) out. I wasn't aware of the alias `"$@"` action. Thanks. – Philip Oakley Sep 09 '13 at 16:31