Je pense que votre problème de base ici est que vous interprétez mal et/ou comprenez mal ce que fait git et pourquoi il le fait.
Lorsque vous clonez un autre dépôt, git fait une copie de ce qui se trouve "là-bas". Il prend également "leurs" étiquettes de branche, telles que master
et fait une copie de cette étiquette dont le "nom complet" en votre L'arbre git est (normalement) remotes/origin/master
(mais dans votre cas, remotes/upstream/master
). La plupart du temps, vous pouvez omettre l'élément remotes/
également, de sorte que vous pouvez vous référer à cette copie originale en tant que upstream/master
.
Si vous effectuez et livrez maintenant une ou plusieurs modifications à un ou plusieurs fichiers, vous êtes le seul à disposer de ces modifications. Pendant ce temps, d'autres personnes peuvent utiliser le référentiel d'origine (à partir duquel vous avez créé votre clone) pour créer d'autres clones et modifier ces clones. Ils sont les seuls à disposer de leurs modifications, bien sûr. Cependant, quelqu'un peut éventuellement avoir des modifications qu'il renvoie au propriétaire d'origine (via "push" ou des correctifs ou autre).
El git pull
est surtout un raccourci pour git fetch
suivi par git merge
. C'est important car cela signifie que vous devez comprendre ce que font réellement ces deux opérations.
El git fetch
dit de retourner à l'endroit d'où vous avez cloné (ou que vous avez configuré comme lieu de récupération) et de trouver "de nouveaux éléments que quelqu'un d'autre a ajoutés, modifiés ou supprimés". Ces changements sont copiés et appliqués à votre copie de ce que vous avez obtenu d'eux plus tôt . Ils sont no appliqué à votre propre travail, seulement au leur.
El git merge
est plus compliquée et c'est là que vous faites fausse route. Ce qu'elle fait, en simplifiant un peu, c'est comparer "ce que vous avez changé dans votre copie" aux "changements que vous avez récupérés de quelqu'un d'autre et qui ont donc été ajoutés à votre copie du travail de quelqu'un d'autre". Si vos modifications et celles de quelqu'un d'autre ne semblent pas entrer en conflit, la méthode de la merge
L'opération les fusionne et vous donne un "commit de fusion" qui lie votre développement et le leur (bien qu'il existe un cas "facile" très courant dans lequel vous n'avez pas de changements et vous obtenez un "fast forward").
Dans la situation que vous rencontrez actuellement, vous avez apporté des modifications et les avez validées - neuf fois, en fait, d'où le "9 en avant" - et elles ont fait de l'argent. pas de changements. Donc, fetch
ne récupère rien, et ensuite merge
prend leur manque de changement et ne fait rien non plus.
Ce que vous voulez, c'est regarder, ou peut-être même "réinitialiser", "leur" version du code.
Si vous voulez simplement le regarder, vous pouvez simplement consulter cette version :
git checkout upstream/master
Cela indique à git que vous voulez déplacer le répertoire courant vers la branche dont le nom complet est actuellement remotes/upstream/master
. Vous verrez leur code à partir de la dernière fois que vous avez exécuté git fetch
et obtenir leur dernier code.
Si vous voulez abandonner toutes vos propres modifications, ce que vous devez faire, c'est changer l'idée que se fait git de la révision à laquelle votre étiquette, master
devrait être nommé. Actuellement, il nomme le commit le plus récent. Si vous retournez sur cette branche :
git checkout master
alors le git reset
vous permettra de "déplacer l'étiquette", pour ainsi dire. Le seul problème restant (en supposant que vous soyez vraiment prêt à abandonner tout ce que vous avez fait) est de trouver où l'étiquette doit pointer.
git log
vous permettra de trouver les noms numériques - ces choses comme 7cfcb29
-qui sont des noms permanents (qui ne changent jamais), et il y a un nombre ridicule d'autres façons de les nommer, mais dans ce cas vous voulez juste le nom upstream/master
.
Pour déplacer l'étiquette, effacer vos propres modifications (celles que vous avez effectuées sont en fait récupérables pendant un certain temps, mais c'est beaucoup plus difficile après cela, alors soyez prudent. très sûr) :
git reset --hard upstream/master
El --hard
dit à git d'effacer ce que vous étiez en train de faire, de déplacer l'étiquette de la branche courante, puis de vérifier le commit donné.
Ce n'est pas très courant de vraiment veulent git reset --hard
et effacer un tas de travail. Une méthode plus sûre (qui facilite grandement la récupération de ce travail si vous décidez qu'une partie de celui-ci en valait la peine après tout) consiste à renommer votre branche existante :
git branch -m master bunchofhacks
et ensuite créer une nouvelle branche locale nommée master
qui "suit" (je n'aime pas vraiment ce terme car je pense qu'il prête à confusion mais c'est le terme git :-) ) le master d'origine (ou amont) :
git branch -t master upstream/master
avec lequel vous pouvez ensuite vous mettre en route :
git checkout master
Les trois dernières commandes (il existe des raccourcis pour n'en faire que deux) permettent de modifier le nom collé sur l'étiquette existante, puis de créer une nouvelle étiquette et de passer à celle-ci :
avant de faire quoi que ce soit :
C0 - "remotes/upstream/master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "master"
après git branch -m
:
C0 - "remotes/upstream/master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "bunchofhacks"
après git branch -t master upstream/master
:
C0 - "remotes/upstream/master", "master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "bunchofhacks"
Ici C0
est le dernier commit (un arbre source complet) que vous avez obtenu lorsque vous avez fait votre première demande d'accès à la base de données. git clone
. C1 à C9 sont vos commits.
Notez que si vous deviez git checkout bunchofhacks
et ensuite git reset --hard HEAD^^
ce qui changerait la dernière image en :
C0 - "remotes/upstream/master", "master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 - "bunchofhacks"
\
\- C8 --- C9
La raison en est que HEAD^^
nomme la révision deux plus haut à partir de la tête de la branche courante (qui juste avant la réinitialisation serait bunchofhacks
), et reset --hard
puis déplace l'étiquette. Les commits C8 et C9 sont maintenant presque invisibles (vous pouvez utiliser des choses comme les fonctions reflog et git fsck
pour les trouver mais ce n'est plus trivial). Vous pouvez déplacer vos étiquettes comme bon vous semble. Le site fetch
s'occupe de ceux qui commencent par remotes/
. Il est conventionnel de faire correspondre "le vôtre" avec "le leur" (donc s'ils ont un remotes/origin/mauve
vous nommeriez le vôtre mauve
aussi), mais vous pouvez taper "les leurs" quand vous voulez nommer/voir les commits que vous avez obtenus "d'eux". (Rappelez-vous qu'"un commit" est un arbre source entier. Vous pouvez choisir un fichier spécifique d'un commit, avec git show
par exemple, si et quand vous le souhaitez).