Andy Andy - 1 month ago 15
Git Question

Does a git clone/push/pull mirror the exact contents of the repos involved?

I wasn't sure how to word the question, so apologies if it's not clear. If you

git clone
a repo that had a bunch of dangling objects, do you clone those? Same for the opposite. If you did a
git gc
and pushed that to someone else, does their repo lose anything the
git gc
would have cleaned up?

I would guess that neither of these would occur, but I can't find any documentation on this scenario.

I found some information that seems to imply that with most protocols
git clone
gives you a clean repo, but if you specify the file using a file path it copies everything.

The main reason to specify the file:// prefix is if you want a clean copy of the
repository with extraneous references or objects left out.

Answer

Git clone doesn't clone dangling objects.

And your git gc will not in any way affect the remote repo when you push to it, unless your push causes dangling objects and then a git gc is run on remote to remove those.

Unless....

It was a shared clone ( specified with the --shared or -s flag) or a local clone (--local or -l). From the docs:

-l

When the repository to clone from is on a local machine, this flag bypasses the normal "git aware" transport mechanism and clones the repository by making a copy of HEAD and everything under objects and refs directories. The files under .git/objects/ directory are hardlinked to save space when possible. This is now the default when the source repository is specified with /path/to/repo syntax, so it essentially is a no-op option. To force copying instead of hardlinking (which may be desirable if you are trying to make a back-up of your repository), but still avoid the usual "git aware" transport mechanism, --no-hardlinks can be used.

-s

When the repository to clone is on the local machine, instead of using hard links, automatically setup .git/objects/info/alternates to share the objects with the source repository. The resulting repository starts out without any object of its own.

NOTE: this is a possibly dangerous operation; do not use it unless you understand what it does. If you clone your repository using this option and then delete branches (or use any other git command that makes any existing commit unreferenced) in the source repository, some objects may become unreferenced (or dangling). These objects may be removed by normal git operations (such as git commit) which automatically call git gc --auto.

So when you do a git clone /path/to/repo you are copying the objects ( or creating hardlinks) and you will get the dangling object in this case. In other cases ( using git protocols, ssh, file protocol etc. ) you will never get the dangling objects in the clone.

Look here for how the transport happens - http://progit.org/book/ch9-6.html

Comments