Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/21.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提交_Git_Merge_Rebase_Magit - Fatal编程技术网

挤压合并之前的旧git提交

挤压合并之前的旧git提交,git,merge,rebase,magit,Git,Merge,Rebase,Magit,我正在清理git回购协议,以便更容易理解。到现在为止,它是私人的,所以我可以改变历史 大多数情况下,我一直在将提交压缩到有意义的集合中 问题是,该项目在其历史早期是另外两个项目的合并。我无法压缩合并之前的提交 我的问题是:我如何做到这一点 具体地说:我有 xxxxxx * master: Latest commit xxxxxx * another commit xxxxxx * Merge projectA and projectB xxxxxx |\ 0000A6 | * a minor

我正在清理git回购协议,以便更容易理解。到现在为止,它是私人的,所以我可以改变历史

大多数情况下,我一直在将提交压缩到有意义的集合中

问题是,该项目在其历史早期是另外两个项目的合并。我无法压缩合并之前的提交

我的问题是:我如何做到这一点

具体地说:我有

xxxxxx * master: Latest commit
xxxxxx * another commit
xxxxxx *   Merge projectA and projectB
xxxxxx |\
0000A6 | * a minor commit in project A
0000A5 | * another minor commit
我想把0000A5和0000A6挤在一起

当我尝试交互式rebase时,magit(我碰巧使用的git的emacs前端)警告我“尽管在rebase范围内进行了合并,仍要继续吗?”当我继续时,它失败了以下几点(取自我的实际工作,而不是上面的简化示例)。我不确定合并之前的提交是否存在重定基址的问题,或者其他问题(“未跟踪文件”行是可疑的,因为合并是将客户端项目移动到较大项目的“client/”子目录中

Last commands done (5 commands done):
   pick fb5de84 Simplified schema:
   squash 96ac7ac Revert schema to full complexity
Next commands to do (29 remaining commands):
   pick 4ad389a Just indentation, for readability
   pick 4241835 First pass at schema
You are currently editing a commit while rebasing branch 'master' on 'ad91ab4'.

Untracked files:
    client/

No changes
You asked to amend the most recent commit, but doing so would make
it empty. You can repeat your command with --allow-empty, or you can
remove the commit entirely with "git reset HEAD^".

Could not apply 96ac7ac7753c03e83b8c1296d892ce9c5fea44c7... Revert schema to full complexity

这里似乎发生了一些事情。我不熟悉您正在使用的前端,但它似乎正在尝试自动重新设置基础,并在出现通常需要手动干预但不知道如何修复的暂停时退出

虽然通过合并重定基址可能会很棘手,但我认为这与当前问题无关。在我看来,96ac7ac只是fb5de84的还原,因此当您将它们挤压在一起时,会得到一个空提交。这是允许的,但需要手动干预。(重基将停止,您可以说类似于
git commit--allow empty
,然后继续。)

您可以通过执行以下操作来确认96ac7ac是否真的是一个完美的还原

git diff 96ac7ac fb5de84^
如果是这样,并且如果前端无法容纳重新基所需的干预,那么您可以放弃这两个提交,而不是挤压它们

您可能遇到的下一件事是,rebase将尝试使历史保持线性,除非您提供
--preserve merges
选项。我认为这就是前端警告您的原因,一旦您告诉它继续,我不知道它是否通过了该选项

即使有正确的选项,通过合并重新定基的问题是,原始合并中超出默认自动解决方案的任何工作都可能丢失。如果需要手动解决冲突,git将再次停止并期望您执行解决方案(您的前端可能不配合)。此外,如果自动解析会成功,但合并包含手动应用的更改(谢天谢地,这很少见,但并非不可能),则更改可能会自动丢失

另一种选择是“变通”合并(如果没有太多)

X --- A --- B --- M --- C <--(master)
  \             /
   D --- E --- F
准备壁球,给你

X --- A --- B --- M --- C <--(master)
  \             /
   D --- E --- F
    \
     EF <--(temp_branch)
在此合并过程中,您必须重新生成在原始合并
M
中完成的任何工作。如果
M
只是自动解析,则新合并(
M'
)也应如此。您可以确认它与

git diff M M`
如果这显示出差异,您必须手动应用它们(这可能也是
M
的情况)。您可以使工作树看起来正确,并使用
--amend
提交

当然,如果合并信号冲突,您必须解决它们;同样,与
M
的差异应该提供良好的指导

当这件事完成后,你就有了

         <*>- M --- C <--(master)
             /
X --- A --- B --- M' <--((HEAD))
  \              /     
   D --------- EF <--(temp_branch)
    \
     E --- F -<*>
屈服

X --- A --- B --- M' --- C` <--(master)
  \              /     
   D --------- EF
如果还想验证每个历史提交,则此符号可能会变得混乱…)


另一种变体是,您可以挤压
E
F
,然后使用
--父过滤器
设置一个
git过滤器分支
,以将
M
B,F
重新设置为
B,EF
的父过滤器e> 有关如何使用父过滤器的详细信息的文档(尽管您必须稍微调整示例以处理合并)。这可能会起作用,因为您特别希望结果具有不变的树。

您要求执行的操作很棘手,因为合并提交的交互式重新基不会以您可能计划的方式结束。请阅读此处:带嫁接的筛选器分支可能是您想要的,请将提交ID和您希望的父级放入。git/info/grafts,(例如echo$(git rev parse$merge^2$merge^2~2)>.git/info/grafts),执行lgdo(log--graph--decoration--oneline)为确保这是您要烘焙的历史记录,请过滤分支。如果挤压提交
0000A5
0000A6
,您将获得一个新的提交。
0000A5
0000A6
未被修改,它们仍然是当前
主分支的历史记录的一部分。然后,您必须再次合并提交的第一个父级“合并projectA和projectB”与通过挤压获得的提交,然后重新设置“合并projectA和projectB”之后的
master
历史记录的基础关于新的合并提交。谢谢!非常详细的回答。你不仅回答了我的问题,还增加了足够的洞察力,以更复杂的方式提高了我使用git的舒适度。
         <*>- M --- C <--(master)
             /
X --- A --- B --- M' <--((HEAD))
  \              /     
   D --------- EF <--(temp_branch)
    \
     E --- F -<*>
git branch --delete temp_branch
git rebase --onto M` M master
X --- A --- B --- M' --- C` <--(master)
  \              /     
   D --------- EF
git diff master master@{1}