+71
Planned

subtree support [SG-9149]

Marc Strapetz 4 years ago updated by Raphael 1 day ago 12

Support for "git subtree" command (add, pull, push, merge, split) and its specific commit layout

Need More User Input Git
+5

For me, this is the one missing feature preventing SmartGit from being the Ultimate Git GUI.

Hello all!


Subtree is particularly useful when working with Roots, a powerful Wordpress framework.

Documentation for Roots & its subprojects recommends installing by pulling the git repo... and deleting the .git folder. That's a shame, because we lose the power of git and every update equates to a fresh install.


The particular about this environment is that we pull Trellis, Bedrock & Sage not as dependencies, but as source the we modify. I e.g. added more steps to deploy additional software on the server. Yet we want to receive diff updates on the code, which is not possible by cutting the link to the original repos. So it makes sense to keep the entire code in a single repository. We only need to manage the path where each sub-repo is checked out, as they do not live in different subfolders.


Submodules do not work for this use case, as explained. Subtrees are an excellent tool though.

They are set up by (e.g. Sage deep down the tree):

git subtree add --prefix=site/web/app/themes/sage sage master -m "Add Sage subtree"


Good news is, once subtrees are set up through command-line, they are transparent to Smartgit! Merging updates from upstream into each respective subtree works like a charm. We only need to resolve merge-conflicts created by our own edits. The SmartGit interface does most of the work (which it could not if we had cut the link with upstream).


Sometimes the subtree path goes missing. I do not know where the error comes from yet, but that would probably be solved by a SmartGit implementation.

Please implement setting up subtrees in Smartgit, as you do for submodules and git-flow. To the looks, only the install step is missing, so it is a relatively small workload.

Thanks!

Some additional reading to help with implementation:

+1

Are there plans to make this happen in SmartGit? We just started using subtrees at work and have a bunch of SmartGit licenses here. Most of my colleagues are no "consoleros" and it would make my live as maintainer much easier if a GUI interface to upstream subtree repos would be in SmartGit.

+1

What commands you miss most?

When merging with the current Smartgit Merge, i.e. `git merge` without `--strategy`, sometimes, changes in certain files that lie in a subtree's root directory end up creating the file in our repository's root directory. Files in subtrees' sub-directories never created this issue and already properly merge.

git merge --strategy subtree ORIGIN/BRANCH

avoids this issue. Nothing else seems needed for merge to work.

Two more helpful links:

https://stackoverflow.com/questions/32407634/when-to-use-git-subtree

https://github.com/git/git/blob/master/contrib/subtree/git-subtree.txt

Did you use "git subtree add" command to initialize the subtree? If so, there should be at least an initial subtree merge commit containing meta information about the subtree, like:

git-subtree-dir: src/project
git-subtree-mainline: e7f09673067cd094778ed6089c8d4fe0756e73ca
git-subtree-split: 4dffc803a8f86d75d64c26fa5836c240048c9ebb

Based on this information, SmartGit can infer the subtree prefix and invoke "git subtree merge --prefix=<prefix>" which internally results in a "git merge -Xsubtree=<prefix>". This seems to be safer than "git merge -s subtree" which has to guess about the prefix and could fail.

Yes, I did initialize with `git subtree add` and the meta-information is present.

Smartgit's output reads `git.exe -c "credential.helper=C:/Program\ Files/SmartGit/lib/credentials.cmd" merge --no-ff <subtree-origin>/master`. This  does not look like it uses `git subtree`.

I didn not know `git merge -s subtree` was guessing. In any case it never guessed wrong.

Is anyone using subtrees to sync back and forth between your main repository and the subtree, i.e. a combination of "git subtree merge" and "git subtree split"? Which exact commands/parameters are you using here?