6

This is a question that seems to come up semi-frequently, but sadly I've not found an answer that I can fully apply to my situation yet, so I figured I'd ask my own question. This is my first question on SO, so be nice. :P

The "problem": Our company develops multiple PHP applications, however one of those applications is a "master" of sorts. All of our other applications is installed inside this "master application", and requires the master application to work.

We use version-control to manage these applications, of course.

While many of the files in our addon applications are in subdirectories, not all of them are. This means that we cannot use subdirectory importing (svn externals, git submodules, etc.). For instance, within the root folder there are several folders (admin, public, kernel and so on) and the addon applications have files within one or more of these folders - they are not independently self-contained within the directory structure of the master application.

We currently use SVN and recently found ourselves considering git due to some of the features available we feel could be useful to us. One thing I'm not clear on with git, however, is if there is truly a way to "merge" (not in the version control sense) these repositories into a single directory locally when developers are working on the code. I have not found a way to do this with SVN either.

In an ideal world, we would have one repository for our "master" application with a structure like so:

  • /
  • --file1
  • --file2
  • --/admin
  • ----file1
  • ----file2
  • --/public
  • ----file1

Our addon application would have a structure like so (remember, we have multiple addon applications):

  • /
  • --filex
  • --/admin
  • ----/myapp
  • ------file1
  • ------file2
  • --/public
  • ----filex

We have experimented with the following approaches, each with its own caveats:

  1. All applications in a single repository. This is less than ideal as it becomes a nightmare managing versions for each application effectively (especially in SVN). Branching and tagging take along files from unrelated and separate applications.
  2. All applications in a separate repository. This is also not ideal (well, it is from a management/organization perspective) because you cannot export two separate repositories to a single folder, so you always work with a checkout of one repository and an export of others. If you are working on application X and there are changes in our master application, you need to manually do a new export of that master application and copy the files over to the application X repository you are working on to have the latest framework code.

Is there any way with git or SVN (or any other version control system for that matter) to allow more than one repository within a single directory without using subdirectories? SVN externals is nearly perfect, but has the requirement that all files in the external repository be in a separate subfolder, which as described above does not work for us. I gather git has equivalent capabilities, but again cannot allow more than one repository in a single folder, leaving us with the same issue.

Related questions: Multiple repositories in one directory (same level) - is it possible? - this is very close to what I am asking I think, but I did not see any solution that I felt could be applied to our situation.

Community
  • 1
  • 1
bfarber
  • 63
  • 4
  • with git, you usually do that kind of stuff with branches. Each developer can have one or each submodule or any combination you can think of. When you feel you are ready to merge your branch with master (or any other) branch, you do it. – Timo Dec 30 '11 at 18:42
  • To be more accurate: You can have one branch for master app and define module branches based on that: they inherit the directory structure, but whatever unique you put in them, stays there. The downside is that you cannot work with multiple branches at once: you need to still checkout them individually. But everything in fact will be in one directory and you can move things from one branch to other quite easily. – Timo Dec 30 '11 at 18:51
  • +1 for moving to git. Or at least considering it. – Adam Dymitruk Dec 30 '11 at 19:23
  • I'm finding I basically have two situations - short term and long term. In the short term, I want to find a way to "virtually" have everything in one repository, while technically storing them separately for versioning purposes. I am not as familiar with git workflows as SVN/CVS, and this may be less of an issue with git. Long term, I'll be taking a closer look at git, but it doesn't appear to do what I'm after out of the box at least. – bfarber Jan 10 '12 at 02:01

3 Answers3

3

I have never attempted to do something like this in a production environment, but you could certainly do:

$ git init
$ mv .git .git1
$ git init
$ mv .git .git2
$ export GIT_DIR=.git1
# do work in first repo
$ export GIT_DIR=.git2
# do work in second repo
William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • Sadly, not being too familiar with git this is a bit above my comprehension (not your fault). I've seen similar suggestions online, and if/when we move to git, I'll revisit this. Thanks. – bfarber Jan 10 '12 at 02:05
  • All of the information git uses to track a repo is stored in a single directory. That directory is named in GIT_DIR. By changing GIT_DIR, you change repositories, while keeping the same working directory. – William Pursell Jan 10 '12 at 14:24
  • I think I get what the above commands do. We have opted to hold off on trying out git (time is always working against us of course), but I'll revisit this in the future. Thanks! – bfarber Jan 10 '12 at 21:16
3

git allows you to specify work-directory and git-directory on the top level git command:

git status

can be altered to use a different .git folder with

git --git-dir=some/other/path/to/a/different/.git/folder status

Likewise, you can specify a different working folder:

git --work-tree=some/other/path status

You can also combine the 2.

If you have to have this workflow all the time, you can override and wrap the git command to always point to a specific .git dir or work dir. An example is "git achievements" which intercepts git commands and gives you rewards for getting better with git and then calls the actual git command: https://github.com/icefox/git-achievements

Looks like a fun problem to solve.

I would also look at just having a branch per application and continually rebase those branches on top of any work that is done to the core app. This would actually be my first choice.

Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141
  • Not being overly familiar with git and how it is used in practice (compared to SVN or CVS, where things are centralized), I'll have to read up a bit more on how this scenario is more commonly tackled with git. Will look into the branching suggestion, thanks. – bfarber Jan 10 '12 at 02:02
  • Git's simplicity will baffle you :) study the .git folder and it's structure. Amazingly simple after you understand it. – Adam Dymitruk Jan 10 '12 at 19:29
  • We have opted, for time reasons, to hold off on trying out git. Everyone is familiar and setup with SVN and not everyone likes to get into the nitty gritty of this sort of thing, so it's a transition we will have to better plan if we decide to go that route. Thanks for the tips though - I will revisit this in the future if we give git a shot. – bfarber Jan 10 '12 at 21:17
  • We were in the same spot as you before. The power, speed control and flexibility that we have now are well worth the transition. Here is our workflow: https://plus.google.com/109096274754593704906/posts/R4qkeyRadLR – Adam Dymitruk Jan 10 '12 at 21:59
2

Subversion 1.6 and 1.7 allow externals of a single file.

See http://svnbook.red-bean.com/en/1.7/svn.advanced.externals.html

"Subversion 1.6 also introduced support for external definitions for files. File externals are configured just like externals for directories and appear as a versioned file in the working copy.

For example, let's say you had the file /trunk/bikeshed/blue.html in your repository, and you wanted this file, as it appeared in revision 40, to appear in your working copy of /trunk/www/ as green.html."

Scott Coldwell
  • 868
  • 7
  • 14
  • This was almost perfect. Except for the fact that you can only use SVN file-externals within the same repository. Our goal was to have one repository per application - if we're going to have all the files in one repository, we wouldn't have this external reference issue in the first place. – bfarber Jan 10 '12 at 01:58
  • Ok, ultimately what I opted to do for simplicity right now is (1) move our addon applications into the main application's branches folder (branches/app1/trunk, branches/app2/trunk, etc.). We can then version those apps (branches/app1/1_2_x) and we can use SVN externals to pull the files into the main application's trunk folder since they are now technically in the same repository. This works perfectly. – bfarber Jan 10 '12 at 21:15
  • Glad you got it figured out! Thanks for sharing your final solution. – Scott Coldwell Jan 11 '12 at 17:01