2017-10-01 1 views
0

私はgitを使って、一連のフィーチャブランチを作成し、完了時にmasterにマージします(git merge --no-ff)。これにより、前のフィーチャブランチの開始点と終了点を識別するのに便利な空のマージコミットが作成されます。`git rebase --preserve-merges`へのより速い方法

複数の並行枝やネストされた枝を処理するために、私はリベースを使用します。私は戻ってマージすることはありません、私はいつも最新のコミットに私のブランチをrebaseし、テストし、最後にとマージするとすべてが完了します。ネストされたブランチでは、私は同じことをします:複数のブランチは、メインブランチに順番にマージされます。メインブランチは、最後にマージされます。

ネストされたブランチとのマージに関する情報を保持するために、私はしばしばgit rebase --preserve-mergesを使用します。これはまさに私が望むものであり、ワークフローには何の問題もありません。

gitの主な問題は、git rebase --preserve-mergesが非常に遅いことです(コミットあたり約2秒かかることがあります)。 What exactly does git's "rebase --preserve-merges" do (and why?)を読んだ後、gitは任意のグラフを処理しなければならないので、gitはマージを維持するために多くの作業を実行する必要があります。

私のワークフローは線形履歴に相当するグラフを生成するので、より速い方法でgit rebase --preserve-mergeを実行する方法があります。履歴の「線形性」を保証します空のマージだけがコミットしますか?私は、最終結果が正しい限り、スクリプトや奇妙なコマンドを使用しても構いません。

 A-B-C 
    / \ 
(1)--------D-- master 
    \ 
    \---F-----I-- feature 
     \/\ /
     E G-H 

    A-B-C E G-H 
    / \/\/ \ 
(2)--------D---F-----I-feature 
     master 

tl; dr:基本的な履歴が線形であることを知っているので、(1)を(2)に変換する方法はありますか?git rebase --preserve-mergesはそれほど多くの作業を必要とせず、高速ですか?

答えて

0

あなた(、Pythonで、例えばgit rev-list --parentsを実行し、コピー操作を開始する前に、すべての親の情報を収集する)、より巧妙なものにbashスクリプトからそれを書き換えることにより、少しそれをすべてをスピードアップすることができるかもしれません基本的には難しいことです。他のリンクノートの答えとして、git rebase -pも正確にを保存しないでくださいと非常にマージしてを再作成します。完全に一般的なケースでは、私はあなたがより限定された特別なケースに有利に無視していることを知っています。 git rebase -pは特別なオプションや処理が適用されたマージで完全に失敗します(--no-commitは "悪いマージ"を生成するための手動修正とマージするか、または-X rename-thresholdまたは-X oursなどとのマージを実行します)。特殊ケース実際には情報は結果として得られるツリーにのみ格納されます。リベースコードはそれを探すことさえありません(これはずっと時間がかかります:最初に元のマージを再現して、オプションのないマージが元の結果を再作成したかどうかを確認する必要があります)。

これらのオプションの速度(または速度の不足)は、リポジトリとそのファイルのサイズ、Windows(極端に遅い)またはUnixishシステム(はるかに高速)を使用するかどうかによって異なります。 Gitの人々は、スクリプトがとても遅いためWindowsで受け入れられるようにするために、C言語での書き換えを続けているので、スクリプトを実行するにはWindowsの速度が非常に遅くなければならないという理由はわかりません。

Windowsでこれを実行している場合、速度を上げる方法の1つはWindowsの使用をやめることです。 :-)(WindowsとLinuxの間の調整には、git pushgit fetchを使用して、リベース自体の間、これを行うことができます。)

+0

残念ながら私はUbuntuにいるので、それはそれに依存しているとは思わない。私が最後にこの問題を抱えたレポは、厄介な歴史を持つ多くの人々によって使用されたので、コマンドの遅さの要因となっていた可能性があります。しかし、私は私の特別なケースでは難しいことに同意しません。単純な 'git rebase'はそれを正しく非常に速く行います。私の唯一の違いは、マージコミットをスキップする代わりに、それらをコピー/再作成する必要があるということです。それほど難しいはずはありませんか? – Svalorzen

+0

大きなリポジトリでは、 'git merge'自体が30分かかります。恐らくあなたのものは*この*大きなものではありませんが、併合を繰り返すことが原因かもしれません。インタラクティブなrebaseはシェルスクリプトであるため、 '-x'フラグをセットしてそれが動作するのを見て、遅延がどこにあるのかを知ることができます。 – torek