]> git.proxmox.com Git - libgit2.git/blame - tests/clone/local.c
New upstream version 1.3.0+dfsg.1
[libgit2.git] / tests / clone / local.c
CommitLineData
121b2673
CMN
1#include "clar_libgit2.h"
2
3#include "git2/clone.h"
4#include "clone.h"
5#include "buffer.h"
2614819c
CMN
6#include "path.h"
7#include "posix.h"
22a2d3d5 8#include "futils.h"
121b2673 9
529fd30d
ET
10static int file_url(git_buf *buf, const char *host, const char *path)
11{
12 if (path[0] == '/')
13 path++;
14
15 git_buf_clear(buf);
16 return git_buf_printf(buf, "file://%s/%s", host, path);
17}
18
7d7f6d33 19#ifdef GIT_WIN32
12f32d91
ET
20static int git_style_unc_path(git_buf *buf, const char *host, const char *path)
21{
22 git_buf_clear(buf);
23
24 if (host)
25 git_buf_printf(buf, "//%s/", host);
26
27 if (path[0] == '/')
28 path++;
29
16288d2d 30 if (git__isalpha(path[0]) && path[1] == ':' && path[2] == '/') {
12f32d91
ET
31 git_buf_printf(buf, "%c$/", path[0]);
32 path += 3;
33 }
34
35 git_buf_puts(buf, path);
36
37 return git_buf_oom(buf) ? -1 : 0;
38}
39
40static int unc_path(git_buf *buf, const char *host, const char *path)
41{
42 char *c;
43
44 if (git_style_unc_path(buf, host, path) < 0)
45 return -1;
46
47 for (c = buf->ptr; *c; c++)
48 if (*c == '/')
49 *c = '\\';
50
51 return 0;
52}
7d7f6d33 53#endif
12f32d91 54
121b2673
CMN
55void test_clone_local__should_clone_local(void)
56{
57 git_buf buf = GIT_BUF_INIT;
121b2673
CMN
58
59 /* we use a fixture path because it needs to exist for us to want to clone */
529fd30d
ET
60 const char *path = cl_fixture("testrepo.git");
61
62 cl_git_pass(file_url(&buf, "", path));
63 cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO));
64 cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL));
65 cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS));
66 cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_NO_LOCAL));
121b2673 67
529fd30d
ET
68 cl_git_pass(file_url(&buf, "localhost", path));
69 cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO));
70 cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL));
71 cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS));
72 cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_NO_LOCAL));
73
74 cl_git_pass(file_url(&buf, "other-host.mycompany.com", path));
75 cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO));
76 cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL));
77 cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS));
78 cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_NO_LOCAL));
79
80 /* Ensure that file:/// urls are percent decoded: .git == %2e%67%69%74 */
81 cl_git_pass(file_url(&buf, "", path));
82 git_buf_shorten(&buf, 4);
83 cl_git_pass(git_buf_puts(&buf, "%2e%67%69%74"));
84 cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO));
85 cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL));
86 cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS));
87 cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_NO_LOCAL));
88
89 cl_assert_equal_i(1, git_clone__should_clone_local(path, GIT_CLONE_LOCAL_AUTO));
90 cl_assert_equal_i(1, git_clone__should_clone_local(path, GIT_CLONE_LOCAL));
91 cl_assert_equal_i(1, git_clone__should_clone_local(path, GIT_CLONE_LOCAL_NO_LINKS));
92 cl_assert_equal_i(0, git_clone__should_clone_local(path, GIT_CLONE_NO_LOCAL));
93
ac3d33df 94 git_buf_dispose(&buf);
121b2673 95}
2614819c
CMN
96
97void test_clone_local__hardlinks(void)
98{
99 git_repository *repo;
6812afaf 100 git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
2614819c
CMN
101 git_buf buf = GIT_BUF_INIT;
102 struct stat st;
103
bc9f67fa
CMN
104 /*
105 * In this first clone, we just copy over, since the temp dir
106 * will often be in a different filesystem, so we cannot
107 * link. It also allows us to control the number of links
108 */
6812afaf
CMN
109 opts.bare = true;
110 opts.local = GIT_CLONE_LOCAL_NO_LINKS;
111 cl_git_pass(git_clone(&repo, cl_fixture("testrepo.git"), "./clone.git", &opts));
2614819c
CMN
112 git_repository_free(repo);
113
bc9f67fa 114 /* This second clone is in the same filesystem, so we can hardlink */
2614819c 115
6812afaf
CMN
116 opts.local = GIT_CLONE_LOCAL;
117 cl_git_pass(git_clone(&repo, cl_git_path_url("clone.git"), "./clone2.git", &opts));
2614819c
CMN
118
119#ifndef GIT_WIN32
120 git_buf_clear(&buf);
121 cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
122
123 cl_git_pass(p_stat(buf.ptr, &st));
bc9f67fa 124 cl_assert_equal_i(2, st.st_nlink);
2614819c
CMN
125#endif
126
2614819c
CMN
127 git_repository_free(repo);
128 git_buf_clear(&buf);
129
6812afaf
CMN
130 opts.local = GIT_CLONE_LOCAL_NO_LINKS;
131 cl_git_pass(git_clone(&repo, cl_git_path_url("clone.git"), "./clone3.git", &opts));
2614819c
CMN
132
133 git_buf_clear(&buf);
134 cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
135
136 cl_git_pass(p_stat(buf.ptr, &st));
137 cl_assert_equal_i(1, st.st_nlink);
138
bc9f67fa
CMN
139 git_repository_free(repo);
140
141 /* this one should automatically use links */
142 cl_git_pass(git_clone(&repo, "./clone.git", "./clone4.git", NULL));
143
144#ifndef GIT_WIN32
145 git_buf_clear(&buf);
146 cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
147
148 cl_git_pass(p_stat(buf.ptr, &st));
149 cl_assert_equal_i(3, st.st_nlink);
150#endif
151
ac3d33df 152 git_buf_dispose(&buf);
2614819c 153 git_repository_free(repo);
bc9f67fa
CMN
154
155 cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES));
156 cl_git_pass(git_futils_rmdir_r("./clone2.git", NULL, GIT_RMDIR_REMOVE_FILES));
157 cl_git_pass(git_futils_rmdir_r("./clone3.git", NULL, GIT_RMDIR_REMOVE_FILES));
158 cl_git_pass(git_futils_rmdir_r("./clone4.git", NULL, GIT_RMDIR_REMOVE_FILES));
2614819c 159}
12f32d91
ET
160
161void test_clone_local__standard_unc_paths_are_written_git_style(void)
162{
163#ifdef GIT_WIN32
164 git_repository *repo;
165 git_remote *remote;
166 git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
167 git_buf unc = GIT_BUF_INIT, git_unc = GIT_BUF_INIT;
168
169 /* we use a fixture path because it needs to exist for us to want to clone */
170 const char *path = cl_fixture("testrepo.git");
171
172 cl_git_pass(unc_path(&unc, "localhost", path));
173 cl_git_pass(git_style_unc_path(&git_unc, "localhost", path));
174
175 cl_git_pass(git_clone(&repo, unc.ptr, "./clone.git", &opts));
209425ce 176 cl_git_pass(git_remote_lookup(&remote, repo, "origin"));
12f32d91
ET
177
178 cl_assert_equal_s(git_unc.ptr, git_remote_url(remote));
179
180 git_remote_free(remote);
181 git_repository_free(repo);
ac3d33df
JK
182 git_buf_dispose(&unc);
183 git_buf_dispose(&git_unc);
12f32d91
ET
184
185 cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES));
186#endif
187}
188
189void test_clone_local__git_style_unc_paths(void)
190{
191#ifdef GIT_WIN32
192 git_repository *repo;
193 git_remote *remote;
194 git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
195 git_buf git_unc = GIT_BUF_INIT;
196
197 /* we use a fixture path because it needs to exist for us to want to clone */
198 const char *path = cl_fixture("testrepo.git");
199
200 cl_git_pass(git_style_unc_path(&git_unc, "localhost", path));
201
202 cl_git_pass(git_clone(&repo, git_unc.ptr, "./clone.git", &opts));
209425ce 203 cl_git_pass(git_remote_lookup(&remote, repo, "origin"));
12f32d91
ET
204
205 cl_assert_equal_s(git_unc.ptr, git_remote_url(remote));
206
207 git_remote_free(remote);
208 git_repository_free(repo);
ac3d33df 209 git_buf_dispose(&git_unc);
12f32d91
ET
210
211 cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES));
212#endif
213}