Warum ist der Zweig git status show aktuell, wenn Änderungen vorgelagert sind?

226

Änderungen sind in einem nachverfolgten Zweig vorgelagert, aber wenn ich tippe git status, zeigt dies an, dass mein lokaler Zweig auf dem neuesten Stand ist. Ist das ein neues Verhalten, habe ich eine Konfigurationseinstellung geändert oder stimmt etwas nicht?

Danke für die Hilfe.

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
GregB
quelle

Antworten:

273

Der Status sagt Ihnen, dass Sie hinter dem angerufenen Schiedsrichter stehen, origin/master der ein lokaler Schiedsrichter in Ihrem lokalen Repo ist . In diesem Fall verfolgt diese Referenz einen Zweig in einer Fernbedienung, die aufgerufen wird origin, aber der Status sagt nichts über den Zweig auf der Fernbedienung aus. Es handelt sich um die Referenz, bei der es sich lediglich um eine Festschreibungs-ID handelt, die in Ihrem lokalen Dateisystem gespeichert ist (in diesem Fall normalerweise in einer Datei, die .git/refs/remotes/origin/masterin Ihrem lokalen Repo aufgerufen wird ).

git pullführt zwei Operationen aus; Zuerst wird eine git fetchAktualisierung der Commits im Remote-Repo durchgeführt (wodurch die origin/masterReferenz in Ihrem lokalen Repo aktualisiert wird ). Anschließend werden diese git mergeCommits in der aktuellen Verzweigung zusammengeführt.

Bis Sie den fetchSchritt (entweder alleine oder über git pull) ausführen, kann Ihr lokales Repo nicht erkennen, dass zusätzliche Commits vorgelagert sind, und betrachtet git statusnur Ihren lokalen origin/masterRef.

Wenn git status"aktuell" angezeigt wird, bedeutet dies "aktuell mit dem Zweig, den der aktuelle Zweig verfolgt", was in diesem Fall "aktuell mit dem aufgerufenen lokalen Verweis origin/master" bedeutet. Dies entspricht nur "aktuell mit dem Upstream-Status, der beim letzten Mal abgerufen wurde fetch", was nicht mit "aktuell mit dem neuesten Live-Status des Upstreams" identisch ist.

Warum funktioniert das so? Nun, der fetchSchritt ist ein potenziell langsamer und teurer Netzwerkbetrieb. Das Design von Git (und anderen verteilten Versionskontrollsystemen ) dient dazu, Netzwerkoperationen zu vermeiden, wenn dies nicht erforderlich ist, und ist ein völlig anderes Modell als das typische Client-Server-System, an das viele Menschen gewöhnt sind (obwohl, wie in den Kommentaren unten ausgeführt, das Konzept von Git eines "Remote Tracking Branch", der hier Verwirrung stiftet, wird nicht von allen DVCSs geteilt). Es ist durchaus möglich, Git offline ohne Verbindung zu einem zentralen Server zu verwenden, und die Ausgabe von git statusspiegelt dies wider.

Das Erstellen und Wechseln von Zweigen (und das Überprüfen ihres Status) in Git soll einfach sein und nicht einen langsamen Netzwerkbetrieb für ein zentrales System ausführen. Die Annahme beim Entwerfen von Git und der git statusAusgabe war, dass Benutzer dies verstehen (zu viele Git-Funktionen sind nur dann sinnvoll, wenn Sie bereits wissen, wie Git funktioniert). Mit der Einführung von Git durch viele, viele Benutzer, die mit DVCS nicht vertraut sind, ist diese Annahme nicht immer gültig.

Jonathan Wakely
quelle
79
Ein später Kommentar, aber ich bin in die gleiche Situation geraten. Ich verstehe, warum Git vor dem Abrufen keine Möglichkeit hat, Änderungen zu erfahren. Aber dann sollte es nicht "aktuell" heißen, was einfach nicht stimmt. Es sollte besser gesagt werden "keine Ahnung, was aus der Ferne passiert sein könnte".
Droidum
31
Vielleicht ist es streng logisch, aber es ist überhaupt nicht menschlich vernünftig. Warum sollten Sie es nicht so gestalten, dass es einen Abruf durchführt, und dann erklären, ob es aktuell ist? Oder ändern Sie die Nachricht, um zu erfahren, was sie wirklich getan hat, z. B. "Ihre Filiale war bei der letzten Überprüfung um {Zeitstempel} mit 'Ursprung / Master' auf dem neuesten Stand"? Oder sagen Sie einfach: "Machen Sie einen Abruf, um herauszufinden, ob Ihre Filiale auf dem neuesten Stand ist"?
Colin
25
Warum sollte die Meldung "Ihre Filiale ist auf dem neuesten Stand" angezeigt werden? Ich sehe keinen Grund darin, den Status von Ursprung / Master zu kennen, und wenn er den tatsächlichen Master-Zweig auf der Ursprungsfernbedienung darstellen soll, dann hat er offensichtlich sowieso keine Ahnung.
whiterook6
2
@pastullo, also erstelle einen Alias.
Jonathan Wakely
23
Dies ist ein perfektes Beispiel für die schreckliche Benutzerfreundlichkeit von Git. Ich mag seine Kraft und Flexibilität, aber ich ändere die Nachricht einfach in "Ihre Filiale ist mit der lokalen Version von 'origin / master' auf dem neuesten Stand". wäre eine enorme Verbesserung. Die Verwirrung hier ist, dass der lokale Zweigursprung / -master (Musterübereinstimmung mit den von Ihnen verwendeten Fernbedienungen / Zweigen), der einen entfernten Zweig verfolgt.
Matthewcummings516
35

Dies liegt daran, dass Ihr lokales Repo nicht bei den Upstream-Fernbedienungen eingecheckt hat. Damit diese Arbeit so funktioniert, wie Sie es erwarten, git fetchführen Sie a git statuserneut aus.

Ryan
quelle
7

Obwohl dies alles brauchbare Antworten sind, habe ich mich entschlossen zu prüfen, ob das lokale Repo mit der Fernbedienung übereinstimmt, ohne sie zu holen oder zu ziehen. Um zu sehen, wo meine Filialen sind, benutze ich einfach:

git remote show origin

Es werden alle aktuell verfolgten Zweige und vor allem die Informationen zurückgegeben, ob sie aktuell sind, vor oder hinter den entfernten Ursprungszweigen. Nach dem obigen Befehl ist dies ein Beispiel für die Rückgabe:

  * 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)

Hoffe das hilft jemandem.

Skycube
quelle
0

"Ursprung / Master" bezieht sich auf die Referenzposition für das HEAD-Commit des Zweigs "Ursprung / Master". Eine Referenz ist ein benutzerfreundlicher Aliasname für ein Git-Objekt, normalerweise ein Commit-Objekt. Die Referenz "Ursprung / Master" wird nur aktualisiert, wenn Sie git pushauf Ihre Fernbedienung zugreifen ( http://git-scm.com/book/en/v2/Git-Internals-Git-References#Remotes ).

Führen Sie im Stammverzeichnis Ihres Projekts Folgendes aus:

cat .git/refs/remotes/origin/master

Vergleichen Sie die angezeigte Commit-ID mit:

cat .git/refs/heads/master

Sie sollten gleich sein, und deshalb sagt Git, dass mastersie auf dem neuesten Stand sind origin/master.

Wenn du rennst

git fetch origin master

Dadurch werden neue Git-Objekte lokal im Ordner .git / properties abgerufen. Und Git aktualisiert .git / FETCH_HEAD so, dass es jetzt auf das neueste Commit des abgerufenen Zweigs verweist.

Um die Unterschiede zwischen Ihrem aktuellen lokalen Zweig und dem vom Upstream abgerufenen Zweig zu sehen, können Sie ihn ausführen

git diff HEAD FETCH_HEAD
Marek Stanley
quelle
1
Sie sollten keine Elemente im .git-Verzeichnis katzen, da dies nicht mit gepackten Refs funktioniert. Das von Ihnen beschriebene Abrufverhalten gilt auch für ältere Versionen von git.
Andrew C
Wird der origin/masterSchiedsrichter nicht auch durch einen Abruf sowie einen Push aktualisiert?
Jonathan Wakely
Richtig. Ich habe bisher Git 1.8.3 verwendet. Ich kann in der Tat feststellen, dass mit Version 2.2.1 FETCH_HEAD auch während eines Abrufs aktualisiert wird. Auch wenn die Meldung "Ihre Filiale ist mit ... auf dem neuesten Stand" oder "Ihre Filiale ist hinter ... durch X-Commits" angezeigt wird, wird sie nur angezeigt, wenn Ihre lokale Filiale eine bestimmte Remote-Filiale verfolgt. Damit der Master den Ursprung / Master verfolgen kann, muss der Git-Zweig -u Ursprung / Master vom Zweig-Master ausgeführt werden. Wenn es kein Tracking gibt, müssen Sie immer noch git diff ausführen.
Marek Stanley
Dann schlage ich vor, dass Sie die Aussage korrigieren, dass die Referenz "Ursprung / Master" nur aktualisiert wird, wenn Sie einen Push auf Ihre Fernbedienung senden
Jonathan Wakely,
0

Schauen Sie sich ein Beispiel für ein Git-Repo an, um zu überprüfen, ob your branch (master)es up to datemit ist origin/master.

Stellen Sie sicher, dass der lokale Master den Ursprung / Master verfolgt:

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

Weitere Informationen zur lokalen Hauptniederlassung:

$ 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

Überprüfen Sie, ob sich Origin / Master auf demselben Commit befindet:

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

Wir können den gleichen Hash sehen und sicher sagen, dass der Zweig mit dem entfernten übereinstimmt, zumindest im aktuellen Git-Repo.

Themenfeld
quelle
0

versuche es git add .vorher mitgit commit

Dejan Baric llevo3
quelle
0

Triviale Antwort, aber in einigen Fällen korrekt, wie die, die mich hierher gebracht hat. Ich habe in einem Repo gearbeitet, das für mich neu war, und ich habe eine Datei hinzugefügt, die vom Status nicht als neu angesehen wurde.

Am Ende stimmte die Datei mit einem Muster in der Gitignore-Datei überein.

krustyengineer
quelle
0

In diesem Fall verwenden Sie git add und integrieren Sie alle ausstehenden Dateien. Verwenden Sie dann git commit und dann git push

git add - Integriere alle Pedent-Dateien

git commit - Speichern Sie das Commit

Git Push - Speichern im Repository

Airton Silveira
quelle