Dlaczego nie popełnić nierozwiązanych zmian?

15

W tradycyjnym VCS rozumiem, dlaczego nie popełniasz nierozwiązanych plików, ponieważ możesz uszkodzić kompilację. Nie rozumiem jednak, dlaczego nie powinieneś zatwierdzać nierozstrzygniętych plików w DVCS (niektóre z nich faktycznie uniemożliwiają zatwierdzenie plików).

Zamiast tego uważam, że twoje repozytorium powinno być zablokowane przed pchaniem i ciągnięciem , ale nie zobowiązując się.

Możliwość zatwierdzenia podczas procesu łączenia ma kilka zalet (jak widzę):

  • Rzeczywiste zmiany scalania są w historii.
  • Jeśli scalenie było bardzo duże, można było dokonywać okresowych zatwierdzeń.
  • Jeśli popełniłeś błąd, znacznie łatwiej byłoby go wycofać (bez konieczności ponawiania całego scalenia).
  • Pliki mogą pozostać oznaczone jako nierozwiązane, dopóki nie zostaną oznaczone jako rozwiązane. Zapobiegnie to pchaniu / ciągnięciu.

Możesz również potencjalnie mieć zestaw zmian działający jako scalenie zamiast tylko jednego. To pozwoli ci nadal korzystać z narzędzi takich jak git rerere.

Dlaczego więc popełnianie niezrozumiałych plików jest marszczone / uniemożliwione? Czy jest jakiś inny powód niż tradycja?

Pigułki przeciwwybuchowe
źródło
1
Komu to się spogląda, czemu się zapobiega?
pdr
@pdr Niektórzy programiści, z którymi pracowałem, zmarszczyli brwi. Przynajmniej hg 1.6po scaleniu pliki są oznaczone jako nierozwiązane. hgbędzie nie pozwalają popełnić dopóki nie zaznaczono je jako rozwiązane (niekoniecznie znaczy, że rzeczywiście trzeba je rozwiązać, ale zakładam, że to pomysł).
Tabletki przeciwwybuchowe
1
Czy więc przez „nierozwiązane pliki” masz na myśli „nierozstrzygnięte scalenia”?
pdr
@pdr nie, hgfaktycznie utrzymuje listę plików, które zostały lub nie zostały oznaczone jako „rozwiązane” (za pomocą hg resolve). Jeśli Una liście są jakieś pliki, nie pozwoli ci to zatwierdzić.
Tabletki przeciwwybuchowe
1
hg resolvejest używany specjalnie do łączenia się z konfliktami; patrz selenic.com/mercurial/hg.1.html#resolve . Note that Mercurial will not let you commit files with unresolved merge conflicts. You must use hg resolve -m ... before you can commit after a conflicting merge.
Mike Partridge

Odpowiedzi:

6

Największym problemem, jaki widzę, jest to, że tworzy okno zatwierdzeń, w którym rzeczy są w połowie scalone i (prawdopodobnie) nie działają poprawnie. Po naciśnięciu końcowego zestawu lokalnych zatwierdzeń, wszystkie te pośrednie zatwierdzenia pojawią się również dla wszystkich innych. W idealnym świecie powinienem móc wyciągnąć dowolne zatwierdzenie, a kod powinien działać. Jeśli zaczniesz zatwierdzać w trakcie scalania, stan kodu nie jest dobrze zdefiniowany.

Jedną rzeczą, którą możesz zrobić, to wprowadzić lokalne zatwierdzenia do scalenia, a następnie spakować je w jeden duży zatwierdzenie, kiedy naciskasz (chociaż nie jestem pewien, w jaki sposób (jeśli?) Jakikolwiek vcs to obsługuje). Chociaż może to przynieść niektóre z wymienionych przez ciebie korzyści, nie jestem pewien, czy jest to warte dodatkowej złożoności (już mamy do czynienia z dość mylącym i złożonym obszarem).

Oleksi
źródło
5
Nie wiem, czy zgadzam się z możliwością wyciągnięcia dowolnego zatwierdzenia i sprawienia, by działało. Dużo sensu w DVCS polega na zatwierdzeniu twojego postępu , więc rzeczy muszą być zepsute lub niekompletne przez większość czasu .
Tabletki przeciwwybuchowe
2
Zawsze mając działające commity ma kilka fajnych korzyści. Na przykład, jeśli próbujesz wyśledzić, kiedy pojawił się błąd, warto przejść przez historię, aby zobaczyć, kiedy coś się zepsuło (vcs ma nawet polecenia do wyszukiwania binarnego w historii). Jeśli nie masz działających zatwierdzeń, nie będziesz w stanie tak skutecznie wyśledzić błędów.
Oleksi
1
Git obsługuje pakiety zatwierdzeń.
deltree,
3

Najbardziej znam Gita, więc odpowiem za tę perspektywę.

Nie widzę powodu, dla którego ty lub jakikolwiek dobry VCS chciałbyś zezwolić na zatwierdzenie niezłapanego pliku, szczególnie jeśli byłby to kod. Musisz utrzymywać repozytorium w spójnym stanie, a to, co sugerujesz, naruszyłoby atomowość zatwierdzania. Wiele VCS fizycznie zmienia plik, aby pokazać, gdzie są konflikty - Git, SVN i CVS używają znaczników typu >>>> <<<<. W VCS z zatwierdzeniami i scaleniami na poziomie repozytorium atomowego, po prostu utworzyłbyś węzeł, który nie ma sensu dla nikogo oprócz ciebie. Podczas opracowywania oprogramowania projekt nie mógł zostać skompilowany. W dokumencie grupy nikt nie wie, które zmiany są poprawne.

Teraz Git udostępnia narzędzia, które mogłyby to ułatwić, gdyby dozwolony typ zatwierdzania był dozwolony. Możesz na przykład zmiażdżyć wszystko, co scalasz, zanim popchniesz. To kończy się tak samo jak typowe zatwierdzenie scalania.

Szczegółowe obawy dotyczące listy świadczeń:

  1. Rzeczywiste zmiany scalania są w historii. Dlaczego potrzebujesz dodatkowych informacji? DVCS bardzo dobrze ograniczają konflikty do ograniczonych obszarów. Po wybraniu zestawu zmian do zachowania, porównanie kopii węzła zatwierdzania scalania z poprzednią kopią da dokładnie to.
  2. Jeśli scalenie było bardzo duże, można było dokonywać okresowych zatwierdzeń. Jest to ważna kwestia, ale nigdy nie powinieneś się tu dostać. Oddziały powinny nieustannie wprowadzać zmiany w górę łańcucha dostaw, aby tak się nigdy nie stało. Narzędzia takie jak rebaselub wybieranie pojedynczych zatwierdzeń na raz mogą również pomóc ci w niektórych sytuacjach.
  3. Jeśli popełniłeś błąd, znacznie łatwiej byłoby cofnąć (bez konieczności ponawiania całego scalenia). Patrz wyżej - twoje konflikty nie powinny stać się tak niemożliwe do opanowania.

Jedyny sposób, w jaki ta sugestia mogłaby zadziałać, to gdyby gałąź była, gdyby całe scalenie było atomowe - można było zobaczyć serię zatwierdzeń, ale byłyby to tylko kroki w większym zatwierdzeniu scalania, które należało traktować jako jeden węzeł w drzewie zatwierdzeń . Nie sądzę, aby jakikolwiek obecny system VCS obsługiwał ten typ przepływu pracy i nie sądzę, że jest to konieczne.

Michael K.
źródło
Konflikty prawdopodobnie nie powinny stać się takimi nie do opanowania, ale często są (przynajmniej z mojego doświadczenia). Myślę, że cała fuzja powinna być atomowa; to właśnie sugeruję. Może nie być konieczne, po prostu zastanawiam się, dlaczego tego nie zrobiono. Nie zawsze możesz wybrać jedną lub drugą opcję w konflikcie; czasami jest to kombinacja obu zmian. Jest to szczególnie mylące.
Tabletki przeciwwybuchowe
„Musisz utrzymać repozytorium w spójnym stanie”. Nie sądzę, że to prawda. Lokalne repozytorium to miejsce do pracy , a nie świątynia. Jeśli pomaga to popełnić w trakcie łączenia, zrób to IMHO. Jeśli zrobisz to, ponieważ nie wiesz nic lepszego, sugerowałbym, aby tego nie robić. Jeśli jednak jesteś doświadczonym programistą, powinieneś zrobić wszystko, co dla ciebie najlepsze. Nie bądź dogmatyczny, jeśli chodzi o utrzymanie nieskazitelności lokalnego repozytorium.
Bryan Oakley,
1

Moje główne doświadczenie związane jest z Mercurialem, chociaż sporadycznie używam git.

Mercurial nie zabrania ci popełniania nierozwiązanych plików, po prostu Cię zniechęca . To samo dotyczy wypychania przed wprowadzeniem zmian, których nie masz.

Wszystko, co musisz zrobić w Mercurial, to po utworzeniu plików w sposób, w jaki chcesz je zatwierdzić:

hg resolve --mark --all
hg commit -m "I'm such a rebel"

--mark ... oznaczy pliki jako rozwiązane bez monitowania za pomocą narzędzia scalania. - all zajmie się zaznaczeniem wszystkich plików oznaczonych konfliktami.

Jeśli chcesz naciskać bez ciągnięcia (a tym samym scalania zmian innych), rób jak Jedi :

hg push --force

Następny facet, który ciągnie, otrzyma +1 głowę (bez zamierzonej gry słów)

Jestem pewien, że istnieje sposób na zrobienie tego samego z Gitem (choć prawdopodobnie jest bardziej skomplikowany).

dukeofgaming
źródło
1

Kiedy scalam w git, natychmiast zatwierdzam wszystkie zmiany (w tym konflikty scalania). Następnie w moich następnych zatwierdzeniach rozwiązuję konflikty scalania za pomocą edytora tekstu. Po rozwiązaniu konfliktów, następnie Pcham w razie potrzeby.

Szczerze mówiąc, nie rozumiem, dlaczego inni nie robią tego w ten sposób lub git tego nie wymusza.

  • „Scalenie zatwierdzenia” jest teraz czystą historią dokładnie tego, co wymagało scalenia.
  • Poniższe zatwierdzenia pokazują dokładnie, co zrobiłeś, aby rozwiązać konflikty scalania.
  • Kiedy pchasz, konflikty są do tej pory rozwiązywane, a kompilacja nieprzerwana na końcu gałęzi.
  • W dowolnym momencie, jeśli spieprzysz rozwiązywanie konfliktów, możesz po prostu wrócić do jednego z zatwierdzeń „po scaleniu” i spróbować ponownie.

Ogromna wada standardowego przepływu pracy rozwiązywania konfliktów wcześniej zatwierdzeniem jest to, że zmiany z lokalnej kopii mogą się wkraść. Dodatki są ukryte przed przeglądem kodu przez ogromną różnicę scalania, więc nie zauważysz, że przypadkowo popełniłeś interfejs API klucz lub itp.

Mój przepływ pracy opisany powyżej pozwala uniknąć tego problemu z kopiowaniem lokalnym, a także pozwala recenzentom kodu zbadać (tylko) szczegóły rozwiązania scalania w różnicach zatwierdzeń, które wyglądają dokładnie tak jak standardowe różnice zmian.

pkamb
źródło
0

Myślę, że najlepiej jest naciskać małe zmiany i naciskać często, gdy jest to możliwe (i oczywiście nie zawsze), i nie zatwierdzaj kodu, który się nie buduje lub jest w połowie kompletny (wszyscy popełniamy błędy, ale nie nie rób tego celowo). Pochodzę także z git i jedną z najlepszych rzeczy, które myślę, jest fakt, że możesz mieć wykonalną kopię repozytorium na pulpicie ... którą możesz następnie zmodyfikować do swoich serc. Po zakończeniu dużych zmian wyślij je.

Robiąc dużo open source z największą frustracją dla mnie, byłem wpakowywany w repozytorium w połowie zrobiony kod i próbowałem stworzyć kompilację, ale nie mogłem, ponieważ facet wykonał połowę pracy i powiedział: „Jestem teraz zajęty , Skończę za tydzień ". Skończyło się więc na tym, że musiałem go zeskrobać (co irytowałoby faceta) lub poświęcić trochę czasu, aby zakończyć i całkowicie go zintegrować.

Wydaje mi się, że z mojego punktu widzenia trzymaj lokalnie dupsko, wysyłaj dobre rzeczy przez drut.

Kelly Elton
źródło
0

Nie bądź niewolnikiem swoich narzędzi.

Celem VCS jest umożliwienie ci wykonywania pracy. Twoim zadaniem nie jest utrzymywanie nieskazitelnego lokalnego repozytorium, twoim zadaniem jest pisanie kodu. Jeśli wcześniejsze zaangażowanie i często lokalnie pozwala ci pracować lepiej, zrób to.

Nie należy jednak wypychać uszkodzonego kodu w górę.

Bryan Oakley
źródło
0

Ponieważ zasadniczo jest to zły pomysł - doprowadzi cię do repozytorium, które jest w opłakanym stanie (i jego wysypka zakłada, że ​​kiedykolwiek będziesz naciskać gdziekolwiek, chociaż można by argumentować, że zawsze powinieneś mieć co najmniej jedną kopię).

Widzę, że w przypadku dużego / złożonego scalenia możesz chcieć zapisać swoją pracę w toku i ustalić punkt odniesienia, ale nadal pozostawiałbyś system w stanie popsucia, który należy rozwiązać.

I są alternatywy - masz możliwość scalenia wcześniej niż głowa - które mogą dać ci możliwość dostosowania się do zmian bez epickich połączeń (lub przynajmniej z większymi połączeniami, które są łatwiejsze do zrozumienia).

Jest to przypadek, w którym uznaję, że rewers bazy gita jest szczególnie przydatny (z zastrzeżeniem zwykłych zastrzeżeń dotyczących rebasingu), ponieważ odtwarzasz zmiany na szczycie stanu, w którym możesz naprawić konflikty w mniejszych częściach.

Murph
źródło