好的,我认为这是一个简单的git场景,我错过了什么?

我有一个主分支和一个特征分支。我在master上做了一些工作,在feature上做了一些工作,然后在master上做了一些工作。我最终得到了这样的东西(字典顺序暗示了提交的顺序):

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

我对git push origin master来保持远程master的更新没有问题,也没有git push origin feature(当在特性上时)来维护我的特性工作的远程备份。到目前为止,我们都很好。

但现在我想在master上的F- G提交的基础上rebase feature,所以我git checkout feature和git rebase master。还好。现在我们有:

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

问题:当我想备份新的基于git的推源特性分支的重基特性时,推被拒绝了,因为树已经因为重基而改变了。这只能用git的push -force origin特性来解决。

我讨厌在不确定自己是否需要的情况下使用武力。那么,我需要它吗?调整基地是否意味着下一步的行动应该是强有力的?

这个功能分支并没有与其他开发者共享,所以事实上我对强制推送没有任何问题,我不会丢失任何数据,问题更多的是概念性的。


当前回答

因为OP确实理解问题,只是寻找一个更好的解决方案…

把这个作为一个实践怎么样?

Have on actual feature-develop branch (where you never rebase and force-push, so your fellow feature developers don't hate you). Here, regularly grab those changes from main with a merge. Messier history, yes, but life is easy and no one get's interupted in his work. Have a second feature-develop branch, where one feature team member regulary pushes all feature commits to, indeed rebased, indeed forced. So almost cleanly based on a fairly recent master commit. Upon feature complete, push that branch on top of master.

这个方法可能已经有了一个模式名。

其他回答

问题是git push假设远程分支可以快进到你的本地分支,也就是说,本地分支和远程分支之间的所有区别都是在本地有一些新的提交,就像这样:

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

当你执行git rebase commit时,D和E会被应用到新的base并创建新的提交。这意味着在调整后,你会有这样的东西:

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

在这种情况下,远程分支不能快进到本地。虽然,理论上本地分支可以合并到远程分支(显然在这种情况下你不需要它),但由于git push只执行快进合并,它会抛出一个错误。

force选项的作用是忽略remote branch的state并将它设置为你推入的commit。所以git push——force origin feature-branch只是用local feature-branch覆盖了origin/feature-branch。

在我看来,只要你是唯一在这个分支上工作的人,就可以在master的基础上重新构建特性分支,并强制将它们推回远程存储库。

先道歉,这不是答案 按照惯例,这应该是一个答案,但我认为重要的是要强调,答案看起来不像使用rebase的正确方式(有些是有效的变通方法,但不像我们从git中期望的那样优雅)。

“git force”——是危险的,可能会覆盖别人的工作 创建新分支——将需要与其他在这个特性分支上工作的人同步,错过了使用git的重点。 重新创建分支(在使用或不使用一行魔法命令删除它之后),会遇到与#2相同的问题。 “git merge”- rebase被设计用来避免/防止日志中的合并提交,并保持git日志的干净和一致。


不幸的是,我还没有答案。 在以上两者之间,“git合并”是唯一一个对团队工作是安全的。


(编辑# 1) 根据这个伟大的文档由Atlassian rebase应该只用于您的本地工作

不要改变公众历史。 正如我们之前在重写历史中讨论过的那样,一旦提交被推入公共存储库,就不应该重新设置提交的基。rebase将用新的提交替换旧的提交,看起来就像项目历史的那一部分突然消失了一样。


(编辑# 2) 根据这个很好的解释,这是一种预期行为。这意味着您可能需要重新合并在原始提交中已经合并的内容。 如果torec是正确的,如果我得到的是正确的,那么我投票给好的老拉(获取/合并)流。

(编辑# 3) 根据不同的场景,以上这些都是正确的。如果你和朋友一起在一个特性分支上工作,不要“push -force”,而是获取并合并origin/feature1。如果你一个人在树枝上工作,你可以“用力”,享受一段漂亮的原木。

其他人已经回答了你的问题。如果你重新设置一个分支,你将需要强制推动该分支。

Rebase和共享存储库通常不能共存。这是在改写历史。如果其他人正在使用该分支或已经从该分支分支,那么rebase将是非常不愉快的。

一般来说,rebase对本地分支机构管理效果很好。远程分支管理最好使用显式合并(——no-ff)。

我们还避免将master合并到一个特性分支中。相反,我们将改名为master,但是使用一个新的分支名称(例如添加一个版本后缀)。这避免了在共享存储库中重基的问题。

以下是我的工作:

Git push -f origin branch_name

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

但是,如果你想避免这种情况,你可以做以下事情:

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

然后,您可以挑选所有提交到新分支的文件。 git选择COMMIT ID 然后推你的新树枝。

我会这样做

rebase feature
git checkout -b feature2 origin/feature
git push -u origin feature2:feature2
Delete the old remote branch feature
git push -u origin feature:feature

现在远程将有功能(基于最新的主人)和feature2(与旧主人头)。这可以让你以后比较,如果你在旋转冲突中犯了错误。