Table of Contents
指定のディレクトリのmodified fileのファイルのみをgit addする
すべてのmodifiedのファイルのみをgit addしたい場合
1
% git add -u
特定のディレクトリ以下すべてのファイルを再帰的にgit addしたい場合
1
% git add directory_name/
で以上で完結しますが, 特定のディレクトリ直下のmodified fileのみ(またはuntracked fileのみ)をgit addしたい場合は対象を制限した上でgit addに渡す必要があります.
このようなケースにおいて, 自分は以下のようなスクリプトで対処しています.
カレントディレクトリ以外の特定のディレクトリ直下のmodified filesをステージングしたい場合
1
2
3
% git ls-files $(git rev-parse --show-toplevel) -m \
| grep -E "(dir_A/|dir_B/)[^/]{1,}\.\w{1,}$" \
| xargs git add
git ls-files $(git rev-parse --show-toplevel) -mをrepository rootから検索してmodifiedのリストを取得grep -E "(dir_A/|dir_B/)"で対象directory pathを含むファイルリストを抽出xargsでgit addに抽出したファイルを渡す
カレントディレクトリ直下のmodified filesをステージングしたい場合
1
2
3
% git ls-files -m \
| grep -v "/" \
| xargs git add
grep -v "/"で/を含む一覧を除外 = 実質上カレントディレクトリのファイルのみとなる
カレントディレクトリ以外の特定のディレクトリ直下のuntracked filesをステージングしたい場合
1
2
3
% git ls-files $(git rev-parse --show-toplevel) -o --exclude-standard \
| grep -E "(dir_A/|dir_B/)[^/]{1,}\.\w{1,}$" \
| xargs git add
staging areaに行っていないmodified file一覧はgit ls-files -mでもれなく取得できますが, そこからの絞り込みはgrepコマンドを使用しているため以下の暗黙の仮定があります.
コマンドが正常に動作するための仮定
dir_A/というディレクトリを対象にするときに, filenameにdir_A/という文字列が入っていない- filenameに
/という文字が含まれていない - ファイルに拡張子(正確には
.という文字列)が必ずついている
git ls-filesの挙動
Def: git ls-files
git ls-filesはstaging-areaに追加されているファイルと作業ツリー内の変更を比較して表示するコマンド- ディレクトリを指定しないで実行すると, カレントディレクトリ以下について上記の情報を表示する
1
git ls-files <directory> [option]
| 短いオプション | 長いオプション | 説明 |
|---|---|---|
-m |
--modified |
stagingされていない変更のあるファイルを表示 |
-o |
--others |
untrackedファイルを表示 (ただし .gitignoreとかで除外されているも含む) |
--exclude-standard |
.git/info/exclude, .gitignoreの効力を適用させる=表示から除外する |
注意点としては, untracked filesを表示するとき, .gitignoreなどで無視されたファイルを表示から除外するため
1
% git ls-files -o --exclude-standard
とオプションを2つ表示する必要があります.
また, repositoryのtoplevel-directoryから検索をかけたい場合は, toplevel-directoryの絶対パスを取得するgit rev-parse --show-toplevelコマンドと合わせて使用します.
1
% git ls-files $(git rev-parse --show-toplevel)
grepの挙動
今回用いているgrepのoptionは以下2つのみです
| オプション | 説明 |
|---|---|
-E |
正規表現によるパターンマッチング |
-v |
マッチしたパターンを除外して表示 |
正規表現について
1
% git ls-files -m | grep -E "(dir_A/|dir_B/)[^/]{1,}\.\w{1,}$"
という表現を用いていますがポイントは以下のみです
(dir_A/|dir_B/): 検索ワードのグルーピング,dir_A/またはdir_B/にマッチする[^/]{1,}:/以外の文字が一回以上続く(=filenameに/が含まれている場合は検索対象外になる)\.:.は任意の位置文字を意味するメタ文字なので, エスケープすることで拡張子の.と一致する\w:[a-zA-Z]の文字クラス(拡張子は.txtにようにアルファベットと.で表現されることを想定)$: 行末を意味するメタ文字
References
(注意:GitHub Accountが必要となります)