Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Browsing git commit history with fzf
# fshow - git commit browser (enter for show, ctrl-d for diff, ` toggles sort)
fshow() {
local out shas sha q k
while out=$(
git log --graph --color=always \
--format="%C(auto)%h%d %s %C(black)%C(bold)%cr" "$@" |
fzf --ansi --multi --no-sort --reverse --query="$q" \
--print-query --expect=ctrl-d --toggle-sort=\`); do
q=$(head -1 <<< "$out")
k=$(head -2 <<< "$out" | tail -1)
shas=$(sed '1,2d;s/^[^a-z0-9]*//;/^$/d' <<< "$out" | awk '{print $1}')
[ -z "$shas" ] && continue
if [ "$k" = ctrl-d ]; then
git diff --color=always $shas | less -R
else
for sha in $shas; do
git show --color=always $sha | less -R
done
fi
done
}
@junegunn

This comment has been minimized.

Copy link
Owner Author

junegunn commented Oct 23, 2015

Simpler version using execute action:

# fshow - git commit browser
fshow() {
  git log --graph --color=always \
      --format="%C(auto)%h%d %s %C(black)%C(bold)%cr" "$@" |
  fzf --ansi --no-sort --reverse --tiebreak=index --toggle-sort=\` \
      --bind "ctrl-m:execute:
                echo '{}' | grep -o '[a-f0-9]\{7\}' | head -1 |
                xargs -I % sh -c 'git show --color=always % | less -R'"
}
@junegunn

This comment has been minimized.

Copy link
Owner Author

junegunn commented Jan 9, 2016

A new version fixed escaping issues:

# fshow - git commit browser
fshow() {
  git log --graph --color=always \
      --format="%C(auto)%h%d %s %C(black)%C(bold)%cr" "$@" |
  fzf --ansi --no-sort --reverse --tiebreak=index --bind=ctrl-s:toggle-sort \
      --bind "ctrl-m:execute:
                (grep -o '[a-f0-9]\{7\}' | head -1 |
                xargs -I % sh -c 'git show --color=always % | less -R') << 'FZF-EOF'
                {}
FZF-EOF"
}
@tobiisdesired

This comment has been minimized.

Copy link

tobiisdesired commented Jan 26, 2016

Inspired by your git browser I implemented a log browser based on fzf. The connection is done via the line number. Don't know if xargs is really necessary.

logshow() {
    cat -n $1 | fzf --reverse --no-sort --tiebreak=index \
                    --bind "ctrl-m:execute:echo {} | grep -Eo "[0-9]+" | head -n 1 | xargs -Ireplace less -N +replaceg $1"
}
@akatrevorjay

This comment has been minimized.

Copy link

akatrevorjay commented Jan 31, 2017

I simplified this: https://gist.github.com/akatrevorjay/9fc061e8371529c4007689a696d33c62

All those heredocs made my brain hurt a little. lulz.

@victorbrca

This comment has been minimized.

Copy link

victorbrca commented Oct 12, 2018

Thanks for this... and another modification. This shows preview of the file, while allowing you to still go into it.

Key binds:

  • q = quit
  • j = down
  • k = up
  • alt-k = preview up
  • alt-j = preview down
  • ctrl-f = preview page down
  • ctrl-b = preview page up
git-commit-show () 
{
  git log --graph --color=always --format="%C(auto)%h%d %s %C(black)%C(bold)%cr"  | \
   fzf --ansi --no-sort --reverse --tiebreak=index --preview \
   'f() { set -- $(echo -- "$@" | grep -o "[a-f0-9]\{7\}"); [ $# -eq 0 ] || git show --color=always $1 ; }; f {}' \
   --bind "j:down,k:up,alt-j:preview-down,alt-k:preview-up,ctrl-f:preview-page-down,ctrl-b:preview-page-up,q:abort,ctrl-m:execute:
                (grep -o '[a-f0-9]\{7\}' | head -1 |
                xargs -I % sh -c 'git show --color=always % | less -R') << 'FZF-EOF'
                {}
FZF-EOF" --preview-window=right:60%
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.