7

There are various ways to "select" commits with git log. For example:

and many others.

However, all of these show only the commits selected for on the command line. What I want is to see all the commits in my range, but highlight (with color, or a marker, or whatever) a specific subset of these commits e.g. the commits that changed a particular file or whatever. So when doing:

git log --oneline master..@ -- path/to/frobnitz

instead of seeing:

12ca6d863 foo
6166da1fd bar
894567343 baz

I would see something like:

46984ad11 (HEAD -> master) git is fun!
2e11a5382 cool beans
>> 12ca6d863 foo
60069036d whatever
d698663d0 something
>> 6166da1fd bar
3d2c811e3 more cool stuff
>> 894567343 baz
3d2c811e3 cool stuff

Furthermore, the ideal solution would work with --graph mode, because I also want to see the merge and branch contexts of the selected commits.

I also note that git log supports various History Simplification scenarios, which get me almost what I want in some cases, but its not easy to figure out how, nor is it exactly what I want. I already have the history I want to see, and I already have the commits I want to highlight.

Some ideas I had, but I don't like any of them:

  • Script it -- run two git logs and then use the output of one to decorate/manipulate the other. The downside of this is that its brittle and it won't work well for different sets of options I might supply to the target log e.g. --graph

  • For the "selected" commits, assign temporary refs e.g. selectedcommits to them, and then use --decorate-refs=selectedcommits to show the relevant commits. This seems messy.

Raman
  • 17,606
  • 5
  • 95
  • 112

3 Answers3

6

Just for fun, while waiting for a better answer.

git log --oneline --decorate=no --graph | less -p $(git log --pretty=%h -- Makefile | tr '\n' '|')

The idea is to pipe the output through, for example, less for highlighting specific commits.

enter image description here

Tested in a bash on Linux and git-bash on Windows.

Here a first try for an alias:

[alias] hl-graph = !git log --oneline --graph --color | less -R -p $(git log --pretty=%h \"$@\" | tr '\n' '|') && :

Commits to be highlited can be defined as usual:

 git hl-graph --since="1 month ago" -- path/to/frobnitz

However the log format can't be modified.

sergej
  • 17,147
  • 6
  • 52
  • 89
  • 1
    That's a nice hack! Deserves an up-vote, but I won't accept it yet :-) – Raman Apr 29 '20 at 21:51
  • 1
    For doing this without less/paging, you can also replace `less -p` with `grep -E --color`. And for colored output, append `--color` to the first log command, and either `less -R` or `grep --color` on the second. – Raman Apr 30 '20 at 05:53
  • @Raman The alias will be non-trivial if you want to pass agruments to the first **and** the second log command. – sergej Apr 30 '20 at 09:15
  • I've added a followup answer with a couple of aliases that focus on the highlighting part, see https://stackoverflow.com/a/61525740/430128. – Raman Apr 30 '20 at 14:28
2

Following up on the answer by @sergej (upvote it!), and recognizing that the repetitive part of the command which needs to be aliased is really just the highlighting, I've configured these aliases:

  hl = "!f() { cd -- ${GIT_PREFIX:-.}; grep --color -E \"$(git log --pretty=%h \"$@\" | tr '\n' '|')\" || true; }; f"
  hlp = "!f() { cd -- ${GIT_PREFIX:-.}; less -R -p $(git log --pretty=%h \"$@\" | tr '\n' '|'); }; f"

These are used by piping the output of any log command to the alias. For example:

git log --oneline --graph --color | git hl --since="1 month ago" -- path/to/frobnitz

(or for the paged version, use hlp)

Raman
  • 17,606
  • 5
  • 95
  • 112
  • Hi @Raman, just a note that Git by default [uses `LESS=FRX less`](https://git-scm.com/docs/git-config#Documentation/git-config.txt-corepager) as its pager command, so to get a more "native" feel with your `hlp` alias I replaced `less -R` with `less -FRX` – philb Jul 09 '21 at 13:43
  • Also, using the `-p`flag of `less` to highlight the patterns means 1) lines before the first pattern are omitted and 2) you are subject to a [bug in `less`](https://github.com/gwsw/less/issues/28). So, as a workaround for both 1 and 2 I use grep to do the highlight and pipe to less at the end: `hlp = "!f() { GREP_COLORS=\"ms=7:\" \\grep --color=always -E \"^|$(git log --pretty=%h \"$@\" | tr '\n' '|' )\" | less -FRX; }; f"` – philb Jul 09 '21 at 15:31
  • and to get bash completion for `log` in the `hl` / `hlp` aliases, you can add ` : git log ; ` ([reference](https://github.com/git/git/blob/7f7ebe054af6d831b999d6c2241b9227c4e4e08d/contrib/completion/git-completion.bash#L26-L30)) just after the opening `!f() {` – philb Jul 09 '21 at 16:27
0

Try the following git command:

git log --name-only --pretty=format:"%h %s" --graph

This command will show all changed files (--name-only), the git commit-hash (%h), the topic from the command (comment from git commit command -> %s) and also the branches drawn by different color-lines.

enter image description here

SwissCodeMen
  • 4,222
  • 8
  • 24
  • 34
  • 3
    This does not answer the question. Specific commits shall be decorated. – sergej Apr 29 '20 at 20:35
  • @sergej I have changed: now it shows _specific subset of these commits_ (all files where have changed in this commit) or what does he mean with **"a specific subset of these commits"** ? – SwissCodeMen Apr 29 '20 at 21:12
  • 2
    All commits shall be shown, but some commits (for example commits touching a file) shall be highlighted. – sergej Apr 29 '20 at 21:16