2015-01-28 15 views
17

mam serie plików w zapasach (stash{0}) i chciałbym git applytylko niektóre części/hunks tych plików (zwykle znany jako trybie interaktywnym).„git stash zastosowanie” w trybie interaktywnym

Czy to możliwe?

Widziałem, że jest to możliwe do wykonania

git stash save -p 'Stash name' 

ale to nie wydaje się możliwe, aby zrobić

git stash apply -p 'Stash name' 

Znasz drogę, aby go osiągnąć?

Odpowiedz

19

Czy to możliwe?

Tak jest!

git checkout -p [email protected]{0} 

Gdzie można wymienić 0 w [email protected]{0} z indeksem na zapas, który chcesz zastosować.

Użyj git stash list i git show -p [email protected]{n}, jeśli nie masz pewności, która n to skrytka, którą chcesz zastosować.

Nie zapomnij o git stash drop [email protected]{n}, gdy wiesz, że nie potrzebujesz już tego skrytka, ponieważ git checkout oczywiście nie upuści za ciebie skrytki.

Dlaczego to działa?

Kluczem jest uświadomienie sobie, że skrytki są, w istocie, references do commits, podobnie jak znaczniki i gałęzie.

Rzeczywiście, są one przechowywane w .git/refs/stash, jedna linia na mieszanie zapasów.

Ostrzeżenia

Jak @mgadda wymienione int komentarzach poniżej, git checkout -p próbuje zastosować całą różnicę między popełnienia oraz bieżącym obszarze roboczym.

W przypadku zapas git, jeżeli zapas starasz się stosować zostało zrobione przed inną popełnienia, następnie git checkout -p [email protected]{n} postara się interaktywnie zastosować wszystkie różnice między [email protected]{n}a wszystko to rodzic popełnia i prąd przestrzeń robocza.

Na przykład, jeśli próbujesz zastosować zapas, który został zapisany „wielu commity temu” w bieżącym obszarze roboczym, git checkout -p [email protected]{n} spróbuje zastosować nie tylko zmiany w zapasach właściwego, ale także spróbować revert wszystkie zmiany, które nastąpiły między zatwierdzeniem, na którym opiera się przechowalnia, a bieżącym zatwierdzeniem.

Podobnie, jeśli próbujesz zastosować skrytkę "z przyszłości", tj. Do gałęzi, która jest liczbą zatwierdzeń przed zatwierdzeniem, na którym bazuje, wtedy git checkout -p [email protected]{n} spróbuje również zastosować wszystkie inne zmiany, które nastąpiły między bieżącym zatwierdzeniem a zatwierdzeniem z przyszłości, poza zmianami ze samej skrytki.

(W przypadku, gdy zastanawiasz się, git checkout -p [email protected]{n} zapas z równoległego oddziału spróbuje przywrócić wszystkie zmiany między obecny popełnić i oryginalny punkt rozgałęzienia i zastosować również wszelkie zmiany pomiędzy punktem rozgałęzienia, a drugi oddział, oprócz zmiany w skrytce).

Istnieje kilka obejścia, żaden z nich idealne są idealne dla każdej sytuacji:

  1. być bardzo ostrożnym z łatami akceptację kiedy robisz git checkout -p [email protected]{n}

  2. Wykonaj git stash pop, następnie git stash ponownie przed wykonaniem git checkout -p .... Ale jeśli chcesz zrobić częściowe zastosowanie swojej skórki, aby uniknąć konfliktów, to tak naprawdę nie pomoże.

  3. Jeśli masz graficznego narzędzia diff obsługiwanego przez git (jak meld), można użyć git difftool i „lewo” stosuje wszystkie zmiany jesteś zainteresowany.

+0

Istnieje zastrzeżenie, o którym trzeba wspomnieć: ponieważ skrytki są tylko zatwierdzeniami, oznacza to, że mają także nadrzędne zatwierdzenia, które nie gwarantują tego samego nadrzędnego zatwierdzenia, co ten, do którego chcesz interaktywnie zastosować zmiany. Zasada: jeśli ukryłeś się przed jakimś innym zatwierdzeniem niż aktualnie zatwierdzony commit, ta technika nie zrobi tego, czego oczekujesz. Obejście: zastosuj cały zestaw zmian ze swojego skrytka (z git skrytką pop), a następnie ponownie przechowuj (git ukryj). Teraz możesz git -out zgodnie z życzeniem. – mgadda

+0

@mgadda, dziękuję. Dodałem sekcję "zastrzeżeń". – LeoRochael

1

Nie sądzę, że istnieje sposób na zastosowanie zmian przez porcje (lub nawet przez plik). Będziesz musiał zastosować skrytkę, a następnie przechować zmiany, których nie chcesz interakcyjnie (z git stash save -p). Jeśli martwisz się konfliktami, możesz najpierw ukryć wszelkie niezatwierdzone zmiany, zastosować swoją skrzynkę, przechować wszystkie konflikty, a następnie zastosować inne.

+0

Tak, głównie proszę, bo chcę uniknąć konfliktów. Celem jest uzyskanie pewnych zmian z (powiedzmy) * branch_A * i być w stanie umieścić je na * branch_B *, dzięki czemu można bezpośrednio uniknąć konfliktów, które mogą mieć te dwie gałęzie. Twoje rozwiązanie działa, ale jest dokładnie "skomplikowanym" sposobem, którego chciałem uniknąć ;-P – Kamafeather

+0

Odwrotne podejście, aby "git ukryć" interaktywnie porcje, które ja * chcę *, a następnie przywrócić je na wybranej gałęzi, zamiast tego 'git stash apply 'interaktywnie porcje, które ja * chcę *, wydaje się najlepszym podejściem. – Kamafeather

Powiązane problemy