-->

Git的子树 - 子树先进的日期,但不能推(Git subtree - subtree up-to-

2019-06-21 18:11发布

我使用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 git@github.com:***
! [rejected]        72a6157733c4e0bf22f72b443e4ad3be0bc555ce -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:***'
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.

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

Answer 1:

我发现这个博客评论答案https://coderwall.com/p/ssxp5q

如果你遇到了“更新被拒绝,因为你的当前分支的尖端后面。合并远程的变化(例如‘git的拉’)”当你推(由于种种原因,尤与git的历史拧约)的问题那么你就需要嵌套的git命令,这样就可以强制推动的Heroku。 例如,在上述的例子:

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


Answer 2:

在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


Answer 3:

使用--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 push运行启动subtree split ,这重写你的提交历史进入这应该是准备推的格式。 事情是这样做到这一点,它去掉public/shared/关闭它有它的任何路径的前面,并删除有关不拥有它的文件的任何信息。 这意味着,即使你拉非压扁,因为他们的名字被他们的裸路径文件中的所有上行子仓库的更新被忽略。 (不接触任何文件提交下的public/shared/或合并是相同的父提交,也被倒塌[编辑:另外,因为我已经发现了一些南瓜检测,所以现在我想这是只有当你拉非压扁,然后简单的合并提交在另一个答案设法选择非压扁的路径,并丢弃压扁路径压扁描述。]),其结果是,它试图推动的东西,最终包含任何工作人承诺你从推动当前的主机存储库,但不工作的人直接提交到子库,或通过另一台主机存储库。

但是,如果你使用--onto ,那么所有的上游提交记录为确定逐字使用,所以当重写过程中遇到他们,因为它要改写合并的父母一方,这将让他们,而不是试图重写他们通常的方式。



Answer 4:

对于“GitHub的页面”类型的应用程序,在那里你部署“DIST”子树为GH-页面分公司,解决方案可能是这个样子

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

我提到这一点,因为它看起来从上面给出的例子的Heroku略有不同。 你可以看到,在我的回购的主分支存在我的“DIST”文件夹,然后我把它作为一个子到GH-页面分支这也是对产地。



Answer 5:

我以前也遇到过这个问题为好,这里是我如何解决它。

我发现是我有没有连接到本地主分支的一个分支。 这个分支存在,它只是挂在虚空。 在你的情况下,它可能是所谓的project-shared 。 假如是这样的话,当你做一个git branch ,你可以看到一个本地project-shared分支,那么你可以“ 追加 ”新提交到您现有的project-shared做一个分支:

git subtree split --prefix=public/shared --onto public-shared --branch public-shared

我理解的方式是git subtree将开始创建新的自支--onto ,在这种情况下,它的本地public-shared分支。 然后在该分支意味着创建一个分支,它只是取代了旧的public-shared分支。

这将使所有以前的SHA public-shared分支。 最后,你可以做一个

git push project-shared project-shared:master

假设你有一个project-shared远程为好; 这将推动当地挂在虚空 project-shared跳转到master远程分支project-shared



Answer 6:

这是因为原始算法的限制。 在处理上合并提交,原来的算法使用切断无关父母简化标准。 特别是,它会检查,如果有父母,具有相同的树。 如果发现了这样的父母,它会崩溃的合并提交,并使用父提交相反,假设其他家长无关的子树的变化。 在某些情况下,这会导致删除的历史,这有子树的实际变化的部分。 特别地,它会下降提交,这将触摸的子树的序列,但导致相同的子树的值。

让我们来看一个例子(你可以很容易地复制),以便更好地理解它是如何工作的。 请看下面的历史记录(行格式为:提交[树]主题):

% git log --graph --decorate --pretty=oneline --pretty="%h [%t] %s"
*   E [z] Merge branch 'master' into side-branch
|\
| * D [z] add dir/file2.txt
* | C [y] Revert "change dir/file1.txt"
* | B [x] change dir/file1.txt
|/
*   A [w] add dir/file1.txt

在这个例子中,我们是分裂的dir 。 提交DE具有相同的树z ,因为我们有承诺C ,其中撤消承诺B ,于是BC序列无助于dir ,即使它有更改。

现在,让我们做的分裂。 首先,我们劈在提交C

% git log `git subtree split -P dir C` ...
* C' [y'] Revert "change dir/file1.txt"
* B' [x'] change dir/file1.txt
* A' [w'] add dir/file1.txt

接下来,我们劈在提交E

% git log `git subtree split -P dir E` ...
* D' [z'] add dir/file2.txt
* A' [w'] add dir/file1.txt

是的,我们失去了两次提交。 努力推动第二裂,因为它不具备这两个提交,它已经钻进了原产地时,这将导致错误。

通常你可以通过使用容忍这种错误push --force ,因为下跌提交一般不会在他们的关键信息。 从长远来看,这个bug需要修复,因此分裂的历史居然会拥有所有的提交,其中触摸dir ,符合市场预期。 我希望修复,包括父母的更深入的分析犯了隐藏的依赖。

作为参考,这里是原代码的一部分,负责的行为。

copy_or_skip()
  ...
  for parent in $newparents; do
      ptree=$(toptree_for_commit $parent) || exit $?
      [ -z "$ptree" ] && continue
      if [ "$ptree" = "$tree" ]; then
          # an identical parent could be used in place of this rev.
          identical="$parent"
      else
          nonidentical="$parent"
      fi
  ...
  if [ -n "$identical" ]; then
      echo $identical
  else
      copy_commit $rev $tree "$p" || exit $?
  fi


Answer 7:

埃里克·伍德拉夫的回答并不能帮助我,但下面做:

我通常是“git的子树拉”与“--squash”选项。 看来这的确让事情更难调和,所以我需要做一个子树拉不挤压这段时间,解决一些冲突,然后按。

我要补充的是,压扁拉没有透露任何冲突,告诉我一切都OK。



Answer 8:

另一个[简单]的解决方案是通过使另一个承诺,如果你能推进远程的头。 你拉这种先进的头到本地子树后,那么你将能够从它再次推。



Answer 9:

您可以强制推送本地更改到远程树回购

git push subtree_remote_address.git `git subtree split --prefix=subtree_folder`:refs/heads/branch --force


Answer 10:

根据克里斯·乔丹的解决方案对于Windows用户快速的PowerShell

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


Answer 11:

所以这是我写的基于断什么@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


Answer 12:

有这个问题了。 下面是我做什么,根据上面的答案:

鉴于:

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

需要注意的令牌是“git的子树推”输出“混帐推”被使用。



文章来源: Git subtree - subtree up-to-date but can't push