'git pull origin mybranch'は、ローカルのmybranch Nコミットをoriginより先に残します。どうして?


92

私はちょうど奇妙について何かを観察しgit pull、私は理解していないいます、。

金曜日、私は地元の支店で働きました。それを呼びましょうmybranch。オフィスを離れる前に、それを元の場所(私のgithubリポジトリ)にプッシュしましたgit push origin mybranch

昨日自宅で、私のpullブランチをラップトップに移動し、さらにコーディングを行ってから、変更をgithub(元)にプッシュしました。

今、私は再び仕事をしていて、昨日の変更を自分の作業マシンにプルしようとしました(週末に私の職場のローカルリポジトリで何も変更しませんでした)。

git pull origin mybranch

これは早送りマージを引き起こしましたが、問題ありません。それから私はをしましたgit status、そしてそれは言った:

# On branch mybranch
# Your branch is ahead of 'origin/mybranch' by 6 commits.
#
nothing to commit (working directory clean)

えっ?週末に触れずに、元の場所から引っ張っただけで、6コミット先になるのはなぜですか?したがって、私はaを実行しgit diff origin/mybranch、差分はちょうどリモートからプルした6つの変更でした。

私はこれを実行することによってのみこれを「修正」することができましたgit fetch origin

From git@github.com:me/project
af8be00..88b0738  mybranch -> origin/mybranch

どうやら、私のローカルリポジトリにはいくつかの参照オブジェクトがありませんでしたが、それはどうしてですか?つまり、プルはすでにフェッチを行っており、そのブランチ以外には何もしていなかったので、git fetch origingit fetch origin mybranchは同じ結果になるはずですか?

git pull origin代わりに常に使用する必要がありgit pull origin branchnameますか?

よくわかりません。


私もこれに気づきました。a git pushもそれを解決するようです(「すべて最新」のレポート)。
ベン・ジェームス

4
git config --get-regexp br.*あなたの設定にローカルブランチがあるかどうかを知ることができます
VonC

3
git config branch.master.remote yourGitHubRepo.gitworkRepo を入力してgit pull origin、ステータスが「ahead」警告のままであるかどうかを(次で)チェックできますか?
VonC、2009年

設定されていません(空の出力)。しかしgit remote show origin、オリジンが私のGitHubリポジトリを指していることを示しているので、それで大丈夫でしょうか?
Matthias、

1
git remoteだけ(GitHubリポジトリの正しいアドレスを表示)では不十分です。Your branch is ahead後に「」警告メッセージが表示されないようにするにはgit pull、まずブランチのリモート名 定義する必要があります。したがって、私の提案:を入力してgit config branch.master.remote yourGitHubRepo.gitから、a git pullとa git statusを試して、問題が解決するかどうかを確認します。
VonC、2009年

回答:


115

git pullgit fetch明示的にフェッチされたヘッドをマージする前に(または、マージ用に構成されたリモートブランチがない場合)、現在のブランチに適切なパラメーターを指定して呼び出します。

構文:git fetch <repository> <ref>where <ref>は、コロンのない単なるブランチ名です。指定されたリモートの追跡されたすべてのブランチの標準のフェッチを行わず、代わりに名前付きブランチだけをフェッチする「ワンショット」フェッチです。FETCH_HEAD

更新: 1.8.4以降のGitバージョンの場合、フェッチするように要求した参照を追跡するリモート追跡ブランチがある場合、追跡ブランチはによって更新されfetchます。この変更は、以前の動作が引き起こした混乱を避けるために特別に行われました。

を実行するとgit pull <repository> <ref>FETCH_HEAD上記のように更新され、チェックアウトにマージされますHEADが、リモートリポジトリの標準追跡ブランチは更新されません(Git <1.8.4)。つまり、ローカルでではリモートブランチよりも先に見えますが、実際には最新の状態です。

個人的には、マージする前に強制更新に関する警告が表示され、マージする内容をプレビューできるので、常にgit fetchフォローしgit merge <remote>/<branch>ます。私が使用git pullするよりも少し多く使用した場合、git pullほとんどのパラメーターなしでプレーンを実行します。当時は、「正しいことbranch.<branch>.remotebranch.<branch>.mergeする」ことを頼りにしています。


4
+1それは本当に良い説明です!説明が 'git help fetch'のどこかに隠れていることは知っていましたが、それを取得できませんでした...
StefanNäweNov

1
+1。良い投稿、gitster.livejournal.com
28309.htmlに

1
では、フェッチによって標準のトラッキングブランチが更新されるため、問題git fetchgit pull <repository> <ref>修正されますか?また、この回答に感謝し、理にかなっている:)
Bart Jedrocha

1
私もこの問題に遭遇したので、git fetchその後にを実行する必要がありますgit merge origin/master master
user1027169 2013年

3

git remote -v showそれが起源になると何が戻りますか?

originがgithubを指している場合、ステータスは最新であり、リモートリポジトリの前ではありません。少なくとも、Git1.6.5では、簡単なテストに使用しています。

とにかく、これを回避するには、masterブランチのリモートリポジトリを明示的に定義します。

$ git config branch.master.remote yourGitHubRepo.git

次に、その後にgit pull origin masterが続くとgit status、クリーンステータスが返されます(先読みなし)。
どうして?get fetch origin master(git pull origin masterに含まれる)はFETCH_HEADCharles Bailey彼の回答で説明しているように)更新するだけでなく、ローカルのGitリポジトリ内の「remote masterブランチ」更新するためです。
その場合、ローカルマスターはリモートマスターよりも「先に」いるようには見えません。


これをgit1.6.5でテストできます。

まず、workrepoを作成します。

PS D:\git\tests> cd pullahead
PS D:\git\tests\pullahead> git init workrepo
Initialized empty Git repository in D:/git/tests/pullahead/workrepo/.git/
PS D:\git\tests\pullahead> cd workrepo
PS D:\git\tests\pullahead\workrepo> echo firstContent > afile.txt
PS D:\git\tests\pullahead\workrepo> git add -A 
PS D:\git\tests\pullahead\workrepo> git commit -m "first commit"

ベアリポジトリ(どこからでもプッシュを受信できるリポジトリ)を作成して、GitHubリポジトリをシミュレートします

PS D:\git\tests\pullahead\workrepo> cd ..
PS D:\git\tests\pullahead> git clone --bare workrepo github

私は作業リポジトリにモディフを追加し、それをgithubリポジトリにプッシュします(リモートとして追加されます)

PS D:\git\tests\pullahead> cd workrepo
PS D:\git\tests\pullahead\workrepo> echo aModif >> afile.txt
PS D:\git\tests\pullahead\workrepo> git ci -a -m "a modif to send to github"
PS D:\git\tests\pullahead\workrepo> git remote add github d:/git/tests/pullahead/github
PS D:\git\tests\pullahead\workrepo> git push github

私は、GitHubにプッシュされたGitHubのクローンを作成したホームリポジトリを作成します。

PS D:\git\tests\pullahead\workrepo> cd ..
PS D:\git\tests\pullahead> git clone github homerepo
PS D:\git\tests\pullahead> cd homerepo
PS D:\git\tests\pullahead\homerepo> type afile.txt
firstContent
aModif

PS D:\git\tests\pullahead\homerepo> echo aHomeModif1  >> afile.txt
PS D:\git\tests\pullahead\homerepo> git ci -a -m "a first home modif"
PS D:\git\tests\pullahead\homerepo> echo aHomeModif2  >> afile.txt
PS D:\git\tests\pullahead\homerepo> git ci -a -m "a second home modif"
PS D:\git\tests\pullahead\homerepo> git push github

その後、最初の実験のためにworkrepoをクローンします

PS D:\git\tests\pullahead\workrepo4> cd ..
PS D:\git\tests\pullahead> git clone workrepo workrepo2
Initialized empty Git repository in D:/git/tests/pullahead/workrepo2/.git/
PS D:\git\tests\pullahead> cd workrepo2
PS D:\git\tests\pullahead\workrepo2> git remote add github d:/git/tests/pullahead/github
PS D:\git\tests\pullahead\workrepo2> git pull github master
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From d:/git/tests/pullahead/github
 * branch            master     -> FETCH_HEAD
Updating c2763f2..75ad279
Fast forward
 afile.txt |  Bin 46 -> 98 bytes
 1 files changed, 0 insertions(+), 0 deletions(-)

そのリポジトリでは、git statusは ' origin'の前のマスターgeingについて言及しています:

PS D:\git\tests\pullahead\workrepo5> git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
nothing to commit (working directory clean)

しかしそれはorigingithub ではありません:

PS D:\git\tests\pullahead\workrepo2> git remote -v show
github  d:/git/tests/pullahead/github (fetch)
github  d:/git/tests/pullahead/github (push)
origin  D:/git/tests/pullahead/workrepo (fetch)
origin  D:/git/tests/pullahead/workrepo (push)

しかし、githubへの起点を持つ(または起点がまったくない、リモートの「github」だけが定義されている)リポジトリでシーケンスを繰り返す場合、ステータスはクリーンです。

PS D:\git\tests\pullahead\workrepo2> cd ..
PS D:\git\tests\pullahead> git clone workrepo workrepo4
PS D:\git\tests\pullahead> cd workrepo4
PS D:\git\tests\pullahead\workrepo4> git remote rm origin
PS D:\git\tests\pullahead\workrepo4> git remote add github d:/git/tests/pullahead/github
PS D:\git\tests\pullahead\workrepo4> git pull github master
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From d:/git/tests/pullahead/github
 * branch            master     -> FETCH_HEAD
Updating c2763f2..75ad279
Fast forward
 afile.txt |  Bin 46 -> 98 bytes
 1 files changed, 0 insertions(+), 0 deletions(-)
PS D:\git\tests\pullahead\workrepo4> git status
# On branch master
nothing to commit (working directory clean)

私はしていた場合originに向いてgithubstatusgit1.6.5のためのクリーンだろう。
それは以前のgitの「先の」警告があるかもしれませんが、とにかく、git config branch.master.remote yourGitHubRepo.git明示的に定義されたものは、Gitの初期バージョンでもそれを処理できるはずです。


お時間を割いていただきありがとうございます。オリジンのリモートはすでに私のGitHubリポジトリをポイントしています。GitHubのURLからそのプロジェクトのクローンを作成し、私のローカルマスターブランチがorigin / masterを追跡しています。mybranchについては、origin / mybranchブランチから作成したので、自動的に追跡されるはずです。しかし、それでもおそらくこれが問題ですか?ローカルのmybranchが実際にorigin / mybranchを追跡しないことは?PS:(MacPorts経由で)git 1.6.1を使用しています。
Matthias、

ローカルブランチが別のブランチを追跡しているかどうかを確認できるgitコマンドはありますか?私はそれをマニュアルページで見つけることができません。
Matthias、

どのリモートブランチがで追跡されているかを確認できますgit remote show origin
Ted Percival、2011

2

を使用して、すべてのリモート(origin元のクローンに付属しているものを除く)を追加するように注意していますgit remote add NAME URLか?git configに追加されたばかりのときにこのバグを見ました。


私はレポをクローンするときにこれを行いました。しかし、私は各ブランチでこれをしませんでした。たとえばmybranchの場合、最初にoriginからフェッチし、次にgit checkout -b mybranch origin/mybranch。git-branchのmanページによると、origin / mybranchは開始点であり、さらに--track: "... 「git pull <repository> <refspec>」を明示的に使用しない場合。この動作は、開始点がリモートブランチの場合のデフォルトです。
Matthias
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.