views:

998

answers:

6

Suppose I have a project in source control with a lot of subdirectories, many of which I don't need at the moment.

I would like to create a working copy containing only some of the entire tree, which still maintaining the ability to make changes, commit them, and push them back up.

Is this possible and if so, how can I do it?

I'm still deciding whether to go with bazaar or mercurial, so answers regarding either of those would be helpful.

Edit: Actually, solutions for git would be useful too.

+3  A: 

Judging from this wiki, this feature is not yet implemented in Mercurial, however there is an extension that can do approximately what you want by 'converting' a repository or its part, rather than actual branching. Since it can convert from and to Hg, it may work as partial cloning. Is this what you needed?

David Parunakian
This is a useful answer, but note the important caveats: `hg convert` lets you get a clone of only a part of a repository yes, but the changesets will not have the same SHA-1 IDs as the changesets in the original. You can't push back to the original repository (at least not safely), though you can try to manually manage transplanting back the changes you do make (e.g. with `hg transplant`). It's not ideal though for a long term clone.
quark
+3  A: 

In most DCVS, the rule is "1 project == 1 repository". There is no notion of "subproject" (unlike in Subversion where you can checkout a subtree and work on that).

The main reason is that your "project" contains a copy of the whole repository in the root folder. Things would get pretty complicated if you could create copies of the whole repository in subfolders.

On the plus side, creating working copies is a fast operation (unless the underlying filesystem is slow).

Aaron Digulla
+4  A: 

Cloning a subset of the tree is not possible, as far as I know, but there are other possibilities.

Git: The command git clone has a --depth flag:

--depth <depth>

Create a shallow clone with a history truncated to the specified number of revisions. A shallow repository has a number of limitations (you cannot clone or fetch from it, nor push from nor into it), but is adequate if you are only interested in the recent history of a large project with a long history, and would want to send in fixes as patches.

Bazaar: The flag --lightweight for the checkout command only downloads a working directory instead of the whole history and saves bandwidth and disk space. All operations are still supported, but a network connection is required to perform them.

I do not know whether Merurial has this feature or not.

spatz
+2  A: 

For Bazaar, you have nested trees: http://bazaar-vcs.org/NestedTreesDesign which allows you to split a big project in sub-projects.
I haven't used this feature yet, so I don't know how well it works.

You can also branch using --hardlink to avoid copying a bunch of files (not sure if it works on Windows...), branch without history (lighter branch) or branch without working tree (no files, only history).

PhiLho
This is supported also in other DVCS: it is **git-submodule in Git**, and I think **Forest extension in Mercurial**. But it is only tangentially related to what original poster was asking about, I think, because it requires extra setup *upfront*.
Jakub Narębski
These are mentioned in the page I link to.I just tried: used split on an existing test tree, committed the change, then branched the sub-tree, it worked. No need to do that upfront, at least for bzr.
PhiLho
@Jakub: you don't need the Forest extension any mroe -- SubRepos were added to the Mercurial core in 1.3.
Steve Losh
+4  A: 

If you already have a repository and you'd like to do this, it's going to be a pain.

If you're going to be doing this with brand new repositories, you might want to look at Mercurial's new subrepos.

Basically you create standalone repositories for certain directories:

myproject/
    .hg/
    source code/
        ... files here ...
    documentation/ (subrepo)
        .hg/
        ... files here ...
    graphics/ (subrepo)
        .hg/
        ... files here ...

This isolates the different pieces of the project in different repositories. The "containing" repo (myproject in this case) keeps track of what revision the subrepos are at every time you commit. The subrepo wiki page I mentioned explains it well.

Steve Losh
+2  A: 

In git, you can use git subtree, which lets you extract a "virtual" repository for just a particular subproject, then make changes in the subproject and then merge those changes back in.

apenwarr