58
git filter-branch --env-filter '
export GIT_AUTHOR_EMAIL="foo@example.com"
export GIT_AUTHOR_NAME="foo"' -- commita..commitb

結果はWhich ref do you want to rewrite?

したがって、範囲表記を使用して、2 つの任意の参照の間の範囲を使用することは許可されてfilter-branchいないようです。

このアプローチが不可能な場合、一連の連続したコミット (ブランチの履歴内のどこか) に対してフィルターを実行する最も簡単な方法は何ですか?

4

8 に答える 8

23

私が見つけた最もクリーンな解決策は、次のことを行うことでした。

  1. に一時ブランチを作成しますrefb
  2. にブランチ フィルタを適用しrefa..tempます。
  3. 一時ブランチにリベースして削除します。

すなわち。

git branch temp refb

git filter-branch --env-filter '
export GIT_AUTHOR_EMAIL="foo@example.com"' refa..temp

git rebase temp
git branch --delete temp
于 2013-03-06T19:44:43.557 に答える
12

git filter-branch 範囲表記を受け入れますが、範囲の終わりはコミットの ID ではなく、参照である必要があります。

git checkout -b tofilter commitb
git filter-branch .... commita..tofilter

コミットだけを指定すると、フィルター処理されたブランチで更新する参照がわかりません。

于 2013-03-06T14:52:33.453 に答える
7

その範囲をチェックする if ステートメントでフィルター コマンドを囲みます。次のコマンドを使用して、コミットが特定の範囲内にあるかどうかを確認できます。

git rev-list start..end | grep **fullsha**

現在のコミットは$GIT_COMMITフィルターに保存されます。したがって、フィルターは次のようになります。

git filter-branch --env-filter '
  if git rev-list commita..commitb | grep $GIT_COMMIT; then
    export GIT_AUTHOR_EMAIL="foo@example.com"
    export GIT_AUTHOR_NAME="foo"
  fi' -- ^commita --all

現在のブランチのみを書き換えたい場合は、次のように置き換え--allますHEAD

于 2013-03-07T07:53:09.130 に答える
5

私はこのようにしています。

branch-you-are-filtering と呼ばれるブランチのコンテンツをフィルタリングしたいとしましょう。

ref-for-commit-to-stop-at と呼ばれる ref を持つ、そのブランチへの先祖コミットがあると仮定します。

git filter-branch --commit-filter 'YOUR_FILTER_COMMANDS' branch-you-are-filtering...ref-for-commit-to-stop-at

実行後、ref-for-commit-to-stop-at のコミットは変更されません。branch-you-are-filtering ブランチ内のフィルタリングされた\changed コミットはすべて、ref-for-commit-to-stop-at に基づきます。

--commit-filter を使用するかどうかはあなた次第です。

于 2015-04-21T16:30:22.177 に答える
5

コミットのsha1は親のものに依存するため、履歴の途中でコミットを上書きすることはできません。したがって、git は、フィルタリング後に HEAD 参照をどこに向けたいかを知りません。したがって、HEAD まですべて書き換える必要があります。

例:

A---B---C---D---E---F   master
            \
             \--G---H   branch

コミット B と C をフィルター処理する場合は、D、E、F、G、H の後のすべてのコミットもフィルター処理する必要があります。そのため、git は範囲の最後で ref を使用するように指示し、終了しないようにします。離れた頭でアップ。

B と C のコミットを変更して停止すると、次のようになります。

A---B---C---D---E---F   master
\           \
 \           \--G---H   branch
  \-B'--C'      (HEAD or a temporary TAG?..)      

したがって、masterandbranchは変更されません。これはあなたが望んでいることではないと思います。つまり、すべてのコミットをオーバーライドする必要があります。履歴は次のようになります。

A---B---C---D---E---F   (loose end, will be garbage collected one day)
\           \
 \           \--G---H   (loose end, will be garbage collected one day)
  \-B'--C'--D'--E'--F'  master
            \
             \--G'--H'  branch
于 2013-03-06T14:53:07.947 に答える