2014-11-12 19 views
10

Ho deciso di riprendere alcuni commit perché il percorso che ho seguito era sbagliato. Quindi ho controllato il commit Added cordova to .gitignore e ho apportato alcune modifiche. Come illustrato di seguito:Git - Crea local HEAD il nuovo master

enter image description here

Ora, quando ho spingo le nuove modifiche, un messaggio di errore si presenta:
error: src refspec (detached from aad6423) does not match any.

Come posso dire a git a scartare i commit precedenti (in viola) e continuare con il mio capo locale come maestro?

+1

Se si sta lavorando con altre persone, il modo corretto di gestirlo sarebbe probabilmente quello di ripristinare le modifiche in cima a 'master'. vedi http://stackoverflow.com/a/1470452/671543 – njzk2

+0

possibile duplicato di [Git: sposta il puntatore del ramo su commit diverso] (http://stackoverflow.com/questions/5471174/git-move-branch-pointer-to -different-commit) –

+0

Ancora un altro compito semplice reso difficile da Git. Gli sviluppatori Git devono utilizzare Stack Overflow come feedback nel loro ciclo SDLC. Hanno bisogno di assumere un esperto di UX perché chiaramente non possono farlo da soli. – jww

risposta

10

Anche se non si desidera più quel vecchio ramo, a Git non piace davvero riscrivere la cronologia o scartare le modifiche. Basta ripristinare e unire.

git branch new_master    # name current detached HEAD 
git checkout master    # switch back to master 
git revert --no-edit HEAD~4..HEAD # create commits reverting back to where the history split 
git merge new_master    # merge 
git branch -d new_master   # don't need it anymore 
+0

Penso che questa sia la risposta corretta, anche se non l'ho ancora provato. Fondamentalmente, se hai già spinto al repository remoto, puoi sovrascrivere le tue modifiche usando 'git push -f', ma questo è un po 'anti-social, specialmente se altri sviluppatori hanno già sincronizzato le tue modifiche. A questo punto, è necessario applicare una patch inversa a 'master' che ritorna al modo in cui era prima del fork, quindi applicare il nuovo commit' HEAD' a questo, quindi premere. –

+1

puoi rebase 'topic' se non ti piacciono i diamanti (o anche cherry-pick come apparentemente c'è solo 1 commit) – njzk2

+0

Ancora un altro compito semplice reso difficile da Git. Gli sviluppatori Git devono utilizzare Stack Overflow come feedback nel loro ciclo SDLC. Hanno bisogno di assumere un esperto di UX perché chiaramente non possono farlo da soli. – jww

1

Poiché si dispone di divergenza, è necessario distruggere il master remoto e spostare la versione locale. A seconda della sicurezza in atto, potresti non essere in grado di farlo. Questo ha anche altre implicazioni, a seconda di chi sta facendo il lavoro basato sul master. Dovrebbe essere fatto con estrema cautela.

git push origin :master // deletes remote master 
git push origin master // pushes local master to remote 

Un altro (probabilmente migliore) approccio sarebbe quello di ripristinare i commit da padroneggiare e commettere i ripristini (che a loro volta sono commit). Quindi seleziona il lavoro che hai svolto sul tuo locale. Innanzitutto, crea un nuovo ramo di argomenti localmente per salvare il tuo lavoro.

git checkout -b <topic_branch_name> // create new branch to save local work 
git checkout master 
git reset --hard HEAD // sync local master to remote HEAD 

git revert <last commit to master> 
git revert <second-to-last commit to master> 
... 
git revert <Added cordova to .gitignore commit> 
git push 

git cherry-pick <commit hash from topic branch commit(s)> 
+0

È necessario prima collegare 'HEAD' ... – Max

+0

Non sono sicuro di seguirlo. Forse la mia modifica aiuta a chiarire. – isherwood

+0

La tua modifica l'ha corretto con il 'checkout -b'. – Max

0

Poiché le modifiche sono state apportate a monte, l'approccio migliore consiste nel ripristinarle con un altro commit. Un commit che annullerà le modifiche. La rimozione di commit o rami da monte è pratica errata. Vedi questo answer per maggiori dettagli.

+0

@EdwardFalk Solo la push al nuovo commit non è riuscita. Ma se il ramo verrà modificato (rimuovi i commit già spinti) provocherà conflitti per tutti gli altri sviluppatori. – dan

12

venire a capo il nuovo locale master:

$ git checkout -B master 

Forza spingere le modifiche:

$ git push -f 
+0

Questo può essere pericoloso se si sta lavorando con altri. Siate consapevoli che la spinta forzata riscriverà la storia, facendo sì che altri debbano gestire la nuova storia. –

+2

@BrianJ D'accordo, la risposta di Max è ciò che dovresti fare nel 99% dei casi. Ma è così che fai esattamente ciò che l'OP ha chiesto. –

+0

Questa è per me una magia. :) Io uso Sourcetree btw. Pericoloso per gli altri, ma ho avuto lo stesso caso con OP. Avevo bisogno che il mio capo fosse il maestro. Grazie! – Glenn

0

Quindi, vorrei fare questo in un paio di passi:

git co -b new_master 

a prendi un bel riferimento a quello che vuoi che sia il nuovo maestro.

git co master ; git co -b old_master 

per mantenere un riferimento al vecchio master nel caso in cui si voglia tornare indietro o qualcosa del genere; puoi sempre eliminare quel ramo più tardi una volta che sei sicuro.

git co master ; git reset --hard new_master 

Questo resetta il capo del ramo si è in (master) per il riferimento specificato (new_master).

git push -f origin 

ciò comporterà una forzatura del nuovo ramo master sul telecomando. Si noti che questa è una pratica sbagliata se qualcun altro sta usando il repository remoto in quanto potrebbe potenzialmente interrompere i propri prelievi/prelievi.

Problemi correlati