git stash
Polecenie git stash
pozwala tymczasowo „odłożyć na półkę” (lub dodać do schowka) zmiany wprowadzone w kopii roboczej, dzięki czemu możesz zacząć pracę nad czymś innym, a następnie wrócić i ponownie zastosować zmiany. Dodawanie do schowka (stashing) jest przydatne, gdy trzeba szybko zmienić kontekst i rozpocząć pracę nad czym innym, będąc w połowie wprowadzania zmian w kodzie, które nie są jeszcze gotowe do zatwierdzenia.
- git stash
- Dodawanie pracy do schowka
- Ponowne stosowanie zmian dodanych do schowka
- Dodawanie do schowka nieśledzonych lub ignorowanych plików
- Zarządzanie wieloma schowkami
- Wyświetlanie różnic między schowkami
- Częściowe dodawanie zmian do schowka
- Tworzenie gałęzi na podstawie schowka
- Oczyszczanie schowka
- Sposób działania polecenia „git stash”
Dodawanie pracy do schowka
Polecenie git stash
pobiera niezatwierdzone zmiany (zarówno zapisane, jak i niezapisane w przechowalni), zapisuje je na potrzeby użycia w przyszłości, a następnie cofa je w kopii roboczej. Przykład:
$ git status
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
$ git stash
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage
$ git status
On branch main
nothing to commit, working tree clean
materiały pokrewne
Gałąź Git
POZNAJ ROZWIĄZANIE
Poznaj środowisko Git z rozwiązaniem Bitbucket Cloud
W tym momencie można swobodnie wprowadzać zmiany, tworzyć nowe commity, przełączać gałęzie oraz wykonywać inne operacje Git, a wrócić i ponownie zastosować zmiany ze schowka, gdy wszystko będzie gotowe.
Należy zauważyć, że schowek jest lokalny względem repozytorium Git, a zapisane w nim zmiany nie są przesyłane na serwer podczas wypychania.
Ponowne stosowanie zmian dodanych do schowka
Za pomocą polecenia git stash pop
można ponownie zastosować zmiany, które wcześniej zostały dodane do schowka:
$ git status
On branch main
nothing to commit, working tree clean
$ git stash pop
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Dropped refs/stash@{0} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)
Wykonanie operacji „pop” na schowku powoduje usunięcie zmian ze schowka i ponowne zastosowanie ich do kopii roboczej.
Można również ponownie zastosować zmiany do kopii roboczej i jednocześnie zachować je w schowku za pomocą polecenia git stash apply
:
$ git stash apply
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Jest ono przydatne, jeśli chcesz zastosować te same zmiany ze schowka w wielu gałęziach.
Znając już podstawy dodawania do schowka, należy pamiętać o pewnym zagrożeniu związanym z korzystaniem z polecenia git stash
: domyślnie Git nie dodaje do schowka zmian wprowadzonych w plikach nieśledzonych lub ignorowanych.
Dodawanie do schowka nieśledzonych lub ignorowanych plików
Domyślnie wykonanie polecenia git stash
spowoduje dodanie do schowka:
- zmian, które zostały dodane do indeksu (zmian z przechowalni);
- zmian wprowadzonych w plikach aktualnie śledzonych przez Git (zmian spoza przechowalni).
Nie spowoduje jednak dodania do schowka:
- nowych plików w kopii roboczej, które nie zostały jeszcze umieszczone w przechowalni;
- plików, które zostały zignorowane.
Jeśli więc do naszego przykładu powyżej dodamy trzeci plik, ale nie umieścimy go w przechowalni (tj. nie wykonamy polecenia git add
), nie zostanie on dodany do schowka w przypadku użycia polecenia git stash
.
$ script.js
$ git status
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Untracked files:
script.js
$ git stash
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage
$ git status
On branch main
Untracked files:
script.js
Dodanie opcji -u
(lub --include-untracked
) pozwala uwzględnić w poleceniu git stash
także nieśledzone pliki:
$ git status
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Untracked files:
script.js
$ git stash -u
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage
$ git status
On branch main
nothing to commit, working tree clean
Można uwzględnić także zmiany wprowadzone w plikach ignorowanych, przekazując opcję -a
(lub --all
) podczas wykonywania polecenia git stash
.
Zarządzanie wieloma schowkami
Nie trzeba ograniczać się do jednego schowka. Można wykonać polecenie git stash
kilkakrotnie, aby utworzyć wiele schowków, a następnie wyświetlić je za pomocą polecenia git stash list
. Domyślnie schowki są oznaczane jako „WIP” (praca w toku) względem gałęzi i commita, na podstawie którego utworzono schowek. Po pewnym czasie trudno jednak zapamiętać, co zawierają poszczególne schowki:
$ git stash list
stash@{0}: WIP on main: 5002d47 our new homepage
stash@{1}: WIP on main: 5002d47 our new homepage
stash@{2}: WIP on main: 5002d47 our new homepage
Aby zapewnić pewien kontekst, dobrze jest dodawać adnotacje z opisem do schowków za pomocą polecenia git stash save "message"
:
$ git stash save "add style to our site"
Saved working directory and index state On main: add style to our site
HEAD is now at 5002d47 our new homepage
$ git stash list
stash@{0}: On main: add style to our site
stash@{1}: WIP on main: 5002d47 our new homepage
stash@{2}: WIP on main: 5002d47 our new homepage
Domyślnie polecenie git stash pop
spowoduje ponowne zastosowanie zmian z ostatnio utworzonego schowka: stash@{0}
Można wybrać schowek, z którego zmiany mają zostać ponownie zastosowane, przekazując jego identyfikator jako ostatni argument, na przykład:
$ git stash pop stash@{2}
Wyświetlanie różnic między schowkami
Można również wyświetlić podsumowanie schowka za pomocą polecenia git stash show
:
$ git stash show
index.html | 1 +
style.css | 3 +++
2 files changed, 4 insertions(+)
Przekazanie opcji -p
(lub --patch
) umożliwia wyświetlenie pełnego zestawu różnic w schowku:
$ git stash show -p
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..d92368b
--- /dev/null
+++ b/style.css
@@ -0,0 +1,3 @@
+* {
+ text-decoration: blink;
+}
diff --git a/index.html b/index.html
index 9daeafb..ebdcbd2 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,2 @@
+<link rel="stylesheet" href="style.css"/>
Częściowe dodawanie zmian do schowka
Można również wybrać dodanie do schowka pojedynczego pliku, kolekcji plików lub poszczególnych zmian z plików. Przekazanie opcji -p
(lub --patch
) do polecenia git stash
spowoduje iteracyjne przejście przez każdy fragment ze zmianami („hunk”) w kopii roboczej z pytaniem, czy ma zostać dodany do schowka:
$ git stash -p
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..d92368b
--- /dev/null
+++ b/style.css
@@ -0,0 +1,3 @@
+* {
+ text-decoration: blink;
+}
Stash this hunk [y,n,q,a,d,/,e,?]? y
diff --git a/index.html b/index.html
index 9daeafb..ebdcbd2 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,2 @@
+<link rel="stylesheet" href="style.css"/>
Stash this hunk [y,n,q,a,d,/,e,?]? n
Naciśnięcie klawisza ? pozwala wyświetlić pełną listę poleceń dotyczących fragmentów ze zmianami. Najczęściej stosuje się następujące z nich:
Polecenie | Opis |
---|---|
/ | Opis wyszukaj fragment ze zmianami za pomocą wyrażenia regularnego |
? | Opis help |
n | Opis nie dodawaj tego fragmentu ze zmianami do schowka |
q | Opis zakończ (wszystkie wybrane dotychczas fragmenty ze zmianami zostaną dodane do schowka) |
N | Opis podziel ten fragment ze zmianami na mniejsze fragmenty |
y | Opis dodaj ten fragment ze zmianami do schowka |
Nie ma konkretnego polecenia przerwania operacji, ale użycie skrótu CTRL-C
(SIGINT) spowoduje przerwanie procesu dodawania do schowka.
Tworzenie gałęzi na podstawie schowka
Jeśli zmiany w gałęzi będą rozbieżne ze zmianami w schowku, przy próbie ponownego zastosowania zawartości schowka za pomocą polecenia „pop” lub „apply” mogą pojawić się konflikty. Zamiast tego można użyć polecenia git stash branch
, aby utworzyć nową gałąź, do której zostaną zastosowane zmiany ze schowka:
$ git stash branch add-stylesheet stash@{1}
Switched to a new branch 'add-stylesheet'
On branch add-stylesheet
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Dropped refs/stash@{1} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)
To spowoduje wyewidencjonowanie nowej gałęzi w oparciu o commit, z którego utworzono schowek, a następnie wykonanie polecenia „pop” w odniesieniu do schowka.
Oczyszczanie schowka
Jeśli jakiś schowek nie będzie już potrzebny, można go usunąć za pomocą polecenia git stash drop
:
$ git stash drop stash@{1}
Dropped stash@{1} (17e2697fd8251df6163117cb3d58c1f62a5e7cdb)
Można również usunąć wszystkie schowki, używając następującego polecenia:
$ git stash clear
Sposób działania polecenia „git stash”
Jeśli interesował Cię wyłącznie sposób użycia polecenia git stash
, możesz przerwać czytanie w tym miejscu. Jeśli jednak chcesz się dowiedzieć, jak dokładnie działa Git (i polecenie git stash
), czytaj dalej!
Schowki są w rzeczywistości zakodowane w repozytorium jako obiekty commitów. Specjalna referencja w lokalizacji .git/refs/stash
wskazuje na ostatni utworzony schowek, a do wcześniej utworzonych schowków można odwołać się za pośrednictwem dziennika reflog referencji stash
. Dlatego do schowków odwołujesz się za pomocą ciągu stash@{n}:
w istocie oznacza to odwołanie do n-tej pozycji w dzienniku reflog referencji stash
. Schowek jest po prostu commitem, dlatego można go sprawdzić za pomocą polecenia git log
:
W zależności od rodzaju zawartości dodawanej do schowka, pojedyncza operacja git stash
powoduje utworzenie dwóch lub trzech nowych commitów. Na powyższym diagramie przedstawiono następujące commity:
stash@{0}
— nowy commit do przechowywania śledzonych plików, które znajdowały się w kopii roboczej w momencie wykonania poleceniagit stash
.- Pierwszy element nadrzędny commita
stash@{0}
— istniejący wcześniej commit, na który w momencie wykonania poleceniagit stash
wskazywał wskaźnik HEAD. - Drugi element nadrzędny commita
stash@{0}
— nowy commit reprezentujący indeks w momencie wykonania poleceniagit stash
. - Trzeci element nadrzędny commita
stash@{0}
— nowy commit reprezentujący nieśledzone pliki, które w momencie wykonania poleceniagit stash
znajdowały się w kopii roboczej. Ten trzeci element nadrzędny jest tworzony tylko wówczas, gdy:- kopia robocza faktycznie zawierała nieśledzone pliki;
- oraz użyto opcji
--include-untracked
lub--all
podczas wywoływania poleceniagit stash
.
Sposób kodowania drzewa roboczego i indeksu jako commitów po użyciu polecenia git stash
:
- Przed dodaniem do schowka drzewo robocze może zawierać zmiany wprowadzone w plikach śledzonych, nieśledzonych i ignorowanych. Niektóre z tych zmian mogą być również przechowywane w indeksie.
- Wywołanie polecenia
git stash
koduje wszelkie zmiany w śledzonych plikach jako dwa nowe commity w grafie DAG: jeden dla zmian poza przechowalnią i jeden dla zmian przechowywanych w indeksie. Specjalna referencjarefs/stash
zostanie zaktualizowana tak, aby je wskazywała.
- Użycie opcji
--include-untracked
pozwala również zakodować wszelkie zmiany w nieśledzonych plikach jako dodatkowy commit.
- Z kolei opcja
--all
umożliwia uwzględnienie zmian wprowadzonych we wszystkich ignorowanych plikach wraz ze zmianami w plikach nieśledzonych w tym samym commicie.
Po wykonaniu polecenia git stash pop
kopia robocza oraz indeks są aktualizowane o zmiany z powyższych commitów, a dziennik reflog schowka jest modyfikowany w celu usunięcia commita zastosowanego za pomocą polecenia „pop”. Warto pamiętać, że commity zastosowane za pomocą polecenia „pop” nie są usuwane od razu, tylko stają się kandydatami do późniejszego usuwania zbędnych elementów.
Udostępnij ten artykuł
Następny temat
Zalecane lektury
Dodaj te zasoby do zakładek, aby dowiedzieć się więcej na temat rodzajów zespołów DevOps lub otrzymywać aktualności na temat metodyki DevOps w Atlassian.