11

git フローでの作業。昨日、誤って開発をマスターにマージしてしまった Git に慣れていない同僚がいます。

開発には、次のリリースでリリースされるかなりの数の機能があり、マージ時に元に戻す必要があります。これにより、すべての変更を元に戻すコミットが作成されました。マスターを開発にマージすると、リバート コミットによって機能によって生成されたコードが削除されます。

新機能を維持しながら、開発をマスターのホットフィックスと同期できるようにするための最良の方法は何ですか?

- 編集 - 明確にするために、復帰は復帰でし。IE git revert -m 1 <sha>、コミットは既にリモート リポジトリにプッシュされているためです。

これを投稿して以来、マスターを分岐して復帰を元に戻すことで、可能な修正を考え出しましたが、衝突を最小限に抑える可能性がある他の可能性があるかどうか知りたいです。

4

2 に答える 2

14

オプション 1: ハード リセットと強制プッシュ

masterアップストリーム リポジトリのブランチに対して非早送り強制更新を実行できる場合は、 のマージdevelop をに戻す代わりにmaster、単純に のハード リセットを実行できますmaster

# On master branch, do a hard reset back to the commit before the merge
git reset --hard <commit of master before the merge>

# Force push to upstream ONLY IF IT'S OK WITH OTHER DEVELOPERS
git push <remote> master --force

ハード リセットと強制プッシュを行うことの潜在的な欠点は、他の開発者が既にマージ コミットに基づいて作業している場合 (つまり、その上でコミットを行っている場合)、同じ作業を上からやり直す必要があることです。のリセットヘッドのmaster。これは、彼らにとって困難で費用のかかる作業である場合もあれば、そうでない場合もあります。

オプション 2: 元に戻す

これを簡単なテストレポでテストしました。私はそれがうまくいくかもしれないことを強調しなければなりません. そのため、最初にレポのバックアップ クローンを使用して、必ずローカルでテストしてください。これを実際のリポジトリで使用する場合は、自己責任で行ってください。

また、これは最も簡単な解決策ではない可能性があります。masterただし、ハード リセット オプションに対する利点は、開発者がリセットブランチ上で作業をやり直す必要がないことです。

わかりました。それで、あなたが試すことができることの 1 つは 、 にマージmasterし、次にからへ developのマージの復帰を元に戻し、準備ができたら にマージすることです。コマンドで:developmasterdevelopmaster

# Coworker accidentally merges develop into master before it's ready
git merge --no-ff develop

# You revert the merge in the master branch (this creates commit "ABCDEFG"
git revert -m 1 <sha of merge commit>

# You want to merge fixes from master into develop
git checkout develop
git merge --no-ff master

# But now all that work in develop is reverted, so revert the revert "ABCDEFG"
git revert ABCDEFG

# When you're ready to merge develop into master...
git checkout master
git merge --no-ff develop

テストリポジトリでこれをテストするために使用した一連のコマンドを次に示します。

mkdir practice
cd practice/
git init

touch readme.txt
git add practice.txt
git commit -m "Add practice.txt"

git checkout -b develop

touch feature1.txt
git add feature1.txt
git commit -m "Add feature 1"

touch feature2.txt
git add feature2.txt
git commit -m "Add feature 2"

git checkout master

touch hotfix1.txt
git add hotfix1.txt
git commit -m "Fix issue 1"

git merge --no-ff develop

# Creates commit "ABCDEFG" that reverts the merge
git revert -m 1 head
git checkout develop
git merge --no-ff master
git revert ABCDEFG
git checkout master
git merge --no-ff develop

「Reverting Revert」テクニックの詳細については、次のLinux カーネル Git の公式ドキュメントを参照してgit revertください。

-m parent-number

--mainline parent-number

通常、マージのどちら側をメインラインと見なすべきかわからないため、マージを元に戻すことはできません。このオプションは、メインラインの親番号 (1 から始まる) を指定し、revert が指定された親に関連する変更を元に戻すことができるようにします。

マージ コミットを元に戻すことは、マージによってもたらされるツリーの変更を決して望まないことを宣言します。その結果、後のマージは、以前に元に戻されたマージの先祖ではないコミットによって導入されたツリーの変更のみをもたらします。これはあなたが望むものかもしれませんし、そうでないかもしれません。

詳細については、revert-a-faulty-merge のハウツーを参照してください。

この手法がどのように機能するかを完全に理解したい場合は、障害のあるマージを元に戻す方法へのリンクを強くお勧めします。理解するのは難しくなく、実際には興味深く魅力的です。

于 2013-07-25T00:24:59.023 に答える