git cherry-pick mówi " ... 38c74d jest połączeniem, ale nie podano opcji-m"

Dokonałem pewnych zmian w mojej gałęzi master i chcę je przenieść pod prąd. kiedy wybieram następujące commity jednak utknąłem na fd9f578 gdzie git mówi:

$ git cherry-pick fd9f578
fatal: Commit fd9f57850f6b94b7906e5bbe51a0d75bf638c74d is a merge but no -m option was given.

Co git próbuje mi powiedzieć i czy cherry-pick jest właściwą rzeczą do użycia tutaj? Gałąź master zawiera zmiany w plikach, które zostały zmodyfikowane w gałęzi upstream, więc jestem pewien, że będą jakieś konflikty scalania, ale te nie są takie złe, aby je wyprostować. Wiem, które zmiany są potrzebne gdzie

Są to commity, które chcę wprowadzić pod prąd.

e7d4cff added some comments...
23e6d2a moved static strings...
44cc65a incorporated test ...
40b83d5 whoops delete whitspace...
24f8a50 implemented global.c...
43651c3 cleaned up ...
068b2fe cleaned up version.c ...
fd9f578 Merge branch 'master' of ssh://extgit/git/sessions_common
4172caa cleaned up comments in sessions.c ...
Author: wufoo, 2012-02-10

4 answers

Sposób, w jaki cherry-pick działa polega na pobraniu różnicy, którą reprezentuje zestaw zmian (różnica między drzewem roboczym w tym punkcie a drzewem roboczym jego rodzica) i zastosowaniu go do bieżącej gałęzi.

Tak więc, jeśli commit ma dwóch lub więcej rodziców, reprezentuje również dwa lub więcej różnic - który z nich należy zastosować?

/ Align = "center" bgcolor = "# E0ffe0 " / cesarz Chin / / align = center / Więc musisz powiedzieć komendzie cherry-pick, która z nich powinna obliczyć, korzystając z opcji -m. Na przykład, git cherry-pick -m 1 fd9f578 aby użyć rodzica 1 jako bazy.

Nie mogę powiedzieć na pewno o twojej konkretnej sytuacji, ale użycie git merge zamiast git cherry-pick jest ogólnie wskazane. Gdy wybierzesz commit merge, zwija wszystkie zmiany wprowadzone w rodzicu, którego nie podałeś -m, w ten jeden commit. Tracisz całą ich historię, i glom razem wszystkie ich diffs. Twoja decyzja.

 403
Author: Borealid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-20 20:05:18

@Borealid odpowiedź jest poprawna, ale załóżmy, że nie zależy ci na zachowaniu dokładnej historii scalania gałęzi i po prostu chcesz wybrać jej linearyzowaną wersję. Oto prosty i bezpieczny sposób, aby to zrobić: {]}

Stan początkowy: jesteś na gałęzi X i chcesz wybrać commity Y..Z.

  1. git checkout -b tempZ Z
  2. git rebase Y
  3. git checkout -b newX X
  4. git cherry-pick Y..tempZ
  5. (opcjonalnie) git branch -D tempZ

To co robi to tworzy gałąź tempZ bazując na Z, ale z historią od Y dalej linearyzowaną, a następnie wybierz ją na kopię X o nazwie newX. (Bezpieczniej jest to zrobić na nowej gałęzi zamiast mutować X.) Oczywiście mogą wystąpić konflikty w kroku 4, które będziesz musiał rozwiązać w zwykły sposób (cherry-pick Działa bardzo podobnie do rebase w tym zakresie). Ostatecznie usuwa tymczasową gałąź tempZ.

Jeśli w Kroku 2 pojawi się komunikat "Current branch tempZ is up to date", to Y..Z było już / align = "left" / linear

Następnie przejrzyj newX i sprawdź, czy to zrobił to, co chciałeś.

(uwaga: nie jest to to samo co proste git rebase X gdy na gałęzi Z, ponieważ nie zależy to w żaden sposób od relacji pomiędzy X i Y; mogą istnieć commity pomiędzy wspólnym przodkiem i Y, których nie chciałeś.)

 18
Author: Daira Hopwood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-25 00:26:02

Oto przepisanie zaakceptowanej odpowiedzi, która idealnie wyjaśnia zalety / zagrożenia możliwych podejść:

/ Align = "left" / fd9f578

Zamiast cherry-picking a merge, najprostszą rzeczą jest cherry wybrać commit(y), które chcesz z każdej gałęzi w merge.

Ponieważ już się połączyłeś, prawdopodobnie wszystkie pożądane commity są na twojej liście. Cherry-wybierz je bezpośrednio i nie musisz zadzieraj z commitem merge.

Wyjaśnienie

Sposób, w jaki cherry-pick działa polega na pobraniu różnicy, którą reprezentuje zestaw zmian (różnica między drzewem roboczym w tym punkcie a drzewem roboczym jego rodzica) i zastosowaniu zestawu zmian do bieżącej gałęzi.

Jeśli commit ma dwóch lub więcej rodziców, jak to ma miejsce w przypadku merge, to commit ten również reprezentuje dwa lub więcej różnic. Błąd występuje z powodu niepewności co do tego, który diff powinien aplikuj.

Alternatywy

Jeśli stwierdzisz, że musisz dołączyć merge vs cherry-wybierając powiązane commity, masz dwie opcje:

  1. (bardziej skomplikowane i niejasne; również odrzuca historię) możesz wskazać, który rodzic powinien zastosować.

    • Użyj w tym celu opcji -m. Na przykład, git cherry-pick -m 1 fd9f578 użyje pierwszego rodzica wymienionego w scalaniu jako bazy.

    • Weź również pod uwagę, że gdy wybierzesz commit merge, zapada się wszystkie zmiany wprowadzone w rodzicu, którego nie podałeś -m do tego jednego commita. Tracisz całą ich historię, i glom razem wszystkie ich diffs. Twoja decyzja.

  2. (prostsze i bardziej znane; zachowuje historię) możesz użyć git merge zamiast git cherry-pick.

    • Jak to zwykle bywa z git merge, spróbuje zastosować wszystkie commity, które istnieją w gałęzi, którą łączysz, i wylistuje je indywidualnie w twoim dzienniku git.
 3
Author: Kay V,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-23 14:02:37

Uproszczenie metody @ Daira Hopwood dobre do wybrania jednego commita. Nie potrzebujesz tymczasowych gałęzi.

W przypadku autora:

  • Z is wanted commit (fd9f578)
  • Y jest commit przed nim
  • x bieżąca gałąź robocza

To zrób:

git checkout Z   # move HEAD to wanted commit
git reset Y      # have Z as changes in working tree
git stash        # save Z in stash
git checkout X   # return to working branch
git stash pop    # apply Z to current branch
git commit -a    # do commit
 0
Author: ephemerr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-23 06:49:18