rugged 1.6.5 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/rugged_allocator.c +0 -54
  3. data/lib/rugged/version.rb +1 -1
  4. data/vendor/libgit2/CMakeLists.txt +3 -8
  5. data/vendor/libgit2/cmake/CheckPrototypeDefinitionSafe.cmake +16 -0
  6. data/vendor/libgit2/cmake/SelectGSSAPI.cmake +3 -3
  7. data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +21 -2
  8. data/vendor/libgit2/cmake/SelectHashes.cmake +4 -0
  9. data/vendor/libgit2/cmake/SelectXdiff.cmake +9 -0
  10. data/vendor/libgit2/deps/pcre/LICENCE +5 -5
  11. data/vendor/libgit2/deps/pcre/pcre.h +2 -2
  12. data/vendor/libgit2/deps/pcre/pcre_compile.c +6 -3
  13. data/vendor/libgit2/deps/pcre/pcre_exec.c +2 -2
  14. data/vendor/libgit2/deps/xdiff/CMakeLists.txt +28 -0
  15. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/git-xdiff.h +4 -1
  16. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.c +19 -18
  17. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.h +2 -4
  18. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.c +3 -3
  19. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xhistogram.c +7 -18
  20. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmacros.h +18 -1
  21. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmerge.c +24 -22
  22. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xpatience.c +21 -30
  23. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.c +13 -30
  24. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.c +18 -1
  25. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.h +2 -1
  26. data/vendor/libgit2/include/git2/common.h +26 -1
  27. data/vendor/libgit2/include/git2/diff.h +41 -3
  28. data/vendor/libgit2/include/git2/errors.h +4 -2
  29. data/vendor/libgit2/include/git2/index.h +9 -0
  30. data/vendor/libgit2/include/git2/oid.h +1 -1
  31. data/vendor/libgit2/include/git2/remote.h +18 -0
  32. data/vendor/libgit2/include/git2/repository.h +12 -2
  33. data/vendor/libgit2/include/git2/sys/alloc.h +0 -34
  34. data/vendor/libgit2/include/git2/sys/commit_graph.h +12 -2
  35. data/vendor/libgit2/include/git2/sys/midx.h +5 -1
  36. data/vendor/libgit2/include/git2/sys/stream.h +16 -2
  37. data/vendor/libgit2/include/git2/sys/transport.h +20 -2
  38. data/vendor/libgit2/include/git2/version.h +4 -4
  39. data/vendor/libgit2/include/git2/worktree.h +3 -1
  40. data/vendor/libgit2/src/CMakeLists.txt +34 -11
  41. data/vendor/libgit2/src/cli/cmd_clone.c +22 -6
  42. data/vendor/libgit2/src/cli/progress.c +9 -8
  43. data/vendor/libgit2/src/cli/progress.h +4 -4
  44. data/vendor/libgit2/src/libgit2/CMakeLists.txt +1 -19
  45. data/vendor/libgit2/src/libgit2/annotated_commit.c +2 -2
  46. data/vendor/libgit2/src/libgit2/annotated_commit.h +1 -1
  47. data/vendor/libgit2/src/libgit2/apply.c +4 -3
  48. data/vendor/libgit2/src/libgit2/blame.c +23 -16
  49. data/vendor/libgit2/src/libgit2/blame_git.c +0 -1
  50. data/vendor/libgit2/src/libgit2/branch.c +2 -2
  51. data/vendor/libgit2/src/libgit2/cherrypick.c +3 -3
  52. data/vendor/libgit2/src/libgit2/clone.c +3 -1
  53. data/vendor/libgit2/src/libgit2/commit.c +31 -9
  54. data/vendor/libgit2/src/libgit2/commit_graph.c +110 -43
  55. data/vendor/libgit2/src/libgit2/commit_graph.h +20 -4
  56. data/vendor/libgit2/src/libgit2/commit_list.c +12 -5
  57. data/vendor/libgit2/src/libgit2/commit_list.h +1 -0
  58. data/vendor/libgit2/src/libgit2/config_file.c +14 -8
  59. data/vendor/libgit2/src/libgit2/describe.c +10 -7
  60. data/vendor/libgit2/src/libgit2/diff.c +16 -7
  61. data/vendor/libgit2/src/libgit2/diff.h +6 -6
  62. data/vendor/libgit2/src/libgit2/diff_file.c +7 -7
  63. data/vendor/libgit2/src/libgit2/diff_generate.c +36 -15
  64. data/vendor/libgit2/src/libgit2/diff_parse.c +20 -4
  65. data/vendor/libgit2/src/libgit2/diff_print.c +26 -7
  66. data/vendor/libgit2/src/libgit2/diff_tform.c +4 -4
  67. data/vendor/libgit2/src/libgit2/diff_xdiff.h +1 -1
  68. data/vendor/libgit2/src/libgit2/email.c +4 -3
  69. data/vendor/libgit2/src/libgit2/errors.c +73 -18
  70. data/vendor/libgit2/src/libgit2/fetch.c +37 -9
  71. data/vendor/libgit2/src/libgit2/fetch.h +0 -2
  72. data/vendor/libgit2/src/libgit2/fetchhead.c +11 -9
  73. data/vendor/libgit2/src/libgit2/grafts.c +272 -0
  74. data/vendor/libgit2/src/libgit2/grafts.h +36 -0
  75. data/vendor/libgit2/src/libgit2/ident.c +3 -3
  76. data/vendor/libgit2/src/libgit2/index.c +325 -125
  77. data/vendor/libgit2/src/libgit2/index.h +14 -1
  78. data/vendor/libgit2/src/libgit2/indexer.c +10 -3
  79. data/vendor/libgit2/src/libgit2/iterator.c +20 -5
  80. data/vendor/libgit2/src/libgit2/iterator.h +3 -0
  81. data/vendor/libgit2/src/libgit2/libgit2.c +39 -0
  82. data/vendor/libgit2/src/libgit2/merge.c +14 -9
  83. data/vendor/libgit2/src/libgit2/merge_file.c +0 -2
  84. data/vendor/libgit2/src/libgit2/midx.c +66 -37
  85. data/vendor/libgit2/src/libgit2/midx.h +13 -3
  86. data/vendor/libgit2/src/libgit2/notes.c +9 -8
  87. data/vendor/libgit2/src/libgit2/object.c +40 -15
  88. data/vendor/libgit2/src/libgit2/object.h +6 -0
  89. data/vendor/libgit2/src/libgit2/odb.c +11 -5
  90. data/vendor/libgit2/src/libgit2/odb_pack.c +16 -3
  91. data/vendor/libgit2/src/libgit2/oid.c +7 -1
  92. data/vendor/libgit2/src/libgit2/oidarray.c +49 -3
  93. data/vendor/libgit2/src/libgit2/oidarray.h +5 -1
  94. data/vendor/libgit2/src/libgit2/pack-objects.c +19 -12
  95. data/vendor/libgit2/src/libgit2/pack-objects.h +5 -2
  96. data/vendor/libgit2/src/libgit2/pack.c +3 -3
  97. data/vendor/libgit2/src/libgit2/parse.c +7 -4
  98. data/vendor/libgit2/src/libgit2/parse.h +1 -1
  99. data/vendor/libgit2/src/libgit2/patch.h +7 -1
  100. data/vendor/libgit2/src/libgit2/patch_generate.c +24 -5
  101. data/vendor/libgit2/src/libgit2/patch_parse.c +16 -8
  102. data/vendor/libgit2/src/libgit2/push.c +2 -2
  103. data/vendor/libgit2/src/libgit2/reader.c +1 -1
  104. data/vendor/libgit2/src/libgit2/rebase.c +72 -84
  105. data/vendor/libgit2/src/libgit2/refdb_fs.c +22 -13
  106. data/vendor/libgit2/src/libgit2/refs.c +8 -1
  107. data/vendor/libgit2/src/libgit2/remote.c +15 -6
  108. data/vendor/libgit2/src/libgit2/remote.h +1 -0
  109. data/vendor/libgit2/src/libgit2/repository.c +580 -301
  110. data/vendor/libgit2/src/libgit2/repository.h +17 -2
  111. data/vendor/libgit2/src/libgit2/reset.c +2 -2
  112. data/vendor/libgit2/src/libgit2/revert.c +8 -11
  113. data/vendor/libgit2/src/libgit2/revparse.c +1 -4
  114. data/vendor/libgit2/src/libgit2/revwalk.c +26 -4
  115. data/vendor/libgit2/src/libgit2/stash.c +9 -8
  116. data/vendor/libgit2/src/libgit2/streams/mbedtls.c +0 -1
  117. data/vendor/libgit2/src/libgit2/streams/openssl.c +8 -16
  118. data/vendor/libgit2/src/libgit2/streams/schannel.c +715 -0
  119. data/vendor/libgit2/src/libgit2/streams/schannel.h +28 -0
  120. data/vendor/libgit2/src/libgit2/streams/socket.c +237 -51
  121. data/vendor/libgit2/src/libgit2/streams/socket.h +3 -1
  122. data/vendor/libgit2/src/libgit2/streams/stransport.c +40 -12
  123. data/vendor/libgit2/src/libgit2/streams/tls.c +5 -0
  124. data/vendor/libgit2/src/libgit2/submodule.h +3 -3
  125. data/vendor/libgit2/src/libgit2/threadstate.c +15 -2
  126. data/vendor/libgit2/src/libgit2/threadstate.h +1 -3
  127. data/vendor/libgit2/src/libgit2/transports/auth.h +1 -2
  128. data/vendor/libgit2/src/libgit2/transports/{auth_negotiate.c → auth_gssapi.c} +32 -32
  129. data/vendor/libgit2/src/libgit2/transports/auth_negotiate.h +1 -1
  130. data/vendor/libgit2/src/libgit2/transports/auth_ntlm.h +1 -1
  131. data/vendor/libgit2/src/libgit2/transports/{auth_ntlm.c → auth_ntlmclient.c} +12 -12
  132. data/vendor/libgit2/src/libgit2/transports/auth_sspi.c +341 -0
  133. data/vendor/libgit2/src/libgit2/transports/git.c +7 -8
  134. data/vendor/libgit2/src/libgit2/transports/http.c +7 -2
  135. data/vendor/libgit2/src/libgit2/transports/httpclient.c +5 -0
  136. data/vendor/libgit2/src/libgit2/transports/local.c +13 -4
  137. data/vendor/libgit2/src/libgit2/transports/smart.c +33 -27
  138. data/vendor/libgit2/src/libgit2/transports/smart.h +23 -8
  139. data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +136 -17
  140. data/vendor/libgit2/src/libgit2/transports/smart_protocol.c +154 -47
  141. data/vendor/libgit2/src/libgit2/transports/ssh.c +3 -3
  142. data/vendor/libgit2/src/libgit2/transports/winhttp.c +14 -15
  143. data/vendor/libgit2/src/libgit2/tree-cache.c +26 -16
  144. data/vendor/libgit2/src/libgit2/tree-cache.h +5 -3
  145. data/vendor/libgit2/src/libgit2/tree.c +1 -1
  146. data/vendor/libgit2/src/libgit2/worktree.c +25 -10
  147. data/vendor/libgit2/src/util/alloc.c +65 -6
  148. data/vendor/libgit2/src/util/alloc.h +34 -9
  149. data/vendor/libgit2/src/util/allocators/failalloc.c +0 -60
  150. data/vendor/libgit2/src/util/allocators/failalloc.h +0 -6
  151. data/vendor/libgit2/src/util/allocators/stdalloc.c +2 -105
  152. data/vendor/libgit2/src/util/allocators/win32_leakcheck.c +0 -68
  153. data/vendor/libgit2/src/util/array.h +6 -1
  154. data/vendor/libgit2/src/util/cc-compat.h +2 -0
  155. data/vendor/libgit2/src/util/filebuf.c +6 -1
  156. data/vendor/libgit2/src/util/filebuf.h +19 -6
  157. data/vendor/libgit2/src/util/fs_path.c +1 -1
  158. data/vendor/libgit2/src/util/futils.c +8 -5
  159. data/vendor/libgit2/src/util/git2_features.h.in +9 -3
  160. data/vendor/libgit2/src/util/net.c +308 -157
  161. data/vendor/libgit2/src/util/net.h +25 -0
  162. data/vendor/libgit2/src/util/posix.c +54 -0
  163. data/vendor/libgit2/src/util/posix.h +22 -0
  164. data/vendor/libgit2/src/util/rand.c +6 -4
  165. data/vendor/libgit2/src/util/staticstr.h +66 -0
  166. data/vendor/libgit2/src/util/util.c +15 -10
  167. data/vendor/libgit2/src/util/util.h +24 -16
  168. data/vendor/libgit2/src/util/win32/error.c +1 -1
  169. data/vendor/libgit2/src/util/win32/path_w32.c +8 -8
  170. data/vendor/libgit2/src/util/win32/posix_w32.c +1 -1
  171. data/vendor/libgit2/src/util/win32/utf-conv.c +73 -75
  172. data/vendor/libgit2/src/util/win32/utf-conv.h +81 -14
  173. data/vendor/libgit2/src/util/win32/w32_util.c +1 -1
  174. metadata +29 -23
  175. data/vendor/libgit2/cmake/SelectWinHTTP.cmake +0 -17
  176. data/vendor/libgit2/src/libgit2/netops.c +0 -124
  177. data/vendor/libgit2/src/libgit2/netops.h +0 -68
  178. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiff.h +0 -0
  179. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.h +0 -0
  180. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xinclude.h +0 -0
  181. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.h +0 -0
  182. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xtypes.h +0 -0
@@ -15,6 +15,7 @@
15
15
  #include "buf.h"
16
16
  #include "common.h"
17
17
  #include "commit.h"
18
+ #include "grafts.h"
18
19
  #include "tag.h"
19
20
  #include "blob.h"
20
21
  #include "futils.h"
@@ -66,7 +67,7 @@ static const struct {
66
67
 
67
68
  static int check_repositoryformatversion(int *version, git_config *config);
68
69
  static int check_extensions(git_config *config, int version);
69
- static int load_global_config(git_config **config);
70
+ static int load_global_config(git_config **config, bool use_env);
70
71
  static int load_objectformat(git_repository *repo, git_config *config);
71
72
 
72
73
  #define GIT_COMMONDIR_FILE "commondir"
@@ -151,6 +152,10 @@ int git_repository__cleanup(git_repository *repo)
151
152
  git_repository_submodule_cache_clear(repo);
152
153
  git_cache_clear(&repo->objects);
153
154
  git_attr_cache_flush(repo);
155
+ git_grafts_free(repo->grafts);
156
+ repo->grafts = NULL;
157
+ git_grafts_free(repo->shallow_grafts);
158
+ repo->shallow_grafts = NULL;
154
159
 
155
160
  set_config(repo, NULL);
156
161
  set_index(repo, NULL);
@@ -191,11 +196,23 @@ void git_repository_free(git_repository *repo)
191
196
  }
192
197
 
193
198
  /* Check if we have a separate commondir (e.g. we have a worktree) */
194
- static int lookup_commondir(bool *separate, git_str *commondir, git_str *repository_path)
199
+ static int lookup_commondir(
200
+ bool *separate,
201
+ git_str *commondir,
202
+ git_str *repository_path,
203
+ uint32_t flags)
195
204
  {
196
- git_str common_link = GIT_STR_INIT;
205
+ git_str common_link = GIT_STR_INIT;
197
206
  int error;
198
207
 
208
+ /* Environment variable overrides configuration */
209
+ if ((flags & GIT_REPOSITORY_OPEN_FROM_ENV)) {
210
+ error = git__getenv(commondir, "GIT_COMMON_DIR");
211
+
212
+ if (!error || error != GIT_ENOTFOUND)
213
+ goto done;
214
+ }
215
+
199
216
  /*
200
217
  * If there's no commondir file, the repository path is the
201
218
  * common path, but it needs a trailing slash.
@@ -222,12 +239,11 @@ static int lookup_commondir(bool *separate, git_str *commondir, git_str *reposit
222
239
  git_str_swap(commondir, &common_link);
223
240
  }
224
241
 
225
- git_str_dispose(&common_link);
226
-
227
242
  /* Make sure the commondir path always has a trailing slash */
228
243
  error = git_fs_path_prettify_dir(commondir, commondir->ptr, NULL);
229
244
 
230
245
  done:
246
+ git_str_dispose(&common_link);
231
247
  return error;
232
248
  }
233
249
 
@@ -252,14 +268,19 @@ GIT_INLINE(int) validate_repo_path(git_str *path)
252
268
  *
253
269
  * Open a repository object from its path
254
270
  */
255
- static int is_valid_repository_path(bool *out, git_str *repository_path, git_str *common_path)
271
+ static int is_valid_repository_path(
272
+ bool *out,
273
+ git_str *repository_path,
274
+ git_str *common_path,
275
+ uint32_t flags)
256
276
  {
257
277
  bool separate_commondir = false;
258
278
  int error;
259
279
 
260
280
  *out = false;
261
281
 
262
- if ((error = lookup_commondir(&separate_commondir, common_path, repository_path)) < 0)
282
+ if ((error = lookup_commondir(&separate_commondir,
283
+ common_path, repository_path, flags)) < 0)
263
284
  return error;
264
285
 
265
286
  /* Ensure HEAD file exists */
@@ -337,19 +358,42 @@ static int load_config_data(git_repository *repo, const git_config *config)
337
358
  return 0;
338
359
  }
339
360
 
340
- static int load_workdir(git_repository *repo, git_config *config, git_str *parent_path)
361
+ static int load_workdir(
362
+ git_repository *repo,
363
+ git_config *config,
364
+ git_str *parent_path)
341
365
  {
342
- int error;
343
- git_config_entry *ce;
366
+ git_config_entry *ce = NULL;
344
367
  git_str worktree = GIT_STR_INIT;
345
368
  git_str path = GIT_STR_INIT;
369
+ git_str workdir_env = GIT_STR_INIT;
370
+ const char *value = NULL;
371
+ int error;
346
372
 
347
373
  if (repo->is_bare)
348
374
  return 0;
349
375
 
350
- if ((error = git_config__lookup_entry(
351
- &ce, config, "core.worktree", false)) < 0)
352
- return error;
376
+ /* Environment variables are preferred */
377
+ if (repo->use_env) {
378
+ error = git__getenv(&workdir_env, "GIT_WORK_TREE");
379
+
380
+ if (error == 0)
381
+ value = workdir_env.ptr;
382
+ else if (error == GIT_ENOTFOUND)
383
+ error = 0;
384
+ else
385
+ goto cleanup;
386
+ }
387
+
388
+ /* Examine configuration values if necessary */
389
+ if (!value) {
390
+ if ((error = git_config__lookup_entry(&ce, config,
391
+ "core.worktree", false)) < 0)
392
+ return error;
393
+
394
+ if (ce && ce->value)
395
+ value = ce->value;
396
+ }
353
397
 
354
398
  if (repo->is_worktree) {
355
399
  char *gitlink = git_worktree__read_link(repo->gitdir, GIT_GITDIR_FILE);
@@ -367,17 +411,21 @@ static int load_workdir(git_repository *repo, git_config *config, git_str *paren
367
411
  }
368
412
 
369
413
  repo->workdir = git_str_detach(&worktree);
370
- }
371
- else if (ce && ce->value) {
372
- if ((error = git_fs_path_prettify_dir(
373
- &worktree, ce->value, repo->gitdir)) < 0)
414
+ } else if (value) {
415
+ if (!*value) {
416
+ git_error_set(GIT_ERROR_NET, "working directory cannot be set to empty path");
417
+ error = -1;
418
+ goto cleanup;
419
+ }
420
+
421
+ if ((error = git_fs_path_prettify_dir(&worktree,
422
+ value, repo->gitdir)) < 0)
374
423
  goto cleanup;
375
424
 
376
425
  repo->workdir = git_str_detach(&worktree);
377
- }
378
- else if (parent_path && git_fs_path_isdir(parent_path->ptr))
426
+ } else if (parent_path && git_fs_path_isdir(parent_path->ptr)) {
379
427
  repo->workdir = git_str_detach(parent_path);
380
- else {
428
+ } else {
381
429
  if (git_fs_path_dirname_r(&worktree, repo->gitdir) < 0 ||
382
430
  git_fs_path_to_dir(&worktree) < 0) {
383
431
  error = -1;
@@ -388,8 +436,10 @@ static int load_workdir(git_repository *repo, git_config *config, git_str *paren
388
436
  }
389
437
 
390
438
  GIT_ERROR_CHECK_ALLOC(repo->workdir);
439
+
391
440
  cleanup:
392
441
  git_str_dispose(&path);
442
+ git_str_dispose(&workdir_env);
393
443
  git_config_entry_free(ce);
394
444
  return error;
395
445
  }
@@ -541,7 +591,10 @@ static int validate_ownership_cb(const git_config_entry *entry, void *payload)
541
591
  return 0;
542
592
  }
543
593
 
544
- static int validate_ownership_config(bool *is_safe, const char *path)
594
+ static int validate_ownership_config(
595
+ bool *is_safe,
596
+ const char *path,
597
+ bool use_env)
545
598
  {
546
599
  validate_ownership_data ownership_data = {
547
600
  path, GIT_STR_INIT, is_safe
@@ -549,7 +602,7 @@ static int validate_ownership_config(bool *is_safe, const char *path)
549
602
  git_config *config;
550
603
  int error;
551
604
 
552
- if (load_global_config(&config) != 0)
605
+ if (load_global_config(&config, use_env) != 0)
553
606
  return 0;
554
607
 
555
608
  error = git_config_get_multivar_foreach(config,
@@ -623,7 +676,8 @@ static int validate_ownership(git_repository *repo)
623
676
  }
624
677
 
625
678
  if (is_safe ||
626
- (error = validate_ownership_config(&is_safe, validation_paths[0])) < 0)
679
+ (error = validate_ownership_config(
680
+ &is_safe, validation_paths[0], repo->use_env)) < 0)
627
681
  goto done;
628
682
 
629
683
  if (!is_safe) {
@@ -637,14 +691,28 @@ done:
637
691
  return error;
638
692
  }
639
693
 
640
- static int find_repo(
641
- git_str *gitdir_path,
642
- git_str *workdir_path,
643
- git_str *gitlink_path,
644
- git_str *commondir_path,
694
+ struct repo_paths {
695
+ git_str gitdir;
696
+ git_str workdir;
697
+ git_str gitlink;
698
+ git_str commondir;
699
+ };
700
+
701
+ #define REPO_PATHS_INIT { GIT_STR_INIT }
702
+
703
+ GIT_INLINE(void) repo_paths_dispose(struct repo_paths *paths)
704
+ {
705
+ git_str_dispose(&paths->gitdir);
706
+ git_str_dispose(&paths->workdir);
707
+ git_str_dispose(&paths->gitlink);
708
+ git_str_dispose(&paths->commondir);
709
+ }
710
+
711
+ static int find_repo_traverse(
712
+ struct repo_paths *out,
645
713
  const char *start_path,
646
- uint32_t flags,
647
- const char *ceiling_dirs)
714
+ const char *ceiling_dirs,
715
+ uint32_t flags)
648
716
  {
649
717
  git_str path = GIT_STR_INIT;
650
718
  git_str repo_link = GIT_STR_INIT;
@@ -656,19 +724,23 @@ static int find_repo(
656
724
  size_t ceiling_offset = 0;
657
725
  int error;
658
726
 
659
- git_str_clear(gitdir_path);
727
+ git_str_clear(&out->gitdir);
660
728
 
661
- error = git_fs_path_prettify(&path, start_path, NULL);
662
- if (error < 0)
729
+ if ((error = git_fs_path_prettify(&path, start_path, NULL)) < 0)
663
730
  return error;
664
731
 
665
- /* in_dot_git toggles each loop:
732
+ /*
733
+ * In each loop we look first for a `.git` dir within the
734
+ * directory, then to see if the directory itself is a repo.
735
+ *
736
+ * In other words: if we start in /a/b/c, then we look at:
666
737
  * /a/b/c/.git, /a/b/c, /a/b/.git, /a/b, /a/.git, /a
667
- * With GIT_REPOSITORY_OPEN_BARE or GIT_REPOSITORY_OPEN_NO_DOTGIT, we
668
- * assume we started with /a/b/c.git and don't append .git the first
669
- * time through.
670
- * min_iterations indicates the number of iterations left before going
671
- * further counts as a search. */
738
+ *
739
+ * With GIT_REPOSITORY_OPEN_BARE or GIT_REPOSITORY_OPEN_NO_DOTGIT,
740
+ * we assume we started with /a/b/c.git and don't append .git the
741
+ * first time through. min_iterations indicates the number of
742
+ * iterations left before going further counts as a search.
743
+ */
672
744
  if (flags & (GIT_REPOSITORY_OPEN_BARE | GIT_REPOSITORY_OPEN_NO_DOTGIT)) {
673
745
  in_dot_git = true;
674
746
  min_iterations = 1;
@@ -695,48 +767,51 @@ static int find_repo(
695
767
  break;
696
768
 
697
769
  if (S_ISDIR(st.st_mode)) {
698
- if ((error = is_valid_repository_path(&is_valid, &path, &common_link)) < 0)
770
+ if ((error = is_valid_repository_path(&is_valid, &path, &common_link, flags)) < 0)
699
771
  goto out;
700
772
 
701
773
  if (is_valid) {
702
774
  if ((error = git_fs_path_to_dir(&path)) < 0 ||
703
- (error = git_str_set(gitdir_path, path.ptr, path.size)) < 0)
775
+ (error = git_str_set(&out->gitdir, path.ptr, path.size)) < 0)
704
776
  goto out;
705
777
 
706
- if (gitlink_path)
707
- if ((error = git_str_attach(gitlink_path, git_worktree__read_link(path.ptr, GIT_GITDIR_FILE), 0)) < 0)
708
- goto out;
709
- if (commondir_path)
710
- git_str_swap(&common_link, commondir_path);
778
+ if ((error = git_str_attach(&out->gitlink, git_worktree__read_link(path.ptr, GIT_GITDIR_FILE), 0)) < 0)
779
+ goto out;
780
+
781
+ git_str_swap(&common_link, &out->commondir);
711
782
 
712
783
  break;
713
784
  }
714
785
  } else if (S_ISREG(st.st_mode) && git__suffixcmp(path.ptr, "/" DOT_GIT) == 0) {
715
786
  if ((error = read_gitfile(&repo_link, path.ptr)) < 0 ||
716
- (error = is_valid_repository_path(&is_valid, &repo_link, &common_link)) < 0)
787
+ (error = is_valid_repository_path(&is_valid, &repo_link, &common_link, flags)) < 0)
717
788
  goto out;
718
789
 
719
790
  if (is_valid) {
720
- git_str_swap(gitdir_path, &repo_link);
791
+ git_str_swap(&out->gitdir, &repo_link);
792
+
793
+ if ((error = git_str_put(&out->gitlink, path.ptr, path.size)) < 0)
794
+ goto out;
721
795
 
722
- if (gitlink_path)
723
- if ((error = git_str_put(gitlink_path, path.ptr, path.size)) < 0)
724
- goto out;
725
- if (commondir_path)
726
- git_str_swap(&common_link, commondir_path);
796
+ git_str_swap(&common_link, &out->commondir);
727
797
  }
728
798
  break;
729
799
  }
730
800
  }
731
801
 
732
- /* Move up one directory. If we're in_dot_git, we'll search the
733
- * parent itself next. If we're !in_dot_git, we'll search .git
734
- * in the parent directory next (added at the top of the loop). */
802
+ /*
803
+ * Move up one directory. If we're in_dot_git, we'll
804
+ * search the parent itself next. If we're !in_dot_git,
805
+ * we'll search .git in the parent directory next (added
806
+ * at the top of the loop).
807
+ */
735
808
  if ((error = git_fs_path_dirname_r(&path, path.ptr)) < 0)
736
809
  goto out;
737
810
 
738
- /* Once we've checked the directory (and .git if applicable),
739
- * find the ceiling for a search. */
811
+ /*
812
+ * Once we've checked the directory (and .git if
813
+ * applicable), find the ceiling for a search.
814
+ */
740
815
  if (min_iterations && (--min_iterations == 0))
741
816
  ceiling_offset = find_ceiling_dir_offset(path.ptr, ceiling_dirs);
742
817
 
@@ -746,29 +821,117 @@ static int find_repo(
746
821
  break;
747
822
  }
748
823
 
749
- if (workdir_path && !(flags & GIT_REPOSITORY_OPEN_BARE)) {
750
- if (!git_str_len(gitdir_path))
751
- git_str_clear(workdir_path);
752
- else if ((error = git_fs_path_dirname_r(workdir_path, path.ptr)) < 0 ||
753
- (error = git_fs_path_to_dir(workdir_path)) < 0)
824
+ if (!(flags & GIT_REPOSITORY_OPEN_BARE)) {
825
+ if (!git_str_len(&out->gitdir))
826
+ git_str_clear(&out->workdir);
827
+ else if ((error = git_fs_path_dirname_r(&out->workdir, path.ptr)) < 0 ||
828
+ (error = git_fs_path_to_dir(&out->workdir)) < 0)
754
829
  goto out;
755
830
  }
756
831
 
757
- /* If we didn't find the repository, and we don't have any other error
758
- * to report, report that. */
759
- if (!git_str_len(gitdir_path)) {
760
- git_error_set(GIT_ERROR_REPOSITORY, "could not find repository from '%s'", start_path);
832
+ /* If we didn't find the repository, and we don't have any other
833
+ * error to report, report that. */
834
+ if (!git_str_len(&out->gitdir)) {
835
+ git_error_set(GIT_ERROR_REPOSITORY, "could not find repository at '%s'", start_path);
761
836
  error = GIT_ENOTFOUND;
762
837
  goto out;
763
838
  }
764
839
 
765
840
  out:
841
+ if (error)
842
+ repo_paths_dispose(out);
843
+
766
844
  git_str_dispose(&path);
767
845
  git_str_dispose(&repo_link);
768
846
  git_str_dispose(&common_link);
769
847
  return error;
770
848
  }
771
849
 
850
+ static int load_grafts(git_repository *repo)
851
+ {
852
+ git_str path = GIT_STR_INIT;
853
+ int error;
854
+
855
+ if ((error = git_repository__item_path(&path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 ||
856
+ (error = git_str_joinpath(&path, path.ptr, "grafts")) < 0 ||
857
+ (error = git_grafts_open_or_refresh(&repo->grafts, path.ptr, repo->oid_type)) < 0)
858
+ goto error;
859
+
860
+ git_str_clear(&path);
861
+
862
+ if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0 ||
863
+ (error = git_grafts_open_or_refresh(&repo->shallow_grafts, path.ptr, repo->oid_type)) < 0)
864
+ goto error;
865
+
866
+ error:
867
+ git_str_dispose(&path);
868
+ return error;
869
+ }
870
+
871
+ static int find_repo(
872
+ struct repo_paths *out,
873
+ const char *start_path,
874
+ const char *ceiling_dirs,
875
+ uint32_t flags)
876
+ {
877
+ bool use_env = !!(flags & GIT_REPOSITORY_OPEN_FROM_ENV);
878
+ git_str gitdir_buf = GIT_STR_INIT,
879
+ ceiling_dirs_buf = GIT_STR_INIT,
880
+ across_fs_buf = GIT_STR_INIT;
881
+ int error;
882
+
883
+ if (use_env && !start_path) {
884
+ error = git__getenv(&gitdir_buf, "GIT_DIR");
885
+
886
+ if (!error) {
887
+ start_path = gitdir_buf.ptr;
888
+ flags |= GIT_REPOSITORY_OPEN_NO_SEARCH;
889
+ flags |= GIT_REPOSITORY_OPEN_NO_DOTGIT;
890
+ } else if (error == GIT_ENOTFOUND) {
891
+ start_path = ".";
892
+ } else {
893
+ goto done;
894
+ }
895
+ }
896
+
897
+ if (use_env && !ceiling_dirs) {
898
+ error = git__getenv(&ceiling_dirs_buf,
899
+ "GIT_CEILING_DIRECTORIES");
900
+
901
+ if (!error)
902
+ ceiling_dirs = ceiling_dirs_buf.ptr;
903
+ else if (error != GIT_ENOTFOUND)
904
+ goto done;
905
+ }
906
+
907
+ if (use_env) {
908
+ error = git__getenv(&across_fs_buf,
909
+ "GIT_DISCOVERY_ACROSS_FILESYSTEM");
910
+
911
+ if (!error) {
912
+ int across_fs = 0;
913
+
914
+ if ((error = git_config_parse_bool(&across_fs,
915
+ git_str_cstr(&across_fs_buf))) < 0)
916
+ goto done;
917
+
918
+ if (across_fs)
919
+ flags |= GIT_REPOSITORY_OPEN_CROSS_FS;
920
+ } else if (error != GIT_ENOTFOUND) {
921
+ goto done;
922
+ }
923
+ }
924
+
925
+ error = find_repo_traverse(out, start_path, ceiling_dirs, flags);
926
+
927
+ done:
928
+ git_str_dispose(&gitdir_buf);
929
+ git_str_dispose(&ceiling_dirs_buf);
930
+ git_str_dispose(&across_fs_buf);
931
+
932
+ return error;
933
+ }
934
+
772
935
  static int obtain_config_and_set_oid_type(
773
936
  git_config **config_ptr,
774
937
  git_repository *repo)
@@ -787,7 +950,7 @@ static int obtain_config_and_set_oid_type(
787
950
  goto out;
788
951
 
789
952
  if (config &&
790
- (error = check_repositoryformatversion(&version, config)) < 0)
953
+ (error = check_repositoryformatversion(&version, config)) < 0)
791
954
  goto out;
792
955
 
793
956
  if ((error = check_extensions(config, version)) < 0)
@@ -797,7 +960,7 @@ static int obtain_config_and_set_oid_type(
797
960
  if ((error = load_objectformat(repo, config)) < 0)
798
961
  goto out;
799
962
  } else {
800
- repo->oid_type = GIT_OID_SHA1;
963
+ repo->oid_type = GIT_OID_DEFAULT;
801
964
  }
802
965
 
803
966
  out:
@@ -817,7 +980,7 @@ int git_repository_open_bare(
817
980
  git_config *config;
818
981
 
819
982
  if ((error = git_fs_path_prettify_dir(&path, bare_path, NULL)) < 0 ||
820
- (error = is_valid_repository_path(&is_valid, &path, &common_path)) < 0)
983
+ (error = is_valid_repository_path(&is_valid, &path, &common_path, 0)) < 0)
821
984
  return error;
822
985
 
823
986
  if (!is_valid) {
@@ -851,173 +1014,22 @@ cleanup:
851
1014
  return error;
852
1015
  }
853
1016
 
854
- static int _git_repository_open_ext_from_env(
855
- git_repository **out,
856
- const char *start_path)
1017
+ static int repo_load_namespace(git_repository *repo)
857
1018
  {
858
- git_repository *repo = NULL;
859
- git_index *index = NULL;
860
- git_odb *odb = NULL;
861
- git_str dir_buf = GIT_STR_INIT;
862
- git_str ceiling_dirs_buf = GIT_STR_INIT;
863
- git_str across_fs_buf = GIT_STR_INIT;
864
- git_str index_file_buf = GIT_STR_INIT;
865
1019
  git_str namespace_buf = GIT_STR_INIT;
866
- git_str object_dir_buf = GIT_STR_INIT;
867
- git_str alts_buf = GIT_STR_INIT;
868
- git_str work_tree_buf = GIT_STR_INIT;
869
- git_str common_dir_buf = GIT_STR_INIT;
870
- const char *ceiling_dirs = NULL;
871
- unsigned flags = 0;
872
1020
  int error;
873
1021
 
874
- if (!start_path) {
875
- error = git__getenv(&dir_buf, "GIT_DIR");
876
- if (error == GIT_ENOTFOUND) {
877
- git_error_clear();
878
- start_path = ".";
879
- } else if (error < 0)
880
- goto error;
881
- else {
882
- start_path = git_str_cstr(&dir_buf);
883
- flags |= GIT_REPOSITORY_OPEN_NO_SEARCH;
884
- flags |= GIT_REPOSITORY_OPEN_NO_DOTGIT;
885
- }
886
- }
887
-
888
- error = git__getenv(&ceiling_dirs_buf, "GIT_CEILING_DIRECTORIES");
889
- if (error == GIT_ENOTFOUND)
890
- git_error_clear();
891
- else if (error < 0)
892
- goto error;
893
- else
894
- ceiling_dirs = git_str_cstr(&ceiling_dirs_buf);
895
-
896
- error = git__getenv(&across_fs_buf, "GIT_DISCOVERY_ACROSS_FILESYSTEM");
897
- if (error == GIT_ENOTFOUND)
898
- git_error_clear();
899
- else if (error < 0)
900
- goto error;
901
- else {
902
- int across_fs = 0;
903
- error = git_config_parse_bool(&across_fs, git_str_cstr(&across_fs_buf));
904
- if (error < 0)
905
- goto error;
906
- if (across_fs)
907
- flags |= GIT_REPOSITORY_OPEN_CROSS_FS;
908
- }
909
-
910
- error = git__getenv(&index_file_buf, "GIT_INDEX_FILE");
911
- if (error == GIT_ENOTFOUND)
912
- git_error_clear();
913
- else if (error < 0)
914
- goto error;
915
- else {
916
- error = git_index_open(&index, git_str_cstr(&index_file_buf));
917
- if (error < 0)
918
- goto error;
919
- }
1022
+ if (!repo->use_env)
1023
+ return 0;
920
1024
 
921
1025
  error = git__getenv(&namespace_buf, "GIT_NAMESPACE");
922
- if (error == GIT_ENOTFOUND)
923
- git_error_clear();
924
- else if (error < 0)
925
- goto error;
926
-
927
- error = git__getenv(&object_dir_buf, "GIT_OBJECT_DIRECTORY");
928
- if (error == GIT_ENOTFOUND)
929
- git_error_clear();
930
- else if (error < 0)
931
- goto error;
932
- else {
933
- error = git_odb__open(&odb, git_str_cstr(&object_dir_buf), NULL);
934
- if (error < 0)
935
- goto error;
936
- }
937
1026
 
938
- error = git__getenv(&work_tree_buf, "GIT_WORK_TREE");
939
- if (error == GIT_ENOTFOUND)
940
- git_error_clear();
941
- else if (error < 0)
942
- goto error;
943
- else {
944
- git_error_set(GIT_ERROR_INVALID, "GIT_WORK_TREE unimplemented");
945
- error = GIT_ERROR;
946
- goto error;
947
- }
948
-
949
- error = git__getenv(&work_tree_buf, "GIT_COMMON_DIR");
950
- if (error == GIT_ENOTFOUND)
951
- git_error_clear();
952
- else if (error < 0)
953
- goto error;
954
- else {
955
- git_error_set(GIT_ERROR_INVALID, "GIT_COMMON_DIR unimplemented");
956
- error = GIT_ERROR;
957
- goto error;
958
- }
959
-
960
- error = git_repository_open_ext(&repo, start_path, flags, ceiling_dirs);
961
- if (error < 0)
962
- goto error;
963
-
964
- if (odb)
965
- git_repository_set_odb(repo, odb);
966
-
967
- error = git__getenv(&alts_buf, "GIT_ALTERNATE_OBJECT_DIRECTORIES");
968
- if (error == GIT_ENOTFOUND) {
969
- git_error_clear();
970
- error = 0;
971
- } else if (error < 0)
972
- goto error;
973
- else {
974
- const char *end;
975
- char *alt, *sep;
976
- if (!odb) {
977
- error = git_repository_odb(&odb, repo);
978
- if (error < 0)
979
- goto error;
980
- }
981
-
982
- end = git_str_cstr(&alts_buf) + git_str_len(&alts_buf);
983
- for (sep = alt = alts_buf.ptr; sep != end; alt = sep+1) {
984
- for (sep = alt; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++)
985
- ;
986
- if (*sep)
987
- *sep = '\0';
988
- error = git_odb_add_disk_alternate(odb, alt);
989
- if (error < 0)
990
- goto error;
991
- }
992
- }
993
-
994
- if (git_str_len(&namespace_buf)) {
995
- error = git_repository_set_namespace(repo, git_str_cstr(&namespace_buf));
996
- if (error < 0)
997
- goto error;
998
- }
999
-
1000
- git_repository_set_index(repo, index);
1027
+ if (error == 0)
1028
+ repo->namespace = git_str_detach(&namespace_buf);
1029
+ else if (error != GIT_ENOTFOUND)
1030
+ return error;
1001
1031
 
1002
- if (out) {
1003
- *out = repo;
1004
- goto success;
1005
- }
1006
- error:
1007
- git_repository_free(repo);
1008
- success:
1009
- git_odb_free(odb);
1010
- git_index_free(index);
1011
- git_str_dispose(&common_dir_buf);
1012
- git_str_dispose(&work_tree_buf);
1013
- git_str_dispose(&alts_buf);
1014
- git_str_dispose(&object_dir_buf);
1015
- git_str_dispose(&namespace_buf);
1016
- git_str_dispose(&index_file_buf);
1017
- git_str_dispose(&across_fs_buf);
1018
- git_str_dispose(&ceiling_dirs_buf);
1019
- git_str_dispose(&dir_buf);
1020
- return error;
1032
+ return 0;
1021
1033
  }
1022
1034
 
1023
1035
  static int repo_is_worktree(unsigned *out, const git_repository *repo)
@@ -1049,21 +1061,16 @@ int git_repository_open_ext(
1049
1061
  unsigned int flags,
1050
1062
  const char *ceiling_dirs)
1051
1063
  {
1052
- int error;
1053
- unsigned is_worktree;
1054
- git_str gitdir = GIT_STR_INIT, workdir = GIT_STR_INIT,
1055
- gitlink = GIT_STR_INIT, commondir = GIT_STR_INIT;
1064
+ struct repo_paths paths = { GIT_STR_INIT };
1056
1065
  git_repository *repo = NULL;
1057
1066
  git_config *config = NULL;
1058
-
1059
- if (flags & GIT_REPOSITORY_OPEN_FROM_ENV)
1060
- return _git_repository_open_ext_from_env(repo_ptr, start_path);
1067
+ unsigned is_worktree;
1068
+ int error;
1061
1069
 
1062
1070
  if (repo_ptr)
1063
1071
  *repo_ptr = NULL;
1064
1072
 
1065
- error = find_repo(
1066
- &gitdir, &workdir, &gitlink, &commondir, start_path, flags, ceiling_dirs);
1073
+ error = find_repo(&paths, start_path, ceiling_dirs, flags);
1067
1074
 
1068
1075
  if (error < 0 || !repo_ptr)
1069
1076
  goto cleanup;
@@ -1071,35 +1078,44 @@ int git_repository_open_ext(
1071
1078
  repo = repository_alloc();
1072
1079
  GIT_ERROR_CHECK_ALLOC(repo);
1073
1080
 
1074
- repo->gitdir = git_str_detach(&gitdir);
1081
+ repo->use_env = !!(flags & GIT_REPOSITORY_OPEN_FROM_ENV);
1082
+
1083
+ repo->gitdir = git_str_detach(&paths.gitdir);
1075
1084
  GIT_ERROR_CHECK_ALLOC(repo->gitdir);
1076
1085
 
1077
- if (gitlink.size) {
1078
- repo->gitlink = git_str_detach(&gitlink);
1086
+ if (paths.gitlink.size) {
1087
+ repo->gitlink = git_str_detach(&paths.gitlink);
1079
1088
  GIT_ERROR_CHECK_ALLOC(repo->gitlink);
1080
1089
  }
1081
- if (commondir.size) {
1082
- repo->commondir = git_str_detach(&commondir);
1090
+ if (paths.commondir.size) {
1091
+ repo->commondir = git_str_detach(&paths.commondir);
1083
1092
  GIT_ERROR_CHECK_ALLOC(repo->commondir);
1084
1093
  }
1085
1094
 
1086
1095
  if ((error = repo_is_worktree(&is_worktree, repo)) < 0)
1087
1096
  goto cleanup;
1097
+
1088
1098
  repo->is_worktree = is_worktree;
1089
1099
 
1090
1100
  error = obtain_config_and_set_oid_type(&config, repo);
1091
1101
  if (error < 0)
1092
1102
  goto cleanup;
1093
1103
 
1104
+ if ((error = load_grafts(repo)) < 0)
1105
+ goto cleanup;
1106
+
1094
1107
  if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0) {
1095
1108
  repo->is_bare = 1;
1096
1109
  } else {
1097
1110
  if (config &&
1098
1111
  ((error = load_config_data(repo, config)) < 0 ||
1099
- (error = load_workdir(repo, config, &workdir)) < 0))
1112
+ (error = load_workdir(repo, config, &paths.workdir)) < 0))
1100
1113
  goto cleanup;
1101
1114
  }
1102
1115
 
1116
+ if ((error = repo_load_namespace(repo)) < 0)
1117
+ goto cleanup;
1118
+
1103
1119
  /*
1104
1120
  * Ensure that the git directory and worktree are
1105
1121
  * owned by the current user.
@@ -1109,10 +1125,7 @@ int git_repository_open_ext(
1109
1125
  goto cleanup;
1110
1126
 
1111
1127
  cleanup:
1112
- git_str_dispose(&gitdir);
1113
- git_str_dispose(&workdir);
1114
- git_str_dispose(&gitlink);
1115
- git_str_dispose(&commondir);
1128
+ repo_paths_dispose(&paths);
1116
1129
  git_config_free(config);
1117
1130
 
1118
1131
  if (error < 0)
@@ -1161,30 +1174,56 @@ out:
1161
1174
  return err;
1162
1175
  }
1163
1176
 
1164
- int git_repository_wrap_odb(git_repository **repo_out, git_odb *odb)
1177
+ int git_repository__wrap_odb(
1178
+ git_repository **out,
1179
+ git_odb *odb,
1180
+ git_oid_t oid_type)
1165
1181
  {
1166
1182
  git_repository *repo;
1167
1183
 
1168
1184
  repo = repository_alloc();
1169
1185
  GIT_ERROR_CHECK_ALLOC(repo);
1170
1186
 
1187
+ repo->oid_type = oid_type;
1188
+
1171
1189
  git_repository_set_odb(repo, odb);
1172
- *repo_out = repo;
1190
+ *out = repo;
1173
1191
 
1174
1192
  return 0;
1175
1193
  }
1176
1194
 
1195
+ #ifdef GIT_EXPERIMENTAL_SHA256
1196
+ int git_repository_wrap_odb(
1197
+ git_repository **out,
1198
+ git_odb *odb,
1199
+ git_oid_t oid_type)
1200
+ {
1201
+ return git_repository__wrap_odb(out, odb, oid_type);
1202
+ }
1203
+ #else
1204
+ int git_repository_wrap_odb(git_repository **out, git_odb *odb)
1205
+ {
1206
+ return git_repository__wrap_odb(out, odb, GIT_OID_DEFAULT);
1207
+ }
1208
+ #endif
1209
+
1177
1210
  int git_repository_discover(
1178
1211
  git_buf *out,
1179
1212
  const char *start_path,
1180
1213
  int across_fs,
1181
1214
  const char *ceiling_dirs)
1182
1215
  {
1216
+ struct repo_paths paths = { GIT_STR_INIT };
1183
1217
  uint32_t flags = across_fs ? GIT_REPOSITORY_OPEN_CROSS_FS : 0;
1218
+ int error;
1184
1219
 
1185
1220
  GIT_ASSERT_ARG(start_path);
1186
1221
 
1187
- GIT_BUF_WRAP_PRIVATE(out, find_repo, NULL, NULL, NULL, start_path, flags, ceiling_dirs);
1222
+ if ((error = find_repo(&paths, start_path, ceiling_dirs, flags)) == 0)
1223
+ error = git_buf_fromstr(out, &paths.gitdir);
1224
+
1225
+ repo_paths_dispose(&paths);
1226
+ return error;
1188
1227
  }
1189
1228
 
1190
1229
  static int load_config(
@@ -1255,32 +1294,81 @@ static const char *path_unless_empty(git_str *buf)
1255
1294
  return git_str_len(buf) > 0 ? git_str_cstr(buf) : NULL;
1256
1295
  }
1257
1296
 
1297
+ GIT_INLINE(int) config_path_system(git_str *out, bool use_env)
1298
+ {
1299
+ if (use_env) {
1300
+ git_str no_system_buf = GIT_STR_INIT;
1301
+ int no_system = 0;
1302
+ int error;
1303
+
1304
+ error = git__getenv(&no_system_buf, "GIT_CONFIG_NOSYSTEM");
1305
+
1306
+ if (error && error != GIT_ENOTFOUND)
1307
+ return error;
1308
+
1309
+ error = git_config_parse_bool(&no_system, no_system_buf.ptr);
1310
+ git_str_dispose(&no_system_buf);
1311
+
1312
+ if (no_system)
1313
+ return 0;
1314
+
1315
+ error = git__getenv(out, "GIT_CONFIG_SYSTEM");
1316
+
1317
+ if (error == 0 || error != GIT_ENOTFOUND)
1318
+ return 0;
1319
+ }
1320
+
1321
+ git_config__find_system(out);
1322
+ return 0;
1323
+ }
1324
+
1325
+ GIT_INLINE(int) config_path_global(git_str *out, bool use_env)
1326
+ {
1327
+ if (use_env) {
1328
+ int error = git__getenv(out, "GIT_CONFIG_GLOBAL");
1329
+
1330
+ if (error == 0 || error != GIT_ENOTFOUND)
1331
+ return 0;
1332
+ }
1333
+
1334
+ git_config__find_global(out);
1335
+ return 0;
1336
+ }
1337
+
1258
1338
  int git_repository_config__weakptr(git_config **out, git_repository *repo)
1259
1339
  {
1260
1340
  int error = 0;
1261
1341
 
1262
1342
  if (repo->_config == NULL) {
1343
+ git_str system_buf = GIT_STR_INIT;
1263
1344
  git_str global_buf = GIT_STR_INIT;
1264
1345
  git_str xdg_buf = GIT_STR_INIT;
1265
- git_str system_buf = GIT_STR_INIT;
1266
1346
  git_str programdata_buf = GIT_STR_INIT;
1347
+ bool use_env = repo->use_env;
1267
1348
  git_config *config;
1268
1349
 
1269
- git_config__find_global(&global_buf);
1270
- git_config__find_xdg(&xdg_buf);
1271
- git_config__find_system(&system_buf);
1272
- git_config__find_programdata(&programdata_buf);
1350
+ if (!(error = config_path_system(&system_buf, use_env)) &&
1351
+ !(error = config_path_global(&global_buf, use_env))) {
1352
+ git_config__find_xdg(&xdg_buf);
1353
+ git_config__find_programdata(&programdata_buf);
1354
+ }
1273
1355
 
1274
- /* If there is no global file, open a backend for it anyway */
1275
- if (git_str_len(&global_buf) == 0)
1276
- git_config__global_location(&global_buf);
1356
+ if (!error) {
1357
+ /*
1358
+ * If there is no global file, open a backend
1359
+ * for it anyway.
1360
+ */
1361
+ if (git_str_len(&global_buf) == 0)
1362
+ git_config__global_location(&global_buf);
1363
+
1364
+ error = load_config(
1365
+ &config, repo,
1366
+ path_unless_empty(&global_buf),
1367
+ path_unless_empty(&xdg_buf),
1368
+ path_unless_empty(&system_buf),
1369
+ path_unless_empty(&programdata_buf));
1370
+ }
1277
1371
 
1278
- error = load_config(
1279
- &config, repo,
1280
- path_unless_empty(&global_buf),
1281
- path_unless_empty(&xdg_buf),
1282
- path_unless_empty(&system_buf),
1283
- path_unless_empty(&programdata_buf));
1284
1372
  if (!error) {
1285
1373
  GIT_REFCOUNT_OWN(config, repo);
1286
1374
 
@@ -1329,6 +1417,56 @@ int git_repository_set_config(git_repository *repo, git_config *config)
1329
1417
  return 0;
1330
1418
  }
1331
1419
 
1420
+ static int repository_odb_path(git_str *out, git_repository *repo)
1421
+ {
1422
+ int error = GIT_ENOTFOUND;
1423
+
1424
+ if (repo->use_env)
1425
+ error = git__getenv(out, "GIT_OBJECT_DIRECTORY");
1426
+
1427
+ if (error == GIT_ENOTFOUND)
1428
+ error = git_repository__item_path(out, repo,
1429
+ GIT_REPOSITORY_ITEM_OBJECTS);
1430
+
1431
+ return error;
1432
+ }
1433
+
1434
+ static int repository_odb_alternates(
1435
+ git_odb *odb,
1436
+ git_repository *repo)
1437
+ {
1438
+ git_str alternates = GIT_STR_INIT;
1439
+ char *sep, *alt;
1440
+ int error;
1441
+
1442
+ if (!repo->use_env)
1443
+ return 0;
1444
+
1445
+ error = git__getenv(&alternates, "GIT_ALTERNATE_OBJECT_DIRECTORIES");
1446
+
1447
+ if (error != 0)
1448
+ return (error == GIT_ENOTFOUND) ? 0 : error;
1449
+
1450
+ alt = alternates.ptr;
1451
+
1452
+ while (*alt) {
1453
+ sep = strchr(alt, GIT_PATH_LIST_SEPARATOR);
1454
+
1455
+ if (sep)
1456
+ *sep = '\0';
1457
+
1458
+ error = git_odb_add_disk_alternate(odb, alt);
1459
+
1460
+ if (sep)
1461
+ alt = sep + 1;
1462
+ else
1463
+ break;
1464
+ }
1465
+
1466
+ git_str_dispose(&alternates);
1467
+ return 0;
1468
+ }
1469
+
1332
1470
  int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
1333
1471
  {
1334
1472
  int error = 0;
@@ -1344,9 +1482,9 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
1344
1482
 
1345
1483
  odb_opts.oid_type = repo->oid_type;
1346
1484
 
1347
- if ((error = git_repository__item_path(&odb_path, repo,
1348
- GIT_REPOSITORY_ITEM_OBJECTS)) < 0 ||
1349
- (error = git_odb__new(&odb, &odb_opts)) < 0)
1485
+ if ((error = repository_odb_path(&odb_path, repo)) < 0 ||
1486
+ (error = git_odb__new(&odb, &odb_opts)) < 0 ||
1487
+ (error = repository_odb_alternates(odb, repo)) < 0)
1350
1488
  return error;
1351
1489
 
1352
1490
  GIT_REFCOUNT_OWN(odb, repo);
@@ -1430,6 +1568,20 @@ int git_repository_set_refdb(git_repository *repo, git_refdb *refdb)
1430
1568
  return 0;
1431
1569
  }
1432
1570
 
1571
+ static int repository_index_path(git_str *out, git_repository *repo)
1572
+ {
1573
+ int error = GIT_ENOTFOUND;
1574
+
1575
+ if (repo->use_env)
1576
+ error = git__getenv(out, "GIT_INDEX_FILE");
1577
+
1578
+ if (error == GIT_ENOTFOUND)
1579
+ error = git_repository__item_path(out, repo,
1580
+ GIT_REPOSITORY_ITEM_INDEX);
1581
+
1582
+ return error;
1583
+ }
1584
+
1433
1585
  int git_repository_index__weakptr(git_index **out, git_repository *repo)
1434
1586
  {
1435
1587
  int error = 0;
@@ -1441,10 +1593,11 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo)
1441
1593
  git_str index_path = GIT_STR_INIT;
1442
1594
  git_index *index;
1443
1595
 
1444
- if ((error = git_str_joinpath(&index_path, repo->gitdir, GIT_INDEX_FILE)) < 0)
1596
+ if ((error = repository_index_path(&index_path, repo)) < 0)
1445
1597
  return error;
1446
1598
 
1447
- error = git_index_open(&index, index_path.ptr);
1599
+ error = git_index__open(&index, index_path.ptr, repo->oid_type);
1600
+
1448
1601
  if (!error) {
1449
1602
  GIT_REFCOUNT_OWN(index, repo);
1450
1603
 
@@ -1480,6 +1633,22 @@ int git_repository_set_index(git_repository *repo, git_index *index)
1480
1633
  return 0;
1481
1634
  }
1482
1635
 
1636
+ int git_repository_grafts__weakptr(git_grafts **out, git_repository *repo)
1637
+ {
1638
+ GIT_ASSERT_ARG(out && repo);
1639
+ GIT_ASSERT(repo->grafts);
1640
+ *out = repo->grafts;
1641
+ return 0;
1642
+ }
1643
+
1644
+ int git_repository_shallow_grafts__weakptr(git_grafts **out, git_repository *repo)
1645
+ {
1646
+ GIT_ASSERT_ARG(out && repo);
1647
+ GIT_ASSERT(repo->shallow_grafts);
1648
+ *out = repo->shallow_grafts;
1649
+ return 0;
1650
+ }
1651
+
1483
1652
  int git_repository_set_namespace(git_repository *repo, const char *namespace)
1484
1653
  {
1485
1654
  git__free(repo->namespace);
@@ -1632,7 +1801,7 @@ static const char *builtin_extensions[] = {
1632
1801
  "objectformat"
1633
1802
  };
1634
1803
 
1635
- static git_vector user_extensions = GIT_VECTOR_INIT;
1804
+ static git_vector user_extensions = { 0, git__strcmp_cb };
1636
1805
 
1637
1806
  static int check_valid_extension(const git_config_entry *entry, void *payload)
1638
1807
  {
@@ -1700,7 +1869,7 @@ static int load_objectformat(git_repository *repo, git_config *config)
1700
1869
 
1701
1870
  if ((error = git_config_get_entry(&entry, config, "extensions.objectformat")) < 0) {
1702
1871
  if (error == GIT_ENOTFOUND) {
1703
- repo->oid_type = GIT_OID_SHA1;
1872
+ repo->oid_type = GIT_OID_DEFAULT;
1704
1873
  git_error_clear();
1705
1874
  error = 0;
1706
1875
  }
@@ -1773,7 +1942,7 @@ int git_repository__extensions(char ***out, size_t *out_len)
1773
1942
  char *extension;
1774
1943
  size_t i, j;
1775
1944
 
1776
- if (git_vector_init(&extensions, 8, NULL) < 0)
1945
+ if (git_vector_init(&extensions, 8, git__strcmp_cb) < 0)
1777
1946
  return -1;
1778
1947
 
1779
1948
  for (i = 0; i < ARRAY_SIZE(builtin_extensions); i++) {
@@ -1805,21 +1974,49 @@ int git_repository__extensions(char ***out, size_t *out_len)
1805
1974
  return -1;
1806
1975
  }
1807
1976
 
1977
+ git_vector_sort(&extensions);
1978
+
1808
1979
  *out = (char **)git_vector_detach(out_len, NULL, &extensions);
1809
1980
  return 0;
1810
1981
  }
1811
1982
 
1983
+ static int dup_ext_err(void **old, void *extension)
1984
+ {
1985
+ GIT_UNUSED(old);
1986
+ GIT_UNUSED(extension);
1987
+ return GIT_EEXISTS;
1988
+ }
1989
+
1812
1990
  int git_repository__set_extensions(const char **extensions, size_t len)
1813
1991
  {
1814
1992
  char *extension;
1815
- size_t i;
1993
+ size_t i, j;
1994
+ int error;
1816
1995
 
1817
1996
  git_repository__free_extensions();
1818
1997
 
1819
1998
  for (i = 0; i < len; i++) {
1820
- if ((extension = git__strdup(extensions[i])) == NULL ||
1821
- git_vector_insert(&user_extensions, extension) < 0)
1999
+ bool is_builtin = false;
2000
+
2001
+ for (j = 0; j < ARRAY_SIZE(builtin_extensions); j++) {
2002
+ if (strcmp(builtin_extensions[j], extensions[i]) == 0) {
2003
+ is_builtin = true;
2004
+ break;
2005
+ }
2006
+ }
2007
+
2008
+ if (is_builtin)
2009
+ continue;
2010
+
2011
+ if ((extension = git__strdup(extensions[i])) == NULL)
1822
2012
  return -1;
2013
+
2014
+ if ((error = git_vector_insert_sorted(&user_extensions, extension, dup_ext_err)) < 0) {
2015
+ git__free(extension);
2016
+
2017
+ if (error != GIT_EEXISTS)
2018
+ return -1;
2019
+ }
1823
2020
  }
1824
2021
 
1825
2022
  return 0;
@@ -1888,7 +2085,7 @@ static bool is_filesystem_case_insensitive(const char *gitdir_path)
1888
2085
  * Return a configuration object with only the global and system
1889
2086
  * configurations; no repository-level configuration.
1890
2087
  */
1891
- static int load_global_config(git_config **config)
2088
+ static int load_global_config(git_config **config, bool use_env)
1892
2089
  {
1893
2090
  git_str global_buf = GIT_STR_INIT;
1894
2091
  git_str xdg_buf = GIT_STR_INIT;
@@ -1896,16 +2093,17 @@ static int load_global_config(git_config **config)
1896
2093
  git_str programdata_buf = GIT_STR_INIT;
1897
2094
  int error;
1898
2095
 
1899
- git_config__find_global(&global_buf);
1900
- git_config__find_xdg(&xdg_buf);
1901
- git_config__find_system(&system_buf);
1902
- git_config__find_programdata(&programdata_buf);
2096
+ if (!(error = config_path_system(&system_buf, use_env)) &&
2097
+ !(error = config_path_global(&global_buf, use_env))) {
2098
+ git_config__find_xdg(&xdg_buf);
2099
+ git_config__find_programdata(&programdata_buf);
1903
2100
 
1904
- error = load_config(config, NULL,
1905
- path_unless_empty(&global_buf),
1906
- path_unless_empty(&xdg_buf),
1907
- path_unless_empty(&system_buf),
1908
- path_unless_empty(&programdata_buf));
2101
+ error = load_config(config, NULL,
2102
+ path_unless_empty(&global_buf),
2103
+ path_unless_empty(&xdg_buf),
2104
+ path_unless_empty(&system_buf),
2105
+ path_unless_empty(&programdata_buf));
2106
+ }
1909
2107
 
1910
2108
  git_str_dispose(&global_buf);
1911
2109
  git_str_dispose(&xdg_buf);
@@ -1915,7 +2113,7 @@ static int load_global_config(git_config **config)
1915
2113
  return error;
1916
2114
  }
1917
2115
 
1918
- static bool are_symlinks_supported(const char *wd_path)
2116
+ static bool are_symlinks_supported(const char *wd_path, bool use_env)
1919
2117
  {
1920
2118
  git_config *config = NULL;
1921
2119
  int symlinks = 0;
@@ -1928,10 +2126,12 @@ static bool are_symlinks_supported(const char *wd_path)
1928
2126
  * _not_ set, then we do not test or enable symlink support.
1929
2127
  */
1930
2128
  #ifdef GIT_WIN32
1931
- if (load_global_config(&config) < 0 ||
2129
+ if (load_global_config(&config, use_env) < 0 ||
1932
2130
  git_config_get_bool(&symlinks, config, "core.symlinks") < 0 ||
1933
2131
  !symlinks)
1934
2132
  goto done;
2133
+ #else
2134
+ GIT_UNUSED(use_env);
1935
2135
  #endif
1936
2136
 
1937
2137
  if (!(symlinks = git_fs_path_supports_symlinks(wd_path)))
@@ -2004,7 +2204,8 @@ static int repo_init_fs_configs(
2004
2204
  const char *cfg_path,
2005
2205
  const char *repo_dir,
2006
2206
  const char *work_dir,
2007
- bool update_ignorecase)
2207
+ bool update_ignorecase,
2208
+ bool use_env)
2008
2209
  {
2009
2210
  int error = 0;
2010
2211
 
@@ -2015,7 +2216,7 @@ static int repo_init_fs_configs(
2015
2216
  cfg, "core.filemode", is_chmod_supported(cfg_path))) < 0)
2016
2217
  return error;
2017
2218
 
2018
- if (!are_symlinks_supported(work_dir)) {
2219
+ if (!are_symlinks_supported(work_dir, use_env)) {
2019
2220
  if ((error = git_config_set_bool(cfg, "core.symlinks", false)) < 0)
2020
2221
  return error;
2021
2222
  } else if (git_config_delete_entry(cfg, "core.symlinks") < 0)
@@ -2052,6 +2253,7 @@ static int repo_init_config(
2052
2253
  git_config *config = NULL;
2053
2254
  bool is_bare = ((flags & GIT_REPOSITORY_INIT_BARE) != 0);
2054
2255
  bool is_reinit = ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0);
2256
+ bool use_env = ((flags & GIT_REPOSITORY_OPEN_FROM_ENV) != 0);
2055
2257
  int version = GIT_REPO_VERSION_DEFAULT;
2056
2258
 
2057
2259
  if ((error = repo_local_config(&config, &cfg_path, NULL, repo_dir)) < 0)
@@ -2072,7 +2274,8 @@ static int repo_init_config(
2072
2274
  SET_REPO_CONFIG(int32, "core.repositoryformatversion", version);
2073
2275
 
2074
2276
  if ((error = repo_init_fs_configs(
2075
- config, cfg_path.ptr, repo_dir, work_dir, !is_reinit)) < 0)
2277
+ config, cfg_path.ptr, repo_dir, work_dir,
2278
+ !is_reinit, use_env)) < 0)
2076
2279
  goto cleanup;
2077
2280
 
2078
2281
  if (!is_bare) {
@@ -2102,7 +2305,7 @@ static int repo_init_config(
2102
2305
  SET_REPO_CONFIG(bool, "receive.denyNonFastforwards", true);
2103
2306
  }
2104
2307
 
2105
- if (oid_type != GIT_OID_SHA1) {
2308
+ if (oid_type != GIT_OID_DEFAULT) {
2106
2309
  SET_REPO_CONFIG(int32, "core.repositoryformatversion", 1);
2107
2310
  SET_REPO_CONFIG(string, "extensions.objectformat", git_oid_type_name(oid_type));
2108
2311
  }
@@ -2136,8 +2339,8 @@ int git_repository_reinit_filesystem(git_repository *repo, int recurse)
2136
2339
  const char *repo_dir = git_repository_path(repo);
2137
2340
 
2138
2341
  if (!(error = repo_local_config(&config, &path, repo, repo_dir)))
2139
- error = repo_init_fs_configs(
2140
- config, path.ptr, repo_dir, git_repository_workdir(repo), true);
2342
+ error = repo_init_fs_configs(config, path.ptr, repo_dir,
2343
+ git_repository_workdir(repo), true, repo->use_env);
2141
2344
 
2142
2345
  git_config_free(config);
2143
2346
  git_str_dispose(&path);
@@ -2606,7 +2809,7 @@ int git_repository_init_ext(
2606
2809
 
2607
2810
  wd = (opts->flags & GIT_REPOSITORY_INIT_BARE) ? NULL : git_str_cstr(&wd_path);
2608
2811
 
2609
- if ((error = is_valid_repository_path(&is_valid, &repo_path, &common_path)) < 0)
2812
+ if ((error = is_valid_repository_path(&is_valid, &repo_path, &common_path, opts->flags)) < 0)
2610
2813
  goto out;
2611
2814
 
2612
2815
  if (is_valid) {
@@ -3221,12 +3424,18 @@ cleanup:
3221
3424
 
3222
3425
  static int checkout_message(git_str *out, git_reference *old, const char *new)
3223
3426
  {
3427
+ const char *idstr;
3428
+
3224
3429
  git_str_puts(out, "checkout: moving from ");
3225
3430
 
3226
- if (git_reference_type(old) == GIT_REFERENCE_SYMBOLIC)
3431
+ if (git_reference_type(old) == GIT_REFERENCE_SYMBOLIC) {
3227
3432
  git_str_puts(out, git_reference__shorthand(git_reference_symbolic_target(old)));
3228
- else
3229
- git_str_puts(out, git_oid_tostr_s(git_reference_target(old)));
3433
+ } else {
3434
+ if ((idstr = git_oid_tostr_s(git_reference_target(old))) == NULL)
3435
+ return -1;
3436
+
3437
+ git_str_puts(out, idstr);
3438
+ }
3230
3439
 
3231
3440
  git_str_puts(out, " to ");
3232
3441
 
@@ -3262,8 +3471,11 @@ static int detach(git_repository *repo, const git_oid *id, const char *new)
3262
3471
  if ((error = git_object_peel(&peeled, object, GIT_OBJECT_COMMIT)) < 0)
3263
3472
  goto cleanup;
3264
3473
 
3265
- if (new == NULL)
3266
- new = git_oid_tostr_s(git_object_id(peeled));
3474
+ if (new == NULL &&
3475
+ (new = git_oid_tostr_s(git_object_id(peeled))) == NULL) {
3476
+ error = -1;
3477
+ goto cleanup;
3478
+ }
3267
3479
 
3268
3480
  if ((error = checkout_message(&log_message, current, new)) < 0)
3269
3481
  goto cleanup;
@@ -3351,6 +3563,7 @@ int git_repository_detach_head(git_repository *repo)
3351
3563
  git_reference *old_head = NULL, *new_head = NULL, *current = NULL;
3352
3564
  git_object *object = NULL;
3353
3565
  git_str log_message = GIT_STR_INIT;
3566
+ const char *idstr;
3354
3567
  int error;
3355
3568
 
3356
3569
  GIT_ASSERT_ARG(repo);
@@ -3364,7 +3577,12 @@ int git_repository_detach_head(git_repository *repo)
3364
3577
  if ((error = git_object_lookup(&object, repo, git_reference_target(old_head), GIT_OBJECT_COMMIT)) < 0)
3365
3578
  goto cleanup;
3366
3579
 
3367
- if ((error = checkout_message(&log_message, current, git_oid_tostr_s(git_object_id(object)))) < 0)
3580
+ if ((idstr = git_oid_tostr_s(git_object_id(object))) == NULL) {
3581
+ error = -1;
3582
+ goto cleanup;
3583
+ }
3584
+
3585
+ if ((error = checkout_message(&log_message, current, idstr)) < 0)
3368
3586
  goto cleanup;
3369
3587
 
3370
3588
  error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_reference_target(old_head),
@@ -3470,6 +3688,66 @@ int git_repository_state_cleanup(git_repository *repo)
3470
3688
  return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files));
3471
3689
  }
3472
3690
 
3691
+ int git_repository__shallow_roots(
3692
+ git_oid **out,
3693
+ size_t *out_len,
3694
+ git_repository *repo)
3695
+ {
3696
+ int error = 0;
3697
+
3698
+ if (!repo->shallow_grafts && (error = load_grafts(repo)) < 0)
3699
+ return error;
3700
+
3701
+ if ((error = git_grafts_refresh(repo->shallow_grafts)) < 0)
3702
+ return error;
3703
+
3704
+ if ((error = git_grafts_oids(out, out_len, repo->shallow_grafts)) < 0)
3705
+ return error;
3706
+
3707
+ return 0;
3708
+ }
3709
+
3710
+ int git_repository__shallow_roots_write(git_repository *repo, git_oidarray *roots)
3711
+ {
3712
+ git_filebuf file = GIT_FILEBUF_INIT;
3713
+ git_str path = GIT_STR_INIT;
3714
+ char oid_str[GIT_OID_MAX_HEXSIZE + 1];
3715
+ size_t i;
3716
+ int filebuf_hash, error = 0;
3717
+
3718
+ GIT_ASSERT_ARG(repo);
3719
+
3720
+ filebuf_hash = git_filebuf_hash_flags(git_oid_algorithm(repo->oid_type));
3721
+ GIT_ASSERT(filebuf_hash);
3722
+
3723
+ if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0)
3724
+ goto on_error;
3725
+
3726
+ if ((error = git_filebuf_open(&file, git_str_cstr(&path), filebuf_hash, 0666)) < 0)
3727
+ goto on_error;
3728
+
3729
+ for (i = 0; i < roots->count; i++) {
3730
+ git_oid_tostr(oid_str, sizeof(oid_str), &roots->ids[i]);
3731
+ git_filebuf_write(&file, oid_str, git_oid_hexsize(repo->oid_type));
3732
+ git_filebuf_write(&file, "\n", 1);
3733
+ }
3734
+
3735
+ git_filebuf_commit(&file);
3736
+
3737
+ if ((error = load_grafts(repo)) < 0) {
3738
+ error = -1;
3739
+ goto on_error;
3740
+ }
3741
+
3742
+ if (!roots->count)
3743
+ remove(path.ptr);
3744
+
3745
+ on_error:
3746
+ git_str_dispose(&path);
3747
+
3748
+ return error;
3749
+ }
3750
+
3473
3751
  int git_repository_is_shallow(git_repository *repo)
3474
3752
  {
3475
3753
  git_str path = GIT_STR_INIT;
@@ -3489,6 +3767,7 @@ int git_repository_is_shallow(git_repository *repo)
3489
3767
 
3490
3768
  if (error < 0)
3491
3769
  return error;
3770
+
3492
3771
  return st.st_size == 0 ? 0 : 1;
3493
3772
  }
3494
3773