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
にタイムラインをできるだけ線形に保つことを望みました。
これをどのようにしますか
git checkout master
git pull Origin master
git merge test
git Push Origin master
私がリモートのものからローカルのブランチを持っているなら、私はリモートのものとこのブランチ以外の他のブランチをマージすることに満足していません。また、私がプッシュしたいものに満足するまで、そして私が変更をプッシュすることもしませんでした。 test
はあなただけのものですか?それを公表する理由はありません。
gitは常にあなたや他の人の変更を尊重しようとします、そして--rebase
もそうします。私はそれを適切に説明することができないと思うので、 Gitの本 - Rebasing または git-ready:/ rebaseの紹介 を少し見てください。とてもクールな機能です
これは非常に実用的な質問ですが、上記のすべての答えは実用的ではありません。
好き
git checkout master
git pull Origin master
git merge test
git Push Origin master
このアプローチには 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
競合を解決したら、あるいは競合がなければ、それらをcommit
とPush
にします。
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 の詳細
付録:
リベースもマージも、誰かの変更を上書きするべきではありません(競合を解決するときにそうすることを選択しない限り)。
開発中の通常のアプローチは
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にテストを進めているのかもわかりません。
最初にマージするブランチをできるだけきれいにします。テストを実行し、状態があなたが望む通りであることを確認してください。新しいコミットを 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
これが私がチームで仕事をするときに使用するワークフローです。シナリオはあなたが説明したとおりです。まず、私がtest
の作業を終えたとき、私はtest
ブランチに取り組んでいる間にmasterに追加されたものを取り込むためにmasterとリベースします。
git pull -r upstream master
これはtest
ブランチをフォークして適用した後にmasterへの変更を引っ張り、そしてmasterの現在の状態の「上に」テストするために行った変更を適用します。他の人があなたがテストで編集したのと同じファイルに変更を加えた場合、ここで衝突があるかもしれません。ある場合は、手動で修正してコミットする必要があります。それが終わったら、masterブランチに切り替えてtest
を問題なくマージしてください。
リベース方法を使用します。主にそれは意味的にあなたのケースを完全に反映しているからです。あなたがしたいのは、現在のブランチの状態を更新し、あたかも最新のブランチに基づいているかのように「ふり」をすることです。
それで、master
をチェックアウトすることなしに、私はそうするでしょう:
git fetch Origin
git rebase -i Origin/master
# ...solve possible conflicts here
もちろん、Originから取得しただけではmaster
のローカル状態は更新されません(マージは実行されません)が、これは私たちの目的には問題ありません。
git checkout master
git pull Origin master
# Merge branch test into master
git merge test
マージ後、ファイルが変更された場合、マージすると「Resolve Conflict」のエラーが発生します。
それで、あなたは最初にすべてのあなたの衝突を解決する必要がありますそしてあなたはすべてのあなたの変更を再びコミットしなければなりませんそしてそれからPush
git Push Origin master
テストブランチで変更を加えた人は、これがより良い方法です。
古いスレッドですが、私は自分のやり方を見つけていません。リベースを操作していて、ブランチからのすべてのコミットをマスターの上にマージしたいという人にとっては、それは価値があるかもしれません。何らかの方法で矛盾がある場合は、コミットごとにそれらを解決できます。
マスターとブランチを最新の状態にします:
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>