Posso fare in modo che l'inoltro veloce sia disattivato di default in git?


263

Non posso davvero mai pensare a un momento in cui avrei usato git merge, piuttosto che git rebasee non vogliono avere un commit vedere. Esiste un modo per configurare git in modo che abbia l'inoltro rapido di default? Il fatto che ci sia --ffun'opzione sembrerebbe implicare che c'è un modo, ma non riesco a trovarlo nella documentazione.


3
Uso mergetutto il tempo per le succursali quando non hanno effettuato alcun commit dal loro telecomando per farle avanzare rapidamente. Sembra il modo più semplice e sicuro per farlo. Sono curioso, ovviamente hai un caso d'uso. Perché mai vorresti creare un commit di unione in cui non ci sono commit su un lato del ramo?
CB Bailey,

12
Uso i rami per creare un raggruppamento logico di commit. Quindi, se faccio una fusione, è fondamentalmente un modo per dire "questi impegni vanno insieme". Puoi quasi pensarlo come un rebase interattivo e una zucca da povero. :-)
Jason Baker,

13
Disattivare l'avanzamento rapido è estremamente utile, in particolare quando si segue un modello come Un modello di ramificazione Git di successo
steinybot

2
Si prega di cambiare la risposta accettata per questo nella risposta di Eric Platon stackoverflow.com/a/6810687/3408 - Ho fatto i passi nella risposta accettata, poi ho capito che era solo per il ramo principale nel repository corrente, che è sciocco.
rjmunro,

3
@ jpmc26 Immagino ognuno per conto suo. Non sono d'accordo con quell'articolo. Trovare i due genitori di un commit di unione non è difficile e ti dice esattamente quali sono stati i cambiamenti. Quindi puoi prendere quelle modifiche e fare un "rebase su" qualche altro ramo. Con il modello piatto devi trovare manualmente e scegliere la ciliegia. Scegliamo di abbracciare la ramificazione. Certo, è complesso quando si guarda l'intero albero, ma questa è la realtà, più cambiamenti si verificano in parallelo. Appiattire tutto nasconde ciò che è realmente accaduto.
steinybot,

Risposte:


282

Sì, c'è --no-ff. È possibile configurare le opzioni di unione per ramo, ad es

git config branch.master.mergeoptions  "--no-ff"

aggiunge quanto segue al tuo $(REPO)/.git/configfile:

[branch "master"]
    mergeoptions = --no-ff

Nota a piè di pagina: parlando della mia esperienza, alla fine ho scoperto che il passaggio dall'avanzamento rapido allo spegnimento è stato per lo più utile per i nuovi arrivati ​​git - tuttavia, una volta che la sensazione di flussi di lavoro e concetti inizia a sprofondare in te sicuramente vuoi evitare di sfocare il tuo grafico di registro con tonnellate di inutili fusioni il tipo di remote ..blarf si impegna.

Nota 2, un decennio più tardi: le altre risposte di seguito forniscono opzioni di configurazione più moderne, ma in realtà, probabilmente VUOI rimanere con le impostazioni predefinite (cioè avanzamento rapido ogni volta che è possibile) in questo giorno ed età, perché la fusione vuota-commette davvero solo rendere la storia molto più difficile da ragionare.


142
Imparare il git è un po 'come l'arrampicata in montagna; ma invece di iniziare con piccole scogliere e avanzare verso quelle più difficili, Git ti fa scalare la stessa montagna ancora e ancora, solo per cadere ad altezze diverse ogni volta, ogni volta altrettanto sorpreso che la linea di vita non fosse attaccata.
conny

12
@Thomas: Sì; git pullè git fetch+ git merge.
Michelle Tilley,

9
Sembra buono, ma c'è un modo per farlo a livello globale, per tutti i rami, invece di doverlo impostare per ogni ramo?
bwinton,

33
Attenzione ai draghi. Questa opzione è pericolosa proprio come ha detto @Thomas ... Ogni git pull crea un merge commit. git pull --ff non sovrascrive le mergeoptions = no-ff nella configurazione di git.
Dalibor Filus,

15
E se sono solo stanco di scrivere git merge --no-ff (branchname)? E voglio git pullfunzionare come sempre?
Dogweather,

341

Sembra che ci sia ancora una domanda in sospeso nel thread: come farlo a livello globale (cioè per tutti i rami)? Per la cronaca, possiamo usare quanto segue:

git config --add merge.ff false

... per applicarlo a tutti i rami nel repository corrente. Per farlo applicare a tutti i rami in tutti i repository in cui qualcuno non lo ha eseguito senza l' --globalopzione (le impostazioni locali hanno la precedenza su globale) eseguire questo:

git config --global --add merge.ff false

Dalla documentazione :

merge.ff
Per impostazione predefinita, git non crea un commit di unione extra quando si unisce un commit che è un discendente del commit corrente. Invece, la punta del ramo corrente viene fatta avanzare rapidamente. Se impostata su false, questa variabile indica a git di creare un commit di unione extra in tal caso (equivalente a fornire l' --no-ffopzione dalla riga di comando). Se impostato su only, sono consentite solo tali fusioni di avanzamento rapido (equivalenti a fornire l' --ff-onlyopzione dalla riga di comando).


18
Nota: è merge.ffstato introdotto in Git 1.7.6. Non è efficace nelle versioni precedenti.
Chris Johnsen,

2
Per le persone che usano Git 1.7.6, questa è la soluzione migliore e più semplice.
Ryan Lundy,

22
Lo sto usando insieme ad un aliaspuff = "pull --ff --ff-only"
stigi il

11
C'è anche (ora, vedi git-scm.com/docs/git-config ) l'opzione pull.ff che può essere impostata su solo , che farà lo stesso dell'alias .
jotomo,

1
Grazie, @jotomo. Tale funzione è disponibile da Git v2.0.0 (da commit b814da891e8261b909fc5d9fb07b4e8b13989c2d).
Eric Platon,

14

Leggendo il thread di risposte ho finito con le seguenti due opzioni

git config --global pull.ff only # Disallows non ff merges on pull. Overrides merge.ff when pulling
git config --global merge.ff false # even create extra merge commit when fast forward merge would be possible

Solo vagamente correlato, ho anche scoperto che questa impostazione evita problemi durante il pull

git config --global pull.rebase true # set up pull to rebase instead of merge

1
git config --global pull.rebase true # notare "true" alla fine della riga
zowers

Grazie @zowers ho risolto questo
problema
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.