rugged 0.21.4 → 0.22.0b1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (224) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -5
  3. data/ext/rugged/extconf.rb +9 -9
  4. data/ext/rugged/rugged.c +4 -2
  5. data/ext/rugged/rugged.h +3 -7
  6. data/ext/rugged/rugged_blob.c +57 -0
  7. data/ext/rugged/rugged_cred.c +23 -0
  8. data/ext/rugged/rugged_index.c +6 -2
  9. data/ext/rugged/rugged_remote.c +65 -52
  10. data/ext/rugged/rugged_remote_collection.c +59 -10
  11. data/ext/rugged/rugged_repo.c +345 -11
  12. data/ext/rugged/rugged_revwalk.c +10 -0
  13. data/ext/rugged/rugged_submodule.c +1042 -0
  14. data/ext/rugged/rugged_submodule_collection.c +236 -0
  15. data/ext/rugged/rugged_tag_collection.c +70 -2
  16. data/ext/rugged/rugged_tree.c +29 -10
  17. data/lib/rugged.rb +3 -0
  18. data/lib/rugged/attributes.rb +41 -0
  19. data/lib/rugged/blob.rb +28 -0
  20. data/lib/rugged/diff.rb +0 -1
  21. data/lib/rugged/diff/line.rb +1 -3
  22. data/lib/rugged/patch.rb +12 -2
  23. data/lib/rugged/repository.rb +7 -0
  24. data/lib/rugged/submodule_collection.rb +48 -0
  25. data/lib/rugged/version.rb +1 -1
  26. data/vendor/libgit2/CMakeLists.txt +27 -3
  27. data/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake +324 -0
  28. data/vendor/libgit2/deps/http-parser/http_parser.h +2 -0
  29. data/vendor/libgit2/deps/zlib/adler32.c +39 -29
  30. data/vendor/libgit2/deps/zlib/crc32.c +33 -50
  31. data/vendor/libgit2/deps/zlib/crc32.h +1 -1
  32. data/vendor/libgit2/deps/zlib/deflate.c +198 -65
  33. data/vendor/libgit2/deps/zlib/deflate.h +8 -4
  34. data/vendor/libgit2/deps/zlib/infback.c +640 -0
  35. data/vendor/libgit2/deps/zlib/inffast.c +3 -3
  36. data/vendor/libgit2/deps/zlib/inffixed.h +3 -3
  37. data/vendor/libgit2/deps/zlib/inflate.c +84 -52
  38. data/vendor/libgit2/deps/zlib/inftrees.c +15 -39
  39. data/vendor/libgit2/deps/zlib/trees.c +18 -36
  40. data/vendor/libgit2/deps/zlib/zconf.h +4 -0
  41. data/vendor/libgit2/deps/zlib/zlib.h +250 -95
  42. data/vendor/libgit2/deps/zlib/zutil.c +13 -10
  43. data/vendor/libgit2/deps/zlib/zutil.h +41 -62
  44. data/vendor/libgit2/include/git2.h +4 -0
  45. data/vendor/libgit2/include/git2/annotated_commit.h +99 -0
  46. data/vendor/libgit2/include/git2/attr.h +16 -13
  47. data/vendor/libgit2/include/git2/branch.h +11 -0
  48. data/vendor/libgit2/include/git2/buffer.h +16 -0
  49. data/vendor/libgit2/include/git2/checkout.h +12 -12
  50. data/vendor/libgit2/include/git2/cherrypick.h +15 -15
  51. data/vendor/libgit2/include/git2/clone.h +77 -69
  52. data/vendor/libgit2/include/git2/common.h +13 -1
  53. data/vendor/libgit2/include/git2/config.h +0 -14
  54. data/vendor/libgit2/include/git2/describe.h +162 -0
  55. data/vendor/libgit2/include/git2/diff.h +13 -8
  56. data/vendor/libgit2/include/git2/errors.h +5 -0
  57. data/vendor/libgit2/include/git2/global.h +38 -0
  58. data/vendor/libgit2/include/git2/merge.h +38 -64
  59. data/vendor/libgit2/include/git2/net.h +2 -2
  60. data/vendor/libgit2/include/git2/notes.h +17 -0
  61. data/vendor/libgit2/include/git2/oid.h +8 -4
  62. data/vendor/libgit2/include/git2/oidarray.h +40 -0
  63. data/vendor/libgit2/include/git2/rebase.h +261 -0
  64. data/vendor/libgit2/include/git2/reflog.h +1 -1
  65. data/vendor/libgit2/include/git2/remote.h +25 -47
  66. data/vendor/libgit2/include/git2/repository.h +4 -1
  67. data/vendor/libgit2/include/git2/reset.h +10 -1
  68. data/vendor/libgit2/include/git2/revert.h +1 -1
  69. data/vendor/libgit2/include/git2/revwalk.h +28 -23
  70. data/vendor/libgit2/include/git2/status.h +19 -15
  71. data/vendor/libgit2/include/git2/submodule.h +18 -0
  72. data/vendor/libgit2/include/git2/sys/config.h +0 -1
  73. data/vendor/libgit2/{src → include/git2/sys}/hashsig.h +11 -7
  74. data/vendor/libgit2/include/git2/sys/refdb_backend.h +13 -0
  75. data/vendor/libgit2/include/git2/sys/refs.h +0 -11
  76. data/vendor/libgit2/include/git2/sys/repository.h +13 -0
  77. data/vendor/libgit2/include/git2/sys/transport.h +352 -0
  78. data/vendor/libgit2/include/git2/threads.h +10 -20
  79. data/vendor/libgit2/include/git2/transaction.h +111 -0
  80. data/vendor/libgit2/include/git2/transport.h +79 -313
  81. data/vendor/libgit2/include/git2/tree.h +4 -2
  82. data/vendor/libgit2/include/git2/types.h +77 -8
  83. data/vendor/libgit2/include/git2/version.h +2 -2
  84. data/vendor/libgit2/src/annotated_commit.c +121 -0
  85. data/vendor/libgit2/src/annotated_commit.h +22 -0
  86. data/vendor/libgit2/src/attr.c +8 -4
  87. data/vendor/libgit2/src/attr_file.c +24 -2
  88. data/vendor/libgit2/src/blame.c +0 -1
  89. data/vendor/libgit2/src/branch.c +32 -3
  90. data/vendor/libgit2/src/buf_text.c +9 -5
  91. data/vendor/libgit2/src/buf_text.h +3 -2
  92. data/vendor/libgit2/src/buffer.c +67 -10
  93. data/vendor/libgit2/src/buffer.h +4 -2
  94. data/vendor/libgit2/src/cache.c +9 -9
  95. data/vendor/libgit2/src/cache.h +1 -1
  96. data/vendor/libgit2/src/cc-compat.h +2 -0
  97. data/vendor/libgit2/src/checkout.c +263 -82
  98. data/vendor/libgit2/src/checkout.h +1 -0
  99. data/vendor/libgit2/src/cherrypick.c +41 -44
  100. data/vendor/libgit2/src/clone.c +96 -58
  101. data/vendor/libgit2/src/commit.c +5 -31
  102. data/vendor/libgit2/src/commit_list.h +3 -1
  103. data/vendor/libgit2/src/config.c +0 -17
  104. data/vendor/libgit2/src/config_cache.c +0 -2
  105. data/vendor/libgit2/src/config_file.c +12 -15
  106. data/vendor/libgit2/src/crlf.c +2 -1
  107. data/vendor/libgit2/src/describe.c +886 -0
  108. data/vendor/libgit2/src/diff.c +29 -3
  109. data/vendor/libgit2/src/diff_file.c +1 -0
  110. data/vendor/libgit2/src/diff_patch.c +2 -3
  111. data/vendor/libgit2/src/diff_print.c +11 -9
  112. data/vendor/libgit2/src/diff_tform.c +4 -4
  113. data/vendor/libgit2/src/errors.c +9 -7
  114. data/vendor/libgit2/src/fetch.c +6 -6
  115. data/vendor/libgit2/src/fetchhead.h +2 -4
  116. data/vendor/libgit2/src/filebuf.c +0 -2
  117. data/vendor/libgit2/src/filebuf.h +2 -3
  118. data/vendor/libgit2/src/fileops.c +9 -7
  119. data/vendor/libgit2/src/global.c +44 -35
  120. data/vendor/libgit2/src/global.h +2 -0
  121. data/vendor/libgit2/src/graph.c +2 -2
  122. data/vendor/libgit2/src/hash.h +3 -1
  123. data/vendor/libgit2/src/hash/hash_common_crypto.h +44 -0
  124. data/vendor/libgit2/src/hash/hash_win32.c +1 -1
  125. data/vendor/libgit2/src/hashsig.c +1 -1
  126. data/vendor/libgit2/src/ignore.c +5 -88
  127. data/vendor/libgit2/src/index.c +70 -57
  128. data/vendor/libgit2/src/index.h +1 -0
  129. data/vendor/libgit2/src/indexer.c +16 -5
  130. data/vendor/libgit2/src/iterator.c +70 -1
  131. data/vendor/libgit2/src/iterator.h +5 -1
  132. data/vendor/libgit2/src/map.h +0 -1
  133. data/vendor/libgit2/src/merge.c +203 -327
  134. data/vendor/libgit2/src/merge.h +3 -13
  135. data/vendor/libgit2/src/mwindow.c +119 -8
  136. data/vendor/libgit2/src/mwindow.h +9 -1
  137. data/vendor/libgit2/src/netops.c +7 -8
  138. data/vendor/libgit2/src/netops.h +6 -16
  139. data/vendor/libgit2/src/notes.c +31 -4
  140. data/vendor/libgit2/src/notes.h +3 -0
  141. data/vendor/libgit2/src/odb.c +23 -1
  142. data/vendor/libgit2/src/odb_loose.c +1 -1
  143. data/vendor/libgit2/src/odb_pack.c +6 -3
  144. data/vendor/libgit2/src/oid.c +9 -1
  145. data/vendor/libgit2/src/oid.h +11 -0
  146. data/vendor/libgit2/src/oidarray.c +21 -0
  147. data/vendor/libgit2/src/oidarray.h +18 -0
  148. data/vendor/libgit2/src/oidmap.h +16 -0
  149. data/vendor/libgit2/src/pack.c +20 -7
  150. data/vendor/libgit2/src/pack.h +3 -0
  151. data/vendor/libgit2/src/path.c +120 -293
  152. data/vendor/libgit2/src/path.h +21 -44
  153. data/vendor/libgit2/src/pathspec.c +1 -1
  154. data/vendor/libgit2/src/pool.c +5 -11
  155. data/vendor/libgit2/src/pool.h +0 -2
  156. data/vendor/libgit2/src/posix.c +6 -6
  157. data/vendor/libgit2/src/posix.h +48 -28
  158. data/vendor/libgit2/src/push.c +19 -48
  159. data/vendor/libgit2/src/push.h +2 -4
  160. data/vendor/libgit2/src/rebase.c +1125 -0
  161. data/vendor/libgit2/src/refdb.c +19 -0
  162. data/vendor/libgit2/src/refdb.h +2 -1
  163. data/vendor/libgit2/src/refdb_fs.c +101 -29
  164. data/vendor/libgit2/src/reflog.c +1 -1
  165. data/vendor/libgit2/src/refs.c +38 -3
  166. data/vendor/libgit2/src/refs.h +13 -2
  167. data/vendor/libgit2/src/refspec.c +20 -2
  168. data/vendor/libgit2/src/remote.c +288 -154
  169. data/vendor/libgit2/src/remote.h +5 -1
  170. data/vendor/libgit2/src/repository.c +75 -36
  171. data/vendor/libgit2/src/repository.h +3 -25
  172. data/vendor/libgit2/src/reset.c +5 -1
  173. data/vendor/libgit2/src/revert.c +4 -6
  174. data/vendor/libgit2/src/revparse.c +15 -18
  175. data/vendor/libgit2/src/revwalk.c +96 -22
  176. data/vendor/libgit2/src/revwalk.h +5 -4
  177. data/vendor/libgit2/src/settings.c +22 -0
  178. data/vendor/libgit2/src/signature.c +37 -2
  179. data/vendor/libgit2/src/signature.h +3 -0
  180. data/vendor/libgit2/src/stash.c +17 -12
  181. data/vendor/libgit2/src/status.c +13 -3
  182. data/vendor/libgit2/src/strnlen.h +2 -1
  183. data/vendor/libgit2/src/submodule.c +75 -35
  184. data/vendor/libgit2/src/thread-utils.h +4 -9
  185. data/vendor/libgit2/src/trace.h +9 -1
  186. data/vendor/libgit2/src/transaction.c +352 -0
  187. data/vendor/libgit2/src/transport.c +91 -97
  188. data/vendor/libgit2/src/transports/auth.c +71 -0
  189. data/vendor/libgit2/src/transports/auth.h +63 -0
  190. data/vendor/libgit2/src/transports/auth_negotiate.c +275 -0
  191. data/vendor/libgit2/src/transports/auth_negotiate.h +27 -0
  192. data/vendor/libgit2/src/transports/cred.c +58 -0
  193. data/vendor/libgit2/src/transports/cred.h +14 -0
  194. data/vendor/libgit2/src/transports/cred_helpers.c +3 -0
  195. data/vendor/libgit2/src/transports/git.c +1 -0
  196. data/vendor/libgit2/src/transports/http.c +208 -82
  197. data/vendor/libgit2/src/transports/local.c +2 -2
  198. data/vendor/libgit2/src/transports/smart.c +2 -0
  199. data/vendor/libgit2/src/transports/smart.h +2 -0
  200. data/vendor/libgit2/src/transports/smart_protocol.c +10 -10
  201. data/vendor/libgit2/src/transports/ssh.c +243 -57
  202. data/vendor/libgit2/src/transports/winhttp.c +139 -35
  203. data/vendor/libgit2/src/tree-cache.c +118 -31
  204. data/vendor/libgit2/src/tree-cache.h +12 -7
  205. data/vendor/libgit2/src/tree.c +83 -64
  206. data/vendor/libgit2/src/tree.h +2 -3
  207. data/vendor/libgit2/src/unix/map.c +8 -2
  208. data/vendor/libgit2/src/unix/posix.h +23 -9
  209. data/vendor/libgit2/src/unix/realpath.c +8 -7
  210. data/vendor/libgit2/src/userdiff.h +3 -3
  211. data/vendor/libgit2/src/util.c +2 -92
  212. data/vendor/libgit2/src/util.h +3 -15
  213. data/vendor/libgit2/src/win32/findfile.c +0 -1
  214. data/vendor/libgit2/src/win32/map.c +3 -2
  215. data/vendor/libgit2/src/win32/mingw-compat.h +5 -12
  216. data/vendor/libgit2/src/win32/msvc-compat.h +3 -32
  217. data/vendor/libgit2/src/win32/posix.h +20 -32
  218. data/vendor/libgit2/src/win32/posix_w32.c +103 -31
  219. data/vendor/libgit2/src/win32/utf-conv.c +6 -36
  220. data/vendor/libgit2/src/win32/utf-conv.h +39 -0
  221. data/vendor/libgit2/src/win32/w32_util.h +0 -1
  222. metadata +32 -7
  223. data/vendor/libgit2/src/win32/path_w32.c +0 -305
  224. data/vendor/libgit2/src/win32/path_w32.h +0 -82
@@ -0,0 +1,352 @@
1
+ /*
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+
8
+ #include "common.h"
9
+ #include "repository.h"
10
+ #include "strmap.h"
11
+ #include "refdb.h"
12
+ #include "pool.h"
13
+ #include "reflog.h"
14
+ #include "signature.h"
15
+
16
+ #include "git2/signature.h"
17
+ #include "git2/sys/refs.h"
18
+ #include "git2/sys/refdb_backend.h"
19
+
20
+ GIT__USE_STRMAP;
21
+
22
+ typedef struct {
23
+ const char *name;
24
+ void *payload;
25
+
26
+ git_ref_t ref_type;
27
+ union {
28
+ git_oid id;
29
+ char *symbolic;
30
+ } target;
31
+ git_reflog *reflog;
32
+
33
+ const char *message;
34
+ git_signature *sig;
35
+
36
+ unsigned int committed :1,
37
+ remove :1;
38
+ } transaction_node;
39
+
40
+ struct git_transaction {
41
+ git_repository *repo;
42
+ git_refdb *db;
43
+
44
+ git_strmap *locks;
45
+ git_pool pool;
46
+ };
47
+
48
+ int git_transaction_new(git_transaction **out, git_repository *repo)
49
+ {
50
+ int error;
51
+ git_pool pool;
52
+ git_transaction *tx = NULL;
53
+
54
+ assert(out && repo);
55
+
56
+ if ((error = git_pool_init(&pool, 1, 0)) < 0)
57
+ return error;
58
+
59
+ tx = git_pool_mallocz(&pool, sizeof(git_transaction));
60
+ if (!tx) {
61
+ error = -1;
62
+ goto on_error;
63
+ }
64
+
65
+ if ((error = git_strmap_alloc(&tx->locks)) < 0) {
66
+ error = -1;
67
+ goto on_error;
68
+ }
69
+
70
+ if ((error = git_repository_refdb(&tx->db, repo)) < 0)
71
+ goto on_error;
72
+
73
+ memcpy(&tx->pool, &pool, sizeof(git_pool));
74
+ tx->repo = repo;
75
+ *out = tx;
76
+ return 0;
77
+
78
+ on_error:
79
+ git_pool_clear(&pool);
80
+ return error;
81
+ }
82
+
83
+ int git_transaction_lock_ref(git_transaction *tx, const char *refname)
84
+ {
85
+ int error;
86
+ transaction_node *node;
87
+
88
+ assert(tx && refname);
89
+
90
+ node = git_pool_mallocz(&tx->pool, sizeof(transaction_node));
91
+ GITERR_CHECK_ALLOC(node);
92
+
93
+ node->name = git_pool_strdup(&tx->pool, refname);
94
+ GITERR_CHECK_ALLOC(node->name);
95
+
96
+ if ((error = git_refdb_lock(&node->payload, tx->db, refname)) < 0)
97
+ return error;
98
+
99
+ git_strmap_insert(tx->locks, node->name, node, error);
100
+ if (error < 0)
101
+ goto cleanup;
102
+
103
+ return 0;
104
+
105
+ cleanup:
106
+ git_refdb_unlock(tx->db, node->payload, false, false, NULL, NULL, NULL);
107
+
108
+ return error;
109
+ }
110
+
111
+ static int find_locked(transaction_node **out, git_transaction *tx, const char *refname)
112
+ {
113
+ git_strmap_iter pos;
114
+ transaction_node *node;
115
+
116
+ pos = git_strmap_lookup_index(tx->locks, refname);
117
+ if (!git_strmap_valid_index(tx->locks, pos)) {
118
+ giterr_set(GITERR_REFERENCE, "the specified reference is not locked");
119
+ return GIT_ENOTFOUND;
120
+ }
121
+
122
+ node = git_strmap_value_at(tx->locks, pos);
123
+
124
+ *out = node;
125
+ return 0;
126
+ }
127
+
128
+ static int copy_common(transaction_node *node, git_transaction *tx, const git_signature *sig, const char *msg)
129
+ {
130
+ if (sig && git_signature__pdup(&node->sig, sig, &tx->pool) < 0)
131
+ return -1;
132
+
133
+ if (!node->sig) {
134
+ git_signature *tmp;
135
+ int error;
136
+
137
+ if (git_reference__log_signature(&tmp, tx->repo) < 0)
138
+ return -1;
139
+
140
+ /* make sure the sig we use is in our pool */
141
+ error = git_signature__pdup(&node->sig, tmp, &tx->pool);
142
+ git_signature_free(tmp);
143
+ if (error < 0)
144
+ return error;
145
+ }
146
+
147
+ if (msg) {
148
+ node->message = git_pool_strdup(&tx->pool, msg);
149
+ GITERR_CHECK_ALLOC(node->message);
150
+ }
151
+
152
+ return 0;
153
+ }
154
+
155
+ int git_transaction_set_target(git_transaction *tx, const char *refname, const git_oid *target, const git_signature *sig, const char *msg)
156
+ {
157
+ int error;
158
+ transaction_node *node;
159
+
160
+ assert(tx && refname && target);
161
+
162
+ if ((error = find_locked(&node, tx, refname)) < 0)
163
+ return error;
164
+
165
+ if ((error = copy_common(node, tx, sig, msg)) < 0)
166
+ return error;
167
+
168
+ git_oid_cpy(&node->target.id, target);
169
+ node->ref_type = GIT_REF_OID;
170
+
171
+ return 0;
172
+ }
173
+
174
+ int git_transaction_set_symbolic_target(git_transaction *tx, const char *refname, const char *target, const git_signature *sig, const char *msg)
175
+ {
176
+ int error;
177
+ transaction_node *node;
178
+
179
+ assert(tx && refname && target);
180
+
181
+ if ((error = find_locked(&node, tx, refname)) < 0)
182
+ return error;
183
+
184
+ if ((error = copy_common(node, tx, sig, msg)) < 0)
185
+ return error;
186
+
187
+ node->target.symbolic = git_pool_strdup(&tx->pool, target);
188
+ GITERR_CHECK_ALLOC(node->target.symbolic);
189
+ node->ref_type = GIT_REF_SYMBOLIC;
190
+
191
+ return 0;
192
+ }
193
+
194
+ int git_transaction_remove(git_transaction *tx, const char *refname)
195
+ {
196
+ int error;
197
+ transaction_node *node;
198
+
199
+ if ((error = find_locked(&node, tx, refname)) < 0)
200
+ return error;
201
+
202
+ node->remove = true;
203
+ node->ref_type = GIT_REF_OID; /* the id will be ignored */
204
+
205
+ return 0;
206
+ }
207
+
208
+ static int dup_reflog(git_reflog **out, const git_reflog *in, git_pool *pool)
209
+ {
210
+ git_reflog *reflog;
211
+ git_reflog_entry *entries;
212
+ size_t len, i;
213
+
214
+ reflog = git_pool_mallocz(pool, sizeof(git_reflog));
215
+ GITERR_CHECK_ALLOC(reflog);
216
+
217
+ reflog->ref_name = git_pool_strdup(pool, in->ref_name);
218
+ GITERR_CHECK_ALLOC(reflog->ref_name);
219
+
220
+ len = in->entries.length;
221
+ reflog->entries.length = len;
222
+ reflog->entries.contents = git_pool_mallocz(pool, len * sizeof(void *));
223
+ GITERR_CHECK_ALLOC(reflog->entries.contents);
224
+
225
+ entries = git_pool_mallocz(pool, len * sizeof(git_reflog_entry));
226
+ GITERR_CHECK_ALLOC(entries);
227
+
228
+ for (i = 0; i < len; i++) {
229
+ const git_reflog_entry *src;
230
+ git_reflog_entry *tgt;
231
+
232
+ tgt = &entries[i];
233
+ reflog->entries.contents[i] = tgt;
234
+
235
+ src = git_vector_get(&in->entries, i);
236
+ git_oid_cpy(&tgt->oid_old, &src->oid_old);
237
+ git_oid_cpy(&tgt->oid_cur, &src->oid_cur);
238
+
239
+ tgt->msg = git_pool_strdup(pool, src->msg);
240
+ GITERR_CHECK_ALLOC(tgt->msg);
241
+
242
+ if (git_signature__pdup(&tgt->committer, src->committer, pool) < 0)
243
+ return -1;
244
+ }
245
+
246
+
247
+ *out = reflog;
248
+ return 0;
249
+ }
250
+
251
+ int git_transaction_set_reflog(git_transaction *tx, const char *refname, const git_reflog *reflog)
252
+ {
253
+ int error;
254
+ transaction_node *node;
255
+
256
+ assert(tx && refname && reflog);
257
+
258
+ if ((error = find_locked(&node, tx, refname)) < 0)
259
+ return error;
260
+
261
+ if ((error = dup_reflog(&node->reflog, reflog, &tx->pool)) < 0)
262
+ return error;
263
+
264
+ return 0;
265
+ }
266
+
267
+ static int update_target(git_refdb *db, transaction_node *node)
268
+ {
269
+ git_reference *ref;
270
+ int error, update_reflog;
271
+
272
+ if (node->ref_type == GIT_REF_OID) {
273
+ ref = git_reference__alloc(node->name, &node->target.id, NULL);
274
+ } else if (node->ref_type == GIT_REF_SYMBOLIC) {
275
+ ref = git_reference__alloc_symbolic(node->name, node->target.symbolic);
276
+ } else {
277
+ abort();
278
+ }
279
+
280
+ GITERR_CHECK_ALLOC(ref);
281
+ update_reflog = node->reflog == NULL;
282
+
283
+ if (node->remove) {
284
+ error = git_refdb_unlock(db, node->payload, 2, false, ref, NULL, NULL);
285
+ } else if (node->ref_type == GIT_REF_OID) {
286
+ error = git_refdb_unlock(db, node->payload, true, update_reflog, ref, node->sig, node->message);
287
+ } else if (node->ref_type == GIT_REF_SYMBOLIC) {
288
+ error = git_refdb_unlock(db, node->payload, true, update_reflog, ref, node->sig, node->message);
289
+ } else {
290
+ abort();
291
+ }
292
+
293
+ git_reference_free(ref);
294
+ node->committed = true;
295
+
296
+ return error;
297
+ }
298
+
299
+ int git_transaction_commit(git_transaction *tx)
300
+ {
301
+ transaction_node *node;
302
+ git_strmap_iter pos;
303
+ int error = 0;
304
+
305
+ assert(tx);
306
+
307
+ for (pos = kh_begin(tx->locks); pos < kh_end(tx->locks); pos++) {
308
+ if (!git_strmap_has_data(tx->locks, pos))
309
+ continue;
310
+
311
+ node = git_strmap_value_at(tx->locks, pos);
312
+ if (node->reflog) {
313
+ if ((error = tx->db->backend->reflog_write(tx->db->backend, node->reflog)) < 0)
314
+ return error;
315
+ }
316
+
317
+ if (node->ref_type != GIT_REF_INVALID) {
318
+ if ((error = update_target(tx->db, node)) < 0)
319
+ return error;
320
+ }
321
+ }
322
+
323
+ return 0;
324
+ }
325
+
326
+ void git_transaction_free(git_transaction *tx)
327
+ {
328
+ transaction_node *node;
329
+ git_pool pool;
330
+ git_strmap_iter pos;
331
+
332
+ assert(tx);
333
+
334
+ /* start by unlocking the ones we've left hanging, if any */
335
+ for (pos = kh_begin(tx->locks); pos < kh_end(tx->locks); pos++) {
336
+ if (!git_strmap_has_data(tx->locks, pos))
337
+ continue;
338
+
339
+ node = git_strmap_value_at(tx->locks, pos);
340
+ if (node->committed)
341
+ continue;
342
+
343
+ git_refdb_unlock(tx->db, node->payload, false, false, NULL, NULL, NULL);
344
+ }
345
+
346
+ git_refdb_free(tx->db);
347
+ git_strmap_free(tx->locks);
348
+
349
+ /* tx is inside the pool, so we need to extract the data */
350
+ memcpy(&pool, &tx->pool, sizeof(git_pool));
351
+ git_pool_clear(&pool);
352
+ }
@@ -9,11 +9,11 @@
9
9
  #include "git2/remote.h"
10
10
  #include "git2/net.h"
11
11
  #include "git2/transport.h"
12
+ #include "git2/sys/transport.h"
12
13
  #include "path.h"
13
14
 
14
15
  typedef struct transport_definition {
15
16
  char *prefix;
16
- unsigned priority;
17
17
  git_transport_cb fn;
18
18
  void *param;
19
19
  } transport_definition;
@@ -24,52 +24,55 @@ static git_smart_subtransport_definition git_subtransport_definition = { git_sma
24
24
  static git_smart_subtransport_definition ssh_subtransport_definition = { git_smart_subtransport_ssh, 0 };
25
25
  #endif
26
26
 
27
- static transport_definition local_transport_definition = { "file://", 1, git_transport_local, NULL };
28
- #ifdef GIT_SSH
29
- static transport_definition ssh_transport_definition = { "ssh://", 1, git_transport_smart, &ssh_subtransport_definition };
30
- #else
31
- static transport_definition dummy_transport_definition = { NULL, 1, git_transport_dummy, NULL };
32
- #endif
27
+ static transport_definition local_transport_definition = { "file://", git_transport_local, NULL };
33
28
 
34
29
  static transport_definition transports[] = {
35
- {"git://", 1, git_transport_smart, &git_subtransport_definition},
36
- {"http://", 1, git_transport_smart, &http_subtransport_definition},
37
- {"https://", 1, git_transport_smart, &http_subtransport_definition},
38
- {"file://", 1, git_transport_local, NULL},
30
+ { "git://", git_transport_smart, &git_subtransport_definition },
31
+ { "http://", git_transport_smart, &http_subtransport_definition },
32
+ #if defined(GIT_SSL) || defined(GIT_WINHTTP)
33
+ { "https://", git_transport_smart, &http_subtransport_definition },
34
+ #endif
35
+ { "file://", git_transport_local, NULL },
39
36
  #ifdef GIT_SSH
40
- {"ssh://", 1, git_transport_smart, &ssh_subtransport_definition},
37
+ { "ssh://", git_transport_smart, &ssh_subtransport_definition },
41
38
  #endif
42
- {NULL, 0, 0}
39
+ { NULL, 0, 0 }
43
40
  };
44
41
 
45
- static git_vector additional_transports = GIT_VECTOR_INIT;
42
+ static git_vector custom_transports = GIT_VECTOR_INIT;
46
43
 
47
44
  #define GIT_TRANSPORT_COUNT (sizeof(transports)/sizeof(transports[0])) - 1
48
45
 
49
- static int transport_find_fn(const char *url, git_transport_cb *callback, void **param)
46
+ static transport_definition * transport_find_by_url(const char *url)
50
47
  {
51
48
  size_t i = 0;
52
- unsigned priority = 0;
53
- transport_definition *definition = NULL, *definition_iter;
49
+ transport_definition *d;
54
50
 
55
- // First, check to see if it's an obvious URL, which a URL scheme
56
- for (i = 0; i < GIT_TRANSPORT_COUNT; ++i) {
57
- definition_iter = &transports[i];
51
+ /* Find a user transport who wants to deal with this URI */
52
+ git_vector_foreach(&custom_transports, i, d) {
53
+ if (strncasecmp(url, d->prefix, strlen(d->prefix)) == 0) {
54
+ return d;
55
+ }
56
+ }
58
57
 
59
- if (strncasecmp(url, definition_iter->prefix, strlen(definition_iter->prefix)))
60
- continue;
58
+ /* Find a system transport for this URI */
59
+ for (i = 0; i < GIT_TRANSPORT_COUNT; ++i) {
60
+ d = &transports[i];
61
61
 
62
- if (definition_iter->priority > priority)
63
- definition = definition_iter;
62
+ if (strncasecmp(url, d->prefix, strlen(d->prefix)) == 0) {
63
+ return d;
64
+ }
64
65
  }
65
66
 
66
- git_vector_foreach(&additional_transports, i, definition_iter) {
67
- if (strncasecmp(url, definition_iter->prefix, strlen(definition_iter->prefix)))
68
- continue;
67
+ return NULL;
68
+ }
69
69
 
70
- if (definition_iter->priority > priority)
71
- definition = definition_iter;
72
- }
70
+ static int transport_find_fn(
71
+ git_transport_cb *out,
72
+ const char *url,
73
+ void **param)
74
+ {
75
+ transport_definition *definition = transport_find_by_url(url);
73
76
 
74
77
  #ifdef GIT_WIN32
75
78
  /* On Windows, it might not be possible to discern between absolute local
@@ -86,12 +89,10 @@ static int transport_find_fn(const char *url, git_transport_cb *callback, void *
86
89
 
87
90
  /* It could be a SSH remote path. Check to see if there's a :
88
91
  * SSH is an unsupported transport mechanism in this version of libgit2 */
89
- if (!definition && strrchr(url, ':'))
90
- #ifdef GIT_SSH
91
- definition = &ssh_transport_definition;
92
- #else
93
- definition = &dummy_transport_definition;
94
- #endif
92
+ if (!definition && strrchr(url, ':')) {
93
+ // re-search transports again with ssh:// as url so that we can find a third party ssh transport
94
+ definition = transport_find_by_url("ssh://");
95
+ }
95
96
 
96
97
  #ifndef GIT_WIN32
97
98
  /* Check to see if the path points to a file on the local file system */
@@ -100,9 +101,9 @@ static int transport_find_fn(const char *url, git_transport_cb *callback, void *
100
101
  #endif
101
102
 
102
103
  if (!definition)
103
- return -1;
104
+ return GIT_ENOTFOUND;
104
105
 
105
- *callback = definition->fn;
106
+ *out = definition->fn;
106
107
  *param = definition->param;
107
108
 
108
109
  return 0;
@@ -112,15 +113,6 @@ static int transport_find_fn(const char *url, git_transport_cb *callback, void *
112
113
  * Public API *
113
114
  **************/
114
115
 
115
- int git_transport_dummy(git_transport **transport, git_remote *owner, void *param)
116
- {
117
- GIT_UNUSED(transport);
118
- GIT_UNUSED(owner);
119
- GIT_UNUSED(param);
120
- giterr_set(GITERR_NET, "This transport isn't implemented. Sorry");
121
- return -1;
122
- }
123
-
124
116
  int git_transport_new(git_transport **out, git_remote *owner, const char *url)
125
117
  {
126
118
  git_transport_cb fn;
@@ -128,94 +120,96 @@ int git_transport_new(git_transport **out, git_remote *owner, const char *url)
128
120
  void *param;
129
121
  int error;
130
122
 
131
- if (transport_find_fn(url, &fn, &param) < 0) {
123
+ if ((error = transport_find_fn(&fn, url, &param)) == GIT_ENOTFOUND) {
132
124
  giterr_set(GITERR_NET, "Unsupported URL protocol");
133
125
  return -1;
134
- }
126
+ } else if (error < 0)
127
+ return error;
135
128
 
136
- error = fn(&transport, owner, param);
137
- if (error < 0)
129
+ if ((error = fn(&transport, owner, param)) < 0)
138
130
  return error;
139
131
 
132
+ GITERR_CHECK_VERSION(transport, GIT_TRANSPORT_VERSION, "git_transport");
133
+
140
134
  *out = transport;
141
135
 
142
136
  return 0;
143
137
  }
144
138
 
145
139
  int git_transport_register(
146
- const char *prefix,
147
- unsigned priority,
140
+ const char *scheme,
148
141
  git_transport_cb cb,
149
142
  void *param)
150
143
  {
151
- transport_definition *d;
152
-
153
- d = git__calloc(sizeof(transport_definition), 1);
154
- GITERR_CHECK_ALLOC(d);
144
+ git_buf prefix = GIT_BUF_INIT;
145
+ transport_definition *d, *definition = NULL;
146
+ size_t i;
147
+ int error = 0;
155
148
 
156
- d->prefix = git__strdup(prefix);
149
+ assert(scheme);
150
+ assert(cb);
157
151
 
158
- if (!d->prefix)
152
+ if ((error = git_buf_printf(&prefix, "%s://", scheme)) < 0)
159
153
  goto on_error;
160
154
 
161
- d->priority = priority;
162
- d->fn = cb;
163
- d->param = param;
155
+ git_vector_foreach(&custom_transports, i, d) {
156
+ if (strcasecmp(d->prefix, prefix.ptr) == 0) {
157
+ error = GIT_EEXISTS;
158
+ goto on_error;
159
+ }
160
+ }
161
+
162
+ definition = git__calloc(1, sizeof(transport_definition));
163
+ GITERR_CHECK_ALLOC(definition);
164
164
 
165
- if (git_vector_insert(&additional_transports, d) < 0)
165
+ definition->prefix = git_buf_detach(&prefix);
166
+ definition->fn = cb;
167
+ definition->param = param;
168
+
169
+ if (git_vector_insert(&custom_transports, definition) < 0)
166
170
  goto on_error;
167
171
 
168
172
  return 0;
169
173
 
170
174
  on_error:
171
- git__free(d->prefix);
172
- git__free(d);
173
- return -1;
175
+ git_buf_free(&prefix);
176
+ git__free(definition);
177
+ return error;
174
178
  }
175
179
 
176
- int git_transport_unregister(
177
- const char *prefix,
178
- unsigned priority)
180
+ int git_transport_unregister(const char *scheme)
179
181
  {
182
+ git_buf prefix = GIT_BUF_INIT;
180
183
  transport_definition *d;
181
- unsigned i;
184
+ size_t i;
185
+ int error = 0;
186
+
187
+ assert(scheme);
188
+
189
+ if ((error = git_buf_printf(&prefix, "%s://", scheme)) < 0)
190
+ goto done;
182
191
 
183
- git_vector_foreach(&additional_transports, i, d) {
184
- if (d->priority == priority && !strcasecmp(d->prefix, prefix)) {
185
- if (git_vector_remove(&additional_transports, i) < 0)
186
- return -1;
192
+ git_vector_foreach(&custom_transports, i, d) {
193
+ if (strcasecmp(d->prefix, prefix.ptr) == 0) {
194
+ if ((error = git_vector_remove(&custom_transports, i)) < 0)
195
+ goto done;
187
196
 
188
197
  git__free(d->prefix);
189
198
  git__free(d);
190
199
 
191
- if (!additional_transports.length)
192
- git_vector_free(&additional_transports);
200
+ if (!custom_transports.length)
201
+ git_vector_free(&custom_transports);
193
202
 
194
- return 0;
203
+ error = 0;
204
+ goto done;
195
205
  }
196
206
  }
197
207
 
198
- return GIT_ENOTFOUND;
199
- }
200
-
201
- /* from remote.h */
202
- int git_remote_valid_url(const char *url)
203
- {
204
- git_transport_cb fn;
205
- void *param;
206
-
207
- return !transport_find_fn(url, &fn, &param);
208
- }
209
-
210
- int git_remote_supported_url(const char* url)
211
- {
212
- git_transport_cb fn;
213
- void *param;
214
-
215
- if (transport_find_fn(url, &fn, &param) < 0)
216
- return 0;
208
+ error = GIT_ENOTFOUND;
217
209
 
218
- return fn != &git_transport_dummy;
210
+ done:
211
+ git_buf_free(&prefix);
212
+ return error;
219
213
  }
220
214
 
221
215
  int git_transport_init(git_transport *opts, unsigned int version)