rugged 1.5.1 → 1.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/extconf.rb +2 -2
  3. data/ext/rugged/rugged_blame.c +2 -0
  4. data/ext/rugged/rugged_blob.c +3 -0
  5. data/ext/rugged/rugged_commit.c +1 -0
  6. data/ext/rugged/rugged_config.c +2 -0
  7. data/ext/rugged/rugged_diff.c +1 -0
  8. data/ext/rugged/rugged_index.c +2 -0
  9. data/ext/rugged/rugged_patch.c +1 -0
  10. data/ext/rugged/rugged_rebase.c +1 -0
  11. data/ext/rugged/rugged_reference.c +1 -0
  12. data/ext/rugged/rugged_remote.c +1 -0
  13. data/ext/rugged/rugged_repo.c +5 -2
  14. data/ext/rugged/rugged_revwalk.c +5 -1
  15. data/ext/rugged/rugged_submodule.c +1 -0
  16. data/ext/rugged/rugged_tag.c +1 -0
  17. data/ext/rugged/rugged_tree.c +4 -0
  18. data/lib/rugged/index.rb +1 -1
  19. data/lib/rugged/tree.rb +1 -1
  20. data/lib/rugged/version.rb +1 -1
  21. data/vendor/libgit2/CMakeLists.txt +5 -1
  22. data/vendor/libgit2/COPYING +30 -0
  23. data/vendor/libgit2/cmake/ExperimentalFeatures.cmake +23 -0
  24. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +2 -0
  25. data/vendor/libgit2/include/git2/common.h +13 -6
  26. data/vendor/libgit2/include/git2/deprecated.h +6 -0
  27. data/vendor/libgit2/include/git2/diff.h +1 -1
  28. data/vendor/libgit2/include/git2/experimental.h +20 -0
  29. data/vendor/libgit2/include/git2/indexer.h +29 -0
  30. data/vendor/libgit2/include/git2/object.h +28 -2
  31. data/vendor/libgit2/include/git2/odb.h +58 -7
  32. data/vendor/libgit2/include/git2/odb_backend.h +106 -18
  33. data/vendor/libgit2/include/git2/oid.h +115 -15
  34. data/vendor/libgit2/include/git2/repository.h +20 -1
  35. data/vendor/libgit2/include/git2/stash.h +60 -6
  36. data/vendor/libgit2/include/git2/strarray.h +0 -13
  37. data/vendor/libgit2/include/git2/sys/odb_backend.h +1 -1
  38. data/vendor/libgit2/include/git2/sys/transport.h +12 -0
  39. data/vendor/libgit2/include/git2/version.h +4 -4
  40. data/vendor/libgit2/include/git2.h +1 -0
  41. data/vendor/libgit2/src/CMakeLists.txt +0 -6
  42. data/vendor/libgit2/src/cli/CMakeLists.txt +6 -2
  43. data/vendor/libgit2/src/cli/cmd_hash_object.c +27 -8
  44. data/vendor/libgit2/src/cli/opt.c +1 -1
  45. data/vendor/libgit2/src/libgit2/CMakeLists.txt +25 -15
  46. data/vendor/libgit2/src/libgit2/annotated_commit.c +1 -1
  47. data/vendor/libgit2/src/libgit2/annotated_commit.h +1 -1
  48. data/vendor/libgit2/src/libgit2/attr_file.c +1 -1
  49. data/vendor/libgit2/src/libgit2/attrcache.c +1 -1
  50. data/vendor/libgit2/src/libgit2/blame.c +2 -0
  51. data/vendor/libgit2/src/libgit2/blob.c +4 -2
  52. data/vendor/libgit2/src/libgit2/blob.h +2 -2
  53. data/vendor/libgit2/src/libgit2/branch.c +2 -2
  54. data/vendor/libgit2/src/libgit2/cherrypick.c +3 -3
  55. data/vendor/libgit2/src/libgit2/clone.c +31 -2
  56. data/vendor/libgit2/src/libgit2/commit.c +52 -17
  57. data/vendor/libgit2/src/libgit2/commit.h +25 -7
  58. data/vendor/libgit2/src/libgit2/commit_graph.c +47 -32
  59. data/vendor/libgit2/src/libgit2/commit_graph.h +3 -0
  60. data/vendor/libgit2/src/libgit2/commit_list.c +6 -2
  61. data/vendor/libgit2/src/libgit2/config.c +1 -1
  62. data/vendor/libgit2/src/libgit2/config_file.c +2 -2
  63. data/vendor/libgit2/src/libgit2/describe.c +8 -8
  64. data/vendor/libgit2/src/libgit2/diff.c +5 -1
  65. data/vendor/libgit2/src/libgit2/diff_file.c +15 -6
  66. data/vendor/libgit2/src/libgit2/diff_generate.c +17 -12
  67. data/vendor/libgit2/src/libgit2/diff_print.c +5 -5
  68. data/vendor/libgit2/src/libgit2/diff_tform.c +4 -0
  69. data/vendor/libgit2/src/libgit2/email.c +2 -2
  70. data/vendor/libgit2/src/libgit2/experimental.h.in +13 -0
  71. data/vendor/libgit2/src/libgit2/fetch.c +3 -6
  72. data/vendor/libgit2/src/libgit2/fetchhead.c +4 -4
  73. data/vendor/libgit2/src/libgit2/ident.c +3 -3
  74. data/vendor/libgit2/src/libgit2/index.c +11 -9
  75. data/vendor/libgit2/src/libgit2/indexer.c +107 -44
  76. data/vendor/libgit2/src/libgit2/iterator.c +4 -2
  77. data/vendor/libgit2/src/libgit2/libgit2.c +19 -0
  78. data/vendor/libgit2/src/libgit2/merge.c +3 -3
  79. data/vendor/libgit2/src/libgit2/midx.c +16 -15
  80. data/vendor/libgit2/src/libgit2/mwindow.c +5 -2
  81. data/vendor/libgit2/src/libgit2/mwindow.h +4 -1
  82. data/vendor/libgit2/src/libgit2/notes.c +5 -5
  83. data/vendor/libgit2/src/libgit2/object.c +89 -25
  84. data/vendor/libgit2/src/libgit2/object.h +12 -3
  85. data/vendor/libgit2/src/libgit2/odb.c +194 -50
  86. data/vendor/libgit2/src/libgit2/odb.h +43 -4
  87. data/vendor/libgit2/src/libgit2/odb_loose.c +128 -70
  88. data/vendor/libgit2/src/libgit2/odb_pack.c +96 -44
  89. data/vendor/libgit2/src/libgit2/oid.c +134 -76
  90. data/vendor/libgit2/src/libgit2/oid.h +183 -9
  91. data/vendor/libgit2/src/libgit2/pack-objects.c +15 -4
  92. data/vendor/libgit2/src/libgit2/pack.c +90 -66
  93. data/vendor/libgit2/src/libgit2/pack.h +29 -15
  94. data/vendor/libgit2/src/libgit2/parse.c +4 -3
  95. data/vendor/libgit2/src/libgit2/patch_parse.c +5 -5
  96. data/vendor/libgit2/src/libgit2/push.c +13 -3
  97. data/vendor/libgit2/src/libgit2/reader.c +1 -1
  98. data/vendor/libgit2/src/libgit2/rebase.c +19 -18
  99. data/vendor/libgit2/src/libgit2/refdb_fs.c +70 -39
  100. data/vendor/libgit2/src/libgit2/reflog.c +7 -5
  101. data/vendor/libgit2/src/libgit2/reflog.h +1 -2
  102. data/vendor/libgit2/src/libgit2/refs.c +2 -0
  103. data/vendor/libgit2/src/libgit2/remote.c +38 -37
  104. data/vendor/libgit2/src/libgit2/remote.h +40 -0
  105. data/vendor/libgit2/src/libgit2/repository.c +212 -36
  106. data/vendor/libgit2/src/libgit2/repository.h +9 -0
  107. data/vendor/libgit2/src/libgit2/reset.c +2 -2
  108. data/vendor/libgit2/src/libgit2/revert.c +4 -4
  109. data/vendor/libgit2/src/libgit2/revparse.c +23 -7
  110. data/vendor/libgit2/src/libgit2/revwalk.c +5 -1
  111. data/vendor/libgit2/src/libgit2/stash.c +201 -26
  112. data/vendor/libgit2/src/libgit2/strarray.c +1 -0
  113. data/vendor/libgit2/src/libgit2/strarray.h +25 -0
  114. data/vendor/libgit2/src/libgit2/streams/openssl.c +1 -1
  115. data/vendor/libgit2/src/libgit2/streams/openssl_dynamic.c +7 -3
  116. data/vendor/libgit2/src/libgit2/streams/socket.c +4 -1
  117. data/vendor/libgit2/src/libgit2/submodule.c +6 -2
  118. data/vendor/libgit2/src/libgit2/sysdir.c +294 -7
  119. data/vendor/libgit2/src/libgit2/sysdir.h +39 -9
  120. data/vendor/libgit2/src/libgit2/tag.c +29 -10
  121. data/vendor/libgit2/src/libgit2/tag.h +2 -2
  122. data/vendor/libgit2/src/libgit2/threadstate.h +1 -1
  123. data/vendor/libgit2/src/libgit2/transports/http.c +8 -7
  124. data/vendor/libgit2/src/libgit2/transports/httpclient.c +9 -0
  125. data/vendor/libgit2/src/libgit2/transports/httpclient.h +10 -0
  126. data/vendor/libgit2/src/libgit2/transports/local.c +14 -0
  127. data/vendor/libgit2/src/libgit2/transports/smart.c +35 -0
  128. data/vendor/libgit2/src/libgit2/transports/smart.h +10 -1
  129. data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +153 -41
  130. data/vendor/libgit2/src/libgit2/transports/smart_protocol.c +42 -12
  131. data/vendor/libgit2/src/libgit2/transports/ssh.c +62 -65
  132. data/vendor/libgit2/src/libgit2/transports/winhttp.c +9 -4
  133. data/vendor/libgit2/src/libgit2/tree-cache.c +4 -4
  134. data/vendor/libgit2/src/libgit2/tree.c +22 -16
  135. data/vendor/libgit2/src/libgit2/tree.h +2 -2
  136. data/vendor/libgit2/src/libgit2/worktree.c +5 -0
  137. data/vendor/libgit2/src/util/CMakeLists.txt +7 -1
  138. data/vendor/libgit2/src/util/fs_path.c +1 -1
  139. data/vendor/libgit2/src/util/futils.c +0 -3
  140. data/vendor/libgit2/src/util/git2_util.h +2 -2
  141. data/vendor/libgit2/src/util/hash/openssl.c +4 -3
  142. data/vendor/libgit2/src/util/hash/rfc6234/sha.h +0 -112
  143. data/vendor/libgit2/src/util/hash.h +13 -0
  144. data/vendor/libgit2/src/util/net.c +338 -84
  145. data/vendor/libgit2/src/util/net.h +7 -0
  146. data/vendor/libgit2/src/util/posix.h +2 -0
  147. data/vendor/libgit2/src/util/rand.c +4 -0
  148. data/vendor/libgit2/src/util/regexp.c +3 -3
  149. data/vendor/libgit2/src/util/thread.h +20 -19
  150. data/vendor/libgit2/src/util/util.h +1 -0
  151. metadata +7 -5
  152. data/vendor/libgit2/src/util/win32/findfile.c +0 -286
  153. data/vendor/libgit2/src/util/win32/findfile.h +0 -22
  154. /data/vendor/libgit2/src/{features.h.in → util/git2_features.h.in} +0 -0
@@ -46,10 +46,8 @@ typedef struct {
46
46
  typedef struct loose_backend {
47
47
  git_odb_backend parent;
48
48
 
49
- int object_zlib_level; /** loose object zlib compression level. */
50
- int fsync_object_files; /** loose object file fsync flag. */
51
- mode_t object_file_mode;
52
- mode_t object_dir_mode;
49
+ git_odb_backend_loose_options options;
50
+ size_t oid_hexsize;
53
51
 
54
52
  size_t objects_dirlen;
55
53
  char objects_dir[GIT_FLEX_ARRAY];
@@ -59,13 +57,19 @@ typedef struct loose_backend {
59
57
  * in order to locate objects matching a short oid.
60
58
  */
61
59
  typedef struct {
60
+ loose_backend *backend;
61
+
62
62
  size_t dir_len;
63
- unsigned char short_oid[GIT_OID_HEXSZ]; /* hex formatted oid to match */
63
+
64
+ /* Hex formatted oid to match (and its length) */
65
+ unsigned char short_oid[GIT_OID_MAX_HEXSIZE];
64
66
  size_t short_oid_len;
65
- int found; /* number of matching
66
- * objects already found */
67
- unsigned char res_oid[GIT_OID_HEXSZ]; /* hex formatted oid of
68
- * the object found */
67
+
68
+ /* Number of matching objects found so far */
69
+ int found;
70
+
71
+ /* Hex formatted oid of the object found */
72
+ unsigned char res_oid[GIT_OID_MAX_HEXSIZE];
69
73
  } loose_locate_object_state;
70
74
 
71
75
 
@@ -78,20 +82,17 @@ typedef struct {
78
82
  static int object_file_name(
79
83
  git_str *name, const loose_backend *be, const git_oid *id)
80
84
  {
81
- size_t alloclen;
82
-
83
- /* expand length for object root + 40 hex sha1 chars + 2 * '/' + '\0' */
84
- GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, be->objects_dirlen, GIT_OID_HEXSZ);
85
- GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, alloclen, 3);
86
- if (git_str_grow(name, alloclen) < 0)
87
- return -1;
85
+ /* append loose object filename: aa/aaa... (41 bytes plus NUL) */
86
+ size_t path_size = be->oid_hexsize + 1;
88
87
 
89
88
  git_str_set(name, be->objects_dir, be->objects_dirlen);
90
89
  git_fs_path_to_dir(name);
91
90
 
92
- /* loose object filename: aa/aaa... (41 bytes) */
91
+ if (git_str_grow_by(name, path_size + 1) < 0)
92
+ return -1;
93
+
93
94
  git_oid_pathfmt(name->ptr + name->size, id);
94
- name->size += GIT_OID_HEXSZ + 1;
95
+ name->size += path_size;
95
96
  name->ptr[name->size] = '\0';
96
97
 
97
98
  return 0;
@@ -100,7 +101,9 @@ static int object_file_name(
100
101
  static int object_mkdir(const git_str *name, const loose_backend *be)
101
102
  {
102
103
  return git_futils_mkdir_relative(
103
- name->ptr + be->objects_dirlen, be->objects_dir, be->object_dir_mode,
104
+ name->ptr + be->objects_dirlen,
105
+ be->objects_dir,
106
+ be->options.dir_mode,
104
107
  GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST | GIT_MKDIR_VERIFY_DIR, NULL);
105
108
  }
106
109
 
@@ -461,8 +464,9 @@ static int locate_object(
461
464
  /* Explore an entry of a directory and see if it matches a short oid */
462
465
  static int fn_locate_object_short_oid(void *state, git_str *pathbuf) {
463
466
  loose_locate_object_state *sstate = (loose_locate_object_state *)state;
467
+ size_t hex_size = sstate->backend->oid_hexsize;
464
468
 
465
- if (git_str_len(pathbuf) - sstate->dir_len != GIT_OID_HEXSZ - 2) {
469
+ if (git_str_len(pathbuf) - sstate->dir_len != hex_size - 2) {
466
470
  /* Entry cannot be an object. Continue to next entry */
467
471
  return 0;
468
472
  }
@@ -477,7 +481,9 @@ static int fn_locate_object_short_oid(void *state, git_str *pathbuf) {
477
481
  if (!sstate->found) {
478
482
  sstate->res_oid[0] = sstate->short_oid[0];
479
483
  sstate->res_oid[1] = sstate->short_oid[1];
480
- memcpy(sstate->res_oid+2, pathbuf->ptr+sstate->dir_len, GIT_OID_HEXSZ-2);
484
+ memcpy(sstate->res_oid + 2,
485
+ pathbuf->ptr+sstate->dir_len,
486
+ hex_size - 2);
481
487
  }
482
488
  sstate->found++;
483
489
  }
@@ -503,7 +509,7 @@ static int locate_object_short_oid(
503
509
  int error;
504
510
 
505
511
  /* prealloc memory for OBJ_DIR/xx/xx..38x..xx */
506
- GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, dir_len, GIT_OID_HEXSZ);
512
+ GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, dir_len, backend->oid_hexsize);
507
513
  GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 3);
508
514
  if (git_str_grow(object_location, alloc_len) < 0)
509
515
  return -1;
@@ -527,6 +533,7 @@ static int locate_object_short_oid(
527
533
  return git_odb__error_notfound("no matching loose object for prefix",
528
534
  short_oid, len);
529
535
 
536
+ state.backend = backend;
530
537
  state.dir_len = git_str_len(object_location);
531
538
  state.short_oid_len = len;
532
539
  state.found = 0;
@@ -545,12 +552,12 @@ static int locate_object_short_oid(
545
552
  return git_odb__error_ambiguous("multiple matches in loose objects");
546
553
 
547
554
  /* Convert obtained hex formatted oid to raw */
548
- error = git_oid_fromstr(res_oid, (char *)state.res_oid);
555
+ error = git_oid__fromstr(res_oid, (char *)state.res_oid, backend->options.oid_type);
549
556
  if (error)
550
557
  return error;
551
558
 
552
559
  /* Update the location according to the oid obtained */
553
- GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, dir_len, GIT_OID_HEXSZ);
560
+ GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, dir_len, backend->oid_hexsize);
554
561
  GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
555
562
 
556
563
  git_str_truncate(object_location, dir_len);
@@ -559,20 +566,12 @@ static int locate_object_short_oid(
559
566
 
560
567
  git_oid_pathfmt(object_location->ptr + dir_len, res_oid);
561
568
 
562
- object_location->size += GIT_OID_HEXSZ + 1;
569
+ object_location->size += backend->oid_hexsize + 1;
563
570
  object_location->ptr[object_location->size] = '\0';
564
571
 
565
572
  return 0;
566
573
  }
567
574
 
568
-
569
-
570
-
571
-
572
-
573
-
574
-
575
-
576
575
  /***********************************************************
577
576
  *
578
577
  * LOOSE BACKEND PUBLIC API
@@ -595,7 +594,7 @@ static int loose_backend__read_header(size_t *len_p, git_object_t *type_p, git_o
595
594
 
596
595
  if (locate_object(&object_path, (loose_backend *)backend, oid) < 0) {
597
596
  error = git_odb__error_notfound("no matching loose object",
598
- oid, GIT_OID_HEXSZ);
597
+ oid, ((struct loose_backend *)backend)->oid_hexsize);
599
598
  } else if ((error = read_header_loose(&raw, &object_path)) == 0) {
600
599
  *len_p = raw.len;
601
600
  *type_p = raw.type;
@@ -617,7 +616,7 @@ static int loose_backend__read(void **buffer_p, size_t *len_p, git_object_t *typ
617
616
 
618
617
  if (locate_object(&object_path, (loose_backend *)backend, oid) < 0) {
619
618
  error = git_odb__error_notfound("no matching loose object",
620
- oid, GIT_OID_HEXSZ);
619
+ oid, ((struct loose_backend *)backend)->oid_hexsize);
621
620
  } else if ((error = read_loose(&raw, &object_path)) == 0) {
622
621
  *buffer_p = raw.data;
623
622
  *len_p = raw.len;
@@ -634,17 +633,19 @@ static int loose_backend__read_prefix(
634
633
  void **buffer_p,
635
634
  size_t *len_p,
636
635
  git_object_t *type_p,
637
- git_odb_backend *backend,
636
+ git_odb_backend *_backend,
638
637
  const git_oid *short_oid,
639
638
  size_t len)
640
639
  {
640
+ struct loose_backend *backend = (struct loose_backend *)_backend;
641
641
  int error = 0;
642
642
 
643
- GIT_ASSERT_ARG(len >= GIT_OID_MINPREFIXLEN && len <= GIT_OID_HEXSZ);
643
+ GIT_ASSERT_ARG(len >= GIT_OID_MINPREFIXLEN &&
644
+ len <= backend->oid_hexsize);
644
645
 
645
- if (len == GIT_OID_HEXSZ) {
646
+ if (len == backend->oid_hexsize) {
646
647
  /* We can fall back to regular read method */
647
- error = loose_backend__read(buffer_p, len_p, type_p, backend, short_oid);
648
+ error = loose_backend__read(buffer_p, len_p, type_p, _backend, short_oid);
648
649
  if (!error)
649
650
  git_oid_cpy(out_oid, short_oid);
650
651
  } else {
@@ -703,15 +704,18 @@ static int loose_backend__exists_prefix(
703
704
  }
704
705
 
705
706
  struct foreach_state {
707
+ struct loose_backend *backend;
706
708
  size_t dir_len;
707
709
  git_odb_foreach_cb cb;
708
710
  void *data;
709
711
  };
710
712
 
711
- GIT_INLINE(int) filename_to_oid(git_oid *oid, const char *ptr)
713
+ GIT_INLINE(int) filename_to_oid(struct loose_backend *backend, git_oid *oid, const char *ptr)
712
714
  {
713
- int v, i = 0;
714
- if (strlen(ptr) != GIT_OID_HEXSZ+1)
715
+ int v;
716
+ size_t i = 0;
717
+
718
+ if (strlen(ptr) != backend->oid_hexsize + 1)
715
719
  return -1;
716
720
 
717
721
  if (ptr[2] != '/') {
@@ -725,7 +729,7 @@ GIT_INLINE(int) filename_to_oid(git_oid *oid, const char *ptr)
725
729
  oid->id[0] = (unsigned char) v;
726
730
 
727
731
  ptr += 3;
728
- for (i = 0; i < 38; i += 2) {
732
+ for (i = 0; i < backend->oid_hexsize - 2; i += 2) {
729
733
  v = (git__fromhex(ptr[i]) << 4) | git__fromhex(ptr[i + 1]);
730
734
  if (v < 0)
731
735
  return -1;
@@ -733,6 +737,10 @@ GIT_INLINE(int) filename_to_oid(git_oid *oid, const char *ptr)
733
737
  oid->id[1 + i/2] = (unsigned char) v;
734
738
  }
735
739
 
740
+ #ifdef GIT_EXPERIMENTAL_SHA256
741
+ oid->type = backend->options.oid_type;
742
+ #endif
743
+
736
744
  return 0;
737
745
  }
738
746
 
@@ -741,7 +749,7 @@ static int foreach_object_dir_cb(void *_state, git_str *path)
741
749
  git_oid oid;
742
750
  struct foreach_state *state = (struct foreach_state *) _state;
743
751
 
744
- if (filename_to_oid(&oid, path->ptr + state->dir_len) < 0)
752
+ if (filename_to_oid(state->backend, &oid, path->ptr + state->dir_len) < 0)
745
753
  return 0;
746
754
 
747
755
  return git_error_set_after_callback_function(
@@ -778,6 +786,7 @@ static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb
778
786
  return -1;
779
787
 
780
788
  memset(&state, 0, sizeof(state));
789
+ state.backend = backend;
781
790
  state.cb = cb;
782
791
  state.data = data;
783
792
  state.dir_len = git_str_len(&buf);
@@ -825,9 +834,10 @@ static void loose_backend__writestream_free(git_odb_stream *_stream)
825
834
  static int filebuf_flags(loose_backend *backend)
826
835
  {
827
836
  int flags = GIT_FILEBUF_TEMPORARY |
828
- (backend->object_zlib_level << GIT_FILEBUF_DEFLATE_SHIFT);
837
+ (backend->options.compression_level << GIT_FILEBUF_DEFLATE_SHIFT);
829
838
 
830
- if (backend->fsync_object_files || git_repository__fsync_gitdir)
839
+ if ((backend->options.flags & GIT_ODB_BACKEND_LOOSE_FSYNC) ||
840
+ git_repository__fsync_gitdir)
831
841
  flags |= GIT_FILEBUF_FSYNC;
832
842
 
833
843
  return flags;
@@ -863,7 +873,7 @@ static int loose_backend__writestream(git_odb_stream **stream_out, git_odb_backe
863
873
 
864
874
  if (git_str_joinpath(&tmp_path, backend->objects_dir, "tmp_object") < 0 ||
865
875
  git_filebuf_open(&stream->fbuf, tmp_path.ptr, filebuf_flags(backend),
866
- backend->object_file_mode) < 0 ||
876
+ backend->options.file_mode) < 0 ||
867
877
  stream->stream.write((git_odb_stream *)stream, hdr, hdrlen) < 0)
868
878
  {
869
879
  git_filebuf_cleanup(&stream->fbuf);
@@ -997,6 +1007,7 @@ static int loose_backend__readstream(
997
1007
  loose_readstream *stream = NULL;
998
1008
  git_hash_ctx *hash_ctx = NULL;
999
1009
  git_str object_path = GIT_STR_INIT;
1010
+ git_hash_algorithm_t algorithm;
1000
1011
  obj_hdr hdr;
1001
1012
  int error = 0;
1002
1013
 
@@ -1013,7 +1024,7 @@ static int loose_backend__readstream(
1013
1024
 
1014
1025
  if (locate_object(&object_path, backend, oid) < 0) {
1015
1026
  error = git_odb__error_notfound("no matching loose object",
1016
- oid, GIT_OID_HEXSZ);
1027
+ oid, backend->oid_hexsize);
1017
1028
  goto done;
1018
1029
  }
1019
1030
 
@@ -1023,9 +1034,11 @@ static int loose_backend__readstream(
1023
1034
  hash_ctx = git__malloc(sizeof(git_hash_ctx));
1024
1035
  GIT_ERROR_CHECK_ALLOC(hash_ctx);
1025
1036
 
1026
- if ((error = git_hash_ctx_init(hash_ctx, GIT_HASH_ALGORITHM_SHA1)) < 0 ||
1027
- (error = git_futils_mmap_ro_file(&stream->map, object_path.ptr)) < 0 ||
1028
- (error = git_zstream_init(&stream->zstream, GIT_ZSTREAM_INFLATE)) < 0)
1037
+ algorithm = git_oid_algorithm(backend->options.oid_type);
1038
+
1039
+ if ((error = git_hash_ctx_init(hash_ctx, algorithm)) < 0 ||
1040
+ (error = git_futils_mmap_ro_file(&stream->map, object_path.ptr)) < 0 ||
1041
+ (error = git_zstream_init(&stream->zstream, GIT_ZSTREAM_INFLATE)) < 0)
1029
1042
  goto done;
1030
1043
 
1031
1044
  /* check for a packlike loose object */
@@ -1081,7 +1094,7 @@ static int loose_backend__write(git_odb_backend *_backend, const git_oid *oid, c
1081
1094
 
1082
1095
  if (git_str_joinpath(&final_path, backend->objects_dir, "tmp_object") < 0 ||
1083
1096
  git_filebuf_open(&fbuf, final_path.ptr, filebuf_flags(backend),
1084
- backend->object_file_mode) < 0)
1097
+ backend->options.file_mode) < 0)
1085
1098
  {
1086
1099
  error = -1;
1087
1100
  goto cleanup;
@@ -1124,13 +1137,34 @@ static void loose_backend__free(git_odb_backend *_backend)
1124
1137
  git__free(_backend);
1125
1138
  }
1126
1139
 
1127
- int git_odb_backend_loose(
1140
+ static void normalize_options(
1141
+ git_odb_backend_loose_options *opts,
1142
+ const git_odb_backend_loose_options *given_opts)
1143
+ {
1144
+ git_odb_backend_loose_options init = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT;
1145
+
1146
+ if (given_opts)
1147
+ memcpy(opts, given_opts, sizeof(git_odb_backend_loose_options));
1148
+ else
1149
+ memcpy(opts, &init, sizeof(git_odb_backend_loose_options));
1150
+
1151
+ if (opts->compression_level < 0)
1152
+ opts->compression_level = Z_BEST_SPEED;
1153
+
1154
+ if (opts->dir_mode == 0)
1155
+ opts->dir_mode = GIT_OBJECT_DIR_MODE;
1156
+
1157
+ if (opts->file_mode == 0)
1158
+ opts->file_mode = GIT_OBJECT_FILE_MODE;
1159
+
1160
+ if (opts->oid_type == 0)
1161
+ opts->oid_type = GIT_OID_DEFAULT;
1162
+ }
1163
+
1164
+ int git_odb__backend_loose(
1128
1165
  git_odb_backend **backend_out,
1129
1166
  const char *objects_dir,
1130
- int compression_level,
1131
- int do_fsync,
1132
- unsigned int dir_mode,
1133
- unsigned int file_mode)
1167
+ git_odb_backend_loose_options *opts)
1134
1168
  {
1135
1169
  loose_backend *backend;
1136
1170
  size_t objects_dirlen, alloclen;
@@ -1148,22 +1182,12 @@ int git_odb_backend_loose(
1148
1182
  backend->parent.version = GIT_ODB_BACKEND_VERSION;
1149
1183
  backend->objects_dirlen = objects_dirlen;
1150
1184
  memcpy(backend->objects_dir, objects_dir, objects_dirlen);
1185
+
1151
1186
  if (backend->objects_dir[backend->objects_dirlen - 1] != '/')
1152
1187
  backend->objects_dir[backend->objects_dirlen++] = '/';
1153
1188
 
1154
- if (compression_level < 0)
1155
- compression_level = Z_BEST_SPEED;
1156
-
1157
- if (dir_mode == 0)
1158
- dir_mode = GIT_OBJECT_DIR_MODE;
1159
-
1160
- if (file_mode == 0)
1161
- file_mode = GIT_OBJECT_FILE_MODE;
1162
-
1163
- backend->object_zlib_level = compression_level;
1164
- backend->fsync_object_files = do_fsync;
1165
- backend->object_dir_mode = dir_mode;
1166
- backend->object_file_mode = file_mode;
1189
+ normalize_options(&backend->options, opts);
1190
+ backend->oid_hexsize = git_oid_hexsize(backend->options.oid_type);
1167
1191
 
1168
1192
  backend->parent.read = &loose_backend__read;
1169
1193
  backend->parent.write = &loose_backend__write;
@@ -1180,3 +1204,37 @@ int git_odb_backend_loose(
1180
1204
  *backend_out = (git_odb_backend *)backend;
1181
1205
  return 0;
1182
1206
  }
1207
+
1208
+
1209
+ #ifdef GIT_EXPERIMENTAL_SHA256
1210
+ int git_odb_backend_loose(
1211
+ git_odb_backend **backend_out,
1212
+ const char *objects_dir,
1213
+ git_odb_backend_loose_options *opts)
1214
+ {
1215
+ return git_odb__backend_loose(backend_out, objects_dir, opts);
1216
+ }
1217
+ #else
1218
+ int git_odb_backend_loose(
1219
+ git_odb_backend **backend_out,
1220
+ const char *objects_dir,
1221
+ int compression_level,
1222
+ int do_fsync,
1223
+ unsigned int dir_mode,
1224
+ unsigned int file_mode)
1225
+ {
1226
+ git_odb_backend_loose_flag_t flags = 0;
1227
+ git_odb_backend_loose_options opts = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT;
1228
+
1229
+ if (do_fsync)
1230
+ flags |= GIT_ODB_BACKEND_LOOSE_FSYNC;
1231
+
1232
+ opts.flags = flags;
1233
+ opts.compression_level = compression_level;
1234
+ opts.dir_mode = dir_mode;
1235
+ opts.file_mode = file_mode;
1236
+ opts.oid_type = GIT_OID_DEFAULT;
1237
+
1238
+ return git_odb__backend_loose(backend_out, objects_dir, &opts);
1239
+ }
1240
+ #endif