Git ignora il file eliminato all’unione

Ho due repository. Di volta in volta, voglio unire il contenuto other in main . Tuttavia l’unione ignora i file cancellati. Lascia che ti spieghi attraverso un esempio:

 mkdir -p test/main test/other cd test/other/ git init touch one two three git add . git commit -m "Add one, two and three." cd ../main/ git init touch four git add . git commit -m "Add four." 

Aggiungi other al main come remoto.

 git remote add other ../other/ git fetch other 

Unisci il suo contenuto.

 git merge --squash other/master git commit -m "Merge other." 

Aggiunge i file correttamente. Ora, rimuovi un file in other .

 cd ../other/ git rm two git commit -m "Remove two." 

Unisci le modifiche in main .

 cd ../main/ git fetch other git merge --squash other/master 

Dopo lo stato di fusione merge dice:

 # On branch master nothing to commit (working directory clean) 

Mi aspetto che l’unione ne elimini two , poiché è stata eliminata in other . Che cosa sto facendo di sbagliato?

Il problema qui è il tuo uso di commit di squash.

Quando fai una merge --squash , abbandoni tutta la cronologia di un ramo. Non hai davvero “fuso il ramo” – hai appena applicato una rappresentazione condensata della sua storia. Quindi se fai una merge --squash successiva merge --squash , git riapplicherà tutti i commit nella cronologia del ramo (dato che i due rami non hanno antenato comune).

Quando esegui la prima merge --squash , crei un commit sul main che contiene “Crea uno, due e tre”. Quindi la cronologia di main è prima “create four”, quindi “create uno, due e tre”.

Quando merge --squash la seconda merge --squash , aggiungi un commit che consiste (in effetti) in “Crea uno, due e tre” più “Rimuovi due”. La rete di questi due commit insieme (schiacciati!) È “Crea uno e tre”. Quindi git unisce automaticamente il commit “Crea uno e tre” con il tuo attuale stato repo, lasciandoti con quattro file presenti. L’unione dei contenuti ha esito positivo perché i file “uno” e “tre” sono identici su entrambi i lati.

È necessario utilizzare “reali” unioni o cherry-picking anziché lo schiacciamento se si desidera mantenere aggiornato un repository con un telecomando. merge --squash non è la stessa cosa di “riprodurre tutti i nuovi commit in un repository remoto e integrarli qui”.