如何在强制推送基本分支后更新我的功能分支。我们只使用 rebase,禁止合并

How to update my feature branch after a force push on the base branch . We only use rebase, merges are forbidden

我们在 git 中使用一个非常简单的结构。

首先我们有 master 分支。

下面我们有develop

最后我们可以有任何 feature 分支

我们只使用 rebase 来更新我们分支上的历史,然后转发到上面的分支。

每周,我们的 develop 分支都会更新一些 features。并且这个分支被 rebased 并合并到 master(从 developmaster)。

问题

当我们将 develop 变基并合并到 master 时,有时会发生冲突,我必须通过对 develop 分支执行 master 变基来修复它们.修复冲突后,我执行 git push --force-with-lease 将更改上传到远程。

此程序后,由于强制推送,开发历史已被更改。

当另一个开发人员正在基于 developfeature 分支上工作时,问题就出现了,但是,在强制推送之前(develop 在强制推送之前)。

我们如何使用 develop 分支的新历史更新此开发人员的 feature 分支。 因为,在我们的 feature 分支中执行 git rebase develop 时。我们最终有很多冲突。

如果我没理解错的话,开发者是这样的情况:

--*--x--*--m <- master
      \
       \
        *--*--f <- develop
               \
                a--b--c <- feature

获取更新后,他到达:

--*--x--*--m <- master
      \     \
       \     *--*--f' <- develop
        *--*--f
               \
                a--b--c <- feature

要仅在 develop 之上重播 a, b, c,请应用@Vitali 建议的命令:

  • spot commit f : featuredevelop,
  • 之间的原始分叉点
  • 运行 : git rebase --onto develop <f> feature

如果一切顺利,他将达到以下状态:

--*--x--*--m <- master
            \
             *--*--f' <- develop
                    \
                     a'--b'--c' <- feature

# only 'a--b--c' are replayed from the original 'feature' branch,
# not '*--*--f'

问题here中有git rebase --onto。 另一种长途是:

1.

git checkout -b feature1 develop  # this will create a new branch that will be in sync with your current develop
  1. 检查 feature 分支上的提交并记下 develop 上的开始和最后一次提交。

git cherry-pick <commitA>^..<commitB>
  1. 冲突总是要你解决,但我发现它不太容易引入错误。解决它们。

  2. 一旦您对当前分支感到满意,请删除旧的 feature 分支并将 feature1 重命名为 feature


问题:功能分支中存在来自已删除集成分支的提交。它们需要被删除或还原。

详细解决方案: 以后,按如下方式更改您的工作流程。

  • 不要将集成分支合并到功能分支中。 git pull origin develop
  • Do 将 master 合并到功能分支中。 git pull origin master
  • Do 将功能分支合并到名为 develop 的集成分支中。 git checkout develop && git merge my-feature

详情

ff-only 选项确保开发人员只获得可快速转发的更改并且他们的功能不会被开发分支中的瞬态突变污染。

开发者应该从 master 开始他们的 feature-that-works 分支。

工作开始时:

git pull
git checkout master
git checkout -b feature-that-works

现在我有一个名为 feature-that-works 的新分支,我已准备好开始编写我的功能。

如果我将集成分支 develop 直接拉入我的 feature-that-works 分支会怎样?我的功能分支被合并到集成分支中的所有其他正在进行的工作所污染。我无法控制其他正在进行的工作,一般来说,我不希望它污染我干净的特性分支。这就是为什么我不从名为 develop 的集成分支拉入我的 feature-that-works.

了解最新变化

把master拉进一个feature分支不是问题。有时我在我的持续部署项目中每天多次从 master 获取数据。这很好!

git checkout feature-that-works
git pull --ff-only origin master

上面带有 --ff-only 选项的命令 如果存在冲突将失败

发生冲突时怎么办

下一个命令在有效的功能下重新设置 master 的基数。

git pull -r origin master

ff-only 选项因冲突而失败时,我必须将我的分支 变基到 master 的顶部 。另一种说法是,我需要在我的功能分支 下对 进行变基。这样就保证了master分支可以一直快进。

通过在我的本地特性分支中变基,可以在没有任何合并冲突的情况下将我的特性分支中的提交历史重播到主分支上。我在本地解决所有冲突,而不是等到将我的更改应用到 master 分支的时候。如果有问题,希望这是一个我可以在本地解决的小问题,而不是等待并让下游的其他人更头疼。

这里的 another good explanation 有一个简单的视觉描述为什么 ff-only 优于 git 合并。

一个有趣的事实:如果没有 ff-only 选项,git pull 命令实际上与 git fetch + git merge.

相同

积分

我将一个feature-that-works合并到develop中。正如我之前提到的,它 而不是 相反的工作方式。

git push origin feature-that-works
git fetch
git checkout develop
git reset --hard origin/develop
git pull origin feature-that-works
git push origin develop

我使用git reset --hard origin/develop的原因是开发分支是可变的。开发可以由其他人强制推动。我想确保我的本地开发分支与远程上游分支匹配 origin/develop.

仅此而已。请记住,即使有良好的工作流程,开发人员也需要沟通,并且有时可能需要与其他开发人员一起解决合并冲突。

交互式变基或 git cherry-pick.

很简单

我认为交互式变基要快一点。有关详细信息,请参阅 git-scm 文档中标题为 Changing Multiple Commit Messages 的部分。

两步交互式变基

  1. 创建 my-feature-cleanup 分支。从 master 分支开始省略所有旧工作。
git checkout master
git checkout -b my-feature-cleanup
  1. 发出 interactve rebase 命令将 my-feature 中的良好提交重新设置为 my-feature-cleanup 分支。
git rebase -i origin/my-feature

以上命令应打开 git-rebase-todo 编辑器 window。为要保留的提交选择 pick,为不想保留的提交选择 drop

# p, pick <commit> = use commit
# d, drop <commit> = remove commit

另一种选择

Cherry pick 也可以。这是相同的想法,但可能需要多个命令才能 cherry pick individual commits 而不是一次完成所有操作。

  1. 开始的方式相同
git checkout master
git checkout -b my-feature-cleanup
  1. 列出 my-feature
  2. 中的提交
git log my-feature
commit 02345 Something I did
commit 12345 Merge branch 'X' of 'Y'
commit 22345 A thing someone else did
commit 32345 Another thing I did
  1. 从最旧的
  2. 开始,从 my-feature 中挑选个人提交
git cherry-pick 32345
git cherry-pick 02345

这将在 my-feature-cleanup 上进行两次提交。

git log my-feature-cleanup
02345 Something I did
32345 Another thing I did
etc...

祝你好运!