Git e "Il ramo 'x' non è completamente unito" Errore


294

Ecco i comandi che ho usato dal ramo principale

git branch experiment
git checkout experiment

Quindi ho apportato alcune modifiche ai miei file, ho eseguito il commit delle modifiche e ho inviato il nuovo ramo a GitHub.

git commit . -m 'changed files'
git push -u origin experiment

Successivamente ho deciso di unire il mio ramo di esperimento nel ramo principale.

git checkout master
git merge experiment

Alla fine ho inviato le modifiche a GitHub.

git push -u origin master

Tutto è andato bene fino a quando ho provato a cancellare il mio ramo di esperimento usando

git branch -d experiment

Ho ricevuto il messaggio di errore error: The branch 'experiment' is not fully merged.Sono un po 'nuovo da git e non so quanto potrei unire i due rami. Cosa mi sto perdendo qui?



2
Questo git commit --amend
succede

12
Inoltre, tieni presente che questo messaggio verrà visualizzato dopo squash: stackoverflow.com/q/41946475/109941
Jim G.

Penso che lo scenario più comune sia, devi solo estrarre le modifiche appena unite prima di eliminare il ramo localmente.
RaisinBranCrunch

Risposte:


313

Nota La formulazione è cambiata in risposta ai commenti. Grazie @slekse
Questo non è un errore, è un avvertimento. Significa che la filiale che stai per eliminare contiene commit che non sono raggiungibili da nessuno dei suoi: la sua filiale a monte, o HEAD (revisione attualmente verificata). In altre parole, quando potresti perdere i commit¹.

In pratica significa che probabilmente hai modificato, riformulato o filtrato i commit e non sembrano identici.

Pertanto, è possibile evitare l'avviso controllando un ramo che contiene i commit di cui si sta facendo riferimento a un riferimento eliminando l'altro ramo.²

Dovrai verificare che in realtà non ti manchi alcun impegno vitale:

git log --graph --left-right --cherry-pick --oneline master...experiment

Questo ti darà un elenco di tutti i non condivisi tra i rami. Nel caso in cui tu sia curioso, potrebbe esserci una differenza senza --cherry-picke questa differenza potrebbe essere il motivo dell'avviso che ricevi:

--cherry-pick

Omettere qualsiasi commit che introduce la stessa modifica di un altro commit sull'altro lato quando l'insieme di commit è limitato con una differenza simmetrica. Ad esempio, se hai due rami, A e B, un modo normale per elencare tutti i commit su un solo lato è con --left-right, come nell'esempio sopra nella descrizione di quell'opzione. Mostra comunque i commit che sono stati raccolti in ciliegio dall'altro ramo (ad esempio, "3 ° su b" può essere scelto in ciliegia dal ramo A). Con questa opzione, tali coppie di commit sono escluse dall'output.


¹ sono in realtà solo rifiuti raccolti dopo un po ', per impostazione predefinita. Inoltre, il git-branchcomando non controlla l'albero di revisione di tutti i rami . L'avvertimento è lì per evitare errori evidenti.

² (La mia preferenza qui è forzare invece la cancellazione, ma potresti voler avere la sicurezza in più).


24
Grazie. La frase chiave era "contiene commit che non sono raggiungibili da nessun'altra testa di riferimento". Anche se non avevo più bisogno del ramo dell'esperimento e l'avevo già unito al master e avevo pianificato di eliminarlo dall'origine, Git non sarebbe stato felice fino a quando non avessi spinto le modifiche per sperimentare sull'origine. Immagino che questo avvertimento fosse una specie di controllo di sanità mentale.
Mellowsoon,

35
-1 "Significa che la filiale che stai per eliminare contiene commit che non sono raggiungibili da nessun'altra testa di riferimento." Questo non è corretto L'avvertimento indica che il ramo non è raggiungibile né dal suo monte (se ne ha uno), né dal HEAD corrente. Vedi la manpage di git-branch.
sleske,

3
@TachyonVortex Nice link. Il comando git branch -vv ha chiarito davvero cosa stava succedendo per me.
Jason Massey,

11
@sleske Grazie per il commento: questa risposta dovrebbe davvero essere modificata. È un peccato che sia altamente votato perché la frase esplicativa principale non è corretta. Ho appena avuto questo problema e ho passato molto tempo a cercare di capire quale fosse il problema, ed era solo che il ramo di tracciamento remoto era stato cancellato come parte della richiesta pull e nel tempo da quando avevo estratto le modifiche dal master sulla filiale locale. L'unico "problema" non era trovare il ramo di tracciamento remoto, che è stato eliminato (e stavo cercando di eliminare il ramo locale per lo stesso motivo).
ely,

3
Sì, questo può accadere semplicemente quando si tenta di eliminare un ramo locale se ci si trova in un ramo diverso da quello in cui si trovava al momento della creazione. "Impegni che non sono raggiungibili da nessun altro riferimento" è errato e inutilmente spaventoso!
Amalgovinus,

80

Come ha sottolineato Drew Taylor, la cancellazione del ramo con -d considera solo l' attuale HEAD nel determinare se il ramo è "completamente unito". Si lamenterà anche se il ramo viene unito a qualche altro ramo. Il messaggio di errore potrebbe essere sicuramente più chiaro a questo proposito ... Puoi controllare il ramo unito prima di cancellare, o semplicemente usare il ramo git -D. Il capitale -D sovrascriverà completamente l'assegno.


2
La parte sull'attuale HEAD l'ha riparata per me. Il mio master era diverso dal ramo delle funzioni di cui ho creato il ramo in conflitto: D
viki.omega9

1
Per qualcuno che impara Git, la parola "attuale" sembra ridondante con "HEAD"? Non esiste una HEAD non corrente: HEAD per definizione è il ramo corrente . Mi sto perdendo qualcosa? Suppongo che potresti dire "ramo corrente" o "HEAD" ma non "HEAD corrente".
Mark Lakata,

Esiste un modo per cambiarlo / configurarlo (ad esempio, è sempre necessario verificare origin/master?) Immagino che il check out origin/masterprima non sia troppo oneroso, ma sembra solo una sorta di flusso strano - perché devo fare il check out a origin/masterlivello locale solo per te per verificare che le mie modifiche siano unite lì?
Alec,

15

Ho provato la risposta di sehe e non ha funzionato.

Per trovare i commit che non sono stati uniti basta usare:

git log feature-branch ^master --no-merges

14

Mi è successo questo oggi, mentre stavo fondendo il mio primo ramo di funzionalità in Master. Come alcuni hanno detto in un thread altrove su SO, il trucco stava tornando al master prima di provare a eliminare il ramo. Una volta tornato nel master, git era felice di eliminare il ramo senza alcun avviso.


7
Non sembra che questo sia il problema specifico qui, ma ho riscontrato il problema che descrivi proprio ora, quindi grazie!
Daniel Buckmaster,

4

Git avverte che potresti perdere la cronologia eliminando questo ramo. Anche se in realtà non eliminerebbe alcun commit immediatamente, alcuni o tutti i commit sul ramo diventerebbero irraggiungibili se non facessero parte di un altro ramo.

Affinché il ramo experimentsia "completamente unito" in un altro ramo, il commit della punta deve essere un antenato della punta dell'altro ramo, effettuando i commit in experimentun sottoinsieme dell'altro ramo. Ciò rende sicuro l'eliminazione experiment, poiché tutti i suoi commit rimarranno parte della cronologia del repository tramite l'altro ramo. Deve essere "completamente" unito, perché potrebbe essere stato già unito più volte, ma ora sono stati aggiunti commit dall'ultima unione che non sono contenuti nell'altro ramo.

Git, tuttavia, non controlla tutti gli altri rami nel repository; solo due:

  1. L'attuale ramo (HEAD)
  2. Il ramo a monte, se ce n'è uno

Il "ramo a monte" per experiment, come nel tuo caso, è probabilmente origin/experiment. Se experimentviene completamente unito nel ramo corrente, Git lo elimina senza alcun reclamo. Se non lo è, ma è completamente unito nel suo ramo a monte, allora Git procede con un avviso che sembra:

warning: deleting branch 'experiment' that has been merged
to 'refs/remotes/origin/experiment', but not yet merged to
HEAD.
Deleted branch experiment (was xxxxxxxx).

Dove xxxxxxxxindica un ID di commit. La fusione completa a monte indica che gli commit experimentsono stati trasferiti nel repository di origine, in modo che, anche se li perdi qui, possano almeno essere salvati altrove.

Poiché Git non controlla altri rami, potrebbe essere sicuro eliminare un ramo perché sai che è completamente unito in un altro; puoi farlo con l' -Dopzione come indicato o passare prima a quel ramo e lasciare che Git confermi lo stato completamente unito per te.


1
La chiave è "completamente unita nel ramo corrente ". Ho avuto un ramo X 'da X completamente ricollegato in X e avevo già eliminato origin / X'. Ma con Y verificato ho ricevuto questo avviso. Quando ho verificato XI sono stato in grado di eliminare X '. È piuttosto stupido, penso.
Lawrence Dol

2
Questa risposta è plagiata da qui senza attribuzione chimera.labs.oreilly.com/books/1230000000561/…
Mark Lakata,

3

per vedere i cambiamenti che non sono stati uniti, ho fatto questo:

git checkout experiment
git merge --no-commit master

git diff --cached

Nota: mostra le modifiche masterche non sono presenti experiment.

Non dimenticare di:

git merge --abort

Quando hai finito, cerca.


@IgorGanapolsky Non so esattamente, anche se di solito man git-reseti comandi git reset sono sufficienti per recuperare da problemi di stato.
ThorSummoner,

3

Soluzione più semplice con spiegazione (soluzione ricontrollata) (affrontato il problema prima)

Il problema è:

1- Non riesco a cancellare un ramo

2- Il terminale continua a visualizzare un messaggio di avviso che indica che alcuni commit non sono ancora stati approvati

3- sapendo che ho controllato il master e il ramo e sono identici (aggiornati)

soluzione:

git checkout master
git merge branch_name
git checkout branch_name
git push
git checkout master
git branch -d branch_name

Spiegazione:

quando il tuo ramo è connesso al ramo remoto a monte (su Github, bitbucket o altro), devi unirlo (spingerlo) nel master e devi spingere le nuove modifiche (commit) nel repository remoto (Github, bitbucket o qualunque cosa) dal ramo,

quello che ho fatto nel mio codice è che sono passato al master, quindi ho unito il ramo in esso (per assicurarmi che siano identici sul tuo computer locale), quindi sono passato di nuovo al ramo e ho inviato gli aggiornamenti o le modifiche al telecomando online repo usando "git push".

successivamente, sono passato di nuovo al master e ho provato a eliminare il ramo e il problema (messaggio di avviso) è scomparso e il ramo è stato eliminato correttamente


3

Puoi semplicemente capire:

git log --cherry master ... sperimentale

--cherry opzione è sinonimo di --right-only --cherry-mark --no-merges

ha detto la pagina man di git-log

è utile limitare l'output ai commit dalla nostra parte e contrassegnare quelli che sono stati applicati all'altro lato di una storia biforcuta con git log --cherry upstream ... mybranch, simile a git cherry upstream mybranch.

FYI. --cherry-pickomette commit equivalenti ma --cherry-marksnon lo fa. È utile trovare rebase e forzare le modifiche aggiornate tra le filiali pubbliche a monte e quelle che collaborano


1

Non avevo il ramo a monte sul mio git locale. Avevo creato una filiale locale dal master, git checkout -b mybranch. Ho creato un ramo con GUI bitbucket sul git upstream e ho spinto il mio ramo locale (mybranch) a quel ramo upstream. Una volta che ho fatto un recupero git sul mio git locale per recuperare il ramo a monte, ho potuto fare un ramo git -d mybranch.


0

Credo che la bandiera --forcesia ciò che stai davvero cercando. Basta usare git branch -d --force <branch_name>per eliminare forzatamente il ramo.

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.