rugged 0.25.0b5 → 0.25.0b6
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_patch.c +77 -17
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +8 -6
- data/vendor/libgit2/include/git2/checkout.h +7 -0
- data/vendor/libgit2/include/git2/common.h +1 -0
- data/vendor/libgit2/include/git2/diff.h +54 -7
- data/vendor/libgit2/include/git2/errors.h +2 -1
- data/vendor/libgit2/include/git2/index.h +25 -0
- data/vendor/libgit2/include/git2/pack.h +4 -4
- data/vendor/libgit2/include/git2/repository.h +20 -1
- data/vendor/libgit2/include/git2/submodule.h +11 -3
- data/vendor/libgit2/include/git2/sys/odb_backend.h +11 -0
- data/vendor/libgit2/src/apply.c +369 -0
- data/vendor/libgit2/src/apply.h +21 -0
- data/vendor/libgit2/src/array.h +0 -1
- data/vendor/libgit2/src/blame_git.c +18 -8
- data/vendor/libgit2/src/buffer.c +252 -20
- data/vendor/libgit2/src/buffer.h +8 -0
- data/vendor/libgit2/src/checkout.c +7 -1
- data/vendor/libgit2/src/clone.c +0 -8
- data/vendor/libgit2/src/common.h +1 -1
- data/vendor/libgit2/src/crlf.c +1 -0
- data/vendor/libgit2/src/delta.c +238 -62
- data/vendor/libgit2/src/delta.h +79 -58
- data/vendor/libgit2/src/diff.c +32 -1547
- data/vendor/libgit2/src/diff.h +12 -122
- data/vendor/libgit2/src/diff_driver.c +1 -2
- data/vendor/libgit2/src/diff_file.c +3 -0
- data/vendor/libgit2/src/diff_generate.c +1611 -0
- data/vendor/libgit2/src/diff_generate.h +123 -0
- data/vendor/libgit2/src/diff_parse.c +105 -0
- data/vendor/libgit2/src/diff_print.c +259 -142
- data/vendor/libgit2/src/diff_stats.c +3 -2
- data/vendor/libgit2/src/diff_tform.c +1 -0
- data/vendor/libgit2/src/diff_tform.h +22 -0
- data/vendor/libgit2/src/diff_xdiff.c +9 -9
- data/vendor/libgit2/src/diff_xdiff.h +5 -5
- data/vendor/libgit2/src/fileops.c +13 -0
- data/vendor/libgit2/src/fileops.h +6 -0
- data/vendor/libgit2/src/global.c +9 -8
- data/vendor/libgit2/src/ignore.c +45 -16
- data/vendor/libgit2/src/index.c +161 -47
- data/vendor/libgit2/src/index.h +2 -0
- data/vendor/libgit2/src/merge.c +2 -0
- data/vendor/libgit2/src/mwindow.c +8 -19
- data/vendor/libgit2/src/mwindow.h +1 -2
- data/vendor/libgit2/src/odb.c +46 -10
- data/vendor/libgit2/src/odb_loose.c +19 -1
- data/vendor/libgit2/src/odb_pack.c +27 -4
- data/vendor/libgit2/src/pack-objects.c +106 -77
- data/vendor/libgit2/src/pack-objects.h +13 -12
- data/vendor/libgit2/src/pack.c +4 -3
- data/vendor/libgit2/src/pack.h +2 -0
- data/vendor/libgit2/src/patch.c +207 -0
- data/vendor/libgit2/src/patch.h +66 -0
- data/vendor/libgit2/src/{diff_patch.c → patch_generate.c} +171 -359
- data/vendor/libgit2/src/patch_generate.h +66 -0
- data/vendor/libgit2/src/patch_parse.c +1121 -0
- data/vendor/libgit2/src/patch_parse.h +54 -0
- data/vendor/libgit2/src/path.c +19 -0
- data/vendor/libgit2/src/path.h +6 -0
- data/vendor/libgit2/src/pool.h +5 -0
- data/vendor/libgit2/src/remote.c +15 -80
- data/vendor/libgit2/src/repository.c +227 -39
- data/vendor/libgit2/src/settings.c +11 -5
- data/vendor/libgit2/src/stash.c +1 -0
- data/vendor/libgit2/src/status.c +1 -0
- data/vendor/libgit2/src/stransport_stream.c +14 -9
- data/vendor/libgit2/src/submodule.c +16 -4
- data/vendor/libgit2/src/sysdir.c +41 -47
- data/vendor/libgit2/src/sysdir.h +0 -5
- data/vendor/libgit2/src/thread-utils.h +5 -51
- data/vendor/libgit2/src/transport.c +3 -5
- data/vendor/libgit2/src/transports/http.c +2 -3
- data/vendor/libgit2/src/transports/smart_pkt.c +1 -0
- data/vendor/libgit2/src/transports/smart_protocol.c +11 -0
- data/vendor/libgit2/src/transports/winhttp.c +16 -2
- data/vendor/libgit2/src/unix/pthread.h +54 -0
- data/vendor/libgit2/src/util.c +23 -5
- data/vendor/libgit2/src/util.h +10 -0
- data/vendor/libgit2/src/varint.c +44 -0
- data/vendor/libgit2/src/varint.h +15 -0
- data/vendor/libgit2/src/vector.c +42 -0
- data/vendor/libgit2/src/vector.h +3 -0
- data/vendor/libgit2/src/win32/precompiled.h +1 -1
- data/vendor/libgit2/src/win32/{pthread.c → thread.c} +50 -80
- data/vendor/libgit2/src/win32/thread.h +62 -0
- data/vendor/libgit2/src/zstream.c +36 -7
- data/vendor/libgit2/src/zstream.h +8 -1
- metadata +20 -9
- data/vendor/libgit2/src/delta-apply.c +0 -166
- data/vendor/libgit2/src/delta-apply.h +0 -62
- data/vendor/libgit2/src/diff_patch.h +0 -83
- data/vendor/libgit2/src/win32/pthread.h +0 -92
@@ -0,0 +1,54 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) the libgit2 contributors. All rights reserved.
|
3
|
+
*
|
4
|
+
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
5
|
+
* a Linking Exception. For full terms see the included COPYING file.
|
6
|
+
*/
|
7
|
+
#ifndef INCLUDE_patch_parse_h__
|
8
|
+
#define INCLUDE_patch_parse_h__
|
9
|
+
|
10
|
+
typedef struct {
|
11
|
+
git_refcount rc;
|
12
|
+
|
13
|
+
/* Original content buffer */
|
14
|
+
const char *content;
|
15
|
+
size_t content_len;
|
16
|
+
|
17
|
+
git_patch_options opts;
|
18
|
+
|
19
|
+
/* The remaining (unparsed) buffer */
|
20
|
+
const char *remain;
|
21
|
+
size_t remain_len;
|
22
|
+
|
23
|
+
const char *line;
|
24
|
+
size_t line_len;
|
25
|
+
size_t line_num;
|
26
|
+
} git_patch_parse_ctx;
|
27
|
+
|
28
|
+
extern git_patch_parse_ctx *git_patch_parse_ctx_init(
|
29
|
+
const char *content,
|
30
|
+
size_t content_len,
|
31
|
+
const git_patch_options *opts);
|
32
|
+
|
33
|
+
extern void git_patch_parse_ctx_free(git_patch_parse_ctx *ctx);
|
34
|
+
|
35
|
+
/**
|
36
|
+
* Create a patch for a single file from the contents of a patch buffer.
|
37
|
+
*
|
38
|
+
* @param out The patch to be created
|
39
|
+
* @param contents The contents of a patch file
|
40
|
+
* @param contents_len The length of the patch file
|
41
|
+
* @param opts The git_patch_options
|
42
|
+
* @return 0 on success, <0 on failure.
|
43
|
+
*/
|
44
|
+
extern int git_patch_from_buffer(
|
45
|
+
git_patch **out,
|
46
|
+
const char *contents,
|
47
|
+
size_t contents_len,
|
48
|
+
const git_patch_options *opts);
|
49
|
+
|
50
|
+
extern int git_patch_parse(
|
51
|
+
git_patch **out,
|
52
|
+
git_patch_parse_ctx *ctx);
|
53
|
+
|
54
|
+
#endif
|
data/vendor/libgit2/src/path.c
CHANGED
@@ -306,6 +306,25 @@ int git_path_join_unrooted(
|
|
306
306
|
return 0;
|
307
307
|
}
|
308
308
|
|
309
|
+
void git_path_squash_slashes(git_buf *path)
|
310
|
+
{
|
311
|
+
char *p, *q;
|
312
|
+
|
313
|
+
if (path->size == 0)
|
314
|
+
return;
|
315
|
+
|
316
|
+
for (p = path->ptr, q = path->ptr; *q; p++, q++) {
|
317
|
+
*p = *q;
|
318
|
+
|
319
|
+
while (*q == '/' && *(q+1) == '/') {
|
320
|
+
path->size--;
|
321
|
+
q++;
|
322
|
+
}
|
323
|
+
}
|
324
|
+
|
325
|
+
*p = '\0';
|
326
|
+
}
|
327
|
+
|
309
328
|
int git_path_prettify(git_buf *path_out, const char *path, const char *base)
|
310
329
|
{
|
311
330
|
char buf[GIT_PATH_MAX];
|
data/vendor/libgit2/src/path.h
CHANGED
@@ -243,6 +243,12 @@ extern bool git_path_contains_file(git_buf *dir, const char *file);
|
|
243
243
|
extern int git_path_join_unrooted(
|
244
244
|
git_buf *path_out, const char *path, const char *base, ssize_t *root_at);
|
245
245
|
|
246
|
+
/**
|
247
|
+
* Removes multiple occurrences of '/' in a row, squashing them into a
|
248
|
+
* single '/'.
|
249
|
+
*/
|
250
|
+
extern void git_path_squash_slashes(git_buf *path);
|
251
|
+
|
246
252
|
/**
|
247
253
|
* Clean up path, prepending base if it is not already rooted.
|
248
254
|
*/
|
data/vendor/libgit2/src/pool.h
CHANGED
@@ -35,6 +35,8 @@ typedef struct {
|
|
35
35
|
uint32_t page_size; /* size of page in bytes */
|
36
36
|
} git_pool;
|
37
37
|
|
38
|
+
#define GIT_POOL_INIT { NULL, 0, 0 }
|
39
|
+
|
38
40
|
#else
|
39
41
|
|
40
42
|
/**
|
@@ -57,6 +59,9 @@ typedef struct {
|
|
57
59
|
uint32_t item_size;
|
58
60
|
uint32_t page_size;
|
59
61
|
} git_pool;
|
62
|
+
|
63
|
+
#define GIT_POOL_INIT { GIT_VECTOR_INIT, 0, 0 }
|
64
|
+
|
60
65
|
#endif
|
61
66
|
|
62
67
|
/**
|
data/vendor/libgit2/src/remote.c
CHANGED
@@ -547,53 +547,6 @@ static int lookup_remote_prune_config(git_remote *remote, git_config *config, co
|
|
547
547
|
return error;
|
548
548
|
}
|
549
549
|
|
550
|
-
static int update_config_refspec(const git_remote *remote, git_config *config, int direction)
|
551
|
-
{
|
552
|
-
git_buf name = GIT_BUF_INIT;
|
553
|
-
unsigned int push;
|
554
|
-
const char *dir;
|
555
|
-
size_t i;
|
556
|
-
int error = 0;
|
557
|
-
const char *cname;
|
558
|
-
|
559
|
-
push = direction == GIT_DIRECTION_PUSH;
|
560
|
-
dir = push ? "push" : "fetch";
|
561
|
-
|
562
|
-
if (git_buf_printf(&name, "remote.%s.%s", remote->name, dir) < 0)
|
563
|
-
return -1;
|
564
|
-
cname = git_buf_cstr(&name);
|
565
|
-
|
566
|
-
/* Clear out the existing config */
|
567
|
-
while (!error)
|
568
|
-
error = git_config_delete_multivar(config, cname, ".*");
|
569
|
-
|
570
|
-
if (error != GIT_ENOTFOUND)
|
571
|
-
return error;
|
572
|
-
|
573
|
-
for (i = 0; i < remote->refspecs.length; i++) {
|
574
|
-
git_refspec *spec = git_vector_get(&remote->refspecs, i);
|
575
|
-
|
576
|
-
if (spec->push != push)
|
577
|
-
continue;
|
578
|
-
|
579
|
-
// "$^" is a unmatcheable regexp: it will not match anything at all, so
|
580
|
-
// all values will be considered new and we will not replace any
|
581
|
-
// present value.
|
582
|
-
if ((error = git_config_set_multivar(
|
583
|
-
config, cname, "$^", spec->string)) < 0) {
|
584
|
-
goto cleanup;
|
585
|
-
}
|
586
|
-
}
|
587
|
-
|
588
|
-
giterr_clear();
|
589
|
-
error = 0;
|
590
|
-
|
591
|
-
cleanup:
|
592
|
-
git_buf_free(&name);
|
593
|
-
|
594
|
-
return error;
|
595
|
-
}
|
596
|
-
|
597
550
|
const char *git_remote_name(const git_remote *remote)
|
598
551
|
{
|
599
552
|
assert(remote);
|
@@ -1423,7 +1376,11 @@ static int update_tips_for_spec(
|
|
1423
1376
|
/* In autotag mode, don't overwrite any locally-existing tags */
|
1424
1377
|
error = git_reference_create(&ref, remote->repo, refname.ptr, &head->oid, !autotag,
|
1425
1378
|
log_message);
|
1426
|
-
|
1379
|
+
|
1380
|
+
if (error == GIT_EEXISTS)
|
1381
|
+
continue;
|
1382
|
+
|
1383
|
+
if (error < 0)
|
1427
1384
|
goto on_error;
|
1428
1385
|
|
1429
1386
|
git_reference_free(ref);
|
@@ -2099,34 +2056,6 @@ int git_remote_add_push(git_repository *repo, const char *remote, const char *re
|
|
2099
2056
|
return write_add_refspec(repo, remote, refspec, false);
|
2100
2057
|
}
|
2101
2058
|
|
2102
|
-
static int set_refspecs(git_remote *remote, git_strarray *array, int push)
|
2103
|
-
{
|
2104
|
-
git_vector *vec = &remote->refspecs;
|
2105
|
-
git_refspec *spec;
|
2106
|
-
size_t i;
|
2107
|
-
|
2108
|
-
/* Start by removing any refspecs of the same type */
|
2109
|
-
for (i = 0; i < vec->length; i++) {
|
2110
|
-
spec = git_vector_get(vec, i);
|
2111
|
-
if (spec->push != push)
|
2112
|
-
continue;
|
2113
|
-
|
2114
|
-
git_refspec__free(spec);
|
2115
|
-
git__free(spec);
|
2116
|
-
git_vector_remove(vec, i);
|
2117
|
-
i--;
|
2118
|
-
}
|
2119
|
-
|
2120
|
-
/* And now we add the new ones */
|
2121
|
-
|
2122
|
-
for (i = 0; i < array->count; i++) {
|
2123
|
-
if (add_refspec(remote, array->strings[i], !push) < 0)
|
2124
|
-
return -1;
|
2125
|
-
}
|
2126
|
-
|
2127
|
-
return 0;
|
2128
|
-
}
|
2129
|
-
|
2130
2059
|
static int copy_refspecs(git_strarray *array, const git_remote *remote, unsigned int push)
|
2131
2060
|
{
|
2132
2061
|
size_t i;
|
@@ -2233,15 +2162,21 @@ static int remove_branch_config_related_entries(
|
|
2233
2162
|
if (git_buf_printf(&buf, "branch.%.*s.merge", (int)branch_len, branch) < 0)
|
2234
2163
|
break;
|
2235
2164
|
|
2236
|
-
if ((error = git_config_delete_entry(config, git_buf_cstr(&buf))) < 0)
|
2237
|
-
|
2165
|
+
if ((error = git_config_delete_entry(config, git_buf_cstr(&buf))) < 0) {
|
2166
|
+
if (error != GIT_ENOTFOUND)
|
2167
|
+
break;
|
2168
|
+
giterr_clear();
|
2169
|
+
}
|
2238
2170
|
|
2239
2171
|
git_buf_clear(&buf);
|
2240
2172
|
if (git_buf_printf(&buf, "branch.%.*s.remote", (int)branch_len, branch) < 0)
|
2241
2173
|
break;
|
2242
2174
|
|
2243
|
-
if ((error = git_config_delete_entry(config, git_buf_cstr(&buf))) < 0)
|
2244
|
-
|
2175
|
+
if ((error = git_config_delete_entry(config, git_buf_cstr(&buf))) < 0) {
|
2176
|
+
if (error != GIT_ENOTFOUND)
|
2177
|
+
break;
|
2178
|
+
giterr_clear();
|
2179
|
+
}
|
2245
2180
|
}
|
2246
2181
|
|
2247
2182
|
if (error == GIT_ITEROVER)
|
@@ -264,7 +264,7 @@ cleanup:
|
|
264
264
|
* the stack could remove directories name limits, but at the cost of doing
|
265
265
|
* repeated malloc/frees inside the loop below, so let's not do it now.
|
266
266
|
*/
|
267
|
-
static
|
267
|
+
static size_t find_ceiling_dir_offset(
|
268
268
|
const char *path,
|
269
269
|
const char *ceiling_directories)
|
270
270
|
{
|
@@ -278,7 +278,7 @@ static int find_ceiling_dir_offset(
|
|
278
278
|
min_len = (size_t)(git_path_root(path) + 1);
|
279
279
|
|
280
280
|
if (ceiling_directories == NULL || min_len == 0)
|
281
|
-
return
|
281
|
+
return min_len;
|
282
282
|
|
283
283
|
for (sep = ceil = ceiling_directories; *sep; ceil = sep + 1) {
|
284
284
|
for (sep = ceil; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++);
|
@@ -305,7 +305,7 @@ static int find_ceiling_dir_offset(
|
|
305
305
|
}
|
306
306
|
}
|
307
307
|
|
308
|
-
return (
|
308
|
+
return (max_len <= min_len ? min_len : max_len);
|
309
309
|
}
|
310
310
|
|
311
311
|
/*
|
@@ -357,29 +357,50 @@ static int find_repo(
|
|
357
357
|
{
|
358
358
|
int error;
|
359
359
|
git_buf path = GIT_BUF_INIT;
|
360
|
+
git_buf repo_link = GIT_BUF_INIT;
|
360
361
|
struct stat st;
|
361
362
|
dev_t initial_device = 0;
|
362
|
-
|
363
|
-
|
363
|
+
int min_iterations;
|
364
|
+
bool in_dot_git;
|
365
|
+
size_t ceiling_offset = 0;
|
364
366
|
|
365
367
|
git_buf_free(repo_path);
|
366
368
|
|
367
|
-
|
369
|
+
error = git_path_prettify(&path, start_path, NULL);
|
370
|
+
if (error < 0)
|
368
371
|
return error;
|
369
372
|
|
370
|
-
|
373
|
+
/* in_dot_git toggles each loop:
|
374
|
+
* /a/b/c/.git, /a/b/c, /a/b/.git, /a/b, /a/.git, /a
|
375
|
+
* With GIT_REPOSITORY_OPEN_BARE or GIT_REPOSITORY_OPEN_NO_DOTGIT, we
|
376
|
+
* assume we started with /a/b/c.git and don't append .git the first
|
377
|
+
* time through.
|
378
|
+
* min_iterations indicates the number of iterations left before going
|
379
|
+
* further counts as a search. */
|
380
|
+
if (flags & (GIT_REPOSITORY_OPEN_BARE | GIT_REPOSITORY_OPEN_NO_DOTGIT)) {
|
381
|
+
in_dot_git = true;
|
382
|
+
min_iterations = 1;
|
383
|
+
} else {
|
384
|
+
in_dot_git = false;
|
385
|
+
min_iterations = 2;
|
386
|
+
}
|
371
387
|
|
372
|
-
|
373
|
-
(
|
374
|
-
|
388
|
+
for (;;) {
|
389
|
+
if (!(flags & GIT_REPOSITORY_OPEN_NO_DOTGIT)) {
|
390
|
+
if (!in_dot_git) {
|
391
|
+
error = git_buf_joinpath(&path, path.ptr, DOT_GIT);
|
392
|
+
if (error < 0)
|
393
|
+
break;
|
394
|
+
}
|
395
|
+
in_dot_git = !in_dot_git;
|
396
|
+
}
|
375
397
|
|
376
|
-
while (!error && !git_buf_len(repo_path)) {
|
377
398
|
if (p_stat(path.ptr, &st) == 0) {
|
378
399
|
/* check that we have not crossed device boundaries */
|
379
400
|
if (initial_device == 0)
|
380
401
|
initial_device = st.st_dev;
|
381
402
|
else if (st.st_dev != initial_device &&
|
382
|
-
|
403
|
+
!(flags & GIT_REPOSITORY_OPEN_CROSS_FS))
|
383
404
|
break;
|
384
405
|
|
385
406
|
if (S_ISDIR(st.st_mode)) {
|
@@ -390,41 +411,37 @@ static int find_repo(
|
|
390
411
|
}
|
391
412
|
}
|
392
413
|
else if (S_ISREG(st.st_mode)) {
|
393
|
-
|
394
|
-
|
395
|
-
if (!(error = read_gitfile(&repo_link, path.ptr))) {
|
396
|
-
if (valid_repository_path(&repo_link)) {
|
397
|
-
git_buf_swap(repo_path, &repo_link);
|
398
|
-
|
399
|
-
if (link_path)
|
400
|
-
error = git_buf_put(link_path,
|
401
|
-
path.ptr, path.size);
|
402
|
-
}
|
403
|
-
|
404
|
-
git_buf_free(&repo_link);
|
414
|
+
error = read_gitfile(&repo_link, path.ptr);
|
415
|
+
if (error < 0)
|
405
416
|
break;
|
417
|
+
if (valid_repository_path(&repo_link)) {
|
418
|
+
git_buf_swap(repo_path, &repo_link);
|
419
|
+
|
420
|
+
if (link_path)
|
421
|
+
error = git_buf_put(link_path, path.ptr, path.size);
|
406
422
|
}
|
407
|
-
|
423
|
+
break;
|
408
424
|
}
|
409
425
|
}
|
410
426
|
|
411
|
-
/*
|
427
|
+
/* Move up one directory. If we're in_dot_git, we'll search the
|
428
|
+
* parent itself next. If we're !in_dot_git, we'll search .git
|
429
|
+
* in the parent directory next (added at the top of the loop). */
|
412
430
|
if (git_path_dirname_r(&path, path.ptr) < 0) {
|
413
431
|
error = -1;
|
414
432
|
break;
|
415
433
|
}
|
416
434
|
|
417
|
-
if
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
try_with_dot_git = !try_with_dot_git;
|
435
|
+
/* Once we've checked the directory (and .git if applicable),
|
436
|
+
* find the ceiling for a search. */
|
437
|
+
if (min_iterations && (--min_iterations == 0))
|
438
|
+
ceiling_offset = find_ceiling_dir_offset(path.ptr, ceiling_dirs);
|
439
|
+
|
440
|
+
/* Check if we should stop searching here. */
|
441
|
+
if (min_iterations == 0
|
442
|
+
&& (path.ptr[ceiling_offset] == 0
|
443
|
+
|| (flags & GIT_REPOSITORY_OPEN_NO_SEARCH)))
|
444
|
+
break;
|
428
445
|
}
|
429
446
|
|
430
447
|
if (!error && parent_path && !(flags & GIT_REPOSITORY_OPEN_BARE)) {
|
@@ -438,14 +455,16 @@ static int find_repo(
|
|
438
455
|
return -1;
|
439
456
|
}
|
440
457
|
|
441
|
-
|
442
|
-
|
458
|
+
/* If we didn't find the repository, and we don't have any other error
|
459
|
+
* to report, report that. */
|
443
460
|
if (!git_buf_len(repo_path) && !error) {
|
444
461
|
giterr_set(GITERR_REPOSITORY,
|
445
462
|
"Could not find repository from '%s'", start_path);
|
446
463
|
error = GIT_ENOTFOUND;
|
447
464
|
}
|
448
465
|
|
466
|
+
git_buf_free(&path);
|
467
|
+
git_buf_free(&repo_link);
|
449
468
|
return error;
|
450
469
|
}
|
451
470
|
|
@@ -480,6 +499,172 @@ int git_repository_open_bare(
|
|
480
499
|
return 0;
|
481
500
|
}
|
482
501
|
|
502
|
+
static int _git_repository_open_ext_from_env(
|
503
|
+
git_repository **out,
|
504
|
+
const char *start_path)
|
505
|
+
{
|
506
|
+
git_repository *repo = NULL;
|
507
|
+
git_index *index = NULL;
|
508
|
+
git_odb *odb = NULL;
|
509
|
+
git_buf dir_buf = GIT_BUF_INIT;
|
510
|
+
git_buf ceiling_dirs_buf = GIT_BUF_INIT;
|
511
|
+
git_buf across_fs_buf = GIT_BUF_INIT;
|
512
|
+
git_buf index_file_buf = GIT_BUF_INIT;
|
513
|
+
git_buf namespace_buf = GIT_BUF_INIT;
|
514
|
+
git_buf object_dir_buf = GIT_BUF_INIT;
|
515
|
+
git_buf alts_buf = GIT_BUF_INIT;
|
516
|
+
git_buf work_tree_buf = GIT_BUF_INIT;
|
517
|
+
git_buf common_dir_buf = GIT_BUF_INIT;
|
518
|
+
const char *ceiling_dirs = NULL;
|
519
|
+
unsigned flags = 0;
|
520
|
+
int error;
|
521
|
+
|
522
|
+
if (!start_path) {
|
523
|
+
error = git__getenv(&dir_buf, "GIT_DIR");
|
524
|
+
if (error == GIT_ENOTFOUND) {
|
525
|
+
giterr_clear();
|
526
|
+
start_path = ".";
|
527
|
+
} else if (error < 0)
|
528
|
+
goto error;
|
529
|
+
else {
|
530
|
+
start_path = git_buf_cstr(&dir_buf);
|
531
|
+
flags |= GIT_REPOSITORY_OPEN_NO_SEARCH;
|
532
|
+
flags |= GIT_REPOSITORY_OPEN_NO_DOTGIT;
|
533
|
+
}
|
534
|
+
}
|
535
|
+
|
536
|
+
error = git__getenv(&ceiling_dirs_buf, "GIT_CEILING_DIRECTORIES");
|
537
|
+
if (error == GIT_ENOTFOUND)
|
538
|
+
giterr_clear();
|
539
|
+
else if (error < 0)
|
540
|
+
goto error;
|
541
|
+
else
|
542
|
+
ceiling_dirs = git_buf_cstr(&ceiling_dirs_buf);
|
543
|
+
|
544
|
+
error = git__getenv(&across_fs_buf, "GIT_DISCOVERY_ACROSS_FILESYSTEM");
|
545
|
+
if (error == GIT_ENOTFOUND)
|
546
|
+
giterr_clear();
|
547
|
+
else if (error < 0)
|
548
|
+
goto error;
|
549
|
+
else {
|
550
|
+
int across_fs = 0;
|
551
|
+
error = git_config_parse_bool(&across_fs, git_buf_cstr(&across_fs_buf));
|
552
|
+
if (error < 0)
|
553
|
+
goto error;
|
554
|
+
if (across_fs)
|
555
|
+
flags |= GIT_REPOSITORY_OPEN_CROSS_FS;
|
556
|
+
}
|
557
|
+
|
558
|
+
error = git__getenv(&index_file_buf, "GIT_INDEX_FILE");
|
559
|
+
if (error == GIT_ENOTFOUND)
|
560
|
+
giterr_clear();
|
561
|
+
else if (error < 0)
|
562
|
+
goto error;
|
563
|
+
else {
|
564
|
+
error = git_index_open(&index, git_buf_cstr(&index_file_buf));
|
565
|
+
if (error < 0)
|
566
|
+
goto error;
|
567
|
+
}
|
568
|
+
|
569
|
+
error = git__getenv(&namespace_buf, "GIT_NAMESPACE");
|
570
|
+
if (error == GIT_ENOTFOUND)
|
571
|
+
giterr_clear();
|
572
|
+
else if (error < 0)
|
573
|
+
goto error;
|
574
|
+
|
575
|
+
error = git__getenv(&object_dir_buf, "GIT_OBJECT_DIRECTORY");
|
576
|
+
if (error == GIT_ENOTFOUND)
|
577
|
+
giterr_clear();
|
578
|
+
else if (error < 0)
|
579
|
+
goto error;
|
580
|
+
else {
|
581
|
+
error = git_odb_open(&odb, git_buf_cstr(&object_dir_buf));
|
582
|
+
if (error < 0)
|
583
|
+
goto error;
|
584
|
+
}
|
585
|
+
|
586
|
+
error = git__getenv(&work_tree_buf, "GIT_WORK_TREE");
|
587
|
+
if (error == GIT_ENOTFOUND)
|
588
|
+
giterr_clear();
|
589
|
+
else if (error < 0)
|
590
|
+
goto error;
|
591
|
+
else {
|
592
|
+
giterr_set(GITERR_INVALID, "GIT_WORK_TREE unimplemented");
|
593
|
+
error = GIT_ERROR;
|
594
|
+
goto error;
|
595
|
+
}
|
596
|
+
|
597
|
+
error = git__getenv(&work_tree_buf, "GIT_COMMON_DIR");
|
598
|
+
if (error == GIT_ENOTFOUND)
|
599
|
+
giterr_clear();
|
600
|
+
else if (error < 0)
|
601
|
+
goto error;
|
602
|
+
else {
|
603
|
+
giterr_set(GITERR_INVALID, "GIT_COMMON_DIR unimplemented");
|
604
|
+
error = GIT_ERROR;
|
605
|
+
goto error;
|
606
|
+
}
|
607
|
+
|
608
|
+
error = git_repository_open_ext(&repo, start_path, flags, ceiling_dirs);
|
609
|
+
if (error < 0)
|
610
|
+
goto error;
|
611
|
+
|
612
|
+
if (odb)
|
613
|
+
git_repository_set_odb(repo, odb);
|
614
|
+
|
615
|
+
error = git__getenv(&alts_buf, "GIT_ALTERNATE_OBJECT_DIRECTORIES");
|
616
|
+
if (error == GIT_ENOTFOUND)
|
617
|
+
giterr_clear();
|
618
|
+
else if (error < 0)
|
619
|
+
goto error;
|
620
|
+
else {
|
621
|
+
const char *end;
|
622
|
+
char *alt, *sep;
|
623
|
+
if (!odb) {
|
624
|
+
error = git_repository_odb(&odb, repo);
|
625
|
+
if (error < 0)
|
626
|
+
goto error;
|
627
|
+
}
|
628
|
+
|
629
|
+
end = git_buf_cstr(&alts_buf) + git_buf_len(&alts_buf);
|
630
|
+
for (sep = alt = alts_buf.ptr; sep != end; alt = sep+1) {
|
631
|
+
for (sep = alt; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++)
|
632
|
+
;
|
633
|
+
if (*sep)
|
634
|
+
*sep = '\0';
|
635
|
+
error = git_odb_add_disk_alternate(odb, alt);
|
636
|
+
if (error < 0)
|
637
|
+
goto error;
|
638
|
+
}
|
639
|
+
}
|
640
|
+
|
641
|
+
error = git_repository_set_namespace(repo, git_buf_cstr(&namespace_buf));
|
642
|
+
if (error < 0)
|
643
|
+
goto error;
|
644
|
+
|
645
|
+
git_repository_set_index(repo, index);
|
646
|
+
|
647
|
+
if (out) {
|
648
|
+
*out = repo;
|
649
|
+
goto success;
|
650
|
+
}
|
651
|
+
error:
|
652
|
+
git_repository_free(repo);
|
653
|
+
success:
|
654
|
+
git_odb_free(odb);
|
655
|
+
git_index_free(index);
|
656
|
+
git_buf_free(&common_dir_buf);
|
657
|
+
git_buf_free(&work_tree_buf);
|
658
|
+
git_buf_free(&alts_buf);
|
659
|
+
git_buf_free(&object_dir_buf);
|
660
|
+
git_buf_free(&namespace_buf);
|
661
|
+
git_buf_free(&index_file_buf);
|
662
|
+
git_buf_free(&across_fs_buf);
|
663
|
+
git_buf_free(&ceiling_dirs_buf);
|
664
|
+
git_buf_free(&dir_buf);
|
665
|
+
return error;
|
666
|
+
}
|
667
|
+
|
483
668
|
int git_repository_open_ext(
|
484
669
|
git_repository **repo_ptr,
|
485
670
|
const char *start_path,
|
@@ -492,6 +677,9 @@ int git_repository_open_ext(
|
|
492
677
|
git_repository *repo;
|
493
678
|
git_config *config = NULL;
|
494
679
|
|
680
|
+
if (flags & GIT_REPOSITORY_OPEN_FROM_ENV)
|
681
|
+
return _git_repository_open_ext_from_env(repo_ptr, start_path);
|
682
|
+
|
495
683
|
if (repo_ptr)
|
496
684
|
*repo_ptr = NULL;
|
497
685
|
|