あなたは知ってる?ちょっとマイナーな Git の小ネタ
未コミットのファイルを diff に含める / add -N / add --intent-to-add
git add -N
することで diff で差分を確認できるようになる
commit 前に diff を使って差分を確認しつつ確認できたものを add していくときによく使う
仕組みとしては単純で、add -N
/ --intent-no-add
で指定したファイルを空のファイルとして add しているので差分が表示できるようになっている
ファイルを細かい単位で add する / add -p / add --patch
[y, n, q, a, d, g, /, i, J, k, K, s ,e ?]
の選択肢があるがだいたい使うのは [y, n, q, a, s, e]
以下は add -p
使用時の一例
- 一気に実装する
-
git add -p {file}
で patch モードへ - コミットしたい単位で y / n を入力して staging していく
- 提案された単位より小さい単位で staging したい場合は s で小さくする
- s が使えなかったり上手くいかない場合は e で手動選択
プロジェクトによっては粒度を気にせず git rebase
してまとめたりするので使わないこともある
CLI で扱いやすい status 表示 / status --porcelain
git status
で表示される情報を cli などで処理しやすいで出力してくれる
基本的には git status -s
/ --short
と結果が変わらないが、 --porcelain
はバージョン指定ができる(デフォルトは v1)ので、ユーザの環境や git のバージョンに依存せず同じ結果を返せることが特徴
この特徴のおかげで過去に作ったスクリプトが git のバージョンアップ後に動かなくなる問題を防げる
筆者は sed を噛ませつつ goimports に渡したりするのに良く使っている
git status --porcelain | sed s/^...// | xargs goimports -w
行単位ではなく単語単位で diff 表示 / diff --word-diff
通常行単位で比較する diff を単語単位で比較して出力してくれる
表示オプションとして [color, plain, porcelain
] があるが個人的には color か porcelain が使いやすいと思う
メール文面やユーザ向けのお知らせなど、単語単位で diff を取ってチェックしたいときに便利(GitHub の PR Diff が word-diff 対応してくれると嬉しい)
ちなみに
--color-words
のオプションもあるが、これは --word-diff=color
と同じ出力になる
git diff --no-index --color-words a.txt b.txt
git 管理外のファイルでも diff 表示 / diff --no-index
--no-index
オプションを使って比較する
git diff --no-index --word-diff=color a.txt b.txt
untracked ファイルを stash する / stash -u / stash --include-untracked
untracked を含めたくない場合は --no-include-untracked
を使う
逆の --only-untracked
は stash show
専用なため untracked のみを stash はできない。git add -N
と組み合わせたりして解決する
ちなみに
OK: git stash save "hoge" -u
NG: git stash -u save "hoge"
指定したコミットで変更したファイル名のみ取得 / show --pretty="" --name-only
push 後にフォーマット漏れで CI の Linter に怒られたりした場合に時々使う
フォーマットとは別に修正も入れたいし、かと言って修正とフォーマットを同一コミットにしたくないときに使える
通常 git show {hash}
は指定したコミットハッシュの変更内容を表示するが、--name-only
のオプションで変更内容ではなく変更されたファイルの情報のみ取り出せる
$ git show --name-only 12345abc
commit 12345abc
Author: i_love_wani <example@example.com>
Date: Sat Jan 01 00:00:00 2000 +0900
hoge/piyo を修正
hoge/fuga/main.go
hoge/piyo/main.go
ただ、この状態だとフォーマッター(例えば gofmt)にわたすには Author などの情報が邪魔なので --pretty=""
で削る
$ git show --name-only --pretty="" 12345abc
hoge/fuga/main.go
hoge/piyo/main.go
するとファイル名のみを取り出すことができるので、後は xargs などを使ってフォーマッターにパスを渡す
git show --name-only --pretty="" 12345abc | xargs gofmt -w
任意のディレクトリに対して git コマンドを実行 / git -C {path}
複数のリポジトリに対してまとめて git 操作したい場合に便利(cd が不要)
git pull --rebase
を実行するスクリプト
例: 指定したディレクトリ配下のリポジトリに対して ※ fish script です
function pullall
set branchName 'develop'
if test (count $argv) -gt 0
set branchName $argv
end
cd ~/hoge/ && find . -type d -depth 1 -exec git -C {} switch $branchName \; -exec git -C {} pull --rebase \;
end
$ pullall feature/hoge` という感じで使えます
やっていることは
-
hoge
ディレクトリに移動 -
hoge
ディレクトリ配下を find し、以下の処理を配下のディレクトリに対して実行 -
git -C {} switch $branchName
で指定したブランチをチェックアウト(引数がない場合は develop になる) -
git -C {} pull --rebase
でpull --rebase
する
変更を維持したまま stash に保存する / stash -k / stash --keep-index
save か push(git stash と同等)のみ使える
コミットしたくないけど逃しておきたい変更(一時的に DB の接続先を変えるとか)がある場合に使える
e.g.
- .env ファイルを修正して DB の接続先を変更
- この修正は今後も時々使ったりする
-
git add .env
で index に追加 git stash save "tmp db connection" -k
- 現在の index の状態はそのままに .env の変更が stash に保存される
最小限の差分で表示する / diff --minimal
+1000 -1000
といったように行が移動したような差分として表示された場合に使える
時間はかかるが正確な diff を取るアルゴリズムを使うので -1000
という正しい差分を表示できる
おまけ: Conversion を全部 resolve する
CI でめちゃめちゃ怒られたけど、全部無視したいときに使ってみてください
javascript:(function(){document.querySelectorAll('.ajax-pagination-btn').forEach((b)=>{b.click()}); setTimeout(function(){document.querySelectorAll('[data-disable-with="Resolving conversation…"]').forEach((b)=>{b.click()});}, 5000);})();
ブックマークレットとして使えます
Discussion