Penso che il tuo problema di base qui sia che stai interpretando male e / o fraintendendo cosa fa git e perché lo fa.
Quando cloni qualche altro repository, git crea una copia di tutto ciò che è "laggiù". Prende anche le "loro" etichette di ramo, come master
, e crea una copia di quell'etichetta il cui "nome completo" nel tuo albero git è (normalmente) remotes/origin/master
(ma nel tuo caso, remotes/upstream/master
). La maggior parte delle volte ometti anche la remotes/
parte, quindi puoi fare riferimento a quella copia originale come upstream/master
.
Se ora apporti e effettui alcune modifiche su alcuni file, sei l'unico con quelle modifiche. Nel frattempo altre persone potrebbero utilizzare il repository originale (da cui hai creato il tuo clone) per creare altri cloni e modificare quei cloni. Sono gli unici con i loro cambiamenti, ovviamente. Alla fine, però, qualcuno potrebbe avere modifiche che rimandano al proprietario originale (tramite "push" o patch o altro).
Il git pull
comando è per lo più solo una scorciatoia per git fetch
seguito da git merge
. Questo è importante perché significa che devi capire cosa fanno effettivamente queste due operazioni.
Il git fetch
comando dice di tornare al punto da cui hai clonato (o altrimenti impostato come luogo da cui recuperare) e trovare "nuove cose che qualcun altro ha aggiunto, modificato o rimosso". Queste modifiche vengono copiate e applicate alla tua copia di ciò che hai ottenuto da esse in precedenza . Essi sono non applicate per il proprio lavoro, solo per loro.
Il git merge
comando è più complicato ed è dove stai andando storto. Quello che fa, semplificato un po ', è confrontare "ciò che hai cambiato nella tua copia" con "le modifiche che hai preso da qualcun altro e che quindi sei stato aggiunto alla tua-copia-del-lavoro-di-qualcun altro". Se le tue modifiche e le loro modifiche non sembrano essere in conflitto, l' merge
operazione le mescola insieme e ti dà un "merge commit" che lega il tuo sviluppo e il loro sviluppo insieme (anche se c'è un caso "facile" molto comune in cui non hai modifiche e si ottiene un "avanzamento veloce").
La situazione si sta incontrando ora è quello in cui sono state apportate modifiche e li-nove volte impegnata, infatti, da qui il "davanti 9" -e hanno fatto alcun cambiamento. Quindi, fetch
diligentemente non recupera nulla, quindi merge
prende la loro mancanza di modifiche e inoltre non fa nulla.
Quello che vuoi è guardare, o forse anche "reimpostare", la "loro" versione del codice.
Se vuoi semplicemente guardarlo, puoi semplicemente controllare quella versione:
git checkout upstream/master
Questo dice a git che vuoi spostare la directory corrente nel ramo il cui nome completo è effettivamente remotes/upstream/master
. Vedrai il loro codice dell'ultima volta che hai eseguito git fetch
e hai ricevuto il loro ultimo codice.
Se vuoi abbandonare tutte le tue modifiche, quello che devi fare è cambiare l'idea di git di quale revisione la tua etichetta,, master
dovrebbe nominare. Attualmente nomina il tuo commit più recente. Se torni su quel ramo:
git checkout master
quindi il git reset
comando ti permetterà di "spostare l'etichetta", per così dire. L'unico problema rimanente (supponendo che tu sia davvero pronto ad abbandonare tutto ciò che indossi) è trovare dove dovrebbe puntare l'etichetta.
git log
ti consentirà di trovare i nomi numerici, quelle cose come, 7cfcb29
che sono nomi permanenti (non cambiano mai) e ci sono un numero ridicolo di altri modi per nominarli, ma in questo caso vuoi solo il nome upstream/master
.
Per spostare l'etichetta, cancellando le tue modifiche (quelle che hai commesso sono effettivamente recuperabili per un po 'di tempo, ma è molto più difficile dopo questo, quindi sii molto sicuro):
git reset --hard upstream/master
Il messaggio --hard
dice a git di cancellare quello che stavi facendo, spostare l'etichetta del ramo corrente e quindi controllare il commit dato.
Non è super comune volerlo davverogit reset --hard
e spazzare via un sacco di lavoro. Un metodo più sicuro (rendendo molto più facile recuperare quel lavoro se decidi che ne è valsa la pena, dopotutto) è rinominare il tuo ramo esistente:
git branch -m master bunchofhacks
e poi crea un nuovo ramo locale chiamato master
"tracce" (non mi piace molto questo termine perché penso che confonda le persone ma questo è il termine git :-)) il master di origine (o upstream):
git branch -t master upstream/master
con cui puoi quindi continuare con:
git checkout master
Quello che fanno gli ultimi tre comandi (ci sono scorciatoie per renderlo solo due comandi) è cambiare il nome incollato sull'etichetta esistente, quindi creare una nuova etichetta, quindi passare ad essa:
prima di fare qualsiasi cosa:
C0 - "remotes/upstream/master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "master"
dopo git branch -m
:
C0 - "remotes/upstream/master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "bunchofhacks"
dopo git branch -t master upstream/master
:
C0 - "remotes/upstream/master", "master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "bunchofhacks"
Ecco C0
l'ultimo commit (un albero dei sorgenti completo) che hai ottenuto la prima volta che hai eseguito il tuo file git clone
. Da C1 a C9 sono i tuoi commit.
Nota che se lo facessi git checkout bunchofhacks
e poi git reset --hard HEAD^^
, questo cambierebbe l'ultima immagine in:
C0 - "remotes/upstream/master", "master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 - "bunchofhacks"
\
\- C8 --- C9
Il motivo è che HEAD^^
nomina la revisione due in alto dall'intestazione del ramo corrente (che sarebbe appena prima del ripristino bunchofhacks
), reset --hard
quindi sposta l'etichetta. I commit C8 e C9 ora sono per lo più invisibili (puoi usare cose come il reflog e git fsck
trovarli ma non è più banale). Le tue etichette possono essere spostate come preferisci. Il fetch
comando si prende cura di quelli che iniziano con remotes/
. È convenzionale abbinare "tuo" con "loro" (quindi se hanno un remotes/origin/mauve
nome mauve
anche tuo ), ma puoi digitare "loro" ogni volta che vuoi nominare / vedere i commit che hai ricevuto "da loro". (Ricorda che "un commit" è un intero albero sorgente. Puoi scegliere un file specifico da un commit, git show
ad esempio con