Git 误操作救命篇,我不想去财务领工资

简介: 1.错误场景有时我们会遇到这种情况:我们从develop 分支新建一个名为feat/home 分支去做A功能,然后由于一些其他原因A 功能需要延后,然后我们再从develop分支新建一个分支去做B功能或者C功能,在多分支多功能开发时,就容易出现做B功能时,忘记切换分支,一直等做完了提交了push之后才发现 push 错了远端的分支,并且 push 的改动与该分支需要开发的功能并没有交集,因此我们需要将已经提交错的分支内容回滚并提交push 到正确的远端分支。


1.错误场景


有时我们会遇到这种情况:我们从develop 分支新建一个名为feat/home 分支去做A功能,然后由于一些其他原因A 功能需要延后,然后我们再从develop分支新建一个分支去做B功能或者C功能,在多分支多功能开发时,就容易出现做B功能时,忘记切换分支,一直等做完了提交了push之后才发现 push 错了远端的分支,并且 push 的改动与该分支需要开发的功能并没有交集,因此我们需要将已经提交错的分支内容回滚并提交push 到正确的远端分支。


2.已经commit,但是未push到远端


使用 git reset 命令,可以在提交层面在私有分支舍弃一些没有提交的更改:


# 回退到上一个版本 
git reset --hard HEAD^ 
# 向前回退两个版本
git reset --hard HEAD~2


git reset 命令主要有三个选项: --soft、--mixed 、--hard,默认参数为 --mixed。


git reset --soft 软重置,只撤销了git commit操作,保留了 git add 操作

git reset --hard 具有破坏性,是很危险的操作,它很容易导致数据丢失,如果我们真的进行了该操作想要找回丢失的数据,那么此时可以使用git reflog 穿梭到未来,找到丢失的commit

git reset --mixed 会保留提交的源码改动,只是将索引信息回退到了某一个版本,如果还需要继续提交,再次执行 git add 和 git commit

第一种方法:


适用于多个分支一起开发的时候将A分支的改动错误的提交到B的场景:


# 将该分支的本不应该提交的commit撤销
git reset HEAD^
# 按需选择想要回到哪个版本
# 回到HEAD
git reset --soft HEAD
# 回到HEAD的前一个版本
git reset --soft HEAD^
# 回到HEAD的前10个版本
git reset --soft HEAD~5 
# 利用id回到指定版本
git reset --soft a06ef2f
# 将撤销的代码暂存起来
git stash
# 切换到正确的分支
git checkout feat/xxx
# 重新应用缓存
git stash pop
# 在正确的分支进行提交操作
git add . && git commit -m "update xxxx"


第二种方法:


适用于在不小心在 master 分支上提交了代码,而实际想要在 feature 分支上提交代码的场景:
# 新建出一个新分支,但是仍在master 分支上,并不会切换到新分支
git branch feat/update
# 恢复master本身提交的状态
git reset --hard origin/master
# 提交错的代码已经在新检出的分支上面了,可以继续进行开发或者push
git checkout feat/update


第三种方法:


适用于想要对特定的某一个或几个commit 进行“嫁接”,使其复制一份到正确的 feature 分支的场景;

在功能性迭代开发中发现一个bug,并提交了一个 commit 进行修复,但是发现该bug也存在线上的发布版本上,必须要尽快对线上进行修复,此时可以使用git cherry-pick 将bug修复的commit 嫁接到 fix 分支上进行代码修复,并及时发布,解决线上bug。


# 先切换到正确的分支
git checkout feat/update
# 取出提交错误的或bug fix的 commit 引入到feat/update 分支中
git cherry-pick a06ef2f
# 回到错误的分支
git checkout feat/feedback
# 将 a06ef2f 的改动从当前分支销毁
git reset --head a06ef2f


如果你只想把改动转移到目标分支,但是并不想提交,可以这样做:


# --no-commit 参数会使嫁接过来的改动不会提交,只会放在暂存区
git cherry-pick b9dabf9 --no-commit


第四种方法:


适用于当多个文件被缓存时,发现其中一个文件是其他分支的功能性改动,想直接取消该文件的缓存:


# 编辑了 1.js 2.js 3.js
# 缓存所有改动的文件
git add .
# 发现 3.js 不应该出现在此时提交的功能上,要取消它的缓存
git reset 3.js
# 此时3.js 被取消了缓存,我们继续提交1.js 2.js
git commit -m "Update 1.js 2.js"
# 将3.js 暂存起来
git stash
# 切换到提交 3.js 改动的分支
git checkout feat/update
# 重新应用缓存起来的 stash(3.js)
# pop 参数会将缓存栈的第一个stash删除,并将对应修改应用到当前分支目录下
git stash pop
# 继续提交
git add && git commit -m "update 3.js"


3.Commit之后已经 push 到了远端


此时我们需要借助 git revert 命令来撤销我们的操作。

解决方式:


# 撤销最近的一次提交
git revert HEAD --no-edit


接着我们使用 sourceTree 查看撤销之后的提交历史:



我们看到想要撤销的 SHA1 为 db6bb3 的 commit(Update 2.js)记录还在,并且多了一个SHA1 为 6e1d7ee 新的 commit(Revert “Update 2.js”)。因此可以看出,git revert 是对给定的 commit 提交进行逆过程,该命令会引入一个新的提交来抵消给定提交的影响。 和 git cherry-pick 一样,revert命令不修改版本库的现存历史记录,相反它只会在记录添加新的提交。


接下来我们已经解决了错误分支的提交,但是还要把这次提交放到正确的分支上,依然可以使用 git cherry pick 去操作:


# 将revert commit push到远端
git push origin feat/feedback
# 切换到正确的分支
git checkout feat/update
将目标commit 嫁接到当前分支
git cherry pick db6bb3f


git revert 后面可以加不同的参数达到不同的撤销效果,常用的如下:


--edit :该参数为git revert 的默认参数,它会自动创建提交日志提醒,此时会弹出编辑器会话,可以在里面修改提交消息,然后再提交。

--no-edit :表示不编辑 commit 信息,revert 的 commit 会直接自动变回 ‘Revert + 想要撤销的commit 的message’ 的格式。上面例子中使用的就是这种方式。

--no-commit:该命令会使撤销的 commit 里面的改动放到暂存区,不进行提交,用户可以自行再次提交。这种参数并且适用于将多个 commit 结果还原到索引中,集体放置在缓冲区,进行用户自定义的操作。


4.改动不仅已经 push 到远端,并且已经合到主仓库


当我们把本不属于该分支的代码或者不需要提交的改动提交到主仓库,并合并到了develop 仓库之后,这是想要撤销合到主仓库的改动,解决方式如下:


1. 当以pull request 的方式进行的合并:


Github中支持pull request撤销操作,在对应的pull request页面点击 Revert 按钮救命即可😊


2. 当用命令行执行合并时:


上面展示了通过界面按钮去操作如何撤销已经合并develop 分支的改动,那么在个人项目中用命令行操作是怎么样的呢?


# 添加三个文件
echo 1 > 1.html
echo 2 > 2.html
echo 3 > 3.html
# 以为提交的是1.html 2.html,将改动推到了远端分支
git add . && git commit -m "Add 1.html 2.html"
git push origin feat/update
# 将feat/update的改动创建一个“合并提交”合入develop 分支,生成的 Merge commit 的SHA1 为 f439c6f
git checkout develop
git merge feat/update --no-ff
# 如果存在冲突,先解决冲突,然后继续请求合并
git add . && git merge --continue
# 将develop 合并的最后结果提交到远端
git push origin develop
# 合并之后发现不应该将3.html 不应该放入功能迭代中。需要撤销本次合并
# 做任何操作前,先保证本地的develop 代码是最新状态
git pull --rebase origin develop
# 从develop分支新建一个 revert 分支
git checkout -b revert-feat/update
# 用 -m 参数指定父编号(从1开始),因为它是“合并提交”
git revert -m 1 f439c6f
# push revert 的改动
git push origin revert-feat/update
# 切换回 develop 分支,将 revert-feat/update 分支进行合并
git checkout develop
git merge revert-feat/update --no-ff
git push origin develop


5.revert 错误,需要再次补救


当我们的代码合到主仓库,并且成功发布到生产环境,此时发现线上有集中报错,必须马上将线上代码回滚到最新版本。这是我们需要进行revert 操作。revert 的代码发布到生产之后,发现错误仍旧存在,最后排查到是某个外部服务依赖出现问题,本次revert 的改动无关,并且外部服务已经恢复。此时需要将 revert 的改动再次发布上生产环境。


我们可以再用一次git revert,revert 掉我们之前的 revert commit:


git revert HEAD --no-edit


这样 revert 撤销的改动又回来了,此时会发现提交历史上又会出现一个新的revert commit。


目录
相关文章
|
2月前
|
安全 Linux iOS开发
技术文档 | 使用 OpenSCA 批量扫描 Gitlab 仓库,盘点资产安心过节
按照下述教程快速批量扫描您的仓库,一旦新的攻击或0Day出现,通过资产清单即可快速定位漏洞及影响范围、有效缩短响应时间。
38 1
|
6月前
|
存储 运维 监控
语雀故障与反思,随便再领半年会员!
语雀故障与反思,随便再领半年会员!
330 0
|
7月前
|
安全 数据安全/隐私保护
某地HVV靠运气拿下权限全过程
某地HVV靠运气拿下权限全过程
80 0
|
8月前
|
人工智能 开发工具 git
Git撤销之世上真有后悔药
Git撤销之世上真有后悔药
|
Shell 网络安全 开发工具
保姆级服务,一键 Git Worktree,这样满意吗?
保姆级服务,一键 Git Worktree,这样满意吗?
保姆级服务,一键 Git Worktree,这样满意吗?
|
云安全 安全 数据安全/隐私保护
算了一笔帐,供房子需要挣多少钱——在贷款的情况下,每个月最低工资。
房价给日常生活带来的压力 以沈阳为例,假设房价4000元/平,买一个70平米的房子,共需要28万元,首付需要84000元,剩余196000元,用贷款来解决。   按照等额还款方式计算: a 贷款15年,年利率:7.
1119 0
辞职后的后续事情——档案移交、失业金等。
     辞职了,以前工作的时候多没有签过合同,辞职之后也就没有什么事情了,不过这次签了合同,交了一年半的保险,辞职之后呢也就有了不少的事情。      基本办完了之后才滤出来了基本步骤,一开始公司的财务和我说的时候我是迷迷糊糊的,只能走一步算一步,历尽“波折”之后终于走完了一大半。
1111 0
|
项目管理
艾伟也谈项目管理,项目经理成长日记(6)——对不上的帐
中午吃过了午饭,端着杯茶做在休息室里正稍稍休憩。公司内部特别开辟出一个空间,并装修成吧台,高脚转椅,微高的台面和酒吧里面的样子多少有点类似。不少人见过微软、google的office的专修格调,让多少人羡慕而又渴望。
1026 0