1. 首页 > 智能数码 >

git回退作取消,从接触编程就开始了

git回退git回退作取消

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

git回退作取消,从接触编程就开始了git回退作取消,从接触编程就开始了


出来混总是要还的,前些天就遇到了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回退到指定版本

cd 到git项目目录下

方法1:使用git log命令查看所有的历史版本,

git log

回车就可以查看历史记录

--->假设查到历史版本的id是 124bb0f757e661ef12cdbe99a805c156297d1f11

git reset --hard 124bb0f757e661ef12cdbe99a805c156297d1f11

在cicd中,怎么实现项目和版本的归纳以及回退

在cicd中,实现项目和版本的归纳以及回退的方法有:

1、使用版本控制工具(例如Git)进行代码管理,将项目打上标签以示区分版本。

2、使用容器技术(例如Docker)对应用进行打包,使用Docker镜像的版本进行部署和回退。

3、在CI/CD流程中引入版本号的概念,例如通过在构建时加入时间戳或者自增序列等,以区分不同版本。

4、实现版本回退需要提前将历史版本备份,当需要回退时,可以直接将备份版本还原。

git 如何让远程分支版本回退

小喵收到需求要做产品A,之后提交commit A1, A2, A3并且同时同步到了远程分支origin master。生活总是辣眼睛的,开发到一定程度后因为一定的原因撤销需求A,要回退到版本到A,本地rest即可,但是如何把远程版本回退呢?

小喵在网络一顿搜索和尝试,请教同事之后有了这个解决方案

把Master(你要回退的分支) 放到Protect a branch 里面,选择可以作的角色。

再次执行 $git push origin master --force

完成回退了,小喵开开心!!!

Git 版本回退命令

简单的来说,git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。

git reset命令 又可以分为 git reset --hard xxx 和 git reset --soft xxx 以及 git reset --mixed xxx 。

为了更好的说明,我们来看一些测试的例子:

原本 abc.md 中的内容是:iiiiiiiiii

git revert 的作用是通过创建一个新的版本,这个版本的内容与我们要回退到的目标版本一样,但是HEAD指针是指向这个新生成的版本,而不是目标版本。

如果我们想恢复之前的某一版本(该版本不是merge类型),但是又想保留该目标版本后面的版本,记录下这整个版本变动流程,就可以用这种方法。

我们使用 git revert HEAD 命令就可以创建一个新的版本,此版本与上一个版本相同。

Git Reset命令

廖雪峰Git教程

【学了就忘】Git后悔 — 33.版本回退作(二)

git reset --mixed commit-id 命令:回退到指定版本。(soft:混合的,即:中等回退。)

该命令不仅修改了分支中HEAD指针的位置,还将暂存区中数据也回退到了指定版本。

但是工作区中的版本仍是回退前的版本。

--mixed 参数是 git reset 命令的默认选项。

示例开始:

首先在版本库中的 readme.txt 文件中添加一行内容,并提交该内容。我们的目的就是要再回退到该版本。

1)查看本地版本库日志

2)向 readme.txt 文件中新增一行数据,并提交到本地版本库

3)现在比对工作区与暂存区、暂存区与本地版本库的异

我们可以看到此时,工作区、暂存区与本地版本库中的 readme.txt 文件状态无异。

4)开始回退作,退回到V3版本

使用 git reset --mixed HEAD^ 命令,退回到前一个版本。

说明:

5)回退后,对比工作区、暂存区与本地库中版本中文件的异

回退后,我们再次对比了工作区、暂存区与本地库中版本中文件的异:

说明:工作区中的内容没有回退,但是暂存区和本地库中的内容回退到了之前的版本。(重要)

6)查看本地版本库的提交日志信息

从上我们可以看到:(重点)

7)恢复到回退前版本

上面说了,使用 git reset --mixed 命令回退,做了两个作

而工作区内容不回退。

我们现在来查看一下工作目录中的文件状态。

我们可以看到 readme.txt 文件是修改未暂存状态。

所以若要恢复到回退之前的版本,也是两种方式:

种常规作,这里就不演示了。下面演示一下第二种方式:

我们查看到, readme.txt 文件的内容已经完全恢复。

63.Git Reset 详解版本回滚的三种模式

意思就是可以让HEAD这个指针指向其他版本。说白了就是通过此命令在版本之间进行穿梭。

它有三种模式,soft,mixed,hard,具体的使用方法下面这张图,展示的很全面了。

这三个模式理解了,对于使用这个命令很有帮助。在理解这三个模式之前,需要略微知道一点Git的基本流程。正如上图,Git会有三个区域:

Working Tree 当前的工作区域

Index/Stage 暂存区域,和git stash命令暂存的地方不一样。使用git add xx,就可以将xx添加近Stage里面

Repository 提交的历史,即使用git commit提交后的结果

首先, Git 必须知道当前版本是哪个版本,在 Git 中,用 HEAD 表示当前版本,上一个版本就是 HEAD^ ,上上一个版本就是 HEAD^^ ,以此类推,当然往上100个版本写100个 ^ 比较容易数不过来,所以写成 HEAD~100 。

--hard 会在重置 HEAD 和branch的同时,重置缓存区和工作目录里的内容。当你在 reset 后面加了 --hard 参数时,你的缓存区和工作目录里的内容会被完全重置为和HEAD的新位置相同的内容。换句话说,就是你的没有commit的修改会被全部擦掉。

回退到上一版本:

回退到指定版本号(以1a2b3c为例)的版本:

reset --hard:重置stage区和工作目录:

--soft 则会保留工作目录的内容,并把因为重置 HEAD 所带来的新的文件异放进暂存区。

什么是「重置 HEAD 所带来的新的异」?就是这里:

由于 HEAD 从 4 移动到了 3,而且在 reset 的过程中工作目录和暂存区的内容没有被清理掉,所以 4 中的改动在 reset 后就也成了工作目录新增的「工作目录和 HEAD 的异」。这就是上面一段中所说的「重置 HEAD 所带来的异」。

这就是--soft 和 --hard 的区别:--hard 会清空工作目录和暂存区的改动,而 --soft则会保留工作目录的内容,并把因为保留工作目录内容所带来的新的文件异放进暂存区。

git reset 如果不加参数,那么默认使用 --mixed 参数。此时表示要:保留工作目录,并清空暂存区。也就是说,工作目录的修改、暂存区的内容以及由 reset 所导致的新的文件异,都会被放进工作目录。简而言之,就是「把所有异都混合(mixed)放在工作目录中」。

首先, Git 必须知道当前版本是哪个版本,在 Git 中,用 HEAD 表示当前版本,上一个版本就是 HEAD^ ,上上一个版本就是 HEAD^^ ,以此类推,当然往上100个版本写100个 ^ 比较容易数不过来,所以写成 HEAD~100 。

回退到上一版本:

回退到指定版本号(以1a2b3c为例)的版本:

--hard 会清空工作目录和暂存区的改动,

--soft则会保留工作目录的内容,并把因为保留工作目录内容所带来的新的文件异放进暂存区。

--mixed 参数。git reset 如果不加参数,那么默认使用 --mixed 参数。此时表示要:保留工作目录,并清空暂存区。

HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令

git reset --hard commit_id

穿梭前,用 git log 可以查看提交历史,以便确定要回退到哪个版本。

要重返未来,用 git reflog 查看命令历史,以便确定要回到未来的哪个版本。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至836084111@qq.com 举报,一经查实,本站将立刻删除。

联系我们

工作日:9:30-18:30,节假日休息