Mainline parent number when cherry picking merge commits

Przypuśćmy, że to jest moja historia Gita

  Z
 /
A -- C -- D
 \  /      
  B

Moja głowa jest obecnie w Z. Chcę wybrać B i C. Jeśli moje zrozumienie jest poprawne, powinienem to zrobić:

git cherry-pick B
git cherry-pick C -m 1
git commit --allow-empty

Zadziałało w moim przypadku, ponieważ C jest no-op (stąd pusty commit potem, potrzebowałem commita z innych powodów), ale zastanawiam się, co robi parametr po -m. Oto co przeczytałem z the docs :

-na parent-number

--mainline parent-number

Zazwyczaj nie możesz wybrać połączenia, ponieważ nie wiesz, która strona połączenia powinna być uważana za linię główną. Ta opcja określa numer rodzica (zaczynając od 1) linii głównej i pozwala cherry-pick odtworzyć zmianę względem podanego rodzica.

W moim przypadku, C ma dwoje rodziców, ale skąd mam wiedzieć, który z nich jest 1 i 2, a co ważniejsze, kiedy ma znaczenie, gdy wybieram 1 albo 2?

Author: Community, 2016-10-20

2 answers

Moje zrozumienie oparte na ta odpowiedź jest taka, że rodzic 1 jest gałęzią scalaną, a rodzic 2 jest gałęzią scalaną z. Więc w Twoim przypadku rodzic 1 to A, a rodzic 2 to B. Ponieważ cherry-pick naprawdę stosuje różnice między dwoma zatwierdzeniami, używasz -m 1, Aby zastosować tylko zmiany z B (ponieważ różnice między A i C zawierają zmiany z B). W Twoim przypadku prawdopodobnie nie ma to znaczenia, ponieważ nie masz commitów pomiędzy A i C.

Więc tak, -m 1 jest tym, czego chcesz, i to jest prawdą, nawet jeśli istnieją dodatkowe commity między A i C.

Jeśli chcesz, aby nowa historia wyglądała trochę bardziej jak oryginalna, jest inny sposób, aby to zrobić: {]}

git cherry-pick B
git checkout Z
git merge --no-ff --no-commit B
git commit --author="Some Dev <[email protected]>" --date="<commit C author date>"

(W razie potrzeby możesz utworzyć nową gałąź dla B przed wybraniem wiśni.)

To zachowa informacje o autorze, powinno dać historię, która wygląda tak:

    B'
   /  \
  Z -- C'
 /
A -- C -- D
 \  /      
  B
 44
Author: Scott Weldon,
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
2016-10-21 00:34:53

Podałem odpowiedź Scotta Weldona, która jest poprawna, ale chcę tylko dodać próbę sztuki ASCII, która zawiera numerację rodzica. Biorąc pod uwagę wykres, który wygląda tak:

       B
      / \
...--A   D--...
      \ /
       C

Możemy stwierdzić, że NODE D jest commitem scalającym, ale nie możemy stwierdzić, czy B Czy C jest pierwszym rodzicem D. Jeden z nich jest koniecznie pierwszym rodzicem, a drugi drugim. Więc jeśli musimy wiedzieć, musimy oznaczyć rysunek, który zajmuje więcej miejsca. Oto jeden z takich próba.

         B
       /   \²
...--A       D--...
       \   /¹
         C

Widzimy teraz, że z jakiegoś powodu,1 narysowałem wykres "do góry nogami": ten commit C jest w rzeczywistości pierwszym rodzicem D, podczas gdy commit B jest drugim rodzicem.

Możliwe jest tworzenie dowolnych połączeń przy użyciu poleceń niższego poziomu ("hydraulika"). W szczególności git commit-tree pobiera tyle argumentów, ile chcesz mu podać, w kolejności, w jakiej je podajesz, i tworzy nowy commit z podanymi commitami jako jego rodzicami. Daj to jeden -p i tworzy zwykły commit z jednym rodzicem. Nie podawaj argumentów -p i tworzy commit root. Podaj mu 155 odrębnych argumentów -p (wszystkie muszą oczywiście rozwiązać się na poprawne identyfikatory commitów) i tworzy jeden ogromny commit scalający octopus.

Komenda git merge zawsze tworzy nowy commit, a pierwszym rodzicem jest bieżący HEAD (stąd bieżąca gałąź, jeśli jest w gałęzi). Drugi rodzic, dla standardowego połączenia dwóch rodziców, pochodzi z .git/MERGE_HEAD, do którego git merge zapisuje drugi identyfikator commita. Jeśli połączenie jest skonfliktowane lub ostateczny commit scalający jest opóźniony o --no-commit, ten plik MERGE_HEAD jest w rzeczywistości tylko miejscem, w którym dostępny jest identyfikator commitu.

(kiedy git merge tworzy połączenie ośmiornicy, używając strategii -s octopus-ta strategia jest zmuszona do takich połączeń-i wielu dodatkowych rodziców, przerywa i nie pozostawia żadnego śladu, jeśli istnieją konflikty scalania, więc przypadek konfliktu nigdy nie występuje. Nie próbowałem łączyć --no-commit z ośmiornicą połączenie, ale logicznie rzecz biorąc, pozostawiłoby 2-gie przez N ' tych rodziców w MERGE_HEAD, jeśli Git w ogóle na to pozwala.)


1upór.

 2
Author: torek,
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
2017-05-23 11:54:22