Git log: list all parents commits
Asked Answered
H

3

6

In a shared GitHub repository, I would like to use git log to show a list of recent commits.

The current history is similar to the following:

                       (master)
B------Merge1--Merge2--Merge3
      /       /       / 
 - -C1       /       /
      - - -C2       /
 - - -C3----------C4

Where the Merge commits are result of a merged pull request, and the C commits are coming from forks of this repository.

git log shows something like this:

git log --oneline master
    Merge3
    Merge2
    Merge1
    B

But what I'm really interested in are the C commits. git log --graph is the only possible way I found to show C1, C2 and C3.

Is there any other option (not involving --graph) that would show C1, C2, and C3?

I would like to be able to do something like this

git log --oneline --no-merges <...insert magic here...> master
 C4
 C3
 C2
 C1
 B

The only sensible thing I found in the man page is --first-parent, but i found no way to disable or invert it.

Harappa answered 18/10, 2013 at 4:6 Comment(0)
R
2

If you're not doing your merges and pulls with --no-ff having actual merge commits at a branch tip is going to be an unreliable indicator, so if you just don't want to see the merge commits,

git log --no-merges --oneline -n 10   # or --since, or something, might do 

If you want to decide how far back to list based on commit attributes rev-list doesn't have as a built-in cutoff criterion it's just a matter of filtering on those attributes in the output of rev-list or more generally some log --pretty=format: selection, here's one that lists only the tips from merged branches leading to the selected branch, getting C1-C2-C4 -- since I can't figure out how you decided to bypass C4 ...

#!/bin/sh
git rev-list --parents "${@-HEAD}" \
| sed -n '/^[^ ]* [^ ]* /!q;s///;s/[^ ]*/&^!/gp' \
| xargs git log --oneline

The sed:

/^[^ ]* [^ ]* /!q      # quit at first rev with less than two parents
s///                   # strip rev and its first parent
s/[^ ]*/&^!/gp         # append ^! to all other (merged) revs

and the ^! suffix tells log to not automatically include parents.

Resinoid answered 18/10, 2013 at 4:35 Comment(8)
Thanks for your response, the rev-list command spits a lot of lines, all of them are in the form: 'shaX' or 'shaX shaY'. Something is not working with the sed expression however, it produces no output.Harappa
THat rev-list will show merge commits as "shaX shaY shaZ [...]". The sample history in your question ends with three merge commits in sequence. The output you describe has no merge commits at all. Could you clarify what the word "similar" means in your question, and perhaps also "recent"?Resinoid
I'm using GitHub and code gets into master via pull requests. Most of them are merges but some are fast-forwards. The example in my question is artificial, but it's pretty similar to the real repo history. By 'recent' I didn't mean anything specific, I'd be happy to limit output with -10, or not, i.e. show full history.Harappa
Okay, then just git log --no-merges --oneline will get you that part of it, and as far as I can tell the only problem is recency. How do you want to decide that?Resinoid
NO WAY! git log --no-merges --oneline is of course the first thing I tried and I was surprised it couldn't do it. I tried it again now just for the sake of and indeed it does EXACTLY what I expected and what I wanted. Maybe my clone was in some kind of weird state earlier? I feel like a moron.Harappa
If you post another answer git log --no-merges --oneline I'll give it the 'solved' mark.Harappa
Did it here for better completeness.Resinoid
Weird the clone I was playing yesterday still shows the merges and not the Cs above, but in a fresh clone everything works as expected. Must be something screwed in that copy then. Thanks a lot!Harappa
H
1

A possible solution is using --graph then some sed and grep magic. This kinda works but it's hacky, was hoping that git-log would be able to do this for me!

I think it needs additional options to show the proper order and not, say, by commit date.

git log --oneline --graph     \
| sed -e 's|[^a-z0-9]*||1'    \
| egrep -v '^[a-z0-9]+ Merge' \
| egrep -v "^$"

The first sed removes the branches "ascii art" that --graph mode outputs. The first grep removes all merge commits. The second grep removes empty lines.

Harappa answered 18/10, 2013 at 7:2 Comment(0)
M
0

This is what worked for me best to find all parents of a commit: I looked for all parents of Merge3. So I did

git log HEAD^

which gave me the first parent Merge2. Then I did

git log HEAD^2

which gave me the second parent C4. Then I did:

git log HEAD^3

which gave me an error. So I knew I have found all parents. I moved to C4 with

git checkout C4

and so on.

Muzz answered 22/11, 2022 at 16:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.