Make git status and gh easier to use with fzf
Tags: fzf, gh, git, fish
Published: 2020-04-30 13:55:18

# 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.

```sh
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.

```sh
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.

```sh
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.