Utilizzando GIT, come posso unire selettivamente le modifiche di un commit su un altro "fork"?
Domanda
Prendi questo scenario:
- Decido di 'fork' una base di codice su github.com e inizio a fare la mia routine: Modifica - Commit - Push; aka hack hack hack.
- Dopo aver apportato alcune modifiche, vedo alcune modifiche apportate da un'altra persona sullo stesso progetto e mi piacciono!
- Decido di volerle unire alle mie. Il problema è che voglio solo una "porzione" di un particolare commit, tra i vari commit che ha fatto.
Quale sarebbe il metodo più efficiente per ottenere queste selezionate quantità di modifiche, unite nel mio "fork"?
Soluzione
Dopo aver trollato le onde del mondo IRC, qualcuno ha dato un'ottima soluzione:
git cherry-pick SHA1 --no-commit
git add --patch
Speriamo che aiuti chiunque altro con la stessa domanda!
EDIT: OK, forse non è così semplice. Ecco i passaggi completi:
-
Per prima cosa devi essere nel tuo repository, fai il
cd
necessario per accedere alla tua directory di lavoro. -
Ora è necessario aggiungere il ramo remoto, quindi recuperarlo. Fallo da:
git remote aggiungi someUser git: //github.com/someUser/someRepo.git
git fetch someUser
-
Ora puoi eseguire comandi come
git log someUser / master
per trovare il commit SHA1 che vuoi unire in 'parzialmente'. -
Una volta che hai SHA, ora puoi eseguire:
git cherry-pick -n SHA1
dove
SHA1
è il commit SHA, duh! -
Probabilmente ci saranno conflitti, a seconda di quanti anni ha il commit e con quale frequenza cambia quella particolare area del progetto. Siamo spiacenti, ma devi risolverli manualmente con il tuo fidato editor. Quindi tira fuori VIM, o qualsiasi altra cosa usi, e scappa via dai conflitti fino a quando non arrivi sul palco in cui ti piacciono i cambiamenti.
-
Ora devi reimpostare l'indice sulla revisione HEAD, quindi puoi utilizzare il fidato GIT
aggiungi --patch
per selezionare e scegliere quali modifiche desideri:git reset HEAD
git add --patch
ogit add -p
-
Yay! Tempo di commit:
git commit -m " Ho unito un numero selezionato di modifiche "
-
Per ripulire il disordine (le cose a cui hai detto di no in
git add --patch
) e mantenere solo le modifiche selezionate nel tuo repository funzionante, esegui:git reset --hard HEAD
Apparentemente
git checkout -f
è anche un'altra opzione.
Altri suggerimenti
Non sono chiaro su quello che vuoi. Se vuoi ottenere solo alcuni commit dagli altri fork, puoi usare git cherry-pick SHA
. Spiegazione completa su gitready .
Mi piace molto la soluzione di Tim, tuttavia a volte mi piace armeggiare con Vimdiff. La mia soluzione a questo problema è rozza, ma funziona per me perché mi piace vim.
Ho impostato vimdiff come mio difftool, e quindi per unire selettivamente ho diff il ramo:
git difftool <branch> <file>
Quindi vado nel riquadro con la versione del ramo corrente e modifico l'originale in vim (a volte questo non è necessario, ma a volte vimdiff apre una versione in / tmp) e disabilito la modalità di sola lettura:
:e <file>
:set readonly!
Ora posso usare gli strumenti patch di vim come do
e dp
per applicare ciò che voglio e fare altre piccole modifiche mentre procedo. Quando ho finito, salvo il file, esco da vim, quindi metto in scena e commetto il file in git come una normale modifica.
Come ho detto, questo non è particolarmente sofisticato, ma è molto potente e puramente nella riga di comando. Assicurati solo di aggiungere un chiaro messaggio di commit, poiché git non includerà automaticamente un messaggio di unione per te.
Se vuoi solo una porta di un commit, probabilmente stai meglio con la scelta del commit che desideri e reimpostando i file che non vuoi toccare.
git cherry-pick SHA1
git checkout HEAD file1 file2 ... fileN
Naturalmente, se in un file sono presenti più parti modificate e si desidera conservarne solo alcune, non si ha altra scelta che modificare il file manualmente, tagliandone le modifiche.