]>
Commit | Line | Data |
---|---|---|
aa13bf05 RB |
1 | #include "clar_libgit2.h" |
2 | #include "buffer.h" | |
3 | #include "path.h" | |
4 | #include "util.h" | |
5 | #include "posix.h" | |
6 | #include "submodule_helpers.h" | |
867f7c9b | 7 | #include "git2/sys/repository.h" |
aa13bf05 RB |
8 | |
9 | /* rewrite gitmodules -> .gitmodules | |
10 | * rewrite the empty or relative urls inside each module | |
11 | * rename the .gitted directory inside any submodule to .git | |
12 | */ | |
13 | void rewrite_gitmodules(const char *workdir) | |
14 | { | |
15 | git_buf in_f = GIT_BUF_INIT, out_f = GIT_BUF_INIT, path = GIT_BUF_INIT; | |
16 | FILE *in, *out; | |
17 | char line[256]; | |
18 | ||
19 | cl_git_pass(git_buf_joinpath(&in_f, workdir, "gitmodules")); | |
20 | cl_git_pass(git_buf_joinpath(&out_f, workdir, ".gitmodules")); | |
21 | ||
22 | cl_assert((in = fopen(in_f.ptr, "r")) != NULL); | |
23 | cl_assert((out = fopen(out_f.ptr, "w")) != NULL); | |
24 | ||
25 | while (fgets(line, sizeof(line), in) != NULL) { | |
26 | char *scan = line; | |
27 | ||
28 | while (*scan == ' ' || *scan == '\t') scan++; | |
29 | ||
30 | /* rename .gitted -> .git in submodule directories */ | |
31 | if (git__prefixcmp(scan, "path =") == 0) { | |
32 | scan += strlen("path ="); | |
33 | while (*scan == ' ') scan++; | |
34 | ||
35 | git_buf_joinpath(&path, workdir, scan); | |
36 | git_buf_rtrim(&path); | |
37 | git_buf_joinpath(&path, path.ptr, ".gitted"); | |
38 | ||
39 | if (!git_buf_oom(&path) && p_access(path.ptr, F_OK) == 0) { | |
40 | git_buf_joinpath(&out_f, workdir, scan); | |
41 | git_buf_rtrim(&out_f); | |
42 | git_buf_joinpath(&out_f, out_f.ptr, ".git"); | |
43 | ||
44 | if (!git_buf_oom(&out_f)) | |
45 | p_rename(path.ptr, out_f.ptr); | |
46 | } | |
47 | } | |
48 | ||
49 | /* copy non-"url =" lines verbatim */ | |
50 | if (git__prefixcmp(scan, "url =") != 0) { | |
51 | fputs(line, out); | |
52 | continue; | |
53 | } | |
54 | ||
55 | /* convert relative URLs in "url =" lines */ | |
56 | scan += strlen("url ="); | |
57 | while (*scan == ' ') scan++; | |
58 | ||
59 | if (*scan == '.') { | |
60 | git_buf_joinpath(&path, workdir, scan); | |
61 | git_buf_rtrim(&path); | |
62 | } else if (!*scan || *scan == '\n') { | |
63 | git_buf_joinpath(&path, workdir, "../testrepo.git"); | |
64 | } else { | |
65 | fputs(line, out); | |
66 | continue; | |
67 | } | |
68 | ||
69 | git_path_prettify(&path, path.ptr, NULL); | |
70 | git_buf_putc(&path, '\n'); | |
71 | cl_assert(!git_buf_oom(&path)); | |
72 | ||
73 | fwrite(line, scan - line, sizeof(char), out); | |
74 | fputs(path.ptr, out); | |
75 | } | |
76 | ||
77 | fclose(in); | |
78 | fclose(out); | |
79 | ||
80 | cl_must_pass(p_unlink(in_f.ptr)); | |
81 | ||
82 | git_buf_free(&in_f); | |
83 | git_buf_free(&out_f); | |
84 | git_buf_free(&path); | |
85 | } | |
125655fe | 86 | |
d5b1866c RB |
87 | static void cleanup_fixture_submodules(void *payload) |
88 | { | |
89 | cl_git_sandbox_cleanup(); /* either "submodules" or "submod2" */ | |
90 | ||
91 | if (payload) | |
92 | cl_fixture_cleanup(payload); | |
93 | } | |
94 | ||
125655fe RB |
95 | git_repository *setup_fixture_submodules(void) |
96 | { | |
97 | git_repository *repo = cl_git_sandbox_init("submodules"); | |
98 | ||
99 | cl_fixture_sandbox("testrepo.git"); | |
100 | ||
101 | rewrite_gitmodules(git_repository_workdir(repo)); | |
102 | p_rename("submodules/testrepo/.gitted", "submodules/testrepo/.git"); | |
103 | ||
d5b1866c RB |
104 | cl_set_cleanup(cleanup_fixture_submodules, "testrepo.git"); |
105 | ||
867f7c9b | 106 | cl_git_pass(git_repository_reinit_filesystem(repo, 1)); |
14997dc5 | 107 | |
125655fe RB |
108 | return repo; |
109 | } | |
110 | ||
111 | git_repository *setup_fixture_submod2(void) | |
112 | { | |
113 | git_repository *repo = cl_git_sandbox_init("submod2"); | |
114 | ||
115 | cl_fixture_sandbox("submod2_target"); | |
116 | p_rename("submod2_target/.gitted", "submod2_target/.git"); | |
117 | ||
118 | rewrite_gitmodules(git_repository_workdir(repo)); | |
119 | p_rename("submod2/not-submodule/.gitted", "submod2/not-submodule/.git"); | |
120 | p_rename("submod2/not/.gitted", "submod2/not/.git"); | |
121 | ||
d5b1866c | 122 | cl_set_cleanup(cleanup_fixture_submodules, "submod2_target"); |
125655fe | 123 | |
867f7c9b | 124 | cl_git_pass(git_repository_reinit_filesystem(repo, 1)); |
14997dc5 | 125 | |
d5b1866c | 126 | return repo; |
125655fe | 127 | } |
a15c7802 RB |
128 | |
129 | void assert_submodule_exists(git_repository *repo, const char *name) | |
130 | { | |
131 | git_submodule *sm; | |
132 | cl_git_pass(git_submodule_lookup(&sm, repo, name)); | |
133 | cl_assert(sm); | |
134 | git_submodule_free(sm); | |
135 | } | |
136 | ||
137 | void refute_submodule_exists( | |
138 | git_repository *repo, const char *name, int expected_error) | |
139 | { | |
140 | git_submodule *sm; | |
141 | cl_assert_equal_i( | |
142 | expected_error, git_submodule_lookup(&sm, repo, name)); | |
143 | } | |
144 | ||
145 | unsigned int get_submodule_status(git_repository *repo, const char *name) | |
146 | { | |
147 | git_submodule *sm = NULL; | |
148 | unsigned int status = 0; | |
149 | ||
150 | cl_git_pass(git_submodule_lookup(&sm, repo, name)); | |
151 | cl_assert(sm); | |
152 | cl_git_pass(git_submodule_status(&status, sm)); | |
153 | git_submodule_free(sm); | |
154 | ||
155 | return status; | |
156 | } |