Differences between git submodule and subtree

99,602

Solution 1

What if I want the links to always point to the HEAD of the external repo?

You can make a submodule to follow the HEAD of a branch of a submodule remote repo, with:

o git submodule add -b <branch> <repository> [<path>]. (to specify a branch to follow)
o git submodule update --remote which will update the content of the submodule to the latest HEAD from <repository>/<branch>, by default origin/master. Your main project will still track the hashes of the HEAD of the submodule even if --remote is used though.


Plus, as noted by philb in the comments, git subtree is a contrib/, as opposed to git submodule (core command)

Solution 2

submodule is link;

subtree is copy

Solution 3

The conceptual difference is:

With git submodules you typically want to separate a large repository into smaller ones. The way of referencing a submodule is maven-style - you are referencing a single commit from the other (submodule) repository. If you need a change within the submodule you have to make a commit/push within the submodule, then reference the new commit in the main repository and then commit/push the changed reference of the main repository. That way you have to have access to both repositories for the complete build.

With git subtree you integrate another repository in yours, including its history. So after integrating it, the size of your repository is probably bigger (so this is no strategy to keep repositories smaller). After the integration there is no connection to the other repository, and you don't need access to it unless you want to get an update. So this strategy is more for code and history reuse - I personally don't use it.

Solution 4

sub-module
pushing a main repo to a remote doesn't push sub-module's files

sub-tree
pushing a main repo to remote pushes sub-tree's files

Share:
99,602
Nathan H
Author by

Nathan H

Soluto #SOreadytohelp

Updated on July 13, 2021

Comments

  • Nathan H
    Nathan H almost 3 years

    What are the conceptual differences between using git submodule and subtree?

    What are the typical scenarios for each?

  • Nathan H
    Nathan H over 8 years
    your answer seems to go against the voted answer here: stackoverflow.com/questions/10443627/…
  • VonC
    VonC over 8 years
    @NathanH this (the possibility to track HEAD) has been added a year later (March 2013, git 1.8.2: github.com/git/git/blob/…)
  • matanster
    matanster over 8 years
    I see the submodule followship behavior is also mentioned in your other anwer. In that case I think you mean to say that always pointing to the HEAD of a submodule is accomplished by using both add -b and --remote thereafter on the update commands, as per the submodule update documentation. In that case, is the -b really still required for following HEAD of master?
  • VonC
    VonC over 8 years
    @matt the -b is used to generate the right .gitmodule metadata for the submodule (it is equivalent to a git config -f .gitmodules submodule.<path>.branch <branch>).
  • matanster
    matanster over 8 years
    Then it has little to do with enabling --remote - --remote works also if -b hasn't been used on add. In both cases the update will cause a commit in the parent repo housing the submodule, so the links do not really "always point to the HEAD" in a very automatic way.... either I didn't get it, or that claim better be removed from the original answer (?)
  • VonC
    VonC over 8 years
    @matt sure, --remote will work without -b, because it will default to origin/master. But with or without -b, a submodule never follows "automatically" a branch, as I mentioned in stackoverflow.com/a/20797186/6309. It checks out the SHA1 memorized in the gitlink, and then updtate its content if you do a git submodule update --remote.
  • matanster
    matanster over 8 years
  • J Bramble
    J Bramble over 7 years
    "pushing a main repo to remote pushes sub-tree's files" No, it doesn't.
  • Maciek Rek
    Maciek Rek about 7 years
    @JBramble I should probably mention that it's done with the SourceTree app eg: git -c diff.mnemonicprefix=false -c core.quotepath=false -c credential.helper=sourcetree push -v --tags production refs/heads/master:refs/heads/master
  • User
    User about 6 years
    But with git subtree you still can also push - if you wanted - right?
  • Franklin Yu
    Franklin Yu about 6 years
    @lxx If you know the repository URL…
  • adi518
    adi518 about 6 years
    @FranklinYu Why would he not know that? can't get that info from the local git meta data?
  • Franklin Yu
    Franklin Yu about 6 years
    @adi518 Yes, if you are the one who created the subtree. However, if you pushed your repository to GitHub and others clone it down, I don’t think he/she automatically knows the subtree URL.
  • Robert Oschler
    Robert Oschler about 6 years
    @NiklasP - can you elaborate on "reference the new commit in the main repository"? That's the one step I'm not clear on how to execute and therefore "changed reference" isn't something I understand either.
  • philb
    philb almost 3 years
    another point that might be useful: git submodule is a "core" Git command, it's part of the Git codebase. git subtree is in the "contrib" directory, it's not installed by Git's Makefile (though some distros do ship it), so it's less developed and less maintained.
  • VonC
    VonC almost 3 years
    @philb Good point. I have included your comment in the answer for more visibility.
  • lmat - Reinstate Monica
    lmat - Reinstate Monica over 2 years
    "HEAD" of a branch is nonsensical. It should be "You can make a submodule to follow a branch of a submodule remote repo...".