git-subtree: Push changes from an cloned repo

21,763

Solution 1

Disclaimer, I suspect I am only a few days ahead of you learing about subtree :-)

If you are just using git subtree push you are not giving subtree enough information to extract and push your changes.

If you cloned the repo correctly the subtree will already be in there. Subtree needs to be told which subtree you want to push from (even if you only have one) and it also needs to know where to push to - specifically, you do not want to push to the top level repo. Hence, you want something like:

git subtree push --prefix=lib [email protected]:arges-github/lib.git master

Obviously the repo and refspec should be changed to match your repo.

If you want to look into what is happening here (and it does help) subtree actually splits the changes that affect the files inside the subtree into a different branch and then pushes that to the subtree repo. To see this happen, use subtree split

git subtree split --rejoin --branch=shared-changes --prefix=lib

then have a look at the branch you've made:

git checkout lib-changes

and, push them manually

git push [email protected]:arges-github/lib.git master

If this isn't working then it may be that you have not merged the subtree into your repo. When you add a subtree:

 git subtree add --squash --prefix lib [email protected]:arges-github/lib.git master

you also need to merge the subtree and push it back to your top level repo.

 git subtree pull --squash --prefix lib [email protected]:arges-github/lib.git master
 git push

Solution 2

I had exactly the same problem you were having and I solved it using essentially the approach Roger Nolan suggested. However, if you're unlucky enough to be on a case-insensitive file system like I was, you also have to make sure that every time you do a pull and a push, the case of your prefix stays the same.

When you do end up mixing up the case by mistake, git will think you have two subtrees whereas only one will exist on the filesystem.

So the solution that I ended up with (in case it helps anyone) is:

  1. Create a script that will push your subtree. Call it publish_<your-subtree-name>.
  2. Create another script that will pull your subtree. Call it update_<your-subtree-name>.
  3. Create a temporary branch at your HEAD and test out update. If your script is right, your temp branch won't move.
  4. Clone the subtree repo elsewhere, add in a test commit, push it and try to pull it into your repo using the update script you just wrote.
  5. If it all works, delete your temporary branch and now check in both scripts to the super project repo.
  6. Then whenever you need to push or pull subtrees, use the scripts.

PS> The --squash parameter is important, particularly if different branches of your reporsitories are pulling different branches of the subtree and also if you have multiple subtrees in your project.

Share:
21,763
arge
Author by

arge

Updated on July 09, 2022

Comments

  • arge
    arge almost 2 years

    I'm using git-subtree(from Avery Pennarun). In my current git repo I have of course all my project files/folders and a subtree called "lib". If I now clone this git repo using git clone I get all of the project files and the subtree "lib" (everything as it should be). What I tried now: I changed something within the subtree "lib" in the cloned repo and tried to push the changes back to the remote repo of the subtree "lib" using git subtree push, but it didn't work. What is the problem? Do I have to add it as subtree first with git subtree add?

    Thx in advance