将git子树更改推送到上游存储库失败

Jef*_*.D. 8 git push git-push git-subtree

我试图确保git的子树在我合并到我的项目之前对我有用.将子树更改推送到上游存储库时遇到问题.

设置是我有两个repos,sub并且main,main包括subrepo作为subtree.

然后我做以下事情:

  1. 使用初始提交初始化两个repos.
  2. sub直接更新仓库(即外部main).
  3. submainrepo中更新repo.
  4. 将更改拆分为sub(使用git subtree split)到一个单独的分支,然后我签出.
  5. 尝试将上游推向sub回购.当然,这种推动被拒绝,因为它将失去直接更新sub.
  6. sub回购中提取新的更改.
  7. 尝试将上游推向sub回购.这一次,它应该工作,但事实并非如此.

我写了一个封装这个问题的脚本.我正在使用git版本1.8.2.1并subtree启用了模块.这是脚本:

#!/bin/bash

echo -n "Wiping old repositories..."
rm -rf main sub sub-home
echo "done"

echo -n "Initializing main and sub repositories..."
mkdir sub-home
( cd sub-home ; git init -q --bare )
git clone sub-home sub > /dev/null 2>&1
( cd sub ; echo subfile > subfile ; git add subfile ;
  git commit -qm "adding root-level file to sub-project" ;
  git push -q origin master )
mkdir main
( cd main ; git init -q ; echo file > file ; git add file ;
  git commit -qm "adding root-level file to main-project" )
echo "done"

echo -n "Adding sub project as a subtree into main project..."
WD=$PWD
( cd main ; git remote add sub-remote file://$WD/sub-home ;
  git subtree add -P sub sub-remote master >/dev/null 2>&1 )
echo "done"

echo -n "Committing to sub-project directly..."
( cd sub ; date > the-date ; git add the-date ;
  git commit -qm "adding the-date to sub-project"
  git push -q origin master )
echo "done"

echo -n "Committing to sub-project from within main project..."
( cd main ; echo 'subfile what?' > sub/subfile ; git add sub/subfile ;
  git commit -qm "changing sub-project from within the main project" )
echo "done"

cd main
git subtree split -q -P sub -b split-branch >/dev/null
git checkout -q split-branch
echo -e "\nPushing from main subtree to sub project, which should fail:"
git push sub-remote master
echo -e "\nBut if we pull first..."
git pull -q --no-edit sub-remote master
echo "...then a push *should* work (but it doesn't):"
git push sub-remote master
cd ..
Run Code Online (Sandbox Code Playgroud)

这是输出:

$ ./test.sh
Wiping old repositories...done
Initializing main and sub repositories...done
Adding sub project as a subtree into main project...done
Committing to sub-project directly...done
Committing to sub-project from within main project...done

Pushing from main subtree to sub project, which should fail:
To file:///tmp/git/sub-home
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'file:///tmp/git/sub-home'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first merge the remote changes (e.g.,
hint: 'git pull') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

But if we pull first...
...then a push *should* work (but it doesn't):
To file:///tmp/git/sub-home
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'file:///tmp/git/sub-home'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and merge the remote changes
hint: (e.g. 'git pull') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Run Code Online (Sandbox Code Playgroud)

进一步的git pull命令(来自split-branch分支main)简单地说"已经是最新的".

对我来说真正令人困惑的是,据我所知,该git push命令应该真正为上游repo提供快进提交,如下面的git log输出所示:

$ ( cd main ; git log )
commit 357fe9fb42f5d122338940eb4f22d3ca9d276318
Merge: 472904f cb5d1d3
Author: Jeff Terrell <jeff.terrell@acm.org>
Date:   Fri Apr 19 16:03:03 2013 -0400

    Merge branch 'master' of file:///tmp/git/sub-home into split-branch

commit 472904f432c3a0a89acde02691b8281ac5246fd1
Author: Jeff Terrell <jeff.terrell@acm.org>
Date:   Fri Apr 19 16:03:02 2013 -0400

    changing sub-project from within the main project

commit cb5d1d34ce56374f78c98c5b3f3daa314907b62d
Author: Jeff Terrell <jeff.terrell@acm.org>
Date:   Fri Apr 19 16:03:02 2013 -0400

    adding the-date to sub-project

commit 7d1942203d30e0d9e8663517e6d594545bc50640
Author: Jeff Terrell <jeff.terrell@acm.org>
Date:   Fri Apr 19 16:03:02 2013 -0400

    adding root-level file to sub-project
$ (cd sub ; git log )
commit cb5d1d34ce56374f78c98c5b3f3daa314907b62d
Author: Jeff Terrell <jeff.terrell@acm.org>
Date:   Fri Apr 19 16:03:02 2013 -0400

    adding the-date to sub-project

commit 7d1942203d30e0d9e8663517e6d594545bc50640
Author: Jeff Terrell <jeff.terrell@acm.org>
Date:   Fri Apr 19 16:03:02 2013 -0400

    adding root-level file to sub-project
Run Code Online (Sandbox Code Playgroud)

以下是我的问题(最后):

  1. 为什么这个推被拒绝了?
  2. 我能做些什么呢?(如果使用该--force选项是答案,我怎么能确定我没有做破坏性的事情?)
  3. 有没有更好的方法来使用该subtree模块来避免这个问题?(注意:我不愿意使用子模块.)

Chr*_*ial 8

你的问题与之无关git subtree.你有好老的棘手的git ui的问题.在这种情况下git push.你显然假设它的语法如下git pull.这很天真 - 你正在使用git;).

你推输出告诉你这里有什么问题:

To file:///tmp/git/sub-home
! [rejected]        master -> master (non-fast-forward)
Run Code Online (Sandbox Code Playgroud)

git pull sub-remote mastersub-remote/master正如您所期望的那样,将头部提取并合并到当前已检出的分支中.但是git push sub-remote master不会将你签出的分支机构的头部推入sub-remote/master.它确实推动了同名的分支.所以在这种情况下master,正如您在上面的输出中所看到的那样.

git help push(语法git push <repsitory> <refspec>):

<refspec>参数的格式是可选的加+,后跟源ref <src>,后跟冒号:,后跟目标引用<dst>.它用于指定远程存储库中<src><dst>ref要更新的对象.

<dst>讲述,其参考在远程侧与该推更新.这里不能使用任意表达式,必须命名实际的ref.如果:<dst>省略,<src>则将更新相同的ref .

所以你要找的命令是git push sub-remote splitbranch:master.但是你为什么不git subtree push首先使用?

  • 这有效; 非常感谢!我赐给你赏金,就像我的意思一样说谢谢.:-)并回答你的问题,我使用`git subree push`(我不记得是什么)有一些问题,所以我想把我的困境减少到最简单的问题.但是,`git subree pull -P sub sub-remote master`后跟`git subree push -P sub sub-remote master`为我工作.现在来调查`--squash`选项...... (2认同)