前
A1-----A2 (master, contains a:apple, b:banana, c:carrot)
\
\----B1 (second, contains a:apple, b:beets, d:dandelion)
- 現在のブランチ: 2 番目
git status
: 掃除
バリアント 1: マスターへの参照なし (非常に醜い)
git read-tree -m -u master
git commit -m 'B2: copy of A2'
git diff master
後:
A1-----A2 (master, contains a:apple, b:banana, c:carrot)
\
\----B1---B2 (second, contains a:apple, b:banana, c:carrot)
- 現在のブランチ: 2 番目 (ff)
git status
: 掃除
diff
状態までmaster
:きれい
バックオフが機能することを確認します。
git reset --hard HEAD^
git clean -f
git branch -avv
前の状態を再度表示します。
この亜種は何をしますか?
git read-tree
指定された他のコミット (ここmaster
) を INDEX に読み込みます
- オプション
-u
が指定されると、それに応じてワークツリーを更新します
- 次に、これは通常どおり B1 にコミットされます
- ただし、「マージされた」ツリーへの参照は追加されません。
バリアント 2: master へのマージ参照を表示する (推奨!)
すみません、正しい方法がわかりませんでした。回避策は次のとおりです。
最初: ダミーのマージを行う
git merge -s ours -m 'B2 dummy' master
2 番目: マージを正しいデータに修正する
git read-tree -m -u master
git commit --amend -m 'B2: copy of A2'
3番目: 本当に一致することを確認しますmaster
:
git diff master
後:
A1-------A2 (master, contains a:apple, b:banana, c:carrot)
\ \
\----B1---B2 (second, contains a:apple, b:banana, c:carrot)
- 現在のブランチ: 2 番目 (ff、マージ済み、最初の親: B1)
git status
: 掃除
diff
状態までmaster
:きれい
バックオフが機能することを確認します。
git reset --hard HEAD^
git clean -f
git branch -avv
必要に応じて、前の状態を再度表示します。
これはどのように作動しますか:
git read-tree -m -u master
マージ情報をリセットするため、残念ながら、マージを開始してツリーを読み取り、後でこのマージをコミットすることはできません。
-u
ただし、これはワークツリーの更新に不可欠であるため、オプションを使用したいと考えています。しかし、 required または同様のもの-u
は-m
、マージ モードから抜け出します。
- そのため、前にダミーのマージを実行します (そして
ours
、マージの競合を防ぐために戦略を使用しますが、これはまさに私たちが望んでいる間違ったことです)。
- 次に、必要に応じてマスターから状態を読み取り
git read-tree
ます
- そして今
amend
、最終的に正しいインデックスの内容とマージします。
- これにより、元のマージ情報が保持されます。
ff
これはアップストリームによることに注意してください。
これの何が問題なのですか?
git commit
アトミックであることを意味します。あなたが正しい状態を持っているかどうかのどちらかです。
- ただし、これにより、競合状態 (停電) によってローカルの git リポジトリが望ましくない状態になる可能性がある非アトミックな状況が発生します。
- これは、この戦略が自動化されたセットアップで使用される場合には不適切です。たとえば、リリース (B1) の後、現在のアップストリーム (マスター) を使用して再起動し、次のリリース (B2 以降) を作成する必要があります。
- したがって、バリアント 2 は、これに対する決定的な最後の言葉と見なすことはできません。はい、何とか機能しますが、きれいでもなく、完璧でもありません。
それを行うための他のソリューションは、複雑すぎるようです。しかし、おそらく私は少し監督しましたか?
完全に理解できない git-plumbing コマンドを使用して、正しい commit-object を自分で作成するか、理解して使用するのが簡単なソリューションには行きません。
または、非常に複雑なサブブランチを実行してから、サブブランチに早送りしてから削除します。これにより、何かが壊れた場合に複雑なクリーンアップが必要になるなど、より複雑なことが発生するため、二重のノーゴーです。
または、ワークツリーをインデックスに更新するために必要なコマンドを見つけます (これ-u
はgit read-tree master
、通常どおり) コミットの前 (!) に発生する必要があるためです。
TODO
これは、サブモジュールで完全にテストされていません。それらが追加、削除、置換などされ、更新さ.gitmodules
れ.git/modules/
ているか、いくつかのものをブロックしている場合。すごい話。