Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
git rebase如何在合并之间工作?_Git - Fatal编程技术网

git rebase如何在合并之间工作?

git rebase如何在合并之间工作?,git,Git,我有一个特性和一个主分支,例如,这样(其中主分支已两次合并到特性中): 您可以使用以下命令重建此MWE: git init f() { echo "$1" > README.md && git add README.md && git commit -m "$1"; } f 1 git tag initial git checkout -b feature f f1 git checkout master f 2 git checkout feature

我有一个特性和一个主分支,例如,这样(其中主分支已两次合并到特性中):

您可以使用以下命令重建此MWE:

git init
f() {   echo "$1" > README.md && git add README.md && git commit -m "$1"; }
f 1
git tag initial
git checkout -b feature
f f1
git checkout master
f 2
git checkout feature
git merge master
f f2
f f3
git checkout master
f 3
git checkout feature
git merge master
f f4
当我使用功能时,我想
git-rebase-I initial
来压缩一些功能分支提交。Git显示了这一点:

pick 4e4025b f1
pick 90e6f74 2
pick 3b78807 f3
pick 6849a63 3
squash
ing仅“f3”产生下图

* be4387c (HEAD -> feature) 3
* a90d504 2
* 2afe0a4 f1
| * c447c7f (master) 3
| * efec11d 2
|/  
* 661d8fc (tag: initial) 1
问题:

  • 为什么git不提供挤压“f2”
  • 我可以只挤压“f3”而不进一步改变整个分支结构吗
为什么git不提供挤压“f2”

因为
f2
是一个合并提交,您没有要求保留合并。默认情况下,
git-rebase
线性化历史并消除合并。它只是将提交文件堆叠在基础之上,就好像它们是新的补丁一样

您可以使用
-p
保留合并,然后您将获得所有提交

$ git rebase -i initial
pick bde29dc f1
pick c9a9c74 2
pick e5565c5 f2
pick 7f18c18 f3
pick ffdd62c 3
pick 35d8ae9 f4

# Rebase aa61de7..35d8ae9 onto aa61de7 (6 commands)
我可以只挤压“f3”而不进一步改变整个分支结构吗

是的,但在将
f3
压缩到
2
之前,如果要保留结构,则必须将
f3
压缩到
f2
中,因为这是拓扑上的前一个提交

pick bde29dc f1
pick c9a9c74 2
pick e5565c5 f2
squash 7f18c18 f3
pick ffdd62c 3
pick 35d8ae9 f4
你会得到这个的

*  (HEAD -> feature) f4
|\  
| *  (master) 3
* |  f2
|\ \  
| |/  
| *  2
* |  f1
|/  
* (tag: initial) 1
尽管将提交压缩为合并提交没有多大意义

如果您改为对提交进行重新排序,以便将
f3
压缩为
2

pick bde29dc f1
pick c9a9c74 2
squash 7f18c18 f3
pick e5565c5 f2
pick ffdd62c 3
pick 35d8ae9 f4
…你会得到。。。有点奇怪

*   (HEAD -> feature) f4
|\  
| * 3
|/  
* f3
* 2
* (tag: initial) 1
尝试使用
git-rebase-i-p
在分支之间移动提交会让人感到困惑,因为
git-rebase-i
为您提供了非线性历史的线性视图。假装非线性历史是线性的是Git容易混淆的地方


但你可能不应该担心保存这些东西。保持Git历史基本上是线性的,这会使一切变得更简单。下面是如何做到这一点

您的历史记录可能是使用
git merge master
更新
功能的结果。这里有一个更好的方法

1 -- 2 ------- 3 [master]
 \    \         \
  f1 - f2 - f3 - f4 [feature]
f2
f4
没有实际值;它们是来自
master
的更新,不包含任何有趣的内容。他们只是让历史变得混乱。只有
f1
f3
包含实际内容。您最好使用
git-rebase-master
消除这些更新合并,并获得一个线性历史记录

$ git rebase master

1 - 2 - 3 [master]
         \
         f1 - f3 [feature]
然后一切都变得清晰简单。通过使用
git-rebase-master
而不是
git-merge-master
更新分支,继续简化历史记录

# After more updates with `git rebase master`
1 - 2 - 3 - 4 - 5 [master]
                 \
                  f1 - f3 - f5 - f6 [feature]
当您准备将
功能
合并到
主控
中时,您需要合并提交。使用
git merge--no-ff特性
强制合并提交,然后删除
特性

$ git merge --no-ff feature
$ git branch -d feature

1 - 2 - 3 - 4 - 5 ------------------ 6 [master]
                 \                 /
                  f1 - f3 - f5 - f6

这将在历史上保留分支,而不必保留分支的头部。这让未来的代码考古学家清楚地认识到,
f1-f3-f5-f6
都是为一个功能而开发的。

为什么git不提供挤压“f2”?
挤压什么?挤压是将两次提交合并为一次提交的操作。所以说“挤压f2”没有多大意义。与您的问题“我只能挤压f3吗?”@Code学徒挤压“f2”类似,我希望“f1”得到“f3”的父级,“2”得到“f3”的合并箭头。挤压“f3”,我希望“f2”得到“f4”的父级。这是错误的逻辑吗?也许只使用
git-rebase-master
。。。出于好奇,当我在“功能”上时,任何一个rebase命令(无意中)都能重写大师的历史吗?@Johannes除非你的历史真的很混乱,否则不会。
$ git merge --no-ff feature
$ git branch -d feature

1 - 2 - 3 - 4 - 5 ------------------ 6 [master]
                 \                 /
                  f1 - f3 - f5 - f6