70

我有一个分支,它应该可供其他贡献者使用,并且应该不断与主人保持同步。

不幸的是,每次我执行“git rebase”然后尝试推送时,都会导致“非快进”消息和推送中止。在这里推送的唯一方法是使用--force。这是否意味着如果我的分支公开并且其他人正在处理它,我应该使用“git merge”而不是变基?

4

2 回答 2

102

关于 git 如何工作的一些说明(非技术性):

当你变基时,git 接受有问题的提交,并在干净的历史记录之上“重新提交”它们。这是为了防止历史显示:

Description: tree -> mywork -> merge -> mywork -> merge -> mywork -> merge
Commit SHA1: aaaa -> bbbb   -> cccc  -> dddd   -> eeee  -> ffff   -> gggg

在 rebase 之后,它可能看起来像这样(或类似):

Description: tree -> rebase
Commit SHA1: aaaa -> hhhh

问题是您尝试推出的新提交不是您要推送到的分支尖端的提交的后代。

现在,您知道提交中包含相同的信息,但 git 不仅负责覆盖那些提交(上面示例中的 bbbb-gggg)。


共享回购模型

如果您使用的是共享存储库,那么这样的事情可能会变得非常混乱。让我解释一下为什么。假设另一个开发人员关闭了分支,他们在他们的分支中提交了aaaa -> gggg。然后他们做出提交iiii

同时,你重新设置并强制推送,导致树看起来像这样:

Description: tree -> rebase
Commit SHA1: aaaa -> hhhh

当其他开发人员尝试推送时,他会收到“非快进”消息。当他进行合并时,两个历史都重新链接在一起,你最终会一团糟

像这样的东西(混乱):

Description: tree -> rebase -> mywork -> merge -> mywork -> merge -> mywork -> merge -> devwork -> merge 
Commit SHA1: aaaa -> hhhh   -> bbbb   -> cccc  -> dddd   -> eeee  -> ffff   -> gggg -> iiii    -> jjjj

换句话说,如果其他人在拉和推,最好坚持使用 git merge,或者避免在 rebase 之后推送(并且只对你的工作进行 rebase)。


公开可见的存储库模型

也许您正在使用不同的(更混乱的)模型,您只是希望人们能够从您的存储库中提取。在这种情况下, git push --force 并不算太糟糕,因为这样他们就可以跟上它。在将补丁提供给您之前,他们可以重新调整他们的更改以在您的更改之上。它可以防止您的回购变得一团糟。

但是,您可能有更好的方法。 git push --镜像

来自 http://www.kernel.org/pub/software/scm/git/docs/git-push.html

不是命名要推送的每个 ref,而是指定将 $GIT_DIR/refs/ 下的所有 refs(包括但不限于 refs/heads/、refs/remotes/ 和 refs/tags/)镜像到远程存储库。新创建的本地 refs 会被推送到远端,本地更新的 refs 会在远端强制更新,删除的 refs 会从远端移除。如果设置了配置选项 remote..mirror,这是默认设置。


git的一大优点是它非常灵活并且允许许多不同类型的工作流。但它真正的优势在于它是一个分布式模型,所以我相信通过这种方式使用它可以获得最大的投资回报率。

于 2009-02-18T05:37:26.640 回答
2

不,rebase 对于公共存储库是完全合法的,甚至可能需要保持历史流畅。请记住,您不得使用 rebase 重写远程发布提交的历史记录。也就是说,rebase 只能应用于您自己的、本地的、您从未发布过的提交。您在获取时使用 rebase 将您的提交放在它们之上,然后也许在那里调整它们。您可能会收到此类消息的另一个原因是您推送的分支已更新并且您需要同步——在您获取的内容之上获取并重新设置您的提交。

于 2013-01-11T10:30:24.500 回答