Dlaczego każde poważne repozytorium Github, które ściągam, każe mi zmiażdżyć moje zobowiązania w jednym zatwierdzeniu?
Myślałem, że dziennik git jest tam, abyś mógł sprawdzić całą swoją historię i zobaczyć dokładnie, jakie zmiany się tam zdarzyły, ale zgniatanie go wyciąga go z historii i łączy w jedno zatwierdzenie. O co chodzi?
Wydaje się to również sprzeczne z mantrą „popełnij wcześnie i popełnij często”.
Odpowiedzi:
Abyś miał jasną i zwięzłą historię gitów, która jasno i łatwo dokumentuje dokonane zmiany i powody.
Na przykład typowy dla mnie „niezaprzeczalny” dziennik git może wyglądać następująco:
Co za bałagan!
Podczas gdy bardziej starannie zarządzany i scalony dziennik git z dodatkowym naciskiem na wiadomości może wyglądać następująco:
Myślę, że ogólnie widzisz sens zgniatania zatwierdzeń i ta sama zasada dotyczy żądań ściągania - Czytelność historii. Możesz także dodawać do dziennika zmian, który ma już setki, a nawet tysiące zatwierdzeń, co pomoże utrzymać krótką i zwięzłą historię.
Chcesz popełniać wcześnie i często. Jest to najlepsza praktyka z wielu powodów. Uważam, że prowadzi mnie to często do zatwierdzania „wip” (praca w toku) lub „część A zrobiona” lub „literówka, drobna poprawka”, gdzie używam git, aby pomóc mi w pracy i dać mi punkty pracy, które Mogę wrócić do tego, jeśli poniższy kod nie działa w miarę postępu pracy. Jednak nie potrzebuję ani nie chcę tej historii jako części ostatecznej historii gita, więc mogę zmiażdżyć swoje commity - ale zobacz uwagi poniżej, co to znaczy w gałęzi programistycznej vs. master.
Jeśli istnieją główne kamienie milowe, które reprezentują odrębne etapy robocze, nadal może być więcej niż jeden zatwierdzenie na funkcję / zadanie / błąd. Może to jednak często uwypuklać fakt, że opracowywany bilet jest „zbyt duży” i należy go podzielić na mniejsze części, które mogą być niezależne, na przykład:
wygląda jak „1 praca”. Albo istnieją, albo nie! Wydaje się, że nie ma sensu go rozwodzić. Jednak doświadczenie pokazało mi, że (w zależności od wielkości i złożoności organizacji) bardziej szczegółową ścieżką może być:
Małe kawałki oznaczają łatwiejsze przeglądy kodu, łatwiejsze testowanie jednostek, lepszą możliwość qa, lepsze dostosowanie do zasady pojedynczej odpowiedzialności itp.
Praktyczne momenty, w których faktycznie należy wykonywać takie squashy, są w zasadzie dwoma odrębnymi etapami, które mają swój własny przebieg pracy
Podczas rozwoju popełniasz „wcześnie i często” oraz za pomocą szybkich komunikatów „jednorazowych”. Czasami możesz chcieć zgnieść tutaj, np. Zgnieść w celu wyczyszczenia i zatwierdzenia wiadomości do zrobienia. W oddziale można zachować wiele zatwierdzeń, które reprezentują różne kroki, które wykonałeś w fazie rozwoju. Większość squashów, które wybierzesz, powinna znajdować się w tych gałęziach funkcji, podczas gdy są one rozwijane, a przed scaleniem do opanowania.
Podczas dodawania do gałęzi głównej chcesz, aby zatwierdzenia były zwięzłe i poprawnie sformatowane zgodnie z istniejącą historią głównej. Może to obejmować identyfikator systemu śledzenia biletów, np. JIRA, jak pokazano w przykładach. Squashing tak naprawdę nie ma tu zastosowania, chyba że chcesz „zrolować” kilka różnych zatwierdzeń na master. Zwykle nie.
Użycie
--no-ff
podczas scalania z master spowoduje użycie jednego zatwierdzenia do scalenia, a także zachowanie historii (w oddziale). Niektóre organizacje uważają to za najlepszą praktykę. Zobacz więcej na https://stackoverflow.com/q/9069061/631619 Zobaczysz również praktyczny efekt, wgit log
którym--no-ff
zatwierdzenie będzie ostatnim zatwierdzeniem, na górze HEAD (gdy właśnie zrobione), podczas gdy bez--no-ff
niego może być w dalszej części historii, w zależności od dat i innych zobowiązań.źródło
Ponieważ często osobie zajmującej się PR-em zależy na efekcie netto zatwierdzeń „dodana funkcja X”, a nie o „szablony podstawowe, funkcja poprawki błędów X, dodawanie funkcji Y, poprawione literówki w komentarzach, skorygowane parametry skalowania danych, mapa skrótów działa lepiej niż lista „... poziom szczegółowości
Jeśli uważasz, że twoje 16 zatwierdzeń najlepiej reprezentują 2 zatwierdzenia zamiast 1 „Dodano funkcję X, zmieniono fakt, że Z używa X”, to prawdopodobnie dobrze jest zaproponować pr z 2 zatwierdzeniami, ale wtedy najlepiej byłoby zaproponować 2 oddzielne pr w tym przypadku (jeśli repo nadal nalega na pojedyncze zatwierdzenia pr)
Nie jest to sprzeczne z mantrą „wcześnie i często popełniaj”, tak jak w repozytorium, podczas gdy wciąż się rozwijasz, nadal masz szczegółowe informacje, więc masz minimalną szansę na utratę pracy, a inni ludzie mogą przeglądać / wyciągać / proponować pr jest przeciw twojej pracy podczas opracowywania nowego pr.
źródło
Główny powód tego, co widzę, jest następujący:
Merge pull request #123 from joebloggs/fix-snafoo
--first-parent
punktu widzenia--first-parent
punktu widzenia (zauważ, że zostało to naprawione tylko w Git 2.6.2, więc możemy wybaczyć GitHub za to, że go nie ma dostępny)Kiedy więc połączysz wszystkie trzy powyższe sytuacje, otrzymasz sytuację, w której łączenie niesprawdzonych zatwierdzeń wygląda brzydko z interfejsu użytkownika GitHub.
Twoja historia ze zgniecionymi zobowiązaniami będzie wyglądać jak
Podczas gdy bez zgniecionych zobowiązań historia będzie wyglądać jak
Gdy masz dużo zatwierdzeń w śledzeniu PR, w którym nastąpiła zmiana, może to być koszmar, jeśli ograniczysz się do korzystania z interfejsu GitHub .
Na przykład, gdzieś w pliku znajduje się odwołanie do wskaźnika zerowego, więc mówisz „kto to zrobił i kiedy? Na jakie wersje wydania ma to wpływ?”. Następnie wędrujesz do widoku winy w interfejsie GitHub i widzisz, że linia została zmieniona
789fdfffdf
... „och, ale poczekaj sekundę, linia właśnie zmieniała swoje wcięcie, aby pasowała do reszty kodu”, więc teraz musisz przejść do stanu drzewa dla tego pliku w zatwierdzeniu nadrzędnym i ponownie odwiedzić strona z winami ... w końcu znajdziesz zatwierdzenie ... to zatwierdzenie sprzed 6 miesięcy ... "och **** to może mieć wpływ na użytkowników przez 6 miesięcy" mówisz ... ach, ale poczekaj, to zatwierdzenie był w rzeczywistości w żądaniu ściągnięcia i został połączony dopiero wczoraj i nikt jeszcze nie wydał nowego wydania ... „Cholera, ludzie, że łączysz zobowiązania bez marnowania historii” to krzyk, który zwykle można usłyszeć po około 2 lub 3 wyprawach z archeologii za pośrednictwem Interfejs GitHubZastanówmy się teraz, jak to działa, jeśli używasz wiersza polecenia Git (i super-niesamowite 2.6.2, które ma poprawkę
git blame --first-parent
)Tak wyglądałaby nasza historia zmian
Ale możemy też
(Innymi słowy: Git CLI pozwala ci zjeść ciasto i zjeść je)
Teraz, gdy natrafimy na problem ze wskaźnikiem zerowym ... cóż, po prostu używamy
git blame --first-parent -w dodgy-file.c
i natychmiast dostajemy dokładne zatwierdzenie, w którym odwołanie do wskaźnika zerowego zostało wprowadzone do gałęzi głównej, ignorując proste zmiany białych znaków.Oczywiście, jeśli wykonujesz scalenia za pomocą interfejsu GitHub, to
git log --first-parent
jest naprawdę kiepski dzięki GitHub wymuszającemu pierwszy wiersz komunikatu zatwierdzenia scalania:Krótko mówiąc:
Interfejs GitHub (październik 2015 r.) Ma szereg niedociągnięć w sposobie łączenia żądań ściągania, prezentacji historii zatwierdzeń i przypisywania informacji o winie. Obecnie najlepszym sposobem na włamanie się do tych usterek w interfejsie GitHub jest poproszenie ludzi o zmiażdżenie swoich zobowiązań przed połączeniem.
Interfejs Git CLI nie ma tych problemów i możesz łatwo wybrać widok, który chcesz zobaczyć, dzięki czemu możesz zarówno odkryć powód, dla którego dokonano konkretnej zmiany w ten sposób (patrząc na historię niezakwestionowanych zmian), a także zobacz skutecznie zgniecione zatwierdzenia.
Post Script
Ostatnim powodem często cytowanym przy zatwierdzaniu zgniatania jest ułatwienie backportowania ... jeśli masz tylko jedno zatwierdzenie do tylnego portu (tj. Zgniecione zatwierdzenie), łatwo jest wybrać cherry ...
Cóż, jeśli patrzysz na historię gitów
git log --first-parent
, możesz po prostu wybrać zatwierdzenia scalania. Większość ludzi ma mylące zatwierdzenia scalania podczas pobierania, ponieważ musisz określić-m N
opcję, ale jeśli dostałeś zatwierdzeniegit log --first-parent
, wiesz, że jest to pierwszy rodzic, którego chcesz śledzić, więc będziegit cherry-pick -m 1 ...
źródło
--first-parent
siebie, aby wygrać spór o zgniatanie spraw ;-)Zgadzam się z opiniami wyrażonymi w innych odpowiedziach w tym wątku na temat pokazywania jasnej i zwięzłej historii dodanych funkcji i naprawionych błędów. Chciałem jednak odnieść się do innego aspektu, do którego pańskie pytanie umknęło, ale nie zostało wyraźnie stwierdzone. Częścią zawieszania się niektórych metod pracy gita jest to, że git pozwala przepisać historię, która wydaje się dziwna, gdy wprowadza się go do gita po użyciu innych form kontroli źródła, w których takie działania są niemożliwe. Co więcej, jest to również sprzeczne z ogólnie przyjętą zasadą kontroli źródła, że gdy coś zostanie zatwierdzone / wpisane do kontroli źródła, powinieneś być w stanie powrócić do tego stanu bez względu na zmiany, które wprowadzisz po tym zatwierdzeniu. Jak sugerujesz w swoim pytaniu, jest to jedna z takich sytuacji. Myślę, że git to świetny system kontroli wersji; jednak, aby to zrozumieć, musisz zrozumieć niektóre szczegóły implementacji i decyzje projektowe, w wyniku czego ma on bardziej stromą krzywą uczenia się. Pamiętaj, że git miał być rozproszonym systemem kontroli wersji, który pomoże wyjaśnić, dlaczego projektanci zezwalają na przepisywanie historii git, a zatwierdzenia squasha są tego przykładem.
źródło
git gc
że uruchomiono go w celu odrzucenia niepowiązanych obiektów.Ze względu na perspektywę ... Najlepszą praktyką jest posiadanie jednego zatwierdzenia na jeden
<<issue-management-system>>
problem, jeśli to możliwe.Możesz mieć tyle zatwierdzeń, ile chcesz we własnym oddziale / repozytorium funkcji, ale twoja historia jest istotna dla tego, co robisz teraz dla twojej perspektywy ... to nie jest HISTORIA dla całego ZESPOŁU / PROJEKTU lub aplikacji z ich perspektywa do zachowania za kilka miesięcy ...
Tak więc za każdym razem, gdy chcesz zatwierdzić naprawę błędu lub funkcję do wspólnego repozytorium (ten przykład dotyczy gałęzi developerskiej), możesz to zrobić w następujący sposób:
jak zmienić bazę gałęzi funkcji, aby szybko się rozwijać
źródło
Chciałbym sprawdzić, czy kod zostanie opublikowany, czy nie.
Gdy projekty pozostają prywatne:
Polecam nie zgniatać i nie zobaczyć, jak powstaje kiełbasa. Jeśli używasz dobrych i małych zatwierdzeń, narzędzia takie jak git bisect są bardzo przydatne i ludzie mogą szybko wskazać zatwierdzenia regresji i zobaczyć, dlaczego to zrobiłeś (z powodu komunikatu zatwierdzenia).
Kiedy projekty stają się publiczne:
Zmiażdż wszystko, ponieważ niektóre zmiany mogą zawierać przecieki bezpieczeństwa. Na przykład hasło, które zostało ponownie zatwierdzone i usunięte.
źródło