Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git subtree simplifications if never contributing upstream?

What optimisations exist (including even alternatives to git subtree) if you wish to include a subproject in your main project but never contribute changes upstream?

Actual use case: I am embedding Ghost into an existing express.js website, e.g. into lib/Ghost. I will need to make a few hacks to it, the type they would not want contributed upstream anyway. Any normal contributing to the Ghost project would be done via a typical forking on GitHub, instead of from within my other project.

Therefore after the initial embedding of Ghost into my project, the only things happening would be the occasional local source code change, plus sometimes fetching from upstream for updates from their master branch.

In such a scenario, is git subtree still a suitable approach, and if it is then are there either any gotchas or simplifications which would apply, due to this need to never contribute upstream? And would it therefore also be possible to have the main TryGhost/Ghost repository as my subtree upstream, rather than first forking Ghost and then having the fork as the project's upstream?

like image 221
rgareth Avatar asked Feb 23 '14 21:02

rgareth


1 Answers

Subtree sounds like a really good fit to me.

If you're making any local changes at all, I think subtree is a better fit over submodules.

  1. Anyone cloning your project won't need to run additional commands like they would with submodules.
  2. Any changes you make will be made directly to your copy of the sub-project and won't need to be pushed to a public repository for others to access like they would with submodules in order for people to sync those changes.
  3. Pulling from up-stream is a cinch, and if other people working on your project don't have git subtree it won't matter (they just won't be merging or splitting upstream).

The only downside I can think of is that you have a full copy of the sub-projects in your repository, but unless it's an enormous project that's optional for your super-project who cares about that?

  • You should not need to make a branch for the subproject, just:

    git subtree add --prefix Ghost --squash -m "Adding Ghost." https://github.com/TryGhost/Ghost.git master
    

    You can freely make changes from that point on and completely ignore the fact that it originally came from Ghost depot. You don't even need to add the remote as you can tell from my example above.

  • If you pull often, you may want to create the remote.

    git remote add ghost https://github.com/TryGhost/Ghost.git
    git subtree pull --prefix=Ghost --squash -m "Updating Ghost." ghost master
    
  • Finally, even if you decide at some later point that you want to contribute back upstream, to a fork or wherever, it's really simple for you to just split out the parts relevant to the sub-project into a branch and then just push the changes from that branch to the fork repository.

    git subtree split -p Ghost -b Ghost-contrib-br --rejoin
    # this should switch to the branch with only the ghost files
    
    git push <remote-contrib-repo>
    

    Note: I didn't use --squash because the history will be only what you modified since the add or last --rejoin

    --rejoin is kind of a lame hack which commits back to your super-project so the split command knows the best starting point for the next split. In the future I think this will be managed from a new section the .git/config (I may even make it so myself).

like image 143
johnb003 Avatar answered Nov 07 '22 19:11

johnb003