检出之前的提交和回滚错误的修改
检出之前的提交
git checkout
git checkout 这个命令有三个不同的作用:检出文件、检出提交和检出分支
用法:
#回到 master 分支
git checkout master
#查看文件之前的版本
git checkout <commit> <file>
#更新工作目录中的所有文件
git checkout <commit>
#注意:
你可以将提交的哈希字串,或是标签作为 <commit> 参数。这会使你处在分离 HEAD 的状态
git checkout 是一种便捷的方式,来将保存的快照「加载」到你的开发机器上去。检出之前的提交是一个只读操作。在查看旧版本的时候绝不会损坏你的仓库。你项目「当前」的状态在master上不会变化。在开发的正常阶段,HEAD 一般指向 master 或是其他的本地分支,但当你检出之前提交的时候,HEAD就不再指向一个分支了——它直接指向一个提交。这被称为「分离 HEAD」状态。
在另一方面,检出旧文件不影响你仓库的当前状态。
所以,在效果上git checkout的这个用法可以用来将单个文件回滚到旧版本
# 这让你的工作目录和 635620e提交所处的状态完全一致你可以查看文件,编译项目,运行测试,甚至编辑文件而不需要考虑是否会影响项目的当前状态,你所做的一切 都不会 被保存到仓库中
git checkout 635620e
git checkout master
一旦你回到 master 分支之后,你可以使用 git revert 或 git reset 来回滚任何不想要的更改
回滚错误的修改
git revert
命令用来撤销一个已经提交的快照,撤销这个提交引入的更改,然后在最后加上一个撤销了更改的 新提交,而不是从项目历史中移除这个提交。这避免了Git丢失项目历史
用法:
#生成一个撤消了 <commit> 引入的修改的新提交,然后应用到当前分支。
git revert <commit>
讨论
撤销(revert)应该用在你想要在项目历史中移除一整个提交的时候。比如说,你在追踪一个 bug,然后你发现它是由一个提交造成的,这时候撤销就很有用。与其说自己去修复它,然后提交一个新的快照,不如用 git revert,它帮你做了所有的事情。
例子
# 编辑一些跟踪的文件
# 提交一份快照
git commit -m "add "
# 撤销刚刚的提交
git revert HEAD
git revert 在后面增加了一个提交来撤销修改,而不是删除它
git reset
如果说 git revert 是一个撤销更改安全的方式,你可以将 git reset 看做一个 危险 的方式
用法:
#从缓存区移除特定文件,但不改变工作目录。它会取消这个文件的缓存,而不覆盖任何更改
git reset <file>
#重设缓冲区和工作目录,匹配最近的一次提交。除了取消缓存之外,--hard 标记告诉 Git 还要重写所有工作目录中的更改。换句话说:它清除了所有未提交的更改,所以在使用前确定你想扔掉你所有本地的开发。
git reset --hard
# 它不仅清除了未提交的更改,同时还清除了 <commit> 之后的所有提交
git reset --hard <commit>
讨论
没有 --hard 标记时 git reset 通过取消缓存或取消一系列的提交,然后重新构建提交来清理仓库。而加上 --hard 标记对于作了大死之后想要重头再来尤其方便。
撤销(revert)被设计为撤销 公开的提交的安全方式,
git reset被设计为重设本地更改。
因为两个命令的目的不同,它们的实现也不一样:重设完全地移除了一堆更改,而撤销保留了原来的更改,用一个新的提交来实现撤销。
取消文件缓存
#git reset 命令在准备缓存快照时经常被用到
# 添加 1.txt 和 2.txt
# 缓存目录下的所有文件
git add .
# 1.txt 和 2.txt 应该在不同的快照中提交
# 取消 1.txt 缓存
git reset 1.txt
#只提次 2.txt
git commit -m "commit 2.txt"
# 在另一份快照中提交 1.txt
git add 1.txt
git commit -m "commit 1.txt"
** git reset 帮助你取消和这次提交无关的修改,让提交能够专注于某一特定的范围**
移除本地修改(绝不要在将提交推送到共享仓库之后执行这样的操作)
# 创建 zhang.txt
# 提交到项目历史
git add zhang.txt
git commit -m "commit zhang.txt"
#再次编辑并提交
git commit -a -m "commit zhang.txt"
# 决定废弃这个功能,并删除相关的更改
git rest --hard HEAD~2
#git reset HEAD~2 命令将当前分支向前倒退两个提交,相当于在项目历史中移除刚创建的这两个提交。记住,这种重设只能用在 非公开 的提交中。绝不要在将提交推送到共享仓库之后执行上面的操作
git clean
git clean 命令将未跟踪的文件从你的工作目录中移除。它只是提供了一条捷径,因为用 git status 查看哪些文件还未跟踪然后手动移除它们也很方便。和一般的 rm 命令一样,
git clean是无法撤消的,所以在删除未跟踪的文件之前想清楚,你是否真的要这么做
git clean 命令经常和 git reset --hard 一起使用。
记住,reset 只影响被跟踪的文件,所以还需要一个单独的命令来清理未被跟踪的文件。这个两个命令相结合,你就可以将工作目录回到之前特定提交时的状态。
用法:
# 执行一次git clean的『演习』。它会告诉你那些文件在命令执行后会被移除,而不是真的删除它。
git clean -n
#移除当前目录下未被跟踪的文件。-f(强制)标记是必需的。它不会删除.gitignore 中指定的未跟踪的文件。
git clean -f
# 移除未跟踪的文件,以及目录。
git clean -df
#移除当前目录下未跟踪的文件,以及 Git 一般忽略的文件
git clean -xf
例子
清除了工作目录中的所有更改,包括新建还没加入缓存的文件。
## 新建一些文件
## 修改一些文件
## 将跟踪的文件回滚回去
git reset --hard
## 移除未跟踪的文件
git clean -df
新的文件没有被加入到仓库中。因此,它们不会受到 git reset --hard 的影响,需要 git clean 来删除它们