Mam dwa repozytoria. W jednym dokonuję zmian w pliku ./hello.test
. Zatwierdzam zmiany i tworzę łatkę z tego zatwierdzenia za pomocą git format-patch -1 HEAD
. Teraz mam drugą repozytorium zawierającego plik, który ma te same treści jak hello.test ale jest umieszczony w innym katalogu pod inną nazwą: ./blue/red/hi.test
. Jak mam się zabrać do zastosowania wyżej wymienionej poprawki do hi.test
pliku? Próbowałem, git am --directory='blue/red' < patch_file
ale to oczywiście narzeka, że pliki nie mają takich samych nazw (o czym myślałem, że Gitowi to nie obchodzi?). Wiem, że prawdopodobnie mógłbym edytować różnice, aby zastosować je do tego konkretnego pliku, ale szukam rozwiązania poleceń.
105
Odpowiedzi:
Możesz utworzyć łatkę za pomocą,
git diff
a następnie zastosować ją za pomocąpatch
narzędzia, które pozwala określić plik, do którego chcesz zastosować różnicę.Na przykład:
źródło
am
lubapply
, ale nie mogę tego znaleźć. Jeśli zauważysz, że często powielasz zmiany, może być lepsze rozwiązanie przy użyciu modułów podrzędnych lub dowolnego języka, który wybierzesz, do udostępniania kodu (np. W Rubim możesz wyodrębnić zduplikowany kod jako klejnot).Istnieje proste rozwiązanie, które nie wymaga ręcznej edycji łatek ani zewnętrznego skryptu.
W pierwszym repozytorium (może to również wyeksportować zakres zatwierdzeń, użyj,
-1
jeśli chcesz wybrać tylko jedno zatwierdzenie):W drugim repozytorium:
Zamiast używać
--relative
ingit format-patch
, innym rozwiązaniem jest użycie-p<n>
opcji in wgit am
celun
usunięcia katalogów ze ścieżki łatek, jak wspomniano w odpowiedzi na podobne pytanie .Możliwe jest również uruchomienie
git format-patch --relative <committish>
bez rozszerzenia--stdout
i wygeneruje zestaw.patch
plików. Pliki te mogą być następnie doprowadzane bezpośrednio dogit am
zgit am --directory blue/red/ path/to/*.patch
.źródło
--directory
opcja wymaga podania pełnej ścieżki katalogu względem katalogu głównego repozytorium; coś takiego jak--directory=./
zmiana katalogu w podkatalogu w repozytorium nie zadziała.--3way
z pomocy zdoes not exist in index
:git am --3way --directory (relative-path) (patch)
-k
klawisza w obu poleceniach, aby nie usuwać pierwszej linii komunikatu o zatwierdzeniu.--3way
nie tylko pomaga w przypadku błędów „nie istnieje w indeksie” (jak wskazał @nobar), ale także pozwala na prostą obsługę konfliktów przy scalaniu. Zamiast pozostawiać konfliktowe pliki nietknięte, dodawany jest blok konfliktu, który można następnie rozwiązać.Odpowiadając na moje pytanie skryptem, który właśnie to robi: https://github.com/mprpic/apply-patch-to-file
Zamiast ręcznie modyfikować plik poprawki, monituje użytkownika o plik docelowy, modyfikuje poprawkę i stosuje ją do repozytorium, w którym aktualnie się znajdujesz.
źródło
Opierając się na odpowiedzi @georgebrock, oto rozwiązanie, którego użyłem:
Najpierw utwórz pliki łatek jak zwykle (np.
git format-patch commitA..commitB
).Następnie upewnij się, że repozytorium docelowe jest czyste (nie powinno być żadnych zmienionych ani nieśledzonych plików) i zastosuj takie łaty:
Dla każdego pliku poprawki zostanie wyświetlony komunikat o błędzie typu „błąd: XYZ nie istnieje w indeksie”. Możesz teraz ręcznie zastosować ten plik poprawki:
Musisz wykonać te trzy kroki dla każdego pliku poprawki.
Pozwoli to zachować oryginalny komunikat o zatwierdzeniu itp. Bez konieczności specjalnego
git format-patch
polecenia lub edytowania plików łaty.źródło
git format-patch -1 commitA --stdout > thing.diff
; (2) Edytuj plik poprawki, dopóki nie zrobi tego, czego potrzebuję; (3) Tekst do zatwierdzenia,git am --3way thing.diff
który ma tę zaletę, że możesz zaakceptować części łatki, które się nakładają, i użyćgit
standardowego procesu rozwiązywania konfliktów dla części, które tego nie robią.Rozumiem, że te dwa pliki są dokładnie takie same w Twojej sytuacji, dlatego łatka prawdopodobnie się powiedzie.
Jednak w przypadku, gdy chcesz zastosować poprawkę do podobnego, ale nie do końca tego samego pliku, lub chcesz wykonać interaktywną łatkę, zastosujesz łączenie trójstronne.
Powiedzmy, że zmodyfikowałeś plik
A
, oznaczmyA~1
jako poprzednią wersję i chcesz zastosować różnicę międzyA~1
doA
do plikuB
.Otwórz narzędzie do łączenia trójstronnego, na przykład Beyond Compare, ścieżka lewego panelu to
A
, środkowy panel jest wspólnym przodkiem, więc ścieżka jestA~1
, ścieżka prawego panelu toB
. Następnie dolny panel pokazuje wynik zastosowania różnicy międzyA~1
doA
do plikuB
.Poniższy rysunek ilustruje ten pomysł.
źródło
FYI: Niedawno miałem problemy z próbą pobrania łatki z Github i umieszczenia jej w pliku lokalnym (co było „przesłonięciem” w nowej lokalizacji).
git am
też nie zastosowałby poprawki, ponieważ plik był „nie w indeksie” lub „brudny”. Ale odkryłem, że prostepatch
polecenie może zastosować poprawkę. Zapytał mnie o nazwę pliku do załatania.W każdym razie wykonałem swoją pracę ...
źródło