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
@@ -326,12 +326,13 @@ static int refdb_fs_backend__exists(
326
326
  {
327
327
  refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
328
328
  git_buf ref_path = GIT_BUF_INIT;
329
+ int error;
329
330
 
330
331
  assert(backend);
331
332
 
332
- if (packed_reload(backend) < 0 ||
333
- git_buf_joinpath(&ref_path, backend->path, ref_name) < 0)
334
- return -1;
333
+ if ((error = packed_reload(backend)) < 0 ||
334
+ (error = git_buf_joinpath(&ref_path, backend->path, ref_name)) < 0)
335
+ return error;
335
336
 
336
337
  *exists = git_path_isfile(ref_path.ptr) ||
337
338
  (git_sortedcache_lookup(backend->refcache, ref_name) != NULL);
@@ -409,8 +410,8 @@ static int packed_lookup(
409
410
  int error = 0;
410
411
  struct packref *entry;
411
412
 
412
- if (packed_reload(backend) < 0)
413
- return -1;
413
+ if ((error = packed_reload(backend)) < 0)
414
+ return error;
414
415
 
415
416
  if (git_sortedcache_rlock(backend->refcache) < 0)
416
417
  return -1;
@@ -615,13 +616,14 @@ static int refdb_fs_backend__iterator_next_name(
615
616
  static int refdb_fs_backend__iterator(
616
617
  git_reference_iterator **out, git_refdb_backend *_backend, const char *glob)
617
618
  {
619
+ int error;
618
620
  refdb_fs_iter *iter;
619
621
  refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
620
622
 
621
623
  assert(backend);
622
624
 
623
- if (packed_reload(backend) < 0)
624
- return -1;
625
+ if ((error = packed_reload(backend)) < 0)
626
+ return error;
625
627
 
626
628
  iter = git__calloc(1, sizeof(refdb_fs_iter));
627
629
  GITERR_CHECK_ALLOC(iter);
@@ -674,16 +676,18 @@ static int reference_path_available(
674
676
  int force)
675
677
  {
676
678
  size_t i;
679
+ int error;
677
680
 
678
- if (packed_reload(backend) < 0)
679
- return -1;
681
+ if ((error = packed_reload(backend)) < 0)
682
+ return error;
680
683
 
681
684
  if (!force) {
682
685
  int exists;
683
686
 
684
- if (refdb_fs_backend__exists(
685
- &exists, (git_refdb_backend *)backend, new_ref) < 0)
686
- return -1;
687
+ if ((error = refdb_fs_backend__exists(
688
+ &exists, (git_refdb_backend *)backend, new_ref)) < 0) {
689
+ return error;
690
+ }
687
691
 
688
692
  if (exists) {
689
693
  giterr_set(GITERR_REFERENCE,
@@ -725,8 +729,8 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *
725
729
  /* Remove a possibly existing empty directory hierarchy
726
730
  * which name would collide with the reference name
727
731
  */
728
- if (git_futils_rmdir_r(name, backend->path, GIT_RMDIR_SKIP_NONEMPTY) < 0)
729
- return -1;
732
+ if ((error = git_futils_rmdir_r(name, backend->path, GIT_RMDIR_SKIP_NONEMPTY)) < 0)
733
+ return error;
730
734
 
731
735
  if (git_buf_joinpath(&ref_path, backend->path, name) < 0)
732
736
  return -1;
@@ -901,40 +905,62 @@ static int packed_write_ref(struct packref *ref, git_filebuf *file)
901
905
  static int packed_remove_loose(refdb_fs_backend *backend)
902
906
  {
903
907
  size_t i;
904
- git_buf full_path = GIT_BUF_INIT;
905
- int failed = 0;
908
+ git_filebuf lock = GIT_FILEBUF_INIT;
909
+ git_buf ref_content = GIT_BUF_INIT;
910
+ int error = 0;
906
911
 
907
912
  /* backend->refcache is already locked when this is called */
908
913
 
909
914
  for (i = 0; i < git_sortedcache_entrycount(backend->refcache); ++i) {
910
915
  struct packref *ref = git_sortedcache_entry(backend->refcache, i);
916
+ git_oid current_id;
911
917
 
912
918
  if (!ref || !(ref->flags & PACKREF_WAS_LOOSE))
913
919
  continue;
914
920
 
915
- if (git_buf_joinpath(&full_path, backend->path, ref->name) < 0)
916
- return -1; /* critical; do not try to recover on oom */
921
+ git_filebuf_cleanup(&lock);
917
922
 
918
- if (git_path_exists(full_path.ptr) && p_unlink(full_path.ptr) < 0) {
919
- if (failed)
920
- continue;
923
+ /* We need to stop anybody from updating the ref while we try to do a safe delete */
924
+ error = loose_lock(&lock, backend, ref->name);
925
+ /* If someone else is updating it, let them do it */
926
+ if (error == GIT_EEXISTS || error == GIT_ENOTFOUND)
927
+ continue;
921
928
 
922
- giterr_set(GITERR_REFERENCE,
923
- "Failed to remove loose reference '%s' after packing: %s",
924
- full_path.ptr, strerror(errno));
925
- failed = 1;
929
+ if (error < 0) {
930
+ git_buf_free(&ref_content);
931
+ giterr_set(GITERR_REFERENCE, "failed to lock loose reference '%s'", ref->name);
932
+ return error;
926
933
  }
927
934
 
935
+ error = git_futils_readbuffer(&ref_content, lock.path_original);
936
+ /* Someone else beat us to cleaning up the ref, let's simply continue */
937
+ if (error == GIT_ENOTFOUND)
938
+ continue;
939
+
940
+ /* This became a symref between us packing and trying to delete it, so ignore it */
941
+ if (!git__prefixcmp(ref_content.ptr, GIT_SYMREF))
942
+ continue;
943
+
944
+ /* Figure out the current id; if we find a bad ref file, skip it so we can do the rest */
945
+ if (loose_parse_oid(&current_id, lock.path_original, &ref_content) < 0)
946
+ continue;
947
+
948
+ /* If the ref moved since we packed it, we must not delete it */
949
+ if (!git_oid_equal(&current_id, &ref->oid))
950
+ continue;
951
+
928
952
  /*
929
953
  * if we fail to remove a single file, this is *not* good,
930
954
  * but we should keep going and remove as many as possible.
931
- * After we've removed as many files as possible, we return
932
- * the error code anyway.
955
+ * If we fail to remove, the ref is still in the old state, so
956
+ * we haven't lost information.
933
957
  */
958
+ p_unlink(lock.path_original);
934
959
  }
935
960
 
936
- git_buf_free(&full_path);
937
- return failed ? -1 : 0;
961
+ git_buf_free(&ref_content);
962
+ git_filebuf_cleanup(&lock);
963
+ return 0;
938
964
  }
939
965
 
940
966
  /*
@@ -944,41 +970,42 @@ static int packed_write(refdb_fs_backend *backend)
944
970
  {
945
971
  git_sortedcache *refcache = backend->refcache;
946
972
  git_filebuf pack_file = GIT_FILEBUF_INIT;
973
+ int error;
947
974
  size_t i;
948
975
 
949
976
  /* lock the cache to updates while we do this */
950
- if (git_sortedcache_wlock(refcache) < 0)
951
- return -1;
977
+ if ((error = git_sortedcache_wlock(refcache)) < 0)
978
+ return error;
952
979
 
953
980
  /* Open the file! */
954
- if (git_filebuf_open(&pack_file, git_sortedcache_path(refcache), 0, GIT_PACKEDREFS_FILE_MODE) < 0)
981
+ if ((error = git_filebuf_open(&pack_file, git_sortedcache_path(refcache), 0, GIT_PACKEDREFS_FILE_MODE)) < 0)
955
982
  goto fail;
956
983
 
957
984
  /* Packfiles have a header... apparently
958
985
  * This is in fact not required, but we might as well print it
959
986
  * just for kicks */
960
- if (git_filebuf_printf(&pack_file, "%s\n", GIT_PACKEDREFS_HEADER) < 0)
987
+ if ((error = git_filebuf_printf(&pack_file, "%s\n", GIT_PACKEDREFS_HEADER)) < 0)
961
988
  goto fail;
962
989
 
963
990
  for (i = 0; i < git_sortedcache_entrycount(refcache); ++i) {
964
991
  struct packref *ref = git_sortedcache_entry(refcache, i);
965
992
  assert(ref);
966
993
 
967
- if (packed_find_peel(backend, ref) < 0)
994
+ if ((error = packed_find_peel(backend, ref)) < 0)
968
995
  goto fail;
969
996
 
970
- if (packed_write_ref(ref, &pack_file) < 0)
997
+ if ((error = packed_write_ref(ref, &pack_file)) < 0)
971
998
  goto fail;
972
999
  }
973
1000
 
974
1001
  /* if we've written all the references properly, we can commit
975
1002
  * the packfile to make the changes effective */
976
- if (git_filebuf_commit(&pack_file) < 0)
1003
+ if ((error = git_filebuf_commit(&pack_file)) < 0)
977
1004
  goto fail;
978
1005
 
979
1006
  /* when and only when the packfile has been properly written,
980
1007
  * we can go ahead and remove the loose refs */
981
- if (packed_remove_loose(backend) < 0)
1008
+ if ((error = packed_remove_loose(backend)) < 0)
982
1009
  goto fail;
983
1010
 
984
1011
  git_sortedcache_updated(refcache);
@@ -991,7 +1018,7 @@ fail:
991
1018
  git_filebuf_cleanup(&pack_file);
992
1019
  git_sortedcache_wunlock(refcache);
993
1020
 
994
- return -1;
1021
+ return error;
995
1022
  }
996
1023
 
997
1024
  static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, const git_oid *old, const git_oid *new, const git_signature *author, const char *message);
@@ -1143,8 +1170,7 @@ static int refdb_fs_backend__write(
1143
1170
 
1144
1171
  assert(backend);
1145
1172
 
1146
- error = reference_path_available(backend, ref->name, NULL, force);
1147
- if (error < 0)
1173
+ if ((error = reference_path_available(backend, ref->name, NULL, force)) < 0)
1148
1174
  return error;
1149
1175
 
1150
1176
  /* We need to perform the reflog append and old value check under the ref's lock */
@@ -1260,15 +1286,14 @@ static int refdb_fs_backend__delete_tail(
1260
1286
  if (git_buf_joinpath(&loose_path, backend->path, ref_name) < 0)
1261
1287
  return -1;
1262
1288
 
1263
- if (git_path_isfile(loose_path.ptr)) {
1264
- error = p_unlink(loose_path.ptr);
1265
- loose_deleted = 1;
1266
- }
1267
-
1268
- git_buf_free(&loose_path);
1269
1289
 
1270
- if (error != 0)
1290
+ error = p_unlink(loose_path.ptr);
1291
+ if (error < 0 && errno == ENOENT)
1292
+ error = 0;
1293
+ else if (error < 0)
1271
1294
  goto cleanup;
1295
+ else if (error == 0)
1296
+ loose_deleted = 1;
1272
1297
 
1273
1298
  if ((error = packed_reload(backend)) < 0)
1274
1299
  goto cleanup;
@@ -1291,6 +1316,7 @@ static int refdb_fs_backend__delete_tail(
1291
1316
  error = packed_write(backend);
1292
1317
 
1293
1318
  cleanup:
1319
+ git_buf_free(&loose_path);
1294
1320
  git_filebuf_cleanup(file);
1295
1321
 
1296
1322
  return error;
@@ -1362,14 +1388,15 @@ static int refdb_fs_backend__rename(
1362
1388
 
1363
1389
  static int refdb_fs_backend__compress(git_refdb_backend *_backend)
1364
1390
  {
1391
+ int error;
1365
1392
  refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
1366
1393
 
1367
1394
  assert(backend);
1368
1395
 
1369
- if (packed_reload(backend) < 0 || /* load the existing packfile */
1370
- packed_loadloose(backend) < 0 || /* add all the loose refs */
1371
- packed_write(backend) < 0) /* write back to disk */
1372
- return -1;
1396
+ if ((error = packed_reload(backend)) < 0 || /* load the existing packfile */
1397
+ (error = packed_loadloose(backend)) < 0 || /* add all the loose refs */
1398
+ (error = packed_write(backend)) < 0) /* write back to disk */
1399
+ return error;
1373
1400
 
1374
1401
  return 0;
1375
1402
  }
@@ -1789,9 +1816,10 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co
1789
1816
  * there maybe an obsolete/unused directory (or directory hierarchy) in the way.
1790
1817
  */
1791
1818
  if (git_path_isdir(git_buf_cstr(&path))) {
1792
- if ((git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_RMDIR_SKIP_NONEMPTY) < 0))
1793
- error = -1;
1794
- else if (git_path_isdir(git_buf_cstr(&path))) {
1819
+ if ((error = git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_RMDIR_SKIP_NONEMPTY)) < 0) {
1820
+ if (error == GIT_ENOTFOUND)
1821
+ error = 0;
1822
+ } else if (git_path_isdir(git_buf_cstr(&path))) {
1795
1823
  giterr_set(GITERR_REFERENCE, "cannot create reflog at '%s', there are reflogs beneath that folder",
1796
1824
  ref->name);
1797
1825
  error = GIT_EDIRECTORY;
@@ -105,6 +105,18 @@ git_reference *git_reference__set_name(
105
105
  return rewrite;
106
106
  }
107
107
 
108
+ int git_reference_dup(git_reference **dest, git_reference *source)
109
+ {
110
+ if (source->type == GIT_REF_SYMBOLIC)
111
+ *dest = git_reference__alloc_symbolic(source->name, source->target.symbolic);
112
+ else
113
+ *dest = git_reference__alloc(source->name, &source->target.oid, &source->peel);
114
+
115
+ GITERR_CHECK_ALLOC(*dest);
116
+
117
+ return 0;
118
+ }
119
+
108
120
  void git_reference_free(git_reference *reference)
109
121
  {
110
122
  if (reference == NULL)
@@ -448,7 +460,7 @@ int git_reference_create_matching(
448
460
  {
449
461
  int error;
450
462
  git_signature *who = NULL;
451
-
463
+
452
464
  assert(id);
453
465
 
454
466
  if ((error = git_reference__log_signature(&who, repo)) < 0)
@@ -547,53 +547,6 @@ static int lookup_remote_prune_config(git_remote *remote, git_config *config, co
547
547
  return error;
548
548
  }
549
549
 
550
- static int update_config_refspec(const git_remote *remote, git_config *config, int direction)
551
- {
552
- git_buf name = GIT_BUF_INIT;
553
- unsigned int push;
554
- const char *dir;
555
- size_t i;
556
- int error = 0;
557
- const char *cname;
558
-
559
- push = direction == GIT_DIRECTION_PUSH;
560
- dir = push ? "push" : "fetch";
561
-
562
- if (git_buf_printf(&name, "remote.%s.%s", remote->name, dir) < 0)
563
- return -1;
564
- cname = git_buf_cstr(&name);
565
-
566
- /* Clear out the existing config */
567
- while (!error)
568
- error = git_config_delete_multivar(config, cname, ".*");
569
-
570
- if (error != GIT_ENOTFOUND)
571
- return error;
572
-
573
- for (i = 0; i < remote->refspecs.length; i++) {
574
- git_refspec *spec = git_vector_get(&remote->refspecs, i);
575
-
576
- if (spec->push != push)
577
- continue;
578
-
579
- // "$^" is a unmatcheable regexp: it will not match anything at all, so
580
- // all values will be considered new and we will not replace any
581
- // present value.
582
- if ((error = git_config_set_multivar(
583
- config, cname, "$^", spec->string)) < 0) {
584
- goto cleanup;
585
- }
586
- }
587
-
588
- giterr_clear();
589
- error = 0;
590
-
591
- cleanup:
592
- git_buf_free(&name);
593
-
594
- return error;
595
- }
596
-
597
550
  const char *git_remote_name(const git_remote *remote)
598
551
  {
599
552
  assert(remote);
@@ -695,7 +648,7 @@ static int set_transport_custom_headers(git_transport *t, const git_strarray *cu
695
648
  return t->set_custom_headers(t, custom_headers);
696
649
  }
697
650
 
698
- int git_remote_connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks, const git_strarray *custom_headers)
651
+ int git_remote_connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks, const git_proxy_options *proxy, const git_strarray *custom_headers)
699
652
  {
700
653
  git_transport *t;
701
654
  const char *url;
@@ -714,6 +667,9 @@ int git_remote_connect(git_remote *remote, git_direction direction, const git_re
714
667
  payload = callbacks->payload;
715
668
  }
716
669
 
670
+ if (proxy)
671
+ GITERR_CHECK_VERSION(proxy, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options");
672
+
717
673
  t = remote->transport;
718
674
 
719
675
  url = git_remote__urlfordirection(remote, direction);
@@ -738,7 +694,7 @@ int git_remote_connect(git_remote *remote, git_direction direction, const git_re
738
694
  goto on_error;
739
695
 
740
696
  if ((error = set_transport_callbacks(t, callbacks)) < 0 ||
741
- (error = t->connect(t, url, credentials, payload, direction, flags)) != 0)
697
+ (error = t->connect(t, url, credentials, payload, proxy, direction, flags)) != 0)
742
698
  goto on_error;
743
699
 
744
700
  remote->transport = t;
@@ -896,6 +852,7 @@ int git_remote_download(git_remote *remote, const git_strarray *refspecs, const
896
852
  git_vector *to_active, specs = GIT_VECTOR_INIT, refs = GIT_VECTOR_INIT;
897
853
  const git_remote_callbacks *cbs = NULL;
898
854
  const git_strarray *custom_headers = NULL;
855
+ const git_proxy_options *proxy = NULL;
899
856
 
900
857
  assert(remote);
901
858
 
@@ -903,10 +860,12 @@ int git_remote_download(git_remote *remote, const git_strarray *refspecs, const
903
860
  GITERR_CHECK_VERSION(&opts->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks");
904
861
  cbs = &opts->callbacks;
905
862
  custom_headers = &opts->custom_headers;
863
+ GITERR_CHECK_VERSION(&opts->proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options");
864
+ proxy = &opts->proxy_opts;
906
865
  }
907
866
 
908
867
  if (!git_remote_connected(remote) &&
909
- (error = git_remote_connect(remote, GIT_DIRECTION_FETCH, cbs, custom_headers)) < 0)
868
+ (error = git_remote_connect(remote, GIT_DIRECTION_FETCH, cbs, proxy, custom_headers)) < 0)
910
869
  goto on_error;
911
870
 
912
871
  if (ls_to_vector(&refs, remote) < 0)
@@ -971,6 +930,7 @@ int git_remote_fetch(
971
930
  git_buf reflog_msg_buf = GIT_BUF_INIT;
972
931
  const git_remote_callbacks *cbs = NULL;
973
932
  const git_strarray *custom_headers = NULL;
933
+ const git_proxy_options *proxy = NULL;
974
934
 
975
935
  if (opts) {
976
936
  GITERR_CHECK_VERSION(&opts->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks");
@@ -978,10 +938,12 @@ int git_remote_fetch(
978
938
  custom_headers = &opts->custom_headers;
979
939
  update_fetchhead = opts->update_fetchhead;
980
940
  tagopt = opts->download_tags;
941
+ GITERR_CHECK_VERSION(&opts->proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options");
942
+ proxy = &opts->proxy_opts;
981
943
  }
982
944
 
983
945
  /* Connect and download everything */
984
- if ((error = git_remote_connect(remote, GIT_DIRECTION_FETCH, cbs, custom_headers)) != 0)
946
+ if ((error = git_remote_connect(remote, GIT_DIRECTION_FETCH, cbs, proxy, custom_headers)) != 0)
985
947
  return error;
986
948
 
987
949
  error = git_remote_download(remote, refspecs, opts);
@@ -2094,34 +2056,6 @@ int git_remote_add_push(git_repository *repo, const char *remote, const char *re
2094
2056
  return write_add_refspec(repo, remote, refspec, false);
2095
2057
  }
2096
2058
 
2097
- static int set_refspecs(git_remote *remote, git_strarray *array, int push)
2098
- {
2099
- git_vector *vec = &remote->refspecs;
2100
- git_refspec *spec;
2101
- size_t i;
2102
-
2103
- /* Start by removing any refspecs of the same type */
2104
- for (i = 0; i < vec->length; i++) {
2105
- spec = git_vector_get(vec, i);
2106
- if (spec->push != push)
2107
- continue;
2108
-
2109
- git_refspec__free(spec);
2110
- git__free(spec);
2111
- git_vector_remove(vec, i);
2112
- i--;
2113
- }
2114
-
2115
- /* And now we add the new ones */
2116
-
2117
- for (i = 0; i < array->count; i++) {
2118
- if (add_refspec(remote, array->strings[i], !push) < 0)
2119
- return -1;
2120
- }
2121
-
2122
- return 0;
2123
- }
2124
-
2125
2059
  static int copy_refspecs(git_strarray *array, const git_remote *remote, unsigned int push)
2126
2060
  {
2127
2061
  size_t i;
@@ -2403,16 +2337,18 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi
2403
2337
  git_refspec *spec;
2404
2338
  const git_remote_callbacks *cbs = NULL;
2405
2339
  const git_strarray *custom_headers = NULL;
2340
+ const git_proxy_options *proxy = NULL;
2406
2341
 
2407
2342
  assert(remote);
2408
2343
 
2409
2344
  if (opts) {
2410
2345
  cbs = &opts->callbacks;
2411
2346
  custom_headers = &opts->custom_headers;
2347
+ proxy = &opts->proxy_opts;
2412
2348
  }
2413
2349
 
2414
2350
  if (!git_remote_connected(remote) &&
2415
- (error = git_remote_connect(remote, GIT_DIRECTION_PUSH, cbs, custom_headers)) < 0)
2351
+ (error = git_remote_connect(remote, GIT_DIRECTION_PUSH, cbs, proxy, custom_headers)) < 0)
2416
2352
  goto cleanup;
2417
2353
 
2418
2354
  free_refspecs(&remote->active_refspecs);
@@ -2462,16 +2398,19 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_
2462
2398
  int error;
2463
2399
  const git_remote_callbacks *cbs = NULL;
2464
2400
  const git_strarray *custom_headers = NULL;
2401
+ const git_proxy_options *proxy = NULL;
2465
2402
 
2466
2403
  if (opts) {
2467
2404
  GITERR_CHECK_VERSION(&opts->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks");
2468
2405
  cbs = &opts->callbacks;
2469
2406
  custom_headers = &opts->custom_headers;
2407
+ GITERR_CHECK_VERSION(&opts->proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options");
2408
+ proxy = &opts->proxy_opts;
2470
2409
  }
2471
2410
 
2472
2411
  assert(remote && refspecs);
2473
2412
 
2474
- if ((error = git_remote_connect(remote, GIT_DIRECTION_PUSH, cbs, custom_headers)) < 0)
2413
+ if ((error = git_remote_connect(remote, GIT_DIRECTION_PUSH, cbs, proxy, custom_headers)) < 0)
2475
2414
  return error;
2476
2415
 
2477
2416
  if ((error = git_remote_upload(remote, refspecs, opts)) < 0)