Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Git基础理解--重置与撤销 #41

Open
@CodeDreamfy

Description

Git作为一个系统,以它的一般操作来管理并操纵着这三棵树:

用途
HEAD 上一次提交的快照,下一次提交的父节点
Index 预期的下一次提交的快照
Work Directory 沙盒,当前工作目录

HEAD

通常指的是当前分支的引用指针,指向到上一次提交的引用,总是指向该分支上的最后一次提交。

常用底层命令

git cat-file -p HEAD
git ls-tree -r HEAD

索引 Index

预期的下一次提交,其实就是本地工作目录编辑的文件添加到追踪,称之为暂存区

git ls-files -s

工作目录

另外两棵树是一种高效但不直观的方式将内容存储在.git文件中。工作目录其实就是解包为实际文件以方便编辑,可以当做是沙盒。

Reset 命令

--soft (移动HEAD)

git reset --soft HEAD~

HEAD指向到上一次commit命令之前,也就是add命令之后的状态,本质上只是撤销了上一次 git commit 命令,执行resetHEAD~时,其实就是把该分支移动回原来的位置,而不会改变索引和工作目录。

--mixed (更新索引)

git reset [--mixed] HEAD~命令

属于默认行为,即执行git reset HEAD~等同于执行了--mixed,执行后会撤销上一次的提交,还会取消暂存所有的东西,于是,我们回滚了所有的git add git commit命令之前

--hard (更新工作目录)

本质上是将HEAD复制到Index上,这一步很危险,会丢失之前的修改,并且还带有取消暂存文件的实际效果,比如指向舍弃本地的修改,可以直接git reset --hard HEAD,意味着将本地的HEAD指向到索引和工作区,甚至还可以通过具体的提交来拉取该文件的对应的版本git reset HASH -- xxxfile

Tips

  1. git reset --hard方式可以将之前多个提交合并成一个,即使用git reset --soft HEAD~x

  2. 执行了git reset 后如果想放弃该操作,可以使用git reflog查看操作历史,找到之前的HEAD后,执行git reset --hard到那个HEAD,甚至可以更快一步,直接执行`git reset --hard HEAD~``

Checkout与Reset区别

不细看执行git checkout [branch]git reset --hard [branch]非常类似,都是会更新三棵树,使其看起来像[branch],不过还是有很大的差别。

  1. 不同于reset --hard,checkout对工作目录是安全的,通过检查确保不会将已经更改的文件弄丢。并会尝试在工作目录中进行简单合并,这样所有还未修改过的文件都会被更新。而reset --hard则会不做检查就全面替换所有东西,丢失所有修改的未提交的文件。
  2. HEAD的更新处理方式不同,reset会移动HEAD分支的指向,而checkout只会移动HEAD自身来指向另一个分支

checkout另一种使用方式就是指定一个文件路径,就像reset一样不会移动HEAD.类似于git reset [branch] file那样用该次提交中的那个文件来更新索引,但它会覆盖工作目录中对应的文件,就像是git reset --hard [branch] file

另外git resetgit addgit checkout都接受--patch选项,允许你根据选择一块一块地恢复文件内容

影响表:

HEAD Index workdir wd safe
Commit Level
reset --soft [commit] REF NO NO YES
reset [commit] REF YES NO YES
reset --hard [commit] REF YES YES NO
checkout HEAD YES YES YES
File Level
reset [commit] NO YES NO YES
checkout [commit] NO YES YES NO

撤销操作

--amend

有时候提交后发现漏掉几个文件没有添加或者没有去掉注释,或者提交信息写错了,可以使用该命令,最终只会有一个提交.

git commit --amend

可以理解为:用新的提交替换旧的提交。但是要注意上一次提交需要没有push到远程分支

取消暂存的文件

当我们执行了git add .后,如果想取消暂存其中一个怎么处理呢?其实git status 已经提示了:git reset HEAD <file>来进行取消暂存

撤销对文件的修改

如果不想保留对文件的修改,git status也提示了如果处理:

git checkou <file>,但这样做其实很危险,因为会将修改的文件永久消失

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

        AltStyle によって変換されたページ (->オリジナル) /