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?
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
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.
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