git stash 命令使用

9/16/2020 git stash

# git stash介绍

使用git stash时要录制工作目录和索引的当前状态,但想回到干净的工作目录。该命令保存您的本地修改,并恢复工作目录以匹配HEAD提交。

简单说就是如果你想把错误分支开发的新代码提交到正确的分支,就可以使用 git stash 命令来实现。

git stash命令会把我们工作区和暂存区的修改保存下来,然后将这些修改的内容从当前的文件中移出并保存在存档库里面。所以我们就回到了之前没有修改过内容的干净的工作区。

# 使用背景

在错误的分支开发了新代码

当前的分支是错误的、已经废弃的分支,但是开发者不知道,并且在此分支开发新的代码,此时有以下三种情况

新代码还未在本地提交 (commit)
新代码本地已提交,但还未push到远程
新代码本地已经提交,且push到远程
1
2
3

# 1、新代码还未在本地提交 (commit)

举个栗子,有如下三个分支:

master
one   // 错误分支
two   // 正确分支
1
2
3

我们在 one 分支下分别创建 src/index.html、**src/js/index.js**文件,并写入一些内容,之后我们使用 git add . 提交到暂存区,这时我们发现 two 分支才是正确分支,幸好此时代码还没有本地进行提交,只需要在当前的 one 分支下命令行输入

git stash
1

这个命令表示把我们当前修改的内容暂存起来,并且工作区会恢复到没有开发新功能之前的代码。

输入完成运行,我们会发现命令行会输出

Saved working directory and index state WIP on master: 2d34170 第一次提交
1

这里需要注意, git stash 默认相当于 git stash push 命令,并且输出内容以统一格式输出

Saved working directory and index state WIP on <branchname>: <hash> <commit message>
1

其中 branchname 是当前所在分支的名字,hash 是当前分支最近一次提交的hash值,commit message 是最近的一次提交的时候添加的提交信息。

之后我们切换到正确分支,然后再使用

git stash apply
1

这个命令表示把我们之前暂存的内容,应用到当前分支。这样就相当于把修改的内容从一个分支移动到了另一个分支。

另外,当只执行一次修改暂存时,我们可以使用 git stash 直接进行,当需要多次修改暂存时,我们可以使用 git stash push -m message 来进行说明,这样可以便于识别。

此外,当我们有较多的修改暂存时,可以使用 git stash list 来查看当前修改列表,这个命令默认展示的是文件的差别统计。如果想展示具体改动的内容的话,可以使用 git stash show -p

# 2、新代码本地已提交,但还未push到远程

根据情况这个问题可以有两种处理的方式。

# 将新代码移到新分支

首先使用 git log 查看当前分支的提交(假设是2d34170),找到后我们使用 git reset 2d34170 把当前分支已提交的内容重置到我们开发新功能之前的样子,现在fd01444处于这次提交之后的所有提交都会被重置为没有提交的状态。

接下来我们需要把这些新开发的功能迁移到一个新的分支。这时候我们可以使用 git checkout -b <new branch> 来进行操作。操作完成后即将新代码移到新的分支。

# 将新代码移到另一个分支

如果我们需要把当前添加的新功能迁移到另一个已经存在的分支,那么我们需要做的前几个步骤跟上面的操作是一样的:

git log  # 查找新功能开发之前的提交
git reset <commit hash> # 将当前分支重置到新功能开发之前的提交
1
2

接下来我们现在的状态就回到了新功能还没有提交的状态,那么就可以继续使用 git stash 相关的命令去操作了。

我们还有另外一个方法也能够将已提交到当前分支的功能添加到另一个分支上,那就是使用 git cherry-pick 命令。首先我们还是先用 git log 查找当前已提交的功能的hash值,然后切换到目标分支,运行命令:

git cherry-pick <commit hash>
1

这样就把我们在另一个分支开发的功能,添加到我们想要的分支了。如果有冲突的话,需要手动处理一下冲突。然后我们回到最初的分支,再次运行 git reset <commit hash> 命令,把已提交的内容进行重置,然后运行命令:

git checkout -- .
1

把当前分支没有添加到暂存区的内容都清除掉,这样也可以达到我们上面所说的,把新功能添加到另一个分支的目的。

# 3、新代码本地已经提交,且push到远程

如果已经提交到远程了,第一步要做的就是进行代码回滚,保证远程不被污染,其次对自己的提交进行撤销。

Last Updated: 6/2/2023, 3:54:33 PM