Come sostituire la filiale locale con la filiale remota interamente in Git?


779

Ho due rami:

  1. filiale locale (quella con cui lavoro)
  2. filiale remota (pubblica, solo commit ben testati vanno lì)

Di recente ho seriamente incasinato la mia filiale locale.

Come sostituirei completamente la filiale locale con quella remota, in modo da poter continuare il mio lavoro da dove si trova ora la filiale remota?

Ho già cercato SO e il check-out sul ramo remoto localmente non ha alcun effetto.


1
So che la risposta accettata ha 1280 voti positivi, ma dovresti davvero considerare di cambiare la risposta accettata con quella di @TTT.
Jamie

Risposte:


1289
  1. Assicurati di aver verificato il ramo che stai sostituendo (dal commento di Zoltán ).
  2. Supponendo che il master sia il ramo locale che stai sostituendo e che "origin / master" sia il ramo remoto su cui vuoi reimpostare:

    git reset --hard origin/master
    

Questo aggiorna il tuo ramo HEAD locale in modo che sia la stessa revisione di origin / master e --hardsincronizzerà questa modifica anche nell'indice e nell'area di lavoro.


4
Grazie per il tuo suggerimento, sono così 'spaventato' di usare --hard e --force già, quindi ho appena scelto la soluzione che non usa quelli.
YemSalat,

13
@KonstantinLevin: ah sì, la denominazione di quelle opzioni è piuttosto irritante. git resetper impostazione predefinita reindirizzerà il ramo corrente e sincronizzerà l'indice. --softsalterà l'aggiornamento dell'indice, --hardsincronizzerà anche l'area di lavoro. La mia esperienza personale sta usando la --hardmaggior parte del tempo, tranne quando voglio annullare l'ultimo commit (che è giusto git reset HEAD^)
araqnid,

9
Dopo aver avuto più esperienza con Git, sono convinto che questa sia una soluzione migliore, grazie.
YemSalat l'

24
probabilmente dovrai prima prendere:git fetch origin remote_branch
b1r3k

53
Dovresti notare che questo sostituirà qualunque ramo in cui ti trovi attualmente con i contenuti di master . Quindi, se ti trovi ad es. In un ramo di funzionalità, sostituirà tutti i suoi commit master, quindi assicurati di aver estratto il ramo che stai sostituendo per primo.
Zoltán,

218

È facile come tre passaggi:

  1. Elimina la tua filiale locale: git branch -d local_branch
  2. Scarica l'ultimo ramo remoto: git fetch origin remote_branch
  3. Ricostruire il ramo locale basato su quello remoto: git checkout -b local_branch origin/remote_branch

7
In realtà quello che @araqnid ha detto è giusto e più conciso. L'ho provato e potresti provarlo anche tu.
Adamsmith,

Wow, il checkout git -b local_branch origin / remote_branch è fantastico! L'ho sempre fatto in due comandi separati. Grazie!
Kendepelchin,

11
Potrebbe essere necessario eseguire git branch -D local_branchla prima operazione se il ramo non viene unito.
szeryf,

grazie, ho avuto difficoltà a usare gitflow, dopo aver pubblicato un ramo e dopo averlo finito, volevo andare al ramo cancellato, e la tua soluzione era l'unica che ha funzionato, pull non sembra funzionare .. oppure devo non l'ho usato bene -
Decebal

2
dovremmo assicurarci che l'attuale ramo non sia quello che deve essere cancellato.
a_secenthusiast

43
git branch -D <branch-name>
git fetch <remote> <branch-name>
git checkout -b <branch-name> --track <remote>/<branch-name>

Cosa fa la parte --track?
eonista l'

3
@GitSync, questo è ciò che git help branchdice --track. When creating a new branch, set up branch.<name>.remote and branch.<name>.merge configuration entries to mark the start-point branch as "upstream" from the new branch. This configuration will tell git to show the relationship between the two branches in git status and git branch -v. Furthermore, it directs git pull without arguments to pull from the upstream when the new branch is checked out. Ho risolto questo comando nella risposta. Grazie per aver sollevato il punto.
Sailesh,

Quindi in parole povere: aggiunge l'URL remoto al nuovo ramo. Quindi sono sincronizzati per sempre. Per così dire.
eonista

2
Puoi dire che è solo per comodità. Se lo fai git status, segnalerà se la tua filiale locale è avanti o dietro la filiale remota se li hai associati. Inoltre, puoi fare git pull(o push) invece del pieno git pull <remote> <branch>se hai già impostato il tuo ramo per tenere traccia <remote/branch>.
Sailesh,

22

Sostituisci tutto con il ramo remoto; ma solo dallo stesso commit è attiva la tua filiale locale:

git reset --hard origin/some-branch

OPPURE , ottieni le ultime novità dalla filiale remota e sostituisci tutto:

git fetch origin some-branch
git reset --hard FETCH_HEAD

A parte, se necessario, puoi cancellare file e directory non tracciati che non hai ancora eseguito il commit:

git clean -fd

Il git cleancomando l'ha fatto per me. git reset hard origin/masternon cancellare i file non tracciati. Grazie!
Mornor,

9

Il modo più sicuro e completo per sostituire l'attuale filiale locale con il telecomando:

git stash
git merge --abort
git rebase --abort
git branch -M yourBranch replaced_yourBranch
git fetch origin yourBranch:yourBranch
git checkout yourBranch

La stashriga salva le modifiche che non hai eseguito il commit. La branchlinea sposta il tuo ramo su un nome diverso, liberando il nome originale. La fetchriga recupera l'ultima copia del telecomando. La checkoutlinea ricrea il ramo originale come ramo di tracciamento.

O come una funzione bash:

replaceWithRemote() {
    yourBranch=${1:-`git rev-parse --abbrev-ref HEAD`}
    git stash
    git merge --abort
    git rebase --abort
    git branch -M ${yourBranch} replaced_${yourBranch}_`git rev-parse --short HEAD`
    git fetch origin ${yourBranch}:${yourBranch}
    git checkout ${yourBranch}
}

che rinomina il ramo corrente in qualcosa come sostituito_master_98d258f.


Potrebbe voler includere git stash popin quel flusso di lavoro. Se si desidera riapplicare i file memorizzati.
eonista l'

Cosa fai con il ramo nascosto? Temo che riapparirà da qualche parte in futuro molto tempo dopo che avrò dimenticato a cosa servisse.
Scott Biggs,

1
@ScottBiggs Se vuoi rimuovere il ramo nascosto, usa "git stash clear".
Mark A. Durham,

5

Sono un po 'sorpreso che nessuno lo abbia ancora menzionato; Lo uso quasi ogni giorno:

git reset --hard @{u}

Fondamentalmente, @{u}è solo una scorciatoia per il ramo a monte che il tuo ramo attuale sta seguendo. Ad esempio, questo equivale in genere a origin/[my-current-branch-name]. È bello perché è indipendente dal ramo.

Assicurarsi git fetchinnanzitutto di ottenere l'ultima copia del ramo remoto.


1
sembra davvero bello, mi sono stancato di copiare e incollare il nome del ramo per ripristinare!
pedroct92,

1
Ho avuto alcuni casi in cui ho aggiunto le risposte a vecchie domande e le mie risposte sono salite in cima alla classifica. Spero che questo lo faccia.
Jamie

3

Può essere fatto in diversi modi, continuando a modificare questa risposta per diffondere una migliore prospettiva di conoscenza.

1) Ripristina difficile

Se stai lavorando dal ramo di sviluppo remoto, puoi ripristinare HEAD all'ultimo commit sul ramo remoto come di seguito:

git reset --hard origin/develop

2) Elimina il ramo corrente ed esegui nuovamente il checkout dal repository remoto

Considerando che stai lavorando allo sviluppo del ramo nel repository locale, che si sincronizza con il ramo remoto / sviluppo, puoi fare come di seguito:

git branch -D develop
git checkout -b develop origin/develop

3) Annulla unione

Se sei nel mezzo di una cattiva unione (erroneamente eseguita con un ramo sbagliato) e volevi evitare l'unione per tornare al ramo più recente come di seguito:

git merge --abort

4) Annulla rebase

Se si è in mezzo a un rebase errato, è possibile interrompere la richiesta di rebase come di seguito:

git rebase --abort

2

Puoi fare come ha detto @Hugo di @Laurent, oppure puoi usare git rebaseper eliminare i commit che vuoi eliminare, se sai quali. Tendo a usare git rebase -i head~N(dove N è un numero, permettendoti di manipolare gli ultimi N commit) per questo tipo di operazioni.


In realtà è stato il comando 'git rebase' che ha incasinato il tutto, quindi alcune fusioni forzate e ripristini forzati .. Comunque, quello che stavo cercando è solo un modo semplice per estrarre l'intero repo dal server remoto senza unire.
YemSalat,

2

La risposta selezionata è assolutamente corretta , tuttavia non mi ha lasciato con gli ultimi commit / push ...

Quindi per me:

git reset --hard dev/jobmanager-tools
git pull  ( did not work as git was not sure what branch i wanted)

Dal momento che so che voglio impostare temporaneamente il mio ramo upstream per alcune settimane su un ramo specifico (lo stesso di quello in cui sono passato / verificato in precedenza e ho effettuato un hard reset)

Quindi dopo il reset

git branch --set-upstream-to=origin/dev/jobmanager-tools
git pull
git status    ( says--> on branch  dev/jobmanager-tools 

1

Se vuoi aggiornare un ramo che non è attualmente estratto puoi fare:

git fetch -f origin rbranch:lbranch

0

Come indicato nella spiegazione scelta, git reset è buono. Ma oggigiorno utilizziamo spesso sottomoduli: repository all'interno di repository. Ad esempio, se usi ZF3 e jQuery nel tuo progetto, molto probabilmente vorrai che vengano clonati dai loro repository originali. In tal caso, git reset non è sufficiente. Dobbiamo aggiornare i sottomoduli con quella versione esatta definita nel nostro repository:

git checkout master
git fetch origin master
git reset --hard origin/master
git pull

git submodule foreach git submodule update

git status

è lo stesso che verrai ricorsivamente (cd) nella directory di lavoro di ciascun sottomodulo e verrà eseguito:

git submodule update

Ed è molto diverso da

git checkout master
git pull

perché i sottomoduli puntano non al ramo ma al commit.

In quei casi, quando si esegue il checkout manuale di un ramo per 1 o più sottomoduli, è possibile eseguire

git submodule foreach git pull

Fornisci una spiegazione, soprattutto quando rispondi a domande così vecchie. La tua risposta non è utile così com'è.
Erik A

La risposta accettata già propone git reset --hard. Questo aggiunge poco valore.
florisla,

0
git reset --hard
git clean -fd

Questo ha funzionato per me - clean ha mostrato anche tutti i file che ha eliminato. Se ti dice che perderai le modifiche, devi riporlo.


-6

Il modo brutto ma più semplice: elimina la cartella locale e clona nuovamente il repository remoto.


10
O semplicemente cancella il ramo e ricontrolla.
Laurent,

Sì, immagino che sia quello che farò se non trovo come farlo in un modo meno "brutto"
YemSalat

2
Brutto a volte è utile sapere. Vorrei che le persone non votassero le cose solo perché non sono il modo convenzionale: ci deve essere una ragione più razionale per il downvoting ... e dovrebbe essere dato. Git è una cosa che ottiene risultati. Non è una sorta di testo sacro.
mike rodent,

3
Non capisco i voti negativi :-( Sì, è inelegante, ecc., Ma in alcuni casi può funzionare meglio ... scusa @Hugo
silverdr,

@Hugo, d'accordo. Qualcosa di misterioso e maleodorante è successo alla mia filiale di sviluppo locale, e sia il Team Lead che il Engineering Manager hanno suggerito, tra le soluzioni più eleganti, di semplicemente (comprimere, copiare e salvare il mio lavoro di funzionalità, quindi) annotare il repository locale e richiuderlo.
AmitaiB,
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.