Gitプルにより、コミットログに無関係な「マージブランチ」メッセージが表示される


110

私はプロジェクトの別の開発者と協力しており、リモートリポジトリとしてGithubを使用しています。私はMacでgit 1.7.7.3を使用していますが、Windowsはgit 1.7.6を使用しています。

これが起こっていることです

  1. 私たちの1人(彼を開発者Aと呼びましょう。ただし、どちらを使うかは問題ではありません)が一連のコミットをGitHubにプッシュします。
  2. もう1人(開発者B)は、ローカルコミットをいくつか行います。
  3. Bは git pull
  4. Bは git push
  5. コミット履歴ログを見ると、github.com:foo / barのMergeブランチ「master」が表示されます

コミットログには、「マージブランチ」メッセージが散らばっていて、開発者Bが開発者Aが行った変更をコミットしていることもわかります。この問題を防ぐ唯一の方法はgit pull --rebase、手順3でaを実行することでしたが、リベースによってどのような副作用が発生するのかわかりません。これは、マルチ開発者のgitリポジトリで作業するのが初めてなので、これは通常の動作ですか?この問題を解決する方法についての考えはありますか?


2
マージせずにログを表示できますgit log --no-merges
wjandrea 2018年

回答:


88

あなたが見ているコミットは完全に問題ありません。がpull効果的に実行されるgit fetchと、git merge通常、実行時にマージが発生しますgit pull

マージの代わりにリベースを使用する代わりの方法も可能ですが、通常はそれを避けるべきです。リベースを使用すると、線形履歴を保持できますが、最初に発生した分岐に関する情報も削除されます。また、現在のブランチの履歴が書き換えられ、ターゲットブランチ(この場合はリモート)に含まれていないすべてのコミットが再作成されます。再作成されたコミットは異なるコミットであるため、他のユーザーと一緒に開発する場合、特に人々がそれらのコミットの一部をチェックアウトしてから書き直される前に(たとえば、機能ブランチを使用する場合)、多くの混乱を引き起こす可能性があります。経験則として、あなたは決してすべきではありませんすでにプッシュされたコミット書き換えないで。

表示されるコミットは、2つ(またはそれ以上)のブランチを組み合わせるためのものです。複数のブランチをマージしてから他に何もしないコミットを行うのはまったく問題ありません。実際、履歴を見たときにブランチを結合するマージコミットがあると、それは非常に明確になります。リベースと比較して、マージはまたオリジナルを効果的に見ることを可能にします、共存した実際のブランチを含め、開発され履歴。

つまり、簡単に言えば、そうです。マージコミットは完全に問題なく、心配する必要はありません。


2
とても良い答えです。一部のオープンソースプロジェクトの投稿ガイドラインで推奨されているため、私自身もリベーススタイルを試してみましたが、問題が発生しました。チームの新しいメンバーも同じでした。リベースオプションは、チームが1日中一緒に作業するためのものではなく、パッチを提出するだけの主な貢献者と他の貢献者がいるプロジェクトには正しいと思います。それらは、メインリポジトリを正常にフェッチし、プルリクエストを発行する直前に変更をリベースする必要があります。
Meligy

2
@sTodorov新しい変更がない場合、プルのフェッチ部分は何もしませんが、マージはまだ実行されています。したがって、現在のローカルブランチが最新でない場合は、新しい変更がブランチにマージされます。そして、早送りマージを実行できない場合(コミットが分岐している場合)、マージコミットが作成されます。
2012年

28
この答えは、OPが説明したようにリベースを使用することは危険であるように見えますが、そうではありません。手順3でリベースしても、履歴全体が書き換えられるわけではありません。プッシュされていないローカルコミットのみが、新しいHEAD(そのブランチにプッシュされた最新のコミット)の上に再適用されることによって書き換えられます。これにより、不要なマージコミットが防止され、他の副作用がなくなります。
bob esponja 2014

1
@bobesponjaプルされたリモートブランチにないすべてのコミットが書き換えられます。これには、他のブランチから発行されたコミット(機能ブランチなど)を含めることができます。そのため、はい、何をリベースするかを考えずにリベースすることはやや危険です。
2014

1
@bobesponjaはい、機能ブランチを早期に公開している場合(他の人が機能するため、または単にバックアップとして)、他の人が既にフェッチしている可能性があるため、リベースしないでください。そのとき、あなたが言うように、リベースは、私の回答で述べたリベースのガイドラインに反します。ただし、コミットを公開しない場合、必要に応じてリベースは問題なく、線形履歴を気にしないでください。しかし、それはあなたがどのように働くかに依存するので、それが本当に安全でない限り、一般的な答えはそれを避けることです。ところで 回答を修正しましたので、問題が解決した場合は、反対票を削除していただければ幸いです。
2014

48

私の理解、図、結論が正しくなかったため、この回答は修正されました。


git pullgitがマージしているため、マージコミットが発生します。これは、マージの代わりにリベースを使用するようにブランチを設定することで変更できます。プルでマージの代わりにリベースを使用すると、共有リポジトリにより線形の履歴が提供されます。一方、マージコミットはブランチでの並行開発努力を示しています。

たとえば、2人が同じブランチで作業しています。ブランチは次のように始まります:

...->C1

最初の人が作業を完了してブランチにプッシュします。

...->C1->C2

2人目は作業を終えてプッシュしたいが、更新する必要があるためにプッシュできません。2人目のローカルリポジトリは次のようになります。

...->C1->C3

プルがマージに設定されている場合、2人称リポジトリは次のようになります。

...->C1->C3->M1
      \      /
       ->C2->

ここで、M1はマージコミットです。この新しいブランチ履歴はレポにプッシュされます。代わりに、ローカルリポジトリをリベースするようにプルが設定されている場合は、次のようになります。

...->C1->C2->C3

マージコミットはありません。歴史はより直線的になりました。

どちらの選択もブランチの履歴を反映しています。gitでは、希望する履歴を選択できます。

実際、リベースがリモートブランチに問題を引き起こす可能性のある場所があります。これはそれらのケースの1つではありません。リベースを使用することをお勧めします。これは、すでに複雑なブランチ履歴を簡素化するだけでなく、共有リポジトリに関連する履歴のバージョンを表示するためです。

Branch.autosetuprebase = alwaysを設定して、gitがリモートブランチをマスターではなくリベースとして自動的に確立するようにできます。

git config --global branch.autosetuprebase always

この設定により、gitは各リモートブランチの構成設定を自動的に作成します。

branch.<branchname>.rebase=true

これは、すでにセットアップされているリモートブランチに対して自分で設定できます。

git config branch.<branchname>.rebase true

@LaurensHolstに以前の発言を質問し、追求してくれたことに感謝します。私は確かにgitがプルコミットとマージコミットでどのように機能するかについてさらに学習しました。

マージコミットの詳細については、ProGit-Bookのプロジェクトへの貢献を参照してください。専用の小さなチームのセクションのショーは、コミットをマージします。


7
「プルでマージの代わりにリベースを使用すると、共有リポジトリに正しい履歴が提供されます。マージを使用すると、誤った履歴が提供されます。」—このかなり大胆な発言を裏付ける根拠は何ですか?マージの履歴が「誤った履歴」であることは決してありません。物事が起こった順番を正確に描写しています。リベースによって行っているのは、実際に履歴を変更して、より線形なバージョンを作成することです。あなたは美学のために正確さを犠牲にします。たぶんあなたがやりたいことがあるかもしれませんが、決して真実ではありません。
Laurens Holst

2
マージの代わりにリベースを使用しても、美学の正確さは失われません。マージには--no-ffを使用するので、美学は必須ではありません。正確さは欲求です。リベースはその精度を提供します。
Bill Door

2
リベースされた履歴はどのように正確ですか?あなたはこれを明確にしていません、そして私はそれがどうなるかわかりません。
Laurens Holst 2012年

1
履歴は、共有リポジトリでコミットが発生した時刻を反映しています。ある日、共有レポはコミットC2を見ました。2日目に、共有リポジトリはコミットC3を確認します。C3がC2の前に来た場合、時間の反映は正しくありません。C3はC2の前に来ませんでした。リベースは、ローカルリポジトリのコミットを再編成して、共有リポジトリによって表示される履歴を適切に反映することです。
Bill Door

6
あなたの質問により、私はマージコミットに関する私の理解を確認する必要がありました。私の図は間違っています。私は議論を修正しています。私の結論も正しくありません。リベースとマージの履歴も同様に正しいです。あなた自身の選択をすることができます。
Bill Door

11

できるよ:

git pull --rebase

ただし、これにより常に変更内容が共同編集者の上に置かれます。しかし、汚染メッセージは表示されません。


9

これには実際にはもっと簡単な答えがあります。開発者Bに、コミットする前にプルを実行させるだけです。これは、リモートリポジトリのコミットの履歴とマージしようとするローカルコミットからローカルリポジトリに作成した履歴が原因で発生するため、これらのマージコミットを防止します。プルを実行したときに「変更は上書きされます」というメッセージが表示された場合は、両方が同じファイルに触れたことを意味するだけなので、次のようにします。

git stash
git pull
git stash pop

その後、マージの競合があれば解決できます。


最も迷惑で心配なのは、マージの競合です。避けた方がいい
Green

1
@Greenマージの競合が心配な場合は、git pullも例外ではありません。
ゾソ2018

あなたがあなたのstash前に忘れた時を除いてpull。ええと、gitは常にゲームのトップにいる必要があります。
linuxNoob

とにかくgit pull --rebase、ローカルの変更の前にリモートの変更を統合する必要があります。
フォンブランド

7

git pullを実行すると、「マージブランチ」メッセージが挿入されます。これはまさにそれが行うことです。git pullを実行すると、リモートブランチがローカルブランチにマージされます。

git pullを実行して競合がある場合、gitログには、競合を解決したユーザーからの競合ファイルの更新が表示されます。これは、競合を修正した人がファイルを再コミットしたためだと思います。

私の知る限り、これはgitのしくみであり、回避策はありません。

リベースするとgitの履歴が消えるので、マージがいつ発生したかはわかりません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.