git:如何重新排序(严格地)提交序列

git:如何重新排序(严格地)提交序列,git,git-rebase,Git,Git Rebase,我正在根据zip快照创建一个回顾性项目历史记录。我已经从手头的快照构建了一个提交的长分支序列。现在,我在最后添加了更多的“发现”快照,这些快照应该位于提交序列的“中间”的不同位置 我正在尝试使用git-rebase-I对git快照进行重新排序。我只是简单地交换选择列表顺序。这应该只是重新写入提交对象,但保持底层树不变(因为快照没有更改) 在本例中,rebase似乎仍在尝试创建补丁,并存在大量冲突,而不是进行简单的重新安排。对于这种特殊情况,是否有更合适的命令?我没有合并,只有一个分支。整个回购协

我正在根据zip快照创建一个回顾性项目历史记录。我已经从手头的快照构建了一个提交的长分支序列。现在,我在最后添加了更多的“发现”快照,这些快照应该位于提交序列的“中间”的不同位置

我正在尝试使用git-rebase-I对git快照进行重新排序。我只是简单地交换选择列表顺序。这应该只是重新写入提交对象,但保持底层树不变(因为快照没有更改)


在本例中,rebase似乎仍在尝试创建补丁,并存在大量冲突,而不是进行简单的重新安排。对于这种特殊情况,是否有更合适的命令?我没有合并,只有一个分支。整个回购协议仍然是非常局部和私有的。

我无法帮助简化重新基准,但我可以解释为什么它不是一个“简单的重新安排”。例如,以一个文件为例,每个修订版都附加一行文本。在第一次提交时,它看起来像:

Commit 1
Commit 1
Commit 2
Commit 3
Commit 1
Commit 2
在第二次提交时,由于您最初将它们按顺序排列,因此看起来如下所示:

Commit 1
Commit 1
Commit 2
Commit 3
Commit 1
Commit 2
在第三次提交(即第二次快照)时,它看起来像:

Commit 1
Commit 1
Commit 2
Commit 3
Commit 1
Commit 2
Git正在处理修补程序,因此对Git来说,一系列提交看起来像:

Commit 1
Commit 1
Commit 2
Commit 3
Commit 1
Commit 2
  • 添加一个带有“提交1”行的文件
  • 在表示“提交1”的行之后添加表示“提交2”和“提交3”的行
  • 删除“提交2”一行之后的“提交3”一行
重新排序时,它看起来像:

Commit 1
Commit 1
Commit 2
Commit 3
Commit 1
Commit 2
  • 添加一个带有“提交1”行的文件
  • 删除“提交2”一行之后的“提交3”一行
  • 在表示“提交1”的行之后添加表示“提交2”和“提交3”的行
它进入第二步,没有看到与“Commit 2”匹配的行,不知道该做什么,因此需要手动合并


手动解析合并,然后在下一步中,git会在预期的位置看到两行,再次需要手动合并。

如果您的历史记录如下所示:

a->b->c->d->e->f
其中
e
f
应该放在
a
d

您仍然可以执行
rebase-i
,但将
edit
放在要插入快照的位置之前的提交上。当git暂停编辑时,将快照放在工作目录中并添加/提交它。继续重基直到下一个点,冲洗,重复


如果需要说明的话,您还需要删除最初放错位置的提交,
e
f
,它们处理放错位置的快照。

不要麻烦重新设置基础。做一个新的分支。如果X是要使用的提交的sha1或treeish,则:

git checkout X -- .
git add -A
git commit -C X
按所需的时间顺序对所有提交重复此操作

我们颠倒最后5次提交的顺序的示例:

git checkout -b temp old_branch~5
git checkout old_branch -- .
git add -A
git commit -C old_branch
git checkout old_branch~1 -- .
git add -A
git commit -C old_branch~1
git checkout old_branch~2 -- .
git add -A
git commit -C old_branch~2
git checkout old_branch~3 -- .
git add -A
git commit -C old_branch~3
git checkout old_branch~4 -- .
git add -A
git commit -C old_branch~4

git push . HEAD:old_branch -f
git checkout old_branch
git branch -d temp

git log -5 # to see the new history

希望这能有所帮助。

git-rebase
假设提交实际上是通过其更改而不仅仅是树来识别的。你尝试做的是非常不寻常的,所以我认为git的陶瓷部分对你没有多大帮助,你必须使用管道。我想知道使用或类似的方法是否有效。@Karl:我会仔细看看这个方法,至少了解它在做什么。快速浏览表明,如果它简化了我对WindowsLinux的困惑,它可能会领先于Adymitruk的方法;-)我认为Adam Dymitruk的答案是最好的,但请看下面的评论。这就是为什么我认为
git rebase
不是这份工作的合适工具。我不确定到底是什么。这将是非常乏味的。您不想应用修补程序,而只是将每次提交时出现的快照缝合在一起。这仍然可能会导致大量冲突。它将尝试应用这些更改,因此结果可能与以前的树不完全相同。我想我可能会同意这一点,但使用初始重基来获取提交sha1的列表,这主要是因为它将它们都放在pick文件中。然后将其作为脚本运行。在其他操作系统上使用30年后,学习一些linux编辑和脚本方法是很尴尬的!
git add-A
命令是否应该有一个尾部
来选择所有文件,或者它是
-A
的一个隐式部分?(我总是看到/使用它)我也遇到了一个问题,即在签出之间删除掉的目录和文件的顺序失败。顶级目录名在每个快照之间更改,通常显示为一组重命名,但这里我只是得到一个附加集!有什么建议吗?重新阅读checkout手册页,会不会是因为我使用的是sha1值,而不是选择提交的branch~depth方法?[即分离与非分离]git add-A应该从repo的根目录执行,您不需要“.”。