Ponowne wyskakiwanie i ukrywanie nie zawsze jest opcją, ponieważ ukrywanie może być oparte na nieaktualnym stanie i powodować konflikty podczas wyskakiwania. (Przestarzały stan nie musi już nawet nigdzie istnieć w historii.)
Tom
Odpowiedzi:
258
Załóżmy, że twoja lista zapasów wygląda następująco:
$ git stash list
stash@{0}: WIP on master: Add some very important feature
stash@{1}: WIP on master: Fix some silly bug
Najpierw musisz usunąć ukryty wpis, którego nazwę chcesz zmienić:
$ git stash drop stash@{1}
Dropped stash@{1} (af8fdeee49a03d1b4609f294635e7f0d622e03db)
Teraz po prostu dodaj go ponownie z nową wiadomością przy użyciu sha zatwierdzenia zwróconej po upuszczeniu:
$ git stash store -m "Very descriptive message" af8fdeee49a03d1b4609f294635e7f0d622e03db
I to wszystko:
$ git stash list
stash@{0}: Very descriptive message
stash@{1}: WIP on master: Add some very important feature
To rozwiązanie wymaga git 1.8.4 lub nowszego i tak, działa również z brudnym katalogiem roboczym.
git show stash@{0}nadal wyświetla stare informacje później. Jak to naprawić? (Należy pamiętać, że skrytka otrzymuje wtedy inny SHA.)
Tino
4
Lepiej jest uzyskać skrót git showi zacząć od git stash store. Następnie git stash listzobaczysz starą i nową skrytkę. Wreszcie możesz wyczyścić starą skrytkę za pomocą git stash drop.
hogi,
6
czy upuszczenie git nie straci zmian?
Shravya Boggarapu,
4
@ShravyaBoggarapu, nie, git nie usuwa zmian aż do git gcuruchomienia. Po stash droptym, jak łatwo możesz znaleźć to normalnie niedostępne zatwierdzenie za pomocą git fsck | grep commitpolecenia.
qzb
2
@ ÐerÆndi po prostu zastosowanie i zapisanie jest łatwą opcją, ale nie działa, gdy zmiany nie mogą być ponownie zastosowane z powodu konfliktów. Tymczasem upuszczanie i przechowywanie działa w każdych okolicznościach. Ponownie przetestowałem moje rozwiązanie - działa ono dobrze w najnowszej wersji git (2.17.0).
qzb
62
Jeśli nie zrobisz tego ręcznie lub nie wprowadzisz ulepszeń do Git, możesz użyć aliasu:
$ git stash list
stash@{0}: On master: Pep8 format
stash@{1}: On master: co other than master with local changes
stash@{2}: On master: tests with deployAtEnd
# Let's say I want to rename the stash@{2} adding an issue reference:
$ git stash-rename stash@{2} NXP-13971-deployAtEnd
$ git stash list
stash@{0}: On master: NXP-13971-deployAtEnd
stash@{1}: On master: Pep8 format
stash@{2}: On master: co other than master with local changes
To zadziała, nawet jeśli masz lokalne zmiany niestacjonarne :)
Niesamowite! Jeszcze git stash-rename 'tests with deployAtEnd' 'NXP-13971-deployAtEnd'
fajniej,
3
więc odpowiedź brzmi: 1) czysta kopia robocza, 2) zastosuj skrytkę, której nazwę chcesz zmienić, 3) upuść ją z listy skrytek, 4) utwórz nową skrytkę z poprawnym komunikatem.
gcb
2
Aby to wyjaśnić, zmieniasz nazwę ostatniej skrytki, a po takiej akcji staje się ona górną skrytką?
onebree
2
Usuwam skrytkę, aby zmienić nazwę, zapisuję bieżące zmiany, jeśli takie istnieją, ponownie tworzę skasowaną skrytkę z żądaną nazwą, ponownie stosuję bieżące zmiany, jeśli takie istnieją.
Julien Carsique,
3
Ta wersja sprawdza, czy oba argumenty są dostępne, aby nie przypadkowo upuściła ostatnią skrytkę. Wymaga także tylko numeru skrytki, a nie całego numeru stash@{0}referencyjnego. gist.github.com/jdforsythe/f248bf6c72fc020225cc3e315a32e922git config --global alias.stash-rename '!_() { if [ -z \"$1\" ] || [ -z \"$2\" ]; then echo \"git stash-rename 0 NewName\" && echo \"\" && git stash list && exit 1; else stash=\"stash@{$1}\"; rev=$(git rev-parse \"${stash}\"); git stash drop \"${stash}\" || exit 1; git stash store -m \"$2\" \"$rev\" || exit 1; git stash list; fi }; _'
jdforsythe
6
To jest bardzo proste. Najpierw cofnij ostatni schowek za pomocą:
git stash pop
Następnie możesz zapisać skrytkę o niestandardowej nazwie w następujący sposób:
Zaimplementuj nowe git reflog updatepolecenie, które aktualizuje komunikat związany z konkretnym wpisem do dziennika ponownego logowania. Aby to zrobić, nowa update_reflog_ent()funkcja (w reflog.c ) zmieniłaby komunikat związany z konkretnym wpisem reflog do aktualizacji. Użyłaby update_reflog()funkcjifor_each_reflog_ent() z update_reflog_entfaktycznie zrobić zmianę.
git stash renameKomenda będzie wtedy trzeba tylko na wezwaniegit
reflog update z odpowiednim odnośniku i nowej wiadomości.
Możesz też oczywiście wyskoczyć z magazynu i zrobić git stash save [message]
Przełącz się z powrotem (zakładając, że pochodzisz z „mistrza”) i oczyść
Wady:
Tymczasowo przełącza gałęzie. Więc ten przepis można zastosować tylko wtedy, gdy git status --porcelainjest czysty (czytaj: nic nie wyświetla)
Zmienia numerację skrytek, więc zmienia się skrytka stash@{0}
Musisz wpisać $MESSAGEdwukrotnie lub użyć zmiennej środowiskowej (w przykładzie MESSAGE:)
Musisz znaleźć nieużywaną nazwę oddziału
Istnieją sposoby na to bez przełączania gałęzi, ale wykracza to poza zakres tej odpowiedzi.
Przykład
git init scratch
cd scratch
for a in A B C D; do date >$a; git add $a; git commit -m $a; done
for a in X Y; do echo $a > Z; git stash save --all; done
git log --oneline --graph --decorate --all; git stash list
Wynik
*-. e0e281b (refs/stash) WIP on master: 8bdcc32 D
|\ \
| | * 4d62f52 untracked files on master: 8bdcc32 D
| * 096f158 index on master: 8bdcc32 D
|/
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: WIP on master: 8bdcc32 D
stash@{1}: WIP on master: 8bdcc32 D
Teraz bez zmiany zatwierdzenia (uwaga: poniższe SHA będą inne po twojej stronie):
git stash drop stash@{1}
git stash store -m ...changed... 2fbf9007dfdfb95ae269a19e13b8b9ca3e24181c
git log --oneline --graph --decorate --all; git stash list
Wynik
*-. 2fbf900 (refs/stash) WIP on master: 8bdcc32 D
|\ \
| | * 246dc5c untracked files on master: 8bdcc32 D
| * 80c5ea0 index on master: 8bdcc32 D
|/
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: ...changed...
stash@{1}: WIP on master: 8bdcc32 D
Jak widać, stash@{0}nadal jest pokazany jak 2fbf900 (refs/stash) WIP on master: 8bdcc32 Dw git log. Jeśli przyjrzysz się uważnie, zobaczysz, że kilka zmian zmieniło SHA. Wynika to z tego, jak obsługiwane są skrytki (rodzice są uwzględnieni w SHA, a skrytki mają swoje skrytki jako rodzic).
Napraw to:
git checkout -b scratch stash
git stash drop
git commit --amend -m ...changed...
git stash store -m ...changed... HEAD
git checkout master
git branch -D scratch
git log --oneline --graph --decorate --all; git stash list
Wynik
*-. 4d55186 (refs/stash) ...changed...
|\ \
| | * 246dc5c untracked files on master: 8bdcc32 D
| * 80c5ea0 index on master: 8bdcc32 D
|/
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: ...changed...
stash@{1}: WIP on master: 8bdcc32 D
Warto wspomnieć: niszczy to indeks, który został zapisany z oryginalną skrytką, zastępując go nowym indeksem, który pasuje do nadrzędnego zatwierdzenia oryginalnej skrytki. Jeśli nie planowano użyć oryginalnego zapisanego indeksu (lub już pasował do elementu nadrzędnego oryginalnej skrytki), nie stanowi to problemu.
torek
1
Oto zmodyfikowana wersja aliasu Juliena, która pozwala poprawnie radzić sobie z On <branch>prefiksem zwykle poprzedzającym ukrywanie nazw:
repo[master] % touch tmp && git add tmp && git stash save first
Saved working directory and index state On master: first
HEAD is now at bd62064 Initial commit
repo[master] % touch tmp && git add tmp && git stash save second
Saved working directory and index state On master: second
HEAD is now at bd62064 Initial commit
repo[master] % git stash list
stash@{0}: On master: second
stash@{1}: On master: first
repo[master] % git stash-rename renamed
stash@{0}: On master: renamed
stash@{1}: On master: first
repo[master] % git stash-rename also-renamed stash@{1}
stash@{0}: On master: also-renamed
stash@{1}: On master: renamed
repo[master] % git stash-rename branch-changed stash@{0} new-branch
stash@{0}: On new-branch: branch-changed
stash@{1}: On master: renamed
repo[master] % git stash-rename branch-name-persists
stash@{0}: On new-branch: branch-name-persists
stash@{1}: On master: renamed
repo[master] % git stash-rename no-branch stash@{0} .
stash@{0}: no-branch
stash@{1}: On master: renamed
repo[master] % git stash-rename renamed
stash@{0}: renamed
stash@{1}: On master: renamed
repo[master] % git stash-rename readd-branch stash@{0} develop
stash@{0}: On develop: readd-branch
stash@{1}: On master: renamed
Większość poleceń służy do analizy argumentów i zastanowienia się, co należy zrobić z nazwą gałęzi. Stosowane gitnarzędzia są następujące:
git rev-parse <stash> znaleźć SHA skrytki.
git stash list --format=%gs -1 <stash>znaleźć przedmiot do skrytki. Zauważ, że różni się to od komunikatu zatwierdzenia skrytki, którego to polecenie nie zmienia. Pojawia się temat przelogowania. git stash listMożesz zmienić temat przeprogramowania bez zmiany skrótów zatwierdzeń związanych ze skrytkami. Zawsze możesz jednak znaleźć oryginalną wiadomość zatwierdzenia, więc nie używaj jej git stash-renamedo usuwania poufnych informacji!
git stash drop <stash>aby usunąć stare odniesienie do skrytki (ale nadal mamy SHA, więc nie jest stracona).
git stash store -m <new-message> <sha>aby zapisać nowe odniesienie do skrytki z tymi samymi informacjami o zatwierdzeniu, ale z innym tematem ponownego logowania .
git stash listaby wyświetlić listę skrytek po zakończeniu operacji. Pamiętaj, że nowe skrytki są zawsze wypychane na początek listy. Konieczne byłoby ponowne popchnięcie wszystkich skrytek przed skrytką będącą przedmiotem zainteresowania, aby przywrócić pierwotne położenie.
Odpowiedzi:
Załóżmy, że twoja lista zapasów wygląda następująco:
Najpierw musisz usunąć ukryty wpis, którego nazwę chcesz zmienić:
Teraz po prostu dodaj go ponownie z nową wiadomością przy użyciu sha zatwierdzenia zwróconej po upuszczeniu:
I to wszystko:
To rozwiązanie wymaga git 1.8.4 lub nowszego i tak, działa również z brudnym katalogiem roboczym.
źródło
git show stash@{0}
nadal wyświetla stare informacje później. Jak to naprawić? (Należy pamiętać, że skrytka otrzymuje wtedy inny SHA.)git show
i zacząć odgit stash store
. Następniegit stash list
zobaczysz starą i nową skrytkę. Wreszcie możesz wyczyścić starą skrytkę za pomocągit stash drop
.git gc
uruchomienia. Postash drop
tym, jak łatwo możesz znaleźć to normalnie niedostępne zatwierdzenie za pomocągit fsck | grep commit
polecenia.Jeśli nie zrobisz tego ręcznie lub nie wprowadzisz ulepszeń do Git, możesz użyć aliasu:
Użycie: „
git stash-rename <stash> [save options] [<message>]
”Z
[save options]
dowolną opcjągit stash save
:[-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all]
Przykład:
To zadziała, nawet jeśli masz lokalne zmiany niestacjonarne :)
EDYCJA 2016/02/22
Uproszczony skrypt, napisy do qzb , https://stackoverflow.com/a/35549615/515973
Użycie: „
git stash-rename <stash> [<message>]
”źródło
git stash-rename 'tests with deployAtEnd' 'NXP-13971-deployAtEnd'
stash@{0}
referencyjnego. gist.github.com/jdforsythe/f248bf6c72fc020225cc3e315a32e922git config --global alias.stash-rename '!_() { if [ -z \"$1\" ] || [ -z \"$2\" ]; then echo \"git stash-rename 0 NewName\" && echo \"\" && git stash list && exit 1; else stash=\"stash@{$1}\"; rev=$(git rev-parse \"${stash}\"); git stash drop \"${stash}\" || exit 1; git stash store -m \"$2\" \"$rev\" || exit 1; git stash list; fi }; _'
To jest bardzo proste. Najpierw cofnij ostatni schowek za pomocą:
Następnie możesz zapisać skrytkę o niestandardowej nazwie w następujący sposób:
Mam nadzieję, że ci się przyda. :)
źródło
Nie sądzę, że jest to możliwe. Odnotowano propozycja stash zmiany nazwy, ale nie zostało jeszcze zrealizowane.
Możesz też oczywiście wyskoczyć z magazynu i zrobić
git stash save [message]
źródło
Z korzyścią dla czytelnika, oto rozszerzenie obecnie akceptowanej i poprawnej odpowiedzi .
Jeśli chcesz nie tylko poprawić komunikat skrytki, ale także poprawić komunikat zatwierdzenia skrytki, np
i
obie zgadzają się na to, co pokazano, potrzebujesz trochę więcej. Może być lepszy sposób, ale mam nadzieję, że ten przepis jest łatwy do zrozumienia.
Aby to zrobić
git commit --amend
, musisz być na TIP oddziału. Stąd rozwiązaniem jest:Wyjaśnione:
git commit --amend
do zastąpienia komunikatu zatwierdzenia, zmieniając SHA „ukrytej skrytki”Wady:
Tymczasowo przełącza gałęzie. Więc ten przepis można zastosować tylko wtedy, gdy
git status --porcelain
jest czysty (czytaj: nic nie wyświetla)Zmienia numerację skrytek, więc zmienia się skrytka
stash@{0}
Musisz wpisać
$MESSAGE
dwukrotnie lub użyć zmiennej środowiskowej (w przykładzieMESSAGE
:)Musisz znaleźć nieużywaną nazwę oddziału
Istnieją sposoby na to bez przełączania gałęzi, ale wykracza to poza zakres tej odpowiedzi.
Przykład
Wynik
Teraz bez zmiany zatwierdzenia (uwaga: poniższe SHA będą inne po twojej stronie):
Wynik
Jak widać,
stash@{0}
nadal jest pokazany jak2fbf900 (refs/stash) WIP on master: 8bdcc32 D
wgit log
. Jeśli przyjrzysz się uważnie, zobaczysz, że kilka zmian zmieniło SHA. Wynika to z tego, jak obsługiwane są skrytki (rodzice są uwzględnieni w SHA, a skrytki mają swoje skrytki jako rodzic).Napraw to:
Wynik
Jak widać,
refs/stash
zmienił się również SHA.źródło
Oto zmodyfikowana wersja aliasu Juliena, która pozwala poprawnie radzić sobie z
On <branch>
prefiksem zwykle poprzedzającym ukrywanie nazw:Składnia:
Przykładowe użycie:
Większość poleceń służy do analizy argumentów i zastanowienia się, co należy zrobić z nazwą gałęzi. Stosowane
git
narzędzia są następujące:git rev-parse <stash>
znaleźć SHA skrytki.git stash list --format=%gs -1 <stash>
znaleźć przedmiot do skrytki. Zauważ, że różni się to od komunikatu zatwierdzenia skrytki, którego to polecenie nie zmienia. Pojawia się temat przelogowania.git stash list
Możesz zmienić temat przeprogramowania bez zmiany skrótów zatwierdzeń związanych ze skrytkami. Zawsze możesz jednak znaleźć oryginalną wiadomość zatwierdzenia, więc nie używaj jejgit stash-rename
do usuwania poufnych informacji!git stash drop <stash>
aby usunąć stare odniesienie do skrytki (ale nadal mamy SHA, więc nie jest stracona).git stash store -m <new-message> <sha>
aby zapisać nowe odniesienie do skrytki z tymi samymi informacjami o zatwierdzeniu, ale z innym tematem ponownego logowania .git stash list
aby wyświetlić listę skrytek po zakończeniu operacji. Pamiętaj, że nowe skrytki są zawsze wypychane na początek listy. Konieczne byłoby ponowne popchnięcie wszystkich skrytek przed skrytką będącą przedmiotem zainteresowania, aby przywrócić pierwotne położenie.źródło
Najprostszy sposób: włóż swoją skrytkę za pomocą git stash pop, a następnie zapisz ją ponownie za pomocą git stash zapisz swoje imię
źródło