私は理解できないgit pull
について奇妙なことを観察しました。
金曜日、私は地元の支部で働きました。 mybranch
と呼びましょう。オフィスを出る前に、Origin(私のgithubリポジトリ)にプッシュしました:git Push Origin mybranch
。
昨日、自宅でラップトップにpull
edし、さらにコーディングを行ってから、変更をgithub(Origin)に戻しました。
今、私は仕事を再開し、昨日から私のマシンに変更を加えようとしました(週末には職場のローカルリポジトリに何も変更しませんでした)。
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コミット先になりますか?そのため、git diff Origin/mybranch
を実行しましたが、差分はちょうどリモートから取得した6つの変更でした。
git fetch Origin
を実行することでのみこれを「修正」できました。
From [email protected]:me/project
af8be00..88b0738 mybranch -> Origin/mybranch
どうやら、私のローカルリポジトリにはいくつかの参照オブジェクトがありませんでしたが、どうすればそれができますか?つまり、プルは既にフェッチを行っており、そのブランチ以外には何もしていなかったので、git fetch Origin
とgit fetch Origin mybranch
は同じ結果になるはずです。
git pull Origin
ではなくgit pull Origin branchname
を常に使用する必要がありますか?
よくわかりません。
git pull
は、明示的にフェッチされたヘッド(または、リモートブランチがマージ用に構成されていない場合)を現在のブランチにマージする前に、適切なパラメーターでgit fetch
を呼び出します。
構文:git fetch <repository> <ref>
ここで、<ref>
はコロンなしのブランチ名であり、指定されたリモートの追跡されたすべてのブランチの標準フェッチを行わず、代わりに単にフェッチする「ワンショット」フェッチです。 FETCH_HEAD
への名前付きブランチ。
pdate: 1.8.4以降のGitバージョンの場合、フェッチを要求したrefを追跡するリモート追跡ブランチがある場合、追跡ブランチはfetch
によって更新されるようになりました。この変更は、以前の動作が引き起こした混乱を避けるために特に行われました。
git pull <repository> <ref>
を実行すると、上記のようにFETCH_HEAD
が更新され、チェックアウトHEAD
にマージされますが、リモートリポジトリの標準追跡ブランチは更新されません(Git <1.8。 4)。これは、ローカルブランチがリモートブランチの前にいるように見えることを意味しますが、実際には最新の状態です。
個人的には、git fetch
に続いてgit merge <remote>/<branch>
を実行します。これは、マージする前に強制更新に関する警告が表示され、マージする内容をプレビューできるためです。git pull
aを使用した場合私がやるよりも、ほとんどの場合、パラメーターなしでgit pull
とbranch.<branch>.remote
に依存して、「正しいことをする」という単純なbranch.<branch>.merge
を実行します。
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マスター(git pull Originマスターに含まれる)は、単にFETCH_HEAD
( Charles Bailey は 彼の答え で説明していますが、alsoも更新しますローカルGitリポジトリ内の「リモートマスターブランチ」。
その場合、ローカルマスターはリモートマスターの「先」にあるようには見えません。
Git1.6.5でこれをテストできます:
最初にワークレポを作成します:
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
作業中のリポジトリにmodifを追加し、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
その後、最初の実験のためにワークレポのクローンを作成します
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ステータスは 'Origin
'の前にマスターゲーイングを示しています:
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)
しかし、それはOrigin
がgithubではないだけです:
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)
しかし、Originからgithub(またはOriginがまったくなく、リモートの '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
を指すgithub
しかなかった場合、status
はgit1.6.5ではクリーンになります。
以前のgitについては「先」の警告があるかもしれませんが、とにかくgit config branch.master.remote yourGitHubRepo.git
明示的に定義されていれば、初期バージョンのGitであっても、それを処理できるはずです。
git remote add NAME URL
を使用して、すべてのリモート(元のクローンに付属するOrigin
を除く)を慎重に追加しますか? git configに追加されたばかりのときにこのバグを見ました。