web-dev-qa-db-ja.com

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

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

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

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

私はtestからgit pull Origin masterをするでしょう。

質問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

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

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

これらすべての目標は、私のtestブランチをmasterで起こっていることで更新し続けることであり、後でそれらをマージしてmasterにタイムラインをできるだけ線形に保つことを望みました。

1817
moe

これをどのようにしますか

git checkout master
git pull Origin master
git merge test
git Push Origin master

私がリモートのものからローカルのブランチを持っているなら、私はリモートのものとこのブランチ以外の他のブランチをマージすることに満足していません。また、私がプッシュしたいものに満足するまで、そして私が変更をプッシュすることもしませんでした。 testはあなただけのものですか?それを公表する理由はありません。

gitは常にあなたや他の人の変更を尊重しようとします、そして--rebaseもそうします。私はそれを適切に説明することができないと思うので、 Gitの本 - Rebasing または git-ready:/ rebaseの紹介 を少し見てください。とてもクールな機能です

2668
KingCrunch

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

好き

git checkout master
git pull Origin master
git merge test
git Push Origin master

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

  1. テストブランチとマスターブランチの間に競合があるかどうかわからないので、それは危険です。

  2. すべてのテストコミットをmasterの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

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

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

以下は簡単な例です。高度な操作については、 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 の詳細

付録:

332
John Yin

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

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

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があなたのためにあります。

マージの手段としてPushを使ってからpullすることはばかげています。また、なぜOriginにテストを進めているのかもわかりません。

85
raylu

最初にマージするブランチをできるだけきれいにします。テストを実行し、状態があなたが望む通りであることを確認してください。新しいコミットを git squash で片付けます。

KingCrunches answer 以外にも、

git checkout master
git pull Origin master
git merge --squash test
git commit
git Push Origin master

もう一方のブランチでたくさんのコミットを行ったかもしれませんが、それはマスターブランチでのコミットは1回だけです。コミット履歴をできるだけきれいに保つために、テストブランチからのコミットをすべてマスターブランチ内の1つのコミットにまとめます( Git:破棄するかどうか? )。それからコミットメッセージを非常に表現力豊かなものに書き換えることもできます。コードを調べることなく、読みやすく理解しやすいもの。

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

そのため、GitHubでは、機能ブランチmybranchに対して次のようにしました。

Originから最新情報を入手する

$ 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
36
Martin Thoma

これが私がチームで仕事をするときに使用するワークフローです。シナリオはあなたが説明したとおりです。まず、私がtestの作業を終えたとき、私はtestブランチに取り組んでいる間にmasterに追加されたものを取り込むためにmasterとリベースします。

git pull -r upstream master

これはtestブランチをフォークして適用した後にmasterへの変更を引っ張り、そしてmasterの現在の状態の「上に」テストするために行った変更を適用します。他の人があなたがテストで編集したのと同じファイルに変更を加えた場合、ここで衝突があるかもしれません。ある場合は、手動で修正してコミットする必要があります。それが終わったら、masterブランチに切り替えてtestを問題なくマージしてください。

6
djheru

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

それで、masterをチェックアウトすることなしに、私はそうするでしょう:

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

もちろん、Originから取得しただけではmasterのローカル状態は更新されません(マージは実行されません)が、これは私たちの目的には問題ありません。

3
user776686
git checkout master
git pull Origin master
# Merge branch test into master
git merge test

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

それで、あなたは最初にすべてのあなたの衝突を解決する必要がありますそしてあなたはすべてのあなたの変更を再びコミットしなければなりませんそしてそれからPush

git Push Origin master

テストブランチで変更を加えた人は、これがより良い方法です。

3
Vinay Sikarwar

古いスレッドですが、私は自分のやり方を見つけていません。リベースを操作していて、ブランチからのすべてのコミットをマスターの上にマージしたいという人にとっては、それは価値があるかもしれません。何らかの方法で矛盾がある場合は、コミットごとにそれらを解決できます。

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

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

あなたがRebaseの間に衝突に遭遇した場合:

まず、ファイル内の競合を解決します。その後:

git add .
git rebase --continue

リベースが完了したら、マスタの上にブランチをリベースします。

git checkout master
git rebase <branch_name>
3
Robin Wieruch