Usando gitk log
, non sono riuscito a individuare una differenza tra i due. Come posso osservare la differenza (con un comando git o qualche strumento)?
Usando gitk log
, non sono riuscito a individuare una differenza tra i due. Come posso osservare la differenza (con un comando git o qualche strumento)?
Risposte:
Il --no-ff
flag impedisce git merge
di eseguire un "avanzamento rapido" se rileva che la tua corrente HEAD
è un antenato del commit che stai cercando di unire. Un avanzamento rapido è quando, invece di costruire un commit di unione, git sposta semplicemente il puntatore del ramo per puntare al commit in entrata. Ciò si verifica comunemente quando si esegue una git pull
senza modifiche locali.
Tuttavia, occasionalmente si desidera impedire che questo comportamento si verifichi, in genere perché si desidera mantenere una topologia di ramo specifica (ad esempio, si sta unendo un ramo di argomento e si desidera assicurarsi che appaia così quando si legge la cronologia). Per fare ciò, puoi passare la --no-ff
bandiera e lo git merge
farai sempre costruire una fusione al posto di fast-forwarding.
Allo stesso modo, se si desidera eseguire un git pull
o utilizzare git merge
per avanzare esplicitamente in avanti e si desidera salvare se non è possibile avanzare rapidamente, è possibile utilizzare il --ff-only
flag. In questo modo puoi fare regolarmente qualcosa di simile git pull --ff-only
senza pensare, e quindi se si rompe, puoi tornare indietro e decidere se vuoi unire o riformulare.
gitk
o git log --graph
che l'unione di avanzamento rapido non ha creato un commit di unione, mentre quello di non avanzamento rapido l'ha fatto.
--no-ff
da una funzionalità da sviluppare o sviluppare a master è simile a unire una richiesta pull?
--no-ff
.
Ecco un sito con una chiara spiegazione e un'illustrazione grafica dell'uso git merge --no-ff
:
Fino a quando ho visto questo, ero completamente perso con Git. L'utilizzo --no-ff
consente a qualcuno che sta esaminando la cronologia di vedere chiaramente la filiale su cui hai eseguito il checkout per lavorare. (quel link punta allo strumento di visualizzazione "network" di github) Ed ecco un altro grande riferimento con le illustrazioni. Questo riferimento integra perfettamente il primo con una maggiore attenzione a coloro che non hanno familiarità con Git.
Se sei come me, e non un Git-guru, la mia risposta qui descrive la gestione dell'eliminazione dei file dal tracciamento di git senza eliminarli dal filesystem locale, che sembra scarsamente documentato ma spesso si verifica. Un'altra nuova situazione sta ottenendo il codice attuale , che riesce ancora a sfuggirmi.
Ho aggiornato un pacchetto sul mio sito Web e ho dovuto tornare alle mie note per vedere il mio flusso di lavoro; Ho ritenuto utile aggiungere un esempio a questa risposta.
Il mio flusso di lavoro di comandi git:
git checkout -b contact-form
(do your work on "contact-form")
git status
git commit -am "updated form in contact module"
git checkout master
git merge --no-ff contact-form
git branch -d contact-form
git push origin master
Sotto: utilizzo effettivo, comprese le spiegazioni.
Nota: l'output seguente è frammentato; git è abbastanza dettagliato.
$ git status
# On branch master
# Changed but not updated:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: ecc/Desktop.php
# modified: ecc/Mobile.php
# deleted: ecc/ecc-config.php
# modified: ecc/readme.txt
# modified: ecc/test.php
# deleted: passthru-adapter.igs
# deleted: shop/mickey/index.php
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# ecc/upgrade.php
# ecc/webgility-config.php
# ecc/webgility-config.php.bak
# ecc/webgility-magento.php
Nota 3 cose sopra:
1) Nell'output puoi vedere le modifiche dall'aggiornamento del pacchetto ECC, inclusa l'aggiunta di nuovi file.
2) Notare anche che ci sono due file (non nella /ecc
cartella) che ho eliminato indipendentemente da questa modifica. Invece di confondere quelle eliminazioni di file ecc
, in seguito creerò un cleanup
ramo diverso per riflettere l'eliminazione di quei file.
3) Non ho seguito il mio flusso di lavoro! Mi sono dimenticato di Git mentre stavo cercando di far funzionare di nuovo ecc.
Sotto: piuttosto che fare tutto compreso git commit -am "updated ecc package"
normalmente, volevo solo aggiungere i file nella /ecc
cartella. Quei file eliminati non facevano parte del mio git add
, ma poiché erano già stati tracciati in git, ho bisogno di rimuoverli dal commit di questo ramo:
$ git checkout -b ecc
$ git add ecc/*
$ git reset HEAD passthru-adapter.igs
$ git reset HEAD shop/mickey/index.php
Unstaged changes after reset:
M passthru-adapter.igs
M shop/mickey/index.php
$ git commit -m "Webgility ecc desktop connector files; integrates with Quickbooks"
$ git checkout master
D passthru-adapter.igs
D shop/mickey/index.php
Switched to branch 'master'
$ git merge --no-ff ecc
$ git branch -d ecc
Deleted branch ecc (was 98269a2).
$ git push origin master
Counting objects: 22, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (14/14), 59.00 KiB, done.
Total 14 (delta 10), reused 0 (delta 0)
To git@github.com:me/mywebsite.git
8a0d9ec..333eff5 master -> master
Avendo utilizzato questo processo più di 10 volte in un giorno, ho iniziato a scrivere script batch per eseguire i comandi, quindi ho creato uno git_update.sh <branch> <"commit message">
script quasi corretto per eseguire i passaggi precedenti. Ecco la fonte Gist per quella sceneggiatura.
Invece di git commit -am
selezionare i file dall'elenco "modificato" prodotto tramite git status
e quindi incollare quelli in questo script. Ciò è avvenuto perché ho apportato dozzine di modifiche, ma volevo vari nomi di rami per aiutare a raggruppare le modifiche.
--no-ff
opzione?
Unione esplicita : crea un nuovo commit di unione. (Questo è ciò che otterrai se lo hai usato --no-ff
.)
Unione rapida in avanti: avanti rapidamente, senza creare un nuovo commit:
Rebase : stabilire un nuovo livello base:
Squash: schiaccia o schiaccia (qualcosa) con forza in modo che diventi piatto:
L' --no-ff
opzione garantisce che non si verifichi una fusione in avanti veloce e che venga sempre creato un nuovo oggetto commit . Questo può essere desiderabile se vuoi che git mantenga una cronologia dei rami delle caratteristiche.
Nell'immagine sopra, il lato sinistro è un esempio della cronologia git dopo l'uso git merge --no-ff
e il lato destro è un esempio dell'uso in git merge
cui era possibile una fusione ff.
EDIT : una versione precedente di questa immagine indicava un solo genitore per il commit unione. I commit di merge hanno più commit parent che git usa per mantenere una cronologia del "ramo delle caratteristiche" e del ramo originale. I collegamenti multipli padre sono evidenziati in verde.
Questa è una vecchia domanda, e questo è in qualche modo sottilmente menzionato negli altri post, ma la spiegazione che ha fatto questo clic per me è che le fusioni non veloci richiederanno un commit separato .
git merge --no-ff ecc
avrai semplicemente un ulteriore merge commit nel git log
for branch master. Ciò non è tecnicamente necessario nel caso in cui master stia indicando un antenato diretto del commit ecc è attivo ma specificando l'opzione --no-ff si sta forzando la creazione di quel commit di merge. Avrà il titolo:Merge branch 'ecc'
Il flag --no-ff fa sì che l'unione crei sempre un nuovo oggetto commit, anche se l'unione potrebbe essere eseguita con un avanzamento veloce. Ciò evita di perdere informazioni sull'esistenza storica di un ramo di funzionalità e raggruppa tutti i commit che insieme hanno aggiunto la funzionalità