rugged 0.24.6.1 → 0.25.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (213) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/ext/rugged/extconf.rb +9 -2
  4. data/ext/rugged/rugged.c +85 -21
  5. data/ext/rugged/rugged.h +7 -21
  6. data/ext/rugged/rugged_backend.c +3 -20
  7. data/ext/rugged/rugged_blame.c +7 -24
  8. data/ext/rugged/rugged_blob.c +136 -59
  9. data/ext/rugged/rugged_branch.c +3 -20
  10. data/ext/rugged/rugged_branch_collection.c +3 -20
  11. data/ext/rugged/rugged_commit.c +251 -101
  12. data/ext/rugged/rugged_config.c +3 -20
  13. data/ext/rugged/rugged_cred.c +3 -20
  14. data/ext/rugged/rugged_diff.c +3 -20
  15. data/ext/rugged/rugged_diff_delta.c +3 -20
  16. data/ext/rugged/rugged_diff_hunk.c +3 -20
  17. data/ext/rugged/rugged_diff_line.c +3 -20
  18. data/ext/rugged/rugged_index.c +46 -229
  19. data/ext/rugged/rugged_note.c +3 -20
  20. data/ext/rugged/rugged_object.c +3 -20
  21. data/ext/rugged/rugged_patch.c +192 -34
  22. data/ext/rugged/rugged_rebase.c +90 -48
  23. data/ext/rugged/rugged_reference.c +4 -21
  24. data/ext/rugged/rugged_reference_collection.c +3 -20
  25. data/ext/rugged/rugged_remote.c +70 -42
  26. data/ext/rugged/rugged_remote_collection.c +3 -20
  27. data/ext/rugged/rugged_repo.c +50 -59
  28. data/ext/rugged/rugged_revwalk.c +4 -21
  29. data/ext/rugged/rugged_settings.c +3 -20
  30. data/ext/rugged/rugged_signature.c +3 -20
  31. data/ext/rugged/rugged_submodule.c +4 -21
  32. data/ext/rugged/rugged_submodule_collection.c +3 -20
  33. data/ext/rugged/rugged_tag.c +3 -20
  34. data/ext/rugged/rugged_tag_collection.c +3 -20
  35. data/ext/rugged/rugged_tree.c +189 -184
  36. data/lib/rugged/attributes.rb +5 -0
  37. data/lib/rugged/blob.rb +5 -0
  38. data/lib/rugged/branch.rb +6 -1
  39. data/lib/rugged/commit.rb +5 -0
  40. data/lib/rugged/console.rb +5 -0
  41. data/lib/rugged/credentials.rb +5 -0
  42. data/lib/rugged/diff/delta.rb +5 -0
  43. data/lib/rugged/diff/hunk.rb +5 -0
  44. data/lib/rugged/diff/line.rb +5 -0
  45. data/lib/rugged/diff.rb +5 -0
  46. data/lib/rugged/index.rb +120 -0
  47. data/lib/rugged/object.rb +5 -0
  48. data/lib/rugged/patch.rb +5 -0
  49. data/lib/rugged/reference.rb +5 -0
  50. data/lib/rugged/remote.rb +5 -0
  51. data/lib/rugged/repository.rb +9 -4
  52. data/lib/rugged/submodule_collection.rb +5 -0
  53. data/lib/rugged/tag.rb +5 -0
  54. data/lib/rugged/tree.rb +156 -1
  55. data/lib/rugged/version.rb +6 -1
  56. data/lib/rugged/walker.rb +5 -0
  57. data/lib/rugged.rb +5 -0
  58. data/vendor/libgit2/CMakeLists.txt +12 -2
  59. data/vendor/libgit2/include/git2/blob.h +39 -28
  60. data/vendor/libgit2/include/git2/commit.h +76 -0
  61. data/vendor/libgit2/include/git2/common.h +21 -1
  62. data/vendor/libgit2/include/git2/describe.h +5 -2
  63. data/vendor/libgit2/include/git2/diff.h +62 -7
  64. data/vendor/libgit2/include/git2/errors.h +2 -1
  65. data/vendor/libgit2/include/git2/index.h +25 -0
  66. data/vendor/libgit2/include/git2/merge.h +10 -1
  67. data/vendor/libgit2/include/git2/odb.h +47 -1
  68. data/vendor/libgit2/include/git2/pack.h +4 -4
  69. data/vendor/libgit2/include/git2/patch.h +1 -1
  70. data/vendor/libgit2/include/git2/proxy.h +92 -0
  71. data/vendor/libgit2/include/git2/refs.h +11 -0
  72. data/vendor/libgit2/include/git2/remote.h +21 -8
  73. data/vendor/libgit2/include/git2/repository.h +20 -1
  74. data/vendor/libgit2/include/git2/revwalk.h +4 -6
  75. data/vendor/libgit2/include/git2/signature.h +13 -0
  76. data/vendor/libgit2/include/git2/submodule.h +11 -3
  77. data/vendor/libgit2/include/git2/sys/merge.h +177 -0
  78. data/vendor/libgit2/include/git2/sys/odb_backend.h +11 -0
  79. data/vendor/libgit2/include/git2/sys/remote.h +16 -0
  80. data/vendor/libgit2/include/git2/sys/stream.h +2 -1
  81. data/vendor/libgit2/include/git2/sys/time.h +31 -0
  82. data/vendor/libgit2/include/git2/sys/transport.h +3 -1
  83. data/vendor/libgit2/include/git2/tag.h +9 -0
  84. data/vendor/libgit2/include/git2/transaction.h +9 -0
  85. data/vendor/libgit2/include/git2/tree.h +55 -0
  86. data/vendor/libgit2/include/git2/version.h +4 -4
  87. data/vendor/libgit2/include/git2.h +1 -0
  88. data/vendor/libgit2/src/annotated_commit.c +99 -80
  89. data/vendor/libgit2/src/annotated_commit.h +5 -2
  90. data/vendor/libgit2/src/apply.c +377 -0
  91. data/vendor/libgit2/src/apply.h +21 -0
  92. data/vendor/libgit2/src/array.h +0 -1
  93. data/vendor/libgit2/src/blob.c +71 -39
  94. data/vendor/libgit2/src/branch.c +7 -5
  95. data/vendor/libgit2/src/buffer.c +252 -20
  96. data/vendor/libgit2/src/buffer.h +8 -0
  97. data/vendor/libgit2/src/checkout.c +69 -42
  98. data/vendor/libgit2/src/clone.c +0 -8
  99. data/vendor/libgit2/src/commit.c +193 -49
  100. data/vendor/libgit2/src/commit_list.c +8 -3
  101. data/vendor/libgit2/src/commit_list.h +1 -0
  102. data/vendor/libgit2/src/common.h +2 -1
  103. data/vendor/libgit2/src/config.c +3 -3
  104. data/vendor/libgit2/src/config_file.c +20 -10
  105. data/vendor/libgit2/src/crlf.c +1 -0
  106. data/vendor/libgit2/src/curl_stream.c +106 -6
  107. data/vendor/libgit2/src/delta.c +238 -62
  108. data/vendor/libgit2/src/delta.h +79 -58
  109. data/vendor/libgit2/src/describe.c +1 -1
  110. data/vendor/libgit2/src/diff.c +32 -1554
  111. data/vendor/libgit2/src/diff.h +14 -122
  112. data/vendor/libgit2/src/diff_driver.c +4 -6
  113. data/vendor/libgit2/src/diff_file.c +3 -0
  114. data/vendor/libgit2/src/diff_generate.c +1613 -0
  115. data/vendor/libgit2/src/diff_generate.h +123 -0
  116. data/vendor/libgit2/src/diff_parse.c +101 -0
  117. data/vendor/libgit2/src/diff_parse.h +18 -0
  118. data/vendor/libgit2/src/diff_print.c +263 -144
  119. data/vendor/libgit2/src/diff_stats.c +21 -12
  120. data/vendor/libgit2/src/diff_tform.c +1 -0
  121. data/vendor/libgit2/src/diff_tform.h +22 -0
  122. data/vendor/libgit2/src/diff_xdiff.c +9 -9
  123. data/vendor/libgit2/src/diff_xdiff.h +5 -5
  124. data/vendor/libgit2/src/fetchhead.c +8 -8
  125. data/vendor/libgit2/src/filebuf.c +6 -1
  126. data/vendor/libgit2/src/filebuf.h +1 -0
  127. data/vendor/libgit2/src/fileops.c +22 -1
  128. data/vendor/libgit2/src/fileops.h +8 -2
  129. data/vendor/libgit2/src/fnmatch.c +18 -5
  130. data/vendor/libgit2/src/global.c +21 -4
  131. data/vendor/libgit2/src/global.h +6 -0
  132. data/vendor/libgit2/src/graph.c +1 -1
  133. data/vendor/libgit2/src/index.c +159 -46
  134. data/vendor/libgit2/src/index.h +2 -0
  135. data/vendor/libgit2/src/iterator.c +1573 -1468
  136. data/vendor/libgit2/src/iterator.h +52 -69
  137. data/vendor/libgit2/src/merge.c +163 -64
  138. data/vendor/libgit2/src/merge.h +61 -2
  139. data/vendor/libgit2/src/merge_driver.c +397 -0
  140. data/vendor/libgit2/src/merge_driver.h +60 -0
  141. data/vendor/libgit2/src/merge_file.c +11 -49
  142. data/vendor/libgit2/src/netops.c +12 -10
  143. data/vendor/libgit2/src/object_api.c +19 -1
  144. data/vendor/libgit2/src/odb.c +228 -52
  145. data/vendor/libgit2/src/odb_loose.c +19 -1
  146. data/vendor/libgit2/src/odb_mempack.c +1 -1
  147. data/vendor/libgit2/src/odb_pack.c +27 -1
  148. data/vendor/libgit2/src/openssl_stream.c +4 -5
  149. data/vendor/libgit2/src/pack-objects.c +105 -76
  150. data/vendor/libgit2/src/pack-objects.h +13 -12
  151. data/vendor/libgit2/src/pack.c +16 -10
  152. data/vendor/libgit2/src/pack.h +2 -0
  153. data/vendor/libgit2/src/patch.c +216 -0
  154. data/vendor/libgit2/src/patch.h +66 -0
  155. data/vendor/libgit2/src/{diff_patch.c → patch_generate.c} +203 -376
  156. data/vendor/libgit2/src/patch_generate.h +68 -0
  157. data/vendor/libgit2/src/patch_parse.c +1159 -0
  158. data/vendor/libgit2/src/patch_parse.h +56 -0
  159. data/vendor/libgit2/src/path.c +38 -2
  160. data/vendor/libgit2/src/path.h +18 -0
  161. data/vendor/libgit2/src/pathspec.c +1 -1
  162. data/vendor/libgit2/src/pool.h +5 -0
  163. data/vendor/libgit2/src/pqueue.c +12 -5
  164. data/vendor/libgit2/src/pqueue.h +1 -0
  165. data/vendor/libgit2/src/proxy.c +32 -0
  166. data/vendor/libgit2/src/proxy.h +14 -0
  167. data/vendor/libgit2/src/push.c +1 -1
  168. data/vendor/libgit2/src/rebase.c +63 -36
  169. data/vendor/libgit2/src/refdb.c +4 -2
  170. data/vendor/libgit2/src/refdb_fs.c +82 -54
  171. data/vendor/libgit2/src/refs.c +13 -1
  172. data/vendor/libgit2/src/remote.c +20 -81
  173. data/vendor/libgit2/src/repository.c +212 -29
  174. data/vendor/libgit2/src/reset.c +1 -1
  175. data/vendor/libgit2/src/revparse.c +1 -1
  176. data/vendor/libgit2/src/revwalk.c +260 -184
  177. data/vendor/libgit2/src/settings.c +11 -3
  178. data/vendor/libgit2/src/signature.c +27 -2
  179. data/vendor/libgit2/src/sortedcache.c +14 -5
  180. data/vendor/libgit2/src/stash.c +1 -0
  181. data/vendor/libgit2/src/status.c +1 -0
  182. data/vendor/libgit2/src/stransport_stream.c +4 -2
  183. data/vendor/libgit2/src/stream.h +2 -2
  184. data/vendor/libgit2/src/submodule.c +16 -4
  185. data/vendor/libgit2/src/sysdir.c +1 -1
  186. data/vendor/libgit2/src/transport.c +3 -5
  187. data/vendor/libgit2/src/transports/http.c +38 -13
  188. data/vendor/libgit2/src/transports/local.c +4 -1
  189. data/vendor/libgit2/src/transports/smart.c +6 -0
  190. data/vendor/libgit2/src/transports/smart.h +1 -0
  191. data/vendor/libgit2/src/transports/smart_pkt.c +5 -13
  192. data/vendor/libgit2/src/transports/smart_protocol.c +22 -7
  193. data/vendor/libgit2/src/transports/winhttp.c +144 -11
  194. data/vendor/libgit2/src/tree.c +267 -2
  195. data/vendor/libgit2/src/unix/posix.h +10 -0
  196. data/vendor/libgit2/src/unix/pthread.h +2 -0
  197. data/vendor/libgit2/src/util.c +25 -2
  198. data/vendor/libgit2/src/util.h +10 -0
  199. data/vendor/libgit2/src/varint.c +44 -0
  200. data/vendor/libgit2/src/varint.h +15 -0
  201. data/vendor/libgit2/src/vector.c +58 -0
  202. data/vendor/libgit2/src/vector.h +8 -0
  203. data/vendor/libgit2/src/win32/posix.h +3 -0
  204. data/vendor/libgit2/src/win32/thread.c +18 -0
  205. data/vendor/libgit2/src/win32/thread.h +2 -0
  206. data/vendor/libgit2/src/win32/w32_util.h +1 -1
  207. data/vendor/libgit2/src/zstream.c +37 -8
  208. data/vendor/libgit2/src/zstream.h +8 -1
  209. metadata +100 -82
  210. data/vendor/libgit2/Makefile.embed +0 -60
  211. data/vendor/libgit2/src/delta-apply.c +0 -166
  212. data/vendor/libgit2/src/delta-apply.h +0 -62
  213. data/vendor/libgit2/src/diff_patch.h +0 -83
@@ -18,6 +18,7 @@
18
18
  #include "message.h"
19
19
  #include "refs.h"
20
20
  #include "object.h"
21
+ #include "oidarray.h"
21
22
 
22
23
  void git_commit__free(void *_commit)
23
24
  {
@@ -37,94 +38,142 @@ void git_commit__free(void *_commit)
37
38
  git__free(commit);
38
39
  }
39
40
 
40
- static int git_commit__create_internal(
41
- git_oid *id,
42
- git_repository *repo,
43
- const char *update_ref,
41
+ static int git_commit__create_buffer_internal(
42
+ git_buf *out,
44
43
  const git_signature *author,
45
44
  const git_signature *committer,
46
45
  const char *message_encoding,
47
46
  const char *message,
48
47
  const git_oid *tree,
49
- git_commit_parent_callback parent_cb,
50
- void *parent_payload,
51
- bool validate)
48
+ git_array_oid_t *parents)
52
49
  {
53
- git_reference *ref = NULL;
54
- int error = 0, matched_parent = 0;
55
- const git_oid *current_id = NULL;
56
- git_buf commit = GIT_BUF_INIT;
57
50
  size_t i = 0;
58
- git_odb *odb;
59
51
  const git_oid *parent;
60
52
 
61
- assert(id && repo && tree && parent_cb);
53
+ assert(out && tree);
62
54
 
63
- if (validate && !git_object__is_valid(repo, tree, GIT_OBJ_TREE))
64
- return -1;
55
+ git_oid__writebuf(out, "tree ", tree);
65
56
 
66
- if (update_ref) {
67
- error = git_reference_lookup_resolved(&ref, repo, update_ref, 10);
68
- if (error < 0 && error != GIT_ENOTFOUND)
69
- return error;
57
+ for (i = 0; i < git_array_size(*parents); i++) {
58
+ parent = git_array_get(*parents, i);
59
+ git_oid__writebuf(out, "parent ", parent);
70
60
  }
71
- giterr_clear();
72
61
 
73
- if (ref)
74
- current_id = git_reference_target(ref);
62
+ git_signature__writebuf(out, "author ", author);
63
+ git_signature__writebuf(out, "committer ", committer);
64
+
65
+ if (message_encoding != NULL)
66
+ git_buf_printf(out, "encoding %s\n", message_encoding);
67
+
68
+ git_buf_putc(out, '\n');
69
+
70
+ if (git_buf_puts(out, message) < 0)
71
+ goto on_error;
72
+
73
+ return 0;
74
+
75
+ on_error:
76
+ git_buf_free(out);
77
+ return -1;
78
+ }
75
79
 
76
- git_oid__writebuf(&commit, "tree ", tree);
80
+ static int validate_tree_and_parents(git_array_oid_t *parents, git_repository *repo, const git_oid *tree,
81
+ git_commit_parent_callback parent_cb, void *parent_payload,
82
+ const git_oid *current_id, bool validate)
83
+ {
84
+ size_t i;
85
+ int error;
86
+ git_oid *parent_cpy;
87
+ const git_oid *parent;
88
+
89
+ if (validate && !git_object__is_valid(repo, tree, GIT_OBJ_TREE))
90
+ return -1;
77
91
 
92
+ i = 0;
78
93
  while ((parent = parent_cb(i, parent_payload)) != NULL) {
79
94
  if (validate && !git_object__is_valid(repo, parent, GIT_OBJ_COMMIT)) {
80
95
  error = -1;
81
96
  goto on_error;
82
97
  }
83
98
 
84
- git_oid__writebuf(&commit, "parent ", parent);
85
- if (i == 0 && current_id && git_oid_equal(current_id, parent))
86
- matched_parent = 1;
99
+ parent_cpy = git_array_alloc(*parents);
100
+ GITERR_CHECK_ALLOC(parent_cpy);
101
+
102
+ git_oid_cpy(parent_cpy, parent);
87
103
  i++;
88
104
  }
89
105
 
90
- if (ref && !matched_parent) {
91
- git_reference_free(ref);
92
- git_buf_free(&commit);
106
+ if (current_id && (parents->size == 0 || git_oid_cmp(current_id, git_array_get(*parents, 0)))) {
93
107
  giterr_set(GITERR_OBJECT, "failed to create commit: current tip is not the first parent");
94
- return GIT_EMODIFIED;
108
+ error = GIT_EMODIFIED;
109
+ goto on_error;
95
110
  }
96
111
 
97
- git_signature__writebuf(&commit, "author ", author);
98
- git_signature__writebuf(&commit, "committer ", committer);
112
+ return 0;
99
113
 
100
- if (message_encoding != NULL)
101
- git_buf_printf(&commit, "encoding %s\n", message_encoding);
114
+ on_error:
115
+ git_array_clear(*parents);
116
+ return error;
117
+ }
118
+
119
+ static int git_commit__create_internal(
120
+ git_oid *id,
121
+ git_repository *repo,
122
+ const char *update_ref,
123
+ const git_signature *author,
124
+ const git_signature *committer,
125
+ const char *message_encoding,
126
+ const char *message,
127
+ const git_oid *tree,
128
+ git_commit_parent_callback parent_cb,
129
+ void *parent_payload,
130
+ bool validate)
131
+ {
132
+ int error;
133
+ git_odb *odb;
134
+ git_reference *ref = NULL;
135
+ git_buf buf = GIT_BUF_INIT;
136
+ const git_oid *current_id = NULL;
137
+ git_array_oid_t parents = GIT_ARRAY_INIT;
102
138
 
103
- git_buf_putc(&commit, '\n');
139
+ if (update_ref) {
140
+ error = git_reference_lookup_resolved(&ref, repo, update_ref, 10);
141
+ if (error < 0 && error != GIT_ENOTFOUND)
142
+ return error;
143
+ }
144
+ giterr_clear();
104
145
 
105
- if (git_buf_puts(&commit, message) < 0)
106
- goto on_error;
146
+ if (ref)
147
+ current_id = git_reference_target(ref);
148
+
149
+ if ((error = validate_tree_and_parents(&parents, repo, tree, parent_cb, parent_payload, current_id, validate)) < 0)
150
+ goto cleanup;
151
+
152
+ error = git_commit__create_buffer_internal(&buf, author, committer,
153
+ message_encoding, message, tree,
154
+ &parents);
155
+
156
+ if (error < 0)
157
+ goto cleanup;
107
158
 
108
159
  if (git_repository_odb__weakptr(&odb, repo) < 0)
109
- goto on_error;
160
+ goto cleanup;
110
161
 
111
- if (git_odb_write(id, odb, commit.ptr, commit.size, GIT_OBJ_COMMIT) < 0)
112
- goto on_error;
162
+ if (git_odb_write(id, odb, buf.ptr, buf.size, GIT_OBJ_COMMIT) < 0)
163
+ goto cleanup;
113
164
 
114
- git_buf_free(&commit);
115
165
 
116
166
  if (update_ref != NULL) {
117
167
  error = git_reference__update_for_commit(
118
168
  repo, ref, update_ref, id, "commit");
119
- git_reference_free(ref);
120
- return error;
169
+ goto cleanup;
121
170
  }
122
171
 
123
- return 0;
124
-
125
- on_error:
126
- git_buf_free(&commit);
127
- return -1;
172
+ cleanup:
173
+ git_array_clear(parents);
174
+ git_reference_free(ref);
175
+ git_buf_free(&buf);
176
+ return error;
128
177
  }
129
178
 
130
179
  int git_commit_create_from_callback(
@@ -566,7 +615,7 @@ int git_commit_nth_gen_ancestor(
566
615
 
567
616
  assert(ancestor && commit);
568
617
 
569
- if (git_object_dup((git_object **) &current, (git_object *) commit) < 0)
618
+ if (git_commit_dup(&current, (git_commit *)commit) < 0)
570
619
  return -1;
571
620
 
572
621
  if (n == 0) {
@@ -740,3 +789,98 @@ cleanup:
740
789
  git_buf_clear(signed_data);
741
790
  return error;
742
791
  }
792
+
793
+ int git_commit_create_buffer(git_buf *out,
794
+ git_repository *repo,
795
+ const git_signature *author,
796
+ const git_signature *committer,
797
+ const char *message_encoding,
798
+ const char *message,
799
+ const git_tree *tree,
800
+ size_t parent_count,
801
+ const git_commit *parents[])
802
+ {
803
+ int error;
804
+ commit_parent_data data = { parent_count, parents, repo };
805
+ git_array_oid_t parents_arr = GIT_ARRAY_INIT;
806
+ const git_oid *tree_id;
807
+
808
+ assert(tree && git_tree_owner(tree) == repo);
809
+
810
+ tree_id = git_tree_id(tree);
811
+
812
+ if ((error = validate_tree_and_parents(&parents_arr, repo, tree_id, commit_parent_from_array, &data, NULL, true)) < 0)
813
+ return error;
814
+
815
+ error = git_commit__create_buffer_internal(
816
+ out, author, committer,
817
+ message_encoding, message, tree_id,
818
+ &parents_arr);
819
+
820
+ git_array_clear(parents_arr);
821
+ return error;
822
+ }
823
+
824
+ /**
825
+ * Append to 'out' properly marking continuations when there's a newline in 'content'
826
+ */
827
+ static void format_header_field(git_buf *out, const char *field, const char *content)
828
+ {
829
+ const char *lf;
830
+
831
+ assert(out && field && content);
832
+
833
+ git_buf_puts(out, field);
834
+ git_buf_putc(out, ' ');
835
+
836
+ while ((lf = strchr(content, '\n')) != NULL) {
837
+ git_buf_put(out, content, lf - content);
838
+ git_buf_puts(out, "\n ");
839
+ content = lf + 1;
840
+ }
841
+
842
+ git_buf_puts(out, content);
843
+ git_buf_putc(out, '\n');
844
+ }
845
+
846
+ int git_commit_create_with_signature(
847
+ git_oid *out,
848
+ git_repository *repo,
849
+ const char *commit_content,
850
+ const char *signature,
851
+ const char *signature_field)
852
+ {
853
+ git_odb *odb;
854
+ int error = 0;
855
+ const char *field;
856
+ const char *header_end;
857
+ git_buf commit = GIT_BUF_INIT;
858
+
859
+ /* We start by identifying the end of the commit header */
860
+ header_end = strstr(commit_content, "\n\n");
861
+ if (!header_end) {
862
+ giterr_set(GITERR_INVALID, "malformed commit contents");
863
+ return -1;
864
+ }
865
+
866
+ field = signature_field ? signature_field : "gpgsig";
867
+
868
+ /* The header ends after the first LF */
869
+ header_end++;
870
+ git_buf_put(&commit, commit_content, header_end - commit_content);
871
+ format_header_field(&commit, field, signature);
872
+ git_buf_puts(&commit, header_end);
873
+
874
+ if (git_buf_oom(&commit))
875
+ return -1;
876
+
877
+ if ((error = git_repository_odb__weakptr(&odb, repo)) < 0)
878
+ goto cleanup;
879
+
880
+ if ((error = git_odb_write(out, odb, commit.ptr, commit.size, GIT_OBJ_COMMIT)) < 0)
881
+ goto cleanup;
882
+
883
+ cleanup:
884
+ git_buf_free(&commit);
885
+ return error;
886
+ }
@@ -13,10 +13,15 @@
13
13
 
14
14
  int git_commit_list_time_cmp(const void *a, const void *b)
15
15
  {
16
- const git_commit_list_node *commit_a = a;
17
- const git_commit_list_node *commit_b = b;
16
+ int64_t time_a = ((git_commit_list_node *) a)->time;
17
+ int64_t time_b = ((git_commit_list_node *) b)->time;
18
18
 
19
- return (commit_a->time < commit_b->time);
19
+ if (time_a < time_b)
20
+ return 1;
21
+ if (time_a > time_b)
22
+ return -1;
23
+
24
+ return 0;
20
25
  }
21
26
 
22
27
  git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p)
@@ -28,6 +28,7 @@ typedef struct git_commit_list_node {
28
28
  uninteresting:1,
29
29
  topo_delay:1,
30
30
  parsed:1,
31
+ added:1,
31
32
  flags : FLAG_BITS;
32
33
 
33
34
  unsigned short in_degree;
@@ -103,7 +103,8 @@
103
103
  /**
104
104
  * Set the error message for this thread, formatting as needed.
105
105
  */
106
- void giterr_set(int error_class, const char *string, ...);
106
+
107
+ void giterr_set(int error_class, const char *string, ...) GIT_FORMAT_PRINTF(2, 3);
107
108
 
108
109
  /**
109
110
  * Set the error message for a regex failure, using the internal regex
@@ -478,7 +478,7 @@ int git_config_iterator_glob_new(git_config_iterator **out, const git_config *cf
478
478
  iter = git__calloc(1, sizeof(all_iter));
479
479
  GITERR_CHECK_ALLOC(iter);
480
480
 
481
- if ((result = regcomp(&iter->regex, regexp, REG_EXTENDED)) != 0) {
481
+ if ((result = p_regcomp(&iter->regex, regexp, REG_EXTENDED)) != 0) {
482
482
  giterr_set_regex(&iter->regex, result);
483
483
  git__free(iter);
484
484
  return -1;
@@ -512,7 +512,7 @@ int git_config_backend_foreach_match(
512
512
  int error = 0;
513
513
 
514
514
  if (regexp != NULL) {
515
- if ((error = regcomp(&regex, regexp, REG_EXTENDED)) != 0) {
515
+ if ((error = p_regcomp(&regex, regexp, REG_EXTENDED)) != 0) {
516
516
  giterr_set_regex(&regex, error);
517
517
  regfree(&regex);
518
518
  return -1;
@@ -1003,7 +1003,7 @@ int git_config_multivar_iterator_new(git_config_iterator **out, const git_config
1003
1003
  goto on_error;
1004
1004
 
1005
1005
  if (regexp != NULL) {
1006
- error = regcomp(&iter->regex, regexp, REG_EXTENDED);
1006
+ error = p_regcomp(&iter->regex, regexp, REG_EXTENDED);
1007
1007
  if (error != 0) {
1008
1008
  giterr_set_regex(&iter->regex, error);
1009
1009
  error = -1;
@@ -232,7 +232,10 @@ static refcounted_strmap *refcounted_strmap_take(diskfile_header *h)
232
232
  {
233
233
  refcounted_strmap *map;
234
234
 
235
- git_mutex_lock(&h->values_mutex);
235
+ if (git_mutex_lock(&h->values_mutex) < 0) {
236
+ giterr_set(GITERR_OS, "Failed to lock config backend");
237
+ return NULL;
238
+ }
236
239
 
237
240
  map = h->values;
238
241
  git_atomic_inc(&map->refcount);
@@ -318,7 +321,10 @@ static int config__refresh(git_config_backend *cfg)
318
321
  if ((error = config_read(values->values, b, reader, b->level, 0)) < 0)
319
322
  goto out;
320
323
 
321
- git_mutex_lock(&b->header.values_mutex);
324
+ if ((error = git_mutex_lock(&b->header.values_mutex)) < 0) {
325
+ giterr_set(GITERR_OS, "Failed to lock config backend");
326
+ goto out;
327
+ }
322
328
 
323
329
  tmp = b->header.values;
324
330
  b->header.values = values;
@@ -460,7 +466,8 @@ static int config_set(git_config_backend *cfg, const char *name, const char *val
460
466
  if ((rval = git_config__normalize_name(name, &key)) < 0)
461
467
  return rval;
462
468
 
463
- map = refcounted_strmap_take(&b->header);
469
+ if ((map = refcounted_strmap_take(&b->header)) == NULL)
470
+ return -1;
464
471
  values = map->values;
465
472
 
466
473
  /*
@@ -527,7 +534,8 @@ static int config_get(git_config_backend *cfg, const char *key, git_config_entry
527
534
  if (!h->parent.readonly && ((error = config_refresh(cfg)) < 0))
528
535
  return error;
529
536
 
530
- map = refcounted_strmap_take(h);
537
+ if ((map = refcounted_strmap_take(h)) == NULL)
538
+ return -1;
531
539
  values = map->values;
532
540
 
533
541
  pos = git_strmap_lookup_index(values, key);
@@ -562,7 +570,7 @@ static int config_set_multivar(
562
570
  if ((result = git_config__normalize_name(name, &key)) < 0)
563
571
  return result;
564
572
 
565
- result = regcomp(&preg, regexp, REG_EXTENDED);
573
+ result = p_regcomp(&preg, regexp, REG_EXTENDED);
566
574
  if (result != 0) {
567
575
  giterr_set_regex(&preg, result);
568
576
  result = -1;
@@ -594,7 +602,8 @@ static int config_delete(git_config_backend *cfg, const char *name)
594
602
  if ((result = git_config__normalize_name(name, &key)) < 0)
595
603
  return result;
596
604
 
597
- map = refcounted_strmap_take(&b->header);
605
+ if ((map = refcounted_strmap_take(&b->header)) == NULL)
606
+ return -1;
598
607
  values = b->header.values->values;
599
608
 
600
609
  pos = git_strmap_lookup_index(values, key);
@@ -633,7 +642,8 @@ static int config_delete_multivar(git_config_backend *cfg, const char *name, con
633
642
  if ((result = git_config__normalize_name(name, &key)) < 0)
634
643
  return result;
635
644
 
636
- map = refcounted_strmap_take(&b->header);
645
+ if ((map = refcounted_strmap_take(&b->header)) == NULL)
646
+ return -1;
637
647
  values = b->header.values->values;
638
648
 
639
649
  pos = git_strmap_lookup_index(values, key);
@@ -647,7 +657,7 @@ static int config_delete_multivar(git_config_backend *cfg, const char *name, con
647
657
 
648
658
  refcounted_strmap_free(map);
649
659
 
650
- result = regcomp(&preg, regexp, REG_EXTENDED);
660
+ result = p_regcomp(&preg, regexp, REG_EXTENDED);
651
661
  if (result != 0) {
652
662
  giterr_set_regex(&preg, result);
653
663
  result = -1;
@@ -816,7 +826,8 @@ static int config_readonly_open(git_config_backend *cfg, git_config_level_t leve
816
826
  /* We're just copying data, don't care about the level */
817
827
  GIT_UNUSED(level);
818
828
 
819
- src_map = refcounted_strmap_take(src_header);
829
+ if ((src_map = refcounted_strmap_take(src_header)) == NULL)
830
+ return -1;
820
831
  b->header.values = src_map;
821
832
 
822
833
  return 0;
@@ -1946,4 +1957,3 @@ done:
1946
1957
  git_buf_free(&reader->buffer);
1947
1958
  return result;
1948
1959
  }
1949
-
@@ -289,6 +289,7 @@ static int crlf_check(
289
289
  ca.eol = check_eol(attr_values[1]); /* eol */
290
290
  }
291
291
  ca.auto_crlf = GIT_AUTO_CRLF_DEFAULT;
292
+ ca.safe_crlf = GIT_SAFE_CRLF_DEFAULT;
292
293
 
293
294
  /*
294
295
  * Use the core Git logic to see if we should perform CRLF for this file
@@ -13,6 +13,17 @@
13
13
  #include "git2/transport.h"
14
14
  #include "buffer.h"
15
15
  #include "vector.h"
16
+ #include "proxy.h"
17
+
18
+ /* This is for backwards compatibility with curl<7.45.0. */
19
+ #ifndef CURLINFO_ACTIVESOCKET
20
+ # define CURLINFO_ACTIVESOCKET CURLINFO_LASTSOCKET
21
+ # define GIT_CURL_BADSOCKET -1
22
+ # define git_activesocket_t long
23
+ #else
24
+ # define GIT_CURL_BADSOCKET CURL_SOCKET_BAD
25
+ # define git_activesocket_t curl_socket_t
26
+ #endif
16
27
 
17
28
  typedef struct {
18
29
  git_stream parent;
@@ -21,6 +32,8 @@ typedef struct {
21
32
  char curl_error[CURL_ERROR_SIZE + 1];
22
33
  git_cert_x509 cert_info;
23
34
  git_strarray cert_info_strings;
35
+ git_proxy_options proxy;
36
+ git_cred *proxy_cred;
24
37
  } curl_stream;
25
38
 
26
39
  static int seterr_curl(curl_stream *s)
@@ -29,21 +42,100 @@ static int seterr_curl(curl_stream *s)
29
42
  return -1;
30
43
  }
31
44
 
45
+ GIT_INLINE(int) error_no_credentials(void)
46
+ {
47
+ giterr_set(GITERR_NET, "proxy authentication required, but no callback provided");
48
+ return GIT_EAUTH;
49
+ }
50
+
51
+ static int apply_proxy_creds(curl_stream *s)
52
+ {
53
+ CURLcode res;
54
+ git_cred_userpass_plaintext *userpass;
55
+
56
+ if (!s->proxy_cred)
57
+ return GIT_ENOTFOUND;
58
+
59
+ userpass = (git_cred_userpass_plaintext *) s->proxy_cred;
60
+ if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXYUSERNAME, userpass->username)) != CURLE_OK)
61
+ return seterr_curl(s);
62
+ if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXYPASSWORD, userpass->password)) != CURLE_OK)
63
+ return seterr_curl(s);
64
+
65
+ return 0;
66
+ }
67
+
68
+ static int ask_and_apply_proxy_creds(curl_stream *s)
69
+ {
70
+ int error;
71
+ git_proxy_options *opts = &s->proxy;
72
+
73
+ if (!opts->credentials)
74
+ return error_no_credentials();
75
+
76
+ /* TODO: see if PROXYAUTH_AVAIL helps us here */
77
+ git_cred_free(s->proxy_cred);
78
+ s->proxy_cred = NULL;
79
+ giterr_clear();
80
+ error = opts->credentials(&s->proxy_cred, opts->url, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, opts->payload);
81
+ if (error == GIT_PASSTHROUGH)
82
+ return error_no_credentials();
83
+ if (error < 0) {
84
+ if (!giterr_last())
85
+ giterr_set(GITERR_NET, "proxy authentication was aborted by the user");
86
+ return error;
87
+ }
88
+
89
+ if (s->proxy_cred->credtype != GIT_CREDTYPE_USERPASS_PLAINTEXT) {
90
+ giterr_set(GITERR_NET, "credentials callback returned invalid credential type");
91
+ return -1;
92
+ }
93
+
94
+ return apply_proxy_creds(s);
95
+ }
96
+
32
97
  static int curls_connect(git_stream *stream)
33
98
  {
34
99
  curl_stream *s = (curl_stream *) stream;
35
- long sockextr;
36
- int failed_cert = 0;
100
+ git_activesocket_t sockextr;
101
+ long connect_last = 0;
102
+ int failed_cert = 0, error;
103
+ bool retry_connect;
37
104
  CURLcode res;
38
- res = curl_easy_perform(s->handle);
105
+
106
+ /* Apply any credentials we've already established */
107
+ error = apply_proxy_creds(s);
108
+ if (error < 0 && error != GIT_ENOTFOUND)
109
+ return seterr_curl(s);
110
+
111
+ do {
112
+ retry_connect = 0;
113
+ res = curl_easy_perform(s->handle);
114
+
115
+ curl_easy_getinfo(s->handle, CURLINFO_HTTP_CONNECTCODE, &connect_last);
116
+
117
+ /* HTTP 407 Proxy Authentication Required */
118
+ if (connect_last == 407) {
119
+ if ((error = ask_and_apply_proxy_creds(s)) < 0)
120
+ return error;
121
+
122
+ retry_connect = true;
123
+ }
124
+ } while (retry_connect);
39
125
 
40
126
  if (res != CURLE_OK && res != CURLE_PEER_FAILED_VERIFICATION)
41
127
  return seterr_curl(s);
42
128
  if (res == CURLE_PEER_FAILED_VERIFICATION)
43
129
  failed_cert = 1;
44
130
 
45
- if ((res = curl_easy_getinfo(s->handle, CURLINFO_LASTSOCKET, &sockextr)) != CURLE_OK)
131
+ if ((res = curl_easy_getinfo(s->handle, CURLINFO_ACTIVESOCKET, &sockextr)) != CURLE_OK) {
46
132
  return seterr_curl(s);
133
+ }
134
+
135
+ if (sockextr == GIT_CURL_BADSOCKET) {
136
+ giterr_set(GITERR_NET, "curl socket is no longer valid");
137
+ return -1;
138
+ }
47
139
 
48
140
  s->socket = sockextr;
49
141
 
@@ -95,12 +187,19 @@ static int curls_certificate(git_cert **out, git_stream *stream)
95
187
  return 0;
96
188
  }
97
189
 
98
- static int curls_set_proxy(git_stream *stream, const char *proxy_url)
190
+ static int curls_set_proxy(git_stream *stream, const git_proxy_options *proxy_opts)
99
191
  {
192
+ int error;
100
193
  CURLcode res;
101
194
  curl_stream *s = (curl_stream *) stream;
102
195
 
103
- if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXY, proxy_url)) != CURLE_OK)
196
+ if ((error = git_proxy_options_dup(&s->proxy, proxy_opts)) < 0)
197
+ return error;
198
+
199
+ if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXY, s->proxy.url)) != CURLE_OK)
200
+ return seterr_curl(s);
201
+
202
+ if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY)) != CURLE_OK)
104
203
  return seterr_curl(s);
105
204
 
106
205
  return 0;
@@ -115,6 +214,7 @@ static int wait_for(curl_socket_t fd, bool reading)
115
214
  FD_ZERO(&outfd);
116
215
  FD_ZERO(&errfd);
117
216
 
217
+ assert(fd >= 0);
118
218
  FD_SET(fd, &errfd);
119
219
  if (reading)
120
220
  FD_SET(fd, &infd);