2015-04-05 11 views
6

Quindi, ho affrontato questo problema abbastanza spesso, e ho provato a cercare qualsiasi soluzione online, ma non sono sicuro se questo è il comportamento previsto di Git o no .'git pull' fa commettere gli altri nella mia area di staging durante il conflitto di fusione

Ogni volta che ho alcuni commit locali e faccio un git pull, git porta tutti i commit delle altre persone nella mia area di staging in caso, ho un conflitto di fusione. Ora, anche se il conflitto è su un singolo file, non capisco perché git porta i commit non conflittuali di altre persone nella mia area di staging, chiedendomi di impegnarli come se fossero cambiamenti/commit fatti da me.

Recentemente, ho avuto lo stesso comportamento sul portatile di un collega, e non abbiamo disattivato tutti i file non aggiunti dal collega prima di eseguire il commit, quindi ho eseguito il commit dell'unico file che era in conflitto. E quello che è successo, è stato abbastanza inaspettato. Apparentemente Git ha cancellato tutti quei file, ha annullato tutte le modifiche, come se il nostro commit le avesse invertite.

Tuttavia, la cosa più strana di tutte è stata, abbiamo guardato in Stash (usiamo Stash per gestire il repository centrale), e non ho visto questi file annullati dal nostro commit in Stash.

Sono in perdita perché è successo. Qualche spiegazione plausibile? Inoltre, ho visto Stash recitare in modo strano a volte. Sembra inaffidabile. Non mostrerà alcun cambiamento tra due commit, eppure ci sono a volte, cambiamenti. Non ho idea di come ciò accada, ma qualcun altro ha riscontrato questi problemi?

Aggiornamento: in seguito ho capito che Stash non era strano solo un po 'non intuitivo. Quando si effettua un'unione, ha mostrato modifiche basate su due genitori diversi. E c'era un piccolo menu a discesa che ti permetteva di cambiare il genitore per vedere le modifiche corrispondenti ad esso. Ho pensato che sarebbe stato utile aggiornarlo qui in modo che le persone non avessero idee fuorvianti.

+1

Una cosa che puoi fare funziona in modo diverso a seconda che tu abbia completato l'unione con cui ti presenta. Prima di completarlo, prova 'git diff HEAD ... HEAD @ {u}' (nota i tre punti, vedi i documenti 'git diff' per quello) per vedere quali modifiche vengono unite; dopo averlo completato, per vedere cosa è stato fatto, quando hai ottenuto l'unione, esegui 'git diff HEAD^... HEAD^2' (i due comandi usano solo diversi modi per specificare i suggerimenti su cui lavorare dato che tu? a partire da diversi commit). – jthill

risposta

7

I file di messa in scena che si stanno visualizzando sono i risultati di tutte le modifiche tra l'ultima volta che si è sincronizzato il ramo locale con il ramo remoto (suppongo che il master non lo menzioni).

Git pull ha "scaricato" le modifiche dall'ultima estrazione, quindi tenta di unire questa copia locale del ramo remoto nel ramo locale. Quindi ha colpito un conflitto in uno dei file modificati.

Quindi deve fermarsi nel mezzo dell'unione per chiedervi come risolvere il conflitto in un file.

Quindi gli altri file sono pronti per unire, sono stati messi in scena e sarebbero stati uniti automaticamente se non ci fossero stati altri conflitti.

Per completare l'unione automatica, è necessario a) risolvere il conflitto, quindi b) premere commit per completare la fusione delle modifiche degli altri utenti nella filiale locale. (Alcune GUI automatizzano il completamento del commit dopo aver cliccato su un pulsante "Ho finito di risolvere")

Noterai anche nella finestra di commit della tua GUI, c'è un messaggio di fusione prefabbricato per il commit in sospeso? Dirà qualcosa come "unione origine/x in x ... Conflitti: y". Una volta che tutti i file modificati possono essere aggiunti allo stage, sei pronto per completare questo commit automatico che è stato messo in pausa.

Quindi questo mi sembra un comportamento atteso, ma stai solo vedendo "dentro" uno dei processi interni di git.

Lo stivaggio non dovrebbe essere necessario o coinvolto qui. Sebbene alcune GUI facciano auto-stash, git stesso non usa la stashing durante un pull.

Nota: non è necessario avere alcun file modificato localmente quando si esegue un pull. (Ad esempio, commettere tutto pulito prima di eseguire qualsiasi operazione di ramo, è una buona pratica) Avere una GUI ripulire i file modificati è quando l'auto-stash è utile, ma ha ancora le sue complicazioni in caso di conflitti. Ad esempio, è necessario risolvere i conflitti, quindi ricordarsi di inserire lo stash in seguito. Se ti affidi troppo all'automazione, diventa confuso quando devi completare il processo automatizzato che non conosci! Quindi ti consiglio di tenere sempre pulita la tua directory di lavoro.

+0

Grazie per la spiegazione. Quindi sembra che questo sia un comportamento previsto. Quindi, si suppone che si debbano commettere i file di messa in scena di quelle altre persone. Mi chiedo sempre come influisce sulla cronologia di quel file? Non mostrerà mai commits/person extra dove nulla è cambiato? Inoltre, lo Stash di cui sto parlando, non è git stash, è la GUI di Atlassian Stash per l'accesso al repository centrale remoto. – Setafire

+0

Sì, è necessario impegnare i file temporanei per completare l'unione. Altrimenti i tuoi file non rispecchieranno esattamente il ramo remoto (cioè quello che hanno tutti gli altri). – scipilot

+0

Sì, influenzerà la cronologia del file, ma solo in quel ramo. Quando si arriva a spingere il ramo, si spinge il commit di unione, ma il file sarà lo stesso del remoto, quindi non ci sono ulteriori modifiche effettive. Mostra semplicemente la storia com'era, hai fatto un'unione locale e hai anche avuto un conflitto. Le persone possono vedere dal commit diff che non ci sono state modifiche effettive a quel file fatto da te, ma ci vuole un po 'di pratica per vederlo. – scipilot

1

Il comportamento predefinito di git pull è di eseguire un fetch e quindi un merge. Un'unione è un vero, nuovo, commit; normalmente questo viene risolto automaticamente in modo che non vengano visualizzate modifiche graduali. Tuttavia, nel caso di un conflitto, il commit non può essere eseguito automaticamente, quindi le modifiche di stage visibili.

+0

Sì, so che è un recupero e fusione. Ma quello che non capisco è perché mette in scena anche i file non conflittuali nella mia area di sosta ogni volta? Non cambia la cronologia di quei file se li rincomincio senza nemmeno toccarli? E come è possibile annullare queste modifiche/eliminare i file se li tolgo? – Setafire