Fixing błąd podczas pracy w innej części podstawy kodu

19

To zdarzyło się przynajmniej raz do mnie. Pracuję nad jakąś częścią kodu i znajduję mały błąd w innej części, a błąd powstrzymuje mnie przed ukończeniem tego, co obecnie próbuję zrobić. Mocowanie błąd może być tak proste, jak zmiana jednego oświadczenia.

Co robicie w takiej sytuacji?

  1. Naprawić błąd i zobowiązać go wraz z obecnej pracy
  2. Zapisz bieżącej pracy gdzie indziej, naprawić błąd w oddzielnym popełnić, a następnie kontynuować pracę [1]
  3. Kontynuować to, co masz robić, popełnić kod (nawet jeśli łamie build nie kilka testów), a następnie naprawić błąd (i kompilacja aby testy przeszły) w oddzielnym popełnienia

[1] W praktyce oznaczałoby to: klon oryginału repozytorium gdzie indziej, naprawić błąd, popełnić / popchnąć zmiany, wyciągnąć zobowiązać się do repozytorium, nad którym pracujesz, scalić zmiany i kontynuować pracę.

Edit: Zmieniłem numer trzy, aby odzwierciedlić to, co naprawdę myśli.

imgx64
źródło
2
Dlaczego nie popełnić zarówno poprawkę błędu i swoją zmianę w pojedynczej transakcji? Jest to dość powszechne, i czyste. Musisz umieścić odpowiednie komentarze w swojej popełnić oczywiście.
@Pierre, to numer 1. Myślę, że mógłbym wybrać lepsze słowo niż silently.
imgx64
I zazwyczaj umieścić kilka poprawek w tym samym popełnić. Odnoszę się do nich za pomocą identyfikatora zadania, a nawet Trac automatycznie dołącza swoje zobowiązania do zadań za pomocą specjalnego haka, który zainstalowałem
2
@Pierre 303 O człowieku, taka złą praktyką! Podzielić zobowiązuje się ziarnisty.
Alternatywą
@mathepic: gdy zmiana dotyczy tylko jednego zadania tak, ale gdy wpływa na wiele zadań, po prostu nie jest to możliwe bez zerwania kompilacji

Odpowiedzi:

15

Zrobiłem 1 i 2, a ostatecznie myślę, że wolę numer 2. Pozwala to na lepszą widoczność poprawki błędu, co może być ważne dla QA / uwag do wydania / innych programistów.

Natknąłem się również na sytuację, w której to, co uważałem za błąd, w rzeczywistości nie było (nie mówiąc, że tak jest w tym przypadku), a „naprawienie” tego w osobnym zatwierdzeniu pozwoliło innemu twórcy skontaktować się ze mną i wyjaśnić, co to było zamiast „naprawić” gubię się podczas normalnego odprawy.

Adam Lear
źródło
11

I zazwyczaj przejść do # 2. Sprawia, że ​​repozytorium jest czystsze, a logi bardziej zrozumiałe. Nienawidzę tego, gdy inni deweloperzy pracuję z zatwierdzeniem 15 różnych poprawek, funkcji i refaktoryzacji w tym samym zatwierdzeniu.

Ponadto, w zależności od tego, jak Twój zespół śledzi defekty, konieczne może być przeszukanie repozytorium defektów, aby upewnić się, że jeśli naprawiana wada jest w środku, oznacza to, że element jest kompletny. Lub może być konieczne utworzenie nowego elementu i oznaczenie go jako ukończonego, aby system defektów i repozytorium kodu były zgodne.

RationalGeek
źródło
7

Robię # 2. Korzystanie z narzędzi takich jak git sprawia, że ​​podział na wiele zatwierdzeń jest banalny. Jeśli nie można przekonać swój zespół, aby przełączyć się do bardziej nowoczesnych narzędzi, git-svn daje przyzwoitą porcję czego można użyć, aby rozwiązać ten problem. Ten blogu daje przegląd dobrego przepływu pracy, który próbujesz rozwiązać: Rzecz o Git

Daenyth
źródło
Dzięki, ten post na blogu jest bardzo przydatny i ma zastosowanie w moim przypadku (używam Mercurial, który mniej więcej ma takie same funkcje jak git). Myślę, że powinienem kiedyś przeczytać Księgę .
imgx64
@ imgx64: Nie wiem, czy to ma odpowiednik indeksu chociaż. To zabójca funkcji git jest IMO
Daenyth
Czytając komentarze w tym poście, Mercurial ma równoważne rozszerzeń. shelveRozszerzenie robi to, co muszę.
imgx64
@ imgx64 Półka może być przydatna, tak. Ale myślę, że rozszerzenie Record jest bardziej odpowiednie. Używam go tylko poprzez interfejs GUI TortoiseHg (możesz kliknąć dwukrotnie plik różnicowy, aby usunąć / dodać go do zatwierdzenia).
barjak
3

Wybieram niepisaną opcję (4): Podziel swój projekt na wysoce wyspecjalizowane zestawy / biblioteki, aby niepowiązane błędy zawsze znajdowały się w innym miejscu w drzewie kontroli wersji.

Przepraszam jeśli powyższe dźwięki snarky, ale mam na myśli to szczerze. Kulę się, gdy widzę monolityczny projekt ze sto formami i przestrzeniami nazw, które nie mają ze sobą nic wspólnego. Często mierzyłem się z tym samym dylematem, zastanawiając się, czy i jak powinienem rozbijać commity dotyczące różnych obszarów funkcjonalnych; Dopiero znacznie później zdałem sobie sprawę, że posiadanie tych wszystkich różnych obszarów funkcjonalnych w ramach jednego projektu, który można zlecić, samo w sobie było poważną wadą projektową.

Nadal często znaleźć zupełnie niepowiązanych błędów, a ja pracuję w funkcji konkretnego. Być może pracuję nad interfejsem użytkownika i znajduję błąd w logice biznesowej i muszę go naprawić, zanim będę mógł przejść dalej. Różnica polega na tym, że logika biznesowa zawsze znajduje się w innym zestawie / projekcie niż interfejs użytkownika, więc wszystko, co muszę zrobić, to dokonać jednej bardzo drobnej zmiany w BL i kontynuować jedną bardzo niewielką zmianę, a następnie kontynuować pracę.

Mając bardzo dobrą organizację projektu sprawia, że nie tylko możliwe, ale dość łatwe do rozwiązania tych problemów bez grzebania zmianę, łamiąc build, lub uzyskiwanie pogrążone w irytujący oddział / scalania (nawet jeśli używasz dvcs to nie jest całkowicie bezbolesny ).

Jeśli brakuje ci tej opcji - tzn. Jesteś młodszym deweloperem, który nie ma nic do powiedzenia w organizacji projektu - po prostu wybrałbym numer 1 i zrobiłbym odpowiednie notatki w dzienniku, aby inni wiedzieli, dlaczego zrobiłeś to, co zrobiłeś. Jeśli popełnił poważne zmiany, a następnie również złożyć raport o błędzie w systemie śledzenia emisyjnej dać wgląd w to, co już ustalone i dlaczego.

Aaronaught
źródło
2
Chociaż się zgadzam, nie działa to we wszystkich sytuacjach. „Błąd w innej części kodu” może być w klasie nadrzędnej lub nawet w innej metodzie w tej samej klasie. Nie można ich rozdzielić w różnych bibliotekach.
imgx64,
@img: Jasne, ale jeśli „inna część” bazy kodu jest w tak bliskiej odległości, co masz w pracy, to prawdopodobnie nawet nie uzasadnia to dużo uwagi - po prostu go naprawić! : P
Aaronaught
1

Staram się zrobić # 2. Jeśli to naprawdę osobny problem, istnieje duże prawdopodobieństwo, że znajduje się on w innym pliku niż ten, nad którym pracujesz. Powinieneś mieć możliwość wpisania pliku jako osobnego zatwierdzenia, nawet jeśli jest on utworzony w tym samym repozytorium, nad którym pracujesz. Ze wszystkich podanych już powodów sensowne jest, aby zatwierdzenia były tak niezależne, jak to możliwe, do śledzenia, a także do cofania zmiany, jeśli jest niepoprawna.

KeithB
źródło
3
Z Git, można podzielić wiele zmian w tym samym pliku na kilku zatwierdzeń - Brakuje mi często nie mając tego podczas pracy nad projektami opartymi SVN.
Peter Boughton
1

I zwykle po prostu naprawić błąd, a następnie kontynuować to, co byłem w pracy. Kiedy nadszedł czas, aby zobowiązać się, przyjmując poprawkę błędu jest w oddzielnym pliku, robię dwie jednoczesne zobowiązuje - pierwszy częściowy popełnić zawierający jedynie poprawkę błędu, a drugi to wszystko.

Uwaga do siebie - myślę o nazwie
źródło
1

Krótka odpowiedź: # 2. Naprawdę chcesz, aby ta poprawka błędu (z notatką w module śledzącym!) Została oznaczona w historii wersji jako osobna jednostka.

Dłuższa odpowiedź:

  • Natknąć się na robaka
  • Napisać test lub więcej wykazując błąd
  • Zdaj test
  • Popełnić tylko, że zmiany i jej badania ( git add --interactivelub darcs record -iczy jednak robi to Twój VCS) (*)
  • Wróć do tego, co robiłem.

(*) W CVS (nie, naprawdę) czasami mam wypisane czyste drzewo, a także kopię, na której pracuję. Następnie używam merge - WinMerge, w moim przypadku - wyciągnąć tylko Bugfix do czystego drzewa więc mogę go popełnić oddzielnie. (Inna opcja, aby zmienić nazwę zmienionych plików cvs updatei scalania. Kiedy już dopuścił się zmienić, usunąć plik i zmienić nazwę Przesunięte pliki z powrotem do ich pierwotnych nazw).

Należy jednak zauważyć, że zwykle znajduję tylko błędy, które są albo związane z tym, nad czym pracuję, albo znajdują się w bliskiej leksykalnej bliskości. Byłbym zaskoczony, gdyby normalne było znajdowanie błędów w niepowiązanych częściach bazy kodu - dlaczego czytasz niepowiązany kod podczas naprawiania błędu? (Tak, jest to dokładne przeciwieństwo tego, co mówi Aaronnaught!)

Frank Shearar
źródło
1

Naprawiam błąd i robię osobne zatwierdzenia , po jednym dla każdej poprawki / funkcji.

Przez większość czasu zmiany nie są w tym samym pliku, więc łatwo jest rozdzielić zatwierdzenia. Jeśli zmiany znajdują się w tym samym pliku, używam TortoiseHg (front-end interfejsu GUI mecurial), aby wybrać dokładnie różnice, które chcę zatwierdzić (myślę, że można to zrobić w wierszu poleceń z rozszerzeniem Record , ale jest to mniej wygodne ).

Niektóre osoby używają kolejek Mercurial do izolowania drobnych poprawek podczas pracy nad funkcją. Drobne poprawki są zestawiane w MQ, a gdy funkcja jest zakończona i zatwierdzona, zatwierdzana jest również zawartość kolejki (jeden zestaw zmian dla każdego wpisu w kolejce).

Barjak
źródło
0

Zwykle robię # 2. Zapisywanie mojej bieżącej pracy w innym miejscu: zwykle działa dobrze, tworząc łatkę. Również niektóre środowiska IDE (IntelliJ) pozwalają na zmiany na półkach, dokładnie to: zapisz bieżącą pracę w innym miejscu.

michid
źródło
0

To, co robię, zależy od tego, czy błąd naprawdę jest w innej części. Jeśli tak, to sprawdzenie go jest niezależne od moich w połowie dokonanych zmian. Dokonuję zmiany, buduję tę inną część, aby upewnić się, że nie popełniłem żadnego trywialnego błędu, testuję go (być może robiąc wszystko, co powstrzymuje mnie od robienia) i sprawdzam, wyjaśniając, co się dzieje. Często zrobię dla niego element roboczy, a po zameldowaniu / rozwiązaniu przydzielę WI testerowi. Potem wracam do tego, co robiłem.

Jeśli wszystko jest uporządkowane z plikami, które zmieniłem w połowie, nie mogę zbudować i przetestować tej części niezależnie. W takim przypadku robię dla niego kolejne WI, a kiedy sprawdzam zmiany, rozwiązuję oba WI z tym samym zameldowaniem, co zwykle jest niezgodne z moimi zasadami, ale w tym przypadku ma zastosowanie.

W obu przypadkach poprawka kończy się testowaniem przeze mnie, sprawdzonym za pomocą jakiegoś śladu, aby ludzie rozumieli, dlaczego losowo zmieniłem ten kod tego dnia, a WI przypisano komuś innemu, aby potwierdzić, że jest poprawny.

Kate Gregory
źródło
0

Robimy # 1. # 2 brzmi dobrze, ale nie mogę powiedzieć, że mieliśmy problemy z # 1, które # 2 by naprawiły.

Dodatkowym czynnikiem w mojej firmie jest to, że tworzymy aplikacje internetowe, a nasze testy przeprowadzane są prawie całkowicie przez interfejs sieciowy - mniej więcej to, co ludzie nazywają testowaniem funkcjonalnym, a nie testowaniem jednostkowym. Wszystkie testy przeszliśmy przed odprawą. Podział zatwierdzeń na mniejsze bity oznaczałoby uruchomienie testów raz dla każdego bitu, co zajęłoby więcej czasu. Chciałbym mieć znacznie szybszy zestaw testów, który pozwoliłby nam wykonywać mniejsze zmiany, ale po prostu tego nie mamy.

Tom Anderson
źródło