可能说的不是很明白,就是我代码写着写着,发现我已经不想这么弄了,用git reset --hard <版本号>
退回到之前的某个版本重新写,这样当我当我写完之后,想在提交到远程仓库,它就会报错
To https://github.com/zifenggao/wenda.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/zifenggao/wenda.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
说我版本是之前的版本,要我合并后再提交,那我应该怎么弄,能了几遍都没搞懂。
首先,根据你的描述,既然你用到了
git reset --hard
,那就可以推断出你已经add
和commit
过了。其次,根据报错,可以推断出你已经
push
过了(这个推断基于只有你一个人拥有 master branch 的更改权限。那么当你执行
git reset --hard
之后,历史纪录是不能跟远程的记录直接合并的。因此才会有这个报错。举个例子,远程是
A -> B -> C -> D
,你git reset --hard
之后是A -> B
。这时候除非远程那边抹掉C
和D
,否则是不能合并的。因此,这时候,你应该使用
git push origin master --force
来强行覆盖远程记录。请不要根据提示使用
git pull
。否则,你的本地又会变成A -> B -> C -> D
。因为git pull
相当于git fetch
+git merge
(以下内容基于上面的例子,远程是
A -> B -> C -> D
,你想回滚到 B 那个状态)楼上提到了
git revert
。其实,git reset --hard
和git revert
都可以实现“回滚代码”。但区别在于:git revert
会把你的本地变成A -> B -> C -> D -> E
。其中,E
干的事儿是删除C
和D
。这样做的好处在于,你git push origin master
就不会有上面的报错了。但,历史线上还是会保留C
和D
这两个 commit。如果使用这个命令,记得要add
然后commit
。git reset --hard
会直接删掉C
和D
,形成A -> B
这样的结果。好处在于更直接更彻底。缺点在于,首先要通过git push origin master --force
去强行更改。其次,一旦你后悔了,除非根据本地的reflog
直接恢复 HEAD 指针,此外没有其他办法。用哪个都是没错的,请根据自己的需要来选择。