功能分支重新设置后,Git 推送被拒绝

A--B--C------F--G  (master)
       \    
        D--E  (feature)
A--B--C------F--G  (master)
                 \
                  D'--E'  (feature)

答案

问题在于git push假定远程分支可以快速转发到您的本地分支,也就是说,本地和远程分支之间的所有区别都在于本地末尾有一些新的提交,如下所示:

Z--X--R         <- origin/some-branch (can be fast-forwarded to Y commit)
       \        
        T--Y    <- some-branch

当您执行git rebase提交 D 和 E 应用于新的基础,并创建新的提交。这意味着在重新设置基准之后,您将得到以下内容:

A--B--C------F--G--D'--E'   <- feature-branch
       \  
        D--E                <- origin/feature-branch

在这种情况下,远程分支无法快速转发到本地。虽然,理论上可以将本地分支合并到远程分支(显然,在这种情况下您不需要它),但是由于git push仅执行快进合并,因此会引发错误。

--force选项的作用只是忽略远程分支的状态,并将其设置为您要推送到其中的提交。因此git push --force origin feature-branch仅使用 local feature-branch覆盖origin/feature-branch feature-branch

在我看来,只要您是该分支上唯一的成员,就可以在master上对功能分支重新建立基础并将其强制推回到远程存储库中就可以了。

开发人员应使用 - f 或 --force 而不是 - f

--force-with-lease

为什么?因为它检查远程分支的更改,这绝对是个好主意。假设 James 和 Lisa 正在同一个功能分支上,而 Lisa 已推送了一次提交。詹姆斯现在重新建立了本地分支机构,并在尝试推送时被拒绝。当然,詹姆斯认为这是由于改组并使用 --force 造成的,并将重写 Lisa 的所有更改。如果詹姆斯使用了 “租用强制”,他将收到一条警告,指出有人进行了提交。我不明白为什么有人在重新定级后进行推送时会使用 --force 而不是 --force-with-lease。

我会改用 “checkout -b”,它更容易理解。

git checkout myFeature
git rebase master
git push origin --delete myFeature
git push origin myFeature

删除时,可以防止推送包含不同 SHA ID 的现有分支。在这种情况下,我仅删除远程分支。

一种解决方法是做 msysGit 的一下重订合并脚本执行 - 变基后,在老头合并feature-s ours 。您最终得到了提交图:

A--B--C------F--G (master)
       \         \
        \         D'--E' (feature)
         \           /
          \       --
           \    /
            D--E (old-feature)

...,您对feature将很快。

换句话说,您可以执行以下操作:

git checkout feature
git branch old-feature
git rebase master
git merge -s ours old-feature
git push origin feature

(未经测试,但我认为是对的...)

在这个分支上可能只有一种开发人员,也可能不是这种情况,即现在(在重新设置基准之后)不与源 / 功能内联。

因此,我建议使用以下顺序:

git rebase master
git checkout -b feature_branch_2
git push origin feature_branch_2

是的,新分支,这应该在没有 --force 的情况下解决此问题,我认为这通常是 git 的主要缺点。

我避免过分用力的方法是创建一个新分支,并继续对该新分支进行工作,并在保持一定稳定性之后,删除重新建立基础的旧分支:

  • 在本地重新建立已签出的分支
  • 从重新建立基础的分支到新分支
  • 将该分支作为新分支推送到远程。并删除远程上的旧分支

别人已经回答了您的问题。如果为分支重新设置基础,则需要强制推送该分支。

变基和共享存储库通常不会相处。这是重写历史。如果其他人正在使用该分支或已从该分支分支,则重新设置基准将非常不愉快。

通常,对本地分支机构管理来说,改组效果很好。远程分支管理最适合与显式合并(--no-ff)一起使用。

我们还避免将 master 合并到功能分支中。取而代之的是,我们改用母版,但使用新的分支名称(例如,添加版本后缀)。这避免了在共享存储库中重新设置基准的问题。

feature分支上的git merge master feature什么问题?这将保留您所做的工作,同时将其与主线分支分开。

A--B--C------F--G
       \         \
        D--E------H

编辑:抱歉没有阅读您的问题说明。在执行重新设置rebase将需要用力。所有修改历史记录的命令都将需要--force参数。这是一种故障保险,可以防止您丢失工作(旧的DE会丢失)。

因此,您执行了git rebase ,使树看起来像(尽管由于DE不再在命名分支中而部分隐藏):

A--B--C------F--G
       \         \
        D--E      D'--E'

因此,当尝试推送新feature分支(其中包含D'E' )时,您将丢失DE

以下对我有用:

git push -f origin branch_name

并且不会删除我的任何代码。

但是,如果要避免这种情况,可以执行以下操作:

git checkout master
git pull --rebase
git checkout -b new_branch_name

那么您就可以将所有提交樱桃挑选到新分支。 git cherry-pick COMMIT ID ,然后推送您的新分支。

对我来说,遵循简单的步骤即可:

1. git checkout myFeature
2. git rebase master
3. git push --force-with-lease
4. git branch -f master HEAD
5. git checkout master
6. git pull

完成上述所有操作后,我们还可以通过以下命令删除 myFeature 分支:

git push origin --delete myFeature