Synopsisgit
git reset
, git checkout
, git revert
是git
工具箱中最经常使用的工具.它们都用来撤销代码仓库中的某些更改,而前两个命令不只能够做用于提交,还能够做用与特定的某个文件.shell
git仓库由上图三个部分组成,__Working Directory__ 工做目录, Staged Snapshot 缓存区, Commit History 提交历史.缓存
git reset
, git checkout
的参数决定了它们的做用域.若是没有包含文件路径,这些操做对于全部的提交生效,这一节探讨提交层面的操做,git revert
没有文件层面的操做.安全
在提交层面,reset将一个分支的末端(HEAD)指向另外一个提交历史.这能够用来移除当前分支的一些提交.好比,下面的这两条命令让_hotfix_分支向后回退了两次提交.bash
git checkout hotfix git reset HEAD~2
如今hotfix分支末端的两次提交变成了悬挂提交.也就是说,下次Git进行垃圾回收的时候,这两个提交将被删除.换句话说,若是你提交了错误的代码,想要抹除掉本身已经提交的内容,你能够用git reset
来丢掉你已经提交的代码,可是默认不会修改你的工做区的代码,因此回退以后你的工做区代码没有任何变化,可是git status
会变化.工具
走一遍流程:spa
git init
初始化一个仓库code
echo "init commit" >> README.md
作用域
git status
查看仓库状态rem
git add .
跟踪文件并提交至缓冲区
git commit -m 'init commit'
提交修改
按照上述流程再增长一个提交,下面直接写shell
代码
echo "first commit" >> README.md git add . git commit -m 'first commit'
下面是当前仓库的状态图
提交历史的状态
git reset HEAD~1
回退代码
此时的仓库的状态变成了这样:
缓冲区和提交历史区域的代码所有被丢弃,仓库的状态也发生了改变.此时提交历史是这样的:
末尾的一次提交变成了悬挂提交.
除了默认的丢弃掉缓冲区和提交历史的代码,git reset
还有其余的选项决定该命令的做用范围.
--soft
工做目录的代码和缓冲区的代码都不会改变 能够称之为软撤销
--mixed
默认的方式,只会保留工做目录的代码
--hard
丢弃掉工做目录,缓冲区,提交历史中的代码,能够称之为硬撤销
这些标记经常和git reset
一块儿使用,--mixed
在你不想彻底舍弃本身的代码,--hard
在你想彻底的丢弃本身的代码.
注意: 当你传入除HEAD之外的提交历史的时候要格外当心,由于git reset
操做会重写你的提交历史,这意味着你以前的提交找不回来了,若是在公共分支上面这样作,会致使其余人的提交代码丢失,切忌在公共分支上面这样作.
这个应该是最经常使用的命令了,当传入一个分支名是,git能够切换到那个分支.
git checkout hotfix
上诉命令从当前分支切换到hotfix
分支,git只不过是将HEAD的指向切换到hotfix的末端,而后更新工做目录.由于这个操做可能会覆盖当前工做目录的内容,因此git在切换以前会强制要求你提交当前工做目录或者是缓冲区中的修改,否则在checkout
的时候这些修改将会丢失.和git reset
不一样的是,git checkout
并无修改这些分支.仅仅是切换了HEAD的引用.
除了分支之外,你还能够传入提交的引用来checkout
到任意的提交.这和checkout
到任意的分支是同样的: 切换HEAD的引用到特定的提交.好比,下面这条命令会checkout
到当前提交的祖父分支:
git checkout HEAD~2
这对于查看当前分支的历史记录很是重要.但若是你当前的HEAD没有任何分支的引用,那么这会形成HEAD的分离.这是很是危险的,若是你接着提交新的提交,而后切换到其余分支以后就没有办法回到以前添加的那些提交.所以,在为分离的HEAD添加新的提交以前你应该建立一个新的分支.
Revert撤销一个提交的同时会建立一个新的提交。这是一个安全的方法,由于它不会重写提交历史。好比,下面的命令会找出倒数第二个提交,而后建立一个新的提交来撤销这些更改,而后把这个提交加入项目中。
git checkout hotfix git revert HEAD~2
未完待续 2017.5.26