tags:

views:

400

answers:

3

If I make a copy of a tracked folder using rsync -a or cp -R, can I then use the copy as if it were a git clone, or will that cause all sorts of weird problems? This is all running on my computer, so no one else is accessing the repository.

Obviously, the git-cloned dir know where it was copied from, so I can do git pull without specifying a source, but assuming I am willing to live without that, is there something I need to worry about?

As an experiment, I created a little project, cloned it and rsynced it, and diffed the resulting folders. Here are the results:

itsadok@quad ~
$ git clone project/.git project2
Initialized empty Git repository in /home/itsadok/project2/.git/

itsadok@quad ~
$ rsync -a project/ project3/

itsadok@quad ~
$ diff -r project2 project3
Only in project3/.git: COMMIT_EDITMSG
diff -r project2/.git/config project3/.git/config
7,12d6
< [remote "origin"]
<       url = /home/itsadok/project/.git
<       fetch = +refs/heads/*:refs/remotes/origin/*
< [branch "master"]
<       remote = origin
<       merge = refs/heads/master
Files project2/.git/index and project3/.git/index differ
diff -r project2/.git/logs/HEAD project3/.git/logs/HEAD
1c1
< 0000000000000000000000000000000000000000 bf6be23d68d0ede45aca7479795693bfba76e73a itsadok <itsadok@quad.(none)> 1242131284 +0300      clone: from /home/itsadok/project/.git
---
> 0000000000000000000000000000000000000000 bf6be23d68d0ede45aca7479795693bfba76e73a itsadok <itsadok@quad.(none)> 1242131066 +0300      commit (initial): first commit
diff -r project2/.git/logs/refs/heads/master project3/.git/logs/refs/heads/master
1c1
< 0000000000000000000000000000000000000000 bf6be23d68d0ede45aca7479795693bfba76e73a itsadok <itsadok@quad.(none)> 1242131284 +0300      clone: from /home/itsadok/project/.git
---
> 0000000000000000000000000000000000000000 bf6be23d68d0ede45aca7479795693bfba76e73a itsadok <itsadok@quad.(none)> 1242131066 +0300      commit (initial): first commit
Only in project2/.git/logs/refs: remotes
Only in project2/.git: packed-refs
Only in project2/.git/refs: remotes

There's quite a bit of a difference, but most of it seems to be about the reference to the origin. Am I right?

+1  A: 

When you clone someone else’s repository, it basically just copies the contents of this directory to your computer.

From the real good Git Internals (Scott Chacon) from Peepcode Press. (Page 44) So just the reference to the origin is missing as far as I'm concerned/I see.

With best regards.

David Klein
I assume you mean peepcode, not peedcode. :)
Andrew Grimm
+9  A: 

It is safe.

The difference in using "git clone" is that it automatically sets up the origin repository, so that you can easily use "git pull" and "git push" to synchronize the two repositories. Also "git clone" does not copy the logs, index and other configuration that is local to a repository. It only copies the version history of the repository (and even that can be stored at byte-level differently, because Git every now and then compresses its database when using "git gc").

Those differences that you see in your example are because rsnc copied also the working directory index, logs and because the rsync-copy did not set up the remote origin. There are quite many configuration and log files that are local to a repository. But there is no danger in copying them directly, for example when restoring backups or moving the repository to another directory/harddrive/machine.

Esko Luontola
Another way of putting this is that git clone does in fact completely clone the "objects" directory when it's used to clone a repo on the same machine--- it just uses cpio to copy everything, converting to hard links if the destination is the same filesystem. Everything outside the objects directory is local information anyway. Simply copying those wholesale (a la cp -R) rather than recreating them (which is what git clone does) should be quite safe. Provided the copied hooks don't do anything too bizarre, of course.
araqnid
+1  A: 

It's exactly the same, well, almost, if you want the same in 'project3' just do:

git remote add origin /home/itsadok/project
git branch -f master origin/master
felipec