2016-10-27 6 views
0

私のgitリポジトリで次のコマンドを実行して、すべてのテキストファイルを強制的にunix行末を使用しました。gitフィルタを実行した後に重複コミットが発生するのはなぜですか?

git filter-branch --force --tree-filter 'git ls-files | xargs file | sed -n -e "/.*: .*text.*/s/\(.*\): .*/\1/p" | xargs dos2unix' --tag-name-filter cat -- --all 

これによると、リポジトリ内のコミットごとに重複コミットが発生し、作成者の日付とコメントは同じです。期待どおりのハッシュが新しいものです。それは私が期待していたはずのものですか?私はそれが既存のコミットを異なるバージョンのファイルで置き換えると思った。

無関係なすべてのコミットが発生しないような変換を行うより良い方法はありますか?

答えて

2

Gitコミットは変更不可能なので、何かを変更する場合はいつでも、特定のコミットについてに変更する必要があります。実際には新しいコミットを作成する必要があります。これには、ファイルの内容、作成者の日付/時刻、または親コミットが含まれます。 (したがって、1つのコミットでコンテンツを変更する場合、それ以降のすべてのコミットを新たに作成する必要があります)。

これはあなたが期待するべきことです。いいえ、方法はありません。新しいコミットを生成しない変換。これは、rebasefilter-branchを含む履歴を書き換えるコマンドに当てはまります。

Pro Gitの本のGit Internals - Git Objectsセクションでこれがどのように機能するかについて詳しく読む。

+0

奇妙なことに、私が実行したフィルタコマンドは、何も必要でない(コミット - >変換が発生していない)コミットを作成しましたか? – MarkE

+0

@ MarkEおそらく、私はこれをテストしていません。 (私は 'git rebase'がどのように動作するのか知っています) –

+1

filter-branchコマンドは、修正されていないコミットを意図的にスキップするという点で、' git rebase'ほどスマートではありません。代わりに、元のコミット*(作成者とコミッターのデータを含む)からの保存されたメタデータを使用して、新しいコミット*を作成します。 * tree *が変更されておらず、* parents *が変更されておらず、残りのデータとメタデータが変更されていない場合、 "コピー"コミットは元のビットと同じビットであるため、同じハッシュしたがって、*同じコミットであり、自然に再利用されます。 (Rebaseは意図的にコミットをコピーするときにコミッターのメタデータを保存しません) – torek