rugged 0.24.6.1 → 0.25.0b1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/rugged_repo.c +44 -36
  3. data/lib/rugged/version.rb +1 -1
  4. data/vendor/libgit2/CMakeLists.txt +10 -21
  5. data/vendor/libgit2/include/git2/checkout.h +0 -7
  6. data/vendor/libgit2/include/git2/commit.h +46 -0
  7. data/vendor/libgit2/include/git2/common.h +1 -16
  8. data/vendor/libgit2/include/git2/odb.h +47 -1
  9. data/vendor/libgit2/include/git2/version.h +2 -2
  10. data/vendor/libgit2/src/array.h +0 -40
  11. data/vendor/libgit2/src/blame.c +3 -8
  12. data/vendor/libgit2/src/blame_git.c +9 -20
  13. data/vendor/libgit2/src/checkout.c +5 -13
  14. data/vendor/libgit2/src/commit.c +132 -52
  15. data/vendor/libgit2/src/common.h +1 -1
  16. data/vendor/libgit2/src/config_cache.c +1 -2
  17. data/vendor/libgit2/src/config_file.c +20 -14
  18. data/vendor/libgit2/src/delta-apply.c +5 -36
  19. data/vendor/libgit2/src/delta-apply.h +0 -12
  20. data/vendor/libgit2/src/describe.c +1 -2
  21. data/vendor/libgit2/src/diff_tform.c +3 -5
  22. data/vendor/libgit2/src/filebuf.c +1 -6
  23. data/vendor/libgit2/src/global.c +8 -28
  24. data/vendor/libgit2/src/global.h +0 -1
  25. data/vendor/libgit2/src/ignore.c +19 -56
  26. data/vendor/libgit2/src/index.c +8 -27
  27. data/vendor/libgit2/src/indexer.c +7 -11
  28. data/vendor/libgit2/src/iterator.c +2 -2
  29. data/vendor/libgit2/src/merge.c +0 -1
  30. data/vendor/libgit2/src/mwindow.c +19 -8
  31. data/vendor/libgit2/src/mwindow.h +2 -1
  32. data/vendor/libgit2/src/object.c +6 -3
  33. data/vendor/libgit2/src/odb.c +188 -48
  34. data/vendor/libgit2/src/odb_loose.c +1 -1
  35. data/vendor/libgit2/src/odb_pack.c +3 -0
  36. data/vendor/libgit2/src/openssl_stream.c +27 -60
  37. data/vendor/libgit2/src/openssl_stream.h +0 -106
  38. data/vendor/libgit2/src/pack-objects.c +2 -4
  39. data/vendor/libgit2/src/pack.c +9 -5
  40. data/vendor/libgit2/src/posix.c +0 -7
  41. data/vendor/libgit2/src/posix.h +0 -1
  42. data/vendor/libgit2/src/push.c +6 -6
  43. data/vendor/libgit2/src/refdb_fs.c +0 -1
  44. data/vendor/libgit2/src/refs.c +0 -3
  45. data/vendor/libgit2/src/refspec.c +2 -4
  46. data/vendor/libgit2/src/remote.c +5 -15
  47. data/vendor/libgit2/src/repository.c +21 -29
  48. data/vendor/libgit2/src/settings.c +1 -23
  49. data/vendor/libgit2/src/stransport_stream.c +9 -15
  50. data/vendor/libgit2/src/submodule.c +2 -3
  51. data/vendor/libgit2/src/sysdir.c +47 -41
  52. data/vendor/libgit2/src/sysdir.h +5 -0
  53. data/vendor/libgit2/src/tag.c +2 -8
  54. data/vendor/libgit2/src/thread-utils.h +51 -5
  55. data/vendor/libgit2/src/transports/http.c +3 -3
  56. data/vendor/libgit2/src/transports/smart_pkt.c +4 -13
  57. data/vendor/libgit2/src/transports/smart_protocol.c +17 -61
  58. data/vendor/libgit2/src/tree.c +100 -83
  59. data/vendor/libgit2/src/tree.h +5 -4
  60. data/vendor/libgit2/src/unix/map.c +0 -5
  61. data/vendor/libgit2/src/util.c +3 -3
  62. data/vendor/libgit2/src/win32/map.c +5 -24
  63. data/vendor/libgit2/src/win32/precompiled.h +1 -1
  64. data/vendor/libgit2/src/win32/{thread.c → pthread.c} +80 -50
  65. data/vendor/libgit2/src/win32/pthread.h +92 -0
  66. data/vendor/libgit2/src/xdiff/xprepare.c +1 -2
  67. metadata +7 -8
  68. data/vendor/libgit2/src/unix/pthread.h +0 -54
  69. data/vendor/libgit2/src/win32/thread.h +0 -62
@@ -458,7 +458,7 @@ static int tree_iterator__set_next(tree_iterator *ti, tree_iterator_frame *tf)
458
458
  /* try to load trees for items in [current,next) range */
459
459
  if (!error && git_tree_entry__is_tree(te))
460
460
  error = git_tree_lookup(
461
- &tf->entries[tf->next]->tree, ti->base.repo, te->oid);
461
+ &tf->entries[tf->next]->tree, ti->base.repo, &te->oid);
462
462
  }
463
463
 
464
464
  if (tf->next > tf->current + 1)
@@ -603,7 +603,7 @@ static int tree_iterator__update_entry(tree_iterator *ti)
603
603
  te = tf->entries[tf->current]->te;
604
604
 
605
605
  ti->entry.mode = te->attr;
606
- git_oid_cpy(&ti->entry.id, te->oid);
606
+ git_oid_cpy(&ti->entry.id, &te->oid);
607
607
 
608
608
  ti->entry.path = tree_iterator__current_filename(ti, te);
609
609
  GITERR_CHECK_ALLOC(ti->entry.path);
@@ -2730,7 +2730,6 @@ static int merge_check_workdir(size_t *conflicts, git_repository *repo, git_inde
2730
2730
  opts.flags |= GIT_DIFF_DISABLE_PATHSPEC_MATCH;
2731
2731
  opts.pathspec.count = merged_paths->length;
2732
2732
  opts.pathspec.strings = (char **)merged_paths->contents;
2733
- opts.ignore_submodules = GIT_SUBMODULE_IGNORE_ALL;
2734
2733
 
2735
2734
  if ((error = git_diff_index_to_workdir(&wd_diff_list, repo, NULL, &opts)) < 0)
2736
2735
  goto done;
@@ -33,20 +33,25 @@ static git_mwindow_ctl mem_ctl;
33
33
  /* Global list of mwindow files, to open packs once across repos */
34
34
  git_strmap *git__pack_cache = NULL;
35
35
 
36
- static void git_mwindow_files_free(void)
36
+ /**
37
+ * Run under mwindow lock
38
+ */
39
+ int git_mwindow_files_init(void)
37
40
  {
38
- git_strmap *tmp = git__pack_cache;
41
+ if (git__pack_cache)
42
+ return 0;
39
43
 
40
- git__pack_cache = NULL;
41
- git_strmap_free(tmp);
44
+ git__on_shutdown(git_mwindow_files_free);
45
+
46
+ return git_strmap_alloc(&git__pack_cache);
42
47
  }
43
48
 
44
- int git_mwindow_global_init(void)
49
+ void git_mwindow_files_free(void)
45
50
  {
46
- assert(!git__pack_cache);
51
+ git_strmap *tmp = git__pack_cache;
47
52
 
48
- git__on_shutdown(git_mwindow_files_free);
49
- return git_strmap_alloc(&git__pack_cache);
53
+ git__pack_cache = NULL;
54
+ git_strmap_free(tmp);
50
55
  }
51
56
 
52
57
  int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
@@ -64,6 +69,12 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
64
69
  return -1;
65
70
  }
66
71
 
72
+ if (git_mwindow_files_init() < 0) {
73
+ git_mutex_unlock(&git__mwindow_mutex);
74
+ git__free(packname);
75
+ return -1;
76
+ }
77
+
67
78
  pos = git_strmap_lookup_index(git__pack_cache, packname);
68
79
  git__free(packname);
69
80
 
@@ -43,7 +43,8 @@ int git_mwindow_file_register(git_mwindow_file *mwf);
43
43
  void git_mwindow_file_deregister(git_mwindow_file *mwf);
44
44
  void git_mwindow_close(git_mwindow **w_cursor);
45
45
 
46
- extern int git_mwindow_global_init(void);
46
+ int git_mwindow_files_init(void);
47
+ void git_mwindow_files_free(void);
47
48
 
48
49
  struct git_pack_file; /* just declaration to avoid cyclical includes */
49
50
  int git_mwindow_get_pack(struct git_pack_file **out, const char *path);
@@ -12,7 +12,6 @@
12
12
  #include "commit.h"
13
13
  #include "tree.h"
14
14
  #include "blob.h"
15
- #include "oid.h"
16
15
  #include "tag.h"
17
16
 
18
17
  bool git_object__strict_input_validation = true;
@@ -167,9 +166,13 @@ int git_object_lookup_prefix(
167
166
  error = git_odb_read(&odb_obj, odb, id);
168
167
  }
169
168
  } else {
170
- git_oid short_oid = {{ 0 }};
169
+ git_oid short_oid;
171
170
 
172
- git_oid__cpy_prefix(&short_oid, id, len);
171
+ /* We copy the first len*4 bits from id and fill the remaining with 0s */
172
+ memcpy(short_oid.id, id->id, (len + 1) / 2);
173
+ if (len % 2)
174
+ short_oid.id[len / 2] &= 0xF0;
175
+ memset(short_oid.id + (len + 1) / 2, 0, (GIT_OID_HEXSZ - len) / 2);
173
176
 
174
177
  /* If len < GIT_OID_HEXSZ (a strict short oid was given), we have
175
178
  * 2 options :
@@ -18,6 +18,7 @@
18
18
 
19
19
  #include "git2/odb_backend.h"
20
20
  #include "git2/oid.h"
21
+ #include "git2/oidarray.h"
21
22
 
22
23
  #define GIT_ALTERNATES_FILE "info/alternates"
23
24
 
@@ -48,8 +49,37 @@ static git_cache *odb_cache(git_odb *odb)
48
49
  return &odb->own_cache;
49
50
  }
50
51
 
52
+ static int odb_otype_fast(git_otype *type_p, git_odb *db, const git_oid *id);
51
53
  static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_depth);
52
54
 
55
+ static git_otype odb_hardcoded_type(const git_oid *id)
56
+ {
57
+ static git_oid empty_blob = {{ 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b,
58
+ 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 }};
59
+ static git_oid empty_tree = {{ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
60
+ 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }};
61
+
62
+ if (!git_oid_cmp(id, &empty_blob))
63
+ return GIT_OBJ_BLOB;
64
+
65
+ if (!git_oid_cmp(id, &empty_tree))
66
+ return GIT_OBJ_TREE;
67
+
68
+ return GIT_OBJ_BAD;
69
+ }
70
+
71
+ static int odb_read_hardcoded(git_rawobj *raw, const git_oid *id)
72
+ {
73
+ git_otype type = odb_hardcoded_type(id);
74
+ if (type == GIT_OBJ_BAD)
75
+ return -1;
76
+
77
+ raw->type = type;
78
+ raw->len = 0;
79
+ raw->data = git__calloc(1, sizeof(uint8_t));
80
+ return 0;
81
+ }
82
+
53
83
  int git_odb__format_object_header(char *hdr, size_t n, git_off_t obj_len, git_otype obj_type)
54
84
  {
55
85
  const char *type_str = git_object_type2string(obj_type);
@@ -651,7 +681,7 @@ int git_odb_exists(git_odb *db, const git_oid *id)
651
681
 
652
682
  if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) {
653
683
  git_odb_object_free(object);
654
- return (int)true;
684
+ return 1;
655
685
  }
656
686
 
657
687
  if (odb_exists_1(db, id, false))
@@ -716,10 +746,8 @@ int git_odb_exists_prefix(
716
746
 
717
747
  if (len < GIT_OID_MINPREFIXLEN)
718
748
  return git_odb__error_ambiguous("prefix length too short");
719
- if (len > GIT_OID_HEXSZ)
720
- len = GIT_OID_HEXSZ;
721
749
 
722
- if (len == GIT_OID_HEXSZ) {
750
+ if (len >= GIT_OID_HEXSZ) {
723
751
  if (git_odb_exists(db, short_id)) {
724
752
  if (out)
725
753
  git_oid_cpy(out, short_id);
@@ -730,10 +758,7 @@ int git_odb_exists_prefix(
730
758
  }
731
759
  }
732
760
 
733
- /* just copy valid part of short_id */
734
- memcpy(&key.id, short_id->id, (len + 1) / 2);
735
- if (len & 1)
736
- key.id[len / 2] &= 0xF0;
761
+ git_oid__cpy_prefix(&key, short_id, len);
737
762
 
738
763
  error = odb_exists_prefix_1(out, db, &key, len, false);
739
764
 
@@ -746,6 +771,72 @@ int git_odb_exists_prefix(
746
771
  return error;
747
772
  }
748
773
 
774
+ int git_odb_expand_ids(
775
+ git_odb *db,
776
+ git_odb_expand_id *ids,
777
+ size_t count)
778
+ {
779
+ size_t i;
780
+
781
+ assert(db && ids);
782
+
783
+ for (i = 0; i < count; i++) {
784
+ git_odb_expand_id *query = &ids[i];
785
+ int error = GIT_EAMBIGUOUS;
786
+
787
+ if (!query->type)
788
+ query->type = GIT_OBJ_ANY;
789
+
790
+ /* if we have a short OID, expand it first */
791
+ if (query->length >= GIT_OID_MINPREFIXLEN && query->length < GIT_OID_HEXSZ) {
792
+ git_oid actual_id;
793
+
794
+ error = odb_exists_prefix_1(&actual_id, db, &query->id, query->length, false);
795
+ if (!error) {
796
+ git_oid_cpy(&query->id, &actual_id);
797
+ query->length = GIT_OID_HEXSZ;
798
+ }
799
+ }
800
+
801
+ /*
802
+ * now we ought to have a 40-char OID, either because we've expanded it
803
+ * or because the user passed a full OID. Ensure its type is right.
804
+ */
805
+ if (query->length >= GIT_OID_HEXSZ) {
806
+ git_otype actual_type;
807
+
808
+ error = odb_otype_fast(&actual_type, db, &query->id);
809
+ if (!error) {
810
+ if (query->type != GIT_OBJ_ANY && query->type != actual_type)
811
+ error = GIT_ENOTFOUND;
812
+ else
813
+ query->type = actual_type;
814
+ }
815
+ }
816
+
817
+ switch (error) {
818
+ /* no errors, so we've successfully expanded the OID */
819
+ case 0:
820
+ continue;
821
+
822
+ /* the object is missing or ambiguous */
823
+ case GIT_ENOTFOUND:
824
+ case GIT_EAMBIGUOUS:
825
+ memset(&query->id, 0, sizeof(git_oid));
826
+ query->length = 0;
827
+ query->type = 0;
828
+ break;
829
+
830
+ /* something went very wrong with the ODB; bail hard */
831
+ default:
832
+ return error;
833
+ }
834
+ }
835
+
836
+ giterr_clear();
837
+ return 0;
838
+ }
839
+
749
840
  int git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *db, const git_oid *id)
750
841
  {
751
842
  int error;
@@ -759,11 +850,53 @@ int git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *db, const git
759
850
  return error;
760
851
  }
761
852
 
853
+ static int odb_read_header_1(
854
+ size_t *len_p, git_otype *type_p, git_odb *db,
855
+ const git_oid *id, bool only_refreshed)
856
+ {
857
+ size_t i;
858
+ git_otype ht;
859
+ bool passthrough = false;
860
+ int error;
861
+
862
+ if (!only_refreshed && (ht = odb_hardcoded_type(id)) != GIT_OBJ_BAD) {
863
+ *type_p = ht;
864
+ *len_p = 0;
865
+ return 0;
866
+ }
867
+
868
+ for (i = 0; i < db->backends.length; ++i) {
869
+ backend_internal *internal = git_vector_get(&db->backends, i);
870
+ git_odb_backend *b = internal->backend;
871
+
872
+ if (only_refreshed && !b->refresh)
873
+ continue;
874
+
875
+ if (!b->read_header) {
876
+ passthrough = true;
877
+ continue;
878
+ }
879
+
880
+ error = b->read_header(len_p, type_p, b, id);
881
+
882
+ switch (error) {
883
+ case GIT_PASSTHROUGH:
884
+ passthrough = true;
885
+ break;
886
+ case GIT_ENOTFOUND:
887
+ break;
888
+ default:
889
+ return error;
890
+ }
891
+ }
892
+
893
+ return passthrough ? GIT_PASSTHROUGH : GIT_ENOTFOUND;
894
+ }
895
+
762
896
  int git_odb__read_header_or_object(
763
897
  git_odb_object **out, size_t *len_p, git_otype *type_p,
764
898
  git_odb *db, const git_oid *id)
765
899
  {
766
- size_t i;
767
900
  int error = GIT_ENOTFOUND;
768
901
  git_odb_object *object;
769
902
 
@@ -777,45 +910,32 @@ int git_odb__read_header_or_object(
777
910
  }
778
911
 
779
912
  *out = NULL;
913
+ error = odb_read_header_1(len_p, type_p, db, id, false);
780
914
 
781
- for (i = 0; i < db->backends.length && error < 0; ++i) {
782
- backend_internal *internal = git_vector_get(&db->backends, i);
783
- git_odb_backend *b = internal->backend;
915
+ if (error == GIT_ENOTFOUND && !git_odb_refresh(db))
916
+ error = odb_read_header_1(len_p, type_p, db, id, true);
784
917
 
785
- if (b->read_header != NULL)
786
- error = b->read_header(len_p, type_p, b, id);
787
- }
918
+ if (error == GIT_ENOTFOUND)
919
+ return git_odb__error_notfound("cannot read header for", id, GIT_OID_HEXSZ);
788
920
 
789
- if (!error || error == GIT_PASSTHROUGH)
921
+ /* we found the header; return early */
922
+ if (!error)
790
923
  return 0;
791
924
 
792
- /*
793
- * no backend could read only the header.
794
- * try reading the whole object and freeing the contents
795
- */
796
- if ((error = git_odb_read(&object, db, id)) < 0)
797
- return error; /* error already set - pass along */
798
-
799
- *len_p = object->cached.size;
800
- *type_p = object->cached.type;
801
- *out = object;
802
-
803
- return 0;
804
- }
805
-
806
- static git_oid empty_tree = {{ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
807
- 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }};
808
-
809
- static int hardcoded_objects(git_rawobj *raw, const git_oid *id)
810
- {
811
- if (!git_oid_cmp(id, &empty_tree)) {
812
- raw->type = GIT_OBJ_TREE;
813
- raw->len = 0;
814
- raw->data = git__calloc(1, sizeof(uint8_t));
815
- return 0;
816
- } else {
817
- return GIT_ENOTFOUND;
925
+ if (error == GIT_PASSTHROUGH) {
926
+ /*
927
+ * no backend has header-reading functionality
928
+ * so try using `git_odb_read` instead
929
+ */
930
+ error = git_odb_read(&object, db, id);
931
+ if (!error) {
932
+ *len_p = object->cached.size;
933
+ *type_p = object->cached.type;
934
+ *out = object;
935
+ }
818
936
  }
937
+
938
+ return error;
819
939
  }
820
940
 
821
941
  static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id,
@@ -826,7 +946,7 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id,
826
946
  git_odb_object *object;
827
947
  bool found = false;
828
948
 
829
- if (!hardcoded_objects(&raw, id))
949
+ if (!only_refreshed && odb_read_hardcoded(&raw, id) == 0)
830
950
  found = true;
831
951
 
832
952
  for (i = 0; i < db->backends.length && !found; ++i) {
@@ -880,6 +1000,29 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
880
1000
  return error;
881
1001
  }
882
1002
 
1003
+ static int odb_otype_fast(git_otype *type_p, git_odb *db, const git_oid *id)
1004
+ {
1005
+ git_odb_object *object;
1006
+ size_t _unused;
1007
+ int error;
1008
+
1009
+ if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) {
1010
+ *type_p = object->cached.type;
1011
+ return 0;
1012
+ }
1013
+
1014
+ error = odb_read_header_1(&_unused, type_p, db, id, false);
1015
+
1016
+ if (error == GIT_PASSTHROUGH) {
1017
+ error = odb_read_1(&object, db, id, false);
1018
+ if (!error)
1019
+ *type_p = object->cached.type;
1020
+ git_odb_object_free(object);
1021
+ }
1022
+
1023
+ return error;
1024
+ }
1025
+
883
1026
  static int read_prefix_1(git_odb_object **out, git_odb *db,
884
1027
  const git_oid *key, size_t len, bool only_refreshed)
885
1028
  {
@@ -950,10 +1093,7 @@ int git_odb_read_prefix(
950
1093
  return 0;
951
1094
  }
952
1095
 
953
- /* just copy valid part of short_id */
954
- memcpy(&key.id, short_id->id, (len + 1) / 2);
955
- if (len & 1)
956
- key.id[len / 2] &= 0xF0;
1096
+ git_oid__cpy_prefix(&key, short_id, len);
957
1097
 
958
1098
  error = read_prefix_1(out, db, &key, len, false);
959
1099
 
@@ -1222,7 +1362,7 @@ int git_odb__error_notfound(
1222
1362
  {
1223
1363
  if (oid != NULL) {
1224
1364
  char oid_str[GIT_OID_HEXSZ + 1];
1225
- git_oid_tostr(oid_str, oid_len+1, oid);
1365
+ git_oid_tostr(oid_str, oid_len, oid);
1226
1366
  giterr_set(GITERR_ODB, "Object not found - %s (%.*s)",
1227
1367
  message, oid_len, oid_str);
1228
1368
  } else
@@ -91,7 +91,7 @@ static int object_mkdir(const git_buf *name, const loose_backend *be)
91
91
 
92
92
  static size_t get_binary_object_header(obj_hdr *hdr, git_buf *obj)
93
93
  {
94
- unsigned long c;
94
+ unsigned char c;
95
95
  unsigned char *data = (unsigned char *)obj->ptr;
96
96
  size_t shift, size, used = 0;
97
97
 
@@ -591,6 +591,9 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir)
591
591
  struct pack_backend *backend = NULL;
592
592
  git_buf path = GIT_BUF_INIT;
593
593
 
594
+ if (git_mwindow_files_init() < 0)
595
+ return -1;
596
+
594
597
  if (pack_backend__alloc(&backend, 8) < 0)
595
598
  return -1;
596
599