我们使用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?
7条答案
按热度按时间b91juud31#
首先,你和你的同事需要就topic/devel分支是用于共享开发还是只用于你自己的开发达成一致。其他开发人员知道不要合并我的开发分支,因为它们随时都会被重新定基。通常工作流程如下:
然后,为了保持与remote的最新状态,我将执行以下操作:
我这样做有两个原因。第一,因为它允许我查看是否有远程更改,而不需要从devel分支切换。第二,这是一种安全机制,以确保我不会覆盖任何未隐藏/提交的更改。此外,如果我不能快进合并到master分支,这意味着有人重定了远程master分支的基(为此他们需要受到严厉的鞭打)或者我不小心犯了师父,需要清理我的结束。
然后,当remote有变化,我已经快进到最新的,我会rebase:
其他开发人员知道他们需要从我的最新版本中重定devel分支的基:
这会导致更清晰的历史记录:
不要随心所欲地来回合并提交。这不仅会创建重复的提交,使历史记录无法跟踪,而且从特定的更改中找到回归变得几乎不可能(这就是为什么你首先使用版本控制,对吗?)。你遇到的问题就是这样做的结果。
另外,听起来其他开发者可能会提交到你的devel分支,你能证实吗?
只有当你的主题分支准备好被
master
接受的时候才可以合并。如果多个开发人员提交到同一个仓库,你应该考虑使用命名分支来区分开发人员的devel分支。例如:
因此所有开发人员主题分支都驻留在自己的嵌套集中。
bprjcwpo2#
你需要强制推送,因为你已经把提交移到了git希望你把提交添加到分支顶端的那一行。
git push -f origin myNewFeature
会解决你的问题。提示:以上是强制推送的合法用法。永远不要重写可公开访问的存储库的历史,否则很多人会讨厌你。
6za6bjd03#
这里要记住的主要事情是pull和rebase在幕后做什么。
一个pull基本上会做两件事:fetch和merge。当你包含--rebase时,它会做一个rebase而不是merge。
一个rebase就像是把你分支后所有的本地修改都存放起来,把你的分支快速转发到目标上的最新提交,然后把你的修改按顺序释放到最上面。
(This解释了为什么你在做一个rebase的时候会得到多个冲突解决提示,而在合并的时候只会得到一个冲突解决提示。你有机会在每个被rebase的commit上解决一个冲突,以便保留你的commit。)
你永远不想把重定基的更改推送到远程分支,因为这是重写历史。Ofcoarse,never有点强,因为几乎总是有异常。例如,你需要维护本地仓库的远程版本才能在特定环境中工作。
这将要求您有时使用强制推送重定基更改:
或者,在某些情况下,管理员可能已删除强制的功能,因此您必须删除并重新创建:
无论是哪种情况,你都必须绝对确定如果有其他人在你的远程分支上与你合作,你知道你在做什么。这可能意味着你最初与合并一起工作,并在去master和删除你的工作分支之前将合并转换为更易于管理的提交格式。
记住,你几乎总是可以通过利用以下优势来回退到git的GC:
这是一个巨大的生命保护程序,因为如果你迷失在所有的变基/冲突管理中,你可以重新设置回一个更稳定的状态。
p8ekf7hl4#
您需要执行强制推送,即
git push -f origin myNewFeature
哦,你最好确保人们不会基于你的开发分支做任何事情--通常你不应该发布你正在重写历史的分支(或者更确切地说,一旦发布就不要重写历史)。一种方法是使用像
wip/myNewFeature
这样的分支名称,然后提到wip
分支将不时地被重定向到master。vktxenjb5#
已经给出的一般答案--在推送基于重定基的更改时使用
git push -f origin myNewFeature
--是一个很好的起点。如果我们假设你要用
git pull --rebase ...
(或类似的),然后强制推送到远程分支,那么在您的示例中,破坏工作流的事情是developer 2正在将myNewFeature
合并到hisNewFeature
中。只要没有其他人在该分支上工作,就可以重定自己的特性分支的基,这是有意义的,所以你需要规则来划分分支领地。您可以通过以下方法来解决这个问题:a)建立一个只从
master
合并的规则,或者b)创建一个集合的develop
分支,您可以在此基础上创建自己的myNewFeature
分支,并建立一个只从develop
合并的规则。(或者你想设置的其他方式),当每个特性准备好被集成到其他特性分支时,develop
将是你推送每个特性的地方。我相信这可以被认为是Gitflow工作流的简化版本。
imzjd6km6#
我同意MrCholo,也许Trevor Norris可以考虑更新它的good answer以替换
与
wlwcrazw7#
因为这个线程是this google search的唯一结果,我只是这个命令是其中的任何人疯狂地滚动:
取消提交您的更改,如果您运行
git status
,您的文件将不会被修改,它们将恢复为编辑后的样子