全教育培训行业第三方平台平台就业机构
扫码试听
扫码试听
Q:2638333071
首页 > 课程问答 > > git回退git回退操作取消(git checkout .回退)
行业动态 行业问答 课程问答 零基础学习 就业前景 技术干货

git回退git回退操作取消(git checkout .回退)

发布时间:3 个 月 前 栏目:课程问答 浏览:

1、git回退git回退操作取消

从接触编程就开始使用Git进行代码管理,先是自己玩Github,又在工作中使用Gitlab,虽然使用时间挺长,可是也只进行一些常用操作,如推拉代码、提交、合并等,更复杂的操作没有使用过,看过的教程也逐渐淡忘了,有些对不起Linus大神。

出来混总是要还的,前些天就遇到了Git里一种十分糟心的场景,并为之前没有深入理解Git命令付出了一下午时间的代价。

先介绍一下这种场景,我们一个项目从N版本升到A版本时引入了另一项目的jar包,又陆续发布了B、C版本,但在C版本后忽然发现了A版本引入的jar包有极大的性能问题,B、C版本都是基于A版本发布的,要修复jar包性能问题,等jar包再发版还得几天,可此时线上又有紧急的Bug要修,于是就陷入了进退两难的境地。

最后决定先将代码回退到A版本之前,再基于旧版本修复Bug,也就开始了五个小时的受苦之路。

基础试探

revert首先肯定的是revert,gitrevertcommit_id能产生一个与commit_id完全相反的提交,即commit_id里是添加,revert提交里就是删除。

但是使用gitlog查看了提交记录后,我就打消了这种想法,因为提交次数太多了,中途还有几次从其他分支的merge操作。”利益于”我们不太干净的提交记录,要完成从C版本到N版本的revert,我需要倒序执行revert操作几十次,如果其中顺序错了一次,最终结果可能就是不对的。

另外我们知道我们在进行代码merge时,也会把merge信息产生一次新的提交,而revert这次mergecommit时需要指定m参数,以指定mainline,这个mainline是主线,也是我们要保留代码的主分支,从feature分支往develop分支合并,或由develop分支合并到master的提交还好确定,但feature分支互相合并时,我哪知道哪个是主线啊。

所以revert的文案被废弃了。

Reset然后就考虑reset了,reset也能使代码回到某次提交,但跟revert不同的是,reset是将提交的HEAD指针指到某次提交,之后的提交记录会消失,就像从没有过这么一次提交。

但由于我们都在feature分支开发,我在feature分支上将代码回退到某次提交后,将其合并到develop分支时却被提示报错。这是因为feature分支回退了提交后,在git的workflow里,feature分支是落后于develop分支的,而合并向develop分支,又需要和develop分支保持最新的同步,需要将develop分支的数据合并到feature分支上,而合并后,原来被reset的代码又回来了。

这个时候另一个可选项是在master分支上执行reset,使用--hard选项完全抛弃这些旧代码,reset后再强制推到远端。

mastergitreset--hardcommit_idmastergitpush--forceoriginmaster但是还是有问题,首先,我们的master分支在gitlab里是被保护的,不能使用forcepush,毕竟风险挺大了,万一有人reset到最开始的提交再强制push的话,虽然可以使用reflog恢复,但也是一番折腾。

另外,reset毕竟太野蛮,我们还是想能保留提交历史,以后排查问题也可以参考。

升级融合

rebase只好用搜索引擎继续搜索,看到有人提出可以先使用rebase把多个提交合并成一个提交,再使用revert产生一次反提交,这种方法的思路非常清晰,把revert和rebase两个命令搭配得很好,相当于使用revert回退的升级版。

先说一下rebase,rebase是”变基”的意思,这里的”基”,在我理解是指commit形成的gitworkflow,使用rebase,我们可以改变这些历史提交,修改commit信息,将多个commit进行组合。

介绍rebase的文档有很多,我们直接来说用它来进行代码回退的步骤。

首先,切出一个新分支F,使用gitlog查询一下要回退到的commit版本N。使用命令gitrebase-iN,-i指定交互模式后,会打开gitrebase编辑界面,形如:pick6fa5869commit1pick0b84ee7commit2pick986c6c8commit3pick91a0dcccommit4这些commit自旧到新由上而下排列,我们只需要在commit_id前添加操作命令即可,在合并commit这个需求里,我们可以选择pick最旧的commit1,然后在后续的commit_id前添加squash命令,将这些commits都合并到最旧的commit1上。保存rebase结果后,再编辑commit信息,使这次rebase失效,git会将之前的这些commit都删除,并将其更改合并为一个新的commit5,如果出错了,也可以使用gitrebase--abort/--continue/--edit-todo对之前的编辑进行撤销、继续编辑。这个时候,主分支上的提交记录是older,commit1,commit2,commit3,commit4,而F分支上的提交记录是older,commit5,由于F分支的祖先节点是older,明显落后于主分支的commit4,将F分支向主分支合并是不允许的,所以我们需要执行gitmergemaster将主分支向F分支合并,合并后git会发现commit1到commit4提交的内容和F分支上commit5的修改内容是完全相同的,会自动进行合并,内容不变,但多了一个commit5。再在F分支上对commit5进行一次revert反提交,就实现了把commit1到commit4的提交全部回退。这种方法的取巧之处在于巧妙地利用了rebase操作历史提交的功能和git识别修改相同自动合并的特性,操作虽然复杂,但历史提交保留得还算完整。

rebase这种修改历史提交的功非常实用,能够很好地解决我们遇到的一个小功能提交了好多次才好使,而把git历史弄得乱七八糟的问题,只需要注意避免在多人同时开发的分支使用就行了。

遗憾的是,当天我并没有理解到rebase的这种思想,又由于试了几个方法都不行太过于慌乱,在rebase完成后,向主分支合并被拒之后对这些方式的可行性产生了怀疑,又加上有同事提出听起来更可行的方式,就中断了操作。

文件操作这种更可行的方式就是对文件操作,然后让git来识别变更,具体是:

从主分支上切出一个跟主分支完全相同的分支F。从文件管理系统复制项目文件夹为bak,在bak内使用gitcheckoutN将代码切到想要的历史提交,这时候git会将bak内的文件恢复到N状态。在从文件管理系统内,将bak文件夹下除了.git文件夹下的所有内容复制粘贴到原项目目录下。git会纯从文件级别识别到变更,然后更新工作区。在原项目目录下执行add和commit,完成反提交。这种方式的巧妙之处在于利用git本身对文件的识别,不牵涉到对workflow操作。

小结

最后终于靠着文件操作方式成功完成了代码回退,事后想来真是一把心酸泪。

为了让我的五个小时不白费,复盘一下当时的场景,学习并总结一下四种代码回退的方式:

revert适合需要回退的历史提交不多,且无合并冲突的情景。如果你可以向master强推代码,且想让gitlog里不再出现被回退代码的痕迹,可以使用gitreset--hard+gitpush--force的方式。如果你有些geek,追求用”正规而正统”的方式来回退代码,rebase+revert满足你的需求。如果你不在乎是否优雅,想用最简单,最直接的方式,文件操作正合适。git真的是非常牛逼的代码管理工具,入手简单,三五个命令组合起来就足够完成工作需求,又对geeker们非常友好,你想要的骚操作它都支持,学无止境啊。

关注我,后续更多干货奉上!

git回退git回退操作取消

2、git远程分支如何进行merge

1,需要本地仓库,并git commit

2,此时git pull会报错:fatal: refusing to merge unrelated histories.

解决办法:git pull origin master --allow-unrelated-histories

注意:master是我需要pull的分支,根据自己需求

错误的解释:

避免这种错误的方法:不要用优盘或其他的方式拷贝源代码,需要一个人创建好项目后push到github或码云,然后通过fetch 或clone的方式

下面推荐一个写的挺好的merge branch ,原文链接:

Git merge 不同的branch

Git的优势是可以创建不同的branch,然后在每个branch上开发。那么问题是:如果不同的branch之间需要做同步,比如sourceBranch上做的修改也需要同步到targetBranch,改怎么做?

1. 如果一个branch是有远程Git server管理的,另一个branch是自己本地的

git branch //假定现在所在的branch是targetBranch,并最好保证没有未提交的修改,并且已经更新到最新

git checkout -b sourceBranch //创建一个本地的sourceBranch并切换到sourceBranch

git commit //把sourceBranch上做的修改先提交

git checkout targetBranch //切换回targetBranch

git merge --no-ff sourceBranch //把sourceBranch的修改merge到targetBranch。注意:建议merge的时候总是用 --no-ff 选项

git status //保证现在workspace是干净的

git push //push到远程,如果远程有新的修改,先做一下git pull

2. 如果两个branch都是远程管理的,想把branchB的内容同步到branchA上

git branch //假定现在所在的branch是branchA,并最好保证没有未提交的修改,并且已经更新到最新

git checkout sourceBranch //确保同一个workspace能在不同的branch直接切换,即保证 .git/config里 [remote "origin"] 的内容是 fetch = +refs/heads/*:refs/remotes/origin/*

解决conflicts如果merge的结果里有显示conflicts

git commit //解决冲突后先commit到sourceBranch

git checkout targetBranch //切换到targetBranch

git merge --no-ff sourceBranch //建议merge的时候总是用 --no-ff 选项

git push origin targetBranch //把sourceBranch的修改merge到targetBranch之后,push到远程的targetBranch

git回退git回退操作取消

3、git如何将完成代码的本地分支合并到远程指定分支上

例如:远程仓库有3个分支:master,develop,develop3.0.只要求我们在develop3.0这个分支上开发。当我们在本地建立一个本地分支比如说test,我们把代码写到了这个test分支上。写完后我们想把test分支合并到远程的develop3.0分支上。我想问这个具体的过程操作是什么样的?

4、git 合并分支是什么意思

eclipsegit合并分支步骤如下:

1、开始进行分支合并操作,先切换回主干(注意此时的主干是我们创建分支时候的主干,不是现在主干进行的情况),如下图所示:

2、将分支信息合并到主干,进行merge操作,选择local-->我最后一次提交的分支,点击merge即可。

3、这个时候通常情况下是没有错误的,接下来要进行一步操作,很危险,就是将最新版本的master给pull下来;修改完冲突之后,进行提交,并推送到主干即可;4、完成提交之后,我们可以将我们的分支删除。登陆eclipse到其他地方选择一次clone,检查是否完成合并。

上一篇:没有了
技术干货
零基础学习
行业多年深耕,从这报名,学费立减800
  • 岳同学180****1241刚刚成功领取
  • 胡同学134****6431刚刚成功领取
  • 李同学150****6122刚刚成功领取
  • 张同学136****2231刚刚成功领取
  • 孙同学178****5521刚刚成功领取
  • 齐同学156****7788刚刚成功领取
猜你喜欢
查看更多
相关推荐
查看更多
现在学习,我的薪资能达到多少?
立即报名

联系我们:

Q:2638333071

鄂ICP备2023015464号