Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Single file as Git submodule

Tags:

I'm trying to ascertain best-practices for shared code amongst Git repositories.

So far, I've obviously come across submodules which seem like they - almost - fit the bill. My project is a PHP MVC framework with a simple structure:

  • /app
  • core.php
  • /core

Where app is a folder containing application-specific controllers, models, views etc. while core contains those of general use, e.g. a login controller. The core.php file itself is the global handler for all requests.

As such, the shared code amongst all of my deployments of this MVC framework is core.php and core.

I can see how it is possible to turn core into a Git submodule, but not core.php.

Is this even possible? Do I need to re-architecture my framework so that core.php resides inside the core folder so I can make the whole folder a submodule, or is there a better way?

like image 666
Will Croft Avatar asked Nov 13 '10 04:11

Will Croft


2 Answers

If you can use symlinks (e.g. you are not using Windows), then you can set up core and core.php like this:

# "base" repository layout: core/ core.app  # each app repository layout: base/   core/   core.php core -> base/core/ core.php -> base/core.php app/ 

In each app repository, the base/ directory is either a submodule that uses the “base” repository or a subtree merge of the “base” repository.

Both methods will let you start making changes to the base code in the context of a particular app and later pull those changes back into the main base repository. When using submodules you have to be careful to always publish new base commits before publishing any app commits that reference those new base commits (this is not a problem when using subtree merges because each app is “flat” and effectively has its own copy of the base).

The third-party git subtree command seems like a very nice way to manage the subtree merge, if you decide against submodules.

Subtree

git init newapp cd newapp ln -s base/core ln -s base/core.php git add core core.php git commit -m'point to base (to be added next)'  # hook up base git subtree add --prefix=base [email protected]:me/app_base.git master  mkdir app # edit app/bar.php  # update base git subtree pull --prefix=base [email protected]:me/app_base.git master  . |-- .git/ |   |-- ... |   `-- ... |-- app/ |   `-- bar.php |-- base/ |   |-- core/ |   |   `-- foo.php |   `-- core.php |-- core -> base/core/ `-- core.php -> base/core.php 

Submodule

git init newapp cd newapp ln -s base/core ln -s base/core.php git add core core.php git commit -m'point to base (to be added next)'  # hook up "base" git submodule add [email protected]:me/app_base.git base git commit -m'incorporate base'  mkdir app # edit app/bar.php  # update base (cd base && git fetch origin && git merge origin/master) git add base git commit -m'updated base' . |-- .git/ |   |-- ... |   `-- ... |-- .gitmodules |-- app/ |   `-- bar.php |-- base/ |   |-- .git/ |   |   |-- ... |   |   `-- ... |   |-- core/ |   |   `-- foo.php |   `-- core.php |-- core -> base/core/ `-- core.php -> base/core.php 
like image 195
Chris Johnsen Avatar answered Oct 04 '22 21:10

Chris Johnsen


Perhaps you are best off maintaining core.php and core in a separate repo, and then using it as a remote. Then you can manage it by pulling it into any project it is used. In order to do this, just start the new project as a separate git repo, and then pull in the 'core' repo as a subtree.

This chapter shows you how to do it:

Updated Reference: http://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_subtree_merge Original Reference: https://git-scm.com/book/en/v1/Git-Tools-Subtree-Merging

It is a little better for you than the setup advised in the previous section of the book (6.6).

Look at it; it might be helpful.

like image 38
rmk Avatar answered Oct 04 '22 22:10

rmk