2012-09-11 4 views
9

Używam Git do śledzenia kodu Matlaba. Przykład zabawki najlepiej ilustruje problem. Projekt do tej pory wygląda tak.Integracja wcięć i zmian treści w Git podczas scalania: Najlepsze praktyki?

C 
/
A-- 
    \ 
    B 

zawartość są x=5

Wykonujemy popełnić C, gdzie linia jest zmieniany na x=6

Następnie dokonać popełnić B, gdzie nasza treść staje się jak poniżej

if flag==1 
    x=5 
end 

Jeśli staramy się połączyć się z celem projektu wyglądające jak

C 
/\ 
A-- D 
    \/
    B 

z wynikiem scalenia w D, otrzymamy konflikt, ponieważ główna linia została zmieniona w obu (wcięcie dodane w B, 5 zmienione na 6 w C).

Czy istnieje sposób najlepsza praktyka integracji zmiany wcięcia z jednej gałęzi, a zawartość zmienia się z innego oddziału, aby uzyskać wynik scalania?

Przeczytałem o jednej strategii w https://stackoverflow.com/a/5262473/288545, a podczas gdy uniknęłoby to konfliktu, odrzuciłoby to wcięcie na korzyść zmiany zawartości (co stanowi ulepszenie, ale nadal utrudnia odczyt kodu).

Przypuszczam, że po prostu ssać go i nie zmienić wcięcia podczas pisania mojego kodu. To czyni go mniej czytelnym, ale nie jest to wielka sprawa w Matlabie. Jednak w python, wcięcia naprawdę mają znaczenie, więc jak ludzie z Pythona sobie z tym poradzą? Staje się to o wiele brzydsze, jeśli istnieją duże bloki kodu, które później zmieniamy, aby były wewnątrz struktur kontrolnych, więc diff dotyka wielu linii i powoduje konflikty scalania z ogromnym bólem głowy.

Czy istnieje strategia, która będzie obsługiwać scalania odstępy zmiany i zmiany treści oddzielnie, a następnie zintegrować je? Chciałbym wynikiem scalenia być

if flag==1 
    x=6 
end 
+0

W pythonie kierujemy wszystkich do 'PEP 8', który nakazuje im wcięcie ich kodu o 4 spacje. Następnie, ponieważ wszyscy piszemy kod z 4 wcięciami, nie musimy się już martwić o zmianę wcięcia ... ;-) – mgilson

+5

@mgilson Problem nadal występuje, jeśli masz kod, który był oryginalnie autonomiczny (unindented), a następnie osadzasz go w strukturze kontrolnej, więc musi być wcięty. Nawet jeśli jesteś idealny, robiąc tylko 4 spacje, nadal będziesz mieć konflikt scalający, ponieważ jeden oddział wprowadza 4 nowe spacje, a drugi oddziału wprowadza zmiany zawartości. –

+0

Mój komentarz był głównie żartem. Masz oczywiście rację. Jednak w takim przypadku nie musi to być również wcięcie. Konflikt seryjny będzie występować zawsze, gdy wystąpią niekompatybilne zmiany w tym samym bloku kodu. Dlatego git zmusza cię do radzenia sobie z tymi niekompatybilnymi zmianami i łączenia ich ręcznie ... oczywiście, istnieje wiele narzędzi, które możesz spróbować uczynić mniej bolesnym z 'git mergetool' ... – mgilson

Odpowiedz

3

Kluczem do rozwiązania problem jest traktowanie whitespace cleanups i funkcja przepisuje jako oddzielne zobowiązuje.

Jako osoba, która zajmuje się integracją branżową, mogę uczciwie powiedzieć, że dwie najbardziej irytujące rzeczy dla integratorów to: 1) programistów, którzy lubią ponownie formatować pliki, których nie napisali, ani funkcji, których nie przepisali, oraz 2) IDE, które formatują całe pliki po prostu otwierając je i zapisując. Oczywiście pliki są bardziej czytelne w obu przypadkach, ale całkowicie pokonują punkt kontroli wersji: zatwierdzenia muszą być inteligentnie sortowane, konstruowane i sprawdzane. Ich kolejność powinna mieć znaczenie. Zatopienie w kuchni powoduje, że historia staje się bezużyteczna, a historia powinna być tylko użyteczna.

Filozofia ta zakłada „Nie zrzucić whitespace zmian w zobowiązuje gdzie one nie należą.” Jeśli przepisujesz dotkniętą funkcję, upewnij się, popraw odstępy. W przeciwnym razie pozostaw to własnemu zatwierdzeniu i upewnij się, że inni pracujący nad tym plikiem wiedzą, że nadchodzą zmiany w spacje. Pozwoli to zaoszczędzić Ci kłopotów w czasie integracji.

Dodatkowo, można uniknąć przypadkowych błędów białych znaków (spacje, tabulatory po spacjami i tym podobne) z git w stanie pre-commit.Wydaj polecenie w repozytorium, aby ustawić:

mv .git/hooks/pre-commit.sample .git/hooks/pre-commit 

on bardziej lub mniej problemów git diff --check, który jest również bardzo przydatny do wykrywania tego typu problemów.

3

Niektóre narzędzia różnicowe są lepsze niż inne. Używam KDiff3 i ustawię go tak, aby był automatycznie wywoływany za pomocą git mergetool. Wciąż nie jest doskonały, ale często potrafi wykryć połączenia opisywanego rodzaju i automatycznie wytworzyć rozsądne połączenie.