git 变基后无法推送到分支
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15143042/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
can't push to branch after rebase
提问by Matt
We use git and have a master branch and developer branches. I need to add a new feature and then rebase the commits to master, then push master to CI server.
我们使用 git 并有一个 master 分支和 developer 分支。我需要添加一个新功能,然后将提交重新设置为 master,然后将 master 推送到 CI 服务器。
The problem is that if I have conflicts during rebase I cannot push to my remote developer branch (on Github) after the rebase is complete, until I pull my remote branch. This causes duplicate commits. When there are no conflicts, works as expected.
问题是,如果我在 rebase 期间遇到冲突,我无法在 rebase 完成后推送到我的远程开发人员分支(在 Github 上),直到我拉我的远程分支。这会导致重复提交。当没有冲突时,按预期工作。
question: after rebase and conflict resolution, how do I sync up my local and remote developer branches without creating duplicate commits
问题:在变基和解决冲突后,如何在不创建重复提交的情况下同步我的本地和远程开发人员分支
Setup:
设置:
// 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 '[email protected]: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
EDIT
编辑
So it sounds like this will break the workflow:
所以听起来这会破坏工作流程:
developer1 working on myNewFeature developer2 working on hisNewFeature both use master as main branch
developer1 在 myNewFeature 上工作 developer2 在 hisNewFeature 上工作都使用 master 作为主分支
developer2 merges myNewFeature into hisNewFeature
developer2 将 myNewFeature 合并到 hisNewFeature
developer1 rebases, resolves conflicts, then force pushes to remote branch for myNewFeature
developer1 变基,解决冲突,然后强制推送到 myNewFeature 的远程分支
a couple days later, developer2, merges myNewFeature into hisNewFeature again
几天后,developer2 再次将 myNewFeature 合并到 hisNewFeature
Will this cause the other developers to hate developer1?
这会导致其他开发人员讨厌 developer1 吗?
采纳答案by Trevor Norris
First, you and those you're working with need to agree whether a topic/devel branch is for shared development or just your own. Other developers know not to merge on my development branches because they'll be rebased at any time. Usually the workflow is as follows:
首先,您和与您一起工作的人需要就主题/开发分支是用于共享开发还是仅用于您自己的分支达成一致。其他开发人员知道不要在我的开发分支上合并,因为它们随时都会被重新定位。通常工作流程如下:
o-----o-----o-----o-----o-----o master
\
o-----o-----o devel0
\
o-----o-----o devel1
Then to stay up-to-date with remote I'll do the following:
然后为了与遥控器保持同步,我将执行以下操作:
git fetch origin
git checkout master
git merge --ff origin/master
I do this for two reasons. First because it allows me to see if there are remote changes without needing to switch from my devel branch. Second it's a safety mechanism to make sure I don't overwrite any un-stashed/committed changes. Also, if I can't fast-forward merge to the master branch that means either someone has rebased the remote master (for which they need to be flogged severely) or I accidentally committed to master and need to clean up my end.
我这样做有两个原因。首先是因为它允许我查看是否有远程更改,而无需从我的开发分支切换。其次,它是一种安全机制,可确保我不会覆盖任何未隐藏/提交的更改。另外,如果我不能快进合并到 master 分支,这意味着要么有人重新定位了远程 master(他们需要被严厉鞭打),要么我不小心提交了 master 并需要清理我的最后。
Then when remote has changes and I've fast forwarded to the latest I'll rebase:
然后当遥控器发生变化并且我已经快进到最新的我会变基:
git checkout devel0
git rebase master
git push -f origin devel0
Other developers then know they'll need to rebase their devel branches off my latest:
其他开发人员然后知道他们需要根据我的最新版本重新构建他们的开发分支:
git fetch <remote>
git checkout devel1
git rebase <remote>/devel0
Which results in much cleaner history:
这导致更清晰的历史:
o-----o master
\
o-----o-----o devel0
\
o-----o-----o devel1
Don'tmerge commits back and forth at your whim. Not only does it create duplicate commits and make history impossible to follow, finding regressions from a specific change becomes near impossible (which is why you're using version control in the first place, right?). The problem you're having is the result of doing just this.
不要随心所欲地来回合并提交。它不仅会创建重复提交并使历史无法跟踪,而且几乎不可能从特定更改中找到回归(这就是您首先使用版本控制的原因,对吗?)。您遇到的问题是这样做的结果。
Also it sounds like other developers may be making commits to your devel branches. Can you confirm this?
此外,听起来其他开发人员可能正在对您的开发分支进行提交。你能证实这一点吗?
The only time to merge is when your topic branch is ready to be accepted into master
.
合并的唯一时间是当您的主题分支准备好被接受到master
.
On a side note. If multiple developers are committing to the same repository you should all consider having named branches to distinguish between developers devel branches. For example:
在旁注。如果多个开发人员提交到同一个存储库,您都应该考虑使用命名分支来区分开发人员的开发分支。例如:
git branch 'my-name/devel-branch'
So all developers topic branches reside within their own nested set.
因此,所有开发人员主题分支都驻留在他们自己的嵌套集中。
回答by Learath2
You need to force the push as you have moved the commits further down the line git is expecting you to add commits to the tip of the branch. git push -f origin myNewFeature
will fix your problem.
您需要强制推送,因为您将提交进一步向下移动,git 期望您将提交添加到分支的尖端。git push -f origin myNewFeature
将解决您的问题。
Tip: Above is a legitimate usage of force pushing. Never ever rewrite the history on a publicly accessible repository or a lot of people will hate you.
提示:以上是强制推送的合法用法。永远不要在可公开访问的存储库上重写历史记录,否则很多人会讨厌你。
回答by Matthew Sanders
The main thing to keep in mind here is what pull and rebase are doing behind the scenes.
这里要记住的主要事情是 pull 和 rebase 在幕后所做的事情。
A pull will basically do two things: fetch and merge. When you include --rebase it will do a rebase instead of the merge.
拉动基本上会做两件事:获取和合并。当您包含 --rebase 时,它将执行 rebase 而不是合并。
A rebase is pretty much like stashing all of your local changes since you branched, fast forwarding your branch to the latest commit on the target, and unstashing your changes in order on top.
rebase 很像存储分支以来的所有本地更改,将分支快速转发到目标上的最新提交,并在顶部按顺序取消存储更改。
(This explains why you may get multiple conflict resolution prompts when doing a rebase vs the one conflict resolution you may get with a merge. You have the opportunity to resolve a conflict on EACH commit that is being rebased in order to otherwise preserve your commits.)
(这解释了为什么在执行 rebase 时您可能会收到多个冲突解决提示,而您可能会通过合并获得一个冲突解决方案。您有机会解决正在 rebase 的每个提交上的冲突,以便以其他方式保留您的提交。 )
You never want to push rebased changes to remote branches as this is rewritting history. Ofcoarse, never is a bit strong as there are almost always exceptions. The case that you need to maintain a remote version of your local repository to work on a specific environment for example.
您永远不想将重新定位的更改推送到远程分支,因为这是重写历史记录。Ofcoarse,从不强硬,因为几乎总是有例外。例如,您需要维护本地存储库的远程版本以在特定环境中工作的情况。
This will require you to push rebased changes at times either using force:
这将要求您有时使用强制推送重新调整的更改:
git push -f origin newfeature
Or in some cases your administrator may have removed the ability to force so you must delete and recreate:
或者在某些情况下,您的管理员可能已经删除了强制功能,因此您必须删除并重新创建:
git push origin :newfeature
git push origin newfeature
In either case you must be absolutely sure you know what you are doing if someone else is collaborating with you on your remote branch. This may mean that you work together initially with merges and rebase those into a more manageable commit format just before going to master and removing your working branch.
在任何一种情况下,如果其他人在您的远程分支上与您合作,您必须绝对确定自己知道自己在做什么。这可能意味着您最初与合并一起工作,并将它们重新设置为更易于管理的提交格式,然后再转到 master 和删除您的工作分支。
Remember you can almost always fallback on git's GC by taking advantage of:
请记住,您几乎总是可以通过利用以下优势来回退 git 的 GC:
git reflog
This is a HUGE life saver as you can reset back to a more stable state if you get lost in all of your rebase/conflict management.
这是一个巨大的救命稻草,因为如果您迷失在所有变基/冲突管理中,您可以重置回更稳定的状态。
回答by ThiefMaster
You need to perform a forced push, i.e. git push -f origin myNewFeature
您需要执行强制推送,即 git push -f origin myNewFeature
Oh, and you better make damn sure that people don't base anything on your dev branch - usually you aren't supposed to publish branches where you are rewriting history at all (or rather do not rewrite history once published). One way would be using a branch name like wip/myNewFeature
and then mentioning that wip
branches will be rebased to master from time to time.
哦,你最好确保人们不会在你的 dev 分支上建立任何东西——通常你不应该在重写历史的地方发布分支(或者更确切地说,一旦发布就不要重写历史)。一种方法是使用像这样的分支名称wip/myNewFeature
,然后提到wip
分支将不时重新定位为 master。
回答by cosmicFluke
The general answer that has already been given -- to use git push -f origin myNewFeature
when pushing rebased changes -- is a good starting place. I'm writing this answer to address the edit about whether it will break your workflow.
已经给出的一般答案——git push -f origin myNewFeature
在推送重新定位的更改时使用——是一个很好的起点。我写这个答案是为了解决关于它是否会破坏你的工作流程的编辑。
If we assume that you're going to be using git pull --rebase ...
(or some variation on that) followed by a force-push to the remote branch, then the thing that breaks the workflow in your example is developer2 is merging myNewFeature
into hisNewFeature
. It makes sense to be able to rebase your own feature branch as long as nobody else is working on that branch, so you need rules to demarcate branch territory.
如果我们假设您将要使用git pull --rebase ...
(或它的一些变体),然后强制推送到远程分支,那么在您的示例中破坏工作流程的事情是 developer2 正在合并myNewFeature
到hisNewFeature
. 只要没有其他人在该分支上工作,就可以重新设定您自己的功能分支的基础,因此您需要规则来划分分支区域。
You can get around this by a) establishing a rule that you only ever merge from master
, or b) creating a collective develop
branch, upon which you base your own myNewFeature
branch, and establish a rule that you only ever merge from develop
. master
will then be reserved only for milestones or releases (or however else you want to set that up), and develop
will be where you push each feature when it's ready to be integrated into other feature branches.
您可以通过 a) 建立一个只能从 合并的规则来解决这个问题master
,或者 b) 创建一个集体develop
分支,您可以以此为基础myNewFeature
建立自己的分支,并建立一个只能从 合并的规则develop
。 master
然后将仅保留给里程碑或版本(或者您想设置的其他任何内容),并且develop
当每个功能准备好集成到其他功能分支时,您将在此处推送每个功能。
I believe this could be considered a simplified version of the Gitflow workflow.
我相信这可以被视为 Gitflow 工作流程的简化版本。
回答by Sylvain Lesage
I agree with MrCholo, and maybe Trevor Norriscould consider updating its good answerto replace
我同意MrCholo,也许Trevor Norris可以考虑更新它的好答案来替换
git push -f origin devel0
with
和
git push --force-with-lease origin devel0