Git Stash命令的使用

1、使用场景

在远程仓库拉取代码之后,需要修改仓库中的某些配置文件才能够正常将工程运行起来。但是,改动后的文件会影响Git正常的拉取操作(Git会提示先处理本地的改动才可以拉取)。
这时候,比较方便的做法是将本地的修改用stash命令保存。之后,工作区就成了一个“干净”的状态,可以进行正常的拉取操作。
拉取完成之后,可以再通过stash命令将之前stash的内容再“取出”到工作区,这样就可以重新运行工程。
由于stash保存的内容,可以跨分支进行“取出”。在上面的场景中,功能算是比较强大了。

2、git stash介绍

运行git help stash命令,可以看到这个命令的帮助:

NAME
       git-stash - Stash the changes in a dirty working directory away

DESCRIPTION
       Use git stash when you want to record the current state of the working directory and the index, but want to go back to a clean working directory. The command saves your local modifications away and reverts the working directory to match the HEAD commit.
       The modifications stashed away by this command can be listed with git stash list, inspected with git stash show, and restored (potentially on top of a different commit) with git stash apply. Calling git stash without any arguments is equivalent to git stash push. A stash is by default listed as "WIP on branchname ...", but you can give a more descriptive message on the command line when you create one.
       The latest stash you created is stored in refs/stash; older stashes are found in the reflog of this reference and can be named using the usual reflog syntax (e.g. stash@{0} is the most recently created stash, stash@{1} is the one before it, stash@{2.hours.ago} is also possible). Stashes may also be referenced by specifying just the stash index (e.g. the integer n is equivalent to stash@{n}).

意思就是说:

git-stash - 将一个修改后的工作区中的改动保存起来,将工作区恢复到改动前的状态。

具体描述:
当你想要保存工作区的当前状态,并想要回到一个干净的工作目录时,可以使用git stash命令。该命令保存本地修改,并将工作区恢复到HEAD指向的commit状态。
git stash保存的内容可以通过命令“git stash list”列出,可以通过“git stash show”命令查看,可以通过“git stash apply”命令恢复(可以恢复到不同的commit/分支上)。不加任何参数调用“git stash”命令等同于“git stash push”。Stash信息默认展示为"WIP on branchname ...",但是你可以在stash命令执行的时候,添加相关描述性的信息。
创建的最新的stash信息保存在"refs/stash",稍微早一点的stash可以通过这个引用的reflog查看,也可以通过通常的reflog语法命名规则指代。比如“stash@{0}”表示最新创建的stash,“stash@{1}”是更早些的stash。stash也可以只通过序号指代,比如"n"代表"stash@{n}"。

3、例子

3.1 下面是一个连续的stash保存并取出的例子

查看最近一次提交:

$ git log -1
commit 1eff7133816e9e77d34c25dd63e017ab899bf490 (HEAD -> master, origin/master)
Author: XiaCheng <xxxxxxx@icloud.com>
Date:   Fri Mar 8 18:57:40 2019 +0800

    add doing mark

改动一个工作区中的文件:

$ echo "asdf" >> style.css 
$ git status
On branch master
Your branch is up to date with 'origin/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:   style.css

no changes added to commit (use "git add" and/or "git commit -a")

将对工作区的修改用stash命令保存:

$ git stash 
Saved working directory and index state WIP on master: 1eff713 add doing mark
$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

再次修改工作区中的一个文件:

$ echo "qwer" >> style.css
$ git status
On branch master
Your branch is up to date with 'origin/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:   style.css

no changes added to commit (use "git add" and/or "git commit -a")

用stash命令保存,并添加描述信息:

$ git stash save "add qwer to style.css"
Saved working directory and index state On master: add qwer to style.css

查看stash列表:

$ git stash list
stash@{0}: On master: add qwer to style.css
stash@{1}: WIP on master: 1eff713 add doing mark

恢复最近一次stash的保存内容:

$ git stash apply stash@{0}
On branch master
Your branch is up to date with 'origin/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:   style.css

no changes added to commit (use "git add" and/or "git commit -a")
$ git status
On branch master
Your branch is up to date with 'origin/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:   style.css

no changes added to commit (use "git add" and/or "git commit -a")

3.2 git stash跨分支

由于git stash保存的内容还没有提交,所以,这些内容不是基于分支的(和具体分支没有关系),而是基于工作区的。下面是一个例子。
接着前面的例子,我们首先将之前的修改复位,然后新建一个分支testBra,并修改style.css:

$ git checkout -- style.css 
$ git checkout -b testBra
Switched to a new branch 'testBra'
localhost:todo_man chengxia$ echo "test branch" >> style.css 
localhost:todo_man chengxia$ git status
On branch testBra
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:   style.css

no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -am "add test content on testBra"
[testBra d9b757d] add test content on testBra
 1 file changed, 1 insertion(+), 1 deletion(-)

接下来,我们取出之前通过stash命令保存的内容:

$ git stash list
stash@{0}: On master: add qwer to style.css
stash@{1}: WIP on master: 1eff713 add doing mark
$ git stash apply stash@{0}
Auto-merging style.css
CONFLICT (content): Merge conflict in style.css
$ git status
On branch testBra
Unmerged paths:
  (use "git reset HEAD <file>..." to unstage)
  (use "git add <file>..." to mark resolution)

    both modified:   style.css

no changes added to commit (use "git add" and/or "git commit -a")
$ vim style.css

这时,提示冲突如下:


Stash冲突内容

3.2.1 git add标识冲突解决

这时候,我们可以采用通常的git add命令标识冲突已经解决,如下:

$ git add style.css 
$ git status
On branch testBra
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   style.css

$ 

但是,这样有时候,并不是我们想要的,因为我们后续可能并不想将这个文件的修改提交,这时可以通过git reset命令标识冲突解决。

3.2.2 git reset标识冲突解决

首先,我们需要先将工作区复位。
unstage:

$ git reset HEAD style.css 
Unstaged changes after reset:
M   style.css
$ git status
On branch testBra
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:   style.css

no changes added to commit (use "git add" and/or "git commit -a")

复位修改:

$ git checkout -- style.css 
localhost:todo_man chengxia$ git status
On branch testBra
nothing to commit, working tree clean
$ git status
On branch testBra
nothing to commit, working tree clean

重新将stash@{0}恢复:

Auto-merging style.css
CONFLICT (content): Merge conflict in style.css
$ git status
On branch testBra
Unmerged paths:
  (use "git reset HEAD <file>..." to unstage)
  (use "git add <file>..." to mark resolution)

    both modified:   style.css

no changes added to commit (use "git add" and/or "git commit -a")

再次提示冲突,这次,改用git reset命令标识冲突已经解决。

$ git reset
Unstaged changes after reset:
M   style.css
$ git status
On branch testBra
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:   style.css

no changes added to commit (use "git add" and/or "git commit -a")

注:这里在解决文件冲突的时候,没有修改文件内容,一般来说,我们需要将文件内容修改为我们想要的之后(去掉标识冲突的<<<<<<>>>>>>======等标记),再标识冲突已经解决。

4、git stash命令参考

  • (1)git stash save "save message": 执行存储时,添加备注说明。
  • (2)git stash list:查看stash列表。
  • (3)git stash show:显示具体做了哪些改动,默认显示第一个stash存储,如果要显示其他存储,后面加stash@{$num},比如第二个git stash show stash@{1}
  • (4)git stash apply:应用某个存储,但不会把存储从存储列表中删除,默认使用第一个存储,即stash@{0},如果要使用其他个,添加git stash apply stash@{$num},比如第二个git stash apply stash@{1}
  • (5) git stash pop:命令恢复之前缓存的工作目录,将缓存堆栈中的对应stash删除,并将对应修改应用到当前的工作目录下,默认为第一个stash,即stash@{0},如果要应用并删除其他stash存储,命令:git stash pop stash@{$num}
  • (6)git stash drop stash@{$num}:删除stash@{$num}存储。
  • (7)git stash clear:删除所有缓存的stash存储。

新增的文件,直接执行stash是不会被存储的。需要先用git add命令将其添加到git暂存区,才可以被git stash保存。

参考材料

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,110评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,443评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,474评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,881评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,902评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,698评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,418评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,332评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,796评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,968评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,110评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,792评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,455评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,003评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,130评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,348评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,047评论 2 355

推荐阅读更多精彩内容