If you are working on a large remote repository and you want to restrict the download to the few branches you are working on, how do you configure the git-clone command, assuming that it is the right command in this case?
-
Is the goal here saving bandwidth? The branches would have to differ pretty radically to make a difference there. That's a fairly unusual case. – Cascabel Nov 15 '10 at 23:36
-
I am working on two branches of the same repository and I need to know how I can save some space. Branching in the same directory to switch from one branch to the other is awkward. – vfclists Nov 15 '10 at 23:42
-
@vfclists That's a totally different question. I'll edit my answer. – Cascabel Nov 15 '10 at 23:48
-
1Just to be clear - in your question you explicitly said you were downloading from a remote, trying to keep only what's necessary, but in your comment you say that the desired two repositories are local. That's a pretty big difference. – Cascabel Nov 15 '10 at 23:57
-
I am working of multiple branches of the same remote repository. I prefer the branches to work directly of the remote, but efficiency gains may mean cloning the whole repository for one branch and getting the other branches to work of that local version. I am worried by any mistakes that may arise when I push, not sure if the pushes from the local branches should go to the original remote, or the local clone then from there to the original remote. Put the original answer back, it is very informative – vfclists Nov 16 '10 at 09:30
-
@vfclists: It may be informative, but as I keep trying to say, it is almost certainly not at all helpful. I've put it back; you're welcome to try it and see how much space you save, but unless you have a very very strange repository, you're going to be disappointed. – Cascabel Nov 16 '10 at 13:08
2 Answers
Answer to the real question
Local clones with git don't generally take up a ton of extra space, because git will use hard links to share the object files. This is hard to notice - if you run du
on each repo, you'll get the full size, but if you run it on the two together, you should see the savings. I'm going to assume you've already for some reason decided that this isn't good enough. Perhaps you're on a filesystem that doesn't support hardlinks, or the clones are on separate drives or something... who knows.
In any case, if you're looking to create a lightweight clone, saving some space, why not save all the space? There's a lovely script in git's contrib directory called git-new-workdir
(the link is to the current version in git.git). It creates a new work directory from a repo, with the .git directory essentially all shared via symlinks - pretty much the only thing that isn't is HEAD
. Drop the script somewhere in your path, and you'll be able to run it like a normal git command:
git new-workdir <original-repo> <new-workdir-path>
Voila! You now have two work trees, with a shared .git directory, so the only extra space you're taking up is the work tree files. No way around that if you want to be able to work!
The one thing you must be careful about is checking out the same branch in both repos. If you then commit to that branch in one repo, the other one will become out of sync - the work tree and index won't match the commit that the branch is now at. Otherwise, you can happily work away in both repositories!
Original answer
Let me first state that there is essentially no chance you want to do this. I'm serious. It's barely going to save you any disk space, while repositories with hard-linked objects (which is the default! you don't even have to do anything to get that!) will save you a ton.
In virtually every case, branches share most of their history. The potential for saving space is only in the small recent part in which they've diverged. Look at git log branchA..branchB
. Those commits are the ones whose objects you will avoid copying. Are there any enormous binary files in there? Any 1000-line diffs? No? Then don't bother with this. It's not going to help you.
Still reading? Okay, well, I don't think git-clone
lets you mess with the refspec (with the exception of --mirror
, but that's obviously not what we're after here). If it's really important to do this, you could manage it by creating an empty repository and pulling, then carefully doing the rest of the setup the clone would've done:
mkdir foo && cd foo && git init
git remote add origin <url>
# set up a refspec to get the branch(es) you want
git config remote.origin.fetch "+refs/heads/foo:refs/remotes/origin/foo ..."
git fetch origin
You've still got some config missing - in particular, you have a local master branch which isn't tracking anything.
This is a pretty strange setup, not grabbing all the branches from origin, but I suppose it should work. Of course, like I said in my comment, you may not be saving yourself a whole lot of trouble. Fetching other remote branches doesn't mean you have to create corresponding local branches, and unless those excluded branches diverge extremely from the ones you've grabbed (i.e. contain lots of unique content), you're not saving much bandwidth or disk space.

- 479,068
- 72
- 370
- 318
-
This looks more like it, but you should switch them around. Is the git-new-workdir option similar to the answer by Greg?Is it based on based on git-clone --local? I guess I prefer original answer because I am not so sure about git-clone --local. Does it git-clone --local work well on Windows? – vfclists Nov 16 '10 at 00:33
-
@vfclists: I'm completely confused about what you want here. You've accepted Greg's answer, which is similar to my "answer to the real question", but here you say you prefer the original answer. Since you've said the clone is local, I'm going to *remove* the original answer, because there's no way you actually want to use it in that case. – Cascabel Nov 16 '10 at 01:04
-
@vfclists: `git clone --local`, as it says in the manpage, is essentially a no-op. Whenever you clone locally, it automatically uses those settings, creating hard links as described in both Greg's and my answer. The `git new-workdir` script is similar, but uses symlinks instead, at a slightly higher level, and shares refs as well (a clone will only share objects, which are essentially immutable). – Cascabel Nov 16 '10 at 01:05
-
1Your 'original answer' fitted my question better, in the sense that it did not involve any 'hackery' or 'shortcuts'. It only involved fetching just the branches needed from the remote. Us Windows folks are a tad suspicious about hardlinks, symlinks and all that. – vfclists Nov 16 '10 at 09:06
-
Your 'original answer' fitted my question better, in the sense that it did not involve any 'hackery' or 'shortcuts'. It only involved fetching just the branches needed from the remote. Us Windows folks are a tad suspicious about hardlinks, symlinks and all that. But the hardlinking/symlinking approach is better if it is safe, and is fully compatible in Windows. I use substed drives as my primary in Windows and I am concerned about any unwanted side effects there. I was put off by the warnings about the --shared option although on examination it appears that few people will use it. – vfclists Nov 16 '10 at 09:18
-
@vfclists: The original answer was way, way hackier than this. And like I've said repeatedly, unless the branches have diverged so much that they're practically separate projects, you're going to save a trivial amount of space that way. – Cascabel Nov 16 '10 at 13:01
-
I'm curious why this answer received a downvote. Is it because I so aggressively tried to talk the OP out of doing this? Do you disagree? – Cascabel Nov 16 '10 at 14:00
If you're working on two branches in two separate directories, then you can set up one to be a clone of the other:
git clone http://remote/repo.git branch-a
git clone branch-a branch-b
Then, fix the origin
remote in branch-b
:
cd branch-b
git remote add origin http://remote/repo.git
(you may have to remove the previous origin
first). This way, the local repository information will be shared by hard links between the two directories, saving you some space compared to making two separate clones of the remote.
Or, go buy a 1 TB drive, they're cheap.

- 951,095
- 183
- 1,149
- 1,285
-
You will indeed need to remove origin first (`git remote rm origin`). – Cascabel Nov 16 '10 at 01:08