Può “git pull” memorizzare automaticamente e pop modifiche in sospeso?

So come risolvere questo:

[email protected]$ git pull Updating 9386059..6e3ffde error: Your local changes to the following files would be overwritten by merge: foo.bar Please, commit your changes or stash them before you can merge. Aborting 

Ma non c’è un modo per far sì che il git pull faccia lo stash e il pop dance per me?

Se questo comando ha un nome diverso, va bene.

Creare un alias di shell per git stash; git pull; git stash pop git stash; git pull; git stash pop git stash; git pull; git stash pop è una soluzione, ma cerco una soluzione migliore.

Per Git 2.6+ (pubblicato il 28 settembre 2015)

L’unica impostazione di git config che potrebbe interessare è:

 rebase.autoStash 

Se impostato su true, crea automaticamente uno stash temporaneo prima dell’inizio dell’operazione e lo applica al termine dell’operazione.
Ciò significa che è ansible eseguire rebase su un worktree sporco.

Tuttavia, utilizzare con caucanvas: l’applicazione di stash finale dopo un rebase di successo potrebbe causare conflitti non banali. Il valore predefinito è falso.

abbinalo con:

 pull.rebase 

Quando è true, rebase rami sopra il ramo scaricato, invece di unire il ramo predefinito dal remoto predefinito quando viene eseguito “git pull”.

 git config pull.rebase true git config rebase.autoStash true 

Questo sarebbe sufficiente per un semplice git pull per lavorare anche su un albero sporco.
Nessun alias necessario in quel caso.


Vedi commit 53c76dc (04 lug 2015) di Kevin Daudt ( Ikke ) .
(Unita da Junio ​​C Hamano – gitster – in commit e69b408 , 17 ago 2015)

pull : consenti albero sporco quando rebase.autostash abilitato

rebase ha imparato a hide le modifiche quando incontra un albero di lavoro sporco, ma git pull --rebase no.

Verificare solo se la struttura di lavoro è sporca quando rebase.autostash non è abilitato.


Nota: se vuoi eseguire il pull senza l’ avvio automatico (anche se rebase.autoStash true è impostato), dal git 2.9 (giugno 2016):

  pull --rebase --no-autostash 

Vedi commit 450dd1d , commit 1662297 , commit 44a59ff , commit 5c82bcd , commit 6ddc97c , commit eff960b , commit efa195d (02 apr 2016) e commit f66398e , commit c48d73b (21 marzo 2016) di Mehul Jain ( mehul2029 ) .
(Unita da Junio ​​C Hamano – gitster – in commit 7c137bb , 13 apr 2016)

Commit f66398e in particolare include:

pull --rebase : add --[no-]autostash flag di --[no-]autostash

Se la variabile di configurazione rebase.autoStash è impostata, non c’è modo di sovrascriverla per ” git pull --rebase ” dalla riga di comando.

Teach ” git pull --rebase ” il --[no-]autostash flag della riga di comando di --[no-]autostash che sovrascrive il valore corrente di rebase.autoStash , se impostato. Come ” git rebase ” comprende l’opzione --[no-]autostash , si tratta semplicemente di passare l’opzione al sottostante ” git rebase ” quando viene chiamato ” git pull --rebase “.


Attenzione: prima di Git 2.14 (3 git pull --rebase --autostash 2017), ” git pull --rebase --autostash ” non si git pull --rebase --autostash automaticamente quando la cronologia locale avanza rapidamente verso l’alto.

Vedi commit f15e7cf (01 giu 2017) di Tyler Brazier ( tylerbrazier ) .
(Unita da Junio ​​C Hamano – gitster – in commit 35898ea , 05 giu 2017)

pull : ff --rebase --autostash funziona in repository sporchi

Quando git pull --rebase --autostash in un repository sporco ha provocato un avanzamento rapido, non è stato eseguito l’arresto automatico dell’istanza e il pull non è riuscito.
Ciò era dovuto a una scorciatoia per evitare l’esecuzione di rebase quando possiamo avanzare velocemente, ma l’autostash viene ignorato su quel codepath.


Aggiornamento: Mariusz Pawelski chiede nei commenti una domanda interessante:

Quindi tutti scrivono di autostash quando autostash rebase (o pull --rebase ).

Ma nessuno sta prendendo in considerazione l’avvio automatico quando si fa un tiro normale con l’ unione .
Quindi non esiste un cambio automatico per quello? O mi manca qualcosa? Preferisco fare git pull --rebase ma OP ha chiesto di git pull ” standard

Risposta:

La discussione originale su questa funzione di avvio automatico è stata implementata originariamente sia per git pull (unione) che git pull --rebase .

Ma … Junio ​​C Hamano (manutentore di Git) ha notato che:

Se il pull-merge fosse qualcosa che inducesse il “fastidio” che ha innescato questo argomento, per definizione, il cambiamento locale si sovrappone all’unione e questo “pop nascosto” interno toccherà i percorsi toccati dall’unione e probabilmente non ne risulterà in “Dropped” ma lascia che altri conflitti vengano risolti.

Sospetto che la configurazione pull.autostash non sia una buona aggiunta perché incoraggia un stream di lavoro cattivo e indolore.
In casi semplici, potrebbe non fare male, ma quando i cambiamenti locali sono complessi, farebbe molto male a non averlo, e la configurazione ruba l’incentivo a scegliere.

L’equazione è leggermente diversa per “pull-rebase”, poiché “rebase” ti insiste per iniziare da un albero di lavoro pulito, quindi il fastidio “scarica e poi smetti” sembra più grande. Ho il sospetto che l’allentamento possa essere una soluzione più produttiva al vero problema.

Quindi, per quanto riguarda un classico pull-merge, è meglio:

incoraggiare l’utente a pensare alla natura del WIP che ha nell’albero di lavoro prima di eseguire ” git pull .
È una bestia troppo complessa che può interferire con quello che fanno gli altri, o è un cambiamento banale che può riporre e ricacciare indietro?

Se è il primo, sarà molto meglio fare ” checkout -b “, continuare a lavorare fino a quando il cambiamento locale non avrà una forma e un “commit” migliori, prima di entrare nel ramo originale.

Se quest’ultimo, è meglio fare:

  • git pull “,
  • dopo aver trovato conflitti, corri
    • git stash ,
    • git merge FETCH_HEAD e
    • git stash pop

Per risparmiare qualche secondo per gli esploratori in arrivo, ecco un riassunto (grazie a @VonC):

 git pull --rebase --autostash 

Come detto sopra, l’impostazione dei due valori di configurazione non funziona attualmente con git pull , poiché la configurazione di autostash si applica solo ai rebases effettivi. Questi comandi git fanno ciò che vuoi:

 git fetch git rebase --autostash FETCH_HEAD 

O impostalo come alias:

 git config alias.pullr '!git fetch; git rebase --autostash FETCH_HEAD' 

Quindi fa:

 git pullr 

Naturalmente, questo alias può essere rinominato come desiderato.

Con Git 2.6+ puoi usare quanto segue:

 alias gup='git -c rebase.autoStash=true pull --rebase' 

Questo --rebase fa sì che git-pull usi rebase invece di merge , quindi le impostazioni / opzioni come --ff-only non si applicano.

Sto usando un alias per tirare con --ff-only di default ( git pull --ff-only ), e quindi posso usare gup (da sopra) nel caso in cui non sia ansible un’unione di forward-forward o ci siano cambiamenti nascosti.

Come hai già detto questo è il modo di farlo. Puoi usarlo in alias per salvarti digitando e per usare scorciatoia o puoi usarlo in una sola riga (può essere anche un alias)

git stash && git pull --rebase && git stash pop

Farà la stessa cosa come hai fatto tu, ma in una singola riga (&&) ed è impostato come alias sarà anche più breve.

Le seguenti righe mostreranno le modifiche in entrata / uscita prima di tirare / spingere

 git log ^master origin/master git log master ^origin/master