2013-01-15 33 views
8

Mam dwa repozytoria. Od czasu do czasu chcę scalić zawartość other w main. Jednak scalanie ignoruje usunięte pliki. Pozwól mi wyjaśnić to na przykładzie:Git ignoruje usunięty plik po scaleniu

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." 

Dodaj other do main jako pilota.

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

Scal jego zawartość.

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

Dodaje pliki poprawnie. Teraz usuń plik w other.

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

Scal zmiany w main.

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

po scaleniu git status mówi:

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

spodziewałbym scalanie usunąć two, gdyż został usunięty other. Co ja robię źle?

Odpowiedz

6

Problem w tym przypadku dotyczy używania gry squasha.

Po wykonaniu merge --squash porzuca się całą historię oddziału. Tak naprawdę nie "połączyłeś gałęzi" - właśnie zastosowałeś skondensowaną reprezentację swojej historii. Więc jeśli zrobisz później merge --squash, git ponownie aplikuje wszystkie zatwierdzenia w historii oddziału (ponieważ dwie gałęzie nie mają wspólnego przodka).

Podczas wykonywania pierwszymerge --squash tworzysz commit na main który zawiera „Tworzenie jeden, dwa, trzy”. Zatem historia main jest najpierw "utwórz cztery", a następnie "utwórz jedną, dwie i trzy".

Po wykonaniu drugiego kroku merge --squash dodajemy zatwierdzenie, które składa się z (w efekcie) "Utwórz jeden, dwa i trzy" oraz "Usuń dwa". Sieć tych dwóch zobowiązań razem (zgnieciona!) To "Utwórz jedną i trzy". Tak więc git automatycznie scala commit "Utwórz jedno i trzy" z aktualnym stanem repo - zostawiając cię z czterema obecnymi plikami. Zawartość merge powiod się automatycznie, ponieważ pliki "jeden" i "trzy" są identyczne po obu stronach.

Powinieneś używać "prawdziwych" scaleń lub zbierania wiórów zamiast zgniatania, jeśli chcesz mieć repo na bieżąco z pilotem. A merge --squash to nie to samo, co "przeglądaj wszystkie nowe zatwierdzenia w zdalnym repozytorium i włącz je tutaj".

+0

To wyjaśnienie ma sens. Chciałem przeprowadzić scalenie w squasha, aby nie zanieczyszczać historii głównej z innymi. Ale wygląda na to, że nie ma innej drogi. Dzięki za pomoc! –

+1

@GergoErdosi Jeśli chcesz * wyświetlić * historię "niezanieczyszczoną", spójrz na opcję 'first-parent' na' git log'. – Borealid

+0

Dzięki za napiwek! –

Powiązane problemy