diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2015-06-01 22:15:11 +0200 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2015-06-01 22:15:11 +0200 |
commit | 10940736887e279583e6b14d7e25de5db73768e1 (patch) | |
tree | 0e28e060fd4e4bafe58a06eaaa915612d6524ec4 /src/clone.c | |
parent | be5fda75879f7ed89c7a72adc257872d1ea13803 (diff) | |
download | libgit2-cmn/link-fallback.tar.gz |
clone: fall back to copying when linking does not workcmn/link-fallback
We use heuristics to make a decent guess at when we can save time and
space by linking object files during a clone. Unfortunately checking the
device id isn't enough, as those would be the same during e.g. a bind-mount,
but the OS still does not allow us to link between mounts of the same
filesystem.
If we fail to perform the links, fall back to copying the contents into
a new file as a last attempt.
Diffstat (limited to 'src/clone.c')
-rw-r--r-- | src/clone.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/src/clone.c b/src/clone.c index 8b42ce706..070daf94d 100644 --- a/src/clone.c +++ b/src/clone.c @@ -532,8 +532,21 @@ static int clone_local_into(git_repository *repo, git_remote *remote, const git_ if (can_link(git_repository_path(src), git_repository_path(repo), link)) flags |= GIT_CPDIR_LINK_FILES; - if ((error = git_futils_cp_r(git_buf_cstr(&src_odb), git_buf_cstr(&dst_odb), - flags, GIT_OBJECT_DIR_MODE)) < 0) + error = git_futils_cp_r(git_buf_cstr(&src_odb), git_buf_cstr(&dst_odb), + flags, GIT_OBJECT_DIR_MODE); + + /* + * can_link() doesn't catch all variations, so if we hit an + * error and did want to link, let's try again without trying + * to link. + */ + if (error < 0 && link) { + flags &= ~GIT_CPDIR_LINK_FILES; + error = git_futils_cp_r(git_buf_cstr(&src_odb), git_buf_cstr(&dst_odb), + flags, GIT_OBJECT_DIR_MODE); + } + + if (error < 0) goto cleanup; git_buf_printf(&reflog_message, "clone: from %s", git_remote_url(remote)); |