第9章 恢复进度

在之前“第5章Git暂存区”一章的结尾,曾经以终结者(The Terminator)的口吻说过:“我会再回来的”,会继续对暂存区的探索。经过了前面三章对Git对象、重置命令和检出命令的探索,现在已经拥有了足够多的武器,是时候“回归”了。

本章“回归”之后,有了前面几章的基础,再看Git状态输出中关于git reset或git checkout的指示,大家就会觉得很亲切、易如反掌了。本章还会重点介绍“回归”使用的git stash命令。

9.1 继续暂存区未完成的实践

经过了前面的实践,现在DEMO版本库应该处于master分支上,看看是不是这样。


$cd/path/to/my/workspace/demo

$git status-sb#Git 1.7.2及以上版本才支持-b参数哦

master

$git log—graph—pretty=oneline—stat

*2b31c199d5b81099d2ecd91619027ab63e8974ef Merge commit 'acc2f69'

|\

|*acc2f69cf6f0ae346732382c819080df75bb2191 commit in detached HEAD mode.

||0 files changed,0 insertions(+),0 deletions(-)

*|4902dc375672fbf52a226e0354100b75d4fe31e3 does master follow this new commit?

|/

|0 files changed,0 insertions(+),0 deletions(-)

*e695606fc5e31b2ff9038a48a3d363f4c21a3d86 which version checked in?

|welcome.txt|1+

|1 files changed,1 insertions(+),0 deletions(-)

*a0c641e92b10d8bcca1ed1bf84ca80340fdefee6 who does commit?

*9e8a761ff9dd343a1380032884f488a2422c495a initialized.

welcome.txt|1+

1 files changed,1 insertions(+),0 deletions(-)


还记得在之前“第5章Git暂存区”一章的结尾是如何保存进度的吗?翻回去看一下,用的是git stash命令。这个命令用于保存当前进度,也是恢复进度要用的命令。

查看保存的进度用命令git stash list。


$git stash list

stash@{0}:WIP on master:e695606 which version checked in?


现在就来恢复进度。使用git stash pop从最近保存的进度进行恢复。


$git stash pop

On branch master

Changes to be committed:

(use "git reset HEAD<file>…" to unstage)

#

new file:a/b/c/hello.txt

#

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:welcome.txt

#

Dropped refs/stash@{0}(c1bd56e2565abd64a0d63450fe42aba23b673cf3)


先不要管git stash pop命令的输出,后面会专题介绍git stash命令。通过查看工作区的状态,可以发现进度已经找回了(状态与进度保存前稍有不同)。


$git status

On branch master

Changes to be committed:

(use "git reset HEAD<file>…"to unstage)

#

new file:a/b/c/hello.txt

#

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:welcome.txt

#


此时再看Git的状态输出,是否别有一番感觉呢?有了前面三章的基础,现在可以游刃有余地应对各种情况了。

(1)以当前暂存区的状态进行提交,即只提交a/b/c/hello.txt,不提交welcome.txt。执行提交:


$git commit-m "add new file:a/b/c/hello.txt,but leave welcome.txt alone."

[master 6610d05]add new file:a/b/c/hello.txt,but leave welcome.txt alone.

1 files changed,2 insertions(+),0 deletions(-)

create mode 100644 a/b/c/hello.txt


查看提交后的状态:


$git status-s

M welcome.txt


(2)反悔了,回到之前的状态。

用重置命令放弃最新的提交:


$git reset—soft HEAD^


查看最新的提交日志,可以看到前面的提交被抛弃了。


$git log-1—pretty=oneline

2b31c199d5b81099d2ecd91619027ab63e8974ef Merge commit 'acc2f69'


工作区和暂存区的状态也都维持在原来的状态。


$git status-s

A a/b/c/hello.txt

M welcome.txt


(3)想将welcome.txt提交。


$git add welcome.txt

$git status-s

A a/b/c/hello.txt

M welcome.txt


(4)想将a/b/c/hello.txt撤出暂存区。

也是用重置命令。


$git reset HEAD a/b/c

$git status-s

M welcome.txt

?? a/


(5)想将剩下的文件(welcome.txt)从暂存区撤出,就是说不想提交任何东西了。还是使用重置命令,甚至可以不使用任何参数。


$git reset

Unstaged changes after reset:

M welcome.txt


(6)想将本地工作区所有的修改清除。即清除welcome.txt的改动,删除添加的目录a及下面的子目录和文件。

清除welcome.txt的改动用检出命令。

实际对于此例执行git checkout.也可以。


$git checkout—welcome.txt


工作区显示还有一个多余的目录a。


$git status

On branch master

Untracked files:

(use "git add<file>…" to include in what will be committed)

#

a/


删除本地多余的目录和文件,可以使用git clean命令。先来测试运行以便看看哪些文件和目录会被删除,以免造成误删。


$git clean-nd

Would remove a/


真正开始强制删除多余的目录和文件。


$git clean-fd

Removing a/


整个世界清净了。


$git status-s