web-dev-qa-db-ja.com

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

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

これは何が起こっているのですか

  1. 私たちの1人(彼を開発者Aと呼びますが、どちらを選んでも構いません)は、GitHubに一連のコミットをプッシュします。
  2. もう1つ(開発者B)は、ローカルコミットをいくつか行います。
  3. Bはgit pull
  4. Bはgit Push
  5. コミット履歴ログを見ると、github.com:foo/barのブランチ 'master'をマージ

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

97
mshafrir

あなたが見ているコミットはまったく問題ありません。 pullは、git fetch その後 git mergeそのため、通常は実行時にマージが行われますgit pull

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

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

つまり、長い話は簡単です。はい、マージコミットはまったく問題ありません。心配する必要はありません。

85
poke

私の理解、図、結論が間違っていたため、この答えは修正されました。


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

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

...->C1

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

...->C1->C2

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

...->C1->C3

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

...->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-BookContributing a a Project を参照してください。 Private Small Teamセクションには、マージコミットが表示されます。

46
Bill Door

できるよ:

git pull --rebase

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

9
gaborous

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

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

私が知る限り、それがgitの仕組みであり、回避方法はありません。

リベースするとgit履歴が吹き飛ばされるので、マージがいつ発生したかを見ることができなくなります。

7
kclair

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

git stash
git pull
git stash pop

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

6
Luke