loading...

Make git status and gh easier to use with fzf

hotoolong profile image hotoolong ・5 min read

Overview

The gh command has been released to make it easier to check out PRs.
I reviewed the flow of git add, commit, and push in my usual fish shell.

I used to use PECO before, but FZF's PREVIEW seemed convenient, so I
I tried using FZF to make GH and git status easier to use.

I used to use PECO before, but FZF's PREVIEW seemed convenient, so I
I'm using PREVIEW and working with GH to improve it.
BIND of FZF also seems to be useful, so I tried to use it while I was looking into it.

The version of the command used.

command version
gh 0.6.4
fish 3.1.0
git 2.26.0
fzf 0.21.0
bat 0.13.0

Check the issue

It looks like you can do the same thing with zsh and bash, but
All of them are created by the function of the fish shell.

The first is the function that displays a list of issues.

function fzf_git_issue
  set -l query (commandline --current-buffer)
  if test -n $query
    set fzf_query --query "$query"
  end

  set -l base_command gh issue list --limit 100
  set -l bind_commands "ctrl-a:reload($base_command --state all)"
  set bind_commands $bind_commands "ctrl-o:reload($base_command --state open)"
  set bind_commands $bind_commands "ctrl-c:reload($base_command --state closed)"
  set -l bind_str (string join ',' $bind_commands)

  set -l out ( \
    command $base_command | \
    fzf $fzf_query \
        --prompt='Open issue list >' \
        --preview "gh issue view {1}" \
        --bind $bind_str \
        --header='C-a: all, C-o: open, C-c: closed' \
  )
  if test -z $out
    return
  end
  set -l issue_id (echo $out | awk '{ print $1 }')
  commandline "gh issue view -w $issue_id"
  commandline -f execute
end

You can use gh to list open issue lists and feed them to fzf.

The contents of the gh issue view are shown in the preview of fzf.

Basically, you can check it from the CLI, check the details, and press Enter to open the browser.

By default, only open issues are allowed to be checked, and

If you want to check the status of an issue is closed, you can use Ctrl-c to refresh the list.

Similarly, if you want to check the status of everything, you can use Ctrl-a to refresh it.

Enter on the selected issue so that it can be viewed in the browser.

Check the PR

The PR confirmation is basically the same as the issue.

function fzf_git_pull_request
  set -l query (commandline --current-buffer)
  if test -n $query
    set fzf_query --query "$query"
  end

  set -l base_command gh pr list --limit 100
  set -l bind_commands "ctrl-a:reload($base_command --state all)"
  set bind_commands $bind_commands "ctrl-o:reload($base_command --state open)"
  set bind_commands $bind_commands "ctrl-c:reload($base_command --state closed)"
  set bind_commands $bind_commands "ctrl-g:reload($base_command --state merged)"
  set bind_commands $bind_commands "ctrl-a:reload($base_command --state all)"
  set -l bind_str (string join ',' $bind_commands)

  set -l out ( \
    command $base_command | \
    fzf $fzf_query \
        --prompt='Select Pull Request>' \
        --preview="gh pr view {1}" \
        --expect=ctrl-k,ctrl-m \
        --header='enter: open in browser, C-k: checkout, C-a: all, C-o: open, C-c: closed, C-g: merged, C-a: all' \
  )
  if test -z $out
    return
  end
  set -l pr_id (echo $out[2] | awk '{ print $1 }')
  if test $out[1] = 'ctrl-k'
    commandline "gh pr checkout $pr_id"
    commandline -f execute
  else if test $out[1] = 'ctrl-m'
    commandline "gh pr view --web $pr_id"
    commandline -f execute
  end
end

You can get a list of PRs by using gh.

Because the status is narrowed down to the one of open when this is also the default, the

If you want to check the merged items, you can use Ctrl-g to display them again.

In the case of PR, you may want to check the initial command with all, especially if you want to see the merged information.

You may want to change the number of items as you use them, but

The default is 30, so it's 100 at one time.

Here.

You can checkout by Ctrl-k with gh pr checkout <id of PR>.

This command is useful. gh It varies.

You can check the PR in your browser and copy the branch name to smooth out the process of switching branches.

check the git status

The git status is also made easy to use by fzf.
The following is the function I created.

function gst --description 'git status -s'
  if ! is_git_dir
    return
  end
  set -l base_command git status -s
  set -l bind_reload "reload($base_command)"
  set -l bind_commands "ctrl-a:execute-silent(git add {2})+$bind_reload"
  set bind_commands $bind_commands "ctrl-u:execute-silent(git restore --staged {2})+$bind_reload"
  set -l bind_str (string join ',' $bind_commands)

  set -l out (command $base_command | \
    fzf --exit-0 \
    --preview="[ '??' = {1} ] && bat --color=always {2} || git diff {2}" \
        --expect=ctrl-m,ctrl-r,ctrl-v,ctrl-c \
        --bind $bind_str \
        --header='C-a: add, C-u: unstage, C-c: commit, C-m(Enter): edit, C-r: rm, C-v: mv' \
  )
  [ $status != 0 ]; and commandline -f repaint; and return

  if string length -q -- $out
    set -l key $out[1]
    set -l file (echo $out[2] | awk -F ' ' '{ print $NF }')

    if test $key = 'ctrl-v'
      commandline -f repaint
      commandline "git mv $file "
    else if test $key = 'ctrl-r'
      commandline "git rm $file "
      commandline -f execute
    else if test $key = 'ctrl-m'
      commandline "$EDITOR $file"
      commandline -f execute
    else if test $key = 'ctrl-c'
      commandline "git commit -v"
      commandline -f execute
    else
      commandline -f repaint
    end
  end
end

The result of git status -s is fed to fzf.

preview displays files that are not managed by git with bat and files that are managed with git diff <selected files> to show the differences.

I'm setting up some commands in FZF's BIND.

Refresh fzf by ctrl-a to git add <selective file>.

Refresh fzf with Ctrl-u to git restore --staged <selected file>.

Type Ctrl-c to git commit -v.

These three operations basically take you to the commit.

Also, when looking at the contents of the git status, there was something that I wanted to fix from diffs and so on, so I changed the

Calling Ctrl-m or Enter to edit a file in the editor. In my case, it will be NVIM.

I prepare git rm/mv as an attachment, but it seems to want to type a command before doing git status.

Summary

I see a lot of people using FZF's PREVIEW to good effect when I check other people's blogs.
I think it is difficult to fit everything in the CLI, but it seems that it can be done with the CLI as much as possible.

Especially since BIND hadn't seen anyone mentioning it on their blog
I'd be happy if people would take a look at this and take advantage of it.

Discussion

pic
Editor guide