2014-12-18 20 views
5

Quindi diciamo che sto lavorando su license.txt nel mio repository locale e lo modifico. Prima di eseguire il commit, Susan lo modifica e lo invia al repository remoto.Dove si posiziona 'git fetch'?

Se faccio git fetch, cosa succede esattamente ai miei aggiornamenti? Dove vanno i risultati?

+0

Immagino di fermarsi con il messaggio "Sono state apportate modifiche senza commit nella directory di lavoro" – sjagr

+0

Dove immaginate che i vostri precedenti commit vadano quando si effettua un nuovo commit? Quello è lo stesso posto in cui saranno fatti questi impazziti. – DCoder

+0

Il/i commit/i di Susan verrà aggiunto al corrispondente * ramo di remote-tracking * (ad esempio 'origine/master') nel repository locale. – Jubobs

risposta

4

Non succede nulla ai tuoi aggiornamenti. git fetch, per mancanza di una parola migliore, recupera commit da un repository remoto e li inserisce nella copia locale del database dell'oggetto. Dal momento che stai lavorando sulla tua filiale, non c'è interazione tra di loro, fino a quando non scegli esplicitamente di interagire, ad esempio, rebasing, cherry-picking, ecc.

Puoi accedere ai commit recuperati verificando i rispettivi rami (ad esempio, origin/master).

+0

* L'albero locale * è un po 'fuorviante, qui; può essere facilmente interpretato erroneamente come * albero di lavoro *. – Jubobs

+2

@Jubobs Vedo che potrebbe essere un po 'confusionario. Puoi suggerire una formulazione migliore? – Mureinik

+0

Si dovrebbe scrivere che i commit sono memorizzati nel database degli oggetti del repository, sul relativo ramo di remote-tracking (ad esempio 'origin/master') – Jubobs

2

git fetch non modifica lo stato dell'albero di lavoro. Infatti, non richiede un albero di lavoro: git fetch può funzionare in un repository nudo (un repository che non ha una struttura di lavoro).

Il commit di Susan produce un nuovo oggetto nel suo repository. Questo oggetto non è noto nel tuo spazio di lavoro, finché non esegui il recupero. A quel punto, quell'oggetto diventa disponibile nel tuo spazio. Poiché quell'oggetto è identificato dal suo hash, che è un numero intero molto grande, è quasi certamente distinto da (non si scontra con) qualsiasi altro oggetto che hai già.

Oltre a prelevare il nuovo commit, git fetch aggiornerà anche i puntatori del ramo remoto. Ad esempio, supponiamo che il ramo master di Susan e il tuo siano identici prima del commit di Susan. Dopo il commit di Susan, il suo ramo ha un nuovo commit che il tuo no. Quando si esegue il git fetch, il puntatore di diramazione locale origin/master viene aggiornato per indicare che il suo capo è ora il commit di Susan. Tuttavia, il tuo ramo locale master rimane invariato.

A questo punto è possibile eseguire git checkout (senza argomenti) e verrà visualizzato un messaggio come branch master is behind origin/master by 1 commit and can be fast-forwarded. Questo viene dal confronto master e origin/master.

È ora possibile integrare con il cambiamento di Susan in diversi modi:

  • git rebase: scegliere ciliegia dei cambiamenti che sono solo nel vostro locale master in cima ai nuovi cambiamenti nella origin/master (riscrittura in tal modo la loro storia), e rendere il risultato il nuovo HEAD sul locale master). Dopo questo, master è rigorosamente avanti a origin/master: è lo stesso di origin/master, oltre alle tue modifiche.
  • git merge: mantenere intatte le modifiche e generare un nuovo commit su master che le comprime e le unisce. Questo commit ha due genitori: il commit precedente su master (in questo caso il commit di Susan) e l'ultimo commit nella serie di commit locali, nella loro forma originale. Ancora una volta, master è ora rigorosamente avanti a origin/master.
  • git reset --hard origin/master: in riconoscimento dell'impegno di Susan che rende obsoleto tutto il tuo lavoro, butti via il tuo lavoro e inoltra semplicemente il tuo locale master al cambio di Susan. Ora master è identico a origin/master.

Le prime due azioni sono combinate con git fetch utilizzando il comando git pull. git pull esegue git fetch seguito da git merge o esegue git fetch eseguito da git rebase. Il comportamento è configurabile per ramo e vi è un'opzione globale su quale modo devono essere configurati i rami appena creati. È possibile ignorare il comportamento utilizzando git pull --rebase o git pull --merge.

Poiché la modifica locale non viene eseguita, non sarà possibile eseguire queste azioni di integrazione (ridistribuzione o unione). Git vuole che tu converta prima le tue modifiche in un commit. Non vi è alcuna interazione tra gli oggetti appena recuperati e si esegue un commit delle modifiche locali.

Non è necessario eseguire alcuna azione ora. Grazie a git fetch, sei informato sulle attività a monte, senza doverti integrare immediatamente. Puoi, ad esempio, fare git log origin/master per vedere cosa è nuovo e come potrebbe avere un impatto sul tuo lavoro. Ma puoi metterlo da parte e continuare a fare nuovi commit.

Problemi correlati