rugged 0.26.0b5 → 0.26.0
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.c +24 -0
- data/ext/rugged/rugged.h +2 -0
- data/ext/rugged/rugged_signature.c +15 -2
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +9 -8
- data/vendor/libgit2/include/git2/common.h +29 -0
- data/vendor/libgit2/include/git2/errors.h +2 -0
- data/vendor/libgit2/include/git2/global.h +1 -1
- data/vendor/libgit2/include/git2/odb.h +2 -2
- data/vendor/libgit2/include/git2/odb_backend.h +1 -1
- data/vendor/libgit2/include/git2/remote.h +3 -3
- data/vendor/libgit2/include/git2/repository.h +2 -2
- data/vendor/libgit2/include/git2/sys/filter.h +11 -0
- data/vendor/libgit2/include/git2/sys/merge.h +5 -5
- data/vendor/libgit2/include/git2/sys/transport.h +10 -0
- data/vendor/libgit2/include/git2/transport.h +6 -6
- data/vendor/libgit2/include/git2/version.h +3 -3
- data/vendor/libgit2/include/git2/worktree.h +69 -10
- data/vendor/libgit2/libgit2.pc.in +2 -2
- data/vendor/libgit2/src/attr_file.c +6 -2
- data/vendor/libgit2/src/attrcache.c +7 -5
- data/vendor/libgit2/src/blame_git.c +12 -8
- data/vendor/libgit2/src/branch.c +17 -48
- data/vendor/libgit2/src/buffer.c +11 -12
- data/vendor/libgit2/src/buffer.h +2 -2
- data/vendor/libgit2/src/checkout.c +3 -6
- data/vendor/libgit2/src/config.c +42 -35
- data/vendor/libgit2/src/config_cache.c +1 -0
- data/vendor/libgit2/src/config_file.c +19 -11
- data/vendor/libgit2/src/config_file.h +1 -0
- data/vendor/libgit2/src/diff.c +35 -0
- data/vendor/libgit2/src/diff_parse.c +7 -1
- data/vendor/libgit2/src/filebuf.c +12 -1
- data/vendor/libgit2/src/filebuf.h +3 -1
- data/vendor/libgit2/src/fileops.c +83 -22
- data/vendor/libgit2/src/fileops.h +25 -0
- data/vendor/libgit2/src/filter.c +30 -14
- data/vendor/libgit2/src/global.c +1 -1
- data/vendor/libgit2/src/hash/hash_collisiondetect.h +1 -11
- data/vendor/libgit2/src/hash/sha1dc/sha1.c +894 -187
- data/vendor/libgit2/src/hash/sha1dc/sha1.h +69 -53
- data/vendor/libgit2/src/hash/sha1dc/ubc_check.c +13 -2
- data/vendor/libgit2/src/hash/sha1dc/ubc_check.h +20 -3
- data/vendor/libgit2/src/idxmap.c +1 -1
- data/vendor/libgit2/src/idxmap.h +1 -2
- data/vendor/libgit2/src/index.c +75 -42
- data/vendor/libgit2/src/indexer.c +31 -11
- data/vendor/libgit2/src/indexer.h +12 -0
- data/vendor/libgit2/src/merge.c +20 -0
- data/vendor/libgit2/src/merge_driver.c +29 -0
- data/vendor/libgit2/src/odb.c +96 -19
- data/vendor/libgit2/src/odb.h +25 -0
- data/vendor/libgit2/src/odb_loose.c +20 -6
- data/vendor/libgit2/src/odb_pack.c +1 -1
- data/vendor/libgit2/src/offmap.c +1 -1
- data/vendor/libgit2/src/offmap.h +1 -2
- data/vendor/libgit2/src/oidmap.c +1 -1
- data/vendor/libgit2/src/oidmap.h +1 -2
- data/vendor/libgit2/src/openssl_stream.c +11 -4
- data/vendor/libgit2/src/pack-objects.c +4 -0
- data/vendor/libgit2/src/pack-objects.h +1 -0
- data/vendor/libgit2/src/pack.c +5 -3
- data/vendor/libgit2/src/patch_generate.c +8 -79
- data/vendor/libgit2/src/patch_parse.c +5 -4
- data/vendor/libgit2/src/path.c +9 -7
- data/vendor/libgit2/src/posix.c +2 -0
- data/vendor/libgit2/src/posix.h +10 -0
- data/vendor/libgit2/src/rebase.c +12 -10
- data/vendor/libgit2/src/refdb_fs.c +33 -10
- data/vendor/libgit2/src/refs.c +89 -8
- data/vendor/libgit2/src/refs.h +14 -0
- data/vendor/libgit2/src/remote.c +9 -10
- data/vendor/libgit2/src/repository.c +178 -146
- data/vendor/libgit2/src/repository.h +25 -0
- data/vendor/libgit2/src/revparse.c +22 -3
- data/vendor/libgit2/src/revwalk.c +6 -3
- data/vendor/libgit2/src/settings.c +22 -1
- data/vendor/libgit2/src/signature.c +4 -1
- data/vendor/libgit2/src/socket_stream.c +2 -4
- data/vendor/libgit2/src/strmap.c +1 -1
- data/vendor/libgit2/src/strmap.h +1 -3
- data/vendor/libgit2/src/submodule.c +27 -7
- data/vendor/libgit2/src/sysdir.c +11 -0
- data/vendor/libgit2/src/sysdir.h +12 -0
- data/vendor/libgit2/src/transports/http.c +3 -0
- data/vendor/libgit2/src/transports/smart.c +6 -0
- data/vendor/libgit2/src/transports/smart_protocol.c +2 -1
- data/vendor/libgit2/src/transports/ssh.c +13 -1
- data/vendor/libgit2/src/transports/winhttp.c +1 -2
- data/vendor/libgit2/src/tree.c +13 -11
- data/vendor/libgit2/src/unix/posix.h +6 -1
- data/vendor/libgit2/src/varint.c +1 -1
- data/vendor/libgit2/src/win32/posix.h +3 -0
- data/vendor/libgit2/src/win32/posix_w32.c +334 -111
- data/vendor/libgit2/src/worktree.c +174 -48
- data/vendor/libgit2/src/worktree.h +1 -1
- metadata +77 -76
@@ -62,6 +62,7 @@ typedef struct refdb_fs_backend {
|
|
62
62
|
int peeling_mode;
|
63
63
|
git_iterator_flag_t iterator_flags;
|
64
64
|
uint32_t direach_flags;
|
65
|
+
int fsync;
|
65
66
|
} refdb_fs_backend;
|
66
67
|
|
67
68
|
static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name);
|
@@ -736,8 +737,9 @@ static int reference_path_available(
|
|
736
737
|
|
737
738
|
static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *name)
|
738
739
|
{
|
739
|
-
int error;
|
740
|
+
int error, filebuf_flags;
|
740
741
|
git_buf ref_path = GIT_BUF_INIT;
|
742
|
+
const char *basedir;
|
741
743
|
|
742
744
|
assert(file && backend && name);
|
743
745
|
|
@@ -746,16 +748,25 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *
|
|
746
748
|
return GIT_EINVALIDSPEC;
|
747
749
|
}
|
748
750
|
|
751
|
+
if (is_per_worktree_ref(name))
|
752
|
+
basedir = backend->gitpath;
|
753
|
+
else
|
754
|
+
basedir = backend->commonpath;
|
755
|
+
|
749
756
|
/* Remove a possibly existing empty directory hierarchy
|
750
757
|
* which name would collide with the reference name
|
751
758
|
*/
|
752
|
-
if ((error = git_futils_rmdir_r(name,
|
759
|
+
if ((error = git_futils_rmdir_r(name, basedir, GIT_RMDIR_SKIP_NONEMPTY)) < 0)
|
753
760
|
return error;
|
754
761
|
|
755
|
-
if (git_buf_joinpath(&ref_path,
|
762
|
+
if (git_buf_joinpath(&ref_path, basedir, name) < 0)
|
756
763
|
return -1;
|
757
764
|
|
758
|
-
|
765
|
+
filebuf_flags = GIT_FILEBUF_FORCE;
|
766
|
+
if (backend->fsync)
|
767
|
+
filebuf_flags |= GIT_FILEBUF_FSYNC;
|
768
|
+
|
769
|
+
error = git_filebuf_open(file, ref_path.ptr, filebuf_flags, GIT_REFS_FILE_MODE);
|
759
770
|
|
760
771
|
if (error == GIT_EDIRECTORY)
|
761
772
|
giterr_set(GITERR_REFERENCE, "cannot lock ref '%s', there are refs beneath that folder", name);
|
@@ -990,15 +1001,18 @@ static int packed_write(refdb_fs_backend *backend)
|
|
990
1001
|
{
|
991
1002
|
git_sortedcache *refcache = backend->refcache;
|
992
1003
|
git_filebuf pack_file = GIT_FILEBUF_INIT;
|
993
|
-
int error;
|
1004
|
+
int error, open_flags = 0;
|
994
1005
|
size_t i;
|
995
1006
|
|
996
1007
|
/* lock the cache to updates while we do this */
|
997
1008
|
if ((error = git_sortedcache_wlock(refcache)) < 0)
|
998
1009
|
return error;
|
999
1010
|
|
1011
|
+
if (backend->fsync)
|
1012
|
+
open_flags = GIT_FILEBUF_FSYNC;
|
1013
|
+
|
1000
1014
|
/* Open the file! */
|
1001
|
-
if ((error = git_filebuf_open(&pack_file, git_sortedcache_path(refcache),
|
1015
|
+
if ((error = git_filebuf_open(&pack_file, git_sortedcache_path(refcache), open_flags, GIT_PACKEDREFS_FILE_MODE)) < 0)
|
1002
1016
|
goto fail;
|
1003
1017
|
|
1004
1018
|
/* Packfiles have a header... apparently
|
@@ -1126,7 +1140,7 @@ out:
|
|
1126
1140
|
static int maybe_append_head(refdb_fs_backend *backend, const git_reference *ref, const git_signature *who, const char *message)
|
1127
1141
|
{
|
1128
1142
|
int error;
|
1129
|
-
git_oid old_id
|
1143
|
+
git_oid old_id;
|
1130
1144
|
git_reference *tmp = NULL, *head = NULL, *peeled = NULL;
|
1131
1145
|
const char *name;
|
1132
1146
|
|
@@ -1134,7 +1148,8 @@ static int maybe_append_head(refdb_fs_backend *backend, const git_reference *ref
|
|
1134
1148
|
return 0;
|
1135
1149
|
|
1136
1150
|
/* if we can't resolve, we use {0}*40 as old id */
|
1137
|
-
git_reference_name_to_id(&old_id, backend->repo, ref->name)
|
1151
|
+
if (git_reference_name_to_id(&old_id, backend->repo, ref->name) < 0)
|
1152
|
+
memset(&old_id, 0, sizeof(old_id));
|
1138
1153
|
|
1139
1154
|
if ((error = git_reference_lookup(&head, backend->repo, GIT_HEAD_FILE)) < 0)
|
1140
1155
|
return error;
|
@@ -1786,7 +1801,7 @@ success:
|
|
1786
1801
|
/* Append to the reflog, must be called under reference lock */
|
1787
1802
|
static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, const git_oid *old, const git_oid *new, const git_signature *who, const char *message)
|
1788
1803
|
{
|
1789
|
-
int error, is_symbolic;
|
1804
|
+
int error, is_symbolic, open_flags;
|
1790
1805
|
git_oid old_id = {{0}}, new_id = {{0}};
|
1791
1806
|
git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT;
|
1792
1807
|
git_repository *repo = backend->repo;
|
@@ -1854,7 +1869,12 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co
|
|
1854
1869
|
goto cleanup;
|
1855
1870
|
}
|
1856
1871
|
|
1857
|
-
|
1872
|
+
open_flags = O_WRONLY | O_CREAT | O_APPEND;
|
1873
|
+
|
1874
|
+
if (backend->fsync)
|
1875
|
+
open_flags |= O_FSYNC;
|
1876
|
+
|
1877
|
+
error = git_futils_writebuffer(&buf, git_buf_cstr(&path), open_flags, GIT_REFLOG_FILE_MODE);
|
1858
1878
|
|
1859
1879
|
cleanup:
|
1860
1880
|
git_buf_free(&buf);
|
@@ -2011,6 +2031,9 @@ int git_refdb_backend_fs(
|
|
2011
2031
|
backend->iterator_flags |= GIT_ITERATOR_PRECOMPOSE_UNICODE;
|
2012
2032
|
backend->direach_flags |= GIT_PATH_DIR_PRECOMPOSE_UNICODE;
|
2013
2033
|
}
|
2034
|
+
if ((!git_repository__cvar(&t, backend->repo, GIT_CVAR_FSYNCOBJECTFILES) && t) ||
|
2035
|
+
git_repository__fsync_gitdir)
|
2036
|
+
backend->fsync = 1;
|
2014
2037
|
|
2015
2038
|
backend->parent.exists = &refdb_fs_backend__exists;
|
2016
2039
|
backend->parent.lookup = &refdb_fs_backend__lookup;
|
data/vendor/libgit2/src/refs.c
CHANGED
@@ -249,6 +249,40 @@ int git_reference_lookup_resolved(
|
|
249
249
|
return 0;
|
250
250
|
}
|
251
251
|
|
252
|
+
int git_reference__read_head(
|
253
|
+
git_reference **out,
|
254
|
+
git_repository *repo,
|
255
|
+
const char *path)
|
256
|
+
{
|
257
|
+
git_buf reference = GIT_BUF_INIT;
|
258
|
+
char *name = NULL;
|
259
|
+
int error;
|
260
|
+
|
261
|
+
if ((error = git_futils_readbuffer(&reference, path)) < 0)
|
262
|
+
goto out;
|
263
|
+
git_buf_rtrim(&reference);
|
264
|
+
|
265
|
+
if (git__strncmp(reference.ptr, GIT_SYMREF, strlen(GIT_SYMREF)) == 0) {
|
266
|
+
git_buf_consume(&reference, reference.ptr + strlen(GIT_SYMREF));
|
267
|
+
|
268
|
+
name = git_path_basename(path);
|
269
|
+
|
270
|
+
if ((*out = git_reference__alloc_symbolic(name, reference.ptr)) == NULL) {
|
271
|
+
error = -1;
|
272
|
+
goto out;
|
273
|
+
}
|
274
|
+
} else {
|
275
|
+
if ((error = git_reference_lookup(out, repo, reference.ptr)) < 0)
|
276
|
+
goto out;
|
277
|
+
}
|
278
|
+
|
279
|
+
out:
|
280
|
+
git__free(name);
|
281
|
+
git_buf_free(&reference);
|
282
|
+
|
283
|
+
return error;
|
284
|
+
}
|
285
|
+
|
252
286
|
int git_reference_dwim(git_reference **out, git_repository *repo, const char *refname)
|
253
287
|
{
|
254
288
|
int error = 0, i;
|
@@ -580,20 +614,63 @@ int git_reference_symbolic_set_target(
|
|
580
614
|
out, ref->db->repo, ref->name, target, 1, ref->target.symbolic, log_message);
|
581
615
|
}
|
582
616
|
|
617
|
+
typedef struct {
|
618
|
+
const char *old_name;
|
619
|
+
git_refname_t new_name;
|
620
|
+
} rename_cb_data;
|
621
|
+
|
622
|
+
static int update_wt_heads(git_repository *repo, const char *path, void *payload)
|
623
|
+
{
|
624
|
+
rename_cb_data *data = (rename_cb_data *) payload;
|
625
|
+
git_reference *head = NULL;
|
626
|
+
char *gitdir = NULL;
|
627
|
+
int error;
|
628
|
+
|
629
|
+
if ((error = git_reference__read_head(&head, repo, path)) < 0) {
|
630
|
+
giterr_set(GITERR_REFERENCE, "could not read HEAD when renaming references");
|
631
|
+
goto out;
|
632
|
+
}
|
633
|
+
|
634
|
+
if ((gitdir = git_path_dirname(path)) == NULL) {
|
635
|
+
error = -1;
|
636
|
+
goto out;
|
637
|
+
}
|
638
|
+
|
639
|
+
if (git_reference_type(head) != GIT_REF_SYMBOLIC ||
|
640
|
+
git__strcmp(head->target.symbolic, data->old_name) != 0) {
|
641
|
+
error = 0;
|
642
|
+
goto out;
|
643
|
+
}
|
644
|
+
|
645
|
+
/* Update HEAD it was pointing to the reference being renamed */
|
646
|
+
if ((error = git_repository_create_head(gitdir, data->new_name)) < 0) {
|
647
|
+
giterr_set(GITERR_REFERENCE, "failed to update HEAD after renaming reference");
|
648
|
+
goto out;
|
649
|
+
}
|
650
|
+
|
651
|
+
out:
|
652
|
+
git_reference_free(head);
|
653
|
+
git__free(gitdir);
|
654
|
+
|
655
|
+
return error;
|
656
|
+
}
|
657
|
+
|
583
658
|
static int reference__rename(git_reference **out, git_reference *ref, const char *new_name, int force,
|
584
659
|
const git_signature *signature, const char *message)
|
585
660
|
{
|
661
|
+
git_repository *repo;
|
586
662
|
git_refname_t normalized;
|
587
663
|
bool should_head_be_updated = false;
|
588
664
|
int error = 0;
|
589
665
|
|
590
666
|
assert(ref && new_name && signature);
|
591
667
|
|
668
|
+
repo = git_reference_owner(ref);
|
669
|
+
|
592
670
|
if ((error = reference_normalize_for_repo(
|
593
|
-
normalized,
|
671
|
+
normalized, repo, new_name, true)) < 0)
|
594
672
|
return error;
|
595
673
|
|
596
|
-
|
597
674
|
/* Check if we have to update HEAD. */
|
598
675
|
if ((error = git_branch_is_head(ref)) < 0)
|
599
676
|
return error;
|
@@ -603,14 +680,18 @@ static int reference__rename(git_reference **out, git_reference *ref, const char
|
|
603
680
|
if ((error = git_refdb_rename(out, ref->db, ref->name, normalized, force, signature, message)) < 0)
|
604
681
|
return error;
|
605
682
|
|
606
|
-
/* Update HEAD it was pointing to the reference being renamed */
|
607
|
-
if (should_head_be_updated
|
608
|
-
|
609
|
-
|
610
|
-
|
683
|
+
/* Update HEAD if it was pointing to the reference being renamed */
|
684
|
+
if (should_head_be_updated) {
|
685
|
+
error = git_repository_set_head(ref->db->repo, normalized);
|
686
|
+
} else {
|
687
|
+
rename_cb_data payload;
|
688
|
+
payload.old_name = ref->name;
|
689
|
+
memcpy(&payload.new_name, &normalized, sizeof(normalized));
|
690
|
+
|
691
|
+
error = git_repository_foreach_head(repo, update_wt_heads, &payload);
|
611
692
|
}
|
612
693
|
|
613
|
-
return
|
694
|
+
return error;
|
614
695
|
}
|
615
696
|
|
616
697
|
|
data/vendor/libgit2/src/refs.h
CHANGED
@@ -107,6 +107,20 @@ int git_reference_lookup_resolved(
|
|
107
107
|
const char *name,
|
108
108
|
int max_deref);
|
109
109
|
|
110
|
+
/**
|
111
|
+
* Read reference from a file.
|
112
|
+
*
|
113
|
+
* This function will read in the file at `path`. If it is a
|
114
|
+
* symref, it will return a new unresolved symbolic reference
|
115
|
+
* with the given name pointing to the reference pointed to by
|
116
|
+
* the file. If it is not a symbolic reference, it will return
|
117
|
+
* the resolved reference.
|
118
|
+
*/
|
119
|
+
int git_reference__read_head(
|
120
|
+
git_reference **out,
|
121
|
+
git_repository *repo,
|
122
|
+
const char *path);
|
123
|
+
|
110
124
|
int git_reference__log_signature(git_signature **out, git_repository *repo);
|
111
125
|
|
112
126
|
/** Update a reference after a commit. */
|
data/vendor/libgit2/src/remote.c
CHANGED
@@ -192,7 +192,7 @@ static int canonicalize_url(git_buf *out, const char *in)
|
|
192
192
|
static int create_internal(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch)
|
193
193
|
{
|
194
194
|
git_remote *remote;
|
195
|
-
git_config *
|
195
|
+
git_config *config_ro = NULL, *config_rw;
|
196
196
|
git_buf canonical_url = GIT_BUF_INIT;
|
197
197
|
git_buf var = GIT_BUF_INIT;
|
198
198
|
int error = -1;
|
@@ -200,7 +200,7 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
|
|
200
200
|
/* name is optional */
|
201
201
|
assert(out && repo && url);
|
202
202
|
|
203
|
-
if ((error =
|
203
|
+
if ((error = git_repository_config_snapshot(&config_ro, repo)) < 0)
|
204
204
|
return error;
|
205
205
|
|
206
206
|
remote = git__calloc(1, sizeof(git_remote));
|
@@ -212,7 +212,8 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
|
|
212
212
|
(error = canonicalize_url(&canonical_url, url)) < 0)
|
213
213
|
goto on_error;
|
214
214
|
|
215
|
-
remote->url = apply_insteadof(
|
215
|
+
remote->url = apply_insteadof(config_ro, canonical_url.ptr, GIT_DIRECTION_FETCH);
|
216
|
+
GITERR_CHECK_ALLOC(remote->url);
|
216
217
|
|
217
218
|
if (name != NULL) {
|
218
219
|
remote->name = git__strdup(name);
|
@@ -221,7 +222,8 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
|
|
221
222
|
if ((error = git_buf_printf(&var, CONFIG_URL_FMT, name)) < 0)
|
222
223
|
goto on_error;
|
223
224
|
|
224
|
-
if ((error =
|
225
|
+
if ((error = git_repository_config__weakptr(&config_rw, repo)) < 0 ||
|
226
|
+
(error = git_config_set_string(config_rw, var.ptr, canonical_url.ptr)) < 0)
|
225
227
|
goto on_error;
|
226
228
|
}
|
227
229
|
|
@@ -233,10 +235,7 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
|
|
233
235
|
if (name && (error = write_add_refspec(repo, name, fetch, true)) < 0)
|
234
236
|
goto on_error;
|
235
237
|
|
236
|
-
if ((error =
|
237
|
-
goto on_error;
|
238
|
-
|
239
|
-
if ((error = lookup_remote_prune_config(remote, config, name)) < 0)
|
238
|
+
if ((error = lookup_remote_prune_config(remote, config_ro, name)) < 0)
|
240
239
|
goto on_error;
|
241
240
|
|
242
241
|
/* Move the data over to where the matching functions can find them */
|
@@ -260,7 +259,7 @@ on_error:
|
|
260
259
|
if (error)
|
261
260
|
git_remote_free(remote);
|
262
261
|
|
263
|
-
git_config_free(
|
262
|
+
git_config_free(config_ro);
|
264
263
|
git_buf_free(&canonical_url);
|
265
264
|
git_buf_free(&var);
|
266
265
|
return error;
|
@@ -2412,7 +2411,7 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_
|
|
2412
2411
|
proxy = &opts->proxy_opts;
|
2413
2412
|
}
|
2414
2413
|
|
2415
|
-
assert(remote
|
2414
|
+
assert(remote);
|
2416
2415
|
|
2417
2416
|
if ((error = git_remote_connect(remote, GIT_DIRECTION_PUSH, cbs, proxy, custom_headers)) < 0)
|
2418
2417
|
return error;
|
@@ -36,6 +36,8 @@
|
|
36
36
|
# include "win32/w32_util.h"
|
37
37
|
#endif
|
38
38
|
|
39
|
+
bool git_repository__fsync_gitdir = false;
|
40
|
+
|
39
41
|
static const struct {
|
40
42
|
git_repository_item_t parent;
|
41
43
|
const char *name;
|
@@ -422,10 +424,10 @@ static int read_gitfile(git_buf *path_out, const char *file_path)
|
|
422
424
|
}
|
423
425
|
|
424
426
|
static int find_repo(
|
425
|
-
git_buf *
|
426
|
-
git_buf *
|
427
|
-
git_buf *
|
428
|
-
git_buf *
|
427
|
+
git_buf *gitdir_path,
|
428
|
+
git_buf *workdir_path,
|
429
|
+
git_buf *gitlink_path,
|
430
|
+
git_buf *commondir_path,
|
429
431
|
const char *start_path,
|
430
432
|
uint32_t flags,
|
431
433
|
const char *ceiling_dirs)
|
@@ -440,7 +442,7 @@ static int find_repo(
|
|
440
442
|
bool in_dot_git;
|
441
443
|
size_t ceiling_offset = 0;
|
442
444
|
|
443
|
-
|
445
|
+
git_buf_clear(gitdir_path);
|
444
446
|
|
445
447
|
error = git_path_prettify(&path, start_path, NULL);
|
446
448
|
if (error < 0)
|
@@ -482,13 +484,13 @@ static int find_repo(
|
|
482
484
|
if (S_ISDIR(st.st_mode)) {
|
483
485
|
if (valid_repository_path(&path, &common_link)) {
|
484
486
|
git_path_to_dir(&path);
|
485
|
-
git_buf_set(
|
487
|
+
git_buf_set(gitdir_path, path.ptr, path.size);
|
486
488
|
|
487
|
-
if (
|
488
|
-
git_buf_attach(
|
489
|
+
if (gitlink_path)
|
490
|
+
git_buf_attach(gitlink_path,
|
489
491
|
git_worktree__read_link(path.ptr, GIT_GITDIR_FILE), 0);
|
490
|
-
if (
|
491
|
-
git_buf_swap(&common_link,
|
492
|
+
if (commondir_path)
|
493
|
+
git_buf_swap(&common_link, commondir_path);
|
492
494
|
|
493
495
|
break;
|
494
496
|
}
|
@@ -498,12 +500,12 @@ static int find_repo(
|
|
498
500
|
if (error < 0)
|
499
501
|
break;
|
500
502
|
if (valid_repository_path(&repo_link, &common_link)) {
|
501
|
-
git_buf_swap(
|
503
|
+
git_buf_swap(gitdir_path, &repo_link);
|
502
504
|
|
503
|
-
if (
|
504
|
-
error = git_buf_put(
|
505
|
-
if (
|
506
|
-
git_buf_swap(&common_link,
|
505
|
+
if (gitlink_path)
|
506
|
+
error = git_buf_put(gitlink_path, path.ptr, path.size);
|
507
|
+
if (commondir_path)
|
508
|
+
git_buf_swap(&common_link, commondir_path);
|
507
509
|
}
|
508
510
|
break;
|
509
511
|
}
|
@@ -529,20 +531,20 @@ static int find_repo(
|
|
529
531
|
break;
|
530
532
|
}
|
531
533
|
|
532
|
-
if (!error &&
|
533
|
-
if (!git_buf_len(
|
534
|
-
git_buf_clear(
|
534
|
+
if (!error && workdir_path && !(flags & GIT_REPOSITORY_OPEN_BARE)) {
|
535
|
+
if (!git_buf_len(gitdir_path))
|
536
|
+
git_buf_clear(workdir_path);
|
535
537
|
else {
|
536
|
-
git_path_dirname_r(
|
537
|
-
git_path_to_dir(
|
538
|
+
git_path_dirname_r(workdir_path, path.ptr);
|
539
|
+
git_path_to_dir(workdir_path);
|
538
540
|
}
|
539
|
-
if (git_buf_oom(
|
541
|
+
if (git_buf_oom(workdir_path))
|
540
542
|
return -1;
|
541
543
|
}
|
542
544
|
|
543
545
|
/* If we didn't find the repository, and we don't have any other error
|
544
546
|
* to report, report that. */
|
545
|
-
if (!git_buf_len(
|
547
|
+
if (!git_buf_len(gitdir_path) && !error) {
|
546
548
|
giterr_set(GITERR_REPOSITORY,
|
547
549
|
"could not find repository from '%s'", start_path);
|
548
550
|
error = GIT_ENOTFOUND;
|
@@ -758,6 +760,29 @@ success:
|
|
758
760
|
return error;
|
759
761
|
}
|
760
762
|
|
763
|
+
static int repo_is_worktree(unsigned *out, const git_repository *repo)
|
764
|
+
{
|
765
|
+
git_buf gitdir_link = GIT_BUF_INIT;
|
766
|
+
int error;
|
767
|
+
|
768
|
+
/* Worktrees cannot have the same commondir and gitdir */
|
769
|
+
if (repo->commondir && repo->gitdir
|
770
|
+
&& !strcmp(repo->commondir, repo->gitdir)) {
|
771
|
+
*out = 0;
|
772
|
+
return 0;
|
773
|
+
}
|
774
|
+
|
775
|
+
if ((error = git_buf_joinpath(&gitdir_link, repo->gitdir, "gitdir")) < 0)
|
776
|
+
return -1;
|
777
|
+
|
778
|
+
/* A 'gitdir' file inside a git directory is currently
|
779
|
+
* only used when the repository is a working tree. */
|
780
|
+
*out = !!git_path_exists(gitdir_link.ptr);
|
781
|
+
|
782
|
+
git_buf_free(&gitdir_link);
|
783
|
+
return error;
|
784
|
+
}
|
785
|
+
|
761
786
|
int git_repository_open_ext(
|
762
787
|
git_repository **repo_ptr,
|
763
788
|
const char *start_path,
|
@@ -765,8 +790,9 @@ int git_repository_open_ext(
|
|
765
790
|
const char *ceiling_dirs)
|
766
791
|
{
|
767
792
|
int error;
|
768
|
-
|
769
|
-
|
793
|
+
unsigned is_worktree;
|
794
|
+
git_buf gitdir = GIT_BUF_INIT, workdir = GIT_BUF_INIT,
|
795
|
+
gitlink = GIT_BUF_INIT, commondir = GIT_BUF_INIT;
|
770
796
|
git_repository *repo;
|
771
797
|
git_config *config = NULL;
|
772
798
|
|
@@ -777,7 +803,7 @@ int git_repository_open_ext(
|
|
777
803
|
*repo_ptr = NULL;
|
778
804
|
|
779
805
|
error = find_repo(
|
780
|
-
&
|
806
|
+
&gitdir, &workdir, &gitlink, &commondir, start_path, flags, ceiling_dirs);
|
781
807
|
|
782
808
|
if (error < 0 || !repo_ptr)
|
783
809
|
return error;
|
@@ -785,24 +811,21 @@ int git_repository_open_ext(
|
|
785
811
|
repo = repository_alloc();
|
786
812
|
GITERR_CHECK_ALLOC(repo);
|
787
813
|
|
788
|
-
repo->gitdir = git_buf_detach(&
|
814
|
+
repo->gitdir = git_buf_detach(&gitdir);
|
789
815
|
GITERR_CHECK_ALLOC(repo->gitdir);
|
790
816
|
|
791
|
-
if (
|
792
|
-
repo->gitlink = git_buf_detach(&
|
817
|
+
if (gitlink.size) {
|
818
|
+
repo->gitlink = git_buf_detach(&gitlink);
|
793
819
|
GITERR_CHECK_ALLOC(repo->gitlink);
|
794
820
|
}
|
795
|
-
if (
|
796
|
-
repo->commondir = git_buf_detach(&
|
821
|
+
if (commondir.size) {
|
822
|
+
repo->commondir = git_buf_detach(&commondir);
|
797
823
|
GITERR_CHECK_ALLOC(repo->commondir);
|
798
824
|
}
|
799
825
|
|
800
|
-
if ((error =
|
826
|
+
if ((error = repo_is_worktree(&is_worktree, repo)) < 0)
|
801
827
|
goto cleanup;
|
802
|
-
|
803
|
-
* only used when the repository is a working tree. */
|
804
|
-
if (git_path_exists(path.ptr))
|
805
|
-
repo->is_worktree = 1;
|
828
|
+
repo->is_worktree = is_worktree;
|
806
829
|
|
807
830
|
/*
|
808
831
|
* We'd like to have the config, but git doesn't particularly
|
@@ -822,13 +845,13 @@ int git_repository_open_ext(
|
|
822
845
|
|
823
846
|
if (config &&
|
824
847
|
((error = load_config_data(repo, config)) < 0 ||
|
825
|
-
(error = load_workdir(repo, config, &
|
848
|
+
(error = load_workdir(repo, config, &workdir)) < 0))
|
826
849
|
goto cleanup;
|
827
850
|
}
|
828
851
|
|
829
852
|
cleanup:
|
830
|
-
git_buf_free(&
|
831
|
-
git_buf_free(&
|
853
|
+
git_buf_free(&gitdir);
|
854
|
+
git_buf_free(&workdir);
|
832
855
|
git_config_free(config);
|
833
856
|
|
834
857
|
if (error < 0)
|
@@ -920,13 +943,10 @@ static int load_config(
|
|
920
943
|
if ((error = git_config_new(&cfg)) < 0)
|
921
944
|
return error;
|
922
945
|
|
923
|
-
error = git_repository_item_path(&config_path, repo, GIT_REPOSITORY_ITEM_CONFIG)
|
924
|
-
|
925
|
-
goto on_error;
|
946
|
+
if ((error = git_repository_item_path(&config_path, repo, GIT_REPOSITORY_ITEM_CONFIG)) == 0)
|
947
|
+
error = git_config_add_file_ondisk(cfg, config_path.ptr, GIT_CONFIG_LEVEL_LOCAL, 0);
|
926
948
|
|
927
|
-
if (
|
928
|
-
cfg, config_path.ptr, GIT_CONFIG_LEVEL_LOCAL, 0)) < 0 &&
|
929
|
-
error != GIT_ENOTFOUND)
|
949
|
+
if (error && error != GIT_ENOTFOUND)
|
930
950
|
goto on_error;
|
931
951
|
|
932
952
|
git_buf_free(&config_path);
|
@@ -1055,18 +1075,22 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
|
|
1055
1075
|
git_odb *odb;
|
1056
1076
|
|
1057
1077
|
if ((error = git_repository_item_path(&odb_path, repo,
|
1058
|
-
GIT_REPOSITORY_ITEM_OBJECTS)) < 0
|
1078
|
+
GIT_REPOSITORY_ITEM_OBJECTS)) < 0 ||
|
1079
|
+
(error = git_odb_new(&odb)) < 0)
|
1059
1080
|
return error;
|
1060
1081
|
|
1061
|
-
|
1062
|
-
if (!error) {
|
1063
|
-
GIT_REFCOUNT_OWN(odb, repo);
|
1082
|
+
GIT_REFCOUNT_OWN(odb, repo);
|
1064
1083
|
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1084
|
+
if ((error = git_odb__set_caps(odb, GIT_ODB_CAP_FROM_OWNER)) < 0 ||
|
1085
|
+
(error = git_odb__add_default_backends(odb, odb_path.ptr, 0, 0)) < 0) {
|
1086
|
+
git_odb_free(odb);
|
1087
|
+
return error;
|
1088
|
+
}
|
1089
|
+
|
1090
|
+
odb = git__compare_and_swap(&repo->_odb, NULL, odb);
|
1091
|
+
if (odb != NULL) {
|
1092
|
+
GIT_REFCOUNT_OWN(odb, NULL);
|
1093
|
+
git_odb_free(odb);
|
1070
1094
|
}
|
1071
1095
|
|
1072
1096
|
git_buf_free(&odb_path);
|
@@ -2059,47 +2083,27 @@ int git_repository_head_detached(git_repository *repo)
|
|
2059
2083
|
return exists;
|
2060
2084
|
}
|
2061
2085
|
|
2062
|
-
static int
|
2086
|
+
static int get_worktree_file_path(git_buf *out, git_repository *repo, const char *worktree, const char *file)
|
2063
2087
|
{
|
2064
|
-
git_buf path = GIT_BUF_INIT;
|
2065
|
-
int err;
|
2066
|
-
|
2067
|
-
assert(out && repo && name);
|
2068
|
-
|
2069
2088
|
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;
|
2089
|
+
return git_buf_printf(out, "%s/worktrees/%s/%s", repo->commondir, worktree, file);
|
2087
2090
|
}
|
2088
2091
|
|
2089
2092
|
int git_repository_head_detached_for_worktree(git_repository *repo, const char *name)
|
2090
2093
|
{
|
2091
|
-
|
2092
|
-
int
|
2094
|
+
git_reference *ref = NULL;
|
2095
|
+
int error;
|
2093
2096
|
|
2094
2097
|
assert(repo && name);
|
2095
2098
|
|
2096
|
-
if (
|
2097
|
-
|
2099
|
+
if ((error = git_repository_head_for_worktree(&ref, repo, name)) < 0)
|
2100
|
+
goto out;
|
2098
2101
|
|
2099
|
-
|
2100
|
-
|
2102
|
+
error = (git_reference_type(ref) != GIT_REF_SYMBOLIC);
|
2103
|
+
out:
|
2104
|
+
git_reference_free(ref);
|
2101
2105
|
|
2102
|
-
return
|
2106
|
+
return error;
|
2103
2107
|
}
|
2104
2108
|
|
2105
2109
|
int git_repository_head(git_reference **head_out, git_repository *repo)
|
@@ -2123,44 +2127,67 @@ int git_repository_head(git_reference **head_out, git_repository *repo)
|
|
2123
2127
|
|
2124
2128
|
int git_repository_head_for_worktree(git_reference **out, git_repository *repo, const char *name)
|
2125
2129
|
{
|
2126
|
-
git_buf
|
2127
|
-
git_reference *head;
|
2128
|
-
int
|
2130
|
+
git_buf path = GIT_BUF_INIT;
|
2131
|
+
git_reference *head = NULL;
|
2132
|
+
int error;
|
2129
2133
|
|
2130
2134
|
assert(out && repo && name);
|
2131
2135
|
|
2132
2136
|
*out = NULL;
|
2133
2137
|
|
2134
|
-
if (
|
2135
|
-
|
2136
|
-
if ((err = read_worktree_head(&buf, repo, name)) < 0)
|
2138
|
+
if ((error = get_worktree_file_path(&path, repo, name, GIT_HEAD_FILE)) < 0 ||
|
2139
|
+
(error = git_reference__read_head(&head, repo, path.ptr)) < 0)
|
2137
2140
|
goto out;
|
2138
2141
|
|
2139
|
-
|
2140
|
-
|
2141
|
-
|
2142
|
-
|
2143
|
-
|
2142
|
+
if (git_reference_type(head) != GIT_REF_OID) {
|
2143
|
+
git_reference *resolved;
|
2144
|
+
|
2145
|
+
error = git_reference_lookup_resolved(&resolved, repo, git_reference_symbolic_target(head), -1);
|
2146
|
+
git_reference_free(head);
|
2147
|
+
head = resolved;
|
2144
2148
|
}
|
2145
|
-
git_buf_consume(&buf, buf.ptr + strlen(GIT_SYMREF));
|
2146
2149
|
|
2147
|
-
|
2150
|
+
*out = head;
|
2151
|
+
|
2152
|
+
out:
|
2153
|
+
if (error)
|
2154
|
+
git_reference_free(head);
|
2155
|
+
|
2156
|
+
git_buf_free(&path);
|
2157
|
+
|
2158
|
+
return error;
|
2159
|
+
}
|
2160
|
+
|
2161
|
+
int git_repository_foreach_head(git_repository *repo, git_repository_foreach_head_cb cb, void *payload)
|
2162
|
+
{
|
2163
|
+
git_strarray worktrees = GIT_VECTOR_INIT;
|
2164
|
+
git_buf path = GIT_BUF_INIT;
|
2165
|
+
int error;
|
2166
|
+
size_t i;
|
2167
|
+
|
2168
|
+
/* Execute callback for HEAD of commondir */
|
2169
|
+
if ((error = git_buf_joinpath(&path, repo->commondir, GIT_HEAD_FILE)) < 0 ||
|
2170
|
+
(error = cb(repo, path.ptr, payload) != 0))
|
2148
2171
|
goto out;
|
2149
|
-
|
2150
|
-
{
|
2151
|
-
|
2152
|
-
err = 0;
|
2172
|
+
|
2173
|
+
if ((error = git_worktree_list(&worktrees, repo)) < 0) {
|
2174
|
+
error = 0;
|
2153
2175
|
goto out;
|
2154
2176
|
}
|
2155
2177
|
|
2156
|
-
|
2157
|
-
|
2158
|
-
|
2178
|
+
/* Execute callback for all worktree HEADs */
|
2179
|
+
for (i = 0; i < worktrees.count; i++) {
|
2180
|
+
if (get_worktree_file_path(&path, repo, worktrees.strings[i], GIT_HEAD_FILE) < 0)
|
2181
|
+
continue;
|
2159
2182
|
|
2160
|
-
|
2161
|
-
|
2183
|
+
if ((error = cb(repo, path.ptr, payload)) != 0)
|
2184
|
+
goto out;
|
2185
|
+
}
|
2162
2186
|
|
2163
|
-
|
2187
|
+
out:
|
2188
|
+
git_buf_free(&path);
|
2189
|
+
git_strarray_free(&worktrees);
|
2190
|
+
return error;
|
2164
2191
|
}
|
2165
2192
|
|
2166
2193
|
int git_repository_head_unborn(git_repository *repo)
|
@@ -2236,13 +2263,13 @@ int git_repository_item_path(git_buf *out, git_repository *repo, git_repository_
|
|
2236
2263
|
parent = git_repository_commondir(repo);
|
2237
2264
|
break;
|
2238
2265
|
default:
|
2239
|
-
giterr_set(GITERR_INVALID, "
|
2266
|
+
giterr_set(GITERR_INVALID, "invalid item directory");
|
2240
2267
|
return -1;
|
2241
2268
|
}
|
2242
2269
|
|
2243
2270
|
if (parent == NULL) {
|
2244
|
-
giterr_set(GITERR_INVALID, "
|
2245
|
-
return
|
2271
|
+
giterr_set(GITERR_INVALID, "path cannot exist in repository");
|
2272
|
+
return GIT_ENOTFOUND;
|
2246
2273
|
}
|
2247
2274
|
|
2248
2275
|
if (git_buf_sets(out, parent) < 0)
|
@@ -2525,7 +2552,9 @@ static int checkout_message(git_buf *out, git_reference *old, const char *new)
|
|
2525
2552
|
|
2526
2553
|
git_buf_puts(out, " to ");
|
2527
2554
|
|
2528
|
-
if (git_reference__is_branch(new)
|
2555
|
+
if (git_reference__is_branch(new) ||
|
2556
|
+
git_reference__is_tag(new) ||
|
2557
|
+
git_reference__is_remote(new))
|
2529
2558
|
git_buf_puts(out, git_reference__shorthand(new));
|
2530
2559
|
else
|
2531
2560
|
git_buf_puts(out, new);
|
@@ -2536,6 +2565,41 @@ static int checkout_message(git_buf *out, git_reference *old, const char *new)
|
|
2536
2565
|
return 0;
|
2537
2566
|
}
|
2538
2567
|
|
2568
|
+
static int detach(git_repository *repo, const git_oid *id, const char *new)
|
2569
|
+
{
|
2570
|
+
int error;
|
2571
|
+
git_buf log_message = GIT_BUF_INIT;
|
2572
|
+
git_object *object = NULL, *peeled = NULL;
|
2573
|
+
git_reference *new_head = NULL, *current = NULL;
|
2574
|
+
|
2575
|
+
assert(repo && id);
|
2576
|
+
|
2577
|
+
if ((error = git_reference_lookup(¤t, repo, GIT_HEAD_FILE)) < 0)
|
2578
|
+
return error;
|
2579
|
+
|
2580
|
+
if ((error = git_object_lookup(&object, repo, id, GIT_OBJ_ANY)) < 0)
|
2581
|
+
goto cleanup;
|
2582
|
+
|
2583
|
+
if ((error = git_object_peel(&peeled, object, GIT_OBJ_COMMIT)) < 0)
|
2584
|
+
goto cleanup;
|
2585
|
+
|
2586
|
+
if (new == NULL)
|
2587
|
+
new = git_oid_tostr_s(git_object_id(peeled));
|
2588
|
+
|
2589
|
+
if ((error = checkout_message(&log_message, current, new)) < 0)
|
2590
|
+
goto cleanup;
|
2591
|
+
|
2592
|
+
error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true, git_buf_cstr(&log_message));
|
2593
|
+
|
2594
|
+
cleanup:
|
2595
|
+
git_buf_free(&log_message);
|
2596
|
+
git_object_free(object);
|
2597
|
+
git_object_free(peeled);
|
2598
|
+
git_reference_free(current);
|
2599
|
+
git_reference_free(new_head);
|
2600
|
+
return error;
|
2601
|
+
}
|
2602
|
+
|
2539
2603
|
int git_repository_set_head(
|
2540
2604
|
git_repository* repo,
|
2541
2605
|
const char* refname)
|
@@ -2558,6 +2622,8 @@ int git_repository_set_head(
|
|
2558
2622
|
|
2559
2623
|
if (ref && current->type == GIT_REF_SYMBOLIC && git__strcmp(current->target.symbolic, ref->name) &&
|
2560
2624
|
git_reference_is_branch(ref) && git_branch_is_checked_out(ref)) {
|
2625
|
+
giterr_set(GITERR_REPOSITORY, "cannot set HEAD to reference '%s' as it is the current HEAD "
|
2626
|
+
"of a linked repository.", git_reference_name(ref));
|
2561
2627
|
error = -1;
|
2562
2628
|
goto cleanup;
|
2563
2629
|
}
|
@@ -2567,7 +2633,8 @@ int git_repository_set_head(
|
|
2567
2633
|
error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE,
|
2568
2634
|
git_reference_name(ref), true, git_buf_cstr(&log_message));
|
2569
2635
|
} else {
|
2570
|
-
error =
|
2636
|
+
error = detach(repo, git_reference_target(ref),
|
2637
|
+
git_reference_is_tag(ref) || git_reference_is_remote(ref) ? refname : NULL);
|
2571
2638
|
}
|
2572
2639
|
} else if (git_reference__is_branch(refname)) {
|
2573
2640
|
error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname,
|
@@ -2582,41 +2649,6 @@ cleanup:
|
|
2582
2649
|
return error;
|
2583
2650
|
}
|
2584
2651
|
|
2585
|
-
static int detach(git_repository *repo, const git_oid *id, const char *from)
|
2586
|
-
{
|
2587
|
-
int error;
|
2588
|
-
git_buf log_message = GIT_BUF_INIT;
|
2589
|
-
git_object *object = NULL, *peeled = NULL;
|
2590
|
-
git_reference *new_head = NULL, *current = NULL;
|
2591
|
-
|
2592
|
-
assert(repo && id);
|
2593
|
-
|
2594
|
-
if ((error = git_reference_lookup(¤t, repo, GIT_HEAD_FILE)) < 0)
|
2595
|
-
return error;
|
2596
|
-
|
2597
|
-
if ((error = git_object_lookup(&object, repo, id, GIT_OBJ_ANY)) < 0)
|
2598
|
-
goto cleanup;
|
2599
|
-
|
2600
|
-
if ((error = git_object_peel(&peeled, object, GIT_OBJ_COMMIT)) < 0)
|
2601
|
-
goto cleanup;
|
2602
|
-
|
2603
|
-
if (from == NULL)
|
2604
|
-
from = git_oid_tostr_s(git_object_id(peeled));
|
2605
|
-
|
2606
|
-
if ((error = checkout_message(&log_message, current, from)) < 0)
|
2607
|
-
goto cleanup;
|
2608
|
-
|
2609
|
-
error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true, git_buf_cstr(&log_message));
|
2610
|
-
|
2611
|
-
cleanup:
|
2612
|
-
git_buf_free(&log_message);
|
2613
|
-
git_object_free(object);
|
2614
|
-
git_object_free(peeled);
|
2615
|
-
git_reference_free(current);
|
2616
|
-
git_reference_free(new_head);
|
2617
|
-
return error;
|
2618
|
-
}
|
2619
|
-
|
2620
2652
|
int git_repository_set_head_detached(
|
2621
2653
|
git_repository* repo,
|
2622
2654
|
const git_oid* commitish)
|