繁体   English   中英

Git从master迁移到Feature分支问题

[英]Git rebase from master to feature branch issue

我有以下情况:

  1. 我已经从master创建了一个开发分支。 在开发分支中重命名/移动了文件(将文件a.jsp移至b.jsp),并将更改推送到远程源/开发分支。
  2. 但是高手仍然有一个.jsp。 由于母版是公共分支,因此其他用户正在进行功能更改并将更改提交/合并到母版中。 这意味着a.jsp文件中有更改。
  3. 当我尝试使用“ git rebase master”将更改从master分支拉到我的开发分支时。 现在,我同时看到文件a.jsp和b.jsp。 但是,我想将新更改从master / a.jsp拉到开发分支b.jsp。 而不是同时拥有两个文件。

有人可以指导我如何更好地处理此问题吗?

目前尚不清楚,为什么重新设置基准不会显示合并冲突(在一侧删除a.jsp和另一侧修改a.jsp之间)。 因为没有,所以如果您希望重新设置基准产生期望的结果,则需要进行交互式重新设置。

在评论中,您询问是否应避免重新定级。 可能有理由考虑。 如果development是所有回购用户共享的长期分支,那么您可能不希望将其作为工作流的常规部分。 但是撇开这一点,这种特殊的变更组合并不会阻止您使用变基。 我将概述如何进行基准测试,因为这解决了原始问题。 您和您的团队将必须决定这是否正确。

在较早尝试重新设置基准之后,可能可以使此工作生效,但是如果您可以先尝试恢复到重新设置基准之前的状态,则可以更轻松地跟踪事物的状态并避免错误。 您可以通过创建一个新的源克隆来做到这一点(假设您尚未推送第一个变基的结果)。 如果这样做,某些东西(如reflog)会丢失; 另一个选择是使用引用日志来帮助您还原当前克隆。

git reflog development

输出应显示development人员指向的每个提交,并为每个提交分别命名诸如development@{1}development@{2}等。您将在重新确定基准之前确定一个提交并进行reset 例如,我假设rebase是导致development引用发生更改的最新内容,在这种情况下,rebase之前的状态为development@{!}

git checkout development
git reset --hard development@{1}

接下来,以交互方式重新启动变基。

git rebase --interactive master development

您将在development分支上得到一个带有提交列表的编辑器。 它看起来像

pick aaaaaaaa Some changes
pick bbbbbbbb move a.jsp to b.jsp; maybe more changes
pick cccccccc more changes

找到将a.jsp移至b.jsp的提交(在上面的示例中为bbbbbbbb ),并将该行开头的单词pick更改为edit 保存并关闭编辑器。 此时,应该开始重新处理。

接下来的操作取决于git的作用。 既然您表示它之前完成了重新设置而没有冲突,所以我认为不会再有冲突了。 因此在重播bbbbbbbb之后,处理将停止。

如果bbbbbbbb仅移动了文件而不进行更改,那么您可以简单地

mv a.jsp b.jsp
git add a.jsp b.jsp
git commit --amend

然后继续变基。 注意,如果aaaaaaaa更改了a.jsp ,那就没关系; git在重放aaaaaaaa时已经合并了这些更改。 类似地,如果cccccccc更改b.jsp ,则此刻无关紧要。 我们只关心bbbbbbbb ,除了重命名文件之外,是否也对其进行了更改。 如果确实如此,那么您可能需要告诉git合并更改(可能通过执行文件级合并)。

在我看来,这里需要格外小心,因为重新设定的行为不符合我的预期(因为它没有将developmenta.jsp迁移到b.jsp视为与master的更改冲突)。 a.jsp )。 因此,我将看一下b.jsp并验证git已经对其进行了哪些更改。 理想情况下,它应该已经反映了master的更改(尽管我认为不会;如果可以,我不希望a.jsp出现)。

如果确实包含来自master的更改,那么您很幸运。 您要做的就是删除a.jsp

rm a.jsp
git add a.jsp
git commit --amend

但是否则,我希望您会发现a.jsp包含master更改以及aaaaaaaa任何更改,而b.jsp包含aaaaaaaabbbbbbbb所有更改。 merge-file命令中, b.jsp将是“当前文件”(有时称为“我们的文件”),而a.jsp将是“其他文件”(有时称为“其文件”)。 我们需要获取基本文件。

我们将a.jsp重命名,以便在签出基本版本时不会丢失“他们的”版本。

mv a.jsp a.jsp.theirs
git checkout HEAD^^ -- a.jsp

checkout命令从aaaaaaaa提交的重写版本(将a移到b提交之前的最后一个提交)中获取a.jsp的版本。 它应该包含“我们的”和“他们的”中的所有更改,并且没有其他更改,因此这是一个很好的合并基础。 所以

git merge-file b.jsp a.jsp a.jsp.theirs

这将执行文件级合并。 它可能会记录冲突(就像git中的任何常规合并一样),您必须通过编辑b.jsp来解决。 处理a.jsp.theirs之后,您可以删除a.jspa.jsp.theirs 然后

git add a.jsp b.jsp
git commit --amend

所以基本上所有的道路都导致这个commit --amend命令,一旦完成,您就可以重新启动commit --amend

git rebase --continue

如果后续提交( cccccccc )包含对b.jsp更改,则希望它们将被合并(但是可能会发生冲突,需要进一步干预)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM