そこでgit-subtreeを使ってrepoBのさまざまなブランチをrepoAのサブディレクトリに作成しました。
git clone repoA
cd repoA
// some commits to repoA here
git subtree add --prefix=src/dirA repoB branchA
私はrepoAでいくつかのコミットを行いました。
git subtree push --prefix=src/dirA repoB branchA
しばらくして、別の repoC から repoB/branchA に何かをコミットしました。そこでも、git-subtree を使用して branchA が追加されました。
今、私は試しています
git subtree pull --prefix=src/dirA repoB branchA
しかし、明らかな理由もなくマージ競合が発生しています。変更は単純で、まったく競合しません。パッチによって確認されています。
このエラーを修正する方法がわかりません。 同じ/類似の問題を扱っている他の
2 つ または 4 つのスレッドをすでに見つけました。
- git-subtree プルの複雑さ
- git subtree pull -P whatever <repo> <ref> 常にマージ競合
- 中央リポジトリからプルするときに git-subtree の競合が発生する
- Git サブツリー マージは、単純な上流の変更をマージするときに競合を報告します。(ただし、これはサブツリーのマージ戦略に関するものです。下記を参照してください)
コミットをリベースしたり編集したりしていないため、これが異なる SHA-1 に関連しているかどうかはわかりません (リンク 1 から 3)。
私の問題はリンク 4 に似ています。git が魔法のように単純なマージに失敗します。ただし、リンク 3 はサブツリー マージ戦略について説明しており、git-subtree については特に説明していないため、これが私の状況にまったく当てはまるかどうかはわかりません。
状況は同じように見えます:
<<<<<<< HEAD
=======
// changes from commit I try to pull from repoB/branchA
>>>>>>> {commit SHA-1 from commit I try to pull from repoB/branchA}
そこで、3ウェイマージウィンドウ(kdiff3)でBASEが明らかに間違っていることに気づきました。しかし、もしそうだとしたら、なぜgitはbase以降のすべての以前のコミットを適用しようとしないのでしょうか?
git log --oneline
マージが失敗した後、マージ/マージを試みる前に、問題のあるコミットの前に重複したコミットがないことがわかります。BASEとして表示されるファイルのバージョンは、最初に発行したときのファイルです。
git subtree add --prefix=src/dirA repoB branchA
repoA 内。
それで何が起こっているのでしょうか? 何らかの理由で git subtree がコミットを見つけられないのに、BASE から HEAD~1 へのコミットを適用しようとせず、実際に不足しているコミット HEAD のみを適用しようとしていることに関係しているようです。
どちらのリポジトリの履歴も台無しにせずにこのエラーを修正するにはどうすればいいでしょうか? なぜ git はこの単純なコミットをプルできず、マージ競合であると判断するのでしょうか?
どのような洞察でも大歓迎です。
ベストアンサー1
さて、私はこれを理解しました。これは 2 つの問題から成っていました。まず、私のツリーは実際には次のようになっていました。
私のツリーには に影響するコミットがありましたが、がすでに移動したsrc/dirA
ためまだプッシュされていませんでした。repoB/branchA
共通の祖先を探しているため、正しいベースが見つからないことがわかりましたgit subtree pull
。そのため、最後に使用したバージョンが使用されました。合併した木々、つまり私がgit subtree add
最初に電話したとき。
さて、共通祖先の問題を解決するには、 を実行する必要があります。これは、おざなりなマージを実行し、git が適切なベースを再び見つけられるようにします (つまり、からgit subtree split --rejoin
にコミットがプッシュされた後) 。repoA
repoB/branchA
しかし、私のケースを見るとわかるように、git subtree split --rejoin
a の後に a が続くとgit subtree pull
問題は解決しません。
プッシュされたかどうかに関係なく、git subtree split
すべてのコミットの合成履歴を作成するため、SHA-1 の合計が異なります。デモ用に合成履歴を独自のブランチに分割しました。src/dirA
split
git subtree pull
は、もちろんその後は成功します。しかし、と合成ツリーの履歴はそれ以降はまったく異なるため、git subtree split --rejoin
次は失敗します。git subtree push
repoB
したがって、問題のあるプッシュされていないコミットの前に戻って、そこから変更を自分のブランチにプルする必要がありました。これは、via がまだ正しいベースを独自に判断できないgit subtree split --rejoin
ため、依然として必要なため複雑です。git subtree pull
git merge
私が現在行っている方法は解決済み私の問題は、問題のある非プッシュコミットの直前のコミットをチェックアウトしたことにありましたsrc/dirA
。その後、git subtree split --rejoin
に続いて を実行しましたgit subtree pull
。これにより、もちろんメイン ツリーに 2 つのマージが追加されますが、これを 1 つのマージにまとめる方法がわかりませんでした。ソース コードを読んだところ、この問題を簡単に解決できるとは思えません。
が成功した後、ブランチgit subtree pull
の残りのコミットを にリベースしました。これで、との共有履歴全体で SHA-1 の合計が一致しました。master
master_fix
repoA/master_fix
repoB/branchA
もちろん、これにはリベースの通常の欠点があります。つまり、他の誰かが で作業していた場合master
、その履歴は によって台無しになってしまいますgit branch -m master_fix master
。