为什么我不能推送这个最新的Git子树?

问题描述 投票:82回答:12

我正在将Git子树与正在处理的几个项目一起使用,以便在它们之间共享一些基本代码。基本代码会经常更新,并且升级可以在任何项目中进行,并且最终所有项目都会被更新。

我遇到了一个问题,其中git报告我的子树是最新的,但是推送被拒绝。例如:

#! git subtree pull --prefix=public/shared project-shared master
From github.com:****
* branch            master     -> FETCH_HEAD
Already up-to-date.

如果我进行推送,我会收到一条消息,没有其他内容可以推送...对吗?对? :(

#! git subtree push --prefix=public/shared project-shared master
git push using:  project-shared master
To [email protected]:***
! [rejected]        72a6157733c4e0bf22f72b443e4ad3be0bc555ce -> master (non-fast-forward)
error: failed to push some refs to '[email protected]:***'
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.

这可能是什么原因?为什么推送失败?

git git-subtree
12个回答
92
投票

我在此博客评论https://coderwall.com/p/ssxp5q中找到了答案

如果您遇到“由于当前分支的提示是背后。推送时合并远程更改(例如'git pull')“问题(由于不管什么原因,特别是git历史记录),那么您需要嵌套git命令,以便您可以强制推送到heroku。例如,以上述示例为例:

git push heroku `git subtree split --prefix pythonapp master`:master --force

0
投票

基于克里斯·乔丹的解决方案为Windows用户提供的快速Powershell

$id = git subtree split --prefix pythonapp master
Write-Host "Id is: $id"
Invoke-Expression "git push heroku $id`:master --force"

0
投票

所以这就是我根据@entheh所说的内容写的。

for /f "delims=" %%b in ('git subtree split --prefix [name-of-your-directory-on-the-file-system-you-setup] -b [name-of-your-subtree-branch]') do @set token=%%b
git push [alias-for-your-subtree] %token%:[name-of-your-subtree-branch] --force

pause

0
投票

也有这个问题。根据最高答案,这就是我所做的事情:

给出:

#! git subtree push --prefix=public/shared project-shared master
git push using:  project-shared master
To [email protected]:***
! [rejected]        72a6157733c4e0bf22f72b443e4ad3be0bc555ce -> master (non-fast-forward)
error: failed to push some refs to '[email protected]:***'
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.

34
投票

在Windows上,嵌套命令不起作用:

git push heroku `git subtree split --prefix pythonapp master`:master --force

您可以先运行嵌套位:

git subtree split --prefix pythonapp master

将(在很多数字之后)返回令牌,例如

157a66d050d7a6188f243243264c765f18bc85fb956

在包含的命令中使用它,例如:

git push heroku 157a66d050d7a6188f243243264c765f18bc85fb956:master --force

29
投票

使用--onto标志:

# DOESN'T WORK: git subtree push --prefix=public/shared project-shared master --onto=project-shared/master

[[编辑:不幸的是subtree push不会将--onto转发到底层的split,因此必须在两个命令中完成操作!完成此操作后,我发现我的命令与其他答案之一相同,但是解释有所不同,因此我还是将其保留在此处。]

git push project-shared $(git subtree split --prefix=public/shared --onto=project-shared/master):master

或者如果您不使用bash:

git subtree split --prefix=public/shared --onto=project-shared/master
# This will print an ID, say 0123456789abcdef0123456789abcdef,
# which you then use as follows:
git push project-shared 01234567:master

我花了几个小时仔细研究git-subtree源以弄清楚这一点,所以希望您对此表示满意;)

subtree push首先运行subtree split,它将您的提交历史重写为应准备好推送的格式。这样做的方法是,将public/shared/从具有该路径的任何路径的开头删除,并删除有关不具有该路径的文件的任何信息。 这意味着,即使不拉动,所有上游子存储库的提交也都将被忽略,因为它们通过裸路径命名文件。(不会触碰public/shared/下的任何文件或合并提交的提交[编辑:此外,我还发现了一些壁球检测功能,所以现在我想这是仅当您不挤压时才进行挤压,然后进行简单的合并提交折叠,另一个答案设法选择了非压缩路径,并丢弃了压缩路径。]结果是,它尝试推送的内容最终包含了有人致力于您要推送的当前主机存储库的工作,但没有工作人员直接提交到子存储库或通过另一个主机存储库提交。

但是,如果您使用--onto,则所有上游提交都记录为OK以便使用逐字记录,因此当重写过程遇到它们作为要重写的合并的父项之一时,它将保留它们尝试以常规方式重写它们。


12
投票

对于“ GitHub页面”类型的应用程序,在其中将“ dist”子树部署到gh-pages分支上,解决方案可能看起来像这样:>

git push origin `git subtree split --prefix dist master`:gh-pages --force

我之所以这样说是因为它看起来与上面给出的heroku示例略有不同。您可以看到我的“ dist”文件夹存在于我的仓库的master分支上,然后将它作为子树推送到gh-pages分支上,该分支也位于原处。


3
投票

我之前也遇到过这个问题,这就是我解决的方法。


2
投票

这是由于原始算法的限制。在处理合并提交时,原始算法使用简化的标准来切断不相关的父母。特别是,它检查是否有父树具有相同的树。如果找到这样的父级,则假定其他父级具有与子树无关的更改,它将折叠合并提交并改为使用父级提交。在某些情况下,这将导致丢弃部分历史记录,从而对子树进行了实际更改。特别是它将丢弃提交的序列,这些序列将接触子树,但导致相同的子树值。

让我们看一个示例(您可以轻松地复制它)以更好地了解其工作原理。考虑以下历史记录(行格式为:commit [tree] subject):


0
投票

[Eric Woodruff的回答没有帮助我,但以下内容帮了我]:>

我通常使用'--squash'选项进行'git subtree pull'。看来这确实使事情更难调和,所以我这次需要进行子树提取而不需要挤压,解决一些冲突然后再推送。

我必须补充说,拉力没有显示任何冲突,告诉我一切都很好。


0
投票

另一个[简单]的解决方案是,如果可以的话,通过再次提交来推进遥控器的头部。将这个高级头像拉入本地子树后,您将能够再次从中推送。


0
投票

您可以强制将本地更改推送到远程子树存储库

© www.soinside.com 2019 - 2024. All rights reserved.