4

Our small team thought it would be a cool idea if the libraries (X, Y, Z) of our project A were separated into git submodules. Little did we realize how big of a pain this would be, especially since how project is still in early stages and is not well segregated yet. I think the project leader made the subdirectories submodules via the git filter-branch command (I can't ask him b/c he's on vacation).

Can we undo this somehow, and slurp the commits in the submodules back into the main project?

Examples of 'pain':

  • Project A must point to X,Y,Z via 'git://' links instead of 'ssh://' if we want users to be able to check it out without ssh access, so we can't make changes directly to X via the A/X copy if we want to be able to push -- we have to clone it out separately, commit, push, then pull from the A/X copy.
  • Furthermore, TortoiseGit and other windows tools don't seem to understand submodules, or at least they don't make it transparent as merely cloning, so now we're patching together things with stupid scripts and hooks.
  • Oh yeah-- for every change in X,Y, or Z we have to add a "Submodule updated" commit in the main project. I'm guessing that submodules were meant for much more mature projects that are maintained by different teams.
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
cespinoza
  • 1,437
  • 1
  • 12
  • 18
  • I didn't find `filter-branch` in one version of the git documentation, but I did find `git submodule` - see http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#submodules. Looking again, I found filter-branch, but I think submodule is more relevant. – Jonathan Leffler Dec 28 '10 at 02:12
  • 2
    Is your project leader going to be happy if you undo the separation? – Jonathan Leffler Dec 28 '10 at 02:13
  • Notable projects do have their libraries split too, e.g. Netfilter. – user502515 Dec 29 '10 at 21:18

3 Answers3

2

I'm not necessarily recommending this as a course of action,ⁱ but I've written a script (unsubmodule.py) that should remove and then merge each submodule in as a subdirectory of the same name, preserving the history of the committed version of each submodule:

https://gist.github.com/763439

I haven't tested it much, so please be careful, e.g. only try it on a fresh clone initially. The script doesn't attempt to preserve any topic branches in the submodules, just the version committed in the supermodule.

ⁱ (Both for the reason Jonathan Leffler mentions in his comment and because I work on several projects that use submodules without major problems.)

Mark Longair
  • 446,582
  • 72
  • 411
  • 327
  • There is a related question here: http://stackoverflow.com/questions/1759587/un-submodule-a-git-submodule where the top-voted answer describes similar steps to those that my script takes, but in that case just for a single submodule. I think my script is safer, as well - I chose to just move the existing submodules out of the way, so you don't lose topic branches or other information in the submodules' .git directories. The comments in that answer with regard to -C and -M for git log apply here as well, of course. – Mark Longair Jan 03 '11 at 13:40
1

You can quite easily merge all repositories together into single one, they don't need to have anything common to merge them, you just need to prevent file conflicts. So first move all files in separate repositories into desired folder where they should be in the merged one and than just merge these separate repositories.

Michal Čihař
  • 9,799
  • 6
  • 49
  • 87
1

Project A must point to X,Y,Z via 'git://' links instead of 'ssh://' if we want users to be able to check it out without ssh access, so we can't make changes directly to X via the A/X copy if we want to be able to push -- we have to clone it out separately, commit, push, then pull from the A/X copy.

Sounds like you want...

[remote "origin"]
        url = git://foobar
        pushurl = ssh://user@corp.com/srv/git/foobar

Oh yeah-- for every change in X,Y, or Z we have to add a "Submodule updated" commit in the main project.

Submodules work like a skiplist, so this is to be expected. If you do not like it, consider using a server-side hook to update the main project whenever a commit in a subproject is done.

user502515
  • 4,346
  • 24
  • 20