文章开始之前分享一些git常用命令

  • git push -ugit push --set-upstream用于推送的同时设置默认上游分支, 用于 git pull/push 不指定分支时的默认拉取的分支(可以配置多个)。
  • git stash -ugit stash --include-untracked命令可以保存包括未跟踪文件(即新添加的文件)在内的所有更改。
  • git reset 分支^ 重置分支到前一次(^)变更, 且已commit的提交会 重新回到工作区。
  • git rebase -X ours dev 在 Git 中,-X--strategy-option 都是用来设定合并策略选项的参数。不过 -X--strategy-option 的简写形式,这两者在功能上是完全相同的。
  • git reflog 查找没有任何指针, 仅有sha1哈希的commit。 (指针包括: 分支指针、标签指针、stash指针…..等等, 如果一个commit分支的某个节点往后没有这些指针中的任何一个, 那么它们将不会被显示, 触发你使用此命令才能够显示。只有显示了, 才有办法找回, 才能最终挽回因之前的错误操作造成的损失。)

前言

由于下午pr代码后, 被要求将多个提交合并为一个提交, 但此时由于自己所在分支已经工作一段时间了,现有的未提交的更改影响到了git rebase -i的操作, 这种情况肯定是不能commit这部分工作内容的, 因此需要用到git stash命令来解决这个问题。

下面是官方对git stash 操作的前言介绍, 当然我的遭遇和这种情况是一类问题

有时,当你在项目的一部分上已经工作一段时间后,所有东西都进入了混乱的状态, 而这时你想要切换到另一个分支做一点别的事情。 问题是,你不想仅仅因为过会儿回到这一点而为做了一半的工作创建一次提交。 针对这个问题的答案是 git stash 命令。
贮藏(stash)会处理工作目录的脏的状态——即跟踪文件的修改与暂存的改动——然后将未完成的修改保存到一个栈上, 而你可以在任何时候重新应用这些改动(甚至在不同的分支上)。

‘git stath’的使用

本人常用的就是 git stash pushgit stash apply 这两个操作了。一个存, 一个取, 直接解决了我遇到的问题。

下面粘一部分官方的使用说明(官方的写的通俗易懂,建议直接在本文末尾点击官方链接去读):

贮藏工作
为了演示贮藏,你需要进入项目并改动几个文件,然后可以暂存其中的一个改动。 如果运行 git status,可以看到有改动的状态:

1
2
3
4
5
6
7
8
9
10
11
$ git status
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

modified: index.html

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: lib/simplegit.rb

现在想要切换分支,但是还不想要提交之前的工作;所以贮藏修改。 将新的贮藏推送到栈上,运行 git stashgit stash push

1
2
3
4
5
$ git stash
Saved working directory and index state \
"WIP on master: 049d078 added the index file"
HEAD is now at 049d078 added the index file
(To restore them type "git stash apply")

可以看到工作目录是干净的了:

1
2
3
$ git status
# On branch master
nothing to commit, working directory clean

此时,你可以切换分支并在其他地方工作;你的修改被存储在栈上。 要查看贮藏的东西,可以使用 git stash list

1
2
3
4
$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log

在本例中,有两个之前的贮藏,所以你接触到了三个不同的贮藏工作。 可以通过原来 stash 命令的帮助提示中的命令将你刚刚贮藏的工作重新应用:git stash apply。 如果想要应用其中一个更旧的贮藏,可以通过名字指定它,像这样:git stash apply stash@{2}。 如果不指定一个贮藏,Git 认为指定的是最近的贮藏:

1
2
3
4
5
6
7
8
9
10
$ 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: index.html
modified: lib/simplegit.rb

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

可以看到 Git 重新修改了当你保存贮藏时撤消的文件。 在本例中,当尝试应用贮藏时有一个干净的工作目录,并且尝试将它应用在保存它时所在的分支。 并不是必须要有一个干净的工作目录,或者要应用到同一分支才能成功应用贮藏。 可以在一个分支上保存一个贮藏,切换到另一个分支,然后尝试重新应用这些修改。 当应用贮藏时工作目录中也可以有修改与未提交的文件——如果有任何东西不能干净地应用,Git 会产生合并冲突。

文件的改动被重新应用了,但是之前暂存的文件却没有重新暂存。 想要那样的话,必须使用 –index 选项来运行 git stash apply 命令,来尝试重新应用暂存的修改。 如果已经那样做了,那么你将回到原来的位置:

1
2
3
4
5
6
7
8
9
10
11
12
$ git stash apply --index
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

modified: index.html

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: lib/simplegit.rb

应用选项只会尝试应用贮藏的工作——在堆栈上还有它。 可以运行 git stash drop 加上将要移除的贮藏的名字来移除它:

1
2
3
4
5
6
$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log
$ git stash drop stash@{0}
Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)

也可以运行 git stash pop 来应用贮藏然后立即从栈上扔掉它。

参考

https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E8%B4%AE%E8%97%8F%E4%B8%8E%E6%B8%85%E7%90%86