侧边栏壁纸
博主头像
孔子说JAVA博主等级

成功只是一只沦落在鸡窝里的鹰,成功永远属于自信且有毅力的人!

  • 累计撰写 297 篇文章
  • 累计创建 134 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

Git stash存储命令详解和使用

孔子说JAVA
2022-09-01 / 0 评论 / 0 点赞 / 69 阅读 / 5,847 字 / 正在检测是否收录...

在协同开发的时候我们都有这样的经历,功能开发了一半,因为某些原因我们想要 checkout 到其他的分支上查看代码或者是执行某个工作。但是如果我们直接执行 checkout,git 会禁止我们的行为,提示一些文件的改动会被覆盖,所以拒绝了我们的 checkout 命令。这时候因为代码没有经过严谨的测试或只是完成了一部分开发任务或者只是测试功能等,使用 git commit 把改动提交了也不合适,即使提交了了,之后在 push 之前也会要把 commit 撤销了。针对这个问题,git 提供了一个解决策略就是 stash 功能,用来临时缓存我们的改动。

1、应用场景

Git stash 命令用于将本地没提交的内容(即工作区的修改和暂存区的修改,git commit的内容不会被缓存,但git add的内容会被缓存)进行缓存并从当前分支移除,缓存的数据结构为堆栈,先进后出。在完成其他工作之后再通过git stash pop命令将之前储藏的修改取出来,继续进行新功能的开发工作。

应用场景一:当正在某分支上(如dev分支)开发某个功能时,这时项目中出现一个bug,需要紧急修复,但是正在开发的功能只是完成了一半,还不想/不能提交,这时可以用git stash命令将修改的内容保存至堆栈区,然后顺利切换到 hotfix 分支进行bug修复,修复完成后,再次切回到dev分支,从堆栈中恢复刚刚保存的内容。

应用场景二:由于个人疏忽,将本应该在dev分支上开发的内容,在master上进行了开发,需要重新切回到dev分支上进行开发,这时可以用git stash 将内容保存至堆栈中,切回到dev分支后,将在master分支上保存的内容恢复到dev分支即可。

总的来说,git stash命令的作用就是将目前还不想提交的但是已经修改的内容保存至堆栈中,后续可以在某个分支上恢复出堆栈中的内容。这也就是说,stash中的内容不仅仅可以恢复到原先开发的分支,也可以恢复到其他任意指定的分支上。git stash作用的范围包括工作区和暂存区中的内容,也就是说没有提交的内容都会保存至堆栈中。

2、命令详解

2.1 git status

git status 显示git文件状态报告,输出的命令很详细,但有些繁琐。
git status -s 或 git status --short 命令以精简的方式显示文件状态,会得到更为紧凑的格式输出。

  • 新添加的未跟踪文件前面有 ?? 标记,
  • 新添加到暂存区中的文件前面有 A 标记,
  • 修改过的文件前面有 M标记。M 有两个可以出现的位置,出现在右边的 M 表示该文件被修改了但是还没放入暂存区,出现在靠左边的 M 表示该文件被修改了并放入了暂存区。
$ git status -s
 M README
MM Rakefile
A  lib/git.rb
M  lib/simplegit.rb
?? LICENSE.txt

输出标记会有两列,第一列是对staging区域而言,第二列是对working目录而言。如上面的状态报告显示:

  • README 文件在工作区被修改了但是还没有将修改后的文件放入暂存区,
  • lib/simplegit.rb 文件被修改了并将修改后的文件放入了暂存区。
  • 而 Rakefile 在工作区被修改并提交到暂存区后又在工作区中被修改了,所以在暂存区和工作区都有该文件被修改了的记录。

2.2 git stash

git stash 命令能够将所有未提交的修改(工作区和暂存区)保存至堆栈中,用于后续恢复当前工作目录。

$ git status
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:   src/main/java/com/wy/CacheTest.java
        modified:   src/main/java/com/wy/StringTest.java

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

$ git stash
Saved working directory and index state WIP on master: b2f489c second

$ git status
On branch master
nothing to commit, working tree clean

git stash --keep-index 命令储存时只保存工作目录中的变更,保持已暂存的变更在暂存区中不动。

# 简写
git stash -k

# 完整命令参数写法:
git stash --keep-index

2.3 git stash save

git stash save 作用等同于 git stash,区别是可以加一些注释,方便以后查找,只有 git stash 也是可以的,但查找时不方便识别。如下:

git stash save “test1”

效果:

stash@{0}: On master: test1

而 git stash 的效果如下:

stash@{0}: WIP on master: b2f489c second

2.4 git stash list

git stash list 命令查看当前 stash 中的内容,即查看 stash 了哪些存储。

$ git stash list
stash@{0}: On master: test2
stash@{1}: On master: test1

2.5 git stash pop

git stash pop 命令将当前 stash 中的内容弹出,并应用到当前分支对应的工作目录上。命令恢复之前缓存的工作目录,将缓存堆栈中的对应 stash删除,并将对应修改应用到当前的工作目录下,默认为第一个stash,即stash@{0},如果要应用并删除其他stash,命令:git stash pop stash@{$num} ,比如应用并删除第二个:git stash pop stash@{1}

  • 注:该命令将堆栈中最近保存的内容删除(栈是先进后出)

在顺序执行 git stash save “test1” 和 git stash save “test2”命令后,执行 git stash pop 效果如下:

$ git stash list
stash@{0}: On master: test2
stash@{1}: On master: test1

$ 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:   src/main/java/com/wy/StringTest.java

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (afc530377eacd4e80552d7ab1dad7234edf0145d)

$ git stash list
stash@{0}: On master: test1

可以看到缓存的数据结构为堆栈,是先进后出的顺序,test2的stash是首先pop出来的。

如果从stash中恢复的内容和当前目录中的内容发生了冲突,也就是说,恢复的内容和当前目录修改了同一行的数据,那么会提示报错,需要解决冲突,可以通过创建新的分支来解决冲突。

2.6 git stash apply

git stash apply 命令将堆栈中的内容应用到当前分支对应的工作目录上,与 git stash pop 命令的区别在于,该命令不会将内容从堆栈中删除,也就是说该命令能够将堆栈的内容多次应用到工作目录中,适应于多个分支的情况。可以使用 git stash apply + stash名字(如stash@{1})指定恢复哪个stash到当前的工作目录。

git stash apply 默认使用第一个存储即stash@{0},如果要使用其他存储,使用 git stash apply stash@{$num} 命令,比如第二个:git stash apply stash@{1}

$ git stash apply
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:   src/main/java/com/wy/StringTest.java

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

$ git stash list
stash@{0}: On master: test2
stash@{1}: On master: test1

可以看到堆栈中的内容并没有被删除。

2.7 git stash drop

git stash drop stash@{$num} 命令用于从堆栈中移除某个指定的stash(丢弃stash@{$num}存储,即从列表中删除这个存储)。

2.8 git stash clear

git stash clear 命令将清除堆栈中的所有内容(即删除所有缓存的stash)。

2.9 git stash show

git stash show 命令查看堆栈中最新保存的stash和当前目录的差异。即与当前工作区比较显示做了哪些改动,默认show第一个存储,如果要显示其他存储,需要在后面加 stash@{$num},比如显示第二个存储与当前目录的差异: git stash show stash@{1}

$ git stash show
 src/main/java/com/wy/StringTest.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

git stash show -p 命令查看详细的差异,同样可以通过 git stash show stash@{$num} -p 命令查看指定的 stash 与当前目录的差异,如 git stash show stash@{1} -p 查看第二个存储与当前目录的差异。

$ git stash show -p
diff --git a/src/main/java/com/wy/CacheTest.java b/src/main/java/com/wy/CacheTest.java
index 6e90837..de0e47b 100644
--- a/src/main/java/com/wy/CacheTest.java
+++ b/src/main/java/com/wy/CacheTest.java
@@ -7,6 +7,6 @@ package com.wy;
  */
 public class CacheTest {
     public static void main(String[] args) {
-        System.out.println("git stash test");
+        System.out.println("git stash test1");
     }
 }
diff --git a/src/main/java/com/wy/StringTest.java b/src/main/java/com/wy/StringTest.java
index a7e146c..711d63f 100644
--- a/src/main/java/com/wy/StringTest.java
+++ b/src/main/java/com/wy/StringTest.java
@@ -12,7 +12,7 @@ public class StringTest {

     @Test
     public void test1() {
-        System.out.println("=================");
+        System.out.println("git stash test1");
         System.out.println(Strings.isNullOrEmpty(""));//true
         System.out.println(Strings.isNullOrEmpty(" "));//false
         System.out.println(Strings.nullToEmpty(null));//""

2.10 git stash branch

git stash branch 命令用于从最新的stash创建分支。

应用场景:当储藏了部分工作,暂时不去理会,继续在当前分支进行开发,后续想将stash中的内容恢复到当前工作目录时,如果是针对同一个文件的修改(即便不是同行数据),那么可能会发生冲突,恢复失败,这里通过创建新的分支来解决。可以用于解决stash中的内容和当前目录的内容发生冲突的情景。发生冲突时,需手动解决冲突。

3、IDEA中的stash使用方式

3.1 git stash 代码暂存

在任意文件上右键选择 Git -> Stash Changes… 可以打开存储文件对话框。

image-1661911173362

使用 git stash 暂存代码,会把暂存区和工作区的改动保存起来。添加备注信息,选择 CREATE STASH。当前工作区内的代码被恢复成了未修改之前的样子。

image-1661911308472

3.2 代码暂存还原

在任意文件上右键选择 Git -> Unstash Changes… 可以打开代码暂存还原对话框。

image-1661911439889

选择之前保存的,同时勾选 Pop stash(还原完成后,会自动删除这个 stash,不勾选则不会删除这个 stash,具体选择看情况),点击 Pop Stash 按钮,工作区之前写的代码就会恢复回来。

image-1661911511660

0

评论区