新しいことを学ぼうとしているgit サブツリーGit 1.7.11 で追加されたコマンドです。サブツリーを追加した後、リベースができなくなるようです。README ファイルがあるプライマリ リポジトリと、同じく README ファイルがあるライブラリ リポジトリがあります。これを lib ディレクトリに追加しますsubtree add
。
$ git subtree add -P lib/mylib myliborigin master
これは正常に動作しますが、履歴は次のようになります。
* 22c1fe6 (HEAD, master) Merge commit 'b6e698d9f4985825efa06dfdd7bba8d2930cd40e' as 'lib/mylib' -
|\
| * b6e698d Squashed 'lib/mylib/' content from commit d7dbd3d
* b99d55b Add readme
* 020e372 Initial
ここで、リポジトリをリベースしたいのですorigin/master
が、スカッシュ コミットが親コミットに直接適用され、サブツリーを追加するときに指定したプレフィックスではなくリポジトリのルートに適用されるため、適用されないため失敗します。
その理由は、squash コミットを見れば明らかです。プレフィックスに関する情報はありません。元の mylib コミットがまとめられただけです。次のマージ コミットだけがそれについて知っていますが、rebase はここでそれを考慮しません。
回避策はありますか (サブツリーのコミットをリベースしない以外に)?
ベストアンサー1
これは単純なケースでは機能します:
git rebase --preserve-merges master
コメントを寄せてくれた@Techlive Zhengに感謝します。
あなたは見るかもしれません
fatal: refusing to merge unrelated histories
Error redoing merge a95986e...
これは、git がサブツリーを自動的に適用できなかったことを意味します。これにより、@ericpeters が回答で説明した状況になります。解決策:
サブツリーを再度追加します (最初に使用したのと同じコマンドを使用します)。
git subtree add -P lib lib-origin master
リベースを続行します:
git rebase --continue
これで準備完了です!
正常に動作したかどうかが気になる場合は、リベース後に元のバージョンと比較して、何も変更されていないことを確認できます。
git diff <ref-before-rebase> <ref-after-rebase> -- .
(-- .
最後の は、git にdiff
現在のディレクトリ内のファイルのみを指示します)。
他のすべてが失敗し、コミット自体を保持する必要がない場合は、git cherry-pick
元のサブツリーコミットのみを実行できます。
コミット メッセージは次のようになりますAdd 'lib/' from commit '9767e6...'
。これが必要なメッセージです。