2011-08-05 11 views
5

私はzipスナップショットから回顧的プロジェクト履歴を構築しています。私はすでにスナップショットからコミットの長いブランチシーケンスを構築しました。私は最後にコミットシーケンスの中間にある様々な場所にすべきいくつかの「発見された」スナップショットを最後に追加しました。git:コミットシーケンスの順序を変更する(厳密に)方法

git rebase -i <startCommit>を使用してgitスナップショットを再注文しようとしています。私は単にピックリストの順序を入れ替えます。これは、単純にコミットオブジェクトを書き直すが、(スナップショットが変更されていないため)基本となるツリーを同じに保つことに過ぎない。

リベースのように見えますが、この場合、単純な再配置ではなく、パッチを作成して多くの競合が発生しています。この特定のケースに対して、より適切なコマンドがありますか?私には合併はなく、一つの枝しかない。レポはまだ非常にローカルでプライベートです。

+1

'git rebase'は、コミットがツリーだけでなく変更によって実際に識別されることを前提としています。あなたがやろうとしていることはまれですので、gitの磁器部分はあまり役に立たず、配管を使わなければならないと思います。 – svick

+0

私は[このカスタムマージドライバ]を使用しているのだろうか(http://stackoverflow.com/questions/928646/how-do-i-tell-git-to-always-select-my-local-version-for-競合する - sp-930495#930495)などが動作します。 –

+0

@Karl:少なくとも、それが何をしているのか理解するには、その方法を通して見栄えが良いでしょう。クイックルックでは、私のWindowsを簡略化すると、Adymitrukの方法より先に鳴るかもしれないことが示唆されています<-> Linuxの混乱;-) –

答えて

3

リベースしないでください。新しい枝を作りなさい。

git checkout X -- . 
git add -A 
git commit -C X 

繰り返しをしたいという時系列順にすべてのコミットのために:Xは、SHA1または、その後、使用することをコミットのtreeishがある場合。

我々は最後の5つのコミットの順番を逆に例:

git checkout -b temp old_branch~5 
git checkout old_branch -- . 
git add -A 
git commit -C old_branch 
git checkout old_branch~1 -- . 
git add -A 
git commit -C old_branch~1 
git checkout old_branch~2 -- . 
git add -A 
git commit -C old_branch~2 
git checkout old_branch~3 -- . 
git add -A 
git commit -C old_branch~3 
git checkout old_branch~4 -- . 
git add -A 
git commit -C old_branch~4 

git push . HEAD:old_branch -f 
git checkout old_branch 
git branch -d temp 

git log -5 # to see the new history 

は、このことができます願っています。

+0

私はこれと一緒に行くかもしれないと思いますが、最初のリベースを使用してコミットsha1のリストを取得することのひねりを得て、主にピックファイルにそれらをすべて入れるためです。その後、スクリプトとして実行します。 30年後に他のOSでLinuxの編集とスクリプトの方法を学ぶのは面倒です! –

+0

'git add -A'コマンドはすべてのファイルを選択するために末尾に' .'を付けるべきですか、 '-A'の暗黙的な部分ですか? (私はいつも見たことがあります/それを使用した) –

+0

私はまた、チェックアウトの間にドロップされたディレクトリとファイルを削除するシーケンスの失敗に問題が発生しています。トップレベルのディレクトリ名は各スナップショット間で変更されますが、通常は名前の変更のセットとして表示されますが、ここでは単に追加セットを取得しています!助言がありますか? –

0

私はリベースを簡単にすることはできませんが、なぜ「単純な再調整」ではないのか説明できます。たとえば、リビジョンごとに1行のテキストが追加されたファイルを1つ取ります。最初のコミットでは、それは次のようになります。

あなた あった、コミット第三に
Commit 1 
Commit 2 
Commit 3 

:あなたはもともと順不同でそれらを置くので二コミットで

Commit 1 

、それは次のようになります二スナップショットは、それは次のようになります。

Commit 1 
Commit 2 
Gitはgitのになるよう、 パッチを扱っている

、セリ

  • 「2をコミット」と「1コミット」という行の後に「3コミット」と言う行を追加します。「1コミット」という行を持つファイルを追加します

    • :コミットのESは次のようになります
    • あなたはそれを並べ替えるときに、それがどのように見える「2をコミット」という行

    後に「3コミット」という行を削除:ライントンを使用してファイルを追加します。

    • "Commit 1"
    • "Commit 2"と書かれた行の後の行を削除してください。
    • "Commit 2"と "Commit 3"という行を追加します。 1 "

    これは2番目のステップに進み、一致する「コミット2」の行がないこと、実行することがわからないため手動でマージする必要があることを示します。

    マージを手作業で解決した後、次のステップでgitは2行目を見ていて、手動でマージする必要があります。

  • +0

    だから、私は 'git rebase'がこの仕事のための正しいツールではないと思うのです。私は正確には何がわかりません。 – svick

    +0

    これは非常に面倒です。パッチを適用するのではなく、各コミット時に存在するスナップショットをつなぎ合わせるだけです。 –

    0

    あなたの歴史はこのようになります場合:efあなたはまだrebase -iを行うことができます

    a間と dのどこかに置かれることになったが、コミット時に editを入れて

    a->b->c->d->e->f 
    

    スナップショットを挿入したい場所の前に配置します。 gitがその編集のために一時停止すると、あなたの作業ディレクトリにスナップショットを置き、追加/コミットします。次の箇所、リンス、リピートまでリベースを続けます。

    言い方が必要な場合は、置き忘れたスナップショットを扱う、最初に置き忘れたコミット、efを削除したい場合もあります。

    +0

    これはおそらく多くの競合を引き起こします。そして、それは変更を適用しようとするので、結果は以前と全く同じツリーではないかもしれません。 – svick