おでーぶでおでーぶ

いろいろ書く。いろいろ。

特定のファイルの git addとかがめんどうくさいのでなんとかする

ある程度編集したときに「あー、このファイルだけコミットしておきたい」みたいな状況ってあると思うんですよ。 他にも「このファイルだけHEADの状態に戻したい」とか「unstageしたい」みたいな。

でも例えばJavaだとpackage名が一緒なファイルがずらーっと並んでしまい、補完しようにも先頭が大体一緒で本当に面倒くさい。

残念ながらJavaをやめるという選択肢がないので、gitのサブコマンドを作って対応する。

ファイル一覧から特定のファイルをaddする - git add $file

#!/usr/bin/env bash

: ${GIT_FILTER_COMMAND:=fzf}

ls_modified_files() {
  echo '--- LABEL : tracked'
  git diff --name-only
}

ls_untracked_files() {
  echo '--- LABEL : untracked'
  git ls-files --others --exclude-standard
}

main() {
  local -r selected_file=$(cat <(ls_modified_files) <(ls_untracked_files) | $GIT_FILTER_COMMAND)

  if [[ -f "$selected_file" || -d "$selected_file" ]]; then
    git add "$selected_file"
  else
    echo 'Not found or Canceled' >&2
  fi
}

main

ファイル一覧から特定のファイルをHEADの状態に戻す- git checkout -- $file

#!/usr/bin/env bash

: ${GIT_FILTER_COMMAND:=fzf}

ls_staged_files() {
  echo '--- LABEL : staged'
  git diff --name-only --staged
}

ls_modified_files() {
  echo '--- LABEL : modified'
  git diff --name-only
}

main() {
  local -r selected_file=$(cat <(ls_staged_files) <(ls_modified_files) | $GIT_FILTER_COMMAND)

  if [[ -f "$selected_file" || -d "$selected_file" ]]; then
    git checkout -- "$selected_file"
  else
    echo 'Not found or Canceled' >&2
  fi
}

main

ファイル一覧から特定のファイルをunstageする - git reset --$file

#!/usr/bin/env bash

: ${GIT_FILTER_COMMAND:=fzf}

ls_staged_files() {
  echo '--- LABEL : staged'
  git diff --name-only --staged
}

main() {
  local -r selected_file=$(cat <(ls_staged_files) | $GIT_FILTER_COMMAND)

  if [[ -f "$selected_file" || -d "$selected_file" ]]; then
    git reset -- "$selected_file"
  else
    echo 'Not found or Canceled' >&2
  fi
}

main

まだtrackしてないディレクトリの内部までほじくるとかはキャンセル処理とかが面倒なのでやってないけれど、余裕で可能だと思います。

おまけ

ファイル名を git-hoge としてPATH配下に認識させておくとgit hogeで起動できる。(サブコマンド)
拡張子をつけてエディタのファイル補完を適用したいなら、シンボリックリンクで対応すればいいと思います。