在将 git 的子树合并到我的项目中之前,我试图确保它对我有用。将子树更改推送到上游存储库时遇到问题。
设置是我有两个存储库sub
和main
, 并且将存储库main
包含sub
为subtree
.
然后我执行以下操作:
- 使用初始提交初始化两个存储库。
- 直接更新
sub
repo(即在 之外main
)。 sub
从 repo 中更新main
repo。sub
将(使用)的更改拆分git subtree split
为一个单独的分支,然后我将其签出。- 尝试将上游推送到
sub
repo。自然,此推送会被拒绝,因为它会丢失对sub
. - 从
sub
repo 中提取新的更改。 - 尝试将上游推送到
sub
repo。这一次,它应该工作,但它没有。
我写了一个脚本来封装这个问题。我正在使用subtree
启用了模块的 git 版本 1.8.2.1。这是脚本:
#!/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 ..
这是输出:
$ ./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.
其他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
这是我的问题(最后):
- 为什么这个推送被拒绝了?
- 我能做些什么呢?(如果使用
--force
选项是答案,我怎么能确定我没有做破坏性的事情?) - 有没有更好的方法来使用该
subtree
模块来避免这个问题?(注意:我不愿意使用子模块。)