2013-01-31 42 views
72

C'è un modo per rebase di un singolo commit da un ramo su un altro ramo?git rebase un singolo commit

così ho

-- -- -- -- -- (Master) 
      \ 
       -- -- -- -- -- XX (Feature-branch) 

e tutto quello che voglio fare è Rebase l'ultimo commit di Feature-ramo sul maestro e rollback una caratteristica-ramo commesso.

-- -- -- -- -- XX (Master) 
      \ 
       -- -- -- -- -- (Feature-branch) 

Come faccio?

+3

Se è possibile ribattere un numero qualsiasi di commit, perché si chiede di rideterminarne uno singolo? Se potessi fare domande in SO, vorrei chiedere qual è la differenza tra rebasing (un singolo commit) e cherry-picking. – Val

+1

Perché non sapevo che esistesse il cherry-picking, e "Faff about on branch", "Get request for fix on different branch", "fix it", "Commit al ramo sbagliato", "D'OH! " abbastanza che la domanda fosse utile. –

risposta

76

È possibile selezionare il carattere da XX.

git checkout master 
git cherry-pick <commit ID of XX> 

E rimuovere l'ultimo commit dal ramo di funzione con git reset.

git checkout Feature-branch 
git reset --hard HEAD^ 
+26

come può una domanda specificatamente chiamata 'git rebase ...' avere la risposta accettata che contiene un cherry-pick, che è un concetto completamente diverso ea volte di per sé considerato impuro? – Bondax

+1

Non sono sicuro se questo è rilevante, ma il commit che volevo rebase aveva alcuni file che erano stati spostati, e 'cherry-pick' li faceva apparire come se fossero stati cancellati dalla vecchia posizione e creati nella nuova posizione. Suppongo che rebase se ne sarebbe occupato, ma a questo punto ho spinto verso l'alto quindi non posso testarlo. In ogni caso, fai attenzione se hai una situazione simile. – waldyrious

+0

Nota: per spingere le modifiche in "Feature-branch" all'origine, è necessario "git push -f origine Feature-branch' poiché il proprio" Feature-branch "è considerato come 1 commit dietro l'origine/caratteristica -branch'. – jojo

51
git rebase --onto master branch~1 branch 

Questo dice "rebase la gamma di commit tra l'ultima-prima-ramo e ramo (cioè, XX commit) sulla punta del ramo principale"

Dopo questa operazione branch punta è spostata sulla commettere XX, in modo che si desidera impostare indietro con

git checkout branch 
git reset --hard [email protected]{1}^ 

che dice "resettare la punta ramo per il commit prima del suo stato precedente"

Quindi un cherry pick è una soluzione più semplice ...

+3

Questo non sembra funzionare per me, perdo i commit prima di XX e il ramo viene rebasso per padroneggiare con un singolo commit, ma non ho mai usato '--onto' prima quindi potrei fare qualcosa di sbagliato. A proposito l'OP ha detto rebase ma sembra che voglia fare un cherry-pick. – tewe

+1

mio errore, rebase sposta effettivamente il ramo su master, deve essere resettato – CharlesB

+0

Qual è la differenza pratica tra questa soluzione e [quella di tewe] (https://stackoverflow.com/a/14635752/452775)? – Lii

1

La risposta di @Charles è corretta. Ad ogni modo ho finito per usare tante volte, soprattutto a REBASE config specifica su un progetto

 
    * a8f9182 (HEAD -> production) production configuration 
    | * daa18b7 (pre) preproduction configuration 
    |/ 
    | * d365f5f (local) local configuration 
    |/ 
    * 27d2835 (dev) amazing new feature that will save the world 
* | 56d2467 (master) boring state of the art for project 
|/ 

che creo un nuovo comando per esso:

 
$ cat ~/bin/git-rebaseshot 
COMMIT=$1 
DEST=${2:-HEAD} 
git rebase ${COMMIT}^ ${COMMIT} --onto $DEST 

normalmente si desidera completare automaticamente i nomi di filiale per quel comando, quindi inserirlo di sourcing questa funzione (aggiungendo .bashrc o .profile):

 
_git_rebaseshot() 
{ 
    __gitcomp_nl "$(__git_refs)" 
} 

git completamento automatico cercherà esso

.210

è possibile utilizzare questo comando come questo:

# rebase config on prepro on actual HEAD 
$ git rebaseshot prepro 
# rebase config on local onto dev 
$ git rebaseshot local dev 
# rebase production config on master 
$ git rebaseshot pro master 

Quando si divide correttamente le caratteristiche, possibities sono infinite.

 
* a8f9182 (HEAD -> postgres) BBDD config 
* a8f9182 (local) local config 
* a8f9182 (debug) log level config 
* a8f9182 (dev) new feature 
| 

Credo che questo è ciò che quilt persone piace fare.

questo comando funzionerà comunque con qualsiasi sha/ref che fornisci:

$ git rebaseshot <Feature branch> master 
$ git rebaseshot <commit of XX> master 
+0

//, puoi collegarti a qualsiasi progetto in cui possiamo vedere questo in azione? –

+0

Per la sua natura, le filiali disponibili per rebaseshot non vengono inoltrate al di fuori del repository locale. Basta creare diversi rami sopra al master (livello log, connessione al database, configurazione) e utilizzare il comando tra di essi. È chiaro vedere l'effetto. – albfan

+0

//, ho riscontrato alcuni problemi. Ci proverò di nuovo. –

6

E 'abbastanza semplice da fare in realtà. La soluzione è eseguire un rebase interattivo e "eliminare" tutti i commit che non si desidera includere nel rebase.

git rebase -i <target_branch> dove target_branch è il ramo che si desidera rebase a

Poi si modificare il file che viene aperto e pick i commit si vuole e drop (o d in breve) tutti i commit si don' voglio portare con te.

+0

IMO è una soluzione molto migliore e in realtà risponde alla domanda. – GabrielOshiro

Problemi correlati