23

以前git-svnは、SVN リポジトリの git ミラーを作成していました。SVN 内の構造が少し標準から外れていたため、git はブランチと共通のコミットを持たないブランチを作成しましたmaster

      A---B---C topic

D---E---F---G master

私はコミットがコミットAに基づいていることを知ってEおり、gitがその事実を認識しない原因となっている問題を修正したことを確信しています(を使用filter-branch)。私がやりたいのは、ブランチに再アタッチtopicして、の親として設定することです:masterEA

      A---B---C topic
     /
D---E---F---G master

git-rebaseAcommit の diff には、 に既に存在する多数のファイルの作成がリストされておりmaster、膨大な数の競合が発生しているため、私にはうまくいかないようです。
私のgitの理解から、Eの親として設定するだけAで、すべての問題を解決するのに十分なはずです。
これは可能ですか?もしそうなら、どうすればいいですか?

4

3 に答える 3

29

グラフトを見てください (グラフト ファイルは にあります.git/info/grafts)。形式は非常に単純です。

<commit sha1> <parent1 sha1> <parent2 sha1> … <parentN sha1>

これにより、コミットが実際に持っているものとは異なる親を持っていると git に信じ込ませます。filter-branch を使用して接ぎ木を永続的にします (接ぎ木ファイルを削除できるようにします):

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

これはリポジトリの履歴を書き換えるので、共有リポジトリでは使用しないでください。


たとえば、マスター ブランチに移植されているコミットの履歴のみを書き換えたい場合は、次のコマンドを使用します。

git filter-branch --tag-name-filter cat -- master..
于 2010-11-12T12:46:48.650 に答える
8

あなたの図に基づいて(ただし、「gitがその事実を(使用して)認識しない原因となっている問題を修正したことはかなり肯定的です」という意味については心配していますfilter-branch)、次のようなことができるはずです以下。

# checkout A
git checkout A

# Reset the branch pointer to E so that E is the parent of the next commit
# --soft ensures that the index stays the same
git reset --soft E

# Remake the commit with the E as the parent, re-using the old commit metadata
git commit -C HEAD@{1}

# Rebase the topic branch onto the modified A commit (current HEAD)
git rebase --onto HEAD A topic
于 2010-11-12T12:58:20.060 に答える
7

必要なのはこれだけです:

git rebase --root --onto master^^ topic^^ topic

root オプションを使用すると、A を含めることができます。

アップデート:

--preserve-mergesリベースするパーツの分岐とマージを保持する場合は、このオプションを追加します。

于 2010-11-24T06:50:20.880 に答える