Uwaga: jedną z największych różnic między Git i Mercurial jest wyraźna obecność indeksu lub obszaru przejściowego .
Od Mercurial for Git User :
Git jest jedynym DistributedSCM, który ujawnia koncepcję indeksu lub obszaru przemieszczania. Inni mogą to wdrożyć i ukryć, ale w żadnym innym przypadku użytkownik nie jest tego świadomy ani nie musi sobie z tym radzić.
Zgrubnym odpowiednikiem Mercurial jest DirState
, który kontroluje informacje o statusie kopii roboczej w celu określenia plików, które mają zostać uwzględnione w następnym zatwierdzeniu. W każdym razie ten plik jest obsługiwany automatycznie.
Ponadto można być bardziej selektywnym w czasie zatwierdzania, określając pliki, które chcesz zatwierdzić w wierszu poleceń lub używając RecordExtension
.
Jeśli czułeś się nieswojo z indeksem, przechodzisz na lepsze ;-)
Rzecz w tym, że naprawdę musisz zrozumieć indeks, aby w pełni wykorzystać Git. Jak przypomina nam ówczesny artykuł z maja 2006 roku (i nadal jest prawdą):
„Jeśli zaprzeczasz Indeksowi, naprawdę zaprzeczasz samemu git”.
Ten artykuł zawiera wiele poleceń, które są teraz prostsze w użyciu (więc nie polegaj zbytnio na jego treści;)), ale ogólna idea pozostaje:
Pracujesz nad nową funkcją i zaczynasz wprowadzać drobne modyfikacje w pliku.
# working, add a few lines
$ git add myFile
# working, another minor modification
$ git add myFile
W tym momencie twój następny commit wprowadzi 2 pomniejsze modyfikacje w bieżącej gałęzi
# working, making major modification for the new features
# ... damn! I cannot commit all this in the current branch: nothing would work
$ git commit
Rejestruje tylko zmiany dodane do obszaru przemieszczania (indeksu) w tym momencie, a nie główne zmiany obecnie widoczne w katalogu roboczym.
$ git branch newFeature_Branch
$ git add myFile
Następne zatwierdzenie zapisze wszystkie inne główne zmiany w nowej gałęzi „newFrature_Branch”.
Teraz dodawanie interaktywne lub nawet dzielenie zatwierdzenia są funkcjami dostępnymi w Mercurial za pomocą hg record
polecenia „ ” lub innych rozszerzeń: musisz zainstalować RecordExtension
lub CrecordExtension
.
Ale to nie jest częścią normalnego przepływu pracy dla Mercurial.
Git postrzega zatwierdzenie jako serię „ zmian zawartości pliku ” i pozwala dodawać te zmiany pojedynczo.
Powinieneś przestudiować tę funkcję i jej konsekwencje: większość mocy Git (jak możliwość łatwego cofania scalania (lub dzielenia problemu na pół lub cofania zatwierdzenia) , w przeciwieństwie do Mercuriala ) pochodzi z tego paradygmatu "zawartości pliku".
tonfa (w profilu: "Hg dev, pythonist": dane ...) włączył się, w komentarzach:
W indeksie nie ma nic "git-ish", hg może użyć indeksu, jeśli został uznany za wartościowy, w rzeczywistości mq
lub shelve
już robi część tego.
O chłopie. Znowu zaczynamy.
Po pierwsze, nie jestem tu po to, aby jedno narzędzie wyglądało lepiej niż inne. Uważam, że Hg jest świetny, bardzo intuicyjny, z dobrym wsparciem (szczególnie na Windowsie, mojej głównej platformie, chociaż pracuję również na Linuksie i Solaris 8 lub 10).
Indeks znajduje się w rzeczywistości z przodu i na środku, tak jak Linus Torvalds pracuje z VCS :
Git używał jawnych aktualizacji indeksu od pierwszego dnia, nawet zanim dokonał pierwszego scalenia. Po prostu zawsze tak pracowałem. Zwykle mam brudne drzewa z jakąś losową łatką w moim drzewie, której nie chcę zatwierdzać, ponieważ jest to tylko aktualizacja Makefile dla następnej wersji
Teraz połączenie indeksu (co nie jest pojęciem widzianym tylko w Git) i paradygmatu „content is king” sprawia, że jest on dość wyjątkowy i „git-ish” :
git to narzędzie do śledzenia zawartości , a nazwa pliku nie ma znaczenia, chyba że jest powiązana z jego zawartością. Dlatego jedynym rozsądnym zachowaniem git add filename jest dodanie zawartości pliku, a także jego nazwy do indeksu.
Uwaga: „zawartość” jest tutaj zdefiniowana w następujący sposób :
Indeks Gita jest zasadniczo bardzo zdefiniowany jako
- wystarczające do zawarcia całej „ zawartości ” drzewa (w tym wszystkie metadane: nazwa pliku, tryb i zawartość pliku są częścią „zawartości” i wszystkie same w sobie są bez znaczenia! )
- dodatkowe informacje o statystykach umożliwiające oczywiste i trywialne (ale niezwykle ważne!) optymalizacje porównywania systemów plików.
Tak naprawdę powinien zobaczyć indeks jako istota treść .
Treść nie jest „nazwą pliku” ani „zawartością pliku” jako oddzielnymi częściami. Naprawdę nie możesz ich rozdzielić .
Same nazwy plików nie mają sensu (muszą mieć też zawartość pliku), a sama zawartość pliku jest podobnie bezsensowna (trzeba wiedzieć, jak do niej dotrzeć).
Próbuję powiedzieć, że git zasadniczo nie pozwala zobaczyć nazwy pliku bez jego zawartości. Cała koncepcja jest szalona i nieważna. Nie ma to żadnego związku z „rzeczywistością”.
Z FAQ główne zalety to:
- wykonaj z drobną szczegółowością
- pomoże ci utrzymać niezamierzoną modyfikację w twoim drzewie przez rozsądnie długi czas
- wykonaj kilka małych kroków dla jednego zatwierdzenia, sprawdzając, co zrobiłeś
git diff
i sprawdzając każdy mały krok za pomocą git add
lub git add -u
.
- umożliwia doskonałe zarządzanie konfliktami Merge:
git diff --base
, git diff --ours
, git diff --theirs
.
- pozwala
git commit --amend
na zmianę komunikatu dziennika tylko wtedy, gdy indeks nie był w międzyczasie modyfikowany
Osobiście uważam, że to zachowanie nie powinno być domyślne, chcesz, aby ludzie popełnili coś, co zostało przetestowane lub przynajmniej skompilowane
Chociaż ogólnie masz rację (jeśli chodzi o część „przetestowaną lub skompilowaną”), sposób, w jaki Git pozwala na rozgałęzianie i scalanie (wybieranie lub rebasing), pozwala na zatwierdzanie tak często, jak chcesz w tymczasowej gałęzi prywatnej (tylko wypychanie do zdalnego repozytorium "kopii zapasowych"), podczas ponownego wykonywania tych "brzydkich zatwierdzeń" w gałęzi publicznej, z wszystkimi właściwymi testami.