Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git子树导出和重新导入的困境_Git_Git Subtree - Fatal编程技术网

Git子树导出和重新导入的困境

Git子树导出和重新导入的困境,git,git-subtree,Git,Git Subtree,我有一个更大的git存储库a,它与我的另一个项目B共享一定数量的代码。为了使维护更容易,我决定使用第三个存储库,其中包含公共代码C,然后通过git子树使用它 我在一个文件夹中准备了所有东西,将公共代码放在文件夹子中,并使用中描述的过程创建C 现在我有了C,它只有几个提交,我想把它放回一个子文件夹中。我使用了中描述的方法,只要子文件夹的所有提交现在都被复制。我不太介意这个,但是现在我不知道如何继续使用这个子目录 我在A/sub中做了额外的更改,希望将其推送到C。如我使用的中所述 创建仅包含子树的分

我有一个更大的git存储库a,它与我的另一个项目B共享一定数量的代码。为了使维护更容易,我决定使用第三个存储库,其中包含公共代码C,然后通过git子树使用它

我在一个文件夹中准备了所有东西,将公共代码放在文件夹子中,并使用中描述的过程创建C

现在我有了C,它只有几个提交,我想把它放回一个子文件夹中。我使用了中描述的方法,只要子文件夹的所有提交现在都被复制。我不太介意这个,但是现在我不知道如何继续使用这个子目录

我在A/sub中做了额外的更改,希望将其推送到C。如我使用的中所述

创建仅包含子树的分支。这需要一点时间,但会成功完成。做

git checkout split-branch
git push remote-c master
给我

failed to push some refs to "remote-c"
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.
但是一位git pull remote-c大师说我已经是最新的了

我如何解决这种情况

EDIT1:我试图用一个小测试脚本重现这个问题。执行此脚本:

( cd testC; git init --bare )
( cd testA; git init )

cd testA
git remote add C ../testC

mkdir sub
echo subFile1 > sub/subFile1
echo subFile2 > sub/subFile2
git add sub
git commit -m "adding files"

echo FileA > fileA
echo FileB > fileB
git add fileA fileB
git commit -m "add root level files"

# extract subtree and push to C
git subtree split -P sub -b split-branch
git push C split-branch:master

# try to make an update in C
git checkout -b cmaster C/master
echo subFile2new > subFile2
git commit subFile2 -m "updated #2 in C"
git push
这导致

To ../testC
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to '../testC'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. If you did not intend to push that branch, you may want to
hint: specify branches to push or set the 'push.default' configuration
hint: variable to 'current' or 'upstream' to push only the current branch.
我尝试了一个git push-f,它似乎很有效。仍然想知道到底发生了什么以及为什么。

git push的默认行为是,如果本地和远程具有相同的命名分支,则尝试将所有分支推送到当前远程分支。从git推送手册:

特殊的refspec:或+:允许非快进更新 指示git推送匹配的分支:对于每个 存在于本地端,如果 远程端已存在相同的名称。这是 如果未找到明确的REFSECE,则默认操作模式为 既不在命令行上,也不在 对应的远程文件--请参见下文,无push.default 已设置配置变量

在这种情况下,由于您当前的遥控器是C,并且您同时拥有本地主机和远程C/master,因此将推送该遥控器,并且由于树完全不匹配,推送将失败,并显示master->master non fast forward消息

当你点击你的分支时,它会说是最新的,因为你正在点击你当前的分支,这是最新的


要修改git push的这种行为,需要在git配置中设置push.default值。在我的解决方案:升级git中查找push.default:-

假设testA和testC目录已经存在,那么您的测试脚本就成功了。我使用的是git v1.8.2.1的最新版本,所以在你发布这篇文章之后,他们可能已经修复了一些东西

$ mkdir testA testC
$ ./test.sh 
Initialized empty Git repository in /tmp/git/testC/
Initialized empty Git repository in /tmp/git/testA/.git/
[master (root-commit) 3d5644d] adding files
 2 files changed, 2 insertions(+)
 create mode 100644 sub/subFile1
 create mode 100644 sub/subFile2
[master 398c203] add root level files
 2 files changed, 2 insertions(+)
 create mode 100644 fileA
 create mode 100644 fileB
Created branch 'split-branch'
57fe3e8fc226d854b623f11444d82dc77fd45682
Counting objects: 4, done.
Delta compression using up to 16 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 269 bytes, done.
Total 4 (delta 0), reused 0 (delta 0)
To ../testC
 * [new branch]      split-branch -> master
Branch cmaster set up to track remote branch master from C.
Switched to a new branch 'cmaster'
[cmaster 07c7c89] updated #2 in C
 1 file changed, 1 insertion(+), 1 deletion(-)
Counting objects: 5, done.
Delta compression using up to 16 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 285 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ../testC
   57fe3e8..07c7c89  cmaster -> master

如果我理解您的意图,我认为git子模块比常量子树合并/提取更好我试过一次,但仍然做噩梦。仅供参考,描述了我在子模块方面的一些问题。这确实是一篇很好的文章,我在中引用了,我仍然会在您的案例中推荐它们,尽管我们在不久前尝试过子模块以获得类似的方法。这导致了严重的反作用,以至于再也没有人想碰子模块了。问题是,我的项目涉及很多在git方面经验有限的人,有时任何VCS和子模块都需要一点温和的技巧。显然子树也是如此;-虽然理论上子模块在这里是完美的,但它们的缺点太高,我们无法接受。小心,您可能已经将C/master推入了本地存储库的主分支。
$ mkdir testA testC
$ ./test.sh 
Initialized empty Git repository in /tmp/git/testC/
Initialized empty Git repository in /tmp/git/testA/.git/
[master (root-commit) 3d5644d] adding files
 2 files changed, 2 insertions(+)
 create mode 100644 sub/subFile1
 create mode 100644 sub/subFile2
[master 398c203] add root level files
 2 files changed, 2 insertions(+)
 create mode 100644 fileA
 create mode 100644 fileB
Created branch 'split-branch'
57fe3e8fc226d854b623f11444d82dc77fd45682
Counting objects: 4, done.
Delta compression using up to 16 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 269 bytes, done.
Total 4 (delta 0), reused 0 (delta 0)
To ../testC
 * [new branch]      split-branch -> master
Branch cmaster set up to track remote branch master from C.
Switched to a new branch 'cmaster'
[cmaster 07c7c89] updated #2 in C
 1 file changed, 1 insertion(+), 1 deletion(-)
Counting objects: 5, done.
Delta compression using up to 16 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 285 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ../testC
   57fe3e8..07c7c89  cmaster -> master