Reputation: 4337
I've just found git-subtree tool that some time ago became a part of main git repo https://github.com/apenwarr/git-subtree/
However I don't fully understand what functionality does this tool provide over the already existing "git read-tree" + "git merge -s subtree". Is the only purpouse of git-subtree - making the resultant commit history look better or does it have more functionality that I've overlooked?
Upvotes: 15
Views: 7603
Reputation: 1323613
In addition to have more options, git subtree
also takes into account Git configuration.
But regarding git subtree pull
, make sure to use Git 2.36+
When git subtree
wants to create a merge, it used "git merge
"(man) and let it be affected by end-users "merge.ff
" configuration, which has been corrected with Git 2.36 (Q2 2022).
See commit 9158a35 (01 Feb 2022) by Thomas Koutcher (koutcher
).
(Merged by Junio C Hamano -- gitster
-- in commit 0ac270c, 17 Feb 2022)
subtree
: force merge commitSigned-off-by: Thomas Koutcher
Reviewed-by: Johannes Altmanninger
When
merge.ff
is set toonly
in.gitconfig
,git subtree pull
will fail with errorfatal: Not possible to fast-forward, aborting.
But the command does want to make merges in these places.
Add
--no-ff
argument togit merge
(man) to enforce this behaviour.
Upvotes: 1
Reputation: 991
If you look at the old subtree code before it got added to git as a contrib module: https://github.com/apenwarr/git-subtree/blob/master/git-subtree.sh you can see that the git subtree tool is really a more advanced wrapper around the lower level git subtree merging strategies.
It basically leverages those strategies in a sensible way to make subtree management much easier. Particularly the --squash stuff is really, really useful.
Upvotes: 5
Reputation: 44234
The commands you describe reads a subtree into a repository. The git-subtree
command has many more options, as described by the documentation. Among others, you can (annotated for simplicity):
add::
Create the <prefix> subtree by importing its contents
from the given <refspec> or <repository> and remote <refspec>.
merge::
Merge recent changes up to <commit> into the <prefix>
subtree.
pull::
Exactly like 'merge', but parallels 'git pull' in that
it fetches the given commit from the specified remote
repository.
push::
Does a 'split' (see above) using the <prefix> supplied
and then does a 'git push' to push the result to the
repository and refspec. This can be used to push your
subtree to different branches of the remote repository.
split::
Extract a new, synthetic project history from the
history of the <prefix> subtree. The new history
includes only the commits (including merges) that
affected <prefix>, and each of those commits now has the
contents of <prefix> at the root of the project instead
of in a subdirectory. Thus, the newly created history
is suitable for export as a separate git repository.
There are also a variety of flags that aid and manipulate the above. I believe all these options were available before via chains of plumbing commands. git-subtree.sh
just wraps them and makes them considerably easier to execute.
Upvotes: 12