1

Gitでは、このようなことは可能ですか?

master B - C - D

これに?

master A - B - C - D

Git を使用した既存のプロジェクトがあり、すべてうまくいきました。しかし、そのプロジェクトの古いバージョンを見つけたので、同じレポにコミットしたいのですが、それを A にして、そのプロジェクトの最も古いバージョンのように見せます。Gitでこれを行うことは可能ですか? または他の回避策はありますか?

4

4 に答える 4

2

はい、かなり簡単に実行できますが、標準の警告から始めてB-C-DB'-C'-D'. それであなたの罰金を仮定すると...

まず、git が一連のコミットとして編成され、それぞれがその親へのポインターを持っていることを理解することから始めます。このようにして、コミットのツリーが作成されます。

tree 1:  B - C - D

あなたがしたいことは、最初のコミットの前に何かを追加することであり、最初のコミットの前に対処することは何もないため、これを行うために新しいツリーを作成する必要があります。

新しいツリーを作成するには、空のコミットから始めます。リポジトリの最初のコミットとして空のコミットを使用すると、このようなことが容易になります。これは、次のコマンドで実行されます (後で参照するために番号が追加されています)。

git checkout --orphan new-branch            (1)
git rm -r --force --cached .                (2)
git clean -fd                               (3)
git clean -fd                               (3a)
git commit --allow-empty -m 'Initialize'    (4)

これにより、他のブランチに接続されていない新しいブランチが作成されます (1)。これにより、作業ディレクトリ内のすべてのファイルがキャッシュされ、コミットの準備が整います。これらのファイルをコミットしたくないので、(2) それらをキャッシュから削除します。while (3) ディレクトリからそれらを削除します。無視されたファイルは消去されませんが、.gitignore ファイルは消去されるため、2 回消去する必要がある場合があります。ファイルは再度消去する必要があります。

最後に、(4) このブランチの最初のコミットとして空のコミットを作成します。--allow-empty引数はこれを可能にします -- そしてどんなメッセージもそうします。

ここで、以前のバージョンのプロジェクトからすべてのファイルを追加し、Aコミットします。

git add .
git commit -m 'A'


------------------
tree 1:  B - C - D
tree 2:  A

に進む準備ができましB-C-DA。がオンの間new-branch、このコマンドはそれらを移動します。

git rebase -i --onto new-branch --root D

これは をチェックアウトDし、ツリーをルートに戻し (巻き戻し)、B各コミットを順番に移動しますA- に戻るまで、各ステップで新しいコミットを作成しDます。 注: ここでマージの競合が発生する可能性が高いため、それらを処理する準備をしてください。

完了すると、ツリーは次のようになります

tree 1: <empty>             <-- this will be garbage collected in time
tree 2: A - B' - C' - D'

この時点で、リモート リポジトリにプッシュ バックします。プッシュを強制する必要があります。

git push --force <remote> <local-branch>:<remote-branch>

これにより、リモート ブランチが上書きされます。これが必要なものであることを確認してください

それだけです。リポジトリの唯一のコピーで作業しないことを忘れないでください。そうすれば、再クローンして、問題が発生した場合に再試行できます。それ以外は、実際のリポジトリgit rebase ...の複雑さに応じて、何が起こっているのか、そして遭遇する可能性のある癖についてよく知っているように、読んでおくことをお勧めします。B-C-D

于 2013-03-01T05:40:52.277 に答える
1

Aを新しいコミットとして追加し、B()の前にインタラクティブにコミットをリベースして、コミットを希望どおりrebase -i B~1に並べ替えることができますか?

于 2013-03-01T02:48:39.307 に答える
1

はい、注意事項があります。あなたがから始めるとしましょう:

B - C - D

結果は次のようになります。

あいうえお'

「プライム」マーカーに注意してください。B' は B と同じツリー(コンテンツ) を持ちますが、親が異なるため、異なる SHA-1 ハッシュを持ちます。

これを行う最も簡単な方法は、移植片を使用することです。A と B の両方を含むリポジトリを作成します。

あ

B - C - D

それらが互いに接続されていないことに注意してください。それらを「グラフト」( Wiki ページ) で相互に接続すると、A が B の親になります...

あ
 \
  ...
     \
      B - C - D

移植は一時的なものなので、点線を使用しました。グラフトは、編集.git/info/graftsおよび書き込みによって作成されます。

<Bのハッシュ> <Aのハッシュ>

グラフトは次のコマンドで永続化されます:

git filter-branch --tag-name-filter cat -- --all

これにより、グラフが次のように変更されます。

あいうえお'

永続化したら、grafts ファイルを削除します。

通常の警告が適用されます。履歴を書き換えているため、リポジトリをプルした人​​はgit reset、ローカルの変更がない限り、 を使用する必要があります。

于 2013-03-01T03:22:11.240 に答える
0

要するに、違います。

Gitの各コミットはハッシュで表され、「親」コミットはハッシュ生成の要素の1つです。

したがって、Bの親を変更すると、BはBではなくなります(つまり、ハッシュは同じではなくなります)

リベースを使用してこれを行うこともできます。最初にAを作成し、AでB、C、D ...をリベースします。ただし、前に述べたように、ハッシュは同じではなくなります。それがあなたにとって大丈夫なら、これを先に進めてください:)

于 2013-03-01T03:06:31.957 に答える