How do I pass a range of commits to git log?
Asked Answered
E

3

1

Ok I give up, I am a Bash noob.

This:

$ git log --no-walk --oneline 6980e6ecede8e188f434f6da669c2297f28decfe 458567536c1f20498da033cb0e42da74439ef12e

prints:

4585675 NNN bethDataFiles, allBethFiles belong to game/game/constants.py
6980e6e NNN bethDataFiles, allBethFiles belong to game/game/constants.py

This:

git log -g --pretty=format:'%ai %H' | awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"'| cut -d' ' -f 4 | awk '!a[$0]++' | tr '\n' ' '

prints me a range of commits:

ba4ee4b099d23642e6cad56d9f41974f6e767781 1daaede0f4e11cae0e0bb00b9ebb43bba4f5671 ...

Now why on earth piping this command to git log as in:

git log -g --pretty=format:'%ai %H' | awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"'| cut -d' ' -f 4 | awk '!a[$0]++' | tr '\r\n' ' ' | git log --format='%h %s %ai' --no-walk

only shows me the first commit:

ba4ee4b _load_active_plugins pre BAPI code - superseded by games.py API: 2016-04-14 19:38:41 +0200

?

$ git --version
git version 2.6.1.windows.1
Embellish answered 19/5, 2016 at 14:6 Comment(0)
B
3

There's a general form with bash and Unix utilities:

... | ... | ... | xargs cmd

(xargs runs cmd more than once as needed after inserting stdin as arguments), or:

cmd $(... | ... | ...)

which runs the pipeline, then provides its output as arguments to cmd.

However, with git log you don't need this as it accepts --stdin to get it to read revision IDs from standard input.

I think we can simplify your pipeline (incidentally, I did not realize some versions of awk know how to compare dates directly; older awk did not):

git log -g --pretty=format:'%ai %H' | \
    awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"' | \
    cut -d' ' -f 4 | awk '!a[$0]++' | tr '\n' ' '

We want the revisions to be one per line so there's no need for the tr. We can also use the original awk to check the uniqueness of the hash ID. So:

git log -g --pretty=format:'%ai %H' | \
    awk '$0 >= "2016-04-13" && $0 <= "2016-04-15" && !a[$4]++ { print $4 }' | \
    git log --no-walk --stdin

Incidentally, it's only because git log -g does a reflog walk (which may produce duplicate hashes) that we need the associative array a to discard repeat hashes.

(edited per comment, but still untested)

Barquentine answered 19/5, 2016 at 17:47 Comment(6)
"it's only because git log -g does a reflog walk (which may produce duplicate hashes) that we need the associative array a to discard repeat hashes" - yep I realized that. Thanks for cleaning up my noobish pipeline - the tr I had added cause I thought that the input being \n delimited might make a difference - it was me hitting in the darkEmbellish
cut -d' ' -f 4 should still be required in the last example, is it not?Burkitt
@JoshKlodnicki: not if I did it right. Note that this tests a[$4], not a[$0]. $4 is from %ai %H producing, e.g., 2021-08-16 12:15:44 -0700 225bc32a989d7a22fa6addafd4ce7dcd04675dbf. Comparing with $0 (rather than $1 $2 $3 put together) seems a bit iffy unless the awk you're using explicitly says that it uses the date-and-time (and maybe offset, or not) and then stops, but I got that from the original post and haven't tested it carefully.Barquentine
@Barquentine Yes, awk works fine, but git log --stdin expects a list of commit hashes (without the dates). I am suggesting adding cut after the awk, unless I am missing something. Of course, selecting the field within awk (print $4) would probably be even better.Burkitt
@JoshKlodnicki: oh, I see, quite right! Well, that's what happens with untested code. :-) I'll edit the awk to add { print $4 }...Barquentine
@Barquentine Thank you for taking the time for a 5-year-old post!Burkitt
T
4

git log does not read any input from stdin. Try doing echo "abcd123" | git log --no-walk and you will notice that git log will ignore stdin. It will look for a commit hash specified as an argument, but there is none. Hence, it will use the default HEAD, and print the latest commit on your current branch.

To print ranges of commit, you could for example do:

If you know the first and last commit hash:

git log abcd123..4567abc

If you know the time interval:

git log --since="10 days ago" --until="5 days ago"

Or if you know the specific dates:

git log --since="2016-04-13" --until="2016-04-15"
Tuppence answered 19/5, 2016 at 14:17 Comment(3)
Thanks, this clears the confusion up but I want to print info on those specific commits that are not a continuous range.Embellish
Actually, git rev-list does have a --stdin argument, and since git log and git rev-list share most of their code, it turns out git log has an (un-advertised) --stdin too.Barquentine
Too late to edit comment: I checked the documentation and --stdin is actually advertised.Barquentine
B
3

There's a general form with bash and Unix utilities:

... | ... | ... | xargs cmd

(xargs runs cmd more than once as needed after inserting stdin as arguments), or:

cmd $(... | ... | ...)

which runs the pipeline, then provides its output as arguments to cmd.

However, with git log you don't need this as it accepts --stdin to get it to read revision IDs from standard input.

I think we can simplify your pipeline (incidentally, I did not realize some versions of awk know how to compare dates directly; older awk did not):

git log -g --pretty=format:'%ai %H' | \
    awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"' | \
    cut -d' ' -f 4 | awk '!a[$0]++' | tr '\n' ' '

We want the revisions to be one per line so there's no need for the tr. We can also use the original awk to check the uniqueness of the hash ID. So:

git log -g --pretty=format:'%ai %H' | \
    awk '$0 >= "2016-04-13" && $0 <= "2016-04-15" && !a[$4]++ { print $4 }' | \
    git log --no-walk --stdin

Incidentally, it's only because git log -g does a reflog walk (which may produce duplicate hashes) that we need the associative array a to discard repeat hashes.

(edited per comment, but still untested)

Barquentine answered 19/5, 2016 at 17:47 Comment(6)
"it's only because git log -g does a reflog walk (which may produce duplicate hashes) that we need the associative array a to discard repeat hashes" - yep I realized that. Thanks for cleaning up my noobish pipeline - the tr I had added cause I thought that the input being \n delimited might make a difference - it was me hitting in the darkEmbellish
cut -d' ' -f 4 should still be required in the last example, is it not?Burkitt
@JoshKlodnicki: not if I did it right. Note that this tests a[$4], not a[$0]. $4 is from %ai %H producing, e.g., 2021-08-16 12:15:44 -0700 225bc32a989d7a22fa6addafd4ce7dcd04675dbf. Comparing with $0 (rather than $1 $2 $3 put together) seems a bit iffy unless the awk you're using explicitly says that it uses the date-and-time (and maybe offset, or not) and then stops, but I got that from the original post and haven't tested it carefully.Barquentine
@Barquentine Yes, awk works fine, but git log --stdin expects a list of commit hashes (without the dates). I am suggesting adding cut after the awk, unless I am missing something. Of course, selecting the field within awk (print $4) would probably be even better.Burkitt
@JoshKlodnicki: oh, I see, quite right! Well, that's what happens with untested code. :-) I'll edit the awk to add { print $4 }...Barquentine
@Barquentine Thank you for taking the time for a 5-year-old post!Burkitt
H
2
  git log --format='%h %s %ai' --no-walk \
       $(git log -g --pretty=format:'%ai %H' \
             | awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"'\
             | cut -d' ' -f 4 | awk '!a[$0]++' | tr '\r\n' ' '
        )

Or slightly better

  git log -g --pretty=format:'%ai %H' | \
        awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"' |\
        cut -d' ' -f 4 | awk '!a[$0]++' | \
        xargs git log --format='%h %s %ai' --no-walk

But I wonder why don't you wish to use --since and --until options of git log ?

Hybris answered 19/5, 2016 at 14:14 Comment(1)
Thanks this works but could you elaborate a bit on the differences on those 2 and why the second is better ? As to why I do use --since and co: https://mcmap.net/q/166208/-how-to-get-git-to-show-commits-in-a-specified-date-range-for-author-date/281545Embellish

© 2022 - 2024 — McMap. All rights reserved.