在Git中,用HEAD
表示当前版本,上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,
当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100
。
撤销一个已提交修改
撤销某次提交,此次操作之前和之后的commit和history都会保留,并且把这次撤销作为一次最新的提交
git revert HEAD 撤销前一次 commit
git revert HEAD^ 撤销前前一次 commit
git revert commit (比如:fa042ce57ebbe5bb9c8db709f719cec2c58ee7ff)撤销指定的版本,撤销也会作为一次提交进行保存。
git revert是提交一个新的版本,将需要revert的版本的内容再反向修改回去,版本会递增,不影响之前提交的内容
修改最近一次的提交信息
提交时,可能没写好或者误操作导致提交的信息不合适,但你还没有 push 到远程分支时,修改上一次的提交信息。
git commit –amend或git commit --amend -m "Fixes bug #42"
如果需要修改已push的文件,需要如下操作:
git rebase -i HEAD~3
git commit -amend
git rebase --continue
撤销本地修改
git checkout -- file
git checkout -- file
可以丢弃工作区的修改,把file文件在工作区的修改全部撤销,这里有两种情况:
- 一种是自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
- 一种是已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
重置修改
已经使用git add
,但是没有使用git commit
,需要修改暂存区内容:
git reset HEAD file
仅用HEAD指向的目录树充值暂存区,工作区不受影响。相当于把git add命令更新到暂存区的内容撤出暂存区
git reset --hard HEAD^
把版本库、暂存区和工作区都回退到HEAD的前一个版本。head版本的提交全部丢失。慎用!
git reset --hard HEAD
等价与:
git reset HEAD file
git checkout -- file
版本回退
git reset --hard HEAD^
git reset --hard commit_id
撤销本地后重做
已经提交了一些内容,并使用git reset –hard撤销了这些更改(见上面),突然意识到:你想还原这些修改!
git reflog
git reflog是一个用来恢复项目历史记录的好办法。你可以通过git reflog恢复几乎任何已提交的内容。
git reflog与git log类似,只不过git reflog显示的是HEAD变更次数的列表。
具体一个例子,假设有三个commit,
git st:
commit3: add test3.c
commit2: add test2.c
commit1: add test1.c
如果执行git reset –hard HEAD~1则 删除了commit3,如果发现删除错误了,需要恢复commit3,这个时候就要使用
git reflog
HEAD@{0}: HEAD~1: updating HEAD
63ee781 HEAD@{1}: commit: test3:q
运行git log则没有这一行记录,可以使用git reset –hard 63ee781将红色记录删除,则恢复了cmmit3,运行git log后可以看到:
git reset --hard 63ee781
git log
commit3: add test3.c
commit2: add test2.c
commit1: add test1.c
停止跟踪一个已被跟踪的文件
场景:你意外将application.log添加到仓库中,现在你每次运行程序,Git都提示application.log中有unstaged的提交。
你在.gitignore中写上”*.log”,但仍旧没用——怎样告诉Git“撤销”跟踪这个文件的变化呢?
git rm --cached application.log
发生了什么:尽管.gitignore阻止Git跟踪文件的变化,甚至是之前没被跟踪的文件是否存在,
但是,一旦文件被add或者commit,Git会开始持续跟踪这 个文件的变化。
类似的,如果你用git add –f来“强制”add,或者覆盖.gitignore,Git还是会继续监视变化。所以以后最好不要使用 –f来add .gitignore文件。
如果你希望移除那些应当被忽略的文件,git rm –cached可以帮助你,并将这些文件保留在磁盘上。
因为这个文件现在被忽略了,你将不会在git status中看到它,也不会再把这个文件commit了。
git reset 与 git revert
git revert 是生成一个新的提交来撤销某次提交,此次提交之前的commit都会被保留
git reset 是回到某次提交,提交及之前的commit都会被保留,但是此次之后的修改都会被退回到暂存区
假设有三个commit,
git st
commit3: add test3.c
commit2: add test2.c
commit1: add test1.c
当执行git revert HEAD~1时, commit2被撤销了,git log可以看到:
revert “commit2”:this reverts commit 5fe21s2…
commit3: add test3.c
commit2: add test2.c
commit1: add test1.c
git status 没有任何变化,如果换做执行git reset –soft(默认) HEAD~1后,运行git log
commit2: add test2.c
commit1: add test1.c
运行git status, 则test3.c处于暂存区,准备提交。
如果换做执行git reset –hard HEAD~1后,
显示:HEAD is now at commit2,运行git log
commit2: add test2.c
commit1: add test1.c
运行git st, 没有任何变化,工作目录文件也不存在