変更が上流に存在する場合、なぜgit statusはブランチが最新であることを示すのですか?


226

変更は追跡されたブランチの上流に存在git statusしますが、入力すると、ローカルブランチが最新であることを示します。これは新しい動作ですか、構成設定を変更しましたか、それとも何か問題がありますか?

助けてくれてありがとう。

ubuntu@host:/my/repo# git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean


ubuntu@host:/my/repo# git pull
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 11 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (11/11), done.
From bitbucket.org:my/repo
   1234567..abcdefg  master     -> origin/master
Updating 1234567..abcdefg
Fast-forward
 file1        |  1 -
 file2        | 43 +++++++++++++++++++++++++++++++++++++++++++
 file3        | 21 ++++++++++++---------
 file4        | 21 ++++++++++++---------
 4 files changed, 67 insertions(+), 19 deletions(-)
 create mode 100644 file5

回答:


274

ステータスがorigin/master 示すのは、ローカルリポジトリのローカル参照である、呼び出された参照の背後にいることです。この場合、refはと呼ばれるリモートのブランチをたまたま追跡してoriginいますが、ステータスはリモートのブランチについて何も伝えていません。これは、ローカルファイルシステムに保存されている単なるコミットIDであるrefについて通知しています(この場合、通常は.git/refs/remotes/origin/masterローカルリポジトリで呼び出されるファイルにあります)。

git pull2つの操作を行います。最初git fetchに、リモートリポジトリのコミット(origin/masterローカルリポジトリのref を更新する)で最新の状態にするために、次に、git mergeこれらのコミットを現在のブランチにマージするためにを行います。

fetchステップを(それ自体で、またはを介してgit pull)実行するまで、ローカルリポジトリは上流に追加のコミットがあることを知る方法がなくgit status、ローカルorigin/master参照のみを調べます。

場合はgit status、最新の言う、それは「最新の枝と現在のブランチトラックその」、「と呼ばれる地元のREFと最新この場合の手段を意味しますorigin/master」。これは、fetch「前回実行したときに取得されたアップストリームステータスの最新情報」と「アップストリームの最新のライブステータスの最新情報」とは異なるだけです。

なぜこのように機能するのですか?さて、fetchステップは潜在的に遅くて高価なネットワーク操作です。Git(およびその他の分散バージョン管理システム)の設計は、不必要なときにネットワーク操作を回避するためのものであり、多くの人が慣れている典型的なクライアント/サーバーシステムとはまったく異なるモデルです(ただし、以下のコメントで指摘されているように、Gitの概念はここで混乱を引き起こす「リモートトラッキングブランチ」の例は、すべてのDVCSで共有されているわけではありません)。集中型サーバーに接続せずにGitをオフラインで使用することは完全に可能であり、の出力git statusはこれを反映しています。

Gitでのブランチの作成と切り替え(およびそのステータスのチェック)は軽量であることが想定されており、集中型システムに対して低速のネットワーク操作を実行するものではありません。Gitとgit status出力を設計する際の前提は、ユーザーがこれを理解することでした(Gitの機能が多すぎると意味があるのは、Gitのしくみをすでに知っている場合のみです)。DVCSに精通していない多くのユーザーがGitを採用した場合、この仮定は常に有効であるとは限りません。


79
コメントが遅れましたが、同じ状況に遭遇しました。gitがフェッチ前に変更について知る方法がない理由を理解しています。しかし、それは単に「真実ではない」という「最新のもの」であってはなりません。「リモートで何が起こったのかわからない」と言ったほうがいいでしょう。
Droidum

31
多分それは厳密に論理的ですが、それは人間に合理的ではありません。フェッチを行うように設計せず、それが最新かどうかを宣言する理由は何ですか?または、メッセージを変更して実際に何をしたかを伝えます。たとえば、「{timestamp}で最後にチェックしたときに、ブランチは 'origin / master'で最新でした」?あるいは、単に「フェッチを行って、ブランチが最新かどうかを確認してください」と言ってください。
コリン5

25
「あなたのブランチは最新です」というメッセージを表示する必要がないのはなぜですか?オリジン/マスターのステータスを把握する意味がありません。それがオリジンリモートの実際のマスターブランチを表すことになっている場合、それは明らかに何の考えもありません。
whiterook6 16

2
@pastullo、エイリアスを作成します。
Jonathan Wakely 2017

23
これは、Gitの恐ろしいユーザビリティの完璧な例です。私はそのパワーと柔軟性を愛していますが、メッセージを「ブランチはローカルバージョンの 'origin / master'で最新のものです」のようなメッセージに変更するだけです。大きな改善になるでしょう。ここでの混乱は、リモートブランチを追跡するローカルブランチのオリジン/マスター(パターンは、使用しているリモート/ブランチと一致する)です。
matthewcummings516 2017

35

これは、ローカルリポジトリが上流のリモートにチェックインしていないためです。これを期待どおりに機能させるには、を使用しgit fetchgit status再度実行します。


7

これらはすべて実行可能な回答ですが、フェッチまたはプルせずに、ローカルリポジトリがリモートと一致しているかどうかを確認する方法を提供することにしました。私のブランチがどこにあるかを確認するために、私は簡単に使用します:

git remote show origin

それが行うことは、現在追跡されているすべてのブランチを返すことであり、最も重要なことは、それらが最新であるか、リモートオリジンブランチの前か後ろかに関する情報です。上記のコマンドの後、返される例は次のとおりです。

  * remote origin
  Fetch URL: https://github.com/xxxx/xxxx.git
  Push  URL: https://github.com/xxxx/xxxx.git
  HEAD branch: master
  Remote branches:
    master      tracked
    no-payments tracked
  Local branches configured for 'git pull':
    master      merges with remote master
    no-payments merges with remote no-payments
  Local refs configured for 'git push':
    master      pushes to master      (local out of date)
    no-payments pushes to no-payments (local out of date)

これが誰かを助けることを願っています。


0

「origin / master」は、ブランチ「origin / master」のHEADコミットへの参照ポインティングを指します。参照は、Gitオブジェクト(通常はコミットオブジェクト)への人にわかりやすいエイリアス名です。「origin / master」参照はgit push、リモートにアクセスしたときにのみ更新されます(http://git-scm.com/book/en/v2/Git-Internals-Git-References#Remotes)。

プロジェクトのルート内から、次を実行します。

cat .git/refs/remotes/origin/master

表示されたコミットIDを以下と比較します。

cat .git/refs/heads/master

それらは同じである必要があります。そのため、Gitはでmaster最新の状態origin/masterです。

あなたが走るとき

git fetch origin master

これにより、新しいGitオブジェクトがローカルで.git / objectsフォルダーの下に取得されます。そして、Gitは.git / FETCH_HEADを更新して、フェッチされたブランチの最新のコミットを指すようにします。

したがって、現在のローカルブランチと上流からフェッチされたブランチの違いを確認するには、次のコマンドを実行します。

git diff HEAD FETCH_HEAD

1
.gitディレクトリの項目を猫化しないでください。パックされた参照では機能しません。また、あなたが説明したフェッチ動作は、古いバージョンのgitに対するものです。
Andrew C

origin/master参照だけでなく、フェッチによっても更新されませんか?
Jonathan Wakely、2015年

正しい。これまではGit 1.8.3を使用していました。確かにバージョン2.2.1では、フェッチ中にFETCH_HEADも更新されます。また、「あなたのブランチは...で最新です」または「あなたのブランチは... Xコミットにより遅れています」というメッセージに関しては、ローカルブランチが特定のリモートブランチを追跡している場合にのみ表示されます。マスターがorigin / masterを追跡するには、ブランチマスターからgit branch -u origin / masterを実行する必要があります。追跡がない場合でも、git diffを実行する必要があります。
Marek Stanley、

それでは、「 "origin / master"参照はgitをリモートにgit pushしたときにのみ更新される」
Jonathan Wakely

0

サンプルgitリポジトリを調べて、your branch (master)up to dateであるかどうかを確認してくださいorigin/master

ローカルマスターが起点/マスターを追跡していることを確認します。

$ git branch -vv
* master a357df1eb [origin/master] This is a commit message

ローカルマスターブランチの詳細:

$ git show --summary
commit a357df1eb941beb5cac3601153f063dae7faf5a8 (HEAD -> master, tag: 2.8.0, origin/master, origin/HEAD)
Author: ...
Date:   Tue Dec 11 14:25:52 2018 +0100

    Another commit message

オリジン/マスターが同じコミットにあるかどうかを確認します。

$ cat .git/packed-refs | grep origin/master
a357df1eb941beb5cac3601153f063dae7faf5a8 refs/remotes/origin/master

周りの同じハッシュを確認でき、少なくとも現在のgitリポジトリでは、ブランチがリモートハッシュと一致していると言っても安全です。



0

私をここに連れてきた場合など、いくつかのケースでは簡単な答えでも正確です。私は新しいリポジトリで作業していましたが、ステータスによって新しいと見なされなかったファイルを追加しました。

最終的に、ファイルは.gitignoreファイルのパターンと一致しました。


0

この場合、git addを使用して保留中のすべてのファイルを統合し、次にgit commitを使用してからgit pushを使用します

git add-すべてのpedentファイルを統合します

git commit-コミットを保存します

git push-リポジトリに保存します

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