Git でいくつかの設定ファイルを追跡しています。通常は対話的に行いますgit add -p
が、パターンに一致するすべての新規/変更/削除された行を自動的に追加する方法を探しています。そうしないと、対話的な分割と追加をすべて実行するのに非常に時間がかかります。git add
ファイル名のパターン マッチングがありますが、コンテンツについては何も見つかりません。
ベストアンサー1
方法は次のとおりです:
git diff > patch
現在の diff のパッチを作成するために使用します。パターンに一致する行
gawk
のみの 2 番目のパッチを作成するために使用します。パターンに一致しない行を削除し、パターンに一致しない行を削除し、ハンク ヘッダーの行番号を変更し、変更された各ハンクを出力しますが、変更がなくなった変更されたハンクは出力しません。+/-
-
+
git stash save
、、、およびを使用してapply patch
、変更されたパッチを適用およびステージングし、残りの変更はステージングしないままにします。add -u
stash pop
これはいくつかのテストケースで機能し、diff 全体 (すべてのファイル) に対して一度に機能し、高速です。
#!/bin/sh
diff=`mktemp`
git diff > $diff
[ -s $diff ] || exit
patch=`mktemp`
gawk -v pat="$1" '
function hh(){
if(keep && n > 0){
for(i=0;i<n;i++){
if(i==hrn){
printf "@@ -%d,%d +%d,%d @@\n", har[1],har[2],har[3],har[4];
}
print out[i];
}
}
}
{
if(/^diff --git a\/.* b\/.*/){
hh();
keep=0;
dr=NR;
n=0;
out[n++]=$0
}
else if(NR == dr+1 && /^index [0-9a-f]+\.\.[0-9a-f]+ [0-9]+$/){
ir=NR;
out[n++]=$0
}
else if(NR == ir+1 && /^\-\-\- a\//){
mr=NR;
out[n++]=$0
}
else if(NR == mr+1 && /^\+\+\+ b\//){
pr=NR;
out[n++]=$0
}
else if(NR == pr+1 && match($0, /^@@ \-([0-9]+),?([0-9]+)? \+([0-9]+),?([0-9]+)? @@/, har)){
hr=NR;
hrn=n
}
else if(NR > hr){
if(/^\-/ && $0 !~ pat){
har[4]++;
sub(/^\-/, " ", $0);
out[n++] = $0
}
else if(/^\+/ && $0 !~ pat){
har[4]--;
}
else{
if(/^[+-]/){
keep=1
}
out[n++] = $0
}
}
}
END{
hh()
}' $diff > $patch
git stash save &&
git apply $patch &&
git add -u &&
git stash pop
rm $diff
rm $patch
参照: