前言
你是否也曾遇到版本回退的困扰,是否害怕使用版本回退,每次当错误提交之后,就惊的一身冷汗。很早以前,我就是这样子的。
场景一
提交了一个commit,发现修改了不该修改的内容,怎么办?在现有分支上修改完了之后再次提交?这样无疑是可以的,但是我们可以通过git revert命令优雅的解决这种问题。
提交一个commit
我们在A分支上提交一个commit。1
2
3 vim a.txt
git add .
git commit -m "增加a.txt文件"
revert最近一次commit
这个时候,我们使用revert命令将这次commit给重置。1
git revert HEAD
revert命令实际上做的事情就是重新生成一个commit覆盖掉之前的那个commit。这个时候git仓库的commit记录是这样的。
提交了多次commit才发现有问题
如果commit之后,你并没有发现问题,同时你又提交了多个commit,突然发现之前的commit有问题怎么办呢。1
2
3
4
5
6
7
8
9
10
11
12 vim a.txt
git add .
git commit -m "增加a.txt文件"
vim b.txt
git add .
git commit -m "增加b.txt文件"
vim c.txt
git add .
git commit -m "增加c.txt文件"
vim d.txt
git add .
git commit -m "增加d.txt文件"
发现a.txt的那次commit是不需要的。这个时候我们找到commit的唯一标识,然后使用revert将其废弃掉。1
2
3 git log
git revert be6afa6ee5
be6afa6ee5就是a.txt文件对应的commit唯一标识。这个时候git仓库的commit记录是这样的。
找不到parent
有时候你在revert的时候会出现如下的问题。
这个问题产生的原因是你revert的这个commit它是从两个不同的分支merge后产生的。所以它的parent有两个,你在revert的时候它不知道该revert到哪一个parent,所以就报错了。
这个时候你可以通过-m参数来指定你需要revert的parent。1
git revert HEAD -m 1
上面的命令就表示你需要revert那个执行merge命令的分支。
场景二
一年以前,不是很懂git的我,每次版本上线之后都不会打入tag,也不会给每次上线的版本单独保存一个分支,所以就出现了这样的问题。当出现线上bug的时候,我需要找到上线的commit,然后将HEAD指向那个commit修改bug(当时的我是多么的智障啊,哈哈哈)。
版本上线后提交若干个commit
这里我们提交若干个commit。1
2
3
4
5
6
7
8
9
10
11
12 vim a.txt
git add .
git commit -m "增加a.txt文件"
vim b.txt
git add .
git commit -m "增加b.txt文件"
vim c.txt
git add .
git commit -m "增加c.txt文件"
vim d.txt
git add .
git commit -m "增加d.txt文件"
强制回退
线上出现问题,因为没有tag,也没有具体分支对应发布版本。我就copy了一份代码,然后reset强制回退后修改bug(千万不要学我,一年前的我就是这么做的)。1
2
3 git log
git reset --hard 01aa54f328
这样就将HEAD强制指向了之前发包的commit。
误操作reset
这尼玛就蛋疼了,你在开发过程中发现自己误操作使用了reset命令。卧槽,git log还没有之前的东西了,怎么办怎么办,大脑一片空白。不要慌不要慌,git还是有记录存在的。1
git reflog
在我们reset –hard之后使用git log命令来查看得到如下结果。
而我们使用git reflog命令来查看可以得到如下结果。
看到这里我们就知道该怎么做了,我们可以直接通过reset命令再将HEAD指向对应的commit。1
git reset --hard f06e667
这里千万不要用git reset –hard HEAD~1,因为你现在HEAD之前1个commit是init的那个commit。
无关联覆盖
前段时间,朋友遇到这样的问题。他在使用hexo做静态博客的过程中,repo仓库地址填写错误,导致hexo d命令执行后将原来一个项目的所有文件都被覆盖掉了。
其实解决是十分简单的,我们只需要强制覆盖掉远程仓库的代码就可以了。1
git push origin -f master
但是我想说的并不是这个,因为这是两个完全没有关联的commit历史,执行pull命令的时候会报错。我们如果要pull远程仓库的代码就需要通过如下的命令了。1
git pull origin master --allow-unrelated-histories
还可以这么用
比如你修改了若干个文件,但是你想将这些文件作为两次commit,而你又恰巧执行了git add .命令,这个时候该如何使用git reset命令呢?1
2
3
4
5
6
7$ vim a.txt
$ vim b.txt
$ git add .
$ git reset HEAD b.txt
$ git commit -m "修改a.txt文件"
$ git add .
$ git commit -m "修改b.txt文件"
git reset命令添加–hard参数之后确实是一个很危险的命令,但是如果你只是使用git reset命令是并不危险的,因为它修改的仅仅是暂存区的内容,而不会修改到你工作目录的文件。
余生没那么长,不要一味的付出去惯那些得寸进尺的人,请忠于自己,活得像最初的模样!