rugged 0.26.0b3 → 0.26.0b4
Sign up to get free protection for your applications and to get access to all the features.
- 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);
|