git rebase 和 git push : non-fast forward, 为什么要用?

标签 git merge rebase

我有一个分支,它应该对其他贡献者可用,并且应该不断地与 master 保持同步。

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

最佳答案

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

当你 rebase 时,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)。


共享 repo 模型

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

与此同时,您重新定位并强制推送,导致树看起来像这样:

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

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

像这样(凌乱):

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

换句话说,如果其他人正在 pull 和 push ,那么您最好坚持使用 git merge,或者避免 push 直到 rebase 之后(并且只 rebase 您的工作)。


公开可见的存储库模型

也许您正在使用不同的(更 gittish)模型,您只是希望人们能够从您的存储库中提取数据。在这种情况下, git push --force 还不错,因为这样他们就可以处理跟上它。在向您提供补丁之前,他们可以重新设置他们的更改 以在您的更改之上。它可以防止您的存储库变得一团糟。

不过,您可能有更好的方法。 git push --mirror

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

Instead of naming each ref to push, specifies that all refs under $GIT_DIR/refs/ (which includes but is not limited to refs/heads/, refs/remotes/, and refs/tags/) be mirrored to the remote repository. Newly created local refs will be pushed to the remote end, locally updated refs will be force updated on the remote end, and deleted refs will be removed from the remote end. This is the default if the configuration option remote..mirror is set.


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

关于git rebase 和 git push : non-fast forward, 为什么要用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/559917/

相关文章:

git 添加不同目录下的文件

git - 为什么无论我是否运行 git add,当我切换分支(修改、添加、删除文件)时,git 一直显示我的更改?

ruby-on-rails - 在 Capistrano 中部署 Git 子目录

python - 使用 pip 从存储库安装软件包时,(s)witch、(i)gnore、(w)ipe、(b)ackup 选项是什么意思?

javascript - 如何使用Lodash根据一个键合并两个集合?

git - 是否可以在 git 中对特定文件进行 rebase ?

git - 无法解决 rebase 冲突

r - R 中合并中的循环多列

r - 合并表: classify output according to how rows where joined

git - 如何用 Git 将一个分支一分为二?