Wyciągnij wszystkie zatwierdzenia z gałęzi, prześlij określone zatwierdzenia do innej


102

Mam następujące oddziały:

  • master
  • production

oraz następujące zdalne oddziały:

  • origin/master
  • origin/production

Mam skrypt, który pobiera origin/mastergałąź i pobiera różnicę tego, co zmieniło się od mojego ostatniego fetch ( log -p master..origin/master). Potem łączę się origin/master.

Znalezione zatwierdzenia są przekazywane do narzędzia do przeglądania kodu.

Chcę skierować udane commity - i tylko je - do gałęzi produkcyjnej, a potem oczywiście do origin/production.

Jak mogę to zrobić?

Mam również uruchomione 2 skrypty: ten, który pobiera z origin/master, przekazuje szczegóły zatwierdzeń do bazy danych i łączy, oraz drugi, który właśnie piszę, i który będzie musiał wypychać udane zatwierdzenia.

Chciałbym, aby te 2 skrypty działały, unikając konfliktu warunków wyścigu / scalania. Ponieważ chcę pracować tylko z określonymi zatwierdzeniami, może jest sposób na pozbycie się zatwierdzeń, których nie chcę?


Co masz na myśli mówiąc o „udanych zatwierdzeniach”?
bdonlan

ten, który został sprawdzony i oznaczony jako pomyślny. to naprawdę nie ma znaczenia, ważne jest to, że są zatwierdzenia, które chcę zachować i wypchnąć do innej gałęzi, a także inne, których chcę się pozbyć / zignorować.
Sylvain

Odpowiedzi:


313

Wydaje mi się, że termin, którego szukasz, to „wiśniowy wybór”. Oznacza to, że weź pojedynczy commit ze środka jednej gałęzi i dodaj go do innego:

A-----B------C
 \
  \
   D

staje się

A-----B------C
 \
  \
   D-----C'

Można to oczywiście zrobić za pomocą polecenia git cherry-pick.

Problem z tym zatwierdzeniem polega na tym, że git uważa, że ​​zatwierdzenia zawierają całą historię przed nimi - więc jeśli masz trzy takie zatwierdzenia:

A-----B-----C

I spróbuj pozbyć się B, musisz stworzyć zupełnie nowy commit, taki jak:

A-----------C'

Gdzie C 'ma inny identyfikator SHA-1. Podobnie, wiśniowe wybieranie zmiany z jednej gałęzi do drugiej polega w zasadzie na wygenerowaniu łatki, a następnie zastosowaniu jej, a tym samym utracie historii w ten sposób.

Ta zmiana identyfikatorów zatwierdzeń łamie między innymi funkcjonalność scalania git (chociaż jeśli jest używana oszczędnie, istnieją heurystyki, które to opisują). Co ważniejsze, ignoruje zależności funkcjonalne - jeśli C faktycznie używał funkcji zdefiniowanej w B, nigdy się nie dowiesz.

Być może lepszym sposobem radzenia sobie z tym byłoby posiadanie bardziej drobnoziarnistych gałęzi. Oznacza to, że zamiast po prostu mieć „master”, miej „featureA”, „bugfixB” itd. Przeprowadź przegląd kodu na całej gałęzi na raz - gdzie każda gałąź jest bardzo skoncentrowana na robieniu tylko jednej rzeczy - a następnie połącz ją jedna gałąź, kiedy skończysz. To jest przepływ pracy, do którego jest przeznaczony git iw czym jest dobry :)

Jeśli nalegasz na zajmowanie się rzeczami na poziomie łatek, możesz spojrzeć na darcs - traktuje repozytorium jako zestaw łatek, a zatem wybieranie wiśni staje się podstawową operacją. Ma to jednak swój własny zestaw problemów, takich jak bycie bardzo wolnym :)

Edycja: Poza tym nie jestem pewien, czy rozumiem twoje drugie pytanie, dotyczące dwóch skryptów. Może mógłbyś opisać to bardziej szczegółowo, być może jako osobne pytanie, aby uniknąć zamieszania?


Jeśli chodzi o moje drugie pytanie, chcę się tylko upewnić, że procesy pobierania zmian (pierwszy skrypt) i wypychanie danych zatwierdzeń do innej lokalizacji (drugi skrypt) mogą działać bez sytuacji wyścigu / konfliktu scalania, podczas pracy z różnymi gałęziami. Ale ostatecznie myślę, że to nie ma znaczenia, ponieważ mogłem połączyć 2 skrypty w jeden, więc 2 skrypty nie działają jednocześnie :)
Sylvain

9
„Ta zmiana identyfikatorów zatwierdzeń łamie między innymi funkcjonalność scalania gita
Narek

5
@Narek Prawdopodobnie oznacza to, że zmiany w zatwierdzeniu C 'będą kolidować z tymi samymi zmianami w zatwierdzeniu C, gdy scalisz drugą gałąź. To konsekwencja utraty historii za popełnieniem C.
bytefu,

1
„I spróbuj się pozbyć B” - dlaczego próbujesz się pozbyć B?
d512

3
@ user1334007, ma na myśli, że wcześniej było to ABC. Teraz, ze względu na Twój ulubiony C, twoja gałąź to AD-C ”, która nie zawiera już„ B ”.
AnneTheAgile

1

Zdaję sobie sprawę, że to stare pytanie, ale odwołuje się do niego tutaj: Jak scalić określone zatwierdzenie w Git

Stąd nowsza odpowiedź: użyj gałęzi funkcji i żądań ściągnięcia.

Jak to wygląda, gdzie fA jest zatwierdzeniem z funkcją A, a fB jest zatwierdzeniem z funkcją B:

            fA   fC (bad commit, don't merge)
           /  \ /
master ----A----B----C
                \  /
                 fB

Żądania pull są powiązane z funkcjonalnością GitHub, ale tak naprawdę mam na myśli tylko to, że ktoś jest odpowiedzialny za scalenie gałęzi funkcji w master.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.