rebase小结 - git rebase详解




你什么时候使用git rebase而不是git merge? (10)

TL; DR

如果您有任何疑问,请使用合并。

简答

rebase和merge之间的唯一区别是:

  • 历史的结果树结构(通常只有在查看提交图时才会显着)是不同的(一个会有分支,另一个则不会)。
  • 合并通常会创建额外的提交(例如树中的节点)。
  • 合并和重组将会以不同的方式处理冲突。 在一次合并将一次呈现它们的时候,Rebase将呈现一个冲突。

所以简短的答案是根据你希望你的历史看起来像什么选择rebase或合并

长答案

选择使用哪种操作时,应考虑几个因素。

您是否从与团队以外的其他开发人员共享的分支(例如开源,公共)获得更改?

如果是这样,不要重新分配。 Rebase销毁分支,除非使用git pull --rebase否则这些开发者将破坏/不一致的存储库。 这是快速打乱其他开发人员的好方法。

你的开发团队有多熟练?

Rebase是一个破坏性的操作。 这意味着,如果您没有正确应用, 您可能会失去承诺的工作和/或打破其他开发人员存储库的一致性。

我曾在一些团队工作过,那时候开发人员都来自公司负责分支和合并的专职人员。 那些开发人员不太了解Git,也不想知道很多。 在这些团队中,我不会冒任何理由冒险推荐重组。

分支本身是否代表有用的信息

一些团队使用每个分支代表一个功能(或bug修复,或子功能等)的分支功能模型。在该模型中,分支有助于识别相关提交的集合。 例如,可以通过恢复该分支的合并(公平地说,这是罕见的操作)来快速恢复特征。 或者通过比较两个分支来比较特征(更常见)。 Rebase会破坏分支,这不是直接的。

我也参与过使用每个开发人员模式的团队(我们都在那里)。 在这种情况下,分支本身不会传达任何附加信息(提交已经有作者)。 重新分配不会造成任何伤害。

出于任何原因你想要恢复合并?

与恢复合并相比,恢复(如撤消)重建是相当困难和/或不可能的(如果重新分配有冲突)。 如果你认为有机会你会想要恢复然后使用合并。

你在一个团队工作吗? 如果是这样,你是否愿意在这个分支上采取全或无的方法?

需要使用相应的git pull --rebase来拉取Rebase操作。 如果你一个人工作,你可能会记得在适当的时候应该使用哪一个。 如果你在一个团队工作,这将很难协调。 这就是为什么大多数rebase工作流程推荐使用rebase来进行所有合并(以及git pull --rebase )。

常见的神话

合并破坏历史(压扁承诺)

假设您有以下合并:

    B -- C
   /      \
  A--------D

有些人会说合并“破坏”了提交历史,因为如果你只查看主分支(A - D)的日志,你会错过B和C中包含的重要提交信息。

如果这是真的,我们不会有这样的问题 。 基本上,你会看到B和C,除非你明确要求不要看到它们(使用--first-parent)。 这对你自己来说很容易。

Rebase允许更安全/更简单的合并

这两种方法合并的方式不同,但不清楚哪个总是比另一个好,可能取决于开发人员的工作流程。 例如,如果开发人员倾向于定期提交(例如,他们在工作过渡到家庭时可能每天执行两次),那么对于给定的分支可能会有很多提交。 许多这些提交可能看起来不像最终产品(我倾向于重构我的方法一次或两次每个功能)。 如果其他人正在研究相关的代码区域,并且他们试图重新设定我的更改,那么这可能是一项非常乏味的操作。

Rebase更酷/更性感/更专业

如果你rm rm -rf别名为rm -rf来“节省时间”,那么rebase可能适合你。

我的两分钱

我总是认为有一天我会遇到一种情况,git rebase是解决问题的绝佳工具。 就像我想我会遇到一个场景,其中git reflog是一个很好的工具,可以解决我的问题。 我已经使用git超过五年了。 它没有发生。

凌乱的历史对我来说从来都不是一个问题。 我从来没有像读过一本令人兴奋的小说一样阅读我的提交历史。 大多数情况下,我需要一个历史记录,我将使用git blame或git bisect。 在这种情况下,合并提交对我来说实际上是有用的,因为如果合并向我引入了有意义的信息问题。

更新(4/2017)

我觉得有义务提及,尽管我的一般建议仍然存在,但我个人对使用rebase进行了软化。 我最近与Angular 2 Material项目进行了很多互动。 他们使用rebase来保持一个非常干净的提交历史记录。 这让我很容易看到什么提交修复了一个给定的缺陷,以及该提交是否包含在发布中。 它是正确使用rebase的一个很好的例子。

什么时候推荐使用git rebasegit merge

成功转型后,我还需要合并吗?


简洁版本

  • 合并将一个分支中的所有更改合并到一个提交中的另一个分支中。
  • 雷根说,我希望我分支的位置移到新的起点

那么你什么时候使用任何一个?

合并

  • 假设您为开发单个功能创建了一个分支。 当你想把这些变化带回主人时,你可能想合并 (你不关心维护所有的临时提交)。

变基

  • 第二种情况是,如果您开始进行一些开发,然后另一位开发人员做出了无关的更改。 您可能想要拉动并重新绑定,以根据回购的当前版本进行更改。

Some practical examples, somewhat connected to large scale development where gerrit is used for review and delivery integration.

I merge when i uplift my feature branch to a fresh remote master. This gives minimal uplift work and it's easy to follow the history of the feature development in for example gitk.

git fetch
git checkout origin/my_feature
git merge origin/master
git commit
git push origin HEAD:refs/for/my_feature

I merge when I prepare a delivery commit.

git fetch
git checkout origin/master
git merge --squash origin/my_feature
git commit
git push origin HEAD:refs/for/master

I rebase when my delivery commit fails integration for whatever reason and I need to update it towards a fresh remote master.

git fetch
git fetch <gerrit link>
git checkout FETCH_HEAD
git rebase origin/master
git push origin HEAD:refs/for/master

This answer is widely oriented around Git Flow . The tables have been generated with the nice ASCII Table Generator , and the history trees with this wonderful command ( aliased as git lg ):

git log --graph --abbrev-commit --decorate --date=format:'%Y-%m-%d %H:%M:%S' --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%ad%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n''          %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'

Tables are in reverse chronological order to be more consistent with the history trees. See also the difference between git merge and git merge --no-ff first (you usually want to use git merge --no-ff as it makes your history look closer to the reality):

git merge

Commands:

Time          Branch "develop"             Branch "features/foo"
------- ------------------------------ -------------------------------
15:04   git merge features/foo
15:03                                  git commit -m "Third commit"
15:02                                  git commit -m "Second commit"
15:01   git checkout -b features/foo
15:00   git commit -m "First commit"

结果:

* 142a74a - YYYY-MM-DD 15:03:00 (XX minutes ago) (HEAD -> develop, features/foo)
|           Third commit - Christophe
* 00d848c - YYYY-MM-DD 15:02:00 (XX minutes ago)
|           Second commit - Christophe
* 298e9c5 - YYYY-MM-DD 15:00:00 (XX minutes ago)
            First commit - Christophe

git merge --no-ff

Commands:

Time           Branch "develop"              Branch "features/foo"
------- -------------------------------- -------------------------------
15:04   git merge --no-ff features/foo
15:03                                    git commit -m "Third commit"
15:02                                    git commit -m "Second commit"
15:01   git checkout -b features/foo
15:00   git commit -m "First commit"

结果:

*   1140d8c - YYYY-MM-DD 15:04:00 (XX minutes ago) (HEAD -> develop)
|\            Merge branch 'features/foo' - Christophe
| * 69f4a7a - YYYY-MM-DD 15:03:00 (XX minutes ago) (features/foo)
| |           Third commit - Christophe
| * 2973183 - YYYY-MM-DD 15:02:00 (XX minutes ago)
|/            Second commit - Christophe
* c173472 - YYYY-MM-DD 15:00:00 (XX minutes ago)
            First commit - Christophe

git merge vs git rebase

First point: always merge features into develop, never rebase develop from features . This is a consequence of the Golden Rule of Rebasing :

The golden rule of git rebase is to never use it on public branches.

In other words :

Never rebase anything you've pushed somewhere.

I would personally add: unless it's a feature branch AND you and your team are aware of the consequences .

So the question of git merge vs git rebase applies almost only to the feature branches (in the following examples, --no-ff has always been used when merging). Note that since I'm not sure there's one better solution ( a debate exists ), I'll only provide how both commands behave. In my case, I prefer using git rebase as it produces a nicer history tree :)

Between feature branches

git merge

Commands:

Time           Branch "develop"              Branch "features/foo"           Branch "features/bar"
------- -------------------------------- ------------------------------- --------------------------------
15:10   git merge --no-ff features/bar
15:09   git merge --no-ff features/foo
15:08                                                                    git commit -m "Sixth commit"
15:07                                                                    git merge --no-ff features/foo
15:06                                                                    git commit -m "Fifth commit"
15:05                                                                    git commit -m "Fourth commit"
15:04                                    git commit -m "Third commit"
15:03                                    git commit -m "Second commit"
15:02   git checkout -b features/bar
15:01   git checkout -b features/foo
15:00   git commit -m "First commit"

结果:

*   c0a3b89 - YYYY-MM-DD 15:10:00 (XX minutes ago) (HEAD -> develop)
|\            Merge branch 'features/bar' - Christophe
| * 37e933e - YYYY-MM-DD 15:08:00 (XX minutes ago) (features/bar)
| |           Sixth commit - Christophe
| *   eb5e657 - YYYY-MM-DD 15:07:00 (XX minutes ago)
| |\            Merge branch 'features/foo' into features/bar - Christophe
| * | 2e4086f - YYYY-MM-DD 15:06:00 (XX minutes ago)
| | |           Fifth commit - Christophe
| * | 31e3a60 - YYYY-MM-DD 15:05:00 (XX minutes ago)
| | |           Fourth commit - Christophe
* | |   98b439f - YYYY-MM-DD 15:09:00 (XX minutes ago)
|\ \ \            Merge branch 'features/foo' - Christophe
| |/ /
|/| /
| |/
| * 6579c9c - YYYY-MM-DD 15:04:00 (XX minutes ago) (features/foo)
| |           Third commit - Christophe
| * 3f41d96 - YYYY-MM-DD 15:03:00 (XX minutes ago)
|/            Second commit - Christophe
* 14edc68 - YYYY-MM-DD 15:00:00 (XX minutes ago)
            First commit - Christophe

git rebase

Commands:

Time           Branch "develop"              Branch "features/foo"           Branch "features/bar"
------- -------------------------------- ------------------------------- -------------------------------
15:10   git merge --no-ff features/bar
15:09   git merge --no-ff features/foo
15:08                                                                    git commit -m "Sixth commit"
15:07                                                                    git rebase features/foo
15:06                                                                    git commit -m "Fifth commit"
15:05                                                                    git commit -m "Fourth commit"
15:04                                    git commit -m "Third commit"
15:03                                    git commit -m "Second commit"
15:02   git checkout -b features/bar
15:01   git checkout -b features/foo
15:00   git commit -m "First commit"

结果:

*   7a99663 - YYYY-MM-DD 15:10:00 (XX minutes ago) (HEAD -> develop)
|\            Merge branch 'features/bar' - Christophe
| * 708347a - YYYY-MM-DD 15:08:00 (XX minutes ago) (features/bar)
| |           Sixth commit - Christophe
| * 949ae73 - YYYY-MM-DD 15:06:00 (XX minutes ago)
| |           Fifth commit - Christophe
| * 108b4c7 - YYYY-MM-DD 15:05:00 (XX minutes ago)
| |           Fourth commit - Christophe
* |   189de99 - YYYY-MM-DD 15:09:00 (XX minutes ago)
|\ \            Merge branch 'features/foo' - Christophe
| |/
| * 26835a0 - YYYY-MM-DD 15:04:00 (XX minutes ago) (features/foo)
| |           Third commit - Christophe
| * a61dd08 - YYYY-MM-DD 15:03:00 (XX minutes ago)
|/            Second commit - Christophe
* ae6f5fc - YYYY-MM-DD 15:00:00 (XX minutes ago)
            First commit - Christophe

From develop to a feature branch

git merge

Commands:

Time           Branch “develop"              Branch "features/foo"           Branch "features/bar"
------- -------------------------------- ------------------------------- -------------------------------
15:10   git merge --no-ff features/bar
15:09                                                                    git commit -m “Sixth commit"
15:08                                                                    git merge --no-ff development
15:07   git merge --no-ff features/foo
15:06                                                                    git commit -m “Fifth commit"
15:05                                                                    git commit -m “Fourth commit"
15:04                                    git commit -m “Third commit"
15:03                                    git commit -m “Second commit"
15:02   git checkout -b features/bar
15:01   git checkout -b features/foo
15:00   git commit -m “First commit"

结果:

*   9e6311a - YYYY-MM-DD 15:10:00 (XX minutes ago) (HEAD -> develop)
|\            Merge branch 'features/bar' - Christophe
| * 3ce9128 - YYYY-MM-DD 15:09:00 (XX minutes ago) (features/bar)
| |           Sixth commit - Christophe
| *   d0cd244 - YYYY-MM-DD 15:08:00 (XX minutes ago)
| |\            Merge branch 'develop' into features/bar - Christophe
| |/
|/|
* |   5bd5f70 - YYYY-MM-DD 15:07:00 (XX minutes ago)
|\ \            Merge branch 'features/foo' - Christophe
| * | 4ef3853 - YYYY-MM-DD 15:04:00 (XX minutes ago) (features/foo)
| | |           Third commit - Christophe
| * | 3227253 - YYYY-MM-DD 15:03:00 (XX minutes ago)
|/ /            Second commit - Christophe
| * b5543a2 - YYYY-MM-DD 15:06:00 (XX minutes ago)
| |           Fifth commit - Christophe
| * 5e84b79 - YYYY-MM-DD 15:05:00 (XX minutes ago)
|/            Fourth commit - Christophe
* 2da6d8d - YYYY-MM-DD 15:00:00 (XX minutes ago)
            First commit - Christophe

git rebase

Commands:

Time           Branch “develop"              Branch "features/foo"           Branch "features/bar"
------- -------------------------------- ------------------------------- -------------------------------
15:10   git merge --no-ff features/bar
15:09                                                                    git commit -m “Sixth commit"
15:08                                                                    git rebase development
15:07   git merge --no-ff features/foo
15:06                                                                    git commit -m “Fifth commit"
15:05                                                                    git commit -m “Fourth commit"
15:04                                    git commit -m “Third commit"
15:03                                    git commit -m “Second commit"
15:02   git checkout -b features/bar
15:01   git checkout -b features/foo
15:00   git commit -m “First commit"

结果:

*   b0f6752 - YYYY-MM-DD 15:10:00 (XX minutes ago) (HEAD -> develop)
|\            Merge branch 'features/bar' - Christophe
| * 621ad5b - YYYY-MM-DD 15:09:00 (XX minutes ago) (features/bar)
| |           Sixth commit - Christophe
| * 9cb1a16 - YYYY-MM-DD 15:06:00 (XX minutes ago)
| |           Fifth commit - Christophe
| * b8ddd19 - YYYY-MM-DD 15:05:00 (XX minutes ago)
|/            Fourth commit - Christophe
*   856433e - YYYY-MM-DD 15:07:00 (XX minutes ago)
|\            Merge branch 'features/foo' - Christophe
| * 694ac81 - YYYY-MM-DD 15:04:00 (XX minutes ago) (features/foo)
| |           Third commit - Christophe
| * 5fd94d3 - YYYY-MM-DD 15:03:00 (XX minutes ago)
|/            Second commit - Christophe
* d01d589 - YYYY-MM-DD 15:00:00 (XX minutes ago)
            First commit - Christophe

Side notes

git cherry-pick

When you just need one specific commit, git cherry-pick is a nice solution (the -x option appends a line that says " (cherry picked from commit...) " to the original commit message body, so it's usually a good idea to use it - git log <commit_sha1> to see it):

Commands:

Time           Branch “develop"              Branch "features/foo"                Branch "features/bar"           
------- -------------------------------- ------------------------------- -----------------------------------------
15:10   git merge --no-ff features/bar                                                                            
15:09   git merge --no-ff features/foo                                                                            
15:08                                                                    git commit -m “Sixth commit"             
15:07                                                                    git cherry-pick -x <second_commit_sha1>  
15:06                                                                    git commit -m “Fifth commit"             
15:05                                                                    git commit -m “Fourth commit"            
15:04                                    git commit -m “Third commit"                                             
15:03                                    git commit -m “Second commit"                                            
15:02   git checkout -b features/bar                                                                              
15:01   git checkout -b features/foo                                                                              
15:00   git commit -m “First commit"                                                                              

结果:

*   50839cd - YYYY-MM-DD 15:10:00 (XX minutes ago) (HEAD -> develop)
|\            Merge branch 'features/bar' - Christophe
| * 0cda99f - YYYY-MM-DD 15:08:00 (XX minutes ago) (features/bar)
| |           Sixth commit - Christophe
| * f7d6c47 - YYYY-MM-DD 15:03:00 (XX minutes ago)
| |           Second commit - Christophe
| * dd7d05a - YYYY-MM-DD 15:06:00 (XX minutes ago)
| |           Fifth commit - Christophe
| * d0d759b - YYYY-MM-DD 15:05:00 (XX minutes ago)
| |           Fourth commit - Christophe
* |   1a397c5 - YYYY-MM-DD 15:09:00 (XX minutes ago)
|\ \            Merge branch 'features/foo' - Christophe
| |/
|/|
| * 0600a72 - YYYY-MM-DD 15:04:00 (XX minutes ago) (features/foo)
| |           Third commit - Christophe
| * f4c127a - YYYY-MM-DD 15:03:00 (XX minutes ago)
|/            Second commit - Christophe
* 0cf894c - YYYY-MM-DD 15:00:00 (XX minutes ago)
            First commit - Christophe

git pull --rebase

Not sure I can explain it better than Derek Gourlay ... Basically, use git pull --rebase instead of git pull :) What's missing in the article though, is that you can enable it by default :

git config --global pull.rebase true

git rerere

Again, nicely explained here . But put simple, if you enable it, you won't have to resolve the same conflict multiple times anymore.


为了补充TSamper提到 我自己的答案

  • 在合并之前进行重新分配通常是一个好主意,因为这个想法是,您将分支B的工作集成到您的分支Y ,您将合并分支B
    但是,再次合并之前,您可以解决分支中的任何冲突(即:“rebase”,例如“从分支B的最近一点开始,在我的分支中重放我的工作)
    如果正确完成,从分支到分支B的后续合并可以快进。

  • 合并直接影响到目的地分支B ,这意味着合并更好是微不足道的,否则分支B可能很长时间才能恢复到稳定状态(解决所有冲突的时间)

重组后的合并点?

在我描述的情况下,我把B重新分配到我的分支上,只是为了有机会从B最近点重放我的作品,但是留在我的分支中。
在这种情况下,合并仍然需要将我的“重播”作品带到B

另一种情况(例如Git Ready中描述 )是通过rebase将您的工作直接带到B (这可以节省所有漂亮的提交,甚至可以让您有机会通过交互式rebase重新排序)。
在这种情况下(当你在B分支的时候重新绑定),你是对的:不需要进一步合并:

默认情况下,我们没有合并或重新设计一个git树

我们通过重新贴牌获得:

第二种情况全是关于:我如何将新功能重新带回主服务器。

我的观点是,通过描述第一个转型的情景,就是提醒大家,转型也可以用作这个步骤的初步步骤(即“让新特征回到主体”)。
您可以使用rebase来首先将新功能分支中的master“带入”:rebase将重播来自HEAD master新功能提交,但仍旧位于新功能分支中,从而有效地将分支起点从旧主提交以HEAD-master
这样可以解决分支中的任何冲突(也就是说,如果冲突解决阶段花费太长时间,则允许主控并行地继续进化)。
然后,您可以切换到master并合并new-feature (或者如果要保留new-feature分支中的提交,则将new-feature绑定到master )。

所以:

  • “重组与合并”可以被看作是两种方式来导入一个作品,比如说master
  • 但是“重新合并然后合并”可以成为一个有效的工作流程,首先可以单独解决冲突,然后恢复工作。


很简单,你可以用另一个分支作为你工作的新基地

如果您有例如分支master并且您创建了一个分支来实现新功能,比如说您将其命名为cool-feature ,那么主分支当然是您的新功能的基础。

现在在某个时候,您想添加您在master分支中实现的新功能。 您可以切换到master并合并cool-feature分支:

$git checkout master
$git merge cool-feature

但是这样一个新的虚拟提交被添加,如果你想避免意大利面条历史,你可以重设:

$git checkout cool-feature
$git rebase master

然后在master合并它:

$git checkout master
$git merge cool-feature

这一次,由于主题分支具有相同的主提交以及提交新功能的提交,因此合并将仅仅是一个快进。


虽然合并绝对是整合变更最简单也是最常见的方式,但它不是唯一的方式: Rebase是另一种整合方式。

理解合并更好一点

当Git执行合并时,它会查找三个提交:

  • (1)共同的祖先提交如果你关注一个项目中两个分支的历史,他们总是至少有一个共同的提交:在这个时间点,两个分支具有相同的内容,然后演变不同。
  • (2)+(3)每个分支的端点集成的目标是组合两个分支的当前状态。 因此,他们各自的最新修订是特别感兴趣的。 结合这三个提交将导致我们正在瞄准的集成。

快进或合并提交

在非常简单的情况下,两个分支之一在分支发生后没有任何新的提交 - 它最新的提交仍然是共同的祖先。

在这种情况下,执行集成非常简单:Git可以在共同的祖先提交之上添加其他分支的所有提交。 在Git中,这种最简单的整合形式被称为“快进”合并。 两家分公司都分享完全相同的历史。

然而,在很多情况下,两家分公司都单独推进。

为了进行整合,Git将不得不创建一个包含它们之间差异的新提交 - 合并提交。

人类承诺与合并承诺

通常,提交是由人类精心创建的。 这是一个有意义的单元,只包含相关的更改并用注释对它们进行注释。

合并提交有点不同:它不是由开发人员创建的,而是由Git自动创建的。 而不是包装一系列相关的变化,其目的是连接两个分支,就像一个结。 如果您想稍后了解合并操作,则需要查看两个分支的历史记录以及相应的提交图。

与Rebase集成

有些人更喜欢没有这种自动合并提交。 相反,他们希望项目的历史看起来好像它是在一条直线上演变而来的。 没有任何迹象表明它在某个时候被分成了多个分支。

让我们一步一步地完成一个rebase操作。 该场景与前面的示例相同:我们要将来自分支B的更改集成到分支-A中,但现在通过使用rebase。

我们将分三步完成

  1. git rebase branch-A // syncs the history with branch-A
  2. git checkout branch-A // change the current branch to branch-A
  3. git merge branch-B // merge/take the changes from branch-B to branch-A

首先,Git将“撤消”分支-A上的所有提交,这些提交在线条开始分支之后发生(在共同的祖先提交之后)。 但是,当然,它不会放弃它们:相反,您可以将这些提交视为“暂时保存”。

接下来,它应用我们想要集成的来自分支B的提交。 在这一点上,两个分支看起来完全一样。

在最后一步,现在重新应用分支-A上的新提交 - 但是在新的位置上,在分支B的集成提交之上(它们是基于重新提交的)。 结果看起来发展是在一条直线上发生的。 不是包含所有组合更改的合并提交,而是保留了原始提交结构。

最后你得到一个干净的分支分支-A ,没有不需要的和自动生成的提交。

注意:git-tower的真棒post 。 在同一篇文章中, rebase缺点也是一个很好的解读。



这里有很多答案都说合并将所有的提交合并为一个,因此建议使用rebase来保存提交。 这是不正确的。 如果你已经推送了你的提交,这是一个坏主意

合并不会消除您的提交。 合并保留了历史! (只需看一下gitk)Rebase重写历史记录,在推送完成后这是一件坏事。

使用合并 -只要您已经推送就不会重新绑定

这里是Linus'(git的作者)接受它 。 这是一个非常好的阅读。 或者你可以在下面阅读我自己的版本。

重新分配主分支:

  • 提供了如何创建提交的错误概念
  • 污染了一大堆可能没有经过良好测试的中间承诺
  • 实际上可能会在这些中间提交中引入构建中断,因为在创建原始主题分支和重新分配基础之间需要进行更改。
  • 使在主人找到好地方难以结帐。
  • 导致提交上的时间戳不与树中的时间顺序对齐。 所以你会看到提交A在master中的提交B之前,但提交B是首先被创作的。 (什么?!)
  • 产生更多的冲突,因为主题分支中的单个提交可能都涉及必须单独解决的合并冲突(进一步说明每次提交中发生的事情的历史记录)。
  • 是对历史的重写。 如果被重新设计的分支已被推到任何地方(与自己以外的任何人共享),那么你已经搞乱了所有拥有该分支的人,因为你已经重写了历史。

相反,将主题分支合并到主控中:

  • 保留创建主题分支的历史记录,包括从主分支到主题分支的任何合并以帮助保持最新状态。 您确实知道开发人员在构建时正在使用哪些代码。
  • master是一个主要由合并组成的分支,并且这些合并提交中的每一个都是历史上的“好点”,因此可以安全地检出,因为这是主题分支已准备好进行集成的地方。
  • 主题分支的所有单独提交都被保留下来,包括它们在主题分支中的事实,因此隔离这些更改是很自然的,您可以根据需要进行钻取。
  • 合并冲突只需要解决一次(在合并时),因此主题分支中进行的中间提交更改不必独立解决。
  • 可以顺利进行多次。 如果您定期将主题分支与主人分享,那么人们可以继续在主题分支上进行构建,并且可以保持独立合并。




git-rebase