Applicare le modifiche dal ramo b ad a, senza unire o aggiungere commit


89

Il mio scenario è che ho un ramo in cui ho apportato grandi miglioramenti al processo di compilazione (ramo A) e in un altro sto lavorando su una funzionalità non correlata (ramo B). Così ora, quando sto hackerando al ramo B, voglio inserire le cose che ho scritto nel ramo A perché voglio build più veloci e più facili. Tuttavia, non voglio "inquinare" il mio ramo B, ma solo aggiungere modifiche dal ramoA a modifiche non programmate.

Cosa ho provato (stando in piedi sul ramo B):

git merge --no-commit branchA

Non funziona perché ti mette all'interno di una fusione. Se così non fosse, sarebbe perfetto.

git checkout branchA -- .

Non funziona perché applica le modifiche tra branchA..branchB e non le modifiche master..branchA.

Qualunque altra cosa?

Modifica: Sì, le modifiche al ramo A vengono salvate. In questo esempio è presente un solo ramo con miglioramenti alla compilazione, ma potrebbero esserci fino a N rami con miglioramenti alla compilazione che desidero applicare mentre lavoro su un ramo di funzionalità.


Le modifiche su A sono già state confermate?
Theolodis

Risposte:


155

Dovevo solo fare qualcosa di simile ed ero in grado di risolverlo aggiungendo --squashal comando di unione

git merge --no-commit --squash branchA
git reset HEAD # to unstage the changes

4
Questo dovrebbe anche avere una nota esplicativa su ciò che sta facendo. Mette in scena la differenza delle modifiche dal ramoA al ramo attuale
KareemElashmawy

diciamo che ho appena unito il codice da branchA a master ma ho dimenticato qualcosa e voglio aggiungere qualche altro codice / modifiche a questo commit di unione senza apparire come un altro commit di unione nella cronologia di git. questo metodo funzionerà?
Sushmit Sagar

@Sushmit Penso che tu possa fare un git commit —amende aggiungerà le nuove modifiche all'ultimo commit, solo che non sono del tutto sicuro se funziona sui commit di unione
guilffer

1
Non credo che --no-commit sia necessario qui? Dovrebbe essere l'impostazione predefinita.
Petter

11

cherry-pick -n dovrebbe fare quello che vuoi, ma non sono sicuro del motivo per cui vuoi che i miglioramenti alla build siano modifiche non in scena - questo rende solo molte cose più difficili (ad esempio unire altre modifiche ai file modificati o ribasare qualsiasi cosa).

In questo esempio è presente un solo ramo con miglioramenti alla compilazione, ma potrebbero esserci fino a N rami con miglioramenti alla compilazione che desidero applicare mentre lavoro su un ramo di funzionalità.

In tal caso creerei un nuovo ramo, C, che unisci sia da A che da B (e da qualsiasi altro ramo con miglioramenti di build). Esegui il commit delle modifiche sul ramo della funzionalità, B, quindi uniscile al ramo C, che ora contiene i miglioramenti della build e le modifiche del ramo della funzionalità, in modo da poterli testare insieme. Se hai bisogno di apportare più modifiche, fallo nel ramo appropriato, non in C, quindi unisci a C. Quindi non cambiare mai nulla nel ramo C, usalo semplicemente per integrare le modifiche da altri rami.

Ciò significa che puoi usare tutte le funzionalità di Git nel ramo C, invece di destreggiarti con modifiche non confermate in un albero sporco.


UseCase for cherry-pick -n: ho creato una copia funzionante del mio codice aggiungendo molte cose in posti casuali. Ora voglio pulire il mio codice prima di impegnarmi nel ramo di questa funzionalità. Quindi passo a un ramo temporaneo, eseguo tutte le modifiche. Torna al ramo delle funzionalità, cherry-pickquel commit. C'è un modo migliore per farlo?
Tejas Kale

6

Dovresti essere in grado di selezionare i commit (con -nper evitare di eseguire il commit immediatamente).


-N non ha funzionato. Dice che l'opzione no -m data il commit cherry-pick non è riuscita.
Alejandro Sanz Díaz

5

Non sono sicuro al 100% di averlo capito chiaramente, ma nel mio caso ho appena creato patch diff tra i rami e poi applicato questo percorso sul ramo B.

All'interno del ramo A:

 git diff branchA..branchB > patch.diff
 git apply patch.diff

4

Non sono sicuro di aver compreso le tue esigenze.

Puoi eseguire un'unione, quindi chiamare git reset HEAD~1.


La seguente sequenza dovrebbe riprodurre ogni commit tra mastere branchAsopra branchB. I commit già applicati branchBverranno ignorati.

# start from branchA
git checkout branchA
# create a temporary branch wip
git checkout -b wip
# use rebase to replay each commit between master and wip on branchB
git rebase --onto branchB master wip

# if you want to remove all the commit history and only keep the resulting diffs,
# use git reset
git reset branchB

# change the active branch
git checkout branchB
# remove temp branch
git branch -d wip

Ciò aggiunge file all'area di staging di git che non voglio. Inoltre, sembra funzionare bene solo quando tutti i rami sono ramificati dallo stesso commit sul ramo master. In caso contrario, vengono introdotti diff non compresi nell'intervallo master..branchA.
Björn Lindqvist

@ BjörnLindqvist: rimuovi l' --softopzione se non vuoi i cambiamenti nell'area di scena. Potresti disegnare un grafico di come sono impostati i tuoi rami?
LeGEC
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.