git stash用于將當(dāng)前工作區(qū)的修改暫存起來(lái)抽诉,就像堆棧一樣礁凡,可以隨時(shí)將某一次緩存的修改再重新應(yīng)用到當(dāng)前工作區(qū)。一旦用好了這個(gè)命令孽亲,會(huì)極大提高工作效率坎穿。
舉例說(shuō)明:
1、準(zhǔn)備工作,首先初始化一個(gè)git倉(cāng)
隨便建立一個(gè)目錄玲昧,進(jìn)去栖茉,然后使用 :
$: git init .
添加一個(gè)文件:
$: touch hello
$: git add .
$: git commit -m "first add"
2、暫存當(dāng)前修改內(nèi)容(git stash)
假設(shè)我們?cè)趯懸粋€(gè)C函數(shù)孵延,如下:
$:~/code/linux/git$ vim hello.c
$:~/code/linux/git$ git diff
diff --git a/hello.c b/hello.c
index e69de29..bdc92a5 100644
--- a/hello.c
+++ b/hello.c
@@ -0,0 +1,2 @@
+void func1(void) {printf("this is func1");}
+void main(void) {return func1();}
調(diào)試OK吕漂,發(fā)現(xiàn)func1功能OK,但是應(yīng)該優(yōu)化一下尘应,可能效率更高惶凝,這個(gè)時(shí)候怎么辦?
直接改func1的話犬钢,如果發(fā)現(xiàn)修改不合適苍鲜,想回退的話很麻煩,這個(gè)時(shí)候可以用git stash將將修改暫存起來(lái)娜饵。
$: ~/code/linux/git$ git stash
Saved working directory and index state WIP on master: 452b08d rename hello as hello.c
HEAD is now at 452b08d rename hello as hello.c
$:~/code/linux/git$ git status
On branch master
nothing to commit, working directory clean
3坡贺、彈出修改內(nèi)容(git stash pop)
這個(gè)時(shí)候你重新編寫func1, 發(fā)現(xiàn)效果不好箱舞,后悔了遍坟,于是可以用git stash pop命令,彈出剛才的內(nèi)容(注意先用git checkout . 清空工作區(qū))
$:~/code/linux/git$ vim hello.c
$:~/code/linux/git$ git diff
diff --git a/hello.c b/hello.c
index e69de29..9c5bff3 100644
--- a/hello.c
+++ b/hello.c
@@ -0,0 +1 @@
+some bad chenges....
$:~/code/linux/git$ git checkout .
$:~/code/linux/git$ git stash pop
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: hello.c
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (208ca2e2c0c455da554986a6770a74ad0de5b1e0)
$:~/code/linux/git$ git diff
diff --git a/hello.c b/hello.c
index e69de29..bdc92a5 100644
--- a/hello.c
+++ b/hello.c
@@ -0,0 +1,2 @@
+void func1(void) {printf("this is func1");}
+void main(void) {return func1();}
注意晴股,git stash pop 彈出成功后愿伴,暫存列表里面就沒(méi)有了,如果當(dāng)前工作區(qū)不干凈电湘,彈出時(shí)有沖突隔节,則暫存列表會(huì)繼續(xù)保留修改。
4寂呛、可以保存多個(gè)修改
假設(shè)你在實(shí)現(xiàn)一個(gè)功能怎诫,有好幾種算法可以實(shí)現(xiàn),你想逐個(gè)嘗試看效果贷痪。
現(xiàn)在你在func1中實(shí)現(xiàn)了一種方法幻妓,準(zhǔn)備嘗試寫func2,用另一種方法劫拢。
那么可以將func1的修改入棧肉津,去寫fun2,等f(wàn)un2寫好后舱沧,你又想試試func3妹沙,那么沒(méi)關(guān)系,可以用同樣的方法保存func2的修改:
$:~/code/linux/git$ git diff
diff --git a/hello.c b/hello.c
index e69de29..bdc92a5 100644
--- a/hello.c
+++ b/hello.c
@@ -0,0 +1,2 @@
+void func1(void) {printf("this is func1");}
+void main(void) {return func1();}
$:~/code/linux/git$ git stash
Saved working directory and index state WIP on master: 452b08d rename hello as hello.c
HEAD is now at 452b08d rename hello as hello.c
$:~/code/linux/git$ git status
On branch master
nothing to commit, working directory clean
$:~/code/linux/git$ vim hello.c
$:~/code/linux/git$ git diff
diff --git a/hello.c b/hello.c
index e69de29..7fd0a13 100644
--- a/hello.c
+++ b/hello.c
@@ -0,0 +1,2 @@
+void func2(void) {printf("this is func2");}
+void main(void) {return func2();}
$:~/code/linux/git$ git stash
Saved working directory and index state WIP on master: 452b08d rename hello as hello.c
HEAD is now at 452b08d rename hello as hello.c
$:~/code/linux/git$ git status
On branch master
nothing to commit, working directory clean
5熟吏、查看保存的內(nèi)容列表(git stash list)
現(xiàn)在我們保存了兩個(gè)修改距糖,一個(gè)func1玄窝,一個(gè)func2,可以通過(guò)git stash list去查看保存內(nèi)容列表:
$:~/code/linux/git$ git stash list
stash@{0}: WIP on master: 452b08d rename hello as hello.c
stash@{1}: WIP on master: 452b08d rename hello as hello.c
可以清楚的看到這兩次修改肾筐,stash@{0}和stash@{1}哆料, 那么哪個(gè)對(duì)應(yīng)func1缸剪,哪個(gè)對(duì)應(yīng)func2的修改呢吗铐?
這時(shí)我們需要使用git stash show stash@{X}命令來(lái)查看,其中‘X’表示列表號(hào)杏节。
$:~/code/linux/git$ git show stash@{0}
commit 72e6a391bcad186ab24676aa1db8d5831c99cec9
Merge: 452b08d 6c95c30
Author: hiekay
Date: Sat Mar 12 19:56:18 2016 +0800
WIP on master: 452b08d rename hello as hello.c
diff --cc hello.c
index e69de29,e69de29..7fd0a13
--- a/hello.c
+++ b/hello.c
@@@ -1,0 -1,0 +1,2 @@@
++void func2(void) {printf("this is func2");}
++void main(void) {return func2();}
$:~/code/linux/git$ git show stash@{1}
commit 7fcca4b66640c51ca76e637df03264b7c41885be
Merge: 452b08d 1c37881
Author: hiekay
Date: Sat Mar 12 19:54:35 2016 +0800
WIP on master: 452b08d rename hello as hello.c
diff --cc hello.c
index e69de29,e69de29..bdc92a5
--- a/hello.c
+++ b/hello.c
@@@ -1,0 -1,0 +1,2 @@@
++void func1(void) {printf("this is func1");}
++void main(void) {return func1();}
發(fā)現(xiàn)stash@{0}對(duì)應(yīng)func2的修改唬渗, stash@{1}對(duì)應(yīng)func1的修改,原來(lái)新入棧的修改奋渔,其代號(hào)為0镊逝,循環(huán)命名。
6嫉鲸、應(yīng)用任意一次修改到當(dāng)前目錄(git apply stash@{x})
如果現(xiàn)在又想回到func1的修改撑蒜,怎么辦呢?在工作區(qū)干凈的情況下玄渗,要使用git stash apply stash@{1}座菠。
注意這時(shí)不能使用git stash pop, 它將最棧頂藤树,即stash@{0}的修改彈出來(lái)浴滴,而func1現(xiàn)在已經(jīng)是stash@{1}了。
$:~/code/linux/git$ git stash apply stash@{1}
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: hello.c
no changes added to commit (use "git add" and/or "git commit -a")
$:~/code/linux/git$ git diff
diff --git a/hello.c b/hello.c
index e69de29..bdc92a5 100644
--- a/hello.c
+++ b/hello.c
@@ -0,0 +1,2 @@
+void func1(void) {printf("this is func1");}
+void main(void) {return func1();}
可見(jiàn)git stash apply可以將列表中任何一次修改應(yīng)用到當(dāng)前工作區(qū)岁钓,我們?cè)俅蝕it stash list一把:
$:~/code/linux/git$ git stash list
stash@{0}: WIP on master: 452b08d rename hello as hello.c
stash@{1}: WIP on master: 452b08d rename hello as hello.c
我們發(fā)現(xiàn)升略,雖然func1的修改已經(jīng)被彈出應(yīng)用到當(dāng)前工作區(qū),其修改內(nèi)容還繼續(xù)保留在暫存列表屡限,并未丟棄品嚣。
當(dāng)然,我們可以使用git stash drop stash@{1}來(lái)丟掉stash@{1}
7钧大、保存時(shí)打標(biāo)記(git stash save)
假設(shè)現(xiàn)在我們又開(kāi)始嘗試寫func3翰撑, 這樣越來(lái)越多,這樣列表會(huì)越來(lái)越大拓型,你要想搞清楚某次修改對(duì)應(yīng)哪個(gè)函數(shù)额嘿,就要挨個(gè)用git stash show看一遍,很麻煩劣挫。
那么册养,這個(gè)時(shí)候git stash 的save參數(shù)就有用了,它可以為這次暫存做個(gè)標(biāo)記压固,使得你用git stash list的時(shí)候顯示這些標(biāo)記球拦,方便你回憶是修改的什么:
$:~/code/linux/git$ vim hello.c
$:~/code/linux/git$ git diff
diff --git a/hello.c b/hello.c
index e69de29..786c214 100644
--- a/hello.c
+++ b/hello.c
@@ -0,0 +1,2 @@
+void func3(void) {printf("this is func3");}
+void main(void) {return func3();}
$:~/code/linux/git$ git stash save "this is func3"
Saved working directory and index state On master: this is func3
HEAD is now at 452b08d rename hello as hello.c
$:~/code/linux/git$ git stash list
stash@{0}: On master: this is func3
stash@{1}: WIP on master: 452b08d rename hello as hello.c
stash@{2}: WIP on master: 452b08d rename hello as hello.c
我們?cè)趕ave后面指定一個(gè)字符串,作為提醒,這樣在git stash list查看時(shí)就能知道每一個(gè)代號(hào)對(duì)應(yīng)的修改了坎炼。