2016-02-01 12 views
5

Scenariusz: repozytorium z całkowicie odłączonymi fragmentami historii. Na przykład. z różnych pilotów, które nie mają wspólnej historii git. (Zwykle występuje w scenariuszach z poddrzewem git.)git cherry-wybrać różnicę między commitami bez wspólnej historii?

Czy można wybrać różnicę między tymi dwoma zatwierdzeniami, nawet jeśli nie mają one wspólnej historii? (A aktywny popełnić ma wspólną historię z jednym z tych dwóch)

Próbowałem to (w podkatalogu z -X subtree=sub/dir opcja):

git cherry-pick -X subtree=vendor/package aaa/aaa..bbb/bbb 

Bez poddrzewa, to byłby prostszy:

git cherry-pick aaa/aaa..bbb/bbb 

Gdzie aaa/aaa i bbb/bbb są dwoma zatwierdzeniami z rozłączoną historią.

Niestety, to nie działa: aaa/aaa..bbb/bbb nie jest odczytywany jako diff, ale coś innego.

To samo można wyświetlić za pomocą git show aaa/aaa..bbb/bbb, które różni się od git diff aaa/aaa bbb/bbb. Na przykład. jeśli oba mają identyczne pliki, wtedy git diff będzie pusty, ale git pokazuje a..b pokaże tylko b, ale nie a.


Uwaga: Mój osobisty przypadek użycia jest z tłem poddrzewa. Wspominam o tym, aby uniknąć przypadku sztucznego użycia, gdzie ludzie zwykle zaczynają debatować na temat ważności przypadku użycia, zamiast na faktycznym pytaniu.

Idealna odpowiedź najpierw zajmie się ogólnym przypadkiem, a następnie zajmie się sprawą poddrzewa.

Odpowiedz

2

Od cherry-picking dotyczy diff, byłoby prostsze create a patch an apply it:

git checkout aaa/aaa 
git cherry-pick -n bbb/bbb 
git diff --cached > my.patch 

Następnie kasy regularnego oddziału i git apply my.patch

Dzieje popełnić 'bbb/bbb', porównuje go do jego bezpośrednim przodkiem, następnie stosuje tę różnicę nad "aaa/aaa": można spodziewać się konfliktów. Przetestuj, czy -X subtree=vendor/package pomaga w przypadku poddrzewa.

+0

git apply to dobry pomysł! Ale nie jestem pewien, czy twoje polecenia robią to, co obiecano. – donquixote

+0

Problemem, który widzę przy wyborze jest to, że wybiera tylko ostatnie zatwierdzenie, a nie cały zakres zatwierdzeń prowadzących od aaa/aaa do bbb/bbb (który tak naprawdę nie istnieje - to jest punkt). – donquixote

2

@VonC wskazuje w dobrym kierunku. Kredyt i +1 za ten pomysł.

byłoby prościej stworzyć łatkę zastosować go:

Jednak można to zrobić za pomocą prostego jednej liniowej (to próbowałem i działa dla mnie):

git diff aaa/aaa bbb/bbb | git apply --directory=vendor/package 

Albo w scenariuszu bez poddrzewa:

git diff aaa/aaa bbb/bbb | git apply 

Nie potrzeba git checkout, git cherr y-pick lub tworzenie lokalnego pliku.
Nadal musisz to robić, oczywiście ...

A oto jak to zrobić bez dodawania i/lub pobierania jakichkolwiek poddrzewa zdalnego sterowania. Zamiast tego możesz sklonować repozytoria pakietów do oddzielnych katalogów poza głównym repozytorium projektu.

git --git-dir="/path/to/package/repo/.git" diff aaa bbb | git apply --directory=vendor/package 

Tak jak ja to rozumiem, to wszystko jest jeszcze przede odpowiednik zwykłej przepływu git subtree pracy. Mam na myśli, że historia git głównego projektu będzie taka sama. Popraw mnie, jeśli się mylę.

+0

Jasne, różnica w git jest prawdopodobnie bardziej bezpośrednia (wahałem się między różnicą a wyborem z wiśni). +1 – VonC

Powiązane problemy