'git stash apply' w trybie interaktywnym
Mam serie plików do schowka (stash{0}
) i chciałbym git apply
tylko niektóre części / fragmenty tych plików(zwykle znane jako Tryb interaktywny ).
Widziałem, że można wykonać
git stash save -p 'Stash name'
Ale wydaje się, że nie jest to możliwe
git stash apply -p 'Stash name'
Wiesz jak to osiągnąć? 4 answers
Tak jest!Czy to możliwe?
git checkout -p stash@{0}
Gdzie możesz zastąpić 0
w stash@{0}
indeksem skrytki, którą chcesz zastosować.
Użyj git stash list
i git show -p stash@{n}
jeśli nie jesteś pewien, który n
jest skrytką, którą chcesz zastosować.
Nie zapomnij git stash drop stash@{n}
Kiedy wiesz, że nie potrzebujesz już tego schowka, ponieważ git checkout
oczywiście nie upuści go dla Ciebie.
Dlaczego to działa?
Kluczem jest uświadomienie sobie, że staśki są w istocie, odwołuje się do commity tak jak znaczniki i gałęzie.
W rzeczy samej, są one przechowywane w.git/refs/stash
, jednej linii na hash skrytki.
Caveats
Jak @mgadda wspomniano w komentarzach poniżej, git checkout -p
próbuje zastosować całą różnicę między zatwierdzeniem a bieżącą przestrzenią roboczą.
W przypadku Git stash, jeśli skrytka, którą próbujesz zastosować, została wykonana przeciwko innemu zatwierdzeniu, to git checkout -p stash@{n}
spróbuje zastosować interaktywnie wszystkie różnice między zatwierdzeniem stash@{n}
a zatwierdzeniem bieżącej przestrzeni roboczej, łącznie ze wszystkimi zatwierdzeniami nadrzędnymi, które są różne .
Na przykład, jeśli próbujesz zastosować skrytkę, która została zapisana "wiele commitów temu" w bieżącym obszarze roboczym, git checkout -p stash@{n}
spróbuje zastosować nie tylko zmiany w skrytce, ale także spróbuje przywrócić wszystkie zmiany, które zaszły pomiędzy zatwierdzeniem, na którym skrytka jest oparta, a aktualnym zatwierdzeniem.
Odwrotnie, jeśli próbujesz zastosować skrytkę "z przyszłości", tzn. do gałęzi, która jest liczbą commitów sprzed zatwierdzenia, na którym skrytka jest oparta, to git checkout -p stash@{n}
spróbuje również zastosować wszystkie inne zmiany, które zaszły między aktualnym zatwierdzeniem a zatwierdzeniem z przyszłości, oprócz zmian z samego skrytki.
(jeśli się zastanawiasz, git checkout -p stash@{n}
skrytka z gałęzi równoległej spróbuje przywrócić wszystkie zmiany pomiędzy aktualnym zatwierdzeniem a oryginalnym punktem rozgałęzienia i stosują również wszystkie zmiany między punktem rozgałęzienia a drugą gałęzią, oprócz zmiany w skrytce).
Obejścia
Istnieje kilka obejść, żaden z nich nie jest idealny dla każdej sytuacji:]}- bądź bardzo ostrożny z plastrami, które akceptujesz, kiedy to robisz
git checkout -p stash@{n}
- bądź bardzo ostrożny z plastrami, które akceptujesz, kiedy to robisz
- zrób
git stash pop
, a następniegit stash
Jeszcze raz przedgit checkout -p ...
. Ale jeśli chcesz zrobić częściowe zastosowanie skrytki, aby uniknąć konfliktów, to nie pomoże. W takim przypadku patrz rozwiązanie 4 poniżej.
- zrób
-
Jeśli masz graficzne narzędzie różnicujące obsługiwane przez git (jak meld ), możesz użyć
git difftool
i "zastosować w lewo" tylko zmiany, które Cię interesują:-
git difftool -d stash@{n}
aby porównać cały schowek i wszystkie jego pliki -
git difftool stash@{n} -- path/to/file
aby porównać pojedynczy plik
-
-
- (na podstawie odpowiedzi @ Andrzej) na odłączona Głowa, wróć do commitu "rodzica" interesującego cię skrytki, zastosuj skrytkę, ponownie Schowaj interaktywnie tylko te części, które Cię interesują, wróć i ponownie zastosuj mniejszy skrytkę.
Krok po kroku:
git checkout stash@{n}^ # notice the "^".
# Now you're in a detached head in the parent commit of the stash.
# It can be applied cleanly:
git stash apply stash@{n}
# Now save only the diffs you're interested in:
git stash -p
# remove the rest of the old stash
git checkout -- . # be careful or you could remove unrelated changes
# go back to the branch where you want to apply the smaller stash
git checkout <my previous branch>
# apply the smaller stash
git stash pop
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
2018-07-20 19:52:18
To, co często robię (w Git bash) to
git stash show -p 'stash@{0}' >tmp.patch
Następnie edytuję plik i usuwam części, których nie chcę. Wreszcie mówię
<tmp.patch git apply
Lub
<tmp.patch patch -p1
Nie działa to jednak w przypadku plików binarnych, ale akceptowana odpowiedź (używając checkOut-p)również nie działa.
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
2019-12-18 08:18:58
Jednym z możliwych sposobów jest zresetowanie indeksu, a następnie użycie interaktywnego add
# 0. ensure there are no uncommitted changes
git status
# 1. apply a changeset as is
git stash apply stash@{n}
# ... fix or discard conflicts if any
# 2. reset the index
git reset
# 3. interactively add the required chunks (except new files)
git add -p
# 4. stash all other changes
git stash save --keep-index "comment"
# 4. or just discards all other changes in the working tree
git checkout-index -f -a
# 5. commit
git commit -m "comment"
Innym sposobem jest użycie interaktywnego resetu zamiast interaktywnego dodawania.
# 0. ensure the working tree does not have unstaged changes
git status
# 1. apply a changeset as is
git stash apply stash@{n}
# ... fix or discard conflicts if any
# 2. interactively exclude the unneeded chunks from the index
git reset -p
# 3. stash all other changes
git stash save --keep-index "comment"
# 3. or just discards all other changes in the working tree
git checkout-index -f -a
# 4. commit
git commit -m "comment"
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
2018-09-05 13:22:22
Myślę, że nie ma sposobu, aby zastosować zmiany przez hunks (lub nawet przez plik). Będziesz musiał zastosować skrytkę, a następnie ukryć zmiany, których nie chcesz interaktywnie(za pomocą git stash save -p
). Jeśli obawiasz się konfliktów, możesz najpierw ukryć niezakontraktowane zmiany, zastosować skrytkę, ukryć sprzeczne fragmenty, a następnie zastosować drugą skrytkę.
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-03-04 11:18:53