git commit --fixup は便利だけど面倒なのでちょっと工夫した

ここ最近また git commit --fixup が再熱してたので改めて調べたり工夫できないかなど考えてた。

--fixup とは何か

まずそもそもという話だけど、以下のようなコマンドで fixup! というメッセージが付与されたコミットを作ることができる。

git commit --fixup <COMMIT-HASH>

# fixup! <COMMIT-HASH の コミットメッセージ>

これだけだと何が嬉しいの?という感じだけど、 git rebase -i --autosquash <COMMIT-HASH> と合わせると rebase のタイミングで自動で fixup に変わってくれる

git rebase -i --autosquash <COMMIT-HASH>

# pick aaaaaaa some commit message
# fixup bbbbbbb fixup! some commit message

こうすることで、修正コミットを入れたいけど最後には1つのコミットとしてマージしたい (いわゆる Squash & Merge 派閥) 人にとっては非常に便利な機能。

他の方の方がうまく説明してくれてるので参考も貼っておきます。

課題点

なんだけど、コミットハッシュをいちいち指定したりするのが面倒で結局 1,2個くらいなら最初から以下のように rebase の時だけだるいことをすればいいなあーでここ数年はやっていた。

git commit -m "w"
git rebase -i <COMMIT-HASH>

# エディタが起動したら1つずつ pick から `f` or `fixup` に変えていく

せっかく再熱してるのでなんとかうまくワークフローに組み込めないかなということで以下のような工夫をしてみることにした。 具体的には

alias の内容はそれぞれ以下

alias gcf='git commit --fixup=HEAD' # HEAD に対して積みたいことが自分のワークフロー上は、ほとんどなので
alias gra='git rebase --autosquash -i'
gra # まで入力して

# ^i で起動

QUERY>
xxxxxxx commit a
xxxxxxx commit b
xxxxxxx commit c
xxxxxxx commit d

# 選択すると xxxxxxx がカーソルに続けて入力されるようになる

gra xxxxxxx

具体的な実装は .zshrc で以下を定義しているだけ

function peco-git-log() {
    local selected_commit=$(git log --oneline -n 20 | peco | awk '{print $1}')
    if [ -n "$selected_commit" ]; then
      BUFFER+="$selected_commit"
      CURSOR=$#BUFFER
      zle redisplay
    fi
    zle clear-screen
}
zle -N peco-git-log
bindkey '^i' peco-git-log

一旦これでしばらくやってみることにした。
どちらかというと peco-git-log が便利でこっちだけ使い続けるみたいになってしまいそうではあるが。。。。

余談

ちなみに自分は以下も peco で検索できるようにしている

コードは、以下にも抜粋するが、 https://github.com/omuomugin/dotfiles/blob/master/.zshrc でも見れる

function peco-ghq () {
  local selected_dir=$(ghq list -p | peco --query "$LBUFFER")
  if [ -n "$selected_dir" ]; then
    BUFFER="cd ${selected_dir}"
    zle accept-line
  fi
  zle clear-screen
}
zle -N peco-ghq
bindkey '^l' peco-ghq

## show list for history
function peco-history() {
    BUFFER=`history -n 1 | tail -r | peco`
    CURSOR=$#BUFFER
    zle redisplay
}
zle -N peco-history
bindkey '^h' peco-history

## show list for git-branch
function peco-git-branch() {
    local selected_branch=$(git branch --format='%(refname:short)' | peco )
    if [ -n "$selected_branch" ]; then
      BUFFER="git switch ${selected_branch}"
      zle accept-line
    fi
    zle clear-screen
}
zle -N peco-git-branch
bindkey '^b' peco-git-branch

function peco-git-log() {
    local selected_commit=$(git log --oneline -n 20 | peco | awk '{print $1}')
    if [ -n "$selected_commit" ]; then
      BUFFER+="$selected_commit"
      CURSOR=$#BUFFER
      zle redisplay
    fi
    zle clear-screen
}
zle -N peco-git-log
bindkey '^i' peco-git-log