Git Rebase教程: 用Git Rebase让时光倒流
创始人
2024-03-01 14:03:39
0

想象一下你正在开发一个激进的新功能。这将是很灿烂的但它需要一段时间。您这几天也许是几个星期一直在做这个。

你的功能分支已经超前master有6个提交了。你是一个优秀的开发人员并做了有意义的语义提交。但有一件事情:你开始慢慢意识到,这个疯狂的东西仍需要更多的时间才能真的做好准备被合并回主分支。

m1-m2-m3-m4 (master)
     \ 
      f1-f2-f3-f4-f5-f6(feature)

你也知道的是,一些地方实际上是交叉不大的新功能。它们可以更早地合并到主分支。不幸的是,你想将部分合并到主分支的内容存在于你六个提交中的某个地方。更糟糕的是,它也包含了依赖于你的功能分支的之前的提交。有人可能会说,你应该在第一处地方做两次提交,但没有人是完美的。

m1-m2-m3-m4 (master)
     \ 
      f1-f2-f3-f4-f5-f6(feature)
             ^
             |
        mixed commit

在你准备提交的时间,你没有预见到,你可能要逐步把该功能合并入主分支。哎呀!你不会想到这件事会有这么久。

你需要的是一种方法可以回溯历史,把它并分成两次提交,这样就可以把代码都安全地分离出来,并可以移植到master分支。

用图说话,就是我们需要这样。

m1-m2-m3-m4 (master)
     \ 
      f1-f2-f3a-f3b-f4-f5-f6(feature)

在将工作分成两个提交后,我们就可以cherry-pick出前面的部分到主分支了。

原来Git自带了一个功能强大的命令git rebase -i ,它可以让我们这样做。它可以让我们改变历史。改变历史可能会产生问题,作为一个经验,应尽快避免历史与他人共享。不过在我们的例子中,我们只是改变我们的本地功能分支的历史。没有人会受到伤害。就这么做了!

好吧,让我们来仔细看看f3提交究竟修改了什么。原来我们共修改了两个文件:userService.js和wishlistService.js。比方说,userService.js的更改可以直接合入主分支而wishlistService.js不能。因为wishlistService.js甚至不存在在主分支里面。它是f1提交中引入的。

专家提示:即使是在一个文件中更改,git也可以搞定。但这篇博客中我们先简化情况。

我们已经建立了一个公众演示仓库,我们将使用这个来练习。为了便于跟踪,每一个提交信息的前缀是在上面的图表中使用的假的SHA。以下是git在分开提交f3时的分支图。

现在,我们要做的第一件事就是使用git的checkout功能checkout出我们的功能分支。用git rebase -i master开始做rebase。

现在接下来git会用所配置的编辑器打开(默认为Vim)一个临时文件。

该文件为您提供一些rebase选择,它带有一个提示(蓝色文字)。对于每一个提交,我们可以选择的动作有pick、rwork、edit、squash、fixup和exec。每一个动作也可以通过它的缩写形式p、r、e、s、f和e引用。描述每一个选项超出了本文范畴,所以让我们专注于我们的具体任务。

我们要为f3提交选择edit选项,因此我们把内容改变成这样。

现在我们保存文件(在Vim中是按下后输入:wq,最后是按下回车)。接下来我们注意到git在编辑选项中选择的提交处停止了rebase。

这意味这git开始将f1、f2、f3生效仿佛它就是常规的rebase,但是在f3生效之后停止。事实上,我们可以看一眼停止的地方的日志就可以证明这一点。

要将f3分成两个提交,我们所要做的是重置git的指针到先前的提交(f2)而保持工作目录和现在一样。这就是git reset在混合模式在做的。由于混合模式是git reset的默认模式,我们可以直接用git reset head~1。就这么做并在运行后用git status看下发生了什么。

git status告诉我们userService.js和wishlistService.js被修改了。如果我们运行 git diff 我们就可以看见在f3里面确切地做了哪些更改。

如果我们看一眼日志我们会发现f3已经消失了。

现在我们有了准备提交的先前的f3提交,而原先的f3提交已经消失了。记住虽然我们仍旧在rebase的中间过程。我们的f4、f5、f6提交还没有缺失,它们会在接下来回来。

让我们创建两个新的提交:首先让我们为可以提交到主分支的userService.js创建一个提交。运行git add userService.js 接着运行 git commit -m “f3a: add updateUser method”。

太棒了!让我们为wishlistService.js的改变创建另外一个提交。运行git add wishlistService.js,接着运行git commit -m “f3b: add addItems method”.

让我们在看一眼日志。

这就是我们想要的,除了f4、f5、f6仍旧缺失。这是因为我们仍在rebase交互的中间,我们需要告诉git继续rebase。用下面的命令继续:git rebase –continue。

让我们再次检查一下日志。

就是这样。我们现在已经得到我们想要的历史了。先前的f3提交现在已经被分割成两个提交f3a和f3b。剩下的最后一件事是cherry-pick出f3a提交到主分支上。

为了完成最后一步,我们首先切换到主分支。我们用git checkout master。现在我们就可以用cherry-pick命令来拾取f3a commit了。本例中我们可以用它的SHA值bd47ee1来引用它。

现在f3a这个提交就在主分支的最上面了。这就是我们需要的!

这篇文章的长度看起来需要花费很大的功夫,但实际上对于一个git高级用户而言这只是一会会。

注:Christoph目前正在与Pascal Precht写一本关于Git rebase的书,您可以在leanpub订阅它并在准备出版时获得通知。

本文作者 Christoph Burgdorf自10岁时就是一名程序员,他是HannoverJS Meetup网站的创始人,并且一直活跃在AngularJS社区。他也是非常了解gti的内内外外,在那里他举办一个thoughtram的工作室来帮助初学者掌握该技术。

本的教程最初发表在他的blog


via: https://www.codementor.io/git-tutorial/git-rebase-split-old-commit-master

作者:cburgdorf 译者:geekpi 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

相关内容

可实现三重空间感知:Ai2...
IT之家 8 月 16 日消息,研究机构 Ai2 现已在 GitH...
2025-08-16 18:43:18
微软官宣!将开源Windo...
快科技8月5日消息,微软近日宣布,计划开源Windows 11的用...
2025-08-05 18:42:51
北京人形机器人创新中心发布...
IT之家 7 月 7 日消息,IT之家从北京人形机器人创新中心官方...
2025-07-07 22:14:23
音画同步,AI视频也能有完...
机器之心报道 编辑:泽南 AI 生成的「最后一道关卡」已经突破...
2025-06-27 22:12:41
银河通用X清华大学发布首款...
该论文由清华大学与北京银河通用机器人有限公司合作完成。论文的共同第...
2025-06-12 17:11:39
【Git】pull 分支报...
报错消息 示例图: 示例代码: ➜ ...
2025-06-01 18:31:43

热门资讯

Helix:高级 Linux ... 说到 基于终端的文本编辑器,通常 Vim、Emacs 和 Nano 受到了关注。这并不意味着没有其他...
使用 KRAWL 扫描 Kub... 用 KRAWL 脚本来识别 Kubernetes Pod 和容器中的错误。当你使用 Kubernet...
JStock:Linux 上不... 如果你在股票市场做投资,那么你可能非常清楚投资组合管理计划有多重要。管理投资组合的目标是依据你能承受...
Epic 游戏商店现在可在 S... 现在可以在 Steam Deck 上运行 Epic 游戏商店了,几乎无懈可击! 但是,它是非官方的。...
《Apex 英雄》正式可在 S... 《Apex 英雄》现已通过 Steam Deck 验证,这使其成为支持 Linux 的顶级多人游戏之...
从 Yum 更新中排除特定/某... 作为系统更新的一部分,你也许需要在基于 Red Hat 系统中由于应用依赖排除一些软件包。如果是,如...
通过 SaltStack 管理... 我在搜索Puppet的替代品时,偶然间碰到了Salt。我喜欢puppet,但是我又爱上Salt了:)...
如何在 Github 上创建一... 学习如何复刻一个仓库,进行更改,并要求维护人员审查并合并它。你知道如何使用 git 了,你有一个 G...
Opera 浏览器内置的 VP... 昨天我们报道过 Opera 浏览器内置了 VPN 服务,用户打开它可以防止他们的在线活动被窥视。不过...
如何检查你的 Linux 系统... 不知道在使用哪个初始化系统?以下是方法。每个主流 Linux 发行版(包括 Ubuntu、Fedor...