Czy kod tymczasowy powinien podlegać kontroli wersji i jak?

29

Oto kilka przykładów kodu tymczasowego / lokalnego. Jest potrzebny do pracy z bazą kodu, ale bycie częścią tego byłoby szkodliwe:

  1. Pliki projektu Ścieżki mogą wymagać edycji w celu odzwierciedlenia układu na bieżącym komputerze.
  2. Makefile. Na przykład optymalizacja może wymagać wyłączenia podczas debugowania, ale nie w przypadku serwera CI.
  3. Brudne brzydkie hacki. Na przykład return 7w środku funkcji, w celu przetestowania czegoś, w zależności od funkcji, i podejrzewa się, że pęknie przy wartości 7. Lub 7 to kod jeszcze nie zaimplementowanego przycisku, który wdrażam i muszę testować przez cały czas życie mojej gałęzi.

Próbowałem trzymać tych w git commit, które zawsze bazuję na górze przed pchaniem do repo, a następnie pchaniem HEAD~. Jest to dość niewygodne i nie działa z svn. Stashing przeraża mnie jeszcze bardziej - „czy pamiętałem, żeby pop po popchnięciu ??”.

Utrzymywanie kodu poza kontrolą wersji powoduje nieprzyjemny hałas za każdym razem, gdy budowane jest zatwierdzenie, a także może przypadkowo zostać wprowadzone do zatwierdzenia w piątek wieczorem.

Jakie byłoby rozsądne rozwiązanie dla takiego wyrzucanego kodu?

Vorac
źródło
Czy ten tymczasowy kod będzie wymagał aktualizacji z oryginalnego projektu w okresie tymczasowego użytkowania?
JeffO
@JeffO, nie jestem pewien, czy cię rozumiem. Brudne fragmenty są małe i rzadko kolidują z tworzonym kodem. Jednak, @ Blrfl, zaangażowanie ich w główny nurt jest bardzo niebezpieczne. Wyobraź sobie return 7w trunkpiątek wieczorem, po kiepskim seryjnej w okresie letnich upałów.
Vorac
@Vorac - po to są recenzje i testy kodu! Mogę pokazać ci znacznie gorzej - kod, który nie działa, chociaż na pierwszy rzut oka wyglądał dobrze. Return 7.. gdyby tylko wszyscy byli tacy oczywisti!
gbjbaanb
@Vorac: To był bardziej filozoficzny komentarz niż cokolwiek innego.
Blrfl
2
Czy istnieje sposób, aby powiedzieć, w jakim środowisku jesteś? Na przykład możesz ustawić go tak, aby uruchamiał kod, jeśli wykryje, że jesteś w środowisku deweloperskim, ale nie w val / prod. W ten sposób nie musisz ciągle dodawać / usuwać kodu zastępczego podczas zatwierdzania.
Saggio

Odpowiedzi:

46

Cały kod jest tymczasowy. Kiedy wprowadzam zmiany, od czasu do czasu wprowadzam symbole zastępcze - ikonę, którą narysowałem, czekając na prawdziwą od projektanta, funkcję, którą znam, wywoła bibliotekę, którą pisze mój kolega i jeszcze się nie zakończyła (lub nie uruchomiła), dodatkowe rejestrowanie, które zostanie usunięte lub w inny sposób uwarunkowane, błędy, które naprawię, gdy zostaną zauważone przez zespół testowy itp.

Więc sprawdź wszystko. Użyj gałęzi funkcji dla całego swojego rozwoju, a następnie możesz połączyć ostateczną wersję w bagażnik i nikt nie będzie musiał wiedzieć, jakie włamania, poprawki i poprawki dokonałeś podczas cyklu programowania, będą musieli tylko zobacz ostateczną wersję. Ale jeśli regularnie angażujesz się w swój oddział, będziesz mógł zobaczyć rzeczy, które warto było zachować, jeśli dzień poszedłby spektakularnie źle, lub nadal kodowałeś po lunchu w pubie.

Kontrola wersji nie jest repozytorium artefaktów ani systemem przechowywania dokumentów. Chodzi o przechowywanie historii zmian. Trzymaj tam wszystko, co ci się podoba, ponieważ pewnego dnia możesz chcieć zobaczyć, co to jest, i to są dni, w których zdajesz sobie sprawę z tego, na czym naprawdę polega Twój SCM.

PS. Naprawdę tymczasowe pliki (np. .Obj lub artefakty kompilacji) nie mają miejsca w SCM. Są to rzeczy, które nie mają żadnej wartości dla nikogo. Możesz powiedzieć, jakie są - jeśli je usuniesz, nie masz nic przeciwko, a nawet zauważysz, że zniknęły.

gbjbaanb
źródło
5
Zgoda. Rozgałęzienie jest właściwą drogą. Utwórz gałąź, rób co chcesz i scal gotowy kod po jego zakończeniu. Head powinien być traktowany jako wersja wydania, którą klient może pobrać i wykorzystać w dowolnym momencie.
Cameron McKay
Świetna odpowiedź, z tego co widziałem, GIT wprowadził lokalną wersję częściowo, aby pomóc ludziom, którzy chcą mieć dziennik swojej lokalnej pracy. Kod tymczasowy powinien pozostać na komputerach deweloperów, dopóki nie będzie gotowy do zatwierdzenia ich w repozytorium
InformedA
2
Wydrukuję duży plakat z napisem „CAŁY KOD JEST TYMCZASOWY” i przykleję go na ścianie. Prawdopodobnie w Comic Sans.
Bob Tway
2
@MattThrower w cytacie z bąbelków, pochodzącym z ust Clippy?
gbjbaanb
1
Jednak nie działający kod lub kod, który się nie kompiluje, nie powinien być poddany kontroli wersji.
Tulains Córdova
17

Pliki projektu Ścieżki mogą wymagać edycji w celu odzwierciedlenia układu na bieżącym komputerze.

W przypadku plików projektu najlepszą strategią jest wygenerowanie pliku projektu za pomocą skryptu. Dodaj rzeczywisty plik projektu do ignorowanych i po prostu ponownie wygeneruj plik projektu w razie potrzeby. Na przykład w projektach Java używam gradle, które mogą wygenerować projekt zaćmienia.

Makefile. Na przykład optymalizacja może wymagać wyłączenia podczas debugowania, ale nie w przypadku serwera CI.

Powinieneś być w stanie przełączać się między trybem optymalizacji i debugowania bez modyfikowania pliku Makefile. Zamiast tego użyj flagi wiersza poleceń, zmiennej środowiskowej lub oddzielnego pliku spoza repozytorium, aby to kontrolować.

Brudne brzydkie hacki. Na przykład zwróć 7 w środku funkcji, aby przetestować coś, w zależności od funkcji, i podejrzewa się, że pęknie przy wartości 7. Lub 7 to kod jeszcze nie zaimplementowanego przycisku, który implementuję i muszę test przez całe życie mojej branży.

Nie możesz napisać testu, który wywoła podejrzenie awarii?

W większości przypadków powinieneś być w stanie dostosować przepływ pracy, aby nie wprowadzać tych zmian w plikach w repozytorium. Pliki zmieniane lokalnie powinny zostać dodane do mechanizmu ignorowania projektu i nie powinny znajdować się w repozytorium. W niektórych przypadkach nadal będziesz wprowadzać tymczasowe zmiany, których nie chcesz umieszczać w repozytorium. Dla tych dodaj specjalną sekwencję, taką jak: XXX, i dodaj przechwytywanie przed zatwierdzeniem, które odrzuca zatwierdzenia, które wciąż tam są.

Winston Ewert
źródło
Czasami muszę zrobić małe włamania do pliku, jednocześnie zapisując kod produkcyjny w tym samym pliku. svnnie obsługuje częściowych zatwierdzeń plików, więc jest to problem w takiej sytuacji. Większość moich kolegów po prostu popełniła włamania do oddziału i oczyściła ich podczas połączenia trunk. Jednak jestem rozproszony (i popełniam błędy podczas łączenia, a połączenia w svn są święte i niezmienne) o wiele łatwiej i stąd to pytanie.
Vorac
@Vorac, zajrzałbym do haków subversion, które pozwalają uruchamiać skrypty podczas zatwierdzania. Powinno być możliwe napisanie skryptu, który odrzuca scalenie, jeśli zawiera XXX lub coś podobnego.
Winston Ewert
1
@Vorac: Jeśli używasz TortoiseSVN, możesz użyć Przywróć po zatwierdzeniu pliku, aby częściowo zatwierdzić, użyj narzędzia różnicowego lub edytora, aby tymczasowo usunąć bloki, których nie chcesz zatwierdzić, a następnie zatwierdzić. Tortoise przywróci pełny plik zaraz po tym i możesz zatwierdzić pozostałe bloki, jeśli są gotowe. Można to zrobić, wykonując szybką kopię zapasową pliku i przywracając go po pierwszym zatwierdzeniu.
leokhorn
5

Kontrola wersji powinna zawierać kod i konfigurację potrzebną do zbudowania aplikacji.

To znaczy że:

  • Tymczasowe rzeczy, które zostały wprowadzone na krótki czas (na przykład czas potrzebny do ustalenia lokalizacji błędu lub na przykład eksperymentowania z funkcją języka) nie powinny mieć kontroli wersji: zachowaj ją, dopóki nie będziesz potrzebować to, a następnie po prostu usuń go podczas wykonywania zatwierdzenia .

  • Pliki lokalne właściwe dla danego komputera mogą być przechowywane w oddziale.

    Unikałbym trzymania ich tylko lokalnie, ponieważ zbyt bolesne jest ponawianie wszystkich tych rzeczy, gdy laptop zostanie skradziony lub wirus zmusi cię do ponownej instalacji systemu operacyjnego (a swoją drogą, okazuje się, że twoja ostatnia kopia zapasowa została wykonana dwa lata temu) .

    Z drugiej strony, uważaj na strukturę plików: lokalna konfiguracja jest OK, aż stanie się przytłaczająca i zmusi cię do wprowadzenia jednej zmiany w każdym pliku każdego z 42 programistów uczestniczących w projekcie.

    Uważaj na możliwość usunięcia szczegółów między maszynami. Może to oznaczać:

    • Zapewniając dostęp do deweloperskiego serwera SQL w celu zastąpienia lokalnych instancji na komputerach programistów,

    • Korzystanie z usług dystrybucji pakietów, takich jak Pypi lub npm, w przypadku pakietów publicznych i ich prywatnych odpowiedników w przypadku pakietów wewnętrznych,

    • Poproś członków zespołu o zainstalowanie tych samych wersji oprogramowania,

    • Spraw, aby aktualizacje oprogramowania były jak najbardziej przejrzyste,

    • Lub umożliwić wdrożenie systemu operacyjnego i potrzebnego oprogramowania na komputerze za pomocą jednego kliknięcia (plus czas dla każdego programisty na zainstalowanie preferowanego Vima vs. Emacsa, Chrome vs. Firefox itp.)

Więc:

Pliki projektu Ścieżki mogą wymagać edycji w celu odzwierciedlenia układu na bieżącym komputerze.

Dlaczego nie użyć tego samego układu na każdym komputerze? Ścieżki w projekcie powinny być względne do pliku projektu, co oznacza, że ​​nie ma znaczenia, gdzie znajduje się projekt. Wersje oprogramowania i bibliotek lepiej są takie same, aby uniknąć tajemniczych błędów, które pojawiają się tylko na niektórych komputerach i nie są możliwe do odtworzenia dla innych członków zespołu.

Przykład:

W projekcie utworzonym za pomocą Visual Studio możesz znaleźć:

  • Same pliki. Ścieżki są względne, nie ma znaczenia, czy na moim komputerze projekt jest zlokalizowany, H:\Development\Hello World Project\podczas gdy inni członkowie zespołu sprawdzali projekt C:\Work\HelloWorld\.

  • Zależności, tj. Biblioteki stron trzecich i biblioteki wewnętrzne. Oba typy powinny być obsługiwane przez NuGet, co powoduje, że wszystkie dyskusje dotyczące konfliktów stają się nieaktualne. Jeśli nie masz tej samej wersji biblioteki, którą mam, poproś NuGet o zaktualizowanie zależności. To takie proste (gdy działa dobrze, co nie zawsze tak jest).

    Należy pamiętać, że kluczowe znaczenie ma także zachowanie bibliotek wewnętrznych w prywatnym NuGet. Posiadanie kilku bibliotek przechowywanych w folderze współdzielonym lub wysyłanych pocztą e-mail przez zespół prowadzi do anarchii i depresyjnych serwerów CI.

  • Ustawienia. Ważne jest, aby zespół dzielił te same ustawienia. Jeśli połowa zespołu zdecyduje się traktować ostrzeżenia jako błędy, a połowa zespołu zachowa ostrzeżenia w niezmienionej postaci, członkowie pierwszej części zespołu poświęcą czas na usuwanie ostrzeżeń generowanych przez programistów z drugiej części zespołu.

  • Ustawienia związane z narzędziami. Są to trudne, ponieważ niektórzy członkowie zespołu mogli zainstalować niektóre narzędzia, a inni nie.

    Zdecydowanie zaleca się zainstalowanie tego samego zestawu narzędzi. Jeśli niektórzy programiści chcą używać StyleCop, a inni nie, zespół nie wykona zadania. Jeśli niektórzy korzystają z umów Kodeksu, a inni nie, będą mieć te same problemy.

Makefile. Na przykład optymalizacja może wymagać wyłączenia podczas debugowania, ale nie w przypadku serwera CI.

Zachowaj kilka plików makefile w kontroli wersji. Nie jest niczym niezwykłym budowanie wersji debugowania również na serwerze CI i przekazywanie jej do klienta, który napotyka trudny błąd.

Brudne brzydkie hacki. Na przykład zwróć 7 w środku funkcji, aby przetestować coś, w zależności od funkcji, i podejrzewasz, że pęknie przy wartości 7.

Unikałbym takiego kodu w pierwszej kolejności. Aby coś przetestować, użyj testów jednostkowych. Jeśli naprawdę zajmuje kilka sekund zamiana kodu w celu debugowania , zrób to, ale i tak usuniesz ten kod za kilka minut, więc nie musisz go zatwierdzać.

Jak to opisujesz, powinieneś napisać test. Na przykład, jeśli chcesz mieć pewność, że:

class TemperatureConverter
{
    public int CelsiusToFahrenheit(int temperature)
    {
        ...
    }
}

zgłasza wyjątek, gdy temperaturejest gorszy od AbsoluteZerostałego, nie powinieneś grać samym kodem. Zamiast tego utwórz test jednostkowy, który:

  • samodzielnie udokumentuj swój kod,
  • zwiększ niezawodność swojego kodu,
  • upewnij się, że opiekunowie mogą polegać na testach regresyjnych podczas modyfikowania powyższej metody,
  • służyć innym programistom z zespołu, którzy mogą potrzebować wykonać ten sam test.
Arseni Mourzenko
źródło
2
Niestety nie mam doświadczenia w pisaniu testów. Obecna platforma wymaga procesora ARM, który konfiguruje sprzęt w odpowiedzi na polecenia USB. Brak sprzężenia zwrotnego ze sprzętu do procesora.
Vorac
2
Jeśli tymczasowy kod może mieć trwałe skutki, nawet jeśli kod może nigdy nie być potrzebny po osiągnięciu tych efektów, myślę, że trzymanie kodu gdzieś byłoby rozsądne na wypadek, gdyby pojawiły się pytania, czy efekty zostały osiągnięte poprawnie. Na przykład, jeśli jakiś format bazy danych produktu zostanie zmieniony podczas opracowywania, można napisać szybkie narzędzie jednorazowe, aby zmienić format. Narzędzie może nigdy nie być potrzebne po przekonwertowaniu jedynej istniejącej bazy danych w starym formacie, ale może być jednak konieczne sprawdzenie, w jaki sposób dokonano konwersji.
supercat
W przypadku plików projektu Visual Studio miałem dobre doświadczenia z ich generowaniem za pomocą CMake, co pozwala na pewną elastyczność w tym, jak dokładnie znajduje się kod źródłowy i kod skompilowany w systemie plików. Następnie kontroluję wersję plików wejściowych CMake zamiast plików projektu VS. Ale nadal jest to zgodne z Twoim zdaniem: „Kontrola wersji powinna zawierać kod i konfigurację niezbędną do zbudowania aplikacji”. Całkowicie się z tym zgadzam!
David K
Z VS, czasami trzeba zadbać, aby upewnić się, że nie mają ścieżki bezwzględne skradanie w Ja wpadłem na więcej niż kilka problemów z odniesieniami uszkodzonych w jakiś sposób podczas uaktualniania do Win64 i posiadające biblioteki dla 3rd program polityczny poruszają się od. C:\Program Files\...DoC:\Program Files (x86)\...
Dan Neely
@DanNeely: właśnie dlatego biblioteki zewnętrzne powinny być obsługiwane przez NuGet.
Arseni Mourzenko
2

Używamy @@komentarzy w kodzie, aby wskazać, że coś nie jest jeszcze gotowe, do celów testowych itp.

W ten sposób możemy zatwierdzić, koledzy nie muszą czekać zbyt długo na synchronizację i mogą zobaczyć, gdzie wciąż trwa praca (np. Zrozumieć, dlaczego część jeszcze nie działa w pełni).

@@Przeprowadzamy globalne poszukiwanie, aby zapobiec „resztkom” przed wejściem w końcowe etapy testów beta itp.

Stosując tę ​​dyscyplinę, nie widzę powodu, aby nie tylko popełniać. W ten sposób nie mamy oddzielnych gałęzi i tylko jeden dodatkowy „protokół” do naśladowania.


Jako dodatkową korzyść, te todo (zwykle małe rzeczy) są zawsze w kodzie. Pracujący nad nimi programista może szybko je przejrzeć i nie trzeba prowadzić osobnych list.
Wiesz, jak idzie rozwój: pracujesz w jednym miejscu, ale ciągle używasz swojego umysłu jako stosu („ Powinienem to zmienić, kiedy skończę tutaj ”). Zapisanie krótkiej @@uwagi zapobiega przepełnieniu stosu.

Używam nawet @@namedo wskazywania problemów, które muszę omówić z „imieniem”.

Jan Doggen
źródło
1

2 rozwiązania HAMSTER:

  • Możesz użyć haka wstępnego zatwierdzenia, aby sprawdzić kod dla jakiegoś niezwykłego słowa kluczowego, takiego jak HAMSTER. Po prostu nie pozwól ludziom zatwierdzać kodu, który został HAMSTEROWANY i używać go, gdy robisz brudne włamania.

  • Inną opcją na przykład w C jest użycie #ifdef HAMSTER, wtedy kod będzie działał tylko na komputerze, na którym masz flagę kompilatora HAMSTER.

użytkownik143985
źródło
0

Poddajemy wszystko kontroli źródła potrzebnej do zbudowania i przetestowania bieżących plików binarnych oraz zrozumienia, dlaczego rzeczy zostały zaprojektowane / zaimplementowane / przetestowane tak, jak są.

Dotyczy to nawet szczytów http://www.extremeprogramming.org/rules/spike.html , takich jak te, które opisałeś; po prostu hostujemy je w innym sub-drzewie.

Solkar
źródło
0

Oto kilka rozwiązań, z których czasami korzystam sam w różnych okolicznościach, i które możesz uznać za pomocne, gdy zastosujesz je do własnych przepływów pracy:

  1. Lekkie gałęzie, które można zgnieść.

    Git jest w tym świetny. Włam się na oddział, dokonaj wielu zobowiązań, a następnie wyrównaj lub zmiażdż swoją historię, aby wyedytować hałas.

  2. Użyj kolejki łat na SCM.

    Często używam StGit, aby przenosić łaty na szczyt mojej obecnej gałęzi. Kiedy skończę z gałęzią, mogę oderwać je od stosu przed scaleniem, zgnieceniem lub zmianą bazy, lub mogę połączyć je z główną bazą kodu, jeśli chcę je zachować.

  3. Użyj RCS jako „pozapasmowego” SCM do małych eksperymentów.

    Czasami chcesz po prostu sprawdzić trwający plik w jednorazowy sposób, bez konieczności późniejszego czyszczenia historii. Zazwyczaj używam RCS do tego w Git lub SVN. Mówię Gitowi, aby ignorował artefakty RCS, sprawdzałem, czy moja praca jest w toku w RCS, a kiedy podoba mi się wynik, po prostu wrzucam *,vpliki lub cały katalog RCS. Po prostu nie uruchamiaj git clean -fdxani nie działaj podobnie, dopóki nie powierzysz swojej pracy „prawdziwemu” SCM, albo będziesz tego żałować.

  4. Nazwane skrytki.

    Kolejny Git-ism, ale przydatny: git stash save --include-untracked <some-cool-title>może być przydatny w szczypaniu. Możesz w ten sposób zapisywać, usuwać i stosować prace w toku oraz przeglądać różne punkty kontrolne za pomocą git stash listlub git reflog --all. Inne SCM mogą mieć podobne funkcje, ale w tym przypadku przebieg może się znacznie różnić.

CodeGnome
źródło
0

Część tego tymczasowego kodu jest tak naprawdę tylko przejawem niewłaściwej metodologii kompilacji / testowania / programowania i mam nadzieję, że ich istnienie będzie motywować do dalszej poprawy.

Przynajmniej na git powinieneś mieć swobodę w manipulowaniu dowolną liczbą gałęzi funkcji, dopóki nie będą gotowe do połączenia w master / trunk.

Kontrola wersji ma ci pomóc , a częściej doceniam spostrzeżenia ze sposobu, w jaki błędy (a może po prostu mniej intuicyjne decyzje) były podejmowane w przeszłości i podejmować bardziej świadome decyzje na teraźniejszość.

prusswan
źródło
0

Wierzę, że niektóre systemy będą wyświetlać ostrzeżenia przed wyświetleniem TODO w komentarzu, więc

// TODO: remove this hack.

może być wszystkim, co jest konieczne, jeśli możesz znaleźć odpowiednią opcję w jakiejś części środowiska programistycznego lub po prostu wstawić jakieś polecenie grep w pliku kompilacji. Może być również możliwe zorganizowanie // HACKlub pobranie dowolnego dowolnego ciągu.

Jest to prostsze niż zorganizowanie kodu w określony sposób i nadzieja, że ​​ludzie będą pamiętać, aby go nie używać. Dzięki temu bezpieczniej jest postępować zgodnie z radą @gbjbaanb (jeśli możesz upewnić się, że wszyscy widzą ostrzeżenia!).

Trzymaj tam wszystko, co ci się podoba, ponieważ pewnego dnia możesz chcieć zobaczyć, co to jest, i to są dni, w których zdajesz sobie sprawę z tego, na czym naprawdę polega Twój SCM.

GKFX
źródło
0

Umieszczenie kodu w kontroli źródła nigdy nie jest szkodliwe.

Każdy z wymienionych elementów powinien mieć kontrolę źródła.

Toby Allen
źródło