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 <[email protected]>
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保存。

转载自:https://www.jianshu.com/p/e9764e61ef90

猜你喜欢

转载自blog.csdn.net/qq_27981847/article/details/130646425