0

I have a clone of a remote repository. When I need another copy of that repository, if I clone that local clone, then origin is pointing to the the first clone. So instead, I just cp -a first second, but this is a waste of space because it makes a full copy of .git/objects.

So, how can I do a second clone and have it in the exact same configuration with storage efficiency (no I'm not running a fs that could use cp -a --reflink)

CodeWizard
  • 128,036
  • 21
  • 144
  • 167
Benoît
  • 3,355
  • 2
  • 29
  • 34

2 Answers2

6

You can use git worktree for this task.

Git worktree use a single repo and allow you to checkout any desired branch on different folders.

Git had this ability since 2007. Under cotrib folder the was an hidden command named 'new-workdir' which was later on added to gin inversion 2.5 and was renamed to git worktree.

git worktree

git worktree will create a new working folder allow us to work on multiple branches on the same time. each copy will point to the origin repository while the 3-states is a new and fresh copy. This save us the need to use git stash or even to clone a new repository since those worktree shares the same repo we can checkout any branch on any worktree, we can do a cherry-pick or merge and all will be done locally on our machine.

Usage:

git worktree add <second path>

will create another folder on your computer which allow you to work on different branch simultaneously.

This will allow you do to any experimentals on the new worktree without having any effect on the repository itself. In the attached image you can see that there are 2 separate working folder but both of them are using a single repo and share the content.

enter image description here


Now since the 2 worktree shares the same .git folder you can use git cherry-pick to grab any commit or file for a specific commit and add it to any existing worktree that you have created.

enter image description here

Community
  • 1
  • 1
CodeWizard
  • 128,036
  • 21
  • 144
  • 167
  • I'm lost. Done that. Made 2 commits. Now in detached head. Created a temp branch. Cannot push without arguments. – Benoît Feb 25 '17 at 15:40
  • read this post on how to recover from detached head. http://stackoverflow.com/questions/34519665/how-to-move-head-back-to-a-previous-location-detached-head/34519716#34519716 – CodeWizard Feb 25 '17 at 15:46
  • But is this normal that worktree creates a detached head in the first place ? – Benoît Feb 25 '17 at 15:48
  • Nope. you did not checkout the desired branch i assume. maybe you did git checkout `origin/branch` simple do a `git checkout -b ` and it will fix your problem – CodeWizard Feb 25 '17 at 15:52
  • 1
    I only did a git worktree ../wip origin.wip and did 2 commits. I wasn't expecting this. But now I'm fine. – Benoît Feb 25 '17 at 16:28
1

https://git.wiki.kernel.org/index.php/Git_FAQ#How_to_share_objects_between_existing_repositories.3F

How to share objects between existing repositories?

Do

echo "/source/git/project/.git/objects/" > .git/objects/info/alternates

and then follow it up with

git repack -a -d -l

where the '-l' means that it will only put local objects in the pack-file (strictly speaking, it will put any loose objects from the alternate tree too, so you'll have a fully packed archive, but it won't duplicate objects that are already packed in the alternate tree).

exussum
  • 18,275
  • 8
  • 32
  • 65