views:

86

answers:

1

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?

+2  A: 

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 help you to get the exact versions of a all tree. There is no exception. Each files of that tree is at the exact version specified by the configuration you have defined.
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 can not "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.

VonC
Note to self: ClearCase is another example of VCS allowing composition in its version selection mechanism... except it has banished such a mode with its more recent methodology UCM: see http://stackoverflow.com/questions/763099/flexible-vs-static-branching-git-vs-clearcase-accurev/764219#764219
VonC
Nicely written. But... When you're checking out the SVN parent, whether the externals have moved or not, you expect it to compile and work. So wouldn't it me sufficient, at least as a default, to hash that particular revision, when you `git svn clone` the parent?
Andres Jaan Tack
@Andres: how would you `git svn dcommit` then? How would you push back any changes you could have made within the "submodule" part of your Git repo (see "true nature of submodules" http://stackoverflow.com/questions/1979167/git-submodule-update/1979194#1979194), which actually correspond to several SVN repo, some of them with an explicit revision not supposed to move?
VonC
This is still deeply unsatisfying. I get that they're different,but I don't get why there can't be some automatic workaround.
Andres Jaan Tack