Git Stash

应用场景

  1. 我在功能开发分支feature_001中正在开发代码。此时经理找我说需要修改一个生产 的紧急bug。这时,我需要创建一个 hotfix_xxx 分支,然后切换到此分支进行bug修复。但是我在feature_001的代码还在开发中,如果我直接切换分支,会导致代码丢失;并且,由于开发并未完成,所以我并不想提交代码到分支上。此时我就使用git stash命令将修改的内容保存到堆栈区。然后切换分支进行bug修复,当修复完成后,再次切换回功能分支,并将堆栈中保存的修改内容恢复到工作区。

  2. 新接到了一个需求,由于疏忽,忘记创建了一个功能分支,直接在master分支上进行开发了。这是我将修改内容使用git stash保存到堆栈区,创建功能分之后切换到功能分支,再使用git stash命令将堆栈区的修改内容恢复到当前分支上,完成了代码的迁移。

常用命令

git stash

将所有未提交的修改(工作区与暂存区)保存到堆栈中, 用于后续恢复当前的工作目录, 栈是先进后出:

## 当前位于master分支,共有一个文件被修改,一个文件被仓库忽略
yangsx95@yangsx95-TWS:~/桌面/testreposi$ git status 
位于分支 master
尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git restore <文件>..." 丢弃工作区的改动)
   修改:     a.txt

未跟踪的文件:
  (使用 "git add <文件>..." 以包含要提交的内容)
   b.txt

修改尚未加入提交(使用 "git add" 和/或 "git commit -a"

## 使用git stash 将工作区与暂存区的内容保存到堆栈, hash为53cffd4
yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash   
保存工作目录和索引状态 WIP on master: 53cffd4 init

## 查看仓库状态,当前没有任何代码为被提交
yangsx95@yangsx95-TWS:~/桌面/testreposi$ git status 
位于分支 master
未跟踪的文件:
  (使用 "git add <文件>..." 以包含要提交的内容)
   b.txt

git stash save

git stash作用一致, 但是可以在save后增加备注:

yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash save "我是备注"
保存工作目录和索引状态 On master: 我是备注

git stash list

查看堆栈中stash的列表:

yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash list 
stash@{0}: On master: 我是备注                 #栈顶
stash@{1}: WIP on master: 53cffd4 init        #栈底
# 先存储的53cffd4, 后存储的我是备注, 所以我是备注在栈顶

git stash show

将工作空间的内容与指定堆栈中的内容进行比较:

yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash show stash@{0} 
 a.txt | 1 +
 1 file changed, 1 insertion(+)

git stash pop

将当前stash中(栈顶)的内容弹出,并应用到当前分支对应的工作目录上。

## 栈内有两个元素
yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash list 
stash@{0}: On master: 我是备注
stash@{1}: WIP on master: 53cffd4 init

# 弹出最上方的内容,并应用到工作目录
yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash pop 
位于分支 master
尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git restore <文件>..." 丢弃工作区的改动)
   修改:     a.txt

未跟踪的文件:
  (使用 "git add <文件>..." 以包含要提交的内容)
   b.txt

修改尚未加入提交(使用 "git add" 和/或 "git commit -a"
丢弃了 refs/stash@{0}(419b7a70caae4a1e1a55c055c9c44f22f5578c96)

## 此时栈内只有一个元素
yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash list 
stash@{0}: WIP on master: 53cffd4 init

git stash apply

git stash pop 只能将存储的内容pop一次,一旦pop结束,就不能再次pop. 有时候某一修改需要应用多个分支的时候,就无法满足要求. git stash apply 则可以多次将栈顶内容应用到分支中.

yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash list 
stash@{0}: WIP on master: 53cffd4 init
yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash apply 
error: 您对下列文件的本地修改将被合并操作覆盖:
   a.txt
请在合并前提交或贮藏您的修改。
正在终止
yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash apply 
error: 您对下列文件的本地修改将被合并操作覆盖:
   a.txt
请在合并前提交或贮藏您的修改。
正在终止
yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash list
stash@{0}: WIP on master: 53cffd4 init

还可以在apply增加名称参数, 恢复指定的修改内容:

yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash list 
stash@{0}: WIP on master: 53cffd4 init

yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash apply stash@{0}

git stash drop

当某些保存的修改内容不再需要时,可以使用git stash drop命令丢弃某个修改内容:

yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash list 
stash@{0}: WIP on master: 53cffd4 init
stash@{1}: WIP on master: 53cffd4 init

## 丢弃栈顶的内容
yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash drop 
丢弃了 refs/stash@{0}(75012ec5540bec9eb2b4969f0782a8362e104417)

yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash list
stash@{0}: WIP on master: 53cffd4 init

## 丢弃指定名称的内容
yangsx95@yangsx95-TWS:~/桌面/testreposi$ git stash drop stash@{0} 
丢弃了 stash@{0}(6be9d8a77e6a45b05b9751535539eebeaa922c0c)

git stash clear

清除堆栈中的所有 内容

git stash branch

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

IDEA 中使用 git stash

右击文件夹, 选择Git -> Stash Chanages 和 Unstash Chanages.

参考

最后更新于