git 在变基后无法推到分支

kb5ga3dv  于 2023-03-28  发布在  Git
关注(0)|答案(7)|浏览(318)

我们使用git,有master分支和developer分支。我需要添加一个新特性,然后将提交重定向到master,然后将master推送到CI服务器。
问题是,如果我在rebase过程中有冲突,我无法在rebase完成后推送到我的远程开发者分支(在Github上),直到我拉取我的远程分支。这会导致重复提交。当没有冲突时,按预期工作。
问:在变基和冲突解决之后,我如何同步我的本地和远程开发人员分支而不创建重复的提交
设置:

// master branch is the main branch
git checkout master
git checkout -b myNewFeature

// I will work on this at work and at home
git push origin myNewFeature

// work work work on myNewFeature
// master branch has been updated and will conflict with myNewFeature
git pull --rebase origin master

// we have conflicts
// solve conflict
git rebase --continue

//repeat until rebase is complete
git push origin myNewFeature

//ERROR
error: failed to push some refs to 'git@github.com:ariklevy/dropLocker.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

// do what git says and pull
git pull origin myNewFeature

git push origin myNewFeature

// Now I have duplicate commits on the remote branch myNewFeature

编辑

听起来这会破坏工作流程:

developer1处理myNewFeature developer2处理hisNewFeature都使用master作为主分支
developer2将myNewFeature合并到他的NewFeature中
developer1重新定基,解决冲突,然后强制推送到myNewFeature的远程分支
几天后,developer2再次将myNewFeature合并到hisNewFeature中
这是否会导致其他开发人员讨厌developer1?

b91juud3

b91juud31#

首先,你和你的同事需要就topic/devel分支是用于共享开发还是只用于你自己的开发达成一致。其他开发人员知道不要合并我的开发分支,因为它们随时都会被重新定基。通常工作流程如下:

o-----o-----o-----o-----o-----o       master
 \
   o-----o-----o                      devel0
                \
                  o-----o-----o       devel1

然后,为了保持与remote的最新状态,我将执行以下操作:

git fetch origin
 git checkout master
 git merge --ff origin/master

我这样做有两个原因。第一,因为它允许我查看是否有远程更改,而不需要从devel分支切换。第二,这是一种安全机制,以确保我不会覆盖任何未隐藏/提交的更改。此外,如果我不能快进合并到master分支,这意味着有人重定了远程master分支的基(为此他们需要受到严厉的鞭打)或者我不小心犯了师父,需要清理我的结束。
然后,当remote有变化,我已经快进到最新的,我会rebase:

git checkout devel0
git rebase master
git push -f origin devel0

其他开发人员知道他们需要从我的最新版本中重定devel分支的基:

git fetch <remote>
git checkout devel1
git rebase <remote>/devel0

这会导致更清晰的历史记录:

o-----o                                 master
       \
         o-----o-----o                  devel0
                      \
                        o-----o-----o   devel1

不要随心所欲地来回合并提交。这不仅会创建重复的提交,使历史记录无法跟踪,而且从特定的更改中找到回归变得几乎不可能(这就是为什么你首先使用版本控制,对吗?)。你遇到的问题就是这样做的结果。

另外,听起来其他开发者可能会提交到你的devel分支,你能证实吗?
只有当你的主题分支准备好被master接受的时候才可以合并。
如果多个开发人员提交到同一个仓库,你应该考虑使用命名分支来区分开发人员的devel分支。例如:

git branch 'my-name/devel-branch'

因此所有开发人员主题分支都驻留在自己的嵌套集中。

bprjcwpo

bprjcwpo2#

你需要强制推送,因为你已经把提交移到了git希望你把提交添加到分支顶端的那一行。git push -f origin myNewFeature会解决你的问题。
提示:以上是强制推送的合法用法。永远不要重写可公开访问的存储库的历史,否则很多人会讨厌你。

6za6bjd0

6za6bjd03#

这里要记住的主要事情是pull和rebase在幕后做什么。
一个pull基本上会做两件事:fetch和merge。当你包含--rebase时,它会做一个rebase而不是merge。
一个rebase就像是把你分支后所有的本地修改都存放起来,把你的分支快速转发到目标上的最新提交,然后把你的修改按顺序释放到最上面。
(This解释了为什么你在做一个rebase的时候会得到多个冲突解决提示,而在合并的时候只会得到一个冲突解决提示。你有机会在每个被rebase的commit上解决一个冲突,以便保留你的commit。)
你永远不想把重定基的更改推送到远程分支,因为这是重写历史。Ofcoarse,never有点强,因为几乎总是有异常。例如,你需要维护本地仓库的远程版本才能在特定环境中工作。
这将要求您有时使用强制推送重定基更改:

git push -f origin newfeature

或者,在某些情况下,管理员可能已删除强制的功能,因此您必须删除并重新创建:

git push origin :newfeature
git push origin newfeature

无论是哪种情况,你都必须绝对确定如果有其他人在你的远程分支上与你合作,你知道你在做什么。这可能意味着你最初与合并一起工作,并在去master和删除你的工作分支之前将合并转换为更易于管理的提交格式。
记住,你几乎总是可以通过利用以下优势来回退到git的GC:

git reflog

这是一个巨大的生命保护程序,因为如果你迷失在所有的变基/冲突管理中,你可以重新设置回一个更稳定的状态。

p8ekf7hl

p8ekf7hl4#

您需要执行强制推送,即git push -f origin myNewFeature
哦,你最好确保人们不会基于你的开发分支做任何事情--通常你不应该发布你正在重写历史的分支(或者更确切地说,一旦发布就不要重写历史)。一种方法是使用像wip/myNewFeature这样的分支名称,然后提到wip分支将不时地被重定向到master。

vktxenjb

vktxenjb5#

已经给出的一般答案--在推送基于重定基的更改时使用git push -f origin myNewFeature--是一个很好的起点。
如果我们假设你要用git pull --rebase ...(或类似的),然后强制推送到远程分支,那么在您的示例中,破坏工作流的事情是developer 2正在将myNewFeature合并到hisNewFeature中。只要没有其他人在该分支上工作,就可以重定自己的特性分支的基,这是有意义的,所以你需要规则来划分分支领地。
您可以通过以下方法来解决这个问题:a)建立一个只从master合并的规则,或者b)创建一个集合的develop分支,您可以在此基础上创建自己的myNewFeature分支,并建立一个只从develop合并的规则。(或者你想设置的其他方式),当每个特性准备好被集成到其他特性分支时,develop将是你推送每个特性的地方。
我相信这可以被认为是Gitflow工作流的简化版本。

imzjd6km

imzjd6km6#

我同意MrCholo,也许Trevor Norris可以考虑更新它的good answer以替换

git push -f origin devel0

git push --force-with-lease origin devel0
wlwcrazw

wlwcrazw7#

因为这个线程是this google search的唯一结果,我只是这个命令是其中的任何人疯狂地滚动:

git reset --soft HEAD~1

取消提交您的更改,如果您运行git status,您的文件将不会被修改,它们将恢复为编辑后的样子

相关问题