views:

82

answers:

3

I'm using git's branching feature to manage 5 variations of a small website. There are 5 versions that will all be live in different subdirectories on production. My approach to checking out the various branches to their respective folders was to:

mkdir foo && cd foo
git init
git remote add origin git@...:project.git
git fetch origin foo:foo

Where "foo" is a given branch name. This was fine, except for that it pulled my entire repo (designs, as3 source, etc...) into those branch folders instead of just the public www folder, which is the only thing I really want on production.

Is there a cleaner way to handle this? Git can't clone subdirectories right?

+1  A: 

Don't mix stuff that you want to keep private into your releasable product.

I'd suggest that you keep your products (html, php, js, img, etc) separate from the sources. Keep the sources in a project or projects, and keep the products separately in another project. Or even just build the products dynamically on demand with a build script that copies/generates/etc the output from the sources. That way it is easy to point to which sources generated what output.

Peter Loron
I like this approach, but this a small/fast project and don't have time to generate a decent build process. Pushing release files to a separate repo also seems like a lot of work to do manually. Because of this, I might take the submodule approach mentioned in VonC's answer. Thanks for your reply.
Trevor Hartman
+2  A: 

The way a DVCS functions (pushing/pulling a all repo) forces you to reason in term of component (coherent set of files, with their own commit lifecycle)

Your www folder should be in your case a submodule (Git) or subRepo (Mercurial).
That way, you would be able to pull everything.


The other solution (if you want to keep your repo the way is is), is to define a special "release" branch (release_foo for foo) in which you remove everything but www.
When the development on foo is ready to be release, you merge on release_foo and remove on that branch what you don't need.
Not an ideal solution, but workable.


The last solution I forgot initially to mention is available since Git1.7:

sparse checkout

Once the repository is cloned, the read-tree trick limits your "view" of the repository to only those files or directories that are in the .git/info/sparse-checkout file.

In your case, you could just create one .git/info/sparse-checkout with the relevant directory, and when you update your working tree, only that directory (like foo) would appear.
That is another solution which would:

  • allows you to keep your repository unmodified
  • avoid any "maintenance" work prior a delivery.
VonC
Sounds like a lot of maintenance to push release files to a separate branch. I'm not even sure how I'd do that: after I make a change in the master branch, how would I push release files to the release branch?
Trevor Hartman
I think I'll try to setup submodules if I have time. Currently I have symlinks on the server pointing into my source/www dir :/
Trevor Hartman
@Trevor: I would consider the "maintenance" work to be very small, since the merge should be trivial (you duplicate `foo` on `foo_release`), and the only modification you do on `foo_release` is to remove a bunch of directories.
VonC
@Trevor: just added one more solution I forgot initially: **sparse checkout**. See my updated answer.
VonC
@VonC sparse checkout sounds perfect. Going to look into that - thanks!
Trevor Hartman
@VonC regarding maintenance: having to manually delete files on every push to prod - especially when making minor tweaks and pushing more than once per hour during dev - is too much work. Writing a script to do it is fine too, but it's borderline overkill for the size of this quickturn project. Plus, I'm lazy.
Trevor Hartman
@Trevor: "Plus, I'm lazy": Best. Justification. Evaaar. You must be smart, then ;) http://www.associatedcontent.com/article/711177/are_smart_people_lazy.html?cat=7 (I totally agree with you, btw, about the cost of the "maintenance" approach)
VonC
@VonC lol, nice link :D
Trevor Hartman
A: 

Currently (AFAIK) a git will only clone the whole repository. Using a separate repository for deployment could be an option. Given git's flexibility, I wouldn't be surprised if you could push/pull from a master development repository, and just push a single branch to a second deployment repository, all from the same local. But I've never tried that out.

Simeon Fitch