1. I do `git log` which helpfully pipes to `more` where I can use vim-stsyle search to find the commit I'm interested in.
2. I find the relevant commit.
3. Now I want to `git show` that commit.
Currently I double click on the human unreadable commit, copy it, quit `more` to get back to the command line, type `git show`, then paste the commit. Navigate, click-click, shortcut, 'q', type a command, paste. That's six pieces of business.
That seems very wrong and time-consuming.
How do I go gracefully from browsing git log to git show without retyping/pasting the human unreadable commit? Preferably with fewer than seven steps.
You could use `git log -p` instead of `git log` so that the diff is included.
To navigate efficiently between the commits, you could pre-seed less with a regex that matches commit (and file) lines, so that "n" and "N" jump from one commit (or file) to the next, something like this
Ooh, thanks. I think I can get away with git log -p to fetch the whole enchilada.
There are just so many things in the git CLI that are a single step away from being usable by default. For example, in Gitlab by default you see a tag to let you know if a branch has been merged. I can do the same in cli by exploring my flag options, but that time adds up for every little convenience that happens to be missing. (And as Gitlab shows, it's not impossible to choose a set of default conveniences that cover the bases for an enormous percentage of the users.)
I'll definitely look into that jumping pattern, too. Thanks for the hints!
The one issue I've seen with using `-p` here is that `git log -p` has worse performance when compared to plain `git log` because it needs to calculate diffs, and when searching in less ends up searching the diff contents (even when this is not desired)
If you know the specific string (or regex) you’re searching for in the commit messages, combining `-p` with one of the pickaxe [0] options might be a bit faster.
I personally use magit, which solves this problem across all of git, but it's tied to Emacs.
tig is a git log browser I've heard good things about that seems to handle this use case very nicely.
You may also be able to pervert less into making this easier, e.g. by using lesskey(1) to add a keybinding that runs `git show $(xclip -o)`. I don't know how wise that would be.
I have definitely used Magit in situations where it was the only use of Emacs, working on the version-controlled content itself in content-specific tools such as Xcode or even MS Word.
Yeah, tig is awesome and I use it exactly for this use case.
For what I see, magit is way ahead when it comes to the feature set, but tig has the killer feature of having a completely flat learning curve (and I say this as an Emacs user): 1) type tig 2) use arrows to move between commits and page up/down to move within diffs. That's all!
Just use vim, it even highlights the git log file:
$ git log | vim -
Inside vim search what you want with '/'
When you find the commit you want put the cursor everywhere over the commit ID and run this normal mode command:
<Esc>:!git show <Ctrl+R><Ctrl+W><Enter>
You will be shown the diff in your default text view program (normally it's 'more' but can also be vimdiff), press <Enter> when you finish and you will be sent directly to the place where you left off.
You can also remap this behaviour to any key/alias you want.
find the log entry you're interested in, move the cursor over the sha1 value, type yiw to yank it into vim's " register (by default). Then open a new window by pressing ctrl-w n.
In that window run
:r !git show <ctrl-r ">
where <ctrl-r "> will retrieve the sha1 value you yanked into the " register.
It's fewer steps, doesn't require using the mouse, and allows you to see both the git log output and git show output in different adjacent windows. You can always press u to undo the change in the new window, switch windows to get back to the git log output, find another sha1 and repeat the process.
If you are using Tmux, you can use thmux-fingers[1] or tmux-thumbs[2], both create Vimium like shortchuts for urls and git hashes that once pressed copy the link to clipboard or the tmux buffer. Then you can just `git show` and `Ctrl-shift-V` or `Ctrl-b ]`. There's a lot of resources that can be yanked with tmux-fingers, kubernetes resources, ips and others
First, the simple optimization for Linux systems: double-click on the commit hash, q, git show, middle-click to paste. That's a simpler copy-paste. I do that surprisingly often, when browsing repositories.
But for a repository I do regular development in, vim with the "fugitive" mode works very well. You can just use :Glog, and browse, hitting enter on a commit to show the full commit, or on a tree to show the tree, or on a file within a tree to show the file (at that version).
I also use :Gdiff to give a vimdiff of changes, to stage the changes I want to commit, and then :Gcommit to commit them.
>> First, the simple optimization for Linux systems: double-click on the commit hash, q, git show, middle-click to paste. That's a simpler copy-paste. I do that surprisingly often, when browsing repositories.
Yes, I also double-click on the commit hash and copy it. But I wish there was an incrementing index starting from the top of git log, such that say the 15th commit down, I could just say `git show 15` and see that diff, instead of having to copy and paste the commit ID ( and use my mouse )
> I wish there was an incrementing index starting from the top of git log, such that say the 15th commit down, I could just say `git show 15` and see that diff, instead of having to copy and paste the commit ID ( and use my mouse )
The 15th commit down can be shown with
git show HEAD~14
However, since the log itself does not show you the count this has limited utility since you’d have to either manually count or add some additional processing in order to insert counts into the output of git log.
If you want to navigate without using the mouse, I'd definitely suggest using vim-fugitive, or tig, or any number of git interfaces that let you browse with keyboard shortcuts.
Re: tig; That means I would need to use one command for viewing git logs, and the `git` command for everything else.
I guess if there was one git wrapper that I could use for everything, that would be better. But then I would be probably forget all the traditional git commands, and would be useless if I had to jump on another machine.
I have a series of keybindings[1] for fish that use fzf to select from various git objects. One keybinding selects from commits. So with this I can type `git show <ctrl-g c>` and then pick the commit I want from the fzf interface.
I use FZF for this. It lets me do an incremental search on fit commit messages and show the diff of the selected commit. It’s a slightly customised version of fshow_preview from this example:
Would `git log --grep='some pattern'` help? Or perhaps since you're searching, "git log -p" (or other flags) to have the log show the data you need inline rather then needing to separately run "git show".
Yes, but IntelliJ's "Show History for Selection" takes the cake. It opens up a timemachine-like view that shows just the changes/commits affecting that block and lets you scroll through them.
1. I do `git log` which helpfully pipes to `more` where I can use vim-stsyle search to find the commit I'm interested in. 2. I find the relevant commit. 3. Now I want to `git show` that commit.
Currently I double click on the human unreadable commit, copy it, quit `more` to get back to the command line, type `git show`, then paste the commit. Navigate, click-click, shortcut, 'q', type a command, paste. That's six pieces of business.
That seems very wrong and time-consuming.
How do I go gracefully from browsing git log to git show without retyping/pasting the human unreadable commit? Preferably with fewer than seven steps.