it-swarm.dev

Come impongo "git pull" per sovrascrivere i file locali?

Come impongo una sovrascrittura di file locali su un git pull?

Lo scenario sta seguendo:

  • Un membro del team sta modificando i modelli per un sito web su cui stiamo lavorando
  • Aggiungono alcune immagini alla directory delle immagini (ma dimentica di aggiungerle sotto il controllo del codice sorgente)
  • Stanno inviando le immagini per posta, più tardi, a me
  • Sto aggiungendo le immagini sotto il controllo del codice sorgente e inserendole in GitHub insieme ad altre modifiche
  • Non possono estrarre gli aggiornamenti da GitHub perché Git non vuole sovrascrivere i loro file.

Questo è l'errore che sto ottenendo:

errore: il file dell'albero di lavoro non tracciato "public/images/icon.gif" verrebbe sovrascritto dall'unione

Come posso costringere Git a sovrascriverli? La persona è un designer - di solito risolvo tutti i conflitti a mano, quindi il server ha la versione più recente che devono solo aggiornare sul proprio computer.

5771
Jakub Troszok

Importante: se si verificano modifiche locali, queste verranno perse. Con o senza l'opzione --hard, qualsiasi commit locale che non è stato premuto verrà perso.[*]

Se si dispone di file che sono non monitorati da Git (ad esempio contenuto utente caricato), questi file non saranno interessati.


Penso che questo sia il modo giusto:

git fetch --all

Quindi, hai due opzioni:

git reset --hard Origin/master

OPPURE Se ti trovi in ​​qualche altro ramo:

git reset --hard Origin/<branch_name>

Spiegazione:

git fetch scarica l'ultima versione dal remoto senza tentare di unire o rebase nulla.

Quindi git reset reimposta il ramo master su ciò che hai appena recuperato. L'opzione --hard cambia tutti i file nella struttura di lavoro in modo che corrispondano ai file in Origin/master


Mantieni i commit locali correnti

[*]: Vale la pena notare che è possibile mantenere gli attuali commit locali creando un ramo da master prima di resettare:

git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard Origin/master

Dopo questo, tutti i vecchi commit verranno mantenuti in new-branch-to-save-current-commits

Modifiche non commesse

Le modifiche non eseguite, tuttavia (anche messe in scena), andranno perse. Assicurati di mettere da parte e salvare tutto ciò di cui hai bisogno. Per questo è possibile eseguire quanto segue:

git stash

E poi per riapplicare queste modifiche senza commit:

git stash pop
8139
RNA

Prova questo:

git reset --hard HEAD
git pull

Dovrebbe fare quello che vuoi.

808
Travis Reeder

ATTENZIONE: git clean cancella tutti i file/directory non tracciati e non può essere annullato.


A volte solo clean -f non aiuta. Se hai DIRECTORIE non tracciate, anche l'opzione -d ha bisogno di:

# WARNING: this can't be undone!

git reset --hard HEAD
git clean -f -d
git pull

ATTENZIONE: git clean cancella tutti i file/directory non tracciati e non può essere annullato.

Potresti utilizzare prima il flag -n (--dry-run). Questo ti mostrerà ciò che verrà eliminato senza effettivamente eliminare nulla:

git clean -n -f -d

Esempio di output:

Would remove untracked-file-1.txt
Would remove untracked-file-2.txt
Would remove untracked/folder
...
409

Come Riccio penso che le risposte siano terribili. Ma anche se la risposta di Hedgehog potrebbe essere migliore, non penso che sia così elegante come potrebbe essere. Il modo in cui ho trovato di farlo è utilizzando "fetch" e "merge" con una strategia definita. Il che dovrebbe fare in modo che le modifiche locali vengano mantenute purché non siano uno dei file con cui si tenta di forzare una sovrascrittura. 

Prima fai un commit delle tue modifiche

 git add *
 git commit -a -m "local file server commit message"

Quindi recuperare le modifiche e sovrascrivere se c'è un conflitto

 git fetch Origin master
 git merge -s recursive -X theirs Origin/master

"-X" è un nome di opzione e "loro" è il valore per tale opzione. Stai scegliendo di utilizzare le "loro" modifiche, invece delle "tue" modifiche se c'è un conflitto.

347
Richard Kersey

Invece di fare:

git fetch --all
git reset --hard Origin/master

Consiglierei di fare quanto segue:

git fetch Origin master
git reset --hard Origin/master

Non è necessario recuperare tutti i telecomandi e le derivazioni se si intende ripristinare il ramo Origin/master giusto?

251
Johanneke

Attenzione, facendo ciò cancellerai definitivamente i tuoi file se hai qualche directory/* nel tuo file gitignore.

Alcune risposte sembrano essere terribili. Terribile nel senso di ciò che è successo a @Lauri seguendo il suggerimento di David Avsajanishvili.

Piuttosto (git> v1.7.6):

git stash --include-untracked
git pull

Più tardi puoi pulire la cronologia di scorta.

Manualmente, uno per uno:

$ git stash list
[email protected]{0}: WIP on <branch>: ...
[email protected]{1}: WIP on <branch>: ...

$ git stash drop [email protected]{0}
$ git stash drop [email protected]{1}

Brutalmente, tutto in una volta:

$ git stash clear

Certo, se vuoi tornare a ciò che hai nascosto:

$ git stash list
...
$ git stash apply [email protected]{5}
102
Hedgehog

Potresti trovare utile questo comando per eliminare le modifiche locali:

git checkout <your-branch> -f

E poi fai una pulizia (rimuove i file non tracciati dall'albero di lavoro):

git clean -f

Se si desidera rimuovere le directory non tracciate oltre ai file non tracciati:

git clean -fd
88
Vishal

Invece di unire con git pull, prova questo: 

git fetch --all

seguito da:

git reset --hard Origin/master.

82
Lloyd Moore

L'unica cosa che ha funzionato per me è stata:

git reset --hard HEAD~5

Questo ti riporterà cinque commit e poi con

git pull

Ho scoperto che cercando come annullare una fusione Git .

55
Chris BIllante

Il problema con tutte queste soluzioni è che sono tutte o troppo complesse, o, un problema ancora più grande, è che rimuovono tutti i file non tracciati dal server web, che non vogliamo poiché ci sono sempre i file di configurazione necessari che sono su il server e non nel repository Git.

Ecco la soluzione più pulita che stiamo usando:

# Fetch the newest code
git fetch

# Delete all files which are being added, so there
# are no conflicts with untracked files
for file in `git diff HEAD..Origin/master --name-status | awk '/^A/ {print $2}'`
do
    rm -f -- "$file"
done

# Checkout all files which were locally modified
for file in `git diff --name-status | awk '/^[CDMRTUX]/ {print $2}'`
do
    git checkout -- "$file"
done

# Finally pull all the changes
# (you could merge as well e.g. 'merge Origin/master')
git pull
  • Il primo comando recupera i dati più recenti.

  • Il secondo comando controlla se ci sono file che vengono aggiunti al repository ed elimina quei file non tracciati dal repository locale che causerebbero conflitti.

  • Il terzo comando controlla tutti i file che sono stati modificati localmente.

  • Infine eseguiamo un pull per aggiornare alla versione più recente, ma questa volta senza conflitti, poiché i file non tracciati che sono nel repository non esistono più e tutti i file modificati localmente sono già gli stessi del repository.

51

Ho avuto lo stesso problema. Nessuno mi ha dato questa soluzione, ma ha funzionato per me.

L'ho risolto da:

  1. Elimina tutti i file. Lascia solo la directory .git.
  2. git reset --hard HEAD
  3. git pull
  4. git Push

Ora funziona.

39

Prima di tutto, prova il modo standard:

git reset HEAD --hard # To remove all not committed changes!
git clean -fd         # To remove all untracked (non-git) files and folders!

Avvertenza : I comandi sopra riportati possono causare perdita di dati/file solo se non li si è impegnati! Se non sei sicuro, crea prima il backup dell'intera cartella del repository.

Quindi tiralo di nuovo.

Se sopra non ti sarà d'aiuto e non ti preoccupi dei tuoi file/directory non tracciati (fai il backup prima solo nel caso), prova i seguenti semplici passaggi:

cd your_git_repo  # where 'your_git_repo' is your git repository folder
rm -rfv *         # WARNING: only run inside your git repository!
git pull          # pull the sources again

Questo rimuoverà tutti i file git (eccetto .git/ dir, dove hai tutti i commit) e lo tiri di nuovo.


Perché git reset HEAD --hard potrebbe non riuscire in alcuni casi?

  1. Regole personalizzate in .gitattributes file

    Avere la regola eol=lf in .gitattributes potrebbe far sì che git modifichi alcune modifiche ai file convertendo le terminazioni di riga CRLF in LF in alcuni file di testo.

    In tal caso, devi impegnare queste modifiche CRLF/LF (esaminandole in git status) oppure provare: git config core.autcrlf false in modo temporaneo a ignorarle.

  2. Incapacità del file system

    Quando si utilizza il file system che non supporta gli attributi di autorizzazione . In esempio si hanno due repository, uno su Linux/Mac (ext3/hfs+) e un altro su file system basato su FAT32/NTFS.

    Come noti, ci sono due diversi tipi di file system, quindi quello che non supporta i permessi Unix fondamentalmente non può resettare i permessi dei file sul sistema che non supporta quel tipo di permessi, quindi non importa quanto --hard tu provi, git rileva sempre alcuni "cambiamenti".

34
kenorb

Bonus:

Parlando di pull/fetch/merge nelle risposte precedenti, mi piacerebbe condividere un trucco interessante e produttivo,

git pull --rebase

Questo comando sopra è il comando più utile nella mia vita Git che ha risparmiato un sacco di tempo.

Prima di spingere il tuo nuovo commit al server, prova questo comando e sincronizzerà automaticamente le ultime modifiche del server (con un fetch + unisci) e posizionerà il tuo commit nella parte superiore del log Git. Non c'è alcun bisogno di preoccuparsi di pull/fusione manuale.

Trova i dettagli in / Cosa fa "git pull --rebase" do?.

33

Ho avuto un problema simile. Dovevo fare questo:

git reset --hard HEAD
git clean -f
git pull
27
Ryan

Ho riassunto altre risposte. Puoi eseguire git pull senza errori:

git fetch --all
git reset --hard Origin/master
git reset --hard HEAD
git clean -f -d
git pull

Avvertenza : Questo script è molto potente, quindi potresti perdere le tue modifiche.

27
Robert Moon

Sulla base delle mie esperienze simili, la soluzione offerta da Strahinja Kustudic sopra è di gran lunga la migliore. Come altri hanno sottolineato, la semplice reimpostazione completa rimuoverà tutti i file non tracciati che potrebbero includere molte cose che non si desidera rimuovere, come i file di configurazione. Ciò che è più sicuro, è quello di rimuovere solo i file che stanno per essere aggiunti e, inoltre, è probabile che si voglia anche eseguire il checkout di tutti i file modificati localmente che stanno per essere aggiornati.

Tenendo a mente, ho aggiornato lo script di Kustudic per fare proprio questo. Ho anche corretto un refuso (mancante nell'originale).

#/bin/sh

# Fetch the newest code
git fetch

# Delete all files which are being added,
# so there are no conflicts with untracked files
for file in `git diff HEAD..Origin/master --name-status | awk '/^A/ {print $2}'`
do
    echo "Deleting untracked file $file..."
    rm -vf "$file"
done

# Checkout all files which have been locally modified
for file in `git diff HEAD..Origin/master --name-status | awk '/^M/ {print $2}'`
do
    echo "Checking out modified file $file..."
    git checkout $file
done

# Finally merge all the changes (you could use merge here as well)
git pull
26
Rolf Kaiser

Credo che ci siano due possibili cause di conflitto, che devono essere risolte separatamente, e per quanto posso dire, nessuna delle risposte di cui sopra si occupa di entrambi:

  • I file locali che non sono tracciati devono essere eliminati, manualmente (più sicuro) o come suggerito in altre risposte, da git clean -f -d

  • Anche i commit locali che non sono sul ramo remoto devono essere eliminati. IMO il modo più semplice per farlo è con: git reset --hard Origin/master (sostituisci 'master' con qualsiasi ramo su cui stai lavorando ed esegui prima un git fetch Origin)

23
tiho

Un modo più semplice sarebbe:

git checkout --theirs /path/to/file.extension
git pull Origin master

Questo sovrascriverà il tuo file locale con il file su git

20
maximus 69

Sembra che la maggior parte delle risposte qui siano focalizzate sul ramo master; tuttavia, ci sono momenti in cui sto lavorando sullo stesso ramo di funzionalità in due luoghi diversi e voglio che un rebase in uno si rifletta nell'altro senza un sacco di salti mortali.

Basato su una combinazione di risposta dell'RNA e risposta di torek a una domanda simile , ho trovato questo che funziona splendidamente:

git fetch
git reset --hard @{u}

Esegui questo da un ramo e resetterà solo il tuo ramo locale alla versione upstream.

Questo può anche essere inserito in un alias git (git forcepull):

git config alias.forcepull "!git fetch ; git reset --hard @{u}"

Oppure, nel tuo file .gitconfig:

[alias]
  forcepull = "!git fetch ; git reset --hard @{u}"

Godere!

20
JacobEvelyn

Ho avuto lo stesso problema e per qualche ragione, anche un git clean -f -d non lo farebbe. Ecco perché: per qualche motivo, se il tuo file viene ignorato da Git (tramite una voce .gitignore, presumo), si preoccupa ancora di sovrascriverlo con un successivo pull , ma a clean non lo farà rimuovilo, a meno che tu non aggiunga -x.

19
Tierlieb

L'ho appena risolto da solo:

git checkout -b tmp # "tmp" or pick a better name for your local changes branch
git add -A
git commit -m 'tmp'
git pull
git checkout master # Or whatever branch you were on originally
git pull
git diff tmp

dove l'ultimo comando fornisce un elenco delle modifiche locali. Continua a modificare il ramo "tmp" finché non è accettabile e quindi unisci di nuovo a master con: 

git checkout master && git merge tmp

Per la prossima volta, probabilmente puoi gestirlo in un modo più pulito cercando "git stash branch" anche se lo stash rischia di causare problemi nei primi tentativi, quindi fai il primo esperimento su un progetto non critico ...

18
Simon B.

Ho una strana situazione che né git clean o git reset funziona. Devo rimuovere il file in conflitto da git index utilizzando il seguente script su ogni file non tracciato:

git rm [file]

Quindi sono in grado di tirare bene.

17
Chen Zhang

Conosco un metodo molto più semplice e meno doloroso:

$ git branch -m [branch_to_force_pull] tmp
$ git fetch
$ git checkout [branch_to_force_pull]
$ git branch -D tmp

Questo è tutto!

16
ddmytrenko

Questi quattro comandi funzionano per me.

git reset --hard HEAD
git checkout Origin/master
git branch -D master
git checkout -b master

Per controllare/tirare dopo aver eseguito questi comandi

git pull Origin master

Ho provato molto ma alla fine ho avuto successo con questi comandi.

13
vishesh chandra

Basta fare

git fetch Origin branchname
git checkout -f Origin/branchname // This will overwrite ONLY new included files
git checkout branchname
git merge Origin/branchname

In questo modo si evitano tutti gli effetti collaterali indesiderati, come l'eliminazione di file o directory che si desidera conservare, ecc.

12
user2696128

Nonostante la domanda iniziale, le risposte migliori possono causare problemi a chi ha un problema simile, ma non vogliono perdere i file locali. Ad esempio, vedi i commenti di Al-Punk e crizCraig. 

La seguente versione impegna le modifiche locali su un ramo temporaneo (tmp), controlla il ramo originale (che presumo master) e unisce gli aggiornamenti. Si potrebbe fare ciò con stash, ma ho scoperto che di solito è più semplice usare semplicemente l'approccio branch/merge.

git checkout -b tmp
git add *; git commit -am "my temporary files"
git checkout master

git fetch Origin master
git merge -s recursive -X theirs Origin master

dove assumiamo il altro repository è Origin master.

12
Snowcrash

Reimposta l'indice e la testa su Origin/master, ma non reimpostare l'albero di lavoro:

git reset Origin/master
11
user811773

Requisiti:

  1. Tieni traccia dei cambiamenti locali così nessuno li perde mai.
  2. Rendere il repository locale corrispondente al repository Origin remoto.

Soluzione:

  1. Stash le modifiche locali.
  2. Recupera con un clean di file e directory ignoring .gitignore e hard reset a Origin .

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard Origin/master
    
9
vezenkov

Ho letto tutte le risposte, ma stavo cercando un singolo comando per farlo. Ecco cosa ho fatto. Aggiunto un alias git a .gitconfig

[alias]
      fp = "!f(){ git fetch ${1} ${2} && git reset --hard ${1}/${2};};f"

Esegui il tuo comando come 

git fp Origin master

equivalente a

git fetch Origin master
git reset --hard Origin/master
9
Venkat Kotra

Non utilizzare git reset --hard. Ciò cancellerà i loro cambiamenti che potrebbero essere completamente indesiderabili. Anziché:

git pull
git reset Origin/master
git checkout <file1> <file2> ...

Ovviamente puoi usare git fetch invece di git pull dato che chiaramente non si unirà, ma se di solito tiri ha senso continuare a tirare qui.

Quindi, quello che succede qui è che git pull aggiorna il tuo riferimento di origine/principale ; git reset aggiorna il riferimento alla diramazione locale on per essere uguale a Origin/master senza aggiornare alcun file, quindi lo stato di estrazione è invariato; quindi git checkout ripristina i file nello stato dell'indice del ramo locale secondo le necessità. Nei casi in cui è stato aggiunto esattamente lo stesso file su live e su master upstream, l'indice corrisponde già al file successivo al reset, quindi nel caso comune non è necessario eseguire git checkout.

Se il ramo upstream contiene anche commit che vuoi applicare automaticamente, puoi seguire una sottile variazione sul processo:

git pull
git merge <commit before problem commit>
git reset <problem commit>
git checkout <file1> <file2> ...
git pull
8
Jim Driscoll

Questa è la procedura consigliata per annullare le modifiche:

  • git commit Configura le modifiche di staged in modo che vengano salvate in reflog (vedi sotto)
  • git fetch Scarica le ultime modifiche a monte
  • git reset --hard Origin/master Hard reset al ramo master Origin

Il reflogregistra i rami e gli altri riferimenti aggiornati nel repository locale. O semplicemente messo - il reflog è la storia delle tue modifiche.

Quindi è sempre una grande pratica da impegnare. I commit sono aggiunti al reflog che ti garantisce sempre un modo per recuperare il codice cancellato.

7
Jordan Georgiev

Ho usato questo comando per sbarazzarmi dei file locali impedendomi di fare un pull/merge. Ma fa attenzione! Esegui git merge … prima per vedere se ci sono solo quei file che vuoi davvero rimuovere.

git merge Origin/master 2>&1 >/dev/null | grep ^[[:space:]] | sed s/^[[:space:]]//g | xargs -L1 rm
  • git merge elenca tra l'altro tutti quei file. Sono preposti da alcuni spazi bianchi.
  • 2>&1 >/dev/null reindirizza l'output dell'errore a quello standard in modo che venga rilevato da grep.
  • grep ^[[:space:]] filtra solo le righe con nomi di file.
  • sed s/^[[:space:]]//g taglia lo spazio bianco dall'inizio.
  • xargs -L1 rm chiama rm su ciascuno di questi file, cancellandoli.

Maneggia con cura: Qualunque output git merge, il rm sarà chiamato per every line che inizia con uno spazio bianco.

5
Glutexo

Stavo cercando di utilizzare il ramo Material2 su Angular2-Webpack-Starter e ho avuto un bel pò di tempo. Questo era l'unico modo per scaricare e utilizzare quel ramo.

git clone --depth 1 https://github.com/angularclass/angular2-webpack-starter.git

cd angular2-webpack-starter/

git checkout -b material2

Apri la cartella del progetto ed elimina tutti i file e le cartelle non nascosti. Lascia tutti quelli nascosti.

git add .

git commit -m "pokemon go"

git reset --hard

git pull Origin material2

(Quando viene visualizzato l'editor, premi ": wq", quindi premi Enter)

Ora sei pronto.

5
Helzgate

Su Windows, esegui questo comando singolo:

git fetch --all & git reset --hard Origin/master
3
Luca C.

Puoi ignorare quel file con un file nella cartella base del progetto:

.gitignore

public/images/*

Quindi estrarre le modifiche e quindi rimuovere quella linea dal file gitignore.

3
Daniel Gaytán

git fetch --all && git reset --hard Origin/master && git pull

0
Suge

1: ripristina un commit precedente

git reset --hard HEAD

2: Elimina file non tracciati

git clean -f

3: Tirare i commit

git pull

Fonti:

0
abhijithvijayan

se si desidera ripristinare il ramo di monitoraggio remoto in modo generico, utilizzare:

git fetch
git reset --keep Origin/$(git rev-parse --abbrev-ref HEAD)

se vuoi resettare anche le tue modifiche locali:

git fetch
git reset --hard Origin/$(git rev-parse --abbrev-ref HEAD)
0
warch