rugged 0.22.2 → 0.23.0b1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/rugged.c +1 -2
  3. data/ext/rugged/rugged_branch_collection.c +6 -44
  4. data/ext/rugged/rugged_config.c +7 -3
  5. data/ext/rugged/rugged_diff_delta.c +1 -1
  6. data/ext/rugged/rugged_diff_line.c +1 -1
  7. data/ext/rugged/rugged_object.c +2 -2
  8. data/ext/rugged/rugged_reference_collection.c +12 -56
  9. data/ext/rugged/rugged_remote.c +4 -33
  10. data/ext/rugged/rugged_remote_collection.c +1 -1
  11. data/ext/rugged/rugged_repo.c +10 -36
  12. data/ext/rugged/rugged_settings.c +3 -3
  13. data/ext/rugged/rugged_tree.c +1 -1
  14. data/lib/rugged/version.rb +1 -1
  15. data/vendor/libgit2/CMakeLists.txt +10 -3
  16. data/vendor/libgit2/COPYING +15 -21
  17. data/vendor/libgit2/include/git2/annotated_commit.h +20 -3
  18. data/vendor/libgit2/include/git2/branch.h +20 -16
  19. data/vendor/libgit2/include/git2/checkout.h +32 -18
  20. data/vendor/libgit2/include/git2/cherrypick.h +2 -2
  21. data/vendor/libgit2/include/git2/clone.h +4 -10
  22. data/vendor/libgit2/include/git2/config.h +66 -12
  23. data/vendor/libgit2/include/git2/describe.h +3 -2
  24. data/vendor/libgit2/include/git2/diff.h +3 -3
  25. data/vendor/libgit2/include/git2/errors.h +1 -0
  26. data/vendor/libgit2/include/git2/filter.h +21 -5
  27. data/vendor/libgit2/include/git2/index.h +32 -0
  28. data/vendor/libgit2/include/git2/merge.h +20 -3
  29. data/vendor/libgit2/include/git2/oid.h +1 -1
  30. data/vendor/libgit2/include/git2/pack.h +13 -0
  31. data/vendor/libgit2/include/git2/patch.h +3 -6
  32. data/vendor/libgit2/include/git2/rebase.h +8 -12
  33. data/vendor/libgit2/include/git2/refs.h +19 -29
  34. data/vendor/libgit2/include/git2/remote.h +5 -11
  35. data/vendor/libgit2/include/git2/repository.h +44 -15
  36. data/vendor/libgit2/include/git2/reset.h +19 -10
  37. data/vendor/libgit2/include/git2/revert.h +2 -2
  38. data/vendor/libgit2/include/git2/submodule.h +3 -9
  39. data/vendor/libgit2/include/git2/sys/config.h +3 -1
  40. data/vendor/libgit2/include/git2/sys/filter.h +10 -2
  41. data/vendor/libgit2/include/git2/sys/hashsig.h +49 -22
  42. data/vendor/libgit2/include/git2/transport.h +1 -1
  43. data/vendor/libgit2/include/git2/types.h +10 -3
  44. data/vendor/libgit2/include/git2/version.h +3 -2
  45. data/vendor/libgit2/src/annotated_commit.c +28 -0
  46. data/vendor/libgit2/src/array.h +19 -8
  47. data/vendor/libgit2/src/attr.c +95 -35
  48. data/vendor/libgit2/src/attr_file.c +51 -17
  49. data/vendor/libgit2/src/attr_file.h +37 -10
  50. data/vendor/libgit2/src/attrcache.c +13 -7
  51. data/vendor/libgit2/src/attrcache.h +1 -0
  52. data/vendor/libgit2/src/blame.c +26 -2
  53. data/vendor/libgit2/src/blame_git.c +6 -2
  54. data/vendor/libgit2/src/blob.c +6 -8
  55. data/vendor/libgit2/src/branch.c +55 -43
  56. data/vendor/libgit2/src/buf_text.c +13 -6
  57. data/vendor/libgit2/src/buffer.c +110 -25
  58. data/vendor/libgit2/src/buffer.h +18 -0
  59. data/vendor/libgit2/src/checkout.c +164 -92
  60. data/vendor/libgit2/src/checkout.h +0 -7
  61. data/vendor/libgit2/src/cherrypick.c +13 -7
  62. data/vendor/libgit2/src/clone.c +23 -25
  63. data/vendor/libgit2/src/commit.c +3 -3
  64. data/vendor/libgit2/src/common.h +23 -1
  65. data/vendor/libgit2/src/config.c +137 -19
  66. data/vendor/libgit2/src/config.h +2 -2
  67. data/vendor/libgit2/src/config_cache.c +2 -1
  68. data/vendor/libgit2/src/config_file.c +39 -18
  69. data/vendor/libgit2/src/config_file.h +1 -1
  70. data/vendor/libgit2/src/crlf.c +1 -1
  71. data/vendor/libgit2/src/delta-apply.c +3 -2
  72. data/vendor/libgit2/src/delta.c +25 -6
  73. data/vendor/libgit2/src/describe.c +2 -0
  74. data/vendor/libgit2/src/diff.c +8 -5
  75. data/vendor/libgit2/src/diff_driver.c +39 -18
  76. data/vendor/libgit2/src/diff_file.c +1 -1
  77. data/vendor/libgit2/src/diff_patch.c +12 -6
  78. data/vendor/libgit2/src/diff_tform.c +21 -24
  79. data/vendor/libgit2/src/filebuf.c +14 -12
  80. data/vendor/libgit2/src/fileops.c +61 -18
  81. data/vendor/libgit2/src/fileops.h +11 -2
  82. data/vendor/libgit2/src/filter.c +351 -99
  83. data/vendor/libgit2/src/filter.h +17 -0
  84. data/vendor/libgit2/src/global.c +38 -9
  85. data/vendor/libgit2/src/hash/hash_generic.c +1 -1
  86. data/vendor/libgit2/src/hashsig.c +28 -16
  87. data/vendor/libgit2/src/ignore.c +2 -2
  88. data/vendor/libgit2/src/index.c +159 -42
  89. data/vendor/libgit2/src/index.h +29 -0
  90. data/vendor/libgit2/src/indexer.c +11 -2
  91. data/vendor/libgit2/src/integer.h +96 -0
  92. data/vendor/libgit2/src/iterator.c +5 -3
  93. data/vendor/libgit2/src/khash.h +41 -29
  94. data/vendor/libgit2/src/merge.c +48 -35
  95. data/vendor/libgit2/src/merge.h +0 -1
  96. data/vendor/libgit2/src/merge_file.c +13 -0
  97. data/vendor/libgit2/src/mwindow.c +1 -1
  98. data/vendor/libgit2/src/notes.c +1 -1
  99. data/vendor/libgit2/src/odb.c +13 -11
  100. data/vendor/libgit2/src/odb_loose.c +22 -10
  101. data/vendor/libgit2/src/odb_mempack.c +4 -2
  102. data/vendor/libgit2/src/offmap.h +3 -2
  103. data/vendor/libgit2/src/oid.c +1 -1
  104. data/vendor/libgit2/src/oidmap.h +2 -1
  105. data/vendor/libgit2/src/openssl_stream.c +6 -3
  106. data/vendor/libgit2/src/pack-objects.c +273 -12
  107. data/vendor/libgit2/src/pack-objects.h +10 -0
  108. data/vendor/libgit2/src/pack.c +17 -6
  109. data/vendor/libgit2/src/pack.h +1 -3
  110. data/vendor/libgit2/src/path.c +68 -38
  111. data/vendor/libgit2/src/pathspec.c +3 -0
  112. data/vendor/libgit2/src/pool.c +9 -8
  113. data/vendor/libgit2/src/posix.c +11 -1
  114. data/vendor/libgit2/src/push.c +15 -17
  115. data/vendor/libgit2/src/push.h +1 -6
  116. data/vendor/libgit2/src/rebase.c +77 -35
  117. data/vendor/libgit2/src/refdb_fs.c +2 -2
  118. data/vendor/libgit2/src/refs.c +107 -81
  119. data/vendor/libgit2/src/refs.h +2 -2
  120. data/vendor/libgit2/src/refspec.c +3 -0
  121. data/vendor/libgit2/src/remote.c +19 -21
  122. data/vendor/libgit2/src/repository.c +258 -67
  123. data/vendor/libgit2/src/repository.h +31 -16
  124. data/vendor/libgit2/src/reset.c +28 -12
  125. data/vendor/libgit2/src/revert.c +12 -7
  126. data/vendor/libgit2/src/revwalk.c +3 -5
  127. data/vendor/libgit2/src/revwalk.h +1 -1
  128. data/vendor/libgit2/src/sortedcache.c +5 -3
  129. data/vendor/libgit2/src/stash.c +3 -5
  130. data/vendor/libgit2/src/strmap.h +2 -1
  131. data/vendor/libgit2/src/submodule.c +5 -6
  132. data/vendor/libgit2/src/tag.c +7 -5
  133. data/vendor/libgit2/src/transaction.c +1 -1
  134. data/vendor/libgit2/src/transports/cred.c +5 -2
  135. data/vendor/libgit2/src/transports/git.c +2 -3
  136. data/vendor/libgit2/src/transports/local.c +15 -34
  137. data/vendor/libgit2/src/transports/smart.c +1 -1
  138. data/vendor/libgit2/src/transports/smart_pkt.c +58 -18
  139. data/vendor/libgit2/src/transports/smart_protocol.c +2 -2
  140. data/vendor/libgit2/src/transports/winhttp.c +2 -2
  141. data/vendor/libgit2/src/tree.c +7 -5
  142. data/vendor/libgit2/src/tsort.c +3 -1
  143. data/vendor/libgit2/src/util.c +25 -0
  144. data/vendor/libgit2/src/util.h +31 -27
  145. data/vendor/libgit2/src/vector.c +2 -7
  146. data/vendor/libgit2/src/win32/dir.c +5 -3
  147. data/vendor/libgit2/src/win32/git2.rc +8 -4
  148. data/vendor/libgit2/src/win32/mingw-compat.h +7 -0
  149. data/vendor/libgit2/src/win32/msvc-compat.h +3 -0
  150. data/vendor/libgit2/src/win32/posix.h +1 -3
  151. data/vendor/libgit2/src/win32/posix_w32.c +31 -7
  152. data/vendor/libgit2/src/win32/utf-conv.c +1 -3
  153. data/vendor/libgit2/src/zstream.c +1 -1
  154. metadata +5 -5
  155. data/vendor/libgit2/src/bswap.h +0 -97
@@ -15,6 +15,7 @@
15
15
  #include "oidmap.h"
16
16
  #include "netops.h"
17
17
  #include "zstream.h"
18
+ #include "pool.h"
18
19
 
19
20
  #include "git2/oid.h"
20
21
  #include "git2/pack.h"
@@ -50,6 +51,12 @@ typedef struct git_pobject {
50
51
  filled:1;
51
52
  } git_pobject;
52
53
 
54
+ typedef struct {
55
+ git_oid id;
56
+ unsigned int uninteresting:1,
57
+ seen:1;
58
+ } git_walk_object;
59
+
53
60
  struct git_packbuilder {
54
61
  git_repository *repo; /* associated repository */
55
62
  git_odb *odb; /* associated object database */
@@ -66,6 +73,9 @@ struct git_packbuilder {
66
73
 
67
74
  git_oidmap *object_ix;
68
75
 
76
+ git_oidmap *walk_objects;
77
+ git_pool object_pool;
78
+
69
79
  git_oid pack_oid; /* hash of written pack */
70
80
 
71
81
  /* synchronization objects */
@@ -16,6 +16,9 @@
16
16
 
17
17
  #include <zlib.h>
18
18
 
19
+ GIT__USE_OFFMAP;
20
+ GIT__USE_OIDMAP;
21
+
19
22
  static int packfile_open(struct git_pack_file *p);
20
23
  static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n);
21
24
  int packfile_unpack_compressed(
@@ -631,7 +634,7 @@ int git_packfile_unpack(
631
634
  struct pack_chain_elem *elem = NULL, *stack;
632
635
  git_pack_cache_entry *cached = NULL;
633
636
  struct pack_chain_elem small_stack[SMALL_STACK_SIZE];
634
- size_t stack_size = 0, elem_pos;
637
+ size_t stack_size = 0, elem_pos, alloclen;
635
638
  git_otype base_type;
636
639
 
637
640
  /*
@@ -690,8 +693,11 @@ int git_packfile_unpack(
690
693
  */
691
694
  if (cached && stack_size == 1) {
692
695
  void *data = obj->data;
693
- obj->data = git__malloc(obj->len + 1);
696
+
697
+ GITERR_CHECK_ALLOC_ADD(&alloclen, obj->len, 1);
698
+ obj->data = git__malloc(alloclen);
694
699
  GITERR_CHECK_ALLOC(obj->data);
700
+
695
701
  memcpy(obj->data, data, obj->len + 1);
696
702
  git_atomic_dec(&cached->refcount);
697
703
  goto cleanup;
@@ -844,16 +850,18 @@ int packfile_unpack_compressed(
844
850
  size_t size,
845
851
  git_otype type)
846
852
  {
853
+ size_t buf_size;
847
854
  int st;
848
855
  z_stream stream;
849
856
  unsigned char *buffer, *in;
850
857
 
851
- buffer = git__calloc(1, size + 1);
858
+ GITERR_CHECK_ALLOC_ADD(&buf_size, size, 1);
859
+ buffer = git__calloc(1, buf_size);
852
860
  GITERR_CHECK_ALLOC(buffer);
853
861
 
854
862
  memset(&stream, 0, sizeof(stream));
855
863
  stream.next_out = buffer;
856
- stream.avail_out = (uInt)size + 1;
864
+ stream.avail_out = (uInt)buf_size;
857
865
  stream.zalloc = use_git_alloc;
858
866
  stream.zfree = use_git_free;
859
867
 
@@ -1092,14 +1100,17 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path)
1092
1100
  {
1093
1101
  struct stat st;
1094
1102
  struct git_pack_file *p;
1095
- size_t path_len = path ? strlen(path) : 0;
1103
+ size_t path_len = path ? strlen(path) : 0, alloc_len;
1096
1104
 
1097
1105
  *pack_out = NULL;
1098
1106
 
1099
1107
  if (path_len < strlen(".idx"))
1100
1108
  return git_odb__error_notfound("invalid packfile path", NULL);
1101
1109
 
1102
- p = git__calloc(1, sizeof(*p) + path_len + 2);
1110
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, sizeof(*p), path_len);
1111
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
1112
+
1113
+ p = git__calloc(1, alloc_len);
1103
1114
  GITERR_CHECK_ALLOC(p);
1104
1115
 
1105
1116
  memcpy(p->pack_name, path, path_len + 1);
@@ -71,9 +71,7 @@ struct pack_chain_elem {
71
71
  typedef git_array_t(struct pack_chain_elem) git_dependency_chain;
72
72
 
73
73
  #include "offmap.h"
74
-
75
- GIT__USE_OFFMAP;
76
- GIT__USE_OIDMAP;
74
+ #include "oidmap.h"
77
75
 
78
76
  #define GIT_PACK_CACHE_MEMORY_LIMIT 16 * 1024 * 1024
79
77
  #define GIT_PACK_CACHE_SIZE_LIMIT 1024 * 1024 /* don't bother caching anything over 1MB */
@@ -620,9 +620,12 @@ static bool _check_dir_contents(
620
620
  bool result;
621
621
  size_t dir_size = git_buf_len(dir);
622
622
  size_t sub_size = strlen(sub);
623
+ size_t alloc_size;
623
624
 
624
625
  /* leave base valid even if we could not make space for subdir */
625
- if (git_buf_try_grow(dir, dir_size + sub_size + 2, false, false) < 0)
626
+ if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, dir_size, sub_size) ||
627
+ GIT_ADD_SIZET_OVERFLOW(&alloc_size, alloc_size, 2) ||
628
+ git_buf_try_grow(dir, alloc_size, false, false) < 0)
626
629
  return false;
627
630
 
628
631
  /* save excursion */
@@ -784,7 +787,7 @@ int git_path_cmp(
784
787
  int git_path_make_relative(git_buf *path, const char *parent)
785
788
  {
786
789
  const char *p, *q, *p_dirsep, *q_dirsep;
787
- size_t plen = path->size, newlen, depth = 1, i, offset;
790
+ size_t plen = path->size, newlen, alloclen, depth = 1, i, offset;
788
791
 
789
792
  for (p_dirsep = p = path->ptr, q_dirsep = q = parent; *p && *q; p++, q++) {
790
793
  if (*p == '/' && *q == '/') {
@@ -822,11 +825,14 @@ int git_path_make_relative(git_buf *path, const char *parent)
822
825
  for (; (q = strchr(q, '/')) && *(q + 1); q++)
823
826
  depth++;
824
827
 
825
- newlen = (depth * 3) + plen;
828
+ GITERR_CHECK_ALLOC_MULTIPLY(&newlen, depth, 3);
829
+ GITERR_CHECK_ALLOC_ADD(&newlen, newlen, plen);
830
+
831
+ GITERR_CHECK_ALLOC_ADD(&alloclen, newlen, 1);
826
832
 
827
833
  /* save the offset as we might realllocate the pointer */
828
834
  offset = p - path->ptr;
829
- if (git_buf_try_grow(path, newlen + 1, 1, 0) < 0)
835
+ if (git_buf_try_grow(path, alloclen, 1, 0) < 0)
830
836
  return -1;
831
837
  p = path->ptr + offset;
832
838
 
@@ -871,7 +877,7 @@ void git_path_iconv_clear(git_path_iconv_t *ic)
871
877
  int git_path_iconv(git_path_iconv_t *ic, char **in, size_t *inlen)
872
878
  {
873
879
  char *nfd = *in, *nfc;
874
- size_t nfdlen = *inlen, nfclen, wantlen = nfdlen, rv;
880
+ size_t nfdlen = *inlen, nfclen, wantlen = nfdlen, alloclen, rv;
875
881
  int retry = 1;
876
882
 
877
883
  if (!ic || ic->map == (iconv_t)-1 ||
@@ -881,7 +887,8 @@ int git_path_iconv(git_path_iconv_t *ic, char **in, size_t *inlen)
881
887
  git_buf_clear(&ic->buf);
882
888
 
883
889
  while (1) {
884
- if (git_buf_grow(&ic->buf, wantlen + 1) < 0)
890
+ GITERR_CHECK_ALLOC_ADD(&alloclen, wantlen, 1);
891
+ if (git_buf_grow(&ic->buf, alloclen) < 0)
885
892
  return -1;
886
893
 
887
894
  nfc = ic->buf.ptr + ic->buf.size;
@@ -1057,6 +1064,37 @@ int git_path_direach(
1057
1064
  return error;
1058
1065
  }
1059
1066
 
1067
+ static int entry_path_alloc(
1068
+ char **out,
1069
+ const char *path,
1070
+ size_t path_len,
1071
+ const char *de_path,
1072
+ size_t de_len,
1073
+ size_t alloc_extra)
1074
+ {
1075
+ int need_slash = (path_len > 0 && path[path_len-1] != '/') ? 1 : 0;
1076
+ size_t alloc_size;
1077
+ char *entry_path;
1078
+
1079
+ GITERR_CHECK_ALLOC_ADD(&alloc_size, path_len, de_len);
1080
+ GITERR_CHECK_ALLOC_ADD(&alloc_size, alloc_size, need_slash);
1081
+ GITERR_CHECK_ALLOC_ADD(&alloc_size, alloc_size, 1);
1082
+ GITERR_CHECK_ALLOC_ADD(&alloc_size, alloc_size, alloc_extra);
1083
+ entry_path = git__calloc(1, alloc_size);
1084
+ GITERR_CHECK_ALLOC(entry_path);
1085
+
1086
+ if (path_len)
1087
+ memcpy(entry_path, path, path_len);
1088
+
1089
+ if (need_slash)
1090
+ entry_path[path_len] = '/';
1091
+
1092
+ memcpy(&entry_path[path_len + need_slash], de_path, de_len);
1093
+
1094
+ *out = entry_path;
1095
+ return 0;
1096
+ }
1097
+
1060
1098
  int git_path_dirload(
1061
1099
  const char *path,
1062
1100
  size_t prefix_len,
@@ -1064,7 +1102,7 @@ int git_path_dirload(
1064
1102
  unsigned int flags,
1065
1103
  git_vector *contents)
1066
1104
  {
1067
- int error, need_slash;
1105
+ int error;
1068
1106
  DIR *dir;
1069
1107
  size_t path_len;
1070
1108
  path_dirent_data de_data;
@@ -1096,11 +1134,10 @@ int git_path_dirload(
1096
1134
 
1097
1135
  path += prefix_len;
1098
1136
  path_len -= prefix_len;
1099
- need_slash = (path_len > 0 && path[path_len-1] != '/') ? 1 : 0;
1100
1137
 
1101
1138
  while ((error = p_readdir_r(dir, de_buf, &de)) == 0 && de != NULL) {
1102
1139
  char *entry_path, *de_path = de->d_name;
1103
- size_t alloc_size, de_len = strlen(de_path);
1140
+ size_t de_len = strlen(de_path);
1104
1141
 
1105
1142
  if (git_path_is_dot_or_dotdot(de_path))
1106
1143
  continue;
@@ -1110,17 +1147,9 @@ int git_path_dirload(
1110
1147
  break;
1111
1148
  #endif
1112
1149
 
1113
- alloc_size = path_len + need_slash + de_len + 1 + alloc_extra;
1114
- if ((entry_path = git__calloc(alloc_size, 1)) == NULL) {
1115
- error = -1;
1150
+ if ((error = entry_path_alloc(&entry_path,
1151
+ path, path_len, de_path, de_len, alloc_extra)) < 0)
1116
1152
  break;
1117
- }
1118
-
1119
- if (path_len)
1120
- memcpy(entry_path, path, path_len);
1121
- if (need_slash)
1122
- entry_path[path_len] = '/';
1123
- memcpy(&entry_path[path_len + need_slash], de_path, de_len);
1124
1153
 
1125
1154
  if ((error = git_vector_insert(contents, entry_path)) < 0) {
1126
1155
  git__free(entry_path);
@@ -1322,30 +1351,31 @@ static bool verify_dotgit_hfs(const char *path, size_t len)
1322
1351
 
1323
1352
  GIT_INLINE(bool) verify_dotgit_ntfs(git_repository *repo, const char *path, size_t len)
1324
1353
  {
1325
- const char *shortname = NULL;
1326
- size_t i, start, shortname_len = 0;
1327
-
1328
- /* See if the repo has a custom shortname (not "GIT~1") */
1329
- if (repo &&
1330
- (shortname = git_repository__8dot3_name(repo)) &&
1331
- shortname != git_repository__8dot3_default)
1332
- shortname_len = strlen(shortname);
1333
-
1334
- if (len >= 4 && strncasecmp(path, ".git", 4) == 0)
1335
- start = 4;
1336
- else if (len >= git_repository__8dot3_default_len &&
1337
- strncasecmp(path, git_repository__8dot3_default, git_repository__8dot3_default_len) == 0)
1338
- start = git_repository__8dot3_default_len;
1339
- else if (shortname_len && len >= shortname_len &&
1340
- strncasecmp(path, shortname, shortname_len) == 0)
1341
- start = shortname_len;
1342
- else
1354
+ git_buf *reserved = git_repository__reserved_names_win32;
1355
+ size_t reserved_len = git_repository__reserved_names_win32_len;
1356
+ size_t start = 0, i;
1357
+
1358
+ if (repo)
1359
+ git_repository__reserved_names(&reserved, &reserved_len, repo, true);
1360
+
1361
+ for (i = 0; i < reserved_len; i++) {
1362
+ git_buf *r = &reserved[i];
1363
+
1364
+ if (len >= r->size &&
1365
+ strncasecmp(path, r->ptr, r->size) == 0) {
1366
+ start = r->size;
1367
+ break;
1368
+ }
1369
+ }
1370
+
1371
+ if (!start)
1343
1372
  return true;
1344
1373
 
1345
- /* Reject paths beginning with ".git\" */
1374
+ /* Reject paths like ".git\" */
1346
1375
  if (path[start] == '\\')
1347
1376
  return false;
1348
1377
 
1378
+ /* Reject paths like '.git ' or '.git.' */
1349
1379
  for (i = start; i < len; i++) {
1350
1380
  if (path[i] != ' ' && path[i] != '.')
1351
1381
  return true;
@@ -318,6 +318,9 @@ static git_pathspec_match_list *pathspec_match_alloc(
318
318
  m = NULL;
319
319
  }
320
320
 
321
+ if (!m)
322
+ return NULL;
323
+
321
324
  /* need to keep reference to pathspec and increment refcount because
322
325
  * failures array stores pointers to the pattern strings of the
323
326
  * pathspec that had no matches
@@ -107,21 +107,22 @@ static void pool_insert_page(git_pool *pool, git_pool_page *page)
107
107
  static void *pool_alloc_page(git_pool *pool, uint32_t size)
108
108
  {
109
109
  git_pool_page *page;
110
- uint32_t alloc_size;
110
+ uint32_t new_page_size;
111
+ size_t alloc_size;
111
112
 
112
113
  if (size <= pool->page_size)
113
- alloc_size = pool->page_size;
114
+ new_page_size = pool->page_size;
114
115
  else {
115
- alloc_size = size;
116
+ new_page_size = size;
116
117
  pool->has_large_page_alloc = 1;
117
118
  }
118
119
 
119
- page = git__calloc(1, alloc_size + sizeof(git_pool_page));
120
- if (!page)
120
+ if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, new_page_size, sizeof(git_pool_page)) ||
121
+ !(page = git__calloc(1, alloc_size)))
121
122
  return NULL;
122
123
 
123
- page->size = alloc_size;
124
- page->avail = alloc_size - size;
124
+ page->size = new_page_size;
125
+ page->avail = new_page_size - size;
125
126
 
126
127
  if (page->avail > 0)
127
128
  pool_insert_page(pool, page);
@@ -225,7 +226,7 @@ char *git_pool_strcat(git_pool *pool, const char *a, const char *b)
225
226
  void *ptr;
226
227
  size_t len_a, len_b;
227
228
 
228
- assert(pool && a && b && pool->item_size == sizeof(char));
229
+ assert(pool && pool->item_size == sizeof(char));
229
230
 
230
231
  len_a = a ? strlen(a) : 0;
231
232
  len_b = b ? strlen(b) : 0;
@@ -155,6 +155,14 @@ ssize_t p_read(git_file fd, void *buf, size_t cnt)
155
155
  {
156
156
  char *b = buf;
157
157
 
158
+ if (!git__is_ssizet(cnt)) {
159
+ #ifdef GIT_WIN32
160
+ SetLastError(ERROR_INVALID_PARAMETER);
161
+ #endif
162
+ errno = EINVAL;
163
+ return -1;
164
+ }
165
+
158
166
  while (cnt) {
159
167
  ssize_t r;
160
168
  #ifdef GIT_WIN32
@@ -229,7 +237,9 @@ int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offs
229
237
  out->data = malloc(len);
230
238
  GITERR_CHECK_ALLOC(out->data);
231
239
 
232
- if ((p_lseek(fd, offset, SEEK_SET) < 0) || ((size_t)p_read(fd, out->data, len) != len)) {
240
+ if (!git__is_ssizet(len) ||
241
+ (p_lseek(fd, offset, SEEK_SET) < 0) ||
242
+ (p_read(fd, out->data, len) != (ssize_t)len)) {
233
243
  giterr_set(GITERR_OS, "mmap emulation failed");
234
244
  return -1;
235
245
  }
@@ -167,10 +167,7 @@ int git_push_add_refspec(git_push *push, const char *refspec)
167
167
  return 0;
168
168
  }
169
169
 
170
- int git_push_update_tips(
171
- git_push *push,
172
- const git_signature *signature,
173
- const char *reflog_message)
170
+ int git_push_update_tips(git_push *push)
174
171
  {
175
172
  git_buf remote_ref_name = GIT_BUF_INIT;
176
173
  size_t i, j;
@@ -183,6 +180,10 @@ int git_push_update_tips(
183
180
  git_vector_foreach(&push->status, i, status) {
184
181
  int fire_callback = 1;
185
182
 
183
+ /* Skip unsuccessful updates which have non-empty messages */
184
+ if (status->msg)
185
+ continue;
186
+
186
187
  /* Find the corresponding remote ref */
187
188
  fetch_spec = git_remote__matching_refspec(push->remote, status->ref);
188
189
  if (!fetch_spec)
@@ -201,21 +202,18 @@ int git_push_update_tips(
201
202
  if (j == push->specs.length)
202
203
  continue;
203
204
 
204
- /* If this ref update was successful (ok, not ng), it will have an empty message */
205
- if (status->msg == NULL) {
206
- /* Update the remote ref */
207
- if (git_oid_iszero(&push_spec->loid)) {
208
- error = git_reference_lookup(&remote_ref, push->remote->repo, git_buf_cstr(&remote_ref_name));
205
+ /* Update the remote ref */
206
+ if (git_oid_iszero(&push_spec->loid)) {
207
+ error = git_reference_lookup(&remote_ref, push->remote->repo, git_buf_cstr(&remote_ref_name));
209
208
 
210
- if (error >= 0) {
211
- error = git_reference_delete(remote_ref);
212
- git_reference_free(remote_ref);
213
- }
214
- } else {
215
- error = git_reference_create(NULL, push->remote->repo,
216
- git_buf_cstr(&remote_ref_name), &push_spec->loid, 1, signature,
217
- reflog_message ? reflog_message : "update by push");
209
+ if (error >= 0) {
210
+ error = git_reference_delete(remote_ref);
211
+ git_reference_free(remote_ref);
218
212
  }
213
+ } else {
214
+ error = git_reference_create(NULL, push->remote->repo,
215
+ git_buf_cstr(&remote_ref_name), &push_spec->loid, 1,
216
+ "update by push");
219
217
  }
220
218
 
221
219
  if (error < 0) {
@@ -109,15 +109,10 @@ int git_push_add_refspec(git_push *push, const char *refspec);
109
109
  *
110
110
  * @param push The push object
111
111
  * @param signature The identity to use when updating reflogs
112
- * @param reflog_message The message to insert into the reflogs. If NULL, the
113
- * default is "update by push".
114
112
  *
115
113
  * @return 0 or an error code
116
114
  */
117
- int git_push_update_tips(
118
- git_push *push,
119
- const git_signature *signature,
120
- const char *reflog_message);
115
+ int git_push_update_tips(git_push *push);
121
116
 
122
117
  /**
123
118
  * Perform the push
@@ -14,6 +14,7 @@
14
14
  #include "array.h"
15
15
  #include "config.h"
16
16
  #include "annotated_commit.h"
17
+ #include "index.h"
17
18
 
18
19
  #include <git2/types.h>
19
20
  #include <git2/annotated_commit.h>
@@ -168,10 +169,31 @@ GIT_INLINE(int) rebase_readoid(
168
169
  return 0;
169
170
  }
170
171
 
172
+ static git_rebase_operation *rebase_operation_alloc(
173
+ git_rebase *rebase,
174
+ git_rebase_operation_t type,
175
+ git_oid *id,
176
+ const char *exec)
177
+ {
178
+ git_rebase_operation *operation;
179
+
180
+ assert((type == GIT_REBASE_OPERATION_EXEC) == !id);
181
+ assert((type == GIT_REBASE_OPERATION_EXEC) == !!exec);
182
+
183
+ if ((operation = git_array_alloc(rebase->operations)) == NULL)
184
+ return NULL;
185
+
186
+ operation->type = type;
187
+ git_oid_cpy((git_oid *)&operation->id, id);
188
+ operation->exec = exec;
189
+
190
+ return operation;
191
+ }
192
+
171
193
  static int rebase_open_merge(git_rebase *rebase)
172
194
  {
173
195
  git_buf state_path = GIT_BUF_INIT, buf = GIT_BUF_INIT, cmt = GIT_BUF_INIT;
174
- git_oid current_id = {{0}};
196
+ git_oid id;
175
197
  git_rebase_operation *operation;
176
198
  size_t i, msgnum = 0, end;
177
199
  int error;
@@ -194,7 +216,7 @@ static int rebase_open_merge(git_rebase *rebase)
194
216
  goto done;
195
217
 
196
218
  /* Read 'current' if it exists */
197
- if ((error = rebase_readoid(&current_id, &buf, &state_path, CURRENT_FILE)) < 0 &&
219
+ if ((error = rebase_readoid(&id, &buf, &state_path, CURRENT_FILE)) < 0 &&
198
220
  error != GIT_ENOTFOUND)
199
221
  goto done;
200
222
 
@@ -203,14 +225,14 @@ static int rebase_open_merge(git_rebase *rebase)
203
225
  GITERR_CHECK_ARRAY(rebase->operations);
204
226
 
205
227
  for (i = 0; i < end; i++) {
206
- operation = git_array_alloc(rebase->operations);
207
- GITERR_CHECK_ALLOC(operation);
208
-
209
228
  git_buf_clear(&cmt);
210
229
 
211
230
  if ((error = git_buf_printf(&cmt, "cmt.%" PRIuZ, (i+1))) < 0 ||
212
- (error = rebase_readoid((git_oid *)&operation->id, &buf, &state_path, cmt.ptr)) < 0)
231
+ (error = rebase_readoid(&id, &buf, &state_path, cmt.ptr)) < 0)
213
232
  goto done;
233
+
234
+ operation = rebase_operation_alloc(rebase, GIT_REBASE_OPERATION_PICK, &id, NULL);
235
+ GITERR_CHECK_ALLOC(operation);
214
236
  }
215
237
 
216
238
  /* Read 'onto_name' */
@@ -444,11 +466,11 @@ static int rebase_normalize_opts(
444
466
  opts->rewrite_notes_ref = git__strdup(given_opts->rewrite_notes_ref);
445
467
  GITERR_CHECK_ALLOC(opts->rewrite_notes_ref);
446
468
  } else if (git_config__get_bool_force(config, "notes.rewrite.rebase", 1)) {
447
- const char *rewrite_ref = git_config__get_string_force(
469
+ char *rewrite_ref = git_config__get_string_force(
448
470
  config, "notes.rewriteref", NOTES_DEFAULT_REF);
449
471
 
450
472
  if (rewrite_ref) {
451
- opts->rewrite_notes_ref = git__strdup(rewrite_ref);
473
+ opts->rewrite_notes_ref = rewrite_ref;
452
474
  GITERR_CHECK_ALLOC(opts->rewrite_notes_ref);
453
475
  }
454
476
  }
@@ -553,9 +575,8 @@ static int rebase_init_operations(
553
575
  if (merge)
554
576
  continue;
555
577
 
556
- operation = git_array_alloc(rebase->operations);
557
- operation->type = GIT_REBASE_OPERATION_PICK;
558
- git_oid_cpy((git_oid *)&operation->id, &id);
578
+ operation = rebase_operation_alloc(rebase, GIT_REBASE_OPERATION_PICK, &id, NULL);
579
+ GITERR_CHECK_ALLOC(operation);
559
580
  }
560
581
 
561
582
  error = 0;
@@ -589,11 +610,21 @@ static int rebase_init(
589
610
  const git_annotated_commit *onto,
590
611
  const git_rebase_options *opts)
591
612
  {
613
+ git_reference *head_ref = NULL;
614
+ git_annotated_commit *head_branch = NULL;
592
615
  git_buf state_path = GIT_BUF_INIT;
593
616
  int error;
594
617
 
595
618
  if ((error = git_buf_joinpath(&state_path, repo->path_repository, REBASE_MERGE_DIR)) < 0)
596
- return error;
619
+ goto done;
620
+
621
+ if (!branch) {
622
+ if ((error = git_repository_head(&head_ref, repo)) < 0 ||
623
+ (error = git_annotated_commit_from_ref(&head_branch, repo, head_ref)) < 0)
624
+ goto done;
625
+
626
+ branch = head_branch;
627
+ }
597
628
 
598
629
  rebase->repo = repo;
599
630
  rebase->type = GIT_REBASE_TYPE_MERGE;
@@ -611,6 +642,10 @@ static int rebase_init(
611
642
 
612
643
  git_buf_free(&state_path);
613
644
 
645
+ done:
646
+ git_reference_free(head_ref);
647
+ git_annotated_commit_free(head_branch);
648
+
614
649
  return error;
615
650
  }
616
651
 
@@ -620,17 +655,17 @@ int git_rebase_init(
620
655
  const git_annotated_commit *branch,
621
656
  const git_annotated_commit *upstream,
622
657
  const git_annotated_commit *onto,
623
- const git_signature *signature,
624
658
  const git_rebase_options *given_opts)
625
659
  {
626
660
  git_rebase *rebase = NULL;
627
661
  git_rebase_options opts;
628
- git_reference *head_ref = NULL;
629
662
  git_buf reflog = GIT_BUF_INIT;
663
+ git_commit *onto_commit = NULL;
630
664
  git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
665
+ git_reference *head_ref = NULL;
631
666
  int error;
632
667
 
633
- assert(repo && branch && (upstream || onto));
668
+ assert(repo && (upstream || onto));
634
669
 
635
670
  *out = NULL;
636
671
 
@@ -639,35 +674,40 @@ int git_rebase_init(
639
674
  if (!onto)
640
675
  onto = upstream;
641
676
 
642
- checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
677
+ checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
643
678
 
644
679
  if ((error = rebase_normalize_opts(repo, &opts, given_opts)) < 0 ||
645
680
  (error = git_repository__ensure_not_bare(repo, "rebase")) < 0 ||
646
681
  (error = rebase_ensure_not_in_progress(repo)) < 0 ||
647
- (error = rebase_ensure_not_dirty(repo)) < 0)
682
+ (error = rebase_ensure_not_dirty(repo)) < 0 ||
683
+ (error = git_commit_lookup(
684
+ &onto_commit, repo, git_annotated_commit_id(onto))) < 0)
648
685
  return error;
649
686
 
650
687
  rebase = git__calloc(1, sizeof(git_rebase));
651
688
  GITERR_CHECK_ALLOC(rebase);
652
689
 
653
- if ((error = rebase_init(rebase, repo, branch, upstream, onto, &opts)) < 0 ||
690
+ if ((error = rebase_init(
691
+ rebase, repo, branch, upstream, onto, &opts)) < 0 ||
654
692
  (error = rebase_setupfiles(rebase)) < 0 ||
655
693
  (error = git_buf_printf(&reflog,
656
694
  "rebase: checkout %s", rebase_onto_name(onto))) < 0 ||
695
+ (error = git_checkout_tree(
696
+ repo, (git_object *)onto_commit, &checkout_opts)) < 0 ||
657
697
  (error = git_reference_create(&head_ref, repo, GIT_HEAD_FILE,
658
- git_annotated_commit_id(onto), 1, signature, reflog.ptr)) < 0 ||
659
- (error = git_checkout_head(repo, &checkout_opts)) < 0)
698
+ git_annotated_commit_id(onto), 1, reflog.ptr)) < 0)
660
699
  goto done;
661
700
 
662
701
  *out = rebase;
663
702
 
664
703
  done:
704
+ git_reference_free(head_ref);
665
705
  if (error < 0) {
666
706
  rebase_cleanup(rebase);
667
707
  git_rebase_free(rebase);
668
708
  }
669
709
 
670
- git_reference_free(head_ref);
710
+ git_commit_free(onto_commit);
671
711
  git_buf_free(&reflog);
672
712
  rebase_opts_free(&opts);
673
713
 
@@ -726,6 +766,7 @@ static int rebase_next_merge(
726
766
  git_commit *current_commit = NULL, *parent_commit = NULL;
727
767
  git_tree *current_tree = NULL, *head_tree = NULL, *parent_tree = NULL;
728
768
  git_index *index = NULL;
769
+ git_indexwriter indexwriter = GIT_INDEXWRITER_INIT;
729
770
  git_rebase_operation *operation;
730
771
  char current_idstr[GIT_OID_HEXSZ];
731
772
  unsigned int parent_count;
@@ -755,20 +796,21 @@ static int rebase_next_merge(
755
796
 
756
797
  git_oid_fmt(current_idstr, &operation->id);
757
798
 
758
- if ((error = rebase_setupfile(rebase, MSGNUM_FILE, -1, "%d\n", rebase->current+1)) < 0 ||
759
- (error = rebase_setupfile(rebase, CURRENT_FILE, -1, "%.*s\n", GIT_OID_HEXSZ, current_idstr)) < 0)
760
- goto done;
761
-
762
799
  normalize_checkout_opts(rebase, current_commit, &checkout_opts, given_checkout_opts);
763
800
 
764
- if ((error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, NULL)) < 0 ||
801
+ if ((error = git_indexwriter_init_for_operation(&indexwriter, rebase->repo, &checkout_opts.checkout_strategy)) < 0 ||
802
+ (error = rebase_setupfile(rebase, MSGNUM_FILE, -1, "%d\n", rebase->current+1)) < 0 ||
803
+ (error = rebase_setupfile(rebase, CURRENT_FILE, -1, "%.*s\n", GIT_OID_HEXSZ, current_idstr)) < 0 ||
804
+ (error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, NULL)) < 0 ||
765
805
  (error = git_merge__check_result(rebase->repo, index)) < 0 ||
766
- (error = git_checkout_index(rebase->repo, index, &checkout_opts)) < 0)
806
+ (error = git_checkout_index(rebase->repo, index, &checkout_opts)) < 0 ||
807
+ (error = git_indexwriter_commit(&indexwriter)) < 0)
767
808
  goto done;
768
809
 
769
810
  *out = operation;
770
811
 
771
812
  done:
813
+ git_indexwriter_cleanup(&indexwriter);
772
814
  git_index_free(index);
773
815
  git_tree_free(current_tree);
774
816
  git_tree_free(head_tree);
@@ -861,7 +903,7 @@ static int rebase_commit_merge(
861
903
  (const git_commit **)&head_commit)) < 0 ||
862
904
  (error = git_commit_lookup(&commit, rebase->repo, commit_id)) < 0 ||
863
905
  (error = git_reference__update_for_commit(
864
- rebase->repo, NULL, "HEAD", commit_id, committer, "rebase")) < 0)
906
+ rebase->repo, NULL, "HEAD", commit_id, "rebase")) < 0)
865
907
  goto done;
866
908
 
867
909
  git_oid_fmt(old_idstr, git_commit_id(current_commit));
@@ -908,20 +950,20 @@ int git_rebase_commit(
908
950
  return error;
909
951
  }
910
952
 
911
- int git_rebase_abort(git_rebase *rebase, const git_signature *signature)
953
+ int git_rebase_abort(git_rebase *rebase)
912
954
  {
913
955
  git_reference *orig_head_ref = NULL;
914
956
  git_commit *orig_head_commit = NULL;
915
957
  int error;
916
958
 
917
- assert(rebase && signature);
959
+ assert(rebase);
918
960
 
919
961
  error = rebase->head_detached ?
920
962
  git_reference_create(&orig_head_ref, rebase->repo, GIT_HEAD_FILE,
921
- &rebase->orig_head_id, 1, signature, "rebase: aborting") :
963
+ &rebase->orig_head_id, 1, "rebase: aborting") :
922
964
  git_reference_symbolic_create(
923
965
  &orig_head_ref, rebase->repo, GIT_HEAD_FILE, rebase->orig_head_name, 1,
924
- signature, "rebase: aborting");
966
+ "rebase: aborting");
925
967
 
926
968
  if (error < 0)
927
969
  goto done;
@@ -929,7 +971,7 @@ int git_rebase_abort(git_rebase *rebase, const git_signature *signature)
929
971
  if ((error = git_commit_lookup(
930
972
  &orig_head_commit, rebase->repo, &rebase->orig_head_id)) < 0 ||
931
973
  (error = git_reset(rebase->repo, (git_object *)orig_head_commit,
932
- GIT_RESET_HARD, NULL, signature, NULL)) < 0)
974
+ GIT_RESET_HARD, NULL)) < 0)
933
975
  goto done;
934
976
 
935
977
  error = rebase_cleanup(rebase);
@@ -1074,10 +1116,10 @@ int git_rebase_finish(
1074
1116
  terminal_ref, GIT_OBJ_COMMIT)) < 0 ||
1075
1117
  (error = git_reference_create_matching(&branch_ref,
1076
1118
  rebase->repo, rebase->orig_head_name, git_commit_id(terminal_commit), 1,
1077
- &rebase->orig_head_id, signature, branch_msg.ptr)) < 0 ||
1119
+ &rebase->orig_head_id, branch_msg.ptr)) < 0 ||
1078
1120
  (error = git_reference_symbolic_create(&head_ref,
1079
1121
  rebase->repo, GIT_HEAD_FILE, rebase->orig_head_name, 1,
1080
- signature, head_msg.ptr)) < 0 ||
1122
+ head_msg.ptr)) < 0 ||
1081
1123
  (error = rebase_copy_notes(rebase, signature, &opts)) < 0)
1082
1124
  goto done;
1083
1125