Git subtree export and re-import woes

时光毁灭记忆、已成空白 提交于 2019-12-07 11:26:15

问题


I have a larger git repository (A) that shares a certain amount of code with another project (B) of mine. To make maintenance easier, I decided to have a third repository with the common code (C) which will then be used via git subtree.

I prepared everything in A (putting the common code in folder "sub") and used the procedure described in Detach (move) subdirectory into separate Git repository to create C

Now that I have C with just a few commits, I wanted to put it back into A, folder sub. I used the approach described in http://www.kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html which worked insofar as all commits for the subfolder were now duplicated. I didn't quite mind this, however now I am stuck with no idea how to continue working with this subdirectory.

I made additional changes in A/sub which I want to push to C. As described in git subtree push changes back to subtree project I used

git subtree split --prefix sub -b split-branch

to create a branch with just the subtree. This takes a bit of time, but finishes successfully. Doing

git checkout split-branch
git push remote-c master

gives me

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.

but a git pull remote-c master says I'm already up-to-date.

How do I resolve this situation?

EDIT1: I tried to reproduce the problem with a small test script. Executing this script:

( 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

This results in

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.

回答1:


I tried a git push -f which seems to have worked. Still would like to know what exactly happened and why.




回答2:


The default behavior of git push is to try to push all branches to the current branch remote if you have same named branches locally and remotely. From the git push manual:

The special refspec : (or +: to allow non-fast-forward updates) directs git to push "matching" branches: for every branch that exists on the local side, the remote side is updated if a branch of the same name already exists on the remote side. This is the default operation mode if no explicit refspec is found (that is neither on the command line nor in any Push line of the corresponding remotes file---see below) and no push.default configuration variable is set.

In this case, since your current remote is C and you have both locally master and remotely C/master it will be pushed, and since the trees will not match at all the push will fail with the master -> master (non-fast-forward) message.

When you git pull to your branch it says up-to-date because you are pulling yo your current branch, which is up to date.

To modify this behavior of git push you need to setup the push.default value in your git config. Look for "push.default" in http://www.kernel.org/pub/software/scm/git/docs/git-config.html




回答3:


My solution: upgrade git. :-)

Your test script succeeds for me, assuming the testA and testC directories already exist. I'm using the latest version of git (v1.8.2.1), so perhaps they fixed something since you posted this.

$ 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


来源:https://stackoverflow.com/questions/12590546/git-subtree-export-and-re-import-woes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!