Gitブランチをマスターにマージするための最良の(そして最も安全な)方法は何ですか?

2011年04月09日に質問されました。  ·  閲覧回数 1.6M回  ·  ソース

moe picture
2011年04月09日

masterから新しいブランチが作成され、 testと呼ばれます。

masterコミットするか、他のブランチを作成して後でmasterにマージする開発者が何人かいます。

test作業に数日かかり、 master内のコミットでtestを継続的に更新したいとします。

私はどうなるgit pull origin masterからtest

質問1:これは正しいアプローチですか? 他の開発者は、私がところで作業したのと同じファイルで簡単に作業できたはずです。


testでの作業が完了し、 masterにマージする準備ができました。 これが私が考えることができる2つの方法です:

A:

git checkout test
git pull origin master
git push origin test
git checkout master
git pull origin test 

B:

git checkout test
git pull origin master
git checkout master
git merge test

私の理解では、リベースはmasterから変更を取得し、その上に私のものをスタックするため、他の人が行った変更を上書きする可能性があるため、 --rebaseを使用していません。

質問2:これら2つの方法のどちらが正しいですか? そこの違いは何ですか?

このすべての目標は、 testブランチをmasterで発生することで更新し続けることであり、後でタイムラインを線形に保つことを期待して、それらをmasterマージして戻すことができます。できるだけ。

回答

KingCrunch picture
2011年04月09日
3145

これをどのように行うか

git checkout master
git pull origin master
git merge test
git push origin master

リモートブランチからローカルブランチがある場合、これ以外のブランチをリモートブランチとマージすることに抵抗があります。 また、自分がプッシュしたいものに満足するまで、変更をプッシュしません。また、自分とローカルリポジトリ専用のことをまったくプッシュしません。 あなたの説明では、 testはあなただけのもののようですか? したがって、公開する理由はありません。

gitは常にあなたや他の人の変更を尊重しようとします。 --rebase同様です。 適切に説明できないと思うので、Gitの本-リベースまたはgit-ready:リベースの概要を見てください。 それはかなりクールな機能です

John Yin picture
2015年03月14日
433

これは非常に実用的な質問ですが、上記のすべての答えが実用的ではありません。

お気に入り

git checkout master
git pull origin master
git merge test
git push origin master

このアプローチには2つの問題があります

  1. テストブランチとマスターブランチの間に競合があるかどうかわからないため、安全ではありません。

  2. すべてのテストコミットをマスターの1つのマージコミットに「絞り込み」ます。 つまり、マスターブランチでは、テストブランチのすべての変更ログを確認することはできません。

したがって、競合が発生する可能性があると思われる場合は、次のgit操作を実行できます。

git checkout test
git pull 
git checkout master
git pull
git merge --no-ff --no-commit test

テストmergeの前にcommitによってコミット早送り避ける--no-ff

競合が発生した場合は、 git statusを実行して競合の詳細を確認し、解決を試みることができます

git status

競合を解決したら、または競合がない場合は、 commitpush

git commit -m 'merge test branch'
git push

ただし、この方法では、テストブランチに記録された変更履歴が失われ、マスターブランチが他の開発者にとってプロジェクトの履歴を理解するのが難しくなります。

したがって、最良の方法は、 merge代わりにrebaseを使用する必要があることです(この時点で、ブランチの競合を解決したとします)。

以下は1つの簡単なサンプルです。高度な操作については、 http://git-scm.com/book/en/v2/Git-Branching-Rebasingを参照して

git checkout master
git pull
git checkout test
git pull
git rebase -i master
git checkout master
git merge test

はい、アッパーが完了すると、すべてのテストブランチのコミットがマスターブランチのヘッドに移動されます。 リベースの主な利点は、直線的ではるかにクリーンなプロジェクト履歴が得られることです。

避ける必要があるのは、マスターブランチなどのパブリックブランチでrebaseを使用しないことだけです。

次のような操作は絶対に行わないでください

git checkout master
git rebase -i test

https://www.atlassian.com/git/tutorials/merging-vs-rebasing/the-golden-rule-of-rebasingの詳細

付録:

  • リベース操作について不明な点がある場合は、 https ://git-scm.com/book/en/v2/Git-Branching-Rebasingを参照して
raylu picture
2011年04月10日
92

リベースもマージも、誰かの変更を上書きしてはなりません(競合を解決するときにそうすることを選択した場合を除く)。

開発中の通常のアプローチは

git checkout master
git pull
git checkout test
git log master.. # if you're curious
git merge origin/test # to update your local test from the fetch in the pull earlier

マスターにマージする準備ができたら、

git checkout master
git log ..test # if you're curious
git merge test
git push

マージで何かが壊れることを心配している場合は、 git merge --abortが用意されています。

マージの手段としてプッシュしてからプルを使用するのはばかげています。 また、なぜあなたがテストを原点に押し上げているのかわかりません。

Martin Thoma picture
2016年04月21日
45

まず、マージするブランチをできるだけクリーンにします。 テストを実行し、状態が希望どおりであることを確認します。 して、新しいコミットをクリーンアップしますgitのスカッシュ

KingCrunchesの回答に加えて、使用することをお勧めします

git checkout master
git pull origin master
git merge --squash test
git commit
git push origin master

他のブランチで多くのコミットを行った可能性がありますが、マスターブランチでは1つのコミットのみである必要があります。 コミット履歴をできるだけクリーンに保つために、テストブランチからのすべてのコミットをマスターブランチの1つのコミットに押しつぶすことができます( Git:押しつぶすか押しつぶさないか?も参照)。 次に、コミットメッセージを非常に表現力豊かなものに書き直すこともできます。 コードを掘り下げることなく、読みやすく理解しやすいもの。

編集:あなたは興味があるかもしれません

したがって、GitHubでは、機能ブランチmybranchに対して次のことを行うことになります。

原点から最新のものを入手

$ git checkout master
$ git pull origin master

マージベースハッシュを見つけます。

$ git merge-base mybranch master
c193ea5e11f5699ae1f58b5b7029d1097395196f

$ git checkout mybranch
$ git rebase -i c193ea5e11f5699ae1f58b5b7029d1097395196f

ここで、最初のものだけがpickであることを確認し、残りはsです:

pick 00f1e76 Add first draft of the Pflichtenheft
s d1c84b6 Update to two class problem
s 7486cd8 Explain steps better

次に、非常に適切なコミットメッセージを選択し、GitHubにプッシュします。 次に、プルリクエストを行います。

プルリクエストをマージした後、ローカルで削除できます。

$ git branch -d mybranch

とGitHubで

$ git push origin :mybranch
Robin Wieruch picture
2018年10月31日
9

古いスレッドですが、私はそれを行う方法を見つけ

マスターとブランチを最新の状態にするには:

git checkout master
git pull --rebase origin master
git checkout <branch_name>
git pull --rebase origin <branch_name>

マスターの上にブランチをマージします。

git checkout <branch_name>
git rebase master

オプション:リベース中に競合が発生した場合:

まず、ファイルの競合を解決します。 次に:

git add .
git rebase --continue

リベースされたブランチをプッシュします。

git push origin <branch_name>

これで、2つのオプションがあります。

  • A)PR(GitHubなど)を作成し、UIを介してそこにマージします
  • B)コマンドラインに戻り、ブランチをマスターにマージします
git checkout master
git merge --no-ff <branch_name>
git push origin master

完了。

djheru picture
2016年03月17日
6

これは、私がチームでの仕事で使用するワークフローです。 シナリオはあなたが説明した通りです。 まず、 test作業が終了したら、マスターを使用してリベースし、 testブランチの作業中にマスターに追加されたものをすべてプルします。

git pull -r upstream master

これにより、 testブランチをフォークして適用したため、変更がマスターにプルされ、マスターの現在の状態を「上に」テストするために行った変更が適用されます。 テストで編集したのと同じファイルに他の人が変更を加えた場合、ここで競合が発生する可能性があります。 ある場合は、手動で修正してコミットする必要があります。 それが済んだら、マスターブランチに切り替えて、問題なくtestをマージするのがよいでしょう。

Vinay Sikarwar picture
2015年04月07日
5
git checkout master
git pull origin master
# Merge branch test into master
git merge test

マージ後、ファイルが変更された場合、マージすると「競合の解決」のエラーが発生します

したがって、最初にすべての競合を解決する必要があり、次にすべての変更を再度コミットしてからプッシュする必要があります

git push origin master

彼は自分がどのような変更を行ったかを知っていたので、これはテストブランチで変更を行った人の方が良いです。

user776686 picture
2018年09月13日
4

リベース方式を使用します。 主な理由は、それがあなたのケースを意味的に完全に反映しているからです。 あなたがしたいのは、現在のブランチの状態を更新し、最新のものに基づいているかのように「ふり」することです。

したがって、 masterチェックアウトしなくても、次のようになります。

git fetch origin
git rebase -i origin/master
# ...solve possible conflicts here

もちろん、オリジンからフェッチするだけでは、 masterのローカル状態は更新されません(マージは実行されないため)が、私たちの目的にはまったく問題ありません-のために、切り替えを避けたいと思います時間を節約できます。

cgnorthcutt picture
2020年02月28日
3

@KingCrunchの答えは多くの場合うまくいくはずです。 発生する可能性のある問題の1つは、テストから最新のものを取得する必要がある別のマシンを使用している可能性があることです。 したがって、最初にプルテストを行うことをお勧めします。 リビジョンは次のようになります。

git checkout test
git pull
git checkout master
git pull origin master
git merge test
git push origin master
omkar picture
2020年05月20日
2

開発ブランチと機能ブランチに従って回答します。

機能ブランチを使用していて、開発で更新する必要がある場合は、次のコマンドを使用します。

git checkout develop
git pull
git checkout feature/xyz
git merge develop

これで、機能が開発で更新され、変更をプッシュできます。