rugged 0.26.0b3 → 0.26.0b4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/ext/rugged/extconf.rb +10 -7
- data/ext/rugged/rugged.c +4 -6
- data/ext/rugged/rugged_repo.c +1 -1
- data/ext/rugged/rugged_revwalk.c +4 -4
- data/ext/rugged/rugged_tree.c +2 -2
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +13 -6
- data/vendor/libgit2/COPYING +33 -0
- data/vendor/libgit2/include/git2/branch.h +12 -0
- data/vendor/libgit2/include/git2/commit.h +6 -3
- data/vendor/libgit2/include/git2/common.h +11 -0
- data/vendor/libgit2/include/git2/errors.h +2 -0
- data/vendor/libgit2/include/git2/index.h +7 -6
- data/vendor/libgit2/include/git2/repository.h +91 -0
- data/vendor/libgit2/include/git2/stash.h +2 -2
- data/vendor/libgit2/include/git2/types.h +3 -0
- data/vendor/libgit2/include/git2/worktree.h +161 -0
- data/vendor/libgit2/src/attr.c +24 -16
- data/vendor/libgit2/src/attr_file.h +1 -1
- data/vendor/libgit2/src/attrcache.c +11 -10
- data/vendor/libgit2/src/attrcache.h +1 -4
- data/vendor/libgit2/src/blob.c +2 -2
- data/vendor/libgit2/src/branch.c +63 -0
- data/vendor/libgit2/src/buffer.h +2 -1
- data/vendor/libgit2/src/cache.c +21 -25
- data/vendor/libgit2/src/cache.h +1 -1
- data/vendor/libgit2/src/checkout.c +0 -2
- data/vendor/libgit2/src/cherrypick.c +2 -2
- data/vendor/libgit2/src/clone.c +2 -3
- data/vendor/libgit2/src/commit.c +8 -4
- data/vendor/libgit2/src/config_file.c +1 -3
- data/vendor/libgit2/src/describe.c +1 -3
- data/vendor/libgit2/src/diff_driver.c +2 -4
- data/vendor/libgit2/src/fetchhead.c +2 -2
- data/vendor/libgit2/src/fileops.c +1 -3
- data/vendor/libgit2/src/hash.h +5 -3
- data/vendor/libgit2/src/hash/hash_collisiondetect.h +57 -0
- data/vendor/libgit2/src/hash/sha1dc/sha1.c +1149 -0
- data/vendor/libgit2/src/hash/sha1dc/sha1.h +94 -0
- data/vendor/libgit2/src/hash/sha1dc/ubc_check.c +361 -0
- data/vendor/libgit2/src/hash/sha1dc/ubc_check.h +35 -0
- data/vendor/libgit2/src/idxmap.c +133 -0
- data/vendor/libgit2/src/idxmap.h +22 -60
- data/vendor/libgit2/src/ignore.c +7 -1
- data/vendor/libgit2/src/ignore.h +1 -1
- data/vendor/libgit2/src/index.c +11 -14
- data/vendor/libgit2/src/indexer.c +8 -11
- data/vendor/libgit2/src/merge.c +5 -5
- data/vendor/libgit2/src/mwindow.c +1 -3
- data/vendor/libgit2/src/odb.c +3 -3
- data/vendor/libgit2/src/odb.h +3 -0
- data/vendor/libgit2/src/odb_mempack.c +11 -18
- data/vendor/libgit2/src/offmap.c +83 -0
- data/vendor/libgit2/src/offmap.h +14 -34
- data/vendor/libgit2/src/oidmap.c +105 -0
- data/vendor/libgit2/src/oidmap.h +19 -22
- data/vendor/libgit2/src/pack-objects.c +10 -13
- data/vendor/libgit2/src/pack.c +17 -26
- data/vendor/libgit2/src/path.c +45 -24
- data/vendor/libgit2/src/rebase.c +3 -3
- data/vendor/libgit2/src/refdb_fs.c +81 -46
- data/vendor/libgit2/src/refs.c +13 -3
- data/vendor/libgit2/src/remote.c +6 -2
- data/vendor/libgit2/src/repository.c +318 -46
- data/vendor/libgit2/src/repository.h +5 -2
- data/vendor/libgit2/src/revert.c +2 -2
- data/vendor/libgit2/src/revwalk.c +6 -8
- data/vendor/libgit2/src/settings.c +5 -0
- data/vendor/libgit2/src/sortedcache.c +3 -5
- data/vendor/libgit2/src/strmap.c +95 -0
- data/vendor/libgit2/src/strmap.h +17 -37
- data/vendor/libgit2/src/submodule.c +12 -8
- data/vendor/libgit2/src/thread-utils.h +6 -0
- data/vendor/libgit2/src/transaction.c +5 -17
- data/vendor/libgit2/src/transports/local.c +2 -1
- data/vendor/libgit2/src/transports/smart.h +2 -0
- data/vendor/libgit2/src/transports/smart_protocol.c +3 -1
- data/vendor/libgit2/src/tree.c +2 -4
- data/vendor/libgit2/src/unix/posix.h +1 -1
- data/vendor/libgit2/src/worktree.c +432 -0
- data/vendor/libgit2/src/worktree.h +35 -0
- metadata +13 -2
data/vendor/libgit2/src/refs.c
CHANGED
@@ -26,8 +26,6 @@
|
|
26
26
|
|
27
27
|
bool git_reference__enable_symbolic_ref_target_validation = true;
|
28
28
|
|
29
|
-
GIT__USE_STRMAP
|
30
|
-
|
31
29
|
#define DEFAULT_NESTING_LEVEL 5
|
32
30
|
#define MAX_NESTING_LEVEL 10
|
33
31
|
|
@@ -1132,6 +1130,18 @@ int git_reference__update_terminal(
|
|
1132
1130
|
return error;
|
1133
1131
|
}
|
1134
1132
|
|
1133
|
+
static const char *commit_type(const git_commit *commit)
|
1134
|
+
{
|
1135
|
+
unsigned int count = git_commit_parentcount(commit);
|
1136
|
+
|
1137
|
+
if (count >= 2)
|
1138
|
+
return " (merge)";
|
1139
|
+
else if (count == 0)
|
1140
|
+
return " (initial)";
|
1141
|
+
else
|
1142
|
+
return "";
|
1143
|
+
}
|
1144
|
+
|
1135
1145
|
int git_reference__update_for_commit(
|
1136
1146
|
git_repository *repo,
|
1137
1147
|
git_reference *ref,
|
@@ -1148,7 +1158,7 @@ int git_reference__update_for_commit(
|
|
1148
1158
|
if ((error = git_commit_lookup(&commit, repo, id)) < 0 ||
|
1149
1159
|
(error = git_buf_printf(&reflog_msg, "%s%s: %s",
|
1150
1160
|
operation ? operation : "commit",
|
1151
|
-
|
1161
|
+
commit_type(commit),
|
1152
1162
|
git_commit_summary(commit))) < 0)
|
1153
1163
|
goto done;
|
1154
1164
|
|
data/vendor/libgit2/src/remote.c
CHANGED
@@ -770,8 +770,12 @@ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_ur
|
|
770
770
|
goto found;
|
771
771
|
}
|
772
772
|
|
773
|
-
/*
|
774
|
-
error = git__getenv(&val, use_ssl ? "
|
773
|
+
/* http_proxy / https_proxy environment variables */
|
774
|
+
error = git__getenv(&val, use_ssl ? "https_proxy" : "http_proxy");
|
775
|
+
|
776
|
+
/* try uppercase environment variables */
|
777
|
+
if (error == GIT_ENOTFOUND)
|
778
|
+
error = git__getenv(&val, use_ssl ? "HTTPS_PROXY" : "HTTP_PROXY");
|
775
779
|
|
776
780
|
if (error < 0) {
|
777
781
|
if (error == GIT_ENOTFOUND) {
|
@@ -28,16 +28,40 @@
|
|
28
28
|
#include "diff_driver.h"
|
29
29
|
#include "annotated_commit.h"
|
30
30
|
#include "submodule.h"
|
31
|
+
#include "worktree.h"
|
31
32
|
|
32
|
-
GIT__USE_STRMAP
|
33
33
|
#include "strmap.h"
|
34
34
|
|
35
35
|
#ifdef GIT_WIN32
|
36
36
|
# include "win32/w32_util.h"
|
37
37
|
#endif
|
38
38
|
|
39
|
+
static const struct {
|
40
|
+
git_repository_item_t parent;
|
41
|
+
const char *name;
|
42
|
+
bool directory;
|
43
|
+
} items[] = {
|
44
|
+
{ GIT_REPOSITORY_ITEM_GITDIR, NULL, true },
|
45
|
+
{ GIT_REPOSITORY_ITEM_WORKDIR, NULL, true },
|
46
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, NULL, true },
|
47
|
+
{ GIT_REPOSITORY_ITEM_GITDIR, "index", false },
|
48
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "objects", true },
|
49
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "refs", true },
|
50
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "packed-refs", false },
|
51
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "remotes", true },
|
52
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "config", false },
|
53
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "info", true },
|
54
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "hooks", true },
|
55
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "logs", true },
|
56
|
+
{ GIT_REPOSITORY_ITEM_GITDIR, "modules", true },
|
57
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "worktrees", true }
|
58
|
+
};
|
59
|
+
|
39
60
|
static int check_repositoryformatversion(git_config *config);
|
40
61
|
|
62
|
+
#define GIT_COMMONDIR_FILE "commondir"
|
63
|
+
#define GIT_GITDIR_FILE "gitdir"
|
64
|
+
|
41
65
|
#define GIT_FILE_CONTENT_PREFIX "gitdir:"
|
42
66
|
|
43
67
|
#define GIT_BRANCH_MASTER "master"
|
@@ -141,8 +165,9 @@ void git_repository_free(git_repository *repo)
|
|
141
165
|
git_buf_free(git_array_get(repo->reserved_names, i));
|
142
166
|
git_array_clear(repo->reserved_names);
|
143
167
|
|
144
|
-
git__free(repo->
|
145
|
-
git__free(repo->
|
168
|
+
git__free(repo->gitlink);
|
169
|
+
git__free(repo->gitdir);
|
170
|
+
git__free(repo->commondir);
|
146
171
|
git__free(repo->workdir);
|
147
172
|
git__free(repo->namespace);
|
148
173
|
git__free(repo->ident_name);
|
@@ -157,17 +182,41 @@ void git_repository_free(git_repository *repo)
|
|
157
182
|
*
|
158
183
|
* Open a repository object from its path
|
159
184
|
*/
|
160
|
-
static bool valid_repository_path(git_buf *repository_path)
|
185
|
+
static bool valid_repository_path(git_buf *repository_path, git_buf *common_path)
|
161
186
|
{
|
162
|
-
/* Check
|
163
|
-
|
164
|
-
|
187
|
+
/* Check if we have a separate commondir (e.g. we have a
|
188
|
+
* worktree) */
|
189
|
+
if (git_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) {
|
190
|
+
git_buf common_link = GIT_BUF_INIT;
|
191
|
+
git_buf_joinpath(&common_link, repository_path->ptr, GIT_COMMONDIR_FILE);
|
192
|
+
|
193
|
+
git_futils_readbuffer(&common_link, common_link.ptr);
|
194
|
+
git_buf_rtrim(&common_link);
|
195
|
+
|
196
|
+
if (git_path_is_relative(common_link.ptr)) {
|
197
|
+
git_buf_joinpath(common_path, repository_path->ptr, common_link.ptr);
|
198
|
+
} else {
|
199
|
+
git_buf_swap(common_path, &common_link);
|
200
|
+
}
|
201
|
+
|
202
|
+
git_buf_free(&common_link);
|
203
|
+
}
|
204
|
+
else {
|
205
|
+
git_buf_set(common_path, repository_path->ptr, repository_path->size);
|
206
|
+
}
|
207
|
+
|
208
|
+
/* Make sure the commondir path always has a trailing * slash */
|
209
|
+
if (git_buf_rfind(common_path, '/') != (ssize_t)common_path->size - 1)
|
210
|
+
git_buf_putc(common_path, '/');
|
165
211
|
|
166
212
|
/* Ensure HEAD file exists */
|
167
213
|
if (git_path_contains_file(repository_path, GIT_HEAD_FILE) == false)
|
168
214
|
return false;
|
169
215
|
|
170
|
-
|
216
|
+
/* Check files in common dir */
|
217
|
+
if (git_path_contains_dir(common_path, GIT_OBJECTS_DIR) == false)
|
218
|
+
return false;
|
219
|
+
if (git_path_contains_dir(common_path, GIT_REFS_DIR) == false)
|
171
220
|
return false;
|
172
221
|
|
173
222
|
return true;
|
@@ -206,6 +255,7 @@ int git_repository_new(git_repository **out)
|
|
206
255
|
GITERR_CHECK_ALLOC(repo);
|
207
256
|
|
208
257
|
repo->is_bare = 1;
|
258
|
+
repo->is_worktree = 0;
|
209
259
|
|
210
260
|
return 0;
|
211
261
|
}
|
@@ -225,9 +275,10 @@ static int load_config_data(git_repository *repo, const git_config *config)
|
|
225
275
|
|
226
276
|
static int load_workdir(git_repository *repo, git_config *config, git_buf *parent_path)
|
227
277
|
{
|
228
|
-
int
|
278
|
+
int error;
|
229
279
|
git_config_entry *ce;
|
230
|
-
git_buf
|
280
|
+
git_buf worktree = GIT_BUF_INIT;
|
281
|
+
git_buf path = GIT_BUF_INIT;
|
231
282
|
|
232
283
|
if (repo->is_bare)
|
233
284
|
return 0;
|
@@ -236,9 +287,26 @@ static int load_workdir(git_repository *repo, git_config *config, git_buf *paren
|
|
236
287
|
&ce, config, "core.worktree", false)) < 0)
|
237
288
|
return error;
|
238
289
|
|
239
|
-
if (
|
290
|
+
if (repo->is_worktree) {
|
291
|
+
char *gitlink = git_worktree__read_link(repo->gitdir, GIT_GITDIR_FILE);
|
292
|
+
if (!gitlink) {
|
293
|
+
error = -1;
|
294
|
+
goto cleanup;
|
295
|
+
}
|
296
|
+
|
297
|
+
git_buf_attach(&worktree, gitlink, 0);
|
298
|
+
|
299
|
+
if ((git_path_dirname_r(&worktree, worktree.ptr)) < 0 ||
|
300
|
+
git_path_to_dir(&worktree) < 0) {
|
301
|
+
error = -1;
|
302
|
+
goto cleanup;
|
303
|
+
}
|
304
|
+
|
305
|
+
repo->workdir = git_buf_detach(&worktree);
|
306
|
+
}
|
307
|
+
else if (ce && ce->value) {
|
240
308
|
if ((error = git_path_prettify_dir(
|
241
|
-
&worktree, ce->value, repo->
|
309
|
+
&worktree, ce->value, repo->gitdir)) < 0)
|
242
310
|
goto cleanup;
|
243
311
|
|
244
312
|
repo->workdir = git_buf_detach(&worktree);
|
@@ -246,7 +314,7 @@ static int load_workdir(git_repository *repo, git_config *config, git_buf *paren
|
|
246
314
|
else if (parent_path && git_path_isdir(parent_path->ptr))
|
247
315
|
repo->workdir = git_buf_detach(parent_path);
|
248
316
|
else {
|
249
|
-
if (git_path_dirname_r(&worktree, repo->
|
317
|
+
if (git_path_dirname_r(&worktree, repo->gitdir) < 0 ||
|
250
318
|
git_path_to_dir(&worktree) < 0) {
|
251
319
|
error = -1;
|
252
320
|
goto cleanup;
|
@@ -257,6 +325,7 @@ static int load_workdir(git_repository *repo, git_config *config, git_buf *paren
|
|
257
325
|
|
258
326
|
GITERR_CHECK_ALLOC(repo->workdir);
|
259
327
|
cleanup:
|
328
|
+
git_buf_free(&path);
|
260
329
|
git_config_entry_free(ce);
|
261
330
|
return error;
|
262
331
|
}
|
@@ -356,6 +425,7 @@ static int find_repo(
|
|
356
425
|
git_buf *repo_path,
|
357
426
|
git_buf *parent_path,
|
358
427
|
git_buf *link_path,
|
428
|
+
git_buf *common_path,
|
359
429
|
const char *start_path,
|
360
430
|
uint32_t flags,
|
361
431
|
const char *ceiling_dirs)
|
@@ -363,6 +433,7 @@ static int find_repo(
|
|
363
433
|
int error;
|
364
434
|
git_buf path = GIT_BUF_INIT;
|
365
435
|
git_buf repo_link = GIT_BUF_INIT;
|
436
|
+
git_buf common_link = GIT_BUF_INIT;
|
366
437
|
struct stat st;
|
367
438
|
dev_t initial_device = 0;
|
368
439
|
int min_iterations;
|
@@ -409,9 +480,16 @@ static int find_repo(
|
|
409
480
|
break;
|
410
481
|
|
411
482
|
if (S_ISDIR(st.st_mode)) {
|
412
|
-
if (valid_repository_path(&path)) {
|
483
|
+
if (valid_repository_path(&path, &common_link)) {
|
413
484
|
git_path_to_dir(&path);
|
414
485
|
git_buf_set(repo_path, path.ptr, path.size);
|
486
|
+
|
487
|
+
if (link_path)
|
488
|
+
git_buf_attach(link_path,
|
489
|
+
git_worktree__read_link(path.ptr, GIT_GITDIR_FILE), 0);
|
490
|
+
if (common_path)
|
491
|
+
git_buf_swap(&common_link, common_path);
|
492
|
+
|
415
493
|
break;
|
416
494
|
}
|
417
495
|
}
|
@@ -419,11 +497,13 @@ static int find_repo(
|
|
419
497
|
error = read_gitfile(&repo_link, path.ptr);
|
420
498
|
if (error < 0)
|
421
499
|
break;
|
422
|
-
if (valid_repository_path(&repo_link)) {
|
500
|
+
if (valid_repository_path(&repo_link, &common_link)) {
|
423
501
|
git_buf_swap(repo_path, &repo_link);
|
424
502
|
|
425
503
|
if (link_path)
|
426
504
|
error = git_buf_put(link_path, path.ptr, path.size);
|
505
|
+
if (common_path)
|
506
|
+
git_buf_swap(&common_link, common_path);
|
427
507
|
}
|
428
508
|
break;
|
429
509
|
}
|
@@ -470,6 +550,7 @@ static int find_repo(
|
|
470
550
|
|
471
551
|
git_buf_free(&path);
|
472
552
|
git_buf_free(&repo_link);
|
553
|
+
git_buf_free(&common_link);
|
473
554
|
return error;
|
474
555
|
}
|
475
556
|
|
@@ -478,14 +559,15 @@ int git_repository_open_bare(
|
|
478
559
|
const char *bare_path)
|
479
560
|
{
|
480
561
|
int error;
|
481
|
-
git_buf path = GIT_BUF_INIT;
|
562
|
+
git_buf path = GIT_BUF_INIT, common_path = GIT_BUF_INIT;
|
482
563
|
git_repository *repo = NULL;
|
483
564
|
|
484
565
|
if ((error = git_path_prettify_dir(&path, bare_path, NULL)) < 0)
|
485
566
|
return error;
|
486
567
|
|
487
|
-
if (!valid_repository_path(&path)) {
|
568
|
+
if (!valid_repository_path(&path, &common_path)) {
|
488
569
|
git_buf_free(&path);
|
570
|
+
git_buf_free(&common_path);
|
489
571
|
giterr_set(GITERR_REPOSITORY, "path is not a repository: %s", bare_path);
|
490
572
|
return GIT_ENOTFOUND;
|
491
573
|
}
|
@@ -493,11 +575,14 @@ int git_repository_open_bare(
|
|
493
575
|
repo = repository_alloc();
|
494
576
|
GITERR_CHECK_ALLOC(repo);
|
495
577
|
|
496
|
-
repo->
|
497
|
-
GITERR_CHECK_ALLOC(repo->
|
578
|
+
repo->gitdir = git_buf_detach(&path);
|
579
|
+
GITERR_CHECK_ALLOC(repo->gitdir);
|
580
|
+
repo->commondir = git_buf_detach(&common_path);
|
581
|
+
GITERR_CHECK_ALLOC(repo->commondir);
|
498
582
|
|
499
583
|
/* of course we're bare! */
|
500
584
|
repo->is_bare = 1;
|
585
|
+
repo->is_worktree = 0;
|
501
586
|
repo->workdir = NULL;
|
502
587
|
|
503
588
|
*repo_ptr = repo;
|
@@ -681,7 +766,7 @@ int git_repository_open_ext(
|
|
681
766
|
{
|
682
767
|
int error;
|
683
768
|
git_buf path = GIT_BUF_INIT, parent = GIT_BUF_INIT,
|
684
|
-
link_path = GIT_BUF_INIT;
|
769
|
+
link_path = GIT_BUF_INIT, common_path = GIT_BUF_INIT;
|
685
770
|
git_repository *repo;
|
686
771
|
git_config *config = NULL;
|
687
772
|
|
@@ -692,7 +777,7 @@ int git_repository_open_ext(
|
|
692
777
|
*repo_ptr = NULL;
|
693
778
|
|
694
779
|
error = find_repo(
|
695
|
-
&path, &parent, &link_path, start_path, flags, ceiling_dirs);
|
780
|
+
&path, &parent, &link_path, &common_path, start_path, flags, ceiling_dirs);
|
696
781
|
|
697
782
|
if (error < 0 || !repo_ptr)
|
698
783
|
return error;
|
@@ -700,13 +785,24 @@ int git_repository_open_ext(
|
|
700
785
|
repo = repository_alloc();
|
701
786
|
GITERR_CHECK_ALLOC(repo);
|
702
787
|
|
703
|
-
repo->
|
704
|
-
GITERR_CHECK_ALLOC(repo->
|
788
|
+
repo->gitdir = git_buf_detach(&path);
|
789
|
+
GITERR_CHECK_ALLOC(repo->gitdir);
|
705
790
|
|
706
791
|
if (link_path.size) {
|
707
|
-
repo->
|
708
|
-
GITERR_CHECK_ALLOC(repo->
|
792
|
+
repo->gitlink = git_buf_detach(&link_path);
|
793
|
+
GITERR_CHECK_ALLOC(repo->gitlink);
|
709
794
|
}
|
795
|
+
if (common_path.size) {
|
796
|
+
repo->commondir = git_buf_detach(&common_path);
|
797
|
+
GITERR_CHECK_ALLOC(repo->commondir);
|
798
|
+
}
|
799
|
+
|
800
|
+
if ((error = git_buf_joinpath(&path, repo->gitdir, "gitdir")) < 0)
|
801
|
+
goto cleanup;
|
802
|
+
/* A 'gitdir' file inside a git directory is currently
|
803
|
+
* only used when the repository is a working tree. */
|
804
|
+
if (git_path_exists(path.ptr))
|
805
|
+
repo->is_worktree = 1;
|
710
806
|
|
711
807
|
/*
|
712
808
|
* We'd like to have the config, but git doesn't particularly
|
@@ -731,6 +827,7 @@ int git_repository_open_ext(
|
|
731
827
|
}
|
732
828
|
|
733
829
|
cleanup:
|
830
|
+
git_buf_free(&path);
|
734
831
|
git_buf_free(&parent);
|
735
832
|
git_config_free(config);
|
736
833
|
|
@@ -748,6 +845,36 @@ int git_repository_open(git_repository **repo_out, const char *path)
|
|
748
845
|
repo_out, path, GIT_REPOSITORY_OPEN_NO_SEARCH, NULL);
|
749
846
|
}
|
750
847
|
|
848
|
+
int git_repository_open_from_worktree(git_repository **repo_out, git_worktree *wt)
|
849
|
+
{
|
850
|
+
git_buf path = GIT_BUF_INIT;
|
851
|
+
git_repository *repo = NULL;
|
852
|
+
int len, err;
|
853
|
+
|
854
|
+
assert(repo_out && wt);
|
855
|
+
|
856
|
+
*repo_out = NULL;
|
857
|
+
len = strlen(wt->gitlink_path);
|
858
|
+
|
859
|
+
if (len <= 4 || strcasecmp(wt->gitlink_path + len - 4, ".git")) {
|
860
|
+
err = -1;
|
861
|
+
goto out;
|
862
|
+
}
|
863
|
+
|
864
|
+
if ((err = git_buf_set(&path, wt->gitlink_path, len - 4)) < 0)
|
865
|
+
goto out;
|
866
|
+
|
867
|
+
if ((err = git_repository_open(&repo, path.ptr)) < 0)
|
868
|
+
goto out;
|
869
|
+
|
870
|
+
*repo_out = repo;
|
871
|
+
|
872
|
+
out:
|
873
|
+
git_buf_free(&path);
|
874
|
+
|
875
|
+
return err;
|
876
|
+
}
|
877
|
+
|
751
878
|
int git_repository_wrap_odb(git_repository **repo_out, git_odb *odb)
|
752
879
|
{
|
753
880
|
git_repository *repo;
|
@@ -773,7 +900,7 @@ int git_repository_discover(
|
|
773
900
|
|
774
901
|
git_buf_sanitize(out);
|
775
902
|
|
776
|
-
return find_repo(out, NULL, NULL, start_path, flags, ceiling_dirs);
|
903
|
+
return find_repo(out, NULL, NULL, NULL, start_path, flags, ceiling_dirs);
|
777
904
|
}
|
778
905
|
|
779
906
|
static int load_config(
|
@@ -793,8 +920,7 @@ static int load_config(
|
|
793
920
|
if ((error = git_config_new(&cfg)) < 0)
|
794
921
|
return error;
|
795
922
|
|
796
|
-
error =
|
797
|
-
&config_path, repo->path_repository, GIT_CONFIG_FILENAME_INREPO);
|
923
|
+
error = git_repository_item_path(&config_path, repo, GIT_REPOSITORY_ITEM_CONFIG);
|
798
924
|
if (error < 0)
|
799
925
|
goto on_error;
|
800
926
|
|
@@ -928,7 +1054,8 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
|
|
928
1054
|
git_buf odb_path = GIT_BUF_INIT;
|
929
1055
|
git_odb *odb;
|
930
1056
|
|
931
|
-
if ((error =
|
1057
|
+
if ((error = git_repository_item_path(&odb_path, repo,
|
1058
|
+
GIT_REPOSITORY_ITEM_OBJECTS)) < 0)
|
932
1059
|
return error;
|
933
1060
|
|
934
1061
|
error = git_odb_open(&odb, odb_path.ptr);
|
@@ -1014,7 +1141,7 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo)
|
|
1014
1141
|
git_buf index_path = GIT_BUF_INIT;
|
1015
1142
|
git_index *index;
|
1016
1143
|
|
1017
|
-
if ((error = git_buf_joinpath(&index_path, repo->
|
1144
|
+
if ((error = git_buf_joinpath(&index_path, repo->gitdir, GIT_INDEX_FILE)) < 0)
|
1018
1145
|
return error;
|
1019
1146
|
|
1020
1147
|
error = git_index_open(&index, index_path.ptr);
|
@@ -1130,13 +1257,13 @@ bool git_repository__reserved_names(
|
|
1130
1257
|
prefixcmp = (error || ignorecase) ? git__prefixcmp_icase :
|
1131
1258
|
git__prefixcmp;
|
1132
1259
|
|
1133
|
-
if (repo->
|
1134
|
-
reserved_names_add8dot3(repo, repo->
|
1260
|
+
if (repo->gitlink &&
|
1261
|
+
reserved_names_add8dot3(repo, repo->gitlink) < 0)
|
1135
1262
|
goto on_error;
|
1136
1263
|
|
1137
|
-
if (repo->
|
1138
|
-
prefixcmp(repo->
|
1139
|
-
reserved_names_add8dot3(repo, repo->
|
1264
|
+
if (repo->gitdir &&
|
1265
|
+
prefixcmp(repo->gitdir, repo->workdir) == 0 &&
|
1266
|
+
reserved_names_add8dot3(repo, repo->gitdir) < 0)
|
1140
1267
|
goto on_error;
|
1141
1268
|
}
|
1142
1269
|
}
|
@@ -1193,7 +1320,7 @@ static int check_repositoryformatversion(git_config *config)
|
|
1193
1320
|
return 0;
|
1194
1321
|
}
|
1195
1322
|
|
1196
|
-
|
1323
|
+
int git_repository_create_head(const char *git_dir, const char *ref_name)
|
1197
1324
|
{
|
1198
1325
|
git_buf ref_path = GIT_BUF_INIT;
|
1199
1326
|
git_filebuf ref = GIT_FILEBUF_INIT;
|
@@ -1856,7 +1983,8 @@ int git_repository_init_ext(
|
|
1856
1983
|
git_repository_init_options *opts)
|
1857
1984
|
{
|
1858
1985
|
int error;
|
1859
|
-
git_buf repo_path = GIT_BUF_INIT, wd_path = GIT_BUF_INIT
|
1986
|
+
git_buf repo_path = GIT_BUF_INIT, wd_path = GIT_BUF_INIT,
|
1987
|
+
common_path = GIT_BUF_INIT;
|
1860
1988
|
const char *wd;
|
1861
1989
|
|
1862
1990
|
assert(out && given_repo && opts);
|
@@ -1868,7 +1996,7 @@ int git_repository_init_ext(
|
|
1868
1996
|
goto cleanup;
|
1869
1997
|
|
1870
1998
|
wd = (opts->flags & GIT_REPOSITORY_INIT_BARE) ? NULL : git_buf_cstr(&wd_path);
|
1871
|
-
if (valid_repository_path(&repo_path)) {
|
1999
|
+
if (valid_repository_path(&repo_path, &common_path)) {
|
1872
2000
|
|
1873
2001
|
if ((opts->flags & GIT_REPOSITORY_INIT_NO_REINIT) != 0) {
|
1874
2002
|
giterr_set(GITERR_REPOSITORY,
|
@@ -1889,7 +2017,7 @@ int git_repository_init_ext(
|
|
1889
2017
|
repo_path.ptr, wd, opts)) &&
|
1890
2018
|
!(error = repo_init_config(
|
1891
2019
|
repo_path.ptr, wd, opts->flags, opts->mode)))
|
1892
|
-
error =
|
2020
|
+
error = git_repository_create_head(
|
1893
2021
|
repo_path.ptr, opts->initial_head);
|
1894
2022
|
}
|
1895
2023
|
if (error < 0)
|
@@ -1901,6 +2029,7 @@ int git_repository_init_ext(
|
|
1901
2029
|
error = repo_init_create_origin(*out, opts->origin_url);
|
1902
2030
|
|
1903
2031
|
cleanup:
|
2032
|
+
git_buf_free(&common_path);
|
1904
2033
|
git_buf_free(&repo_path);
|
1905
2034
|
git_buf_free(&wd_path);
|
1906
2035
|
|
@@ -1930,6 +2059,49 @@ int git_repository_head_detached(git_repository *repo)
|
|
1930
2059
|
return exists;
|
1931
2060
|
}
|
1932
2061
|
|
2062
|
+
static int read_worktree_head(git_buf *out, git_repository *repo, const char *name)
|
2063
|
+
{
|
2064
|
+
git_buf path = GIT_BUF_INIT;
|
2065
|
+
int err;
|
2066
|
+
|
2067
|
+
assert(out && repo && name);
|
2068
|
+
|
2069
|
+
git_buf_clear(out);
|
2070
|
+
|
2071
|
+
if ((err = git_buf_printf(&path, "%s/worktrees/%s/HEAD", repo->commondir, name)) < 0)
|
2072
|
+
goto out;
|
2073
|
+
if (!git_path_exists(path.ptr))
|
2074
|
+
{
|
2075
|
+
err = -1;
|
2076
|
+
goto out;
|
2077
|
+
}
|
2078
|
+
|
2079
|
+
if ((err = git_futils_readbuffer(out, path.ptr)) < 0)
|
2080
|
+
goto out;
|
2081
|
+
git_buf_rtrim(out);
|
2082
|
+
|
2083
|
+
out:
|
2084
|
+
git_buf_free(&path);
|
2085
|
+
|
2086
|
+
return err;
|
2087
|
+
}
|
2088
|
+
|
2089
|
+
int git_repository_head_detached_for_worktree(git_repository *repo, const char *name)
|
2090
|
+
{
|
2091
|
+
git_buf buf = GIT_BUF_INIT;
|
2092
|
+
int ret;
|
2093
|
+
|
2094
|
+
assert(repo && name);
|
2095
|
+
|
2096
|
+
if (read_worktree_head(&buf, repo, name) < 0)
|
2097
|
+
return -1;
|
2098
|
+
|
2099
|
+
ret = git__strncmp(buf.ptr, GIT_SYMREF, strlen(GIT_SYMREF)) != 0;
|
2100
|
+
git_buf_free(&buf);
|
2101
|
+
|
2102
|
+
return ret;
|
2103
|
+
}
|
2104
|
+
|
1933
2105
|
int git_repository_head(git_reference **head_out, git_repository *repo)
|
1934
2106
|
{
|
1935
2107
|
git_reference *head;
|
@@ -1949,6 +2121,48 @@ int git_repository_head(git_reference **head_out, git_repository *repo)
|
|
1949
2121
|
return error == GIT_ENOTFOUND ? GIT_EUNBORNBRANCH : error;
|
1950
2122
|
}
|
1951
2123
|
|
2124
|
+
int git_repository_head_for_worktree(git_reference **out, git_repository *repo, const char *name)
|
2125
|
+
{
|
2126
|
+
git_buf buf = GIT_BUF_INIT;
|
2127
|
+
git_reference *head;
|
2128
|
+
int err;
|
2129
|
+
|
2130
|
+
assert(out && repo && name);
|
2131
|
+
|
2132
|
+
*out = NULL;
|
2133
|
+
|
2134
|
+
if (git_repository_head_detached_for_worktree(repo, name))
|
2135
|
+
return -1;
|
2136
|
+
if ((err = read_worktree_head(&buf, repo, name)) < 0)
|
2137
|
+
goto out;
|
2138
|
+
|
2139
|
+
/* We can only resolve symbolic references */
|
2140
|
+
if (git__strncmp(buf.ptr, GIT_SYMREF, strlen(GIT_SYMREF)))
|
2141
|
+
{
|
2142
|
+
err = -1;
|
2143
|
+
goto out;
|
2144
|
+
}
|
2145
|
+
git_buf_consume(&buf, buf.ptr + strlen(GIT_SYMREF));
|
2146
|
+
|
2147
|
+
if ((err = git_reference_lookup(&head, repo, buf.ptr)) < 0)
|
2148
|
+
goto out;
|
2149
|
+
if (git_reference_type(head) == GIT_REF_OID)
|
2150
|
+
{
|
2151
|
+
*out = head;
|
2152
|
+
err = 0;
|
2153
|
+
goto out;
|
2154
|
+
}
|
2155
|
+
|
2156
|
+
err = git_reference_lookup_resolved(
|
2157
|
+
out, repo, git_reference_symbolic_target(head), -1);
|
2158
|
+
git_reference_free(head);
|
2159
|
+
|
2160
|
+
out:
|
2161
|
+
git_buf_free(&buf);
|
2162
|
+
|
2163
|
+
return err;
|
2164
|
+
}
|
2165
|
+
|
1952
2166
|
int git_repository_head_unborn(git_repository *repo)
|
1953
2167
|
{
|
1954
2168
|
git_reference *ref = NULL;
|
@@ -2007,10 +2221,50 @@ int git_repository_is_empty(git_repository *repo)
|
|
2007
2221
|
return is_empty;
|
2008
2222
|
}
|
2009
2223
|
|
2224
|
+
int git_repository_item_path(git_buf *out, git_repository *repo, git_repository_item_t item)
|
2225
|
+
{
|
2226
|
+
const char *parent;
|
2227
|
+
|
2228
|
+
switch (items[item].parent) {
|
2229
|
+
case GIT_REPOSITORY_ITEM_GITDIR:
|
2230
|
+
parent = git_repository_path(repo);
|
2231
|
+
break;
|
2232
|
+
case GIT_REPOSITORY_ITEM_WORKDIR:
|
2233
|
+
parent = git_repository_workdir(repo);
|
2234
|
+
break;
|
2235
|
+
case GIT_REPOSITORY_ITEM_COMMONDIR:
|
2236
|
+
parent = git_repository_commondir(repo);
|
2237
|
+
break;
|
2238
|
+
default:
|
2239
|
+
giterr_set(GITERR_INVALID, "Invalid item directory");
|
2240
|
+
return -1;
|
2241
|
+
}
|
2242
|
+
|
2243
|
+
if (parent == NULL) {
|
2244
|
+
giterr_set(GITERR_INVALID, "Path cannot exist in repository");
|
2245
|
+
return -1;
|
2246
|
+
}
|
2247
|
+
|
2248
|
+
if (git_buf_sets(out, parent) < 0)
|
2249
|
+
return -1;
|
2250
|
+
|
2251
|
+
if (items[item].name) {
|
2252
|
+
if (git_buf_joinpath(out, parent, items[item].name) < 0)
|
2253
|
+
return -1;
|
2254
|
+
}
|
2255
|
+
|
2256
|
+
if (items[item].directory) {
|
2257
|
+
if (git_path_to_dir(out) < 0)
|
2258
|
+
return -1;
|
2259
|
+
}
|
2260
|
+
|
2261
|
+
return 0;
|
2262
|
+
}
|
2263
|
+
|
2010
2264
|
const char *git_repository_path(git_repository *repo)
|
2011
2265
|
{
|
2012
2266
|
assert(repo);
|
2013
|
-
return repo->
|
2267
|
+
return repo->gitdir;
|
2014
2268
|
}
|
2015
2269
|
|
2016
2270
|
const char *git_repository_workdir(git_repository *repo)
|
@@ -2023,6 +2277,12 @@ const char *git_repository_workdir(git_repository *repo)
|
|
2023
2277
|
return repo->workdir;
|
2024
2278
|
}
|
2025
2279
|
|
2280
|
+
const char *git_repository_commondir(git_repository *repo)
|
2281
|
+
{
|
2282
|
+
assert(repo);
|
2283
|
+
return repo->commondir;
|
2284
|
+
}
|
2285
|
+
|
2026
2286
|
int git_repository_set_workdir(
|
2027
2287
|
git_repository *repo, const char *workdir, int update_gitlink)
|
2028
2288
|
{
|
@@ -2073,6 +2333,12 @@ int git_repository_is_bare(git_repository *repo)
|
|
2073
2333
|
return repo->is_bare;
|
2074
2334
|
}
|
2075
2335
|
|
2336
|
+
int git_repository_is_worktree(git_repository *repo)
|
2337
|
+
{
|
2338
|
+
assert(repo);
|
2339
|
+
return repo->is_worktree;
|
2340
|
+
}
|
2341
|
+
|
2076
2342
|
int git_repository_set_bare(git_repository *repo)
|
2077
2343
|
{
|
2078
2344
|
int error;
|
@@ -2127,7 +2393,7 @@ int git_repository__set_orig_head(git_repository *repo, const git_oid *orig_head
|
|
2127
2393
|
|
2128
2394
|
git_oid_fmt(orig_head_str, orig_head);
|
2129
2395
|
|
2130
|
-
if ((error = git_buf_joinpath(&file_path, repo->
|
2396
|
+
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_ORIG_HEAD_FILE)) == 0 &&
|
2131
2397
|
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_MERGE_FILE_MODE)) == 0 &&
|
2132
2398
|
(error = git_filebuf_printf(&file, "%.*s\n", GIT_OID_HEXSZ, orig_head_str)) == 0)
|
2133
2399
|
error = git_filebuf_commit(&file);
|
@@ -2148,7 +2414,7 @@ int git_repository_message(git_buf *out, git_repository *repo)
|
|
2148
2414
|
|
2149
2415
|
git_buf_sanitize(out);
|
2150
2416
|
|
2151
|
-
if (git_buf_joinpath(&path, repo->
|
2417
|
+
if (git_buf_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0)
|
2152
2418
|
return -1;
|
2153
2419
|
|
2154
2420
|
if ((error = p_stat(git_buf_cstr(&path), &st)) < 0) {
|
@@ -2169,7 +2435,7 @@ int git_repository_message_remove(git_repository *repo)
|
|
2169
2435
|
git_buf path = GIT_BUF_INIT;
|
2170
2436
|
int error;
|
2171
2437
|
|
2172
|
-
if (git_buf_joinpath(&path, repo->
|
2438
|
+
if (git_buf_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0)
|
2173
2439
|
return -1;
|
2174
2440
|
|
2175
2441
|
error = p_unlink(git_buf_cstr(&path));
|
@@ -2290,6 +2556,12 @@ int git_repository_set_head(
|
|
2290
2556
|
if (error < 0 && error != GIT_ENOTFOUND)
|
2291
2557
|
goto cleanup;
|
2292
2558
|
|
2559
|
+
if (ref && current->type == GIT_REF_SYMBOLIC && git__strcmp(current->target.symbolic, ref->name) &&
|
2560
|
+
git_reference_is_branch(ref) && git_branch_is_checked_out(ref)) {
|
2561
|
+
error = -1;
|
2562
|
+
goto cleanup;
|
2563
|
+
}
|
2564
|
+
|
2293
2565
|
if (!error) {
|
2294
2566
|
if (git_reference_is_branch(ref)) {
|
2295
2567
|
error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE,
|
@@ -2405,7 +2677,7 @@ int git_repository_state(git_repository *repo)
|
|
2405
2677
|
|
2406
2678
|
assert(repo);
|
2407
2679
|
|
2408
|
-
if (git_buf_puts(&repo_path, repo->
|
2680
|
+
if (git_buf_puts(&repo_path, repo->gitdir) < 0)
|
2409
2681
|
return -1;
|
2410
2682
|
|
2411
2683
|
if (git_path_contains_file(&repo_path, GIT_REBASE_MERGE_INTERACTIVE_FILE))
|
@@ -2447,7 +2719,7 @@ int git_repository__cleanup_files(
|
|
2447
2719
|
for (error = 0, i = 0; !error && i < files_len; ++i) {
|
2448
2720
|
const char *path;
|
2449
2721
|
|
2450
|
-
if (git_buf_joinpath(&buf, repo->
|
2722
|
+
if (git_buf_joinpath(&buf, repo->gitdir, files[i]) < 0)
|
2451
2723
|
return -1;
|
2452
2724
|
|
2453
2725
|
path = git_buf_cstr(&buf);
|
@@ -2491,7 +2763,7 @@ int git_repository_is_shallow(git_repository *repo)
|
|
2491
2763
|
struct stat st;
|
2492
2764
|
int error;
|
2493
2765
|
|
2494
|
-
if ((error = git_buf_joinpath(&path, repo->
|
2766
|
+
if ((error = git_buf_joinpath(&path, repo->gitdir, "shallow")) < 0)
|
2495
2767
|
return error;
|
2496
2768
|
|
2497
2769
|
error = git_path_lstat(path.ptr, &st);
|