Git - co zrobić gdy się scommituje za dużo zmian?

Posted by Piotr Sarnacki Tue, 07 Apr 2009 09:40:00 GMT

Jak zauważył słusznie Radarek w komentarzu taki sam efekt można uzyskać poleceniem git reset --mixed HEAD~1. W tym wypadku można by treść całego posta wyrzucić do kosza, ale zostawię dla potomnych, żeby można było zobaczyć jak trzeba się nagimnastykować jeżeli się nie zajrzy do dokumentacji ;-)

Czasami podczas pracy nad jakimiś większymi zmianami warto rozbić pracę na mniejsze commity. Zdarza mi się czasami dodać przełącznik -a z rozpędu, który commituje wszystkie zmiany. Najgorzej jest gdy wrzucam przy okazji nową wersję jakiegoś plugina do railsów. W takim wypadku zmiany w aplikacji są przeplatane zmianami w pluginie. Później gdy trzeba spojrzeć na coś w logach gita, może to dość znacznie utrudnić pracę.

Na szczęście git jest bardzo elastyczny i łatwo jest takie coś odwrócić.

Wyobraźmy sobie taką sytuację:


  # przechodzę do nowej gałęzi, żeby zaimplementować nowy feature
  git checkout -b feature_200

  #....
  # tutaj dużo zmian, między innymi dodanie 
  # nowego pluginu, uaktualnienie innego, 
  # zmiany w samym kodzie itp. itd.

  # a teraz chcemy scommitować tylko zmiany w 
  # danym pluginie:
  git add vendor/plugins/acts_as_foobar
  git commit -m "Nowa wersja acts_as_foobar kompatybilna z railsami 2.3" -a
  # oj... dodałem -a, scommitowały się też 
  # zmiany w kodzie

Co teraz? Nic trudnego :)


  # tworzymy patche względem mastera
  git format-patch master

W tym momencie powinno pojawić się sporo plików o nazwach na przykład:


0001-Nowa-wersja-acts_as_foobar-kompatybilna-zrailsami-2.3.patch
#... ewentualnie więcej
Teraz trzeba wyrzucić “zepsuty” commit:

  git rebase -i HEAD~3

Teraz powinien otworzyć się edytor, w którym widnieją linijki zaczynające się od słowa pick. Kasujemy linijkę z niechcianym commitem (tutaj uwaga – jeżeli nie jesteście pewni, że wszystko gra, to najlepiej zrobić backup repo, po takim zabiegu commit po prostu zniknie). Po zapisaniu zmian commit powinien zostać wyrzucony z drzewka i można zaaplikować wcześniej stworzonego patcha:


git apply 0001-Nowa-wersja-acts_as_foobar-kompatybilna-zrailsami-2.3.patch

W tym momencie wszystko powinno wyglądać tak jak przed commitem – można teraz poprawić swój błąd.

Wiem, że to może się wydawać skomplikowane (szczególnie rebase), ale w praktyce zajmuje krótką chwilę, a dzięki takiemu zabiegowi nie ma bałaganu w repozytorium.

A może Wy macie jakieś ciekawe metody na rozwiązywanie problemów z gitem? Może inny sposób na powyższy problem?

Posted in  | Tags , ,  | 2 comments | no trackbacks

Comments

  1. Avatar Radarek said 1 day later:

    Tak na szybko to widzę, że załatwisz to jednym poleceniem:

    git reset—mixed HEAD~1

    Osobiście nie używam nigdy opcji -a (czy też git add . na całym drzewie). Więcej z tego szkody niż pożytku.

    “Wiem, że to może się wydawać skomplikowane (szczególnie rebase),”

    git rebase używam bardzo często. Sam git jest trudny, ale zainwestowana nauka w niego się zwraca. Svn nie dawał mi takiej kontroli nad kodem jaką daje git. Łącznie z bezpieczeństwem, że nic złego sobie nie zrobię.

  2. Avatar Piotr Sarnacki said 2 days later:

    Radarek: Dzięki za info. I kolejny RTFM ;-)

    Co do używania -a. Też już staram się nie używać, ale zdarzało mi się często gęsto i teraz muszę leczyć się z tego nawyku.

Trackbacks

Use the following link to trackback from your own site:
http://blog.drogomir.com/articles/trackback/58

(leave url/email »)

   Comment Markup Help Preview comment