Ich denke, Ihr grundlegendes Problem hier ist, dass Sie falsch interpretieren und / oder falsch verstehen, was Git macht und warum es es tut.
Wenn Sie ein anderes Repository klonen, erstellt git eine Kopie dessen, was "dort drüben" ist. Es nimmt auch "ihre" Verzweigungsbezeichnungen, wie z. B. master
, und erstellt eine Kopie dieser Bezeichnung, deren "vollständiger Name" in Ihrem Git-Baum (normalerweise) lautet remotes/origin/master
(aber in Ihrem Fall remotes/upstream/master
). Meistens können Sie das remotes/
Teil auch weglassen , sodass Sie auf diese Originalkopie als verweisen können upstream/master
.
Wenn Sie jetzt Änderungen an Dateien vornehmen und festschreiben, sind Sie der einzige mit diesen Änderungen. In der Zwischenzeit können andere Personen das ursprüngliche Repository (aus dem Sie Ihren Klon erstellt haben) verwenden, um andere Klone zu erstellen und diese Klone zu ändern. Sie sind natürlich die einzigen mit ihren Veränderungen. Möglicherweise hat jemand Änderungen, die er an den ursprünglichen Eigentümer zurücksendet (über "Push" oder Patches oder was auch immer).
Der git pull
Befehl ist meistens nur eine Abkürzung für git fetch
gefolgt von git merge
. Dies ist wichtig, da Sie verstehen müssen, was diese beiden Vorgänge tatsächlich tun.
Der git fetch
Befehl besagt, dass Sie dorthin zurückkehren sollen, wo Sie geklont haben (oder sich anderweitig als Abrufort eingerichtet haben) und "neue Inhalte suchen, die von einer anderen Person hinzugefügt, geändert oder entfernt wurden". Diese Änderungen werden kopiert und auf Ihre Kopie dessen angewendet , was Sie zuvor von ihnen erhalten haben . Sie werden nicht auf Ihre eigene Arbeit angewendet, sondern nur auf ihre.
Der git merge
Befehl ist komplizierter und genau dort, wo Sie schief gehen. Was es ein wenig vereinfacht macht, ist, "was Sie in Ihrer Kopie geändert haben" mit "Änderungen zu vergleichen, die Sie von jemand anderem abgerufen und somit zu Ihrer Kopie der Arbeit eines anderen hinzugefügt haben". Wenn Ihre Änderungen und ihre Änderungen nicht in Konflikt zu geraten scheinen, werden sie durch die merge
Operation zusammengeführt und erhalten ein "Merge Commit", das Ihre Entwicklung und ihre Entwicklung miteinander verbindet (obwohl es einen sehr häufigen "einfachen" Fall gibt, in dem Sie keine haben ändert sich und Sie erhalten einen "schnellen Vorlauf").
Die Situation, der Sie jetzt begegnen, ist eine, in der Sie Änderungen vorgenommen und diese festgeschrieben haben - neun Mal, daher die "Voraus 9" - und sie haben keine Änderungen vorgenommen. Also fetch
holt pflichtbewusst nichts ab, merge
nimmt dann ihren Mangel an Veränderungen und tut auch nichts.
Was Sie wollen, ist, sich "ihre" Version des Codes anzusehen oder vielleicht sogar "zurückzusetzen".
Wenn Sie es sich nur ansehen möchten, können Sie sich einfach diese Version ansehen:
git checkout upstream/master
Das sagt git, dass Sie das aktuelle Verzeichnis in den Zweig verschieben möchten, dessen vollständiger Name tatsächlich lautet remotes/upstream/master
. Sie sehen ihren Code ab dem letzten Mal, als Sie ausgeführt haben git fetch
und den neuesten Code erhalten haben.
Wenn Sie alle Ihre eigenen Änderungen aufgeben möchten, müssen Sie die Idee von git ändern, welche Revision Ihr Label master
benennen soll. Derzeit wird Ihr letztes Commit benannt. Wenn Sie zu diesem Zweig zurückkehren:
git checkout master
dann können Sie mit dem git reset
Befehl sozusagen "das Etikett verschieben". Das einzige verbleibende Problem (vorausgesetzt, Sie sind wirklich bereit, alles aufzugeben, was Sie nicht tun) besteht darin, herauszufinden, wohin das Etikett zeigen soll.
git log
Sie können die numerischen Namen finden - solche Dinge wie 7cfcb29
-, die permanente (sich nie ändernde) Namen sind, und es gibt eine lächerliche Anzahl anderer Möglichkeiten, sie zu benennen, aber in diesem Fall möchten Sie nur den Namen upstream/master
.
Um das Etikett zu verschieben, löschen Sie Ihre eigenen Änderungen (alle Änderungen, die Sie vorgenommen haben, können tatsächlich für eine Weile wiederhergestellt werden, aber danach ist es viel schwieriger. Seien Sie also sehr sicher):
git reset --hard upstream/master
Der --hard
git git soll löschen, was Sie getan haben, die aktuelle Verzweigungsbezeichnung verschieben und dann das angegebene Commit überprüfen.
Es ist nicht üblich, wirklichgit reset --hard
eine Menge Arbeit zu wollen und auszulöschen. Eine sicherere Methode (die es viel einfacher macht, diese Arbeit wiederherzustellen, wenn Sie der Meinung sind, dass sich ein Teil davon gelohnt hat) besteht darin, Ihren vorhandenen Zweig umzubenennen:
git branch -m master bunchofhacks
und dann mache einen neuen lokalen Zweig mit dem Namen master
"Tracks" (ich mag diesen Begriff nicht wirklich, da ich denke, dass er die Leute verwirrt, aber das ist der Git-Begriff :-)) der Ursprungs- (oder Upstream-) Master:
git branch -t master upstream/master
womit Sie sich dann beschäftigen können:
git checkout master
Die letzten drei Befehle (es gibt Verknüpfungen, mit denen nur zwei Befehle erstellt werden können) ändern den Namen, der auf dem vorhandenen Etikett eingefügt ist, erstellen dann ein neues Etikett und wechseln zu diesem:
bevor Sie etwas tun:
C0 - "remotes/upstream/master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "master"
nachher git branch -m
:
C0 - "remotes/upstream/master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "bunchofhacks"
nachher git branch -t master upstream/master
:
C0 - "remotes/upstream/master", "master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "bunchofhacks"
Hier C0
ist das letzte Commit (ein vollständiger Quellbaum), das Sie erhalten haben, als Sie das erste Mal Ihr Commit ausgeführt haben git clone
. C1 bis C9 sind Ihre Commits.
Beachten Sie , dass dies das letzte Bild ändern würde , wenn Sie es git checkout bunchofhacks
dann git reset --hard HEAD^^
tun würden:
C0 - "remotes/upstream/master", "master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 - "bunchofhacks"
\
\- C8 --- C9
Der Grund dafür ist, dass HEAD^^
die Revision zwei vom Kopf des aktuellen Zweigs (kurz vor dem Zurücksetzen bunchofhacks
) nach oben benannt und reset --hard
dann die Beschriftung verschoben wird. Die Commits C8 und C9 sind jetzt größtenteils unsichtbar (Sie können Dinge wie das Reflog verwenden und git fsck
sie finden, aber es ist nicht mehr trivial). Ihre Etiketten können Sie bewegen, wie Sie möchten. Der fetch
Befehl kümmert sich um diejenigen, die mit beginnen remotes/
. Es ist üblich, "Ihre" mit "Ihnen" abzugleichen (wenn sie also einen haben remotes/origin/mauve
, würden Sie auch Ihren Namen nennen mauve
), aber Sie können "Ihre" eingeben, wann immer Sie Commits benennen / sehen möchten, die Sie "von ihnen" erhalten haben. (Denken Sie daran, dass "ein Commit" ein ganzer Quellbaum ist. Sie können eine bestimmte Datei aus einem Commit auswählen, git show
z.