Git撤销操作
Git中提供了几个相关的撤销操作的命令,如 clean、checkout、reset和revert;在看这篇文章之前,我希望你能够浏览一下我的另一篇文章:Git工作区、暂存区和历史记录区,看完之后理解这篇文章会更简单一些
git clean
git clean 命令用来从你的工作目录中删除所有没有 tracked 过的文件
参数说明
1 | git clean -n |
是一次 clean 的演习, 告诉你哪些文件会被删除。 记住他不会真正的删除文件, 只是一个提醒。
1 | git clean -f |
删除当前目录下所有没有 track 过的文件。 他不会删除 .gitignore 文件里面指定的文件夹和文件, 不管这些文件有没有被 track 过。
1 | git clean -f <path> |
删除指定路径下的没有被 track 过的文件。
1 | git clean -df |
删除当前目录下没有被 track 过的文件和文件夹。
1 | git clean -xf |
删除当前目录下所有没有 track 过的文件。 不管他是否是 .gitignore 文件里面指定的文件夹和文件。
应用场景
假如你要删除所有工作目录下面的修改,包括新添加的文件:
1 | git reset --hard |
运行后,工作目录和缓存区回到最近一次 commit 时候一摸一样的状态, git status 会告诉你这是一个干净的工作目录,又是一个新的开始了。
git checkout
git checkout 命令用来丢弃本地修改
参数说明
1 | git checkout -- files |
把文件从暂存区域复制到工作目录,用来丢弃本地修改
1 | git checkout . |
会用暂存区全部的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动
1 | git checkout HEAD . |
会用 HEAD 指向的 master 分支中的全部文件替换暂存区以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动
应用场景
有时候我们的工作区会增加一些不想要的文件(多数为隐藏文件),比如 .idea/、.DS_Store 文件,此时我们不想将这些无关紧要的文件添加到暂存区,所以就像将它们从工作区丢弃,此时就可以利用下面的命令将该文件夹丢弃:
1 | git checkout .idea/ |
当然,这种总是会自动生成的文件最好写到 .gitignore 里,否则每次都要 checkout 会很烦的
git reset
git reset 命令撤销对于暂存区 / 历史记录区的修改,也就是撤销你本地的 add,commit 操作
参数说明
1 | git reset |
撤销所有暂存区域文件
1 | git reset -- files |
用来撤销最后一次的 git add files(因为每 git add file 一次,暂存区的文件都会被更改一次)
1 | git reset --mixed <commit id> |
会保留源码,只是将 git commit 和 index 信息回退到了某个版本。(相当于撤销了 add 和 commit 操作,提交的修改都回到了工作区)
1 | git reset --soft <commit id> |
保留源码,只回退 commit 信息到某个版本,不涉及index的回退,如果还需要提交,直接commit即可。(也就是只撤销了commit,并没有撤销add)
1 | git reset --hard <commit id> |
源码也会回退到某个版本,commit 和 index 都回回退到某个版本。(注意,这种方式是改变本地代码仓库源码),当然有人在 push 代码以后,也可以使用 reset --hard <commit id>
回退本地的代码到某个版本之前,但是这样会有一个问题,你线上的代码没有变,线上 commit,index 都没有变,当你把本地代码修改完提交的时候你会发现全是冲突。。(此时就需要用到下面要介绍的 git revert 了)
应用场景
当我们在使用 pull 的时候,可能会出现冲突,就需要 merge,而在冲突状态下,需要解决冲突的文件会从 index 暂存区打回到工作区,如果我们想放弃 index 和工作区的改动,就可以执行下面这条命令:
1 | git reset --hard HEAD |
上面这条命令用来撤销还没 commit 的 merge,就放弃了 index 暂存区和工作区的改动
当我们在本地进行了 add 和 commit 操作之后,发现本地的修改都是错误的,想要回到前一版本,就可以执行下面这条命令:
1 | git reset --hard HEAD^ |
上面这条命令用来撤销已经 commit 的内容(等价于 git reset --hard HEAD~1
)。原理就是放弃工作区和 index 的改动,同时 HEAD 指针指向前一个 commit 对象
如果我们已经用 add 命令将某个文件加入暂存区了,此时想撤销对这个文件的 add 操作,就可以用下面的命令:
1 | git reset HEAD <file> |
上面这条命令用来撤销对单个文件的 git add,执行之后该文件会从暂存区回到工作区中
git revert
git revert 用于反转提交,执行 revert 命令时要求工作树必须是干净的。git revert 用一个新提交来消除一个历史提交所做的任何修改。
###参数说明
1 | git revert <commit id> |
revert 使用,需要先找到你想回滚版本唯一的 commit 标识代码,可以用 git log
进行查看,commit id 是一串 40 位的字符串,通常用前几位即可(6 位就差不多保证唯一了);执行完之后,revert 的那一次 commit 被撤销,原理是 git revert 用一次逆向的 commit “中和”之前的提交,所以此时 HEAD 继续前进,只是新的 commit 的内容和要 revert 的内容正好相反,能够抵消要被 revert 的内容;这样在日后合并老的 branch 时,导致这部分改变不会再次出现,就不会出现类似 git reset 带来的冲突问题
应用场景
对于已经把代码 push 到线上仓库,但是此时发现 push 的代码有问题,你想回退本地代码的同时也回退线上代码,回滚到某个指定的版本,使得线上和线下代码保持一致:
1 | git revert <commit id> |
执行完此命令之后,再执行 git push 就可以将线上代码回滚到某个指定版本,同时不会像 git reset 一样可能会导致一大堆冲突
git 的其它删除命令
这些命令类似于 Linux 的命令,是一种物理层面的删除,也会经常遇到:
1 | git rm --cached readme.txt |
只从缓存区中删除readme.txt,保留物理文件
1 | git rm readme.txt |
不但从缓存区中删除,同时删除物理文件
1 | git mv a.txt b.txt |
把a.txt改名为b.txt
参考文章
听说赞过就能年薪百万