違いはありますが、Gitマージは「すでに最新」と報告します


286

マスターとテストの2つのブランチを持つgitリポジトリがあります。

マスターブランチとテストブランチには違いがあります。

両方のブランチですべての変更がコミットされています。

私が行った場合:

gitチェックアウトマスター
git diffテスト

変更を含む画面が表示され、違いが示されます。テストブランチの変更をマージしたいので、

gitマージテスト

しかし、「すでに最新の状態です」というメッセージが表示されます

ただし、各ブランチの下にあるファイルを調べると、明らかに違いがわかります。

ここでの問題は何ですか?どのように解決しますか?


コミットされていない変更されたコードはありますか?
ozma 2017年

回答:


146

「すでに最新」というメッセージは、マージしようとしているブランチからのすべての変更が、現在作業中のブランチにすでにマージされていることを意味します。より具体的には、マージしようとしているブランチが現在のブランチの親であることを意味します。おめでとうございます、これがあなたが行う最も簡単なマージです。:)

を使用gitkしてリポジトリを確認します。「test」ブランチのラベル​​は、「master」ブランチラベルの下にある必要があります。

ブランチはその親に関して最新です。マージによると、最後のマージ以降、親に新しい変更はありません。これは、ブランチが同じであるという意味ではありません。作業中のブランチに多くの変更を加えることができ、そのように聞こえるからです。

2019年10月12日を編集:

この回答に対するコメントのチャールズ・ドレイクによれば、問題を修正するための1つの解決策は次のとおりです。

git checkout master
git reset --hard test

これにより、「テスト」レベルに戻ります。

次に行います:

git push --force origin master

変更を中央リポジトリに強制的に戻すため。


2
聖なる* c!あなたが正しい!別のブランチ(不安定な開発)が誤ってマスターとマージされ、テストブランチが不安定なサブセットであったことが起こったと思います。私がしようとしたマージは、マスターを「テスト」レベルに戻すことでした。
Charles Darke

2
正しい。その操作は意味をなさないので、Gitは何もしません。:)
ボンベ

24
私が今やったのは:git checkout master; git reset --hard test; これにより、「テスト」レベルに戻ります。次に、「git push --force origin master」を実行して、変更を中央リポジトリに強制的に戻しました。
Charles Darke

22
gitに「親とマージしようとしている」と警告するメッセージが表示されていれば、良かったでしょう。
Charles Darke

1
リモート側にすでに存在するブランチの子孫ではないブランチをプッシュすることは悪いことと考えられています:git-pushとgit-pullのmanページの議論を見てください。
ボンベ

131

これは、リモートマスターに変更があることがわかっているときによく発生するので、を使用してそれらをマージしようとしますgit merge master。ただし、これはリモートマスターとはマージされませんが、ローカルマスターとはマージされます。

したがって、マージを行う前に、マスターをチェックアウトしてから、git pullそこに進みます。その後、新しい変更をブランチにマージできます。


7
ブランチの切り替えを回避できる方法はありますか?マージされるブランチにいる間にマージされるブランチをプルしてからマージするようなものですか?
Japheth Ongeri-インカリメバ16年

ああ、いいね。git fetch現在別のブランチを使用している場合でも、masterブランチを更新すると思いました。そうではないことがわかりました。ありがとう!fetch取得するブランチを指定できるオプションがあると確信しています。
ライク、

1
@Raikできますgit fetch --allが、これはブランチをフェッチするだけで、プルはしません。
インゴビュルク、2017年

6
@ JaphethOngeri-inkalimevaあなたはただ行うことができますgit fetch --all && git merge origin/mastermasterリモートの変更をマージするためにローカルを更新する必要はありません。
IngoBürk'11年

@IngoBürk私は2つのブランチを持っていgit merge masterましたgit merge origin/master。また、2つのブランチを更新する前にチェックアウトmastergit pullました。同じコンテンツを共有していても、2つのブランチ間にPRを作成すると、いくつかのdiffファイルが表示されました。git pullターゲットブランチを機能ブランチに修正しました。Already up to date! Merge made by the 'recursive' strategy.これにより、変更が反映されずにマージコミットが行われましたが、予期しないdiffファイルがPRから削除されました。「同等の」ローカルブランチとリモートブランチのマージに違いがあるのはなぜですか?
wrapperapps

45

master次のコミット履歴を持つブランチがあるとします。

A -- B -- C -- D

ここで、ブランチテストを作成して作業し、4つのコミットを実行します。


                 E -- F -- G -- H
                /
A -- B -- C -- D

masterの頭はDを指し、testの頭はHを指します。

マージするブランチのHEADが、マージするブランチの一連のコミットのコミットの親である場合、「すでに最新の」メッセージが表示されます。その場合、ここでは:Dはの親ですE

から何も変わっていないので、testto からにマージするものはありません。ここでやりたいことは、文字どおりGit にHを指すように指示することなので、masterのブランチには次のコミット履歴があります。mastermastermaster

A -- B -- C -- D -- E -- F -- G -- H

これはGitコマンドのジョブですreset。また、作業ディレクトリにこの変更を反映させたいので、ハードリセットを行います。

git reset --hard H

3
過去に、使用するのgit reset --hardはかなり抜本的なことだと言われましたが、コミットが失われることはありますか?これらの変更を行うより安全な方法はありgit reset --hardますか、または誇張された危険性はありますか?
Graham R. Armstrong

1
このコマンドは正気で、心配する必要はありません。この--hardオプションで注意すべきことは、実際に作業ディレクトリを変更するため、コミットされていない変更が失われることだけです。個人的には、git status手動で実行するすべてのgitコマンドの前後に、リポジトリがクリーンであるか、予期した状態にあるかを確認しています。
Marek Stanley

これにより、「ブランチと 'origin / master'が分岐しました」ステータスメッセージが表示されます。どうすれば解決できますか?
Eido95 2017年

1
私はあなたに複数の賛成票を与えることができるといいのですが。ありがとう!
KMC

--hardオプションの必要性はありますか?私はこの状況を数回経験しており、常になしでリセットし--hardます。コミットされていない変更を失うリスクなしで、問題なく動作しました。
カシミール

16

私にとって何がうまくいくか、あなたがbranch1を持っていて、それをbranch2にマージしたいとしましょう。

gitコマンドラインを開き、branch2のルートフォルダーに移動して、次のように入力します。

git checkout branch1
git pull branch1
git checkout branch2
git merge branch1
git push

競合がある場合は、git pushを実行する必要はありませんが、まず競合を解決してからpushします。


6

マージは常に現在のHEADと1つ以上のコミット(通常はブランチヘッドまたはタグ)の間で行わ
れ、インデックスファイルは開始時にHEADコミットのツリー(つまり、最後のコミットの内容)と一致する必要があります。
つまり、git diff --cached HEAD変更を報告してはなりません。

マージされたコミットはすでにに含まれていHEADます。これは「すでに最新」と呼ばれる最も単純なケースです。

これは、テスト中のコミットが既にマスターにマージされていることを意味しますが、他のコミットはマスターで行われるgit diff testため、依然としていくつかの違いがあります。


6

これは、マージするブランチのローカルコピーが古いために発生します。私は自分のブランチを呼び出しMyBranch、それをにマージしたいと思いProjectMasterます。

_>git status
On branch MyBranch-Issue2
Your branch is up-to-date with 'origin/MyBranch-Issue2'.

nothing to commit, working tree clean

_>git merge ProjectMaster
Already up-to-date.

しかし、マージが必要な変更あることは知っています。

ここに、と入力するとgit merge ProjectMaster、gitがこのブランチのローカルコピーを調べます。これが当てはまるかどうかを確認するには、まずGitにブランチが古いかどうかを確認して確認し、変更がある場合は変更をフェッチするように指示しますfetch。次に、マージしたいブランチに飛び、そこで何が起こっているのかを確認します...

_>git fetch origin

_>git checkout ProjectMaster
Switched to branch ProjectMaster
**Your branch is behind 'origin/ProjectMaster' by 85 commits, and can be fast-forwarded.**
  (use "git pull" to update your local branch)

あはは!私のローカルコピーは、85のコミットによって古くなっており、すべてを説明しています!ここで、Pull足りない変更を取り下げてからMyBranch、ジャンプして再度マージを試みます。

_>git pull
Updating 669f825..5b49912
Fast-forward

_>git checkout MyBranch-Issue2
Switched to branch MyBranch-Issue2
Your branch is up-to-date with 'origin/MyBranch-Issue2'.

_>git merge ProjectMaster
Auto-merging Runbooks/File1.ps1
CONFLICT (content): Merge conflict in Runbooks/Runbooks/File1.ps1

Automatic merge failed; fix conflicts and then commit the result.

そして今、私は修正する別の問題があります...


5

不思議なことに、GITはローカルブランチがリモートブランチとは異なるものだと思ったため、これが起こりました。これはブランチグラフに表示されていました。2つの異なるブランチ(remotes / origin / branch_nameとbranch_name)が表示されていました。

解決策は、ローカルリポジトリを削除し、リモートから再クローンすることでした。これにより、GITはremotes / origin / branch_name>とbranch_nameが実際に同じであることを理解し、を発行できgit merge branch_nameます。

rm <my_repo>
git clone <my_repo>
cd <my_repo>
git checkout <branch_name>
git pull
git checkout master
git merge <branch_name>

これは、Acarterとまったく同じ答えではありませんか?
Andrew C

Acarterは実際にはポイントを逃したと思います-リモコンに変更はありませんでした-それはまったく問題ではありませんでした。「git checkout master」、次に「git merge <branch_name>」で早送りマージを強制する必要がありました。ブランチはマスターより先だったので、逆の方法では何もしませんでした。ボンベの答えは良い説明ですが、質問の「どうすれば解決するか」の部分には答えられませんでした。
MrMas 2018

5

git merge origin/master代わりgit merge masterに私のために働いた。したがって、マスターを機能ブランチにマージするには、次を使用できます。

git checkout feature_branch
git merge origin/master

5

最初にマージするブランチをチェックアウトしてからプルしてください(ローカルバージョンがリモートバージョンと一致するように)。

次に、マージを実行するブランチにチェックアウトすると、gitマージが機能するはずです。


1
これは私にとってはそれでした-私はマスターの間にプルをしました。「ブランチ」で新しいコミットを取得したことを知った。「ブランチ」をマスターにマージしようとしました-「すでに最新」。DID gitのチェックアウト「ブランチ」 -だ、私は実行して、「ブランチ」を更新するために必要な手段「あなたのブランチが遅れている...と高速転送することができます。」git pull「ブランチ」にしながら、
sdbbs

3

私に起こり、このページに送られました。同じシナリオがあったかどうかはわかりませんが、私はその「テスト」ブランチを「再マージ」しようとしていました。

そのため、以前はそれをマージしましたが、そのマージ中の特定の変更を意図的に除外しているため、ブランチ間で明らかに相違点があります。以前に除外した特定の変更/ファイルを追加する必要があることに気づいた/忘れたため、再マージしようとしていました。もう一度マージすると、以前に除外したすべての変更が表示されることを期待していました。 、しかし私は間違っていて、代わりに「すでに最新」のメッセージが表示されます。

@Bombeのコメント/回答を読んだら、彼は正しい、そしてgitはそのように動作すると思うので、私が行ったのは、テストブランチでファイルのハードバックアップを作成し、次にマスターブランチをチェックアウトして手動でファイルを貼り付けてコミットすることでしたそれが新しい変更であるかのように。

これが正しい方法であるかどうか、または同じ問題を抱えている他の人を助けることができるかどうかはわかりませんが、それは私の特定のケースに対する解決策を提供しました。


同じ状況です。このシナリオでは、「統合」ブランチを複数の「機能」ブランチに分割して戻したいと考えています。
Yadli 2017

2
手動貼り付けの代わりに、1つのブランチから現在のブランチに直接ファイルをチェックアウトできますgit checkout srcBranch -- path/to/file。ファイルグロブも使用できます。
トッド、

おかげで、私はあなたのチェックアウト方法を使用しました、しかし私checkout srcBranch -- *は私の差分を入れて、それから見ました
portforwardpodcast

2

ブランチAをブランチBにマージすると「すでに最新の状態です」と報告された場合、リバースが常に当てはまるとは限りません。これは、ブランチBがブランチAの子孫である場合にのみ当てはまります。そうでない場合、ブランチBは単にAにない変更を持つことができます。

例:

  1. マスターからブランチAとBを作成します
  2. マスターでいくつかの変更を行い、これらの変更をブランチBにのみマージします(ブランチAの更新や更新の忘れはありません)。
  3. ブランチAに変更を加え、AをBにマージします。

この時点で、AからBにマージすると「すでに最新」と報告されますが、ブランチBにはマスターからの更新があり、ブランチAにはないため、ブランチは異なります。


2

Git Bashを使用してこのシナリオに直面しました。

リポジトリには複数のブランチがあり、各ブランチには異なるコミットサイクルがあり、マージはたまに発生します。Old_BranchはNew_Branchの親として使用されました

Old_Branchは、New_Branchとマージする必要があるいくつかの変更で更新されました

すべてのブランチからすべてのソースを取得するために、ブランチなしで以下のpullコマンドを使用していました。

git pull origin

奇妙なことに、これはすべてのブランチからすべてのコミットをプルするわけではありません。示されているように、ほとんどすべてのブランチとタグを示していると考えていました。

したがって、これを修正するには、Old_Branchが最新の

git checkout Old_Branch

git pull origin Old_Branch

New_Branchをチェックアウトしました

git checkout New_Branch

確かにそれを引っ張った

git pull origin New_Branch

git merge Old_Branch

そして、ビオラはOld_BranchからNew_Branchへの競合を修正するようになりました:)これは予想されていました


0

同じことが私にも起こりました。しかし、シナリオは少し異なり、私はマスターブランチを持っていて、それからrelease_1(言う)を切り分けました。release_1ブランチにいくつかの変更を加え、それをoriginにマージしました。次に、sshを実行し、リモートサーバーでコマンドgit checkout -b release_1を使用してrelease_1を再度チェックアウトします。これにより、実際に新しいブランチrelease_が作成されます。オリジンから既存のブランチrelease_1をチェックアウトするのではなく、マスターから。「-b」スイッチを削除して問題を解決しました


0

私も同じ問題を抱えていました。リモコンに変更を加えたが、まだ「最新の状態」が表示されていた。リポジトリを再クローンすると問題が解決しました。


0

ばかげているが、それは起こるかもしれません。#91-fix-html-markupこのマージを行う場合、ブランチ名の前に課題参照(例:)があるとします。

$ git merge #91-fix-html-markup

インラインコメントを開始する#ため、以降のすべてが無視されるため、意図したとおりに機能しません#

この場合#、ブランチ名を省略して名前を変更するか、一重引用符を使用してブランチ名を囲むことができますgit merge '#91-fix-html-markup'

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