6

一度に 1 つずつ、約 10 の機能ブランチをマージしたマスター ブランチがあります。

したがって、最近の履歴は次のようになります。

merged feat/10 (HEAD of master)
merged feat/9
merged feat/8
merged feat/7
merged feat/6
merged feat/5
...

これが悪いことがわかったfeat/7ので、マスターから削除したいと考えています。そのマージ コミットを元に戻すだけでは十分ではありません。なぜなら、壊れたコミットが履歴にまったく存在することを望まないからです。インタラクティブなリベースを実際に使用することはできません。これは、履歴を平坦化して、すべてが単一のブランチで行われたかのように見せてしまうためです。また、すべての優れたマージ履歴を保持したいからです。

ブランチの履歴から特定のマージコミットを削除する方法はありますか?

実際の履歴は上記の例よりもはるかに複雑であるため、feat/7 以降のすべてのマージを手動でやり直すことは適切なオプションではないことに注意してください。

編集

これを dup として閉じることに投票した人のために明確にするために: これはリベースを使用してコミットを実行する方法に関する FAQ ではなく、もちろん何度も回答されています。ここでの質問は、マージ履歴を平坦化せずにコミットを取り出すことについてです。

4

4 に答える 4

1

これはやりたいことではありませんが (いわば、マージ コミットを「ザップ」します)、実際にgit reset --hardは、rebaseまたはfilter-branch. マージを元に戻すだけです。

git revert -m 1 <commit_for_feat7>

マスター ブランチをリバートで汚染するのは特に好きではありませんが、本質的に問題はありません。しばらくパッチfeat7を当てない場合、または単に変更セットを履歴から消したい場合、このソリューションは history-revision よりもはるかに問題が少なくなります。

于 2012-08-06T12:28:30.197 に答える
1

親がコミットを指すようにコミットgit filter-branch --parent-filterを書き換えるために使用できます。他のすべてのコミット (9-10) の親をそのままにしておきます。これにより、マージ コミットが履歴に保持されます。feat/8feat/6

これに関する唯一の問題は、削除されたコードが変更される結果となる競合がどうなるかということです...実際に知る方法はなく、それが原因である可能性があります。

于 2012-08-06T10:00:50.127 に答える
1

あなたの履歴が現在そのように見えていて、まだブランチを削除していない場合はgit reset --hard HEAD~4、7 にマージする前の状態にコードをリセットするだけgit mergeで、良いものを元に戻すことができます。私の頭。

EDIT : rebase で -p スイッチを使用してマージを保持できますが、このスイッチを -i と共に使用すると結果が生じる場合があります。man git-rebase ページを確認し、BUGS 部分を参照して現在のバグを確認してください。

EDIT2 :このコマンドを使用する前に適切な予防措置を講じていない場合、私は一切の責任を負いません。マンページも読む前に使用しないでください。

于 2012-08-06T08:48:03.627 に答える
0

現在のハッシュは履歴全体に依存するため、単に git からデータを削除することはできません。

1 つのオプションは、feat/6 から始まる新しいブランチを作成し、feat/8 からマージを開始して、ブランチ ヘッドが feat/7 からの変更なしで別のハッシュを指すことができるようにすることです。

私が間違っていなければ、もう1つのオプションはgit replace(以前は接ぎ木と呼ばれていたと思います)です。これにより、feat/8 のポインタを feat/7 から feat/6 に「置換」できます。これがどのように正確に達成されるかは完全にはわかりませんが、ハッシュが変更されないためfeat/8にはfeat/7へのポインターがまだどこかにあるため、真の代替ではないように見えますが、git replaceどういうわけか代替を追加しますfeat/8 が feat/6 を指す履歴。マニュアルページから:

git replace [-f] <object> <replacement>   
git replace -d <object>…  
git replace -l [<pattern>]

.git/refs/replace/ に置換参照を追加します

置換参照の名前は、置換されるオブジェクトの SHA1 です。置換参照の内容は、置換オブジェクトの SHA1 です。

-f が指定されていない限り、置換参照は .git/refs/replace/ ディレクトリにまだ存在していてはなりません。

置換参照は、到達可能性トラバーサル (プルーン、パック転送、および fsck) を実行するコマンドを除くすべての git コマンドでデフォルトで使用されます。

git の直後に --no-replace-objects オプションを使用して、コマンドの置換参照の使用を無効にすることができます。

編集: git replacefeat/7 からの変更は feat/8 のマージに存在するため、再考するのは悪い考えかもしれません。おそらく最初のオプションを使用する必要があります: マージされた feat/6 から新しいブランチを開始し、feat/8 から再マージします。

于 2012-08-06T09:36:39.293 に答える