rugged 1.6.5 → 1.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/rugged/rugged_allocator.c +0 -54
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +3 -8
- data/vendor/libgit2/cmake/CheckPrototypeDefinitionSafe.cmake +16 -0
- data/vendor/libgit2/cmake/SelectGSSAPI.cmake +3 -3
- data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +21 -2
- data/vendor/libgit2/cmake/SelectHashes.cmake +4 -0
- data/vendor/libgit2/cmake/SelectXdiff.cmake +9 -0
- data/vendor/libgit2/deps/pcre/LICENCE +5 -5
- data/vendor/libgit2/deps/pcre/pcre.h +2 -2
- data/vendor/libgit2/deps/pcre/pcre_compile.c +6 -3
- data/vendor/libgit2/deps/pcre/pcre_exec.c +2 -2
- data/vendor/libgit2/deps/xdiff/CMakeLists.txt +28 -0
- data/vendor/libgit2/{src/libgit2 → deps}/xdiff/git-xdiff.h +4 -1
- data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.c +19 -18
- data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.h +2 -4
- data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.c +3 -3
- data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xhistogram.c +7 -18
- data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmacros.h +18 -1
- data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmerge.c +24 -22
- data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xpatience.c +21 -30
- data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.c +13 -30
- data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.c +18 -1
- data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.h +2 -1
- data/vendor/libgit2/include/git2/common.h +26 -1
- data/vendor/libgit2/include/git2/diff.h +41 -3
- data/vendor/libgit2/include/git2/errors.h +4 -2
- data/vendor/libgit2/include/git2/index.h +9 -0
- data/vendor/libgit2/include/git2/oid.h +1 -1
- data/vendor/libgit2/include/git2/remote.h +18 -0
- data/vendor/libgit2/include/git2/repository.h +12 -2
- data/vendor/libgit2/include/git2/sys/alloc.h +0 -34
- data/vendor/libgit2/include/git2/sys/commit_graph.h +12 -2
- data/vendor/libgit2/include/git2/sys/midx.h +5 -1
- data/vendor/libgit2/include/git2/sys/stream.h +16 -2
- data/vendor/libgit2/include/git2/sys/transport.h +20 -2
- data/vendor/libgit2/include/git2/version.h +4 -4
- data/vendor/libgit2/include/git2/worktree.h +3 -1
- data/vendor/libgit2/src/CMakeLists.txt +34 -11
- data/vendor/libgit2/src/cli/cmd_clone.c +22 -6
- data/vendor/libgit2/src/cli/progress.c +9 -8
- data/vendor/libgit2/src/cli/progress.h +4 -4
- data/vendor/libgit2/src/libgit2/CMakeLists.txt +1 -19
- data/vendor/libgit2/src/libgit2/annotated_commit.c +2 -2
- data/vendor/libgit2/src/libgit2/annotated_commit.h +1 -1
- data/vendor/libgit2/src/libgit2/apply.c +4 -3
- data/vendor/libgit2/src/libgit2/blame.c +23 -16
- data/vendor/libgit2/src/libgit2/blame_git.c +0 -1
- data/vendor/libgit2/src/libgit2/branch.c +2 -2
- data/vendor/libgit2/src/libgit2/cherrypick.c +3 -3
- data/vendor/libgit2/src/libgit2/clone.c +3 -1
- data/vendor/libgit2/src/libgit2/commit.c +31 -9
- data/vendor/libgit2/src/libgit2/commit_graph.c +110 -43
- data/vendor/libgit2/src/libgit2/commit_graph.h +20 -4
- data/vendor/libgit2/src/libgit2/commit_list.c +12 -5
- data/vendor/libgit2/src/libgit2/commit_list.h +1 -0
- data/vendor/libgit2/src/libgit2/config_file.c +14 -8
- data/vendor/libgit2/src/libgit2/describe.c +10 -7
- data/vendor/libgit2/src/libgit2/diff.c +16 -7
- data/vendor/libgit2/src/libgit2/diff.h +6 -6
- data/vendor/libgit2/src/libgit2/diff_file.c +7 -7
- data/vendor/libgit2/src/libgit2/diff_generate.c +36 -15
- data/vendor/libgit2/src/libgit2/diff_parse.c +20 -4
- data/vendor/libgit2/src/libgit2/diff_print.c +26 -7
- data/vendor/libgit2/src/libgit2/diff_tform.c +4 -4
- data/vendor/libgit2/src/libgit2/diff_xdiff.h +1 -1
- data/vendor/libgit2/src/libgit2/email.c +4 -3
- data/vendor/libgit2/src/libgit2/errors.c +73 -18
- data/vendor/libgit2/src/libgit2/fetch.c +37 -9
- data/vendor/libgit2/src/libgit2/fetch.h +0 -2
- data/vendor/libgit2/src/libgit2/fetchhead.c +11 -9
- data/vendor/libgit2/src/libgit2/grafts.c +272 -0
- data/vendor/libgit2/src/libgit2/grafts.h +36 -0
- data/vendor/libgit2/src/libgit2/ident.c +3 -3
- data/vendor/libgit2/src/libgit2/index.c +325 -125
- data/vendor/libgit2/src/libgit2/index.h +14 -1
- data/vendor/libgit2/src/libgit2/indexer.c +10 -3
- data/vendor/libgit2/src/libgit2/iterator.c +20 -5
- data/vendor/libgit2/src/libgit2/iterator.h +3 -0
- data/vendor/libgit2/src/libgit2/libgit2.c +39 -0
- data/vendor/libgit2/src/libgit2/merge.c +14 -9
- data/vendor/libgit2/src/libgit2/merge_file.c +0 -2
- data/vendor/libgit2/src/libgit2/midx.c +66 -37
- data/vendor/libgit2/src/libgit2/midx.h +13 -3
- data/vendor/libgit2/src/libgit2/notes.c +9 -8
- data/vendor/libgit2/src/libgit2/object.c +40 -15
- data/vendor/libgit2/src/libgit2/object.h +6 -0
- data/vendor/libgit2/src/libgit2/odb.c +11 -5
- data/vendor/libgit2/src/libgit2/odb_pack.c +16 -3
- data/vendor/libgit2/src/libgit2/oid.c +7 -1
- data/vendor/libgit2/src/libgit2/oidarray.c +49 -3
- data/vendor/libgit2/src/libgit2/oidarray.h +5 -1
- data/vendor/libgit2/src/libgit2/pack-objects.c +19 -12
- data/vendor/libgit2/src/libgit2/pack-objects.h +5 -2
- data/vendor/libgit2/src/libgit2/pack.c +3 -3
- data/vendor/libgit2/src/libgit2/parse.c +7 -4
- data/vendor/libgit2/src/libgit2/parse.h +1 -1
- data/vendor/libgit2/src/libgit2/patch.h +7 -1
- data/vendor/libgit2/src/libgit2/patch_generate.c +24 -5
- data/vendor/libgit2/src/libgit2/patch_parse.c +16 -8
- data/vendor/libgit2/src/libgit2/push.c +2 -2
- data/vendor/libgit2/src/libgit2/reader.c +1 -1
- data/vendor/libgit2/src/libgit2/rebase.c +72 -84
- data/vendor/libgit2/src/libgit2/refdb_fs.c +22 -13
- data/vendor/libgit2/src/libgit2/refs.c +8 -1
- data/vendor/libgit2/src/libgit2/remote.c +15 -6
- data/vendor/libgit2/src/libgit2/remote.h +1 -0
- data/vendor/libgit2/src/libgit2/repository.c +580 -301
- data/vendor/libgit2/src/libgit2/repository.h +17 -2
- data/vendor/libgit2/src/libgit2/reset.c +2 -2
- data/vendor/libgit2/src/libgit2/revert.c +8 -11
- data/vendor/libgit2/src/libgit2/revparse.c +1 -4
- data/vendor/libgit2/src/libgit2/revwalk.c +26 -4
- data/vendor/libgit2/src/libgit2/stash.c +9 -8
- data/vendor/libgit2/src/libgit2/streams/mbedtls.c +0 -1
- data/vendor/libgit2/src/libgit2/streams/openssl.c +8 -16
- data/vendor/libgit2/src/libgit2/streams/schannel.c +715 -0
- data/vendor/libgit2/src/libgit2/streams/schannel.h +28 -0
- data/vendor/libgit2/src/libgit2/streams/socket.c +237 -51
- data/vendor/libgit2/src/libgit2/streams/socket.h +3 -1
- data/vendor/libgit2/src/libgit2/streams/stransport.c +40 -12
- data/vendor/libgit2/src/libgit2/streams/tls.c +5 -0
- data/vendor/libgit2/src/libgit2/submodule.h +3 -3
- data/vendor/libgit2/src/libgit2/threadstate.c +15 -2
- data/vendor/libgit2/src/libgit2/threadstate.h +1 -3
- data/vendor/libgit2/src/libgit2/transports/auth.h +1 -2
- data/vendor/libgit2/src/libgit2/transports/{auth_negotiate.c → auth_gssapi.c} +32 -32
- data/vendor/libgit2/src/libgit2/transports/auth_negotiate.h +1 -1
- data/vendor/libgit2/src/libgit2/transports/auth_ntlm.h +1 -1
- data/vendor/libgit2/src/libgit2/transports/{auth_ntlm.c → auth_ntlmclient.c} +12 -12
- data/vendor/libgit2/src/libgit2/transports/auth_sspi.c +341 -0
- data/vendor/libgit2/src/libgit2/transports/git.c +7 -8
- data/vendor/libgit2/src/libgit2/transports/http.c +7 -2
- data/vendor/libgit2/src/libgit2/transports/httpclient.c +5 -0
- data/vendor/libgit2/src/libgit2/transports/local.c +13 -4
- data/vendor/libgit2/src/libgit2/transports/smart.c +33 -27
- data/vendor/libgit2/src/libgit2/transports/smart.h +23 -8
- data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +136 -17
- data/vendor/libgit2/src/libgit2/transports/smart_protocol.c +154 -47
- data/vendor/libgit2/src/libgit2/transports/ssh.c +3 -3
- data/vendor/libgit2/src/libgit2/transports/winhttp.c +14 -15
- data/vendor/libgit2/src/libgit2/tree-cache.c +26 -16
- data/vendor/libgit2/src/libgit2/tree-cache.h +5 -3
- data/vendor/libgit2/src/libgit2/tree.c +1 -1
- data/vendor/libgit2/src/libgit2/worktree.c +25 -10
- data/vendor/libgit2/src/util/alloc.c +65 -6
- data/vendor/libgit2/src/util/alloc.h +34 -9
- data/vendor/libgit2/src/util/allocators/failalloc.c +0 -60
- data/vendor/libgit2/src/util/allocators/failalloc.h +0 -6
- data/vendor/libgit2/src/util/allocators/stdalloc.c +2 -105
- data/vendor/libgit2/src/util/allocators/win32_leakcheck.c +0 -68
- data/vendor/libgit2/src/util/array.h +6 -1
- data/vendor/libgit2/src/util/cc-compat.h +2 -0
- data/vendor/libgit2/src/util/filebuf.c +6 -1
- data/vendor/libgit2/src/util/filebuf.h +19 -6
- data/vendor/libgit2/src/util/fs_path.c +1 -1
- data/vendor/libgit2/src/util/futils.c +8 -5
- data/vendor/libgit2/src/util/git2_features.h.in +9 -3
- data/vendor/libgit2/src/util/net.c +308 -157
- data/vendor/libgit2/src/util/net.h +25 -0
- data/vendor/libgit2/src/util/posix.c +54 -0
- data/vendor/libgit2/src/util/posix.h +22 -0
- data/vendor/libgit2/src/util/rand.c +6 -4
- data/vendor/libgit2/src/util/staticstr.h +66 -0
- data/vendor/libgit2/src/util/util.c +15 -10
- data/vendor/libgit2/src/util/util.h +24 -16
- data/vendor/libgit2/src/util/win32/error.c +1 -1
- data/vendor/libgit2/src/util/win32/path_w32.c +8 -8
- data/vendor/libgit2/src/util/win32/posix_w32.c +1 -1
- data/vendor/libgit2/src/util/win32/utf-conv.c +73 -75
- data/vendor/libgit2/src/util/win32/utf-conv.h +81 -14
- data/vendor/libgit2/src/util/win32/w32_util.c +1 -1
- metadata +29 -23
- data/vendor/libgit2/cmake/SelectWinHTTP.cmake +0 -17
- data/vendor/libgit2/src/libgit2/netops.c +0 -124
- data/vendor/libgit2/src/libgit2/netops.h +0 -68
- /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiff.h +0 -0
- /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.h +0 -0
- /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xinclude.h +0 -0
- /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.h +0 -0
- /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(
|
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
|
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(
|
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,
|
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(
|
361
|
+
static int load_workdir(
|
362
|
+
git_repository *repo,
|
363
|
+
git_config *config,
|
364
|
+
git_str *parent_path)
|
341
365
|
{
|
342
|
-
|
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
|
-
|
351
|
-
|
352
|
-
|
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
|
-
|
372
|
-
|
373
|
-
|
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(
|
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(
|
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
|
-
|
641
|
-
git_str
|
642
|
-
git_str
|
643
|
-
git_str
|
644
|
-
git_str
|
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
|
-
|
647
|
-
|
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(
|
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
|
-
/*
|
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
|
-
*
|
668
|
-
*
|
669
|
-
*
|
670
|
-
* min_iterations indicates the number of
|
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(
|
775
|
+
(error = git_str_set(&out->gitdir, path.ptr, path.size)) < 0)
|
704
776
|
goto out;
|
705
777
|
|
706
|
-
if (
|
707
|
-
|
708
|
-
|
709
|
-
|
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(
|
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
|
-
|
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
|
-
/*
|
733
|
-
*
|
734
|
-
*
|
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
|
-
/*
|
739
|
-
*
|
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 (
|
750
|
-
if (!git_str_len(
|
751
|
-
git_str_clear(
|
752
|
-
else if ((error = git_fs_path_dirname_r(
|
753
|
-
(error = git_fs_path_to_dir(
|
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
|
758
|
-
* to report, report that. */
|
759
|
-
if (!git_str_len(
|
760
|
-
git_error_set(GIT_ERROR_REPOSITORY, "could not find repository
|
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
|
-
|
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 =
|
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
|
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 (!
|
875
|
-
|
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
|
939
|
-
|
940
|
-
|
941
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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->
|
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
|
-
|
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
|
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
|
-
*
|
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
|
-
|
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
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
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
|
-
|
1275
|
-
|
1276
|
-
|
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 =
|
1348
|
-
|
1349
|
-
|
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 =
|
1596
|
+
if ((error = repository_index_path(&index_path, repo)) < 0)
|
1445
1597
|
return error;
|
1446
1598
|
|
1447
|
-
error =
|
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 =
|
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 =
|
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,
|
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
|
-
|
1821
|
-
|
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
|
-
|
1900
|
-
|
1901
|
-
|
1902
|
-
|
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
|
-
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1908
|
-
|
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,
|
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 !=
|
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
|
-
|
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
|
-
|
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
|
-
|
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 ((
|
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
|
|