Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are git submodules incompatible with svn externals?

There are lots of webpages out there suggesting hackish ways to make svn externals look like git submodules. I have read some accounts of what the difference is, but this doesn't seem very fundamental:

Git submodules link to a particular commit in another project's repository, while svn:externals always fetch the latest revision.

Why does this difference make them so fundamentally incompatible? Isn't there a reasonable default we can assume, such as that most svn:externals point to tags that never move?

like image 248
Andres Jaan Tack Avatar asked Jun 28 '10 11:06

Andres Jaan Tack


People also ask

Can you use Git and SVN together?

git-svn is a specialized tool for Git users to interact with Git repositories. It works by providing a Git frontend to an SVN backend. With git-svn, you use Git commands on the local repository, so it's just like using normal Git. However, behind the scenes, the relevant SVN commands are sent to the server.

Can a submodule point to a branch?

You can set the submodule to track a particular branch (requires git 1.8. 2+), which is what we are doing with Komodo, or you can reference a particular repository commit (the later requires updating the main repository whenever you want to pull in new changes from the module – i.e. updating the commit hash reference).

Can you push to a submodule?

In the parent repo, you can also use git push --recurse-submodules=check which prevents pushing the parent repo if the submodule(s) are not pushed first. Another option is git push --recurse-submodules=on-demand which will try to push the submodules automatically (if necessary) before pushing the parent repo.

What is the use of .gitmodules file?

The . gitmodules file, located in the top-level directory of a Git working tree, is a text file with a syntax matching the requirements of git-config[1]. The file contains one subsection per submodule, and the subsection value is the name of the submodule.


1 Answers

The fundamental difference is the composition rule.

In a true component-based approach, you define a configuration, that is:
The list of labels (of SHA1 commits for Git) you need for your project to "work" (i.e. "develop", "compile", "deploy", ...).

Each commit referenced in a configuration helps you to get the exact versions of all trees. There is no exception. Each file of that tree is at the exact version specified by the configuration you have defined.


Note for git1.8.2

"git submodule" started learning a new mode to integrate with the tip of the remote branch (as opposed to integrating with the commit recorded in the superproject's gitlink).

So soon (March 2013), a submodule could reference an upstream HEAD, and not just a fixed SHA1.


(Before 1.8.2) There can be only one label/SHA1 per module. From one common parent repo, you cannot define a module within a module.
(But a module, which is just a reference to an external Git repo, can have its own submodules definition: the parent repo will only refer the first-level submodule, which in turn will reference whatever submodules it had committed within itself)


No so in SVN external: you can define directory externals as well as file external, with or without an explicit revision in it.
You can compose various external properties. For instance:

$ svn propget svn:externals calc
third-party/sounds             http://svn.example.com/repos/sounds
third-party/skins -r148        http://svn.example.com/skinproj
third-party/skins/toolkit -r21 http://svn.example.com/skin-maker

The result is not a configuration (one reference for 'calc'), but a composition of selection rules which define the exact "patchwork" you need in the directory 'calc'


In short, you cannot "compute" one SHA1 for a 'calc' submodule which would be the exact equivalent of a bunch of svn:external properties on a 'calc' SVN directory.

like image 197
VonC Avatar answered Oct 16 '22 02:10

VonC