自动从两个分支之间的差异创建单个提交

时间:2019-11-06 08:34:25

标签: git

在处理要素时,我总是从当前的主分支(例如,“ feature / my-feature-name”)创建要素分支,然后在完成后将其合并回master。

问题在于,我最终带来了许多“进行中的工作”,这些无意义的承诺以这种方式掌握了。

为避免此问题,我想创建一个新的本地功能分支(例如,“ feature / my-feature-name-CLEAN”),其中不包含我在“ feature / my-feature”中所做的任何提交-name”,但在功能/我的功能名称和母版之间存在未提交更改的区别。这样,我就可以在一次提交中将那些更改提交到“功能/我的功能名称-CLEAN”中,然后将其合并到主服务器中。

此处描述了类似的内容: git create commit from diff between two branches

您知道是否存在可以自动执行此操作的git命令,脚本或Git客户端功能吗?

2 个答案:

答案 0 :(得分:2)

在Git中,大约有三种(或十种或数百种,取决于您要如何计数)不同的方式来执行此操作,但是您的特定情况可能最简单的方法是使用{{1 }}。

  

侧边栏:git merge --squash通常进行合并提交。 git merge 从不进行合并提交。这使git merge --squash有点误导性命令。 Git使用合并 machinery 来获取结果,但使您在最后手动运行git merge --squash,并且此时可以提供全新的提交消息。

让我们确切说明这是如何工作的。请记住,Git实际上是关于 commits 的全部-具有丑陋的哈希ID的实体,并且根本不关心分支名称,例如{{ 1}}和git commit。该名称实际上仅包含一个提交哈希ID。每个提交都拥有其直接 parent 提交的另一个哈希ID, 1 ,因此可以通过从末尾开始并向后工作来处理这些提交。

实际哈希ID看起来是随机的,并且是不可预测的。我们将使用诸如master之类的单个大写字母来代表真实的哈希ID,并且我们将按顺序分配它们,因此很容易看出我们何时进行了提交。当然,这将严重限制我们 可以进行的提交数量(这就是为什么 Git使用如此大的丑陋哈希ID)。我们从第一个提交开始:

feature/my-feature-name
没有父级的

,因为没有更早的提交。名称H 指向此提交(名称A <-- master 包含其实际的哈希ID)。

现在,我们进行第二次提交。新的提交指向第一个提交,Git更新名称master使其指向第二个提交:

master

我们进行第三次,第四次等提交,并得到一条链:

master

名称始终指向链中 last 提交的(包含其哈希ID)。这就是Git中分支的全部内容:一个包含 last 提交的哈希ID的名称。每个提交都包含一步一步提交的哈希ID,这就是Git存储库保存 history 的方式。

让我们在这里有点懒,不要再将内部箭头绘制为箭头了。这不完全是懒惰,因为现在我要开始绘制第二个分支名称。我们将使用新名称A <-B <-- master

... <-F <-G <-H   <-- master

请注意,两个名字都指向同一提交。分支feature/tall上的所有提交都在我们的新分支...--F--G--H <-- feature/tall (HEAD), master 上。我们还将在括号中添加master一词,并附加在其中一个名称上,以便我们可以记住我们在哪个分支上。

现在,我们进行新的提交,其中一些主题很傻,例如feature/tallmy hands are typing words

HEAD

我们现在已经到了要进行一次提交的阶段,您希望将其标记为wip。因此,首先我们需要找到提交...--F--G--H <-- master \ I--J--K--L--M--N <-- feature/tall (HEAD) 的哈希ID。如果feature/tall-CLEAN仍指向H,那是找到它的简便方法。 2 假设是这种情况,您可以简单地做到:

master

为您提供了这一点:

H

现在您可以运行:

git checkout -b feature/tall-CLEAN master

这将比较提交...--F--G--H <-- feature/tall-CLEAN (HEAD), master \ I--J--K--L--M--N <-- feature/tall (您现在没有的提交)与提交git merge --squash feature/tall ,以查看更改了什么。然后,它将那些相同的更改应用于提交H,以准备进行新的提交N

要实际制作H,必须运行O。这将使O并移动名称git commit指向新的提交:

O

而您正是您想要的。


1 实际上,每个提交都有一个此类哈希ID的列表。但是,大多数提交在列表中只有一个条目。合并提交具有两个或多个条目,而您(或任何人)在新的空存储库中进行的第一个提交都具有一个空列表(无父提交),因为没有较早的提交。 / p>

2 如果feature/tall-CLEAN不再指向 O <-- feature/tall-CLEAN (HEAD) / ...--F--G--H <-- master \ I--J--K--L--M--N <-- feature/tall ,则需要找到提交master。一种方法是运行H,然后检查输出。然后,您可以剪切并粘贴其缩写的哈希ID。另一种方法是使用H,它应该打印出git log --graph --oneline --decorate master feature/tall的哈希ID,您可以再次剪切和粘贴该哈希ID。

答案 1 :(得分:0)

我相信您可以压缩所有 dirty 提交的交互式基础master来完成工作。

请参阅文档here,以获取有关变基选项的更多信息。