git pull mantenendo le modifiche locali


132

Come posso aggiornare (estrarre) un progetto git in modo sicuro, mantenendo intatti i file specifici, anche se ci sono cambiamenti a monte?

miorepo / config / config.php

C'è un modo, anche se questo file è stato modificato sul telecomando, quando tengo pull, tutto il resto viene aggiornato, ma questo file è invariato (nemmeno unito)?

PS. Devo fare quello che sto chiedendo perché sto solo scrivendo script di distribuzione basati su git. Non riesco a modificare i file di configurazione in modelli.

quindi, ho bisogno di un modo per scrivere script di aggiornamento che non perda ciò che è stato modificato localmente. Speravo in qualcosa di semplice come:

git assume-remote-unchanged file1
git assume-remote-unchanged file2

poi git pull


Le modifiche sono config.phpimpegnate?
Mark Longair,


Non è impegnata. Preferirei non doverlo fare
Johnny Everson

@JhonnyEverson: è la stessa classe generale di problemi (hai un file di configurazione e non vuoi impegnare impostazioni specifiche, ma la struttura del file di configurazione deve essere tracciata.)
Daenyth

Risposte:


248

Esiste una soluzione semplice basata sullo stash Git. Riponi tutto ciò che hai cambiato, tira tutte le nuove cose, applica la tua scorta.

git stash
git pull
git stash pop

Sul pop stash potrebbero esserci dei conflitti. Nel caso che descrivi, in effetti ci sarebbe un conflitto config.php. Ma risolvere il conflitto è facile perché sai che quello che metti nella scorta è quello che vuoi. Quindi fai questo:

git checkout --theirs -- config.php

5
quel checkout git - il loro comando è molto confuso. Ha fatto quello che volevo una volta e qualcosa di veramente brutto un'altra volta. Hai qualche buona documentazione al riguardo?
Milimetrico

3
Sì, a volte 'loro' e 'nostro' possono essere fonte di confusione. In un git merge'nostro' è ciò che è attualmente nella directory di lavoro. Ma per un git rebase(o git rebase -onto) il significato può essere scambiato.
GoZoner,

1
git stash , git pull , git stash apply Puoi eliminare la scorta con: git stash dropDopo aver unito le modifiche correttamente
BeingSuman il

11
La cosa con git è che devi capire cosa sta per fare. L'altra cosa con git è che anche per le persone intelligenti è spesso molto difficile capire cosa farà Git.
Brad Thomas,

1
Dovresti verificare se c'è qualcosa da nascondere. Altrimenti faresti apparire modifiche nascoste rispetto a una precedente git stash.
Jörn Reimerdes,

15

Se hai un file nel tuo repository che dovrebbe essere personalizzato dalla maggior parte dei puller, rinominalo in qualcosa di simile config.php.templatee aggiungilo config.phpal tuo .gitignore.


5
controlla anche questa risposta , puoi usare .gitattributesper mantenere sempre le tue modifiche durante l'unione.
KurzedMetal,

È più simile a quello di cui avevo bisogno. Il modello è la soluzione elegante ma temo di non poterlo usare poiché sto solo scrivendo script di distribuzione.
Johnny Everson,

6

Aggiornamento: questo risponde letteralmente alla domanda posta, ma penso che la risposta di KurzedMetal sia davvero ciò che vuoi.

Supponendo che:

  1. Sei sul ramo master
  2. Il ramo a monte è masterdentroorigin
  3. Non hai modifiche senza commit

.... potresti fare:

# Do a pull as usual, but don't commit the result:
git pull --no-commit

# Overwrite config/config.php with the version that was there before the merge
# and also stage that version:
git checkout HEAD config/config.php

# Create the commit:
git commit -F .git/MERGE_MSG

È possibile creare un alias per questo se è necessario farlo frequentemente. Tieni presente che se hai apportato modifiche non impegnate a config/config.php, ciò le eliminerebbe.



1

Per rispondere alla domanda: se si desidera escludere determinati file di un checkout, è possibile utilizzare sparse-checkout

1) In .git/info/sparse-checkout, definire ciò che si desidera conservare. Qui, vogliamo tutti (*) ma (notare il punto esclamativo) config.php:

 /*
 !/config.php

2) Di 'a git che vuoi prendere in considerazione la cassa sparsa

 git config core.sparseCheckout true

3) Se hai già questo file localmente, fai quello che git fa su un checkout sparso (digli che deve escludere questo file impostando il flag "skip-worktree" su di esso)

git update-index --skip-worktree config.php

4) Goditi un repository in cui il tuo file config.php è tuo - qualsiasi modifica si trovi nel repository.


Si noti che i valori di configurazione NON DOVREBBERO essere nel controllo del codice sorgente:

  • È una potenziale violazione della sicurezza
  • Causa problemi come questo per la distribuzione

Ciò significa che DEVI escluderli (inseriscili in .gitignore prima del primo commit) e crea il file appropriato su ogni istanza in cui esegui il checkout della tua app (copiando e adattando un file "template")

Nota che, una volta che un file viene preso in carico da git, .gitignore non avrà alcun effetto.

Dato che, una volta che il file è sotto il controllo del codice sorgente, hai solo due opzioni (): - Riordina tutta la cronologia per rimuovere il file (con git filter-branch) - Crea un commit che rimuove il file. È come combattere una battaglia persa, ma, beh, a volte devi conviverci.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.