私は自分のチームでgitを使用しています。差分、ログ、マージなどから空白の変更を削除したいと思います。これを行う最も簡単な方法は、gitが末尾の空白(およびその他の空白エラー)適用されるすべてのコミットから。
次を~/.gitconfig
ファイルで追加しようとしましたが、コミットしても何もしません。たぶん、それは異なる何かのために設計されています。解決策は何ですか?
[core]
whitespace = trailing-space,space-before-tab
[apply]
whitespace = fix
誰かがRuby固有のアイデアを持っている場合に備えて、Rubyを使用しています。コミットする前の自動コードフォーマットは次のステップになりますが、それは難しい問題であり、大きな問題を実際に引き起こしていません。
これらの設定(core.whitespace
およびapply.whitespace
)は、末尾の空白を削除するためではなく、次の目的のためにあります。
core.whitespace
:それらを検出し、エラーを発生させますapply.whitespace
:それらを削除しますが、パッチ中のみであり、「常に自動的に」ではありません私はgit hook pre-commit
がそれに対してより良い仕事をすると信じています(末尾の空白の削除を含む)
pre-commit
フックを実行しないことをいつでも選択できることに注意してください。
git commit --no-verify .
cd .git/hooks/ ; chmod -x pre-commit
警告:デフォルトでは、pre-commit
スクリプト( this one など)にはnot「トレーリングを削除」機能はありませんが、「警告」機能は:
if (/\s$/) {
bad_line("trailing whitespace", $_);
}
ただし、より優れたpre-commit
フックを構築、特に次のことを考慮する場合は:
ステージング領域に追加された一部の変更のみでGitをコミットすると、が作業コピーとして存在することはなく、動作しない可能性のある「アトミック」リビジョンになります。
たとえば、 oldman は、空白を検出して削除する 別の回答 a pre-commit
hook を提案します。
フックは各ファイルのファイル名を取得するため、特定の種類のファイルには注意することをお勧めします。.md
(マークダウン)ファイルの末尾の空白を削除したくない!
変更をパッチとして扱うようにGitをasすことにより、Gitをtrickして空白を修正することができます。 「プリコミットフック」ソリューションとは対照的に、これらのソリューションは空白修正コマンドをGitに追加します。
はい、これらはハッキングです。
次のGitエイリアスは、 my ~/.gitconfig
から取得されます。
「堅牢」とは、これらのエイリアスがエラーなしで実行され、ツリーまたはインデックスが汚れているかどうかに関係なく、正しいことを実行することを意味します。ただし、インタラクティブgit rebase -i
が既に進行中の場合は機能しません。 my ~/.gitconfig
を参照してください。このコーナーケースを気にする場合の追加チェックについては、最後に説明したgit add -e
トリックが機能するはずです。
Gitエイリアスを作成せずにシェルで直接実行する場合は、二重引用符の間にすべてをコピーして貼り付けてください(シェルがBashのようなものであると仮定)。
次のfixws
Gitエイリアスは、インデックスに含まれるすべての空白エラーを修正しますが、ツリーに影響を与えません:
# Logic:
#
# The 'git stash save' fails if the tree is clean (instead of
# creating an empty stash :P). So, we only 'stash' and 'pop' if
# the tree is dirty.
#
# The 'git rebase --whitespace=fix HEAD~' throws away the commit
# if it's empty, and adding '--keep-empty' prevents the whitespace
# from being fixed. So, we first check that the index is dirty.
#
# Also:
# - '(! git diff-index --quiet --cached HEAD)' is true (zero) if
# the index is dirty
# - '(! git diff-files --quiet .)' is true if the tree is dirty
#
# The 'rebase --whitespace=fix' trick is from here:
# https://stackoverflow.com/a/19156679/470844
fixws = !"\
if (! git diff-files --quiet .) && \
(! git diff-index --quiet --cached HEAD) ; then \
git commit -m FIXWS_SAVE_INDEX && \
git stash save FIXWS_SAVE_TREE && \
git rebase --whitespace=fix HEAD~ && \
git stash pop && \
git reset --soft HEAD~ ; \
Elif (! git diff-index --quiet --cached HEAD) ; then \
git commit -m FIXWS_SAVE_INDEX && \
git rebase --whitespace=fix HEAD~ && \
git reset --soft HEAD~ ; \
fi"
アイデアは、インデックスに空白エラーがある場合、git fixws
の前にgit commit
を実行することです。
次のfixws-global-tree-and-index
Gitエイリアスは、インデックスとツリー(存在する場合)のすべての空白エラーを修正します。
# The different cases are:
# - dirty tree and dirty index
# - dirty tree and clean index
# - clean tree and dirty index
#
# We have to consider separate cases because the 'git rebase
# --whitespace=fix' is not compatible with empty commits (adding
# '--keep-empty' makes Git not fix the whitespace :P).
fixws-global-tree-and-index = !"\
if (! git diff-files --quiet .) && \
(! git diff-index --quiet --cached HEAD) ; then \
git commit -m FIXWS_SAVE_INDEX && \
git add -u :/ && \
git commit -m FIXWS_SAVE_TREE && \
git rebase --whitespace=fix HEAD~2 && \
git reset HEAD~ && \
git reset --soft HEAD~ ; \
Elif (! git diff-files --quiet .) ; then \
git add -u :/ && \
git commit -m FIXWS_SAVE_TREE && \
git rebase --whitespace=fix HEAD~ && \
git reset HEAD~ ; \
Elif (! git diff-index --quiet --cached HEAD) ; then \
git commit -m FIXWS_SAVE_INDEX && \
git rebase --whitespace=fix HEAD~ && \
git reset --soft HEAD~ ; \
fi"
バージョン管理されていないファイルの空白も修正するには、次のようにします
git add --intent-to-add <unversioned files> && git fixws-global-tree-and-index
これらのバージョンはコピーと貼り付けが簡単ですが、副次的な条件が満たされない場合、正しいことを行いません。
git add -e
を使用してIDエディターでパッチを「編集」する:
:
(export GIT_EDITOR=: && git -c apply.whitespace=fix add -ue .) && git checkout . && git reset
git commit -m TEMP && git rebase --whitespace=fix HEAD~ && git reset --soft HEAD~
git add -u :/ && git commit -m TEMP && git rebase --whitespace=fix HEAD~ && git reset HEAD~
export GIT_EDITOR=: && git -c apply.whitespace=fix add -ue .
トリックの説明この回答 からgit rebase --whitespace=fix
トリックについて学ぶ前は、どこでもより複雑なgit add
トリックを使用していました。
手動で行った場合:
apply.whitespace
をfix
に設定します(これは一度だけ行う必要があります):
git config apply.whitespace fix
これは、Gitにpatchesの空白を修正するように指示します。
変更をpatchとして扱うようにGitを説得します:
git add -up .
ヒット a+enter各ファイルのすべての変更を選択します。 Gitが空白のエラーを修正することについて警告が表示されます。
(この時点でgit -c color.ui=auto diff
は、インデックス付けされていない変更がまさに空白エラーであることを示しています)。
作業コピーから空白エラーを削除します。
git checkout .
変更を元に戻します(コミットする準備ができていない場合):
git reset
GIT_EDITOR=:
は、エディターとして:
を使用することを意味し、コマンドとして:
はIDです。
Git 末尾の空白を削除するpre-commitフック を見つけました。
#!/bin/sh
if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
# Find files with trailing whitespace
for FILE in `exec git diff-index --check --cached $against -- | sed '/^[+-]/d' | sed -r 's/:[0-9]+:.*//' | uniq` ; do
# Fix them!
sed -i 's/[[:space:]]*$//' "$FILE"
git add "$FILE"
done
exit
Mac OS(またはおそらくBSD)では、sedコマンドのパラメーターはわずかに異なる必要があります。これを試して:
#!/bin/sh
if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
# Find files with trailing whitespace
for FILE in `exec git diff-index --check --cached $against -- | sed '/^[+-]/d' | sed -E 's/:[0-9]+:.*//' | uniq` ; do
# Fix them!
sed -i '' -E 's/[[:space:]]*$//' "$FILE"
git add "$FILE"
done
このファイルを.git/hooks/pre-commit
として保存するか、既に存在するファイルを探して、その中のどこかに下部チャンクを貼り付けます。そして、chmod a+x
も忘れないでください。
または、( Gitコミットフック-グローバル設定 を介して)グローバルに使用する場合は、$GIT_PREFIX/git-core/templates/hooks
に配置できます(GIT_PREFIXは/ usrまたは/ usr/localまたは/ usr/shareまたは/ opt/local/share)そして既存のリポジトリ内でgit init
を実行します。
git help init
によると:
既存のリポジトリでgit initを実行するのは安全です。すでに存在するものは上書きされません。 git initを再実行する主な理由は、新しく追加されたテンプレートを取得するためです。
このタスクはお気に入りのエディターに任せたいと思います。
保存時に末尾のスペースを削除するコマンドを設定するだけです。
mypre-commithooks を試してください。末尾の空白とを自動検出できますそれを削除。ありがとうございました!
GitBash(windows), Mac OS X and Linux
の下で機能します!
スナップショット:
$ git commit -am "test"
auto remove trailing whitespace in foobar/main.m!
auto remove trailing whitespace in foobar/AppDelegate.m!
[master 80c11fe] test
1 file changed, 2 insertions(+), 2 deletions(-)
以前の提案では、ターゲットファイルの末尾の空白が多すぎる場合、読み取り不可能なコミットが作成される傾向があるため、変更/追加した行から末尾の空白のみを削除するこの事前コミットフックを作成しました。
#!/bin/sh
if git rev-parse --verify HEAD >/dev/null 2>&1 ; then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
IFS='
'
files=$(git diff-index --check --cached $against -- | sed '/^[+-]/d' | Perl -pe 's/:[0-9]+:.*//' | uniq)
for file in $files ; do
diff=$(git diff --cached $file)
if test "$(git config diff.noprefix)" = "true"; then
prefix=0
else
prefix=1
fi
echo "$diff" | patch -R -p$prefix
diff=$(echo "$diff" | Perl -pe 's/[ \t]+$// if m{^\+}')
out=$(echo "$diff" | patch -p$prefix -f -s -t -o -)
if [ $? -eq 0 ]; then
echo "$diff" | patch -p$prefix -f -t -s
fi
git add $file
done
OK、これはこの問題を解決するための新しいタックです…私のアプローチは、フックを使用せず、フィルターとgit属性を使用することです。これができるのは、開発する各マシンで、ファイルの最後にある余分な末尾の空白と余分な空白行を削除してからコミットするフィルターのセットです。次に、フィルターを適用するファイルの種類を示す.gitattributesファイルをセットアップします。フィルターには2つのフェーズがあります。clean
はインデックスにファイルを追加するときに適用され、smudge
は作業ディレクトリにファイルを追加するときに適用されます。
最初に、グローバル構成にグローバル属性ファイルを使用するように指示します。
git config --global core.attributesfile ~/.gitattributes_global
次に、フィルターを作成します。
git config --global filter.fix-eol-eof.clean fixup-eol-eof %f
git config --global filter.fix-eol-eof.smudge cat
git config --global filter.fix-eol-eof.required true
最後に、fixup-eol-eof
スクリプトをパスのどこかに置き、実行可能にします。このスクリプトはsedを使用してオンザフライ編集を行います(行末のスペースと空白、およびファイルの末尾の余分な空白行を削除します)
fixup-eol-eofは次のようになります。
#!/bin/bash
sed -e 's/[ ]*$//' -e :a -e '/^\n*$/{$d;N;ba' -e '}' $1
最後に、お気に入りのエディターで〜/ .gitattributes_globalを作成または開き、次のような行を追加します。
pattern attr1 [attr2 [attr3 […]]]
したがって、空白の問題を修正したい場合は、すべてのcソースファイルに対して、次のような行を追加します。
*.c filter=fix-eol-eof
フィルターには2つのフェーズがあります。1つは、インデックスに追加またはチェックインするときに適用されるクリーンフェーズと、gitが作業ディレクトリにデータを入れるときのスマッジフェーズです。ここでは、ファイルの最後にない場合に末尾の改行文字を追加する可能性があることを除いて、cat
コマンドを使用してコンテンツを実行するだけです。 cleanコマンドは、 http://sed.sourceforge.net/sed1line.txt のメモからまとめた空白フィルタリングです。シェルスクリプトに入れる必要があるようです。ファイルの最後にある余分な余分な行をgit-configファイルに直接衛生化するなど、sedコマンドを注入する方法がわかりませんでした。 (は末尾の空白を取り除くことができますが、別のsedスクリプトを必要とせずに、filter.fix-eol-eof
を次のように設定するだけです。 sed 's/[ \t]*$//' %f
ここで、\t
は実際のタブです(タブを押します)。
Require = trueを使用すると、問題が発生した場合にエラーが発生し、トラブルを回避できます。
Gitに関する私の言語が不正確な場合はご容赦ください。私は概念をかなりよく理解していると思うが、まだ用語を学んでいる。
以下は、ubuntu + mac os x互換バージョンです。
#!/bin/sh
#
# A git hook script to find and fix trailing whitespace
# in your commits. Bypass it with the --no-verify option
# to git-commit
#
if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
# Find files with trailing whitespace
for FILE in `exec git diff-index --check --cached $against -- | sed '/^[+-]/d' | (sed -r 's/:[0-9]+:.*//' > /dev/null 2>&1 || sed -E 's/:[0-9]+:.*//') | uniq` ; do
# Fix them!
(sed -i 's/[[:space:]]*$//' "$FILE" > /dev/null 2>&1 || sed -i '' -E 's/[[:space:]]*$//' "$FILE")
git add "$FILE"
done
# Now we can commit
exit
楽しんで
今日これについて考えていました。これが私がJavaプロジェクトのためにやったことのすべてです:
egrep -rl ' $' --include *.Java * | xargs sed -i 's/\s\+$//g'
Sublime Textユーザーの場合。
以下を適切に設定しますSetting-User設定。
"trim_trailing_white_space_on_save": true
ファイルのforループは、$ IFSシェル変数を使用します。指定されたスクリプトでは、$ IFS変数にも含まれる文字を含むファイル名は、forループ内の2つの異なるファイルとして表示されます。このスクリプトはそれを修正します:sed-manualのマルチラインモード修飾子は、ubuntuボックスではデフォルトで機能しないようです。そのため、別の実装を探しましたが、反復ラベルでこれを見つけました。正しく理解できた場合、ファイルの最終行。
#!/bin/sh
#
# A git hook script to find and fix trailing whitespace
# in your commits. Bypass it with the --no-verify option
# to git-commit
#
if git rev-parse --verify HEAD >/dev/null 2>&1
then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
SAVEIFS="$IFS"
# only use new-line character as seperator, introduces EOL-bug?
IFS='
'
# Find files with trailing whitespace
for FILE in $(
git diff-index --check --cached $against -- \
| sed '/^[+-]/d' \
| ( sed -r 's/:[0-9]+:.*//' || sed -E 's/:[0-9]+:.*//' ) \
| uniq \
)
do
# replace whitespace-characters with nothing
# if first execution of sed-command fails, try second one( MacOSx-version)
(
sed -i ':a;N;$!ba;s/\n\+$//' "$FILE" > /dev/null 2>&1 \
|| \
sed -i '' -E ':a;N;$!ba;s/\n\+$//' "$FILE" \
) \
&& \
# (re-)add files that have been altered to git commit-tree
# when change was a [:space:]-character @EOL|EOF git-history becomes weird...
git add "$FILE"
done
# restore $IFS
IFS="$SAVEIFS"
# exit script with the exit-code of git's check for whitespace-characters
exec git diff-index --check --cached $against --
[1] sed-subsitionパターン: sedを使用して改行(\ n)を置き換える方法 。
これは、コミットの前に空白を削除しません自動的にですが、それはかなり簡単です。次のPerlスクリプトを、$ PATHのdirにあるgit-wsf(git whitespace fix)という名前のファイルに配置しました。
git wsf | sh
gitがdiffとして報告するファイルの行からすべての空白onlyを削除します。
#! /bin/sh
git diff --check | Perl -x $0
exit
#! /usr/bin/Perl
use strict;
my %stuff;
while (<>) {
if (/trailing whitespace./) {
my ($file,$line) = split(/:/);
Push @{$stuff{$file}},$line;
}
}
while (my ($file, $line) = each %stuff) {
printf "ex %s <<EOT\n", $file;
for (@$line) {
printf '%ds/ *$//'."\n", $_;
}
print "wq\nEOT\n";
}
ファイルの行末の末尾の空白を移植可能に削除するには、ed
を使用します。
test -s file &&
printf '%s\n' H ',g/[[:space:]]*$/s///' 'wq' | ed -s file
少し遅れますが、これは誰かを助けるかもしれないので、ここに行きます。
VIMでファイルを開きます。タブを空白に置き換えるには、vimコマンドラインに次のように入力します
:%s#\t# #gc
他の末尾の空白を取り除くには
:%s#\s##gc
これはほとんど私のためにそれをしました。編集するファイルがたくさんあると面倒です。しかし、事前コミットフックや複数のエディターでの作業よりも簡単だと感じました。