6

初始场景:

A (master)
 \
 B - C  - D (development)

合并后我想要的--squash:

A     -     E (master/development)
 \         /
 B - C - D 

在分支master上,git log将是

commit E
    Squashed commit of the following:
    commit D
    commit C
    commit B
commit A

继续在分支上开发development

A     -     E (master)
 \         / \         
 B - C - D    F - G - H (development)

再次与壁球合并:

A     -     E     -     I(master/development)
 \         / \         /
 B - C - D    F - G - H

在分支master上,git log将是

commit I
    Squashed commit of the following:
    commit H
    commit G
    commit F
commit E
    Squashed commit of the following:
    commit D
    commit C
    commit B
commit A

在分支development上,git log将是

Commit I
Commit H
Commit G
Commit F
Commit E
Commit D
Commit C
Commit B
Commit A

我想与压缩的提交合并,master同时保持每个提交都在development.

我不知道如何实现。我的问题是我不知道如何在第一次合并中D指出,并且将包含而不是仅包含。EIB,C,D,E,F,G,HF,G,H

4

3 回答 3

4

您无法使用显示的结构获得所需的日志结果(git log --merges master会这样做)。会给你你想要的日志的结构打破了这一点。最后,这是使用 Git 的一种弄巧成拙的方式。


希望能够运行git log master并且只看到压缩的提交。这行不通。Git 不知道有些提交是针对master而有些是针对development. 让我们看看建议的结构。

A     -     E     -     I [master] [development]
 \         / \         /
 B - C - D    F - G - H

此时,masterdevelopment指向同一个commit。就 Git 历史而言,它们是相同的。分支只不过是指向提交的标签。提交不记得他们提交到哪个分支git log master并将git log development生成相同的日志,显示从 A 到 I 的所有提交。E 和 I 压缩的提交日志将是多余的。

可以git log --merges master使用(或)获得您想要的内容development以仅显示合并提交,但这将显示任何合并提交,即使是作为development. 所以它真的不起作用。

这整个想法是不必要的复杂,请继续阅读。


为了得到你想要的日志结果,你必须像这样打破两个分支之间的关系。

A     -     E     -     I [master]
 \                   
 B - C - D - F - G - H [development]

你可以以某种方式使其工作,但没有意义。 git log master包含所有相同的日志消息,因此它将与 一样长git log development,但它们会被粉碎在一起。你不能git log master用来做代码考古(即“为什么要这样写这一行”),因为所有更改都被拼凑成一个差异,这使得将一行更改与特定提交消息关联起来变得更加困难。由于masterand的历史development是不相关的,因此无法确保开发中的所有内容都成为 master,反之亦然(例如,对 master 的热修复)。

git log master提供的信息比. 少git log development,而且更难理解master与保留合并历史记录没有关联development并失去了所有好处。维护这种复杂的设置毫无意义。


相反,用于git merge --no-ff合并功能分支(不是一个连续的“开发”分支)并保留分支历史以便于考古。

              G - J [feature/tacos]
             /
A     -     E     -     K [master]
 \         / \         /
 B - C - D    F - H - I

E 和 K 是由git merge --no-ff. 没有连续development的分支,由特征分支处理。功能分支是一次性使用的,一旦合并就被删除。有关功能分支的信息保留在合并提交中,并git merge --no-ff保证保留分支结构。feature/tacos是一个功能分支,用于处理尚未合并的 tacos。

git log --graph --decorate master将显示 master 的完整历史记录,合并提交显示功能何时结束,以及说明分支历史记录的行。诸如GitX 之类的 GUI Git 历史记录工具是将历史记录作为图形读取的另一种方式。

最后,Git 历史是一个图表。如果你学会了如何使用 Git 来处理这个图形,生活会容易得多。如果你试图让 Git 历史线性化,就像一大堆煎饼一样,你就违背了 Git 的意义,并为自己和其他人创造了额外的工作。

于 2015-10-17T21:53:21.573 回答
1

好吧,不可能准确地得到你想要的东西,就像你合并分支一样,无论如何你都会在提交日志中看到来自两个分支的提交。你可能想要的是这样的:

A      -     E (master)
 \         
 B - C - D (development)

development您只需从分支中挑选提交,压缩它们并应用到master.

最简单的方法是这样的:

git checkout development && git rebase -i master HEAD

然后,您将除第一个操作之外的所有操作替换为squash. 结果,您将获得一个独立的头,该头指向被压扁的提交,应用在master. 你只需要重置master到这个提交,你就完成了。

我想,提交消息不会完全符合您的要求,因为它将重新排序所有提交的提交消息,而不是它们的哈希,但是您将能够使用该--exec选项挂钩到提交消息的生成。

一切都有点过于手动,但您可以编写所有内容并创建别名。我相信,这是您可以使用的最接近的方式git,而不是用某种高级编程语言重写所有内容。

于 2015-10-17T22:15:26.307 回答
0

那只是一个常规的合并...

#!/bin/sh
git init
touch a; git add a; git commit -m a
git checkout -b patch
touch b; git add b; git commit -m b
touch c; git add c; git commit -m c
git checkout master
git merge --no-ff patch
git log --graph --oneline

结果

*   a9fbaec Merge branch 'patch'
|\
| * fb7eac4 c
| * 94f44c1 b
|/
* 4de57a5 a
于 2015-10-17T21:03:12.003 回答