Mi sto unendo in un ramo remoto che potrebbe avere molti conflitti. Come posso sapere se ci saranno conflitti o no?
Non vedo niente di simile a un --dry-run
on git-merge
.
Mi sto unendo in un ramo remoto che potrebbe avere molti conflitti. Come posso sapere se ci saranno conflitti o no?
Non vedo niente di simile a un --dry-run
on git-merge
.
Risposte:
Come notato in precedenza, passa la --no-commit
bandiera, ma per evitare un commit ad avanzamento rapido, passa anche in questo --no-ff
modo:
$ git merge --no-commit --no-ff $BRANCH
Per esaminare le modifiche organizzate:
$ git diff --cached
E puoi annullare l'unione, anche se si tratta di un'unione con avanzamento rapido:
$ git merge --abort
git merge --only-if-there-wont-be-any-conflicts
o git diff --show-conflicts <commit>
sarebbe davvero utile. Peccato che non sia ancora possibile o mi sto perdendo qualcosa?
git pull --ff-only
!
Ho dovuto solo implementare un metodo che trova automaticamente conflitti tra un repository e il suo telecomando. Questa soluzione esegue l'unione in memoria in modo che non tocchi l'indice né l'albero di lavoro. Penso che questo sia il modo più sicuro possibile per risolvere questo problema. Ecco come funziona:
git fetch origin master
git merge-base FETCH_HEAD master
git merge-tree mergebase master FETCH_HEAD
( mergebase è l'id esadecimale che merge-base stampato nel passaggio precedente)Supponiamo ora che tu voglia unire il master remoto con il tuo master locale, ma puoi usare tutti i rami. git merge-tree
eseguirà l'unione in memoria e stamperà il risultato sull'output standard. Grep per il modello <<
o >>
. Oppure puoi stampare l'output su un file e verificarlo. Se trovi una riga che inizia con "cambiato in entrambi", molto probabilmente ci sarà un conflitto.
git merge-tree `git merge-base FETCH_HEAD master` FETCH_HEAD master
git merge-tree `git merge-base clieop master` clieop master | grep -A3 "changed in both"
semplicemente fantastica! +100
+<<<<<<< .our
modo:, quindi uso un'espressione grep comegrep -q '^+<* \.our$'
La mia semplice soluzione a forza bruta a questo è:
Crea un ramo "pre-master" (dal master ovviamente)
Unisci tutte le cose che vuoi in questo pre-master.
Quindi puoi vedere come è avvenuta la fusione senza toccare il master.
Ad ogni modo, seguirei i consigli di @ orange80.
git merge --abort
se ci sono conflitti, git reset --hard HEAD~1
se c'è stata un'unione o git reset --hard origin/master
. La creazione di un altro ramo ti dà una sensazione di sicurezza ma se impari come funziona git capirai che è una paura fuori posto. Quando la preoccupazione è di non modificare la copia di lavoro, ciò non offre alcuna soluzione.
git merge --no-commit
non interromperà un'unione se può essere inoltrato rapidamente. git merge --abort
non funziona se è stato unito. Se vuoi scrivere questo come uno script, è imbarazzante, dal momento git merge
che non risponde con abbastanza buoni codici di errore per spiegare i diversi tipi di conflitti. Lavorare con un nuovo ramo impedisce a uno script interrotto di lasciare il repository in uno stato che richiede un intervento manuale. Sicuro che non puoi perdere nulla. Ma è più facile costruire diversamente.
Annullare un'unione con git è così facile che non dovresti nemmeno preoccuparti della corsa a secco:
$ git pull $REMOTE $BRANCH
# uh oh, that wasn't right
$ git reset --hard ORIG_HEAD
# all is right with the world
MODIFICA: Come notato nei commenti qui sotto, se hai cambiamenti nella directory di lavoro o nell'area di gestione temporanea, probabilmente vorrai riporli prima di fare quanto sopra (altrimenti scompariranno seguendo quanto git reset
sopra)
git branch --contains HEAD
o anche più direttamente, basta usaregit merge --ff-only
--dry-run
non "controllerebbe semplicemente se un'unione avanza rapidamente". Restituirebbe l'output esatto di un'unione: file, conflitti ecc. Se la volontà non è davvero interessante, vero?
git stash; git reset --hard
? @BrianPhillips
Ho creato un alias per farlo e funziona come un incantesimo, lo faccio:
git config --global alias.mergetest '!f(){ git merge --no-commit --no-ff "$1"; git merge --abort; echo "Merge aborted"; };f '
Adesso chiamo e basta
git mergetest <branchname>
Per scoprire se ci sono conflitti.
Differisci il tuo ramo corrente contro il ramo remoto, questo ti dirà cosa cambierà quando fai un pull / merge.
#see diff between current master and remote branch
git diff master origin/master
Per farlo uso il comando request-pull git. Ti consente di vedere ogni cambiamento che potrebbe accadere durante l'unione, ma senza fare nulla sui tuoi repository locali o remoti .
Ad esempio, immagina di voler unire un ramo chiamato "feature-x" nel tuo ramo principale
git request-pull master origin feature-x
ti mostrerà un riepilogo di ciò che accadrebbe (senza fare nulla):
The following changes since commit fc01dde318:
Layout updates (2015-06-25 11:00:47 +0200)
are available in the git repository at:
http://fakeurl.com/myrepo.git/ feature-x
for you to fetch changes up to 841d3b41ad:
----------------------------------------------------------------
john (2):
Adding some layout
Refactoring
ioserver.js | 8 +++---
package.json | 7 +++++-
server.js | 4 +--
layout/ldkdsd.js | 277 +++++++++++++++++++++++++++++++++++++
4 files changed, 289 insertions(+), 7 deletions(-)
create mode 100644 layout/ldkdsd.js
Se aggiungi il -p
parametro, otterrai anche il testo completo della patch, esattamente come se stessi facendo un git diff su ogni file modificato.
master
e cosa origin
fare nelle opzioni della riga di comando, e se mi trovassi ad esempio in un locale branch1
e volessi fare un request-pull
ramo di una caratteristica locale branch2
? Ho ancora bisogno origin
? Certo, si può sempre leggere la documentazione.
Sono sorpreso che nessuno abbia ancora suggerito di usare le patch.
Supponiamo che desideri testare un'unione da your_branch
in master
(suppongo che tu abbia master
verificato):
$ git diff master your_branch > your_branch.patch
$ git apply --check your_branch.patch
$ rm your_branch.patch
Questo dovrebbe fare il trucco.
Se ricevi errori come
error: patch failed: test.txt:1
error: test.txt: patch does not apply
ciò significa che la patch non ha avuto successo e un'unione produrrebbe conflitti. Nessun output indica che la patch è pulita e si sarebbe in grado di unire facilmente il ramo
Nota che questo non cambierà effettivamente l'albero di lavoro (oltre a creare ovviamente il file patch, ma puoi tranquillamente eliminarlo in seguito). Dalla documentazione di git-apply:
--check
Instead of applying the patch, see if the patch is applicable to the
current working tree and/or the index file and detects errors. Turns
off "apply".
Nota a chiunque sia più intelligente / più esperto di git di me: per favore fatemi sapere se ho torto qui e questo metodo mostra un comportamento diverso rispetto a una fusione normale. Sembra strano che negli ultimi 8 anni che questa domanda non esistesse nessuno suggerirebbe questa soluzione apparentemente ovvia.
git diff master your_branch | git apply --check
.
Questo potrebbe essere interessante: dalla documentazione:
Se hai provato un'unione che ha provocato conflitti complessi e vuoi ricominciare da capo, puoi recuperare con git merge --abort .
Ma potresti anche farlo nel modo ingenuo (ma lento):
rm -Rf /tmp/repository
cp -r repository /tmp/
cd /tmp/repository
git merge ...
...if successful, do the real merge. :)
(Nota: non funzionerà solo clonando su / tmp, avresti bisogno di una copia, per essere sicuro che le modifiche non confermate non entrino in conflitto).
cp -r repository/.git /tmp/repository/.git
, cd /tmp/repository
, git reset --hard
, git add --all
, git reset --hard
(per buona misura), git status
(per controllare che è pulito).
Sono consapevole che questa è una vecchia domanda, ma è la prima a comparire su una ricerca su Google.
Git ha introdotto un'opzione --ff-only durante l'unione.
Da: http://git-scm.com/docs/git-merge
--ff-only
Rifiuta di unire ed uscire con uno stato diverso da zero a meno che l'attuale HEAD non sia già aggiornato o l'unione non possa essere risolta come avanzamento rapido.
In questo modo si tenterà di unire e avanzare rapidamente, e in caso contrario si interrompe e viene richiesto che non è possibile eseguire l'avanzamento rapido, ma che non viene toccato il ramo operativo. Se è in grado di avanzare rapidamente, eseguirà l'unione sul ramo di lavoro. Questa opzione è disponibile anche su git pull
. Pertanto, è possibile effettuare le seguenti operazioni:
git pull --ff-only origin branchA #See if you can pull down and merge branchA
git merge --ff-only branchA branchB #See if you can merge branchA into branchB
Uso git log per vedere cosa è cambiato in un ramo di funzionalità dal ramo principale
git log does_this_branch..contain_this_branch_changes
ad es. - per vedere quali sono i commit in un ramo di funzionalità che è stato / non è stato unito al master:
git log master..feature_branch
Se vuoi avanzare rapidamente da B ad A, allora assicurati che git log B..A non ti mostri nulla, cioè che A non abbia nulla che B non abbia. Ma anche se B..A ha qualcosa, potresti comunque essere in grado di unire senza conflitti, quindi quanto sopra mostra due cose: che ci sarà un avanzamento veloce e quindi non otterrai un conflitto.
La mia soluzione è unire all'indietro.
Invece di unire il tuo ramo nel ramo "target" remoto, unisci quel ramo nel tuo.
git checkout my-branch
git merge origin/target-branch
Vedrai se ci sono conflitti e puoi pianificare come risolverli.
Dopodiché puoi annullare l'unione tramite git merge --abort
o (se non ci sono stati conflitti e se si è verificata l'unione) tornare indietro al commit precedente tramitegit reset --hard HEAD~1