Mark Harrison
Mark Harrison

Reputation: 304722

Does "git clone" create a totally relative directory?

i.e., can I

cd d1
git clone .../foo
mv foo ../d2

and use d2/foo normally?

Is there any later git operation that would pin the git directory to an absolute path?

Upvotes: 2

Views: 4424

Answers (3)

Kaz
Kaz

Reputation: 58666

The scoop is basically this:

~/test$ mkdir origrepo
~/test$ cd origrepo/
~/test/origrepo$ git init
Initialized empty Git repository in /home/kaz/test/origrepo/.git/
~/test/origrepo$ cd ..
~/test$ mkdir d1
~/test$ cd d1
~/test/d1$ git clone ../origrepo
Cloning into 'origrepo'...
done.
warning: You appear to have cloned an empty repository.
~/test/d1$ cat origrepo/.git/config 
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = /home/kaz/test/d1/../origrepo
[branch "master"]
    remote = origin
    merge = refs/heads/master
    rebase = true

None of the objects in the cloned repo's tree will be absolute or relative to the original directory in any way (unless someone has done something silly, like store absolute symlinks in version control, which are expected to resolve within the tree itself).

The actual objects in the git database have abstract names having nothing to do with their path names in the checked out tree. (A "bare" git repository doesn't even have a checked out tree). The names in the index are relative.

However, as we can see from the above dump of the .git/config file, the reference to the upstream remote is absolute: /home/kaz/test/d1/../origrepo.

If we move the repo /home/kaz/test/d1/../origrepo; then any git operations which access the remote will not work, like git fetch or git ls-remote.

If the remote moves, we have to edit the URL in the config file, or use git remote set-url ... command to fix it.

The fact that the reference is absolute has nothing to do with it. Even if the reference were relative like this:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = ../../origrepo   ## probably doesn't work!

at best (if it worked) it would allow these two git repos to be moved together as a unit. If the original repo is move relative to the new one, the relative path doesn't help.

On the other hand, the reference being absolute lets us move the newly cloned repo (within the same filesystem), such that it still refers to its remote. That wouldn't work if it were relative.

Upvotes: 1

Todd
Todd

Reputation: 3113

Yes, you can git clone into any directory and move it around to any other directory and use it "normally". All git really cares about is the .git folder, and that the subdirectories of the project match the repository's history.

If you are trying to prevent someone from modifying the directory structure or moving the location around, you may need to employ your system's administration policies and tools.

Upvotes: 4

trent
trent

Reputation: 28075

A git repository doesn't know where it is; you can do this with no fear of weird consequences.

Of course, if you move the original repository, the clone won't know where to pull from (remotes are absolute paths). This is the only caveat to moving repositories (that I know of).

Upvotes: 3

Related Questions