本文主要来介绍一下 Git 的内部状态管理系统。它利用基于节点和指针的数据结构来跟踪及管理编辑操做的时间线。html
对本地项目而言,任一时刻,Git 处于三种状态中的一种:工做区状态、暂存区状态和提交区状态。
下面利用新建项目来演示一下不一样状态及其转换。python
$ mkdir git_tree_test && cd git_tree_test $ git init 提示:使用 'master' 做为初始分支的名称。这个默认分支名称可能会更改。要在新仓库中 提示:配置使用初始分支名,并消除这条警告,请执行: 提示: 提示: git config --global init.defaultBranch <名称> 提示: 提示:除了 'master' 以外,一般选定的名字有 'main'、'trunk' 和 'development'。 提示:能够经过如下命令重命名刚建立的分支: 提示: 提示: git branch -m <name> 已初始化空的 Git 仓库于 /Users/phillee/git_tree_test/.git/ $ git status 位于分支 master 尚无提交 无文件要提交(建立/拷贝文件并使用 "git add" 创建跟踪)
这时咱们初始化了一个本地项目,默认建立 master 分支,尚无文件跟踪及提交。git
$ touch reset_lifecycle_file $ git status 位于分支 master 尚无提交 未跟踪的文件: (使用 "git add <文件>..." 以包含要提交的内容) reset_lifecycle_file 提交为空,可是存在还没有跟踪的文件(使用 "git add" 创建跟踪)
如今咱们为项目新增了文件 reset_lifecycle_file ,还没有提交,当前位于工做区(Working directory)。博客园代码显示系统太垃圾了,这时的
$ git add reset_lifecycle_file $ git status 位于分支 master 尚无提交 要提交的变动: (使用 "git rm --cached <文件>..." 以取消暂存) 新文件: reset_lifecycle_file
全部变更的文件,Git 都记录在一个区域,叫作"暂存区"(Staging index)。咱们经过 git add
指令将工做区中的内容保存到暂存区,这时已经实现了对文件的跟踪,但尚未请求提交。这时候的文件已经被跟踪了,
$ git commit -m "init commit" [master(根提交) 88b5382] init commit 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 reset_lifecycle_file $ git status 位于分支 master 无文件要提交,干净的工做区
暂存区保留变更的文件信息,等到修改结束添加到"提交历史"(Commit history)中,这就至关于当前项目的一个快照(snapshot)。
项目提交历史就是由不一样时间的快照构成。Git 能够根据此提交信息将项目恢复到任意一个快照状态。bash
前面叙述并展现了三种状态之间的前向转换,如今咱们反过来看一下,如何将当前状态转换成其父状态。微信
$ touch gitadd_test_file $ vim gitadd_test_file
新建一个测试文件并利用该文件进行不一样状态之间转换的实验。数据结构
i
键进入编辑模式;Hello world!
;esc
退出编辑模式;shift+;
进入命令编辑模式;x
回车便可保存到文件并退出vim
。$ git status 位于分支 master 未跟踪的文件: (使用 "git add <文件>..." 以包含要提交的内容) gitadd_test_file 提交为空,可是存在还没有跟踪的文件(使用 "git add" 创建跟踪) $ git add gitadd_test_file $ git commit -m "add one file for test" [master d97ee77] add one file for test 1 file changed, 1 insertion(+) create mode 100644 gitadd_test_file $ git log --oneline d97ee77 (HEAD -> master) add one file for test 88b5382 init commit
按步骤2-4的方式将新建立的文件添加到提交历史中。如今咱们尝试将已经提交 commit
但还没有 push
到远端仓库的状态返回到暂存区状态。此时的
$ git reset --soft 88b538 $ git status 位于分支 master 要提交的变动: (使用 "git restore --staged <文件>..." 以取消暂存) 新文件: gitadd_test_file
如上结果所示,这时已经处于 git commit
命令以前的状态,达到此结果使用的是 git reset --soft
指令。
该操做会保留文件的改动及索引状态,撤销完成后将回到添加改动的状态。注意与接下来要使用的 git reset --hard
之间的区别。此时的
$ git restore --staged gitadd_test_file $ git status 位于分支 master 未跟踪的文件: (使用 "git add <文件>..." 以包含要提交的内容) gitadd_test_file 提交为空,可是存在还没有跟踪的文件(使用 "git add" 创建跟踪)
经过 git restore --staged
指令,咱们得以将暂存区状态返回到工做区状态,也就是 git add
以前的状态。此时的
$ git add gitadd_test_file $ git commit -m "add test file for git add test" [master d535a57] add test file for git add test 1 file changed, 1 insertion(+) create mode 100644 gitadd_test_file $ git log --oneline d535a57 (HEAD -> master) add test file for git add test 88b5382 init commit $ git reset --hard 88b538 HEAD 如今位于 88b5382 init commit $ git status 位于分支 master 无文件要提交,干净的工做区
注意这里是将 gitadd_test_file
从新添加到暂存区,而后保存到提交历史中。从提交历史中的状态直接返回到 git add
以前的状态使用的指令是 git reset --hard
,该指令强制将 HEAD
指针指向提交历史线中的前一个提交状态,会连同咱们刚才新建的文件一块儿所有撤销。这是一个比较危险的举动,使用的时候要注意场合。固然即便这么操做了也并不是就不能复原了,只是会多几步操做而已。
(全文完)
本文做者 :phillee
发表日期 :2021年3月30日
本文连接 :https://www.cnblogs.com/phillee/p/14598437.html
版权声明 :自由转载-非商用-非衍生-保持署名(创意共享3.0许可协议/CC BY-NC-SA 3.0)。转载请注明出处!
限于本人水平,若是文章和代码有表述不当之处,还请不吝赐教。
感谢您的支持
微信支付