2013-03-26 8 views
15

Come parte del nostro flusso di lavoro basato su rebase, spero di utilizzare un'unione sul ramo principale. In particolare, desidero unirmi solo quando il ramo dell'argomento è stato ridefinito sul commit master più recente, rendendo in tal modo possibile unire uno in avanti veloce. Posso ottenere che utilizzando:Come ottenere `git --no-ff --ff-only` che non è consentito

git merge --ff-only

Inoltre, desidero registrare l'integrazione del ramo discussione con un vuoto commit ecco perché desidero usare --no-ff che impone che il comportamento :

git merge --no-ff

Quello che voglio davvero, però, è una combinazione di entrambi: unire solo quando è banale, ma mi permetta di registrare comunque. Git pensa che

fatal: You cannot combine --no-ff with --ff-only.

che appare ovvia per alcuni.

git merge --edit --no-ff topicbranch

non raggiunge il comportamento che voglio neanche. Quindi, come posso unirmi con l'opzione --no-ff se il ramo dell'argomento in questione viene ridefinito con l'ultimo commit master?


AGGIORNAMENTO: Sembra che la risposta di Charles Bailey farà il trucco. Se si desidera avere questo rotolato in un alias git si potrebbe emettere questo qui:

git config --global alias.integrate '!test "$(git merge-base HEAD "$1")" = "$(git rev-parse HEAD)" && git merge --no-ff --edit $1 || echo >&2 "Not up-to-date; refusing to merge, rebase first!"' 

Un po 'di un boccone, ma opere. Notare la forza di una modifica del messaggio di commit con l'opzione --edit.

+0

Perché l'ovvietà falso? '--ff-only' dice che non voglio fare nessun commit di merge Voglio solo spostare il ramo locale in avanti - se possibile - a questo suggerimento; '--no-ff' dice che * voglio * effettuare un commit di unione tra qui e là anche se è possibile spostare semplicemente il ramo locale in avanti. Per inciso, non vedo dove si sta specificando '--ff-only', quindi non vedo da dove viene l'errore. –

+0

Il --ff-only è stato emesso nel titolo. Modificheremo il testo per renderlo più chiaro. E sto usando il controllo -ff-only per vedere se l'unione è banale. @CharlesBailey, trovo che sei abbastanza liberale con i tuoi voti negativi. tsk tsk. – DrSAR

+3

Quindi in pratica non vuoi '--ff-only' perché * fai * vuoi fare un commit di unione. Puoi eseguire il controllo come passaggio separato: ad es. 'test $ (git merge-base HEAD topicbranch) = $ (git rev-parse HEAD) && git merge --no-ff topicbranch' –

risposta

7

Non si desidera --ff-only perché si desidera eseguire un commit unione che --ff-only inibisce.

Il controllo che si desidera può essere eseguito come controllo separato prima di eseguire il comando di unione. Potresti impacchettarlo in una semplice funzione di shell.

E.g.

merge_if_ahead() { 
    if test "$(git merge-base HEAD "$1")" = "$(git rev-parse HEAD)"; then 
     git merge --no-ff "$1" 
    else 
     echo >&2 "Not up to date; refusing to merge" 
     return 1 
    fi 
} 
+0

Ciao, hai qualche idea se posso usare questo per farla affermare su Bitbucket o Github? È possibile farlo utilizzando Git Hooks? –

2

ho creato un alias che funziona per i miei semplici test

git config --global alias.ffmerge '!sh -c "git merge --ff-only $1 && git reset --hard [email protected]{1} && git merge --no-ff $1" -' 

Si compone di 3 comandi, uno dopo l'altro, che fallirà, non appena il primo fallisce. Spiegando ciascuno:

git merge --ff-only $1 

Errore se l'unione non può continuare come unione di avanzamento veloce. ($ 1 è il nome del ramo passato come argomento)

git reset --hard [email protected]{1} 

Se il primo comando ha esito positivo significa che possiamo fare una fusione fast-forward, ma come vogliamo fare un merge commit ci sposteremo di nuovo alla condizione di HEAD appena prima della fusione (riuscita). HEAD @ {1} è un puntatore di reflog.

git merge --no-ff $1 

Ora noi penseremo al reale si fondono con una fusione commettere anche se la fusione può andare un testa come un fast-forward.

Una semplice chiamata a git ffmerge farà il tutto per noi, l'unico passaggio che può fallire è il primo e che ci lascerebbe in una copia di lavoro invariata come prima.

Come sempre con git reset --hard la copia di lavoro deve essere pulita.

+0

Reset hard eliminerà tutte le modifiche non modificate. Questo non è necessario e pericoloso nel contesto di ciò che deve essere effettivamente controllato. (Ad esempio, dovresti solo verificare se è possibile eseguire un fast-forward ma ora devi _should_, ma non controllare se sono presenti modifiche non pianificate o non modificate.) –

+0

@Andreas Wederbrand Grazie per questo. Nonostante il difficile reset, funziona per i miei scopi (ed è meno dipendente dai problemi di shell come la soluzione -z). Ottieni un +1 per compensare le feroci abitudini di voto degli altri. Anche se cercherò di ottenere il cast della soluzione di bereal in un alias funzionante. – DrSAR

+0

Sono d'accordo che reset --hard potrebbe essere pericoloso ed è per questo che ho detto che la copia di lavoro dovrebbe essere pulita. Questo tipo di fusioni di solito accadrebbe su una sorta di macchina di fusione in cui non accade nient'altro. –

1
git config alias.mff '!mff() { git merge --ff-only "$1" && git reset --hard [email protected]{1} && git merge --no-ff "$1"; }; mff' 

e da allora in poi

git mff other-branch 
+0

Com'è diverso dalla risposta di @ andreas-wederbrand? – DrSAR

+1

Oh, in realtà ho trascurato la sua soluzione. Ma come chiedi, la mia soluzione non avvia un nuovo eseguibile 'sh', ma semplicemente definisce una funzione che viene chiamata. Ciò consente di risparmiare il costo di avviare un altro processo. – Vampire

Problemi correlati