rugged 0.21.4 → 0.22.0b1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -5
- data/ext/rugged/extconf.rb +9 -9
- data/ext/rugged/rugged.c +4 -2
- data/ext/rugged/rugged.h +3 -7
- data/ext/rugged/rugged_blob.c +57 -0
- data/ext/rugged/rugged_cred.c +23 -0
- data/ext/rugged/rugged_index.c +6 -2
- data/ext/rugged/rugged_remote.c +65 -52
- data/ext/rugged/rugged_remote_collection.c +59 -10
- data/ext/rugged/rugged_repo.c +345 -11
- data/ext/rugged/rugged_revwalk.c +10 -0
- data/ext/rugged/rugged_submodule.c +1042 -0
- data/ext/rugged/rugged_submodule_collection.c +236 -0
- data/ext/rugged/rugged_tag_collection.c +70 -2
- data/ext/rugged/rugged_tree.c +29 -10
- data/lib/rugged.rb +3 -0
- data/lib/rugged/attributes.rb +41 -0
- data/lib/rugged/blob.rb +28 -0
- data/lib/rugged/diff.rb +0 -1
- data/lib/rugged/diff/line.rb +1 -3
- data/lib/rugged/patch.rb +12 -2
- data/lib/rugged/repository.rb +7 -0
- data/lib/rugged/submodule_collection.rb +48 -0
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +27 -3
- data/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake +324 -0
- data/vendor/libgit2/deps/http-parser/http_parser.h +2 -0
- data/vendor/libgit2/deps/zlib/adler32.c +39 -29
- data/vendor/libgit2/deps/zlib/crc32.c +33 -50
- data/vendor/libgit2/deps/zlib/crc32.h +1 -1
- data/vendor/libgit2/deps/zlib/deflate.c +198 -65
- data/vendor/libgit2/deps/zlib/deflate.h +8 -4
- data/vendor/libgit2/deps/zlib/infback.c +640 -0
- data/vendor/libgit2/deps/zlib/inffast.c +3 -3
- data/vendor/libgit2/deps/zlib/inffixed.h +3 -3
- data/vendor/libgit2/deps/zlib/inflate.c +84 -52
- data/vendor/libgit2/deps/zlib/inftrees.c +15 -39
- data/vendor/libgit2/deps/zlib/trees.c +18 -36
- data/vendor/libgit2/deps/zlib/zconf.h +4 -0
- data/vendor/libgit2/deps/zlib/zlib.h +250 -95
- data/vendor/libgit2/deps/zlib/zutil.c +13 -10
- data/vendor/libgit2/deps/zlib/zutil.h +41 -62
- data/vendor/libgit2/include/git2.h +4 -0
- data/vendor/libgit2/include/git2/annotated_commit.h +99 -0
- data/vendor/libgit2/include/git2/attr.h +16 -13
- data/vendor/libgit2/include/git2/branch.h +11 -0
- data/vendor/libgit2/include/git2/buffer.h +16 -0
- data/vendor/libgit2/include/git2/checkout.h +12 -12
- data/vendor/libgit2/include/git2/cherrypick.h +15 -15
- data/vendor/libgit2/include/git2/clone.h +77 -69
- data/vendor/libgit2/include/git2/common.h +13 -1
- data/vendor/libgit2/include/git2/config.h +0 -14
- data/vendor/libgit2/include/git2/describe.h +162 -0
- data/vendor/libgit2/include/git2/diff.h +13 -8
- data/vendor/libgit2/include/git2/errors.h +5 -0
- data/vendor/libgit2/include/git2/global.h +38 -0
- data/vendor/libgit2/include/git2/merge.h +38 -64
- data/vendor/libgit2/include/git2/net.h +2 -2
- data/vendor/libgit2/include/git2/notes.h +17 -0
- data/vendor/libgit2/include/git2/oid.h +8 -4
- data/vendor/libgit2/include/git2/oidarray.h +40 -0
- data/vendor/libgit2/include/git2/rebase.h +261 -0
- data/vendor/libgit2/include/git2/reflog.h +1 -1
- data/vendor/libgit2/include/git2/remote.h +25 -47
- data/vendor/libgit2/include/git2/repository.h +4 -1
- data/vendor/libgit2/include/git2/reset.h +10 -1
- data/vendor/libgit2/include/git2/revert.h +1 -1
- data/vendor/libgit2/include/git2/revwalk.h +28 -23
- data/vendor/libgit2/include/git2/status.h +19 -15
- data/vendor/libgit2/include/git2/submodule.h +18 -0
- data/vendor/libgit2/include/git2/sys/config.h +0 -1
- data/vendor/libgit2/{src → include/git2/sys}/hashsig.h +11 -7
- data/vendor/libgit2/include/git2/sys/refdb_backend.h +13 -0
- data/vendor/libgit2/include/git2/sys/refs.h +0 -11
- data/vendor/libgit2/include/git2/sys/repository.h +13 -0
- data/vendor/libgit2/include/git2/sys/transport.h +352 -0
- data/vendor/libgit2/include/git2/threads.h +10 -20
- data/vendor/libgit2/include/git2/transaction.h +111 -0
- data/vendor/libgit2/include/git2/transport.h +79 -313
- data/vendor/libgit2/include/git2/tree.h +4 -2
- data/vendor/libgit2/include/git2/types.h +77 -8
- data/vendor/libgit2/include/git2/version.h +2 -2
- data/vendor/libgit2/src/annotated_commit.c +121 -0
- data/vendor/libgit2/src/annotated_commit.h +22 -0
- data/vendor/libgit2/src/attr.c +8 -4
- data/vendor/libgit2/src/attr_file.c +24 -2
- data/vendor/libgit2/src/blame.c +0 -1
- data/vendor/libgit2/src/branch.c +32 -3
- data/vendor/libgit2/src/buf_text.c +9 -5
- data/vendor/libgit2/src/buf_text.h +3 -2
- data/vendor/libgit2/src/buffer.c +67 -10
- data/vendor/libgit2/src/buffer.h +4 -2
- data/vendor/libgit2/src/cache.c +9 -9
- data/vendor/libgit2/src/cache.h +1 -1
- data/vendor/libgit2/src/cc-compat.h +2 -0
- data/vendor/libgit2/src/checkout.c +263 -82
- data/vendor/libgit2/src/checkout.h +1 -0
- data/vendor/libgit2/src/cherrypick.c +41 -44
- data/vendor/libgit2/src/clone.c +96 -58
- data/vendor/libgit2/src/commit.c +5 -31
- data/vendor/libgit2/src/commit_list.h +3 -1
- data/vendor/libgit2/src/config.c +0 -17
- data/vendor/libgit2/src/config_cache.c +0 -2
- data/vendor/libgit2/src/config_file.c +12 -15
- data/vendor/libgit2/src/crlf.c +2 -1
- data/vendor/libgit2/src/describe.c +886 -0
- data/vendor/libgit2/src/diff.c +29 -3
- data/vendor/libgit2/src/diff_file.c +1 -0
- data/vendor/libgit2/src/diff_patch.c +2 -3
- data/vendor/libgit2/src/diff_print.c +11 -9
- data/vendor/libgit2/src/diff_tform.c +4 -4
- data/vendor/libgit2/src/errors.c +9 -7
- data/vendor/libgit2/src/fetch.c +6 -6
- data/vendor/libgit2/src/fetchhead.h +2 -4
- data/vendor/libgit2/src/filebuf.c +0 -2
- data/vendor/libgit2/src/filebuf.h +2 -3
- data/vendor/libgit2/src/fileops.c +9 -7
- data/vendor/libgit2/src/global.c +44 -35
- data/vendor/libgit2/src/global.h +2 -0
- data/vendor/libgit2/src/graph.c +2 -2
- data/vendor/libgit2/src/hash.h +3 -1
- data/vendor/libgit2/src/hash/hash_common_crypto.h +44 -0
- data/vendor/libgit2/src/hash/hash_win32.c +1 -1
- data/vendor/libgit2/src/hashsig.c +1 -1
- data/vendor/libgit2/src/ignore.c +5 -88
- data/vendor/libgit2/src/index.c +70 -57
- data/vendor/libgit2/src/index.h +1 -0
- data/vendor/libgit2/src/indexer.c +16 -5
- data/vendor/libgit2/src/iterator.c +70 -1
- data/vendor/libgit2/src/iterator.h +5 -1
- data/vendor/libgit2/src/map.h +0 -1
- data/vendor/libgit2/src/merge.c +203 -327
- data/vendor/libgit2/src/merge.h +3 -13
- data/vendor/libgit2/src/mwindow.c +119 -8
- data/vendor/libgit2/src/mwindow.h +9 -1
- data/vendor/libgit2/src/netops.c +7 -8
- data/vendor/libgit2/src/netops.h +6 -16
- data/vendor/libgit2/src/notes.c +31 -4
- data/vendor/libgit2/src/notes.h +3 -0
- data/vendor/libgit2/src/odb.c +23 -1
- data/vendor/libgit2/src/odb_loose.c +1 -1
- data/vendor/libgit2/src/odb_pack.c +6 -3
- data/vendor/libgit2/src/oid.c +9 -1
- data/vendor/libgit2/src/oid.h +11 -0
- data/vendor/libgit2/src/oidarray.c +21 -0
- data/vendor/libgit2/src/oidarray.h +18 -0
- data/vendor/libgit2/src/oidmap.h +16 -0
- data/vendor/libgit2/src/pack.c +20 -7
- data/vendor/libgit2/src/pack.h +3 -0
- data/vendor/libgit2/src/path.c +120 -293
- data/vendor/libgit2/src/path.h +21 -44
- data/vendor/libgit2/src/pathspec.c +1 -1
- data/vendor/libgit2/src/pool.c +5 -11
- data/vendor/libgit2/src/pool.h +0 -2
- data/vendor/libgit2/src/posix.c +6 -6
- data/vendor/libgit2/src/posix.h +48 -28
- data/vendor/libgit2/src/push.c +19 -48
- data/vendor/libgit2/src/push.h +2 -4
- data/vendor/libgit2/src/rebase.c +1125 -0
- data/vendor/libgit2/src/refdb.c +19 -0
- data/vendor/libgit2/src/refdb.h +2 -1
- data/vendor/libgit2/src/refdb_fs.c +101 -29
- data/vendor/libgit2/src/reflog.c +1 -1
- data/vendor/libgit2/src/refs.c +38 -3
- data/vendor/libgit2/src/refs.h +13 -2
- data/vendor/libgit2/src/refspec.c +20 -2
- data/vendor/libgit2/src/remote.c +288 -154
- data/vendor/libgit2/src/remote.h +5 -1
- data/vendor/libgit2/src/repository.c +75 -36
- data/vendor/libgit2/src/repository.h +3 -25
- data/vendor/libgit2/src/reset.c +5 -1
- data/vendor/libgit2/src/revert.c +4 -6
- data/vendor/libgit2/src/revparse.c +15 -18
- data/vendor/libgit2/src/revwalk.c +96 -22
- data/vendor/libgit2/src/revwalk.h +5 -4
- data/vendor/libgit2/src/settings.c +22 -0
- data/vendor/libgit2/src/signature.c +37 -2
- data/vendor/libgit2/src/signature.h +3 -0
- data/vendor/libgit2/src/stash.c +17 -12
- data/vendor/libgit2/src/status.c +13 -3
- data/vendor/libgit2/src/strnlen.h +2 -1
- data/vendor/libgit2/src/submodule.c +75 -35
- data/vendor/libgit2/src/thread-utils.h +4 -9
- data/vendor/libgit2/src/trace.h +9 -1
- data/vendor/libgit2/src/transaction.c +352 -0
- data/vendor/libgit2/src/transport.c +91 -97
- data/vendor/libgit2/src/transports/auth.c +71 -0
- data/vendor/libgit2/src/transports/auth.h +63 -0
- data/vendor/libgit2/src/transports/auth_negotiate.c +275 -0
- data/vendor/libgit2/src/transports/auth_negotiate.h +27 -0
- data/vendor/libgit2/src/transports/cred.c +58 -0
- data/vendor/libgit2/src/transports/cred.h +14 -0
- data/vendor/libgit2/src/transports/cred_helpers.c +3 -0
- data/vendor/libgit2/src/transports/git.c +1 -0
- data/vendor/libgit2/src/transports/http.c +208 -82
- data/vendor/libgit2/src/transports/local.c +2 -2
- data/vendor/libgit2/src/transports/smart.c +2 -0
- data/vendor/libgit2/src/transports/smart.h +2 -0
- data/vendor/libgit2/src/transports/smart_protocol.c +10 -10
- data/vendor/libgit2/src/transports/ssh.c +243 -57
- data/vendor/libgit2/src/transports/winhttp.c +139 -35
- data/vendor/libgit2/src/tree-cache.c +118 -31
- data/vendor/libgit2/src/tree-cache.h +12 -7
- data/vendor/libgit2/src/tree.c +83 -64
- data/vendor/libgit2/src/tree.h +2 -3
- data/vendor/libgit2/src/unix/map.c +8 -2
- data/vendor/libgit2/src/unix/posix.h +23 -9
- data/vendor/libgit2/src/unix/realpath.c +8 -7
- data/vendor/libgit2/src/userdiff.h +3 -3
- data/vendor/libgit2/src/util.c +2 -92
- data/vendor/libgit2/src/util.h +3 -15
- data/vendor/libgit2/src/win32/findfile.c +0 -1
- data/vendor/libgit2/src/win32/map.c +3 -2
- data/vendor/libgit2/src/win32/mingw-compat.h +5 -12
- data/vendor/libgit2/src/win32/msvc-compat.h +3 -32
- data/vendor/libgit2/src/win32/posix.h +20 -32
- data/vendor/libgit2/src/win32/posix_w32.c +103 -31
- data/vendor/libgit2/src/win32/utf-conv.c +6 -36
- data/vendor/libgit2/src/win32/utf-conv.h +39 -0
- data/vendor/libgit2/src/win32/w32_util.h +0 -1
- metadata +32 -7
- data/vendor/libgit2/src/win32/path_w32.c +0 -305
- data/vendor/libgit2/src/win32/path_w32.h +0 -82
data/vendor/libgit2/src/refdb.c
CHANGED
@@ -242,3 +242,22 @@ int git_refdb_init_backend(git_refdb_backend *backend, unsigned int version)
|
|
242
242
|
backend, version, git_refdb_backend, GIT_REFDB_BACKEND_INIT);
|
243
243
|
return 0;
|
244
244
|
}
|
245
|
+
|
246
|
+
int git_refdb_lock(void **payload, git_refdb *db, const char *refname)
|
247
|
+
{
|
248
|
+
assert(payload && db && refname);
|
249
|
+
|
250
|
+
if (!db->backend->lock) {
|
251
|
+
giterr_set(GITERR_REFERENCE, "backend does not support locking");
|
252
|
+
return -1;
|
253
|
+
}
|
254
|
+
|
255
|
+
return db->backend->lock(payload, db->backend, refname);
|
256
|
+
}
|
257
|
+
|
258
|
+
int git_refdb_unlock(git_refdb *db, void *payload, int success, int update_reflog, const git_reference *ref, const git_signature *sig, const char *message)
|
259
|
+
{
|
260
|
+
assert(db);
|
261
|
+
|
262
|
+
return db->backend->unlock(db->backend, payload, success, update_reflog, ref, sig, message);
|
263
|
+
}
|
data/vendor/libgit2/src/refdb.h
CHANGED
@@ -51,6 +51,7 @@ int git_refdb_reflog_write(git_reflog *reflog);
|
|
51
51
|
int git_refdb_has_log(git_refdb *db, const char *refname);
|
52
52
|
int git_refdb_ensure_log(git_refdb *refdb, const char *refname);
|
53
53
|
|
54
|
-
|
54
|
+
int git_refdb_lock(void **payload, git_refdb *db, const char *refname);
|
55
|
+
int git_refdb_unlock(git_refdb *db, void *payload, int success, int update_reflog, const git_reference *ref, const git_signature *sig, const char *message);
|
55
56
|
|
56
57
|
#endif
|
@@ -707,16 +707,11 @@ static int reference_path_available(
|
|
707
707
|
|
708
708
|
static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *name)
|
709
709
|
{
|
710
|
-
|
710
|
+
int error;
|
711
711
|
git_buf ref_path = GIT_BUF_INIT;
|
712
712
|
|
713
713
|
assert(file && backend && name);
|
714
714
|
|
715
|
-
if (!git_path_isvalid(backend->repo, name, GIT_PATH_REJECT_DEFAULTS)) {
|
716
|
-
giterr_set(GITERR_INVALID, "Invalid reference name '%s'.", name);
|
717
|
-
return GIT_EINVALIDSPEC;
|
718
|
-
}
|
719
|
-
|
720
715
|
/* Remove a possibly existing empty directory hierarchy
|
721
716
|
* which name would collide with the reference name
|
722
717
|
*/
|
@@ -750,6 +745,57 @@ static int loose_commit(git_filebuf *file, const git_reference *ref)
|
|
750
745
|
return git_filebuf_commit(file);
|
751
746
|
}
|
752
747
|
|
748
|
+
static int refdb_fs_backend__lock(void **out, git_refdb_backend *_backend, const char *refname)
|
749
|
+
{
|
750
|
+
int error;
|
751
|
+
git_filebuf *lock;
|
752
|
+
refdb_fs_backend *backend = (refdb_fs_backend *) _backend;
|
753
|
+
|
754
|
+
lock = git__calloc(1, sizeof(git_filebuf));
|
755
|
+
GITERR_CHECK_ALLOC(lock);
|
756
|
+
|
757
|
+
if ((error = loose_lock(lock, backend, refname)) < 0) {
|
758
|
+
git__free(lock);
|
759
|
+
return error;
|
760
|
+
}
|
761
|
+
|
762
|
+
*out = lock;
|
763
|
+
return 0;
|
764
|
+
}
|
765
|
+
|
766
|
+
static int refdb_fs_backend__write_tail(
|
767
|
+
git_refdb_backend *_backend,
|
768
|
+
const git_reference *ref,
|
769
|
+
git_filebuf *file,
|
770
|
+
int update_reflog,
|
771
|
+
const git_signature *who,
|
772
|
+
const char *message,
|
773
|
+
const git_oid *old_id,
|
774
|
+
const char *old_target);
|
775
|
+
|
776
|
+
static int refdb_fs_backend__delete_tail(
|
777
|
+
git_refdb_backend *_backend,
|
778
|
+
git_filebuf *file,
|
779
|
+
const char *ref_name,
|
780
|
+
const git_oid *old_id, const char *old_target);
|
781
|
+
|
782
|
+
static int refdb_fs_backend__unlock(git_refdb_backend *backend, void *payload, int success, int update_reflog,
|
783
|
+
const git_reference *ref, const git_signature *sig, const char *message)
|
784
|
+
{
|
785
|
+
git_filebuf *lock = (git_filebuf *) payload;
|
786
|
+
int error = 0;
|
787
|
+
|
788
|
+
if (success == 2)
|
789
|
+
error = refdb_fs_backend__delete_tail(backend, lock, ref->name, NULL, NULL);
|
790
|
+
else if (success)
|
791
|
+
error = refdb_fs_backend__write_tail(backend, ref, lock, update_reflog, sig, message, NULL, NULL);
|
792
|
+
else
|
793
|
+
git_filebuf_cleanup(lock);
|
794
|
+
|
795
|
+
git__free(lock);
|
796
|
+
return error;
|
797
|
+
}
|
798
|
+
|
753
799
|
/*
|
754
800
|
* Find out what object this reference resolves to.
|
755
801
|
*
|
@@ -1068,7 +1114,6 @@ cleanup:
|
|
1068
1114
|
return error;
|
1069
1115
|
}
|
1070
1116
|
|
1071
|
-
|
1072
1117
|
static int refdb_fs_backend__write(
|
1073
1118
|
git_refdb_backend *_backend,
|
1074
1119
|
const git_reference *ref,
|
@@ -1080,9 +1125,7 @@ static int refdb_fs_backend__write(
|
|
1080
1125
|
{
|
1081
1126
|
refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
|
1082
1127
|
git_filebuf file = GIT_FILEBUF_INIT;
|
1083
|
-
int error = 0
|
1084
|
-
const char *new_target = NULL;
|
1085
|
-
const git_oid *new_id = NULL;
|
1128
|
+
int error = 0;
|
1086
1129
|
|
1087
1130
|
assert(backend);
|
1088
1131
|
|
@@ -1094,6 +1137,24 @@ static int refdb_fs_backend__write(
|
|
1094
1137
|
if ((error = loose_lock(&file, backend, ref->name)) < 0)
|
1095
1138
|
return error;
|
1096
1139
|
|
1140
|
+
return refdb_fs_backend__write_tail(_backend, ref, &file, true, who, message, old_id, old_target);
|
1141
|
+
}
|
1142
|
+
|
1143
|
+
static int refdb_fs_backend__write_tail(
|
1144
|
+
git_refdb_backend *_backend,
|
1145
|
+
const git_reference *ref,
|
1146
|
+
git_filebuf *file,
|
1147
|
+
int update_reflog,
|
1148
|
+
const git_signature *who,
|
1149
|
+
const char *message,
|
1150
|
+
const git_oid *old_id,
|
1151
|
+
const char *old_target)
|
1152
|
+
{
|
1153
|
+
refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
|
1154
|
+
int error = 0, cmp = 0, should_write;
|
1155
|
+
const char *new_target = NULL;
|
1156
|
+
const git_oid *new_id = NULL;
|
1157
|
+
|
1097
1158
|
if ((error = cmp_old_ref(&cmp, _backend, ref->name, old_id, old_target)) < 0)
|
1098
1159
|
goto on_error;
|
1099
1160
|
|
@@ -1118,20 +1179,22 @@ static int refdb_fs_backend__write(
|
|
1118
1179
|
goto on_error; /* not really error */
|
1119
1180
|
}
|
1120
1181
|
|
1121
|
-
if (
|
1122
|
-
|
1123
|
-
|
1124
|
-
if (should_write) {
|
1125
|
-
if ((error = reflog_append(backend, ref, NULL, NULL, who, message)) < 0)
|
1126
|
-
goto on_error;
|
1127
|
-
if ((error = maybe_append_head(backend, ref, who, message)) < 0)
|
1182
|
+
if (update_reflog) {
|
1183
|
+
if ((error = should_write_reflog(&should_write, backend->repo, ref->name)) < 0)
|
1128
1184
|
goto on_error;
|
1185
|
+
|
1186
|
+
if (should_write) {
|
1187
|
+
if ((error = reflog_append(backend, ref, NULL, NULL, who, message)) < 0)
|
1188
|
+
goto on_error;
|
1189
|
+
if ((error = maybe_append_head(backend, ref, who, message)) < 0)
|
1190
|
+
goto on_error;
|
1191
|
+
}
|
1129
1192
|
}
|
1130
1193
|
|
1131
|
-
return loose_commit(
|
1194
|
+
return loose_commit(file, ref);
|
1132
1195
|
|
1133
1196
|
on_error:
|
1134
|
-
git_filebuf_cleanup(
|
1197
|
+
git_filebuf_cleanup(file);
|
1135
1198
|
return error;
|
1136
1199
|
}
|
1137
1200
|
|
@@ -1141,17 +1204,29 @@ static int refdb_fs_backend__delete(
|
|
1141
1204
|
const git_oid *old_id, const char *old_target)
|
1142
1205
|
{
|
1143
1206
|
refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
|
1144
|
-
git_buf loose_path = GIT_BUF_INIT;
|
1145
|
-
size_t pack_pos;
|
1146
1207
|
git_filebuf file = GIT_FILEBUF_INIT;
|
1147
|
-
int error = 0
|
1148
|
-
bool loose_deleted = 0;
|
1208
|
+
int error = 0;
|
1149
1209
|
|
1150
1210
|
assert(backend && ref_name);
|
1151
1211
|
|
1152
1212
|
if ((error = loose_lock(&file, backend, ref_name)) < 0)
|
1153
1213
|
return error;
|
1154
1214
|
|
1215
|
+
return refdb_fs_backend__delete_tail(_backend, &file, ref_name, old_id, old_target);
|
1216
|
+
}
|
1217
|
+
|
1218
|
+
static int refdb_fs_backend__delete_tail(
|
1219
|
+
git_refdb_backend *_backend,
|
1220
|
+
git_filebuf *file,
|
1221
|
+
const char *ref_name,
|
1222
|
+
const git_oid *old_id, const char *old_target)
|
1223
|
+
{
|
1224
|
+
refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
|
1225
|
+
git_buf loose_path = GIT_BUF_INIT;
|
1226
|
+
size_t pack_pos;
|
1227
|
+
int error = 0, cmp = 0;
|
1228
|
+
bool loose_deleted = 0;
|
1229
|
+
|
1155
1230
|
error = cmp_old_ref(&cmp, _backend, ref_name, old_id, old_target);
|
1156
1231
|
if (error < 0)
|
1157
1232
|
goto cleanup;
|
@@ -1197,7 +1272,7 @@ static int refdb_fs_backend__delete(
|
|
1197
1272
|
error = packed_write(backend);
|
1198
1273
|
|
1199
1274
|
cleanup:
|
1200
|
-
git_filebuf_cleanup(
|
1275
|
+
git_filebuf_cleanup(file);
|
1201
1276
|
|
1202
1277
|
return error;
|
1203
1278
|
}
|
@@ -1578,11 +1653,6 @@ static int lock_reflog(git_filebuf *file, refdb_fs_backend *backend, const char
|
|
1578
1653
|
|
1579
1654
|
repo = backend->repo;
|
1580
1655
|
|
1581
|
-
if (!git_path_isvalid(backend->repo, refname, GIT_PATH_REJECT_DEFAULTS)) {
|
1582
|
-
giterr_set(GITERR_INVALID, "Invalid reference name '%s'.", refname);
|
1583
|
-
return GIT_EINVALIDSPEC;
|
1584
|
-
}
|
1585
|
-
|
1586
1656
|
if (retrieve_reflog_path(&log_path, repo, refname) < 0)
|
1587
1657
|
return -1;
|
1588
1658
|
|
@@ -1847,6 +1917,8 @@ int git_refdb_backend_fs(
|
|
1847
1917
|
backend->parent.del = &refdb_fs_backend__delete;
|
1848
1918
|
backend->parent.rename = &refdb_fs_backend__rename;
|
1849
1919
|
backend->parent.compress = &refdb_fs_backend__compress;
|
1920
|
+
backend->parent.lock = &refdb_fs_backend__lock;
|
1921
|
+
backend->parent.unlock = &refdb_fs_backend__unlock;
|
1850
1922
|
backend->parent.has_log = &refdb_reflog_fs__has_log;
|
1851
1923
|
backend->parent.ensure_log = &refdb_reflog_fs__ensure_log;
|
1852
1924
|
backend->parent.free = &refdb_fs_backend__free;
|
data/vendor/libgit2/src/reflog.c
CHANGED
@@ -148,7 +148,7 @@ size_t git_reflog_entrycount(git_reflog *reflog)
|
|
148
148
|
return reflog->entries.length;
|
149
149
|
}
|
150
150
|
|
151
|
-
const git_reflog_entry * git_reflog_entry_byindex(git_reflog *reflog, size_t idx)
|
151
|
+
const git_reflog_entry * git_reflog_entry_byindex(const git_reflog *reflog, size_t idx)
|
152
152
|
{
|
153
153
|
assert(reflog);
|
154
154
|
|
data/vendor/libgit2/src/refs.c
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
#include <git2/refdb.h>
|
23
23
|
#include <git2/sys/refs.h>
|
24
24
|
#include <git2/signature.h>
|
25
|
+
#include <git2/commit.h>
|
25
26
|
|
26
27
|
GIT__USE_STRMAP;
|
27
28
|
|
@@ -411,7 +412,7 @@ static int reference__create(
|
|
411
412
|
return 0;
|
412
413
|
}
|
413
414
|
|
414
|
-
|
415
|
+
int git_reference__log_signature(git_signature **out, git_repository *repo)
|
415
416
|
{
|
416
417
|
int error;
|
417
418
|
git_signature *who;
|
@@ -441,7 +442,7 @@ int git_reference_create_matching(
|
|
441
442
|
assert(id);
|
442
443
|
|
443
444
|
if (!signature) {
|
444
|
-
if ((error =
|
445
|
+
if ((error = git_reference__log_signature(&who, repo)) < 0)
|
445
446
|
return error;
|
446
447
|
else
|
447
448
|
signature = who;
|
@@ -482,7 +483,7 @@ int git_reference_symbolic_create_matching(
|
|
482
483
|
assert(target);
|
483
484
|
|
484
485
|
if (!signature) {
|
485
|
-
if ((error =
|
486
|
+
if ((error = git_reference__log_signature(&who, repo)) < 0)
|
486
487
|
return error;
|
487
488
|
else
|
488
489
|
signature = who;
|
@@ -1090,6 +1091,40 @@ int git_reference__update_terminal(
|
|
1090
1091
|
return reference__update_terminal(repo, ref_name, oid, 0, signature, log_message);
|
1091
1092
|
}
|
1092
1093
|
|
1094
|
+
int git_reference__update_for_commit(
|
1095
|
+
git_repository *repo,
|
1096
|
+
git_reference *ref,
|
1097
|
+
const char *ref_name,
|
1098
|
+
const git_oid *id,
|
1099
|
+
const git_signature *committer,
|
1100
|
+
const char *operation)
|
1101
|
+
{
|
1102
|
+
git_reference *ref_new = NULL;
|
1103
|
+
git_commit *commit = NULL;
|
1104
|
+
git_buf reflog_msg = GIT_BUF_INIT;
|
1105
|
+
int error;
|
1106
|
+
|
1107
|
+
if ((error = git_commit_lookup(&commit, repo, id)) < 0 ||
|
1108
|
+
(error = git_buf_printf(&reflog_msg, "%s%s: %s",
|
1109
|
+
operation ? operation : "commit",
|
1110
|
+
git_commit_parentcount(commit) == 0 ? " (initial)" : "",
|
1111
|
+
git_commit_summary(commit))) < 0)
|
1112
|
+
goto done;
|
1113
|
+
|
1114
|
+
if (ref)
|
1115
|
+
error = git_reference_set_target(
|
1116
|
+
&ref_new, ref, id, committer, git_buf_cstr(&reflog_msg));
|
1117
|
+
else
|
1118
|
+
error = git_reference__update_terminal(
|
1119
|
+
repo, ref_name, id, committer, git_buf_cstr(&reflog_msg));
|
1120
|
+
|
1121
|
+
done:
|
1122
|
+
git_reference_free(ref_new);
|
1123
|
+
git_buf_free(&reflog_msg);
|
1124
|
+
git_commit_free(commit);
|
1125
|
+
return error;
|
1126
|
+
}
|
1127
|
+
|
1093
1128
|
int git_reference_has_log(git_repository *repo, const char *refname)
|
1094
1129
|
{
|
1095
1130
|
int error;
|
data/vendor/libgit2/src/refs.h
CHANGED
@@ -35,7 +35,7 @@
|
|
35
35
|
#define GIT_FETCH_HEAD_FILE "FETCH_HEAD"
|
36
36
|
#define GIT_MERGE_HEAD_FILE "MERGE_HEAD"
|
37
37
|
#define GIT_REVERT_HEAD_FILE "REVERT_HEAD"
|
38
|
-
#define
|
38
|
+
#define GIT_CHERRYPICK_HEAD_FILE "CHERRY_PICK_HEAD"
|
39
39
|
#define GIT_BISECT_LOG_FILE "BISECT_LOG"
|
40
40
|
#define GIT_REBASE_MERGE_DIR "rebase-merge/"
|
41
41
|
#define GIT_REBASE_MERGE_INTERACTIVE_FILE GIT_REBASE_MERGE_DIR "interactive"
|
@@ -63,7 +63,7 @@ struct git_reference {
|
|
63
63
|
} target;
|
64
64
|
|
65
65
|
git_oid peel;
|
66
|
-
char name[
|
66
|
+
char name[GIT_FLEX_ARRAY];
|
67
67
|
};
|
68
68
|
|
69
69
|
git_reference *git_reference__set_name(git_reference *ref, const char *name);
|
@@ -98,4 +98,15 @@ int git_reference_lookup_resolved(
|
|
98
98
|
const char *name,
|
99
99
|
int max_deref);
|
100
100
|
|
101
|
+
int git_reference__log_signature(git_signature **out, git_repository *repo);
|
102
|
+
|
103
|
+
/** Update a reference after a commit. */
|
104
|
+
int git_reference__update_for_commit(
|
105
|
+
git_repository *repo,
|
106
|
+
git_reference *ref,
|
107
|
+
const char *ref_name,
|
108
|
+
const git_oid *id,
|
109
|
+
const git_signature *committer,
|
110
|
+
const char *operation);
|
111
|
+
|
101
112
|
#endif
|
@@ -119,6 +119,12 @@ int git_refspec__parse(git_refspec *refspec, const char *input, bool is_fetch)
|
|
119
119
|
if (!git_reference__is_valid_name(refspec->dst, flags))
|
120
120
|
goto invalid;
|
121
121
|
}
|
122
|
+
|
123
|
+
/* if the RHS is empty, then it's a copy of the LHS */
|
124
|
+
if (!refspec->dst) {
|
125
|
+
refspec->dst = git__strdup(refspec->src);
|
126
|
+
GITERR_CHECK_ALLOC(refspec->dst);
|
127
|
+
}
|
122
128
|
}
|
123
129
|
|
124
130
|
refspec->string = git__strdup(input);
|
@@ -223,7 +229,13 @@ static int refspec_transform(
|
|
223
229
|
|
224
230
|
int git_refspec_transform(git_buf *out, const git_refspec *spec, const char *name)
|
225
231
|
{
|
226
|
-
|
232
|
+
assert(out && spec && name);
|
233
|
+
git_buf_sanitize(out);
|
234
|
+
|
235
|
+
if (!git_refspec_src_matches(spec, name)) {
|
236
|
+
giterr_set(GITERR_INVALID, "ref '%s' doesn't match the source", name);
|
237
|
+
return -1;
|
238
|
+
}
|
227
239
|
|
228
240
|
if (!spec->pattern)
|
229
241
|
return git_buf_puts(out, spec->dst);
|
@@ -233,7 +245,13 @@ int git_refspec_transform(git_buf *out, const git_refspec *spec, const char *nam
|
|
233
245
|
|
234
246
|
int git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name)
|
235
247
|
{
|
236
|
-
|
248
|
+
assert(out && spec && name);
|
249
|
+
git_buf_sanitize(out);
|
250
|
+
|
251
|
+
if (!git_refspec_dst_matches(spec, name)) {
|
252
|
+
giterr_set(GITERR_INVALID, "ref '%s' doesn't match the destination", name);
|
253
|
+
return -1;
|
254
|
+
}
|
237
255
|
|
238
256
|
if (!spec->pattern)
|
239
257
|
return git_buf_puts(out, spec->src);
|
data/vendor/libgit2/src/remote.c
CHANGED
@@ -21,7 +21,7 @@
|
|
21
21
|
|
22
22
|
static int dwim_refspecs(git_vector *out, git_vector *refspecs, git_vector *refs);
|
23
23
|
|
24
|
-
static int
|
24
|
+
static int add_refspec_to(git_vector *vector, const char *string, bool is_fetch)
|
25
25
|
{
|
26
26
|
git_refspec *spec;
|
27
27
|
|
@@ -34,7 +34,7 @@ static int add_refspec(git_remote *remote, const char *string, bool is_fetch)
|
|
34
34
|
}
|
35
35
|
|
36
36
|
spec->push = !is_fetch;
|
37
|
-
if (git_vector_insert(
|
37
|
+
if (git_vector_insert(vector, spec) < 0) {
|
38
38
|
git_refspec__free(spec);
|
39
39
|
git__free(spec);
|
40
40
|
return -1;
|
@@ -43,6 +43,11 @@ static int add_refspec(git_remote *remote, const char *string, bool is_fetch)
|
|
43
43
|
return 0;
|
44
44
|
}
|
45
45
|
|
46
|
+
static int add_refspec(git_remote *remote, const char *string, bool is_fetch)
|
47
|
+
{
|
48
|
+
return add_refspec_to(&remote->refspecs, string, is_fetch);
|
49
|
+
}
|
50
|
+
|
46
51
|
static int download_tags_value(git_remote *remote, git_config *cfg)
|
47
52
|
{
|
48
53
|
const git_config_entry *ce;
|
@@ -80,6 +85,8 @@ static int ensure_remote_name_is_valid(const char *name)
|
|
80
85
|
return error;
|
81
86
|
}
|
82
87
|
|
88
|
+
#if 0
|
89
|
+
/* We could export this as a helper */
|
83
90
|
static int get_check_cert(int *out, git_repository *repo)
|
84
91
|
{
|
85
92
|
git_config *cfg;
|
@@ -105,11 +112,32 @@ static int get_check_cert(int *out, git_repository *repo)
|
|
105
112
|
*out = git_config__get_bool_force(cfg, "http.sslverify", 1);
|
106
113
|
return 0;
|
107
114
|
}
|
115
|
+
#endif
|
116
|
+
|
117
|
+
static int canonicalize_url(git_buf *out, const char *in)
|
118
|
+
{
|
119
|
+
#ifdef GIT_WIN32
|
120
|
+
const char *c;
|
121
|
+
|
122
|
+
/* Given a UNC path like \\server\path, we need to convert this
|
123
|
+
* to //server/path for compatibility with core git.
|
124
|
+
*/
|
125
|
+
if (in[0] == '\\' && in[1] == '\\' &&
|
126
|
+
(git__isalpha(in[2]) || git__isdigit(in[2]))) {
|
127
|
+
for (c = in; *c; c++)
|
128
|
+
git_buf_putc(out, *c == '\\' ? '/' : *c);
|
129
|
+
|
130
|
+
return git_buf_oom(out) ? -1 : 0;
|
131
|
+
}
|
132
|
+
#endif
|
133
|
+
|
134
|
+
return git_buf_puts(out, in);
|
135
|
+
}
|
108
136
|
|
109
137
|
static int create_internal(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch)
|
110
138
|
{
|
111
139
|
git_remote *remote;
|
112
|
-
git_buf fetchbuf = GIT_BUF_INIT;
|
140
|
+
git_buf canonical_url = GIT_BUF_INIT, fetchbuf = GIT_BUF_INIT;
|
113
141
|
int error = -1;
|
114
142
|
|
115
143
|
/* name is optional */
|
@@ -121,14 +149,11 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
|
|
121
149
|
remote->repo = repo;
|
122
150
|
remote->update_fetchhead = 1;
|
123
151
|
|
124
|
-
if (
|
152
|
+
if (git_vector_init(&remote->refs, 32, NULL) < 0 ||
|
153
|
+
canonicalize_url(&canonical_url, url) < 0)
|
125
154
|
goto on_error;
|
126
155
|
|
127
|
-
|
128
|
-
goto on_error;
|
129
|
-
|
130
|
-
remote->url = git__strdup(url);
|
131
|
-
GITERR_CHECK_ALLOC(remote->url);
|
156
|
+
remote->url = git_buf_detach(&canonical_url);
|
132
157
|
|
133
158
|
if (name != NULL) {
|
134
159
|
remote->name = git__strdup(name);
|
@@ -138,6 +163,10 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
|
|
138
163
|
if (fetch != NULL) {
|
139
164
|
if (add_refspec(remote, fetch, true) < 0)
|
140
165
|
goto on_error;
|
166
|
+
|
167
|
+
/* Move the data over to where the matching functions can find them */
|
168
|
+
if (dwim_refspecs(&remote->active_refspecs, &remote->refspecs, &remote->refs) < 0)
|
169
|
+
goto on_error;
|
141
170
|
}
|
142
171
|
|
143
172
|
if (!name)
|
@@ -146,11 +175,13 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
|
|
146
175
|
|
147
176
|
*out = remote;
|
148
177
|
git_buf_free(&fetchbuf);
|
178
|
+
git_buf_free(&canonical_url);
|
149
179
|
return 0;
|
150
180
|
|
151
181
|
on_error:
|
152
182
|
git_remote_free(remote);
|
153
183
|
git_buf_free(&fetchbuf);
|
184
|
+
git_buf_free(&canonical_url);
|
154
185
|
return error;
|
155
186
|
}
|
156
187
|
|
@@ -159,7 +190,7 @@ static int ensure_remote_doesnot_exist(git_repository *repo, const char *name)
|
|
159
190
|
int error;
|
160
191
|
git_remote *remote;
|
161
192
|
|
162
|
-
error =
|
193
|
+
error = git_remote_lookup(&remote, repo, name);
|
163
194
|
|
164
195
|
if (error == GIT_ENOTFOUND)
|
165
196
|
return 0;
|
@@ -180,34 +211,15 @@ static int ensure_remote_doesnot_exist(git_repository *repo, const char *name)
|
|
180
211
|
int git_remote_create(git_remote **out, git_repository *repo, const char *name, const char *url)
|
181
212
|
{
|
182
213
|
git_buf buf = GIT_BUF_INIT;
|
183
|
-
git_remote *remote = NULL;
|
184
214
|
int error;
|
185
215
|
|
186
|
-
if ((error = ensure_remote_name_is_valid(name)) < 0)
|
187
|
-
return error;
|
188
|
-
|
189
|
-
if ((error = ensure_remote_doesnot_exist(repo, name)) < 0)
|
190
|
-
return error;
|
191
|
-
|
192
216
|
if (git_buf_printf(&buf, "+refs/heads/*:refs/remotes/%s/*", name) < 0)
|
193
217
|
return -1;
|
194
218
|
|
195
|
-
|
196
|
-
goto on_error;
|
197
|
-
|
219
|
+
error = git_remote_create_with_fetchspec(out, repo, name, url, git_buf_cstr(&buf));
|
198
220
|
git_buf_free(&buf);
|
199
221
|
|
200
|
-
|
201
|
-
goto on_error;
|
202
|
-
|
203
|
-
*out = remote;
|
204
|
-
|
205
|
-
return 0;
|
206
|
-
|
207
|
-
on_error:
|
208
|
-
git_buf_free(&buf);
|
209
|
-
git_remote_free(remote);
|
210
|
-
return -1;
|
222
|
+
return error;
|
211
223
|
}
|
212
224
|
|
213
225
|
int git_remote_create_with_fetchspec(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch)
|
@@ -267,12 +279,13 @@ int git_remote_dup(git_remote **dest, git_remote *source)
|
|
267
279
|
|
268
280
|
if (source->pushurl != NULL) {
|
269
281
|
remote->pushurl = git__strdup(source->pushurl);
|
270
|
-
GITERR_CHECK_ALLOC(remote->pushurl);
|
282
|
+
GITERR_CHECK_ALLOC(remote->pushurl);
|
271
283
|
}
|
272
284
|
|
285
|
+
remote->transport_cb = source->transport_cb;
|
286
|
+
remote->transport_cb_payload = source->transport_cb_payload;
|
273
287
|
remote->repo = source->repo;
|
274
288
|
remote->download_tags = source->download_tags;
|
275
|
-
remote->check_cert = source->check_cert;
|
276
289
|
remote->update_fetchhead = source->update_fetchhead;
|
277
290
|
|
278
291
|
if (git_vector_init(&remote->refs, 32, NULL) < 0 ||
|
@@ -341,7 +354,7 @@ static int get_optional_config(
|
|
341
354
|
return error;
|
342
355
|
}
|
343
356
|
|
344
|
-
int
|
357
|
+
int git_remote_lookup(git_remote **out, git_repository *repo, const char *name)
|
345
358
|
{
|
346
359
|
git_remote *remote;
|
347
360
|
git_buf buf = GIT_BUF_INIT;
|
@@ -367,11 +380,9 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
|
|
367
380
|
remote->name = git__strdup(name);
|
368
381
|
GITERR_CHECK_ALLOC(remote->name);
|
369
382
|
|
370
|
-
if ((error = get_check_cert(&remote->check_cert, repo)) < 0)
|
371
|
-
goto cleanup;
|
372
|
-
|
373
383
|
if (git_vector_init(&remote->refs, 32, NULL) < 0 ||
|
374
384
|
git_vector_init(&remote->refspecs, 2, NULL) < 0 ||
|
385
|
+
git_vector_init(&remote->passive_refspecs, 2, NULL) < 0 ||
|
375
386
|
git_vector_init(&remote->active_refspecs, 2, NULL) < 0) {
|
376
387
|
error = -1;
|
377
388
|
goto cleanup;
|
@@ -659,18 +670,21 @@ int git_remote_connect(git_remote *remote, git_direction direction)
|
|
659
670
|
return -1;
|
660
671
|
}
|
661
672
|
|
662
|
-
/*
|
663
|
-
*
|
673
|
+
/* If we don't have a transport object yet, and the caller specified a
|
674
|
+
* custom transport factory, use that */
|
675
|
+
if (!t && remote->transport_cb &&
|
676
|
+
(error = remote->transport_cb(&t, remote, remote->transport_cb_payload)) < 0)
|
677
|
+
return error;
|
678
|
+
|
679
|
+
/* If we still don't have a transport, then use the global
|
680
|
+
* transport registrations which map URI schemes to transport factories */
|
664
681
|
if (!t && (error = git_transport_new(&t, remote, url)) < 0)
|
665
682
|
return error;
|
666
683
|
|
667
684
|
if (t->set_callbacks &&
|
668
|
-
|
685
|
+
(error = t->set_callbacks(t, remote->callbacks.sideband_progress, NULL, remote->callbacks.certificate_check, remote->callbacks.payload)) < 0)
|
669
686
|
goto on_error;
|
670
687
|
|
671
|
-
if (!remote->check_cert)
|
672
|
-
flags |= GIT_TRANSPORTFLAGS_NO_CHECK_CERT;
|
673
|
-
|
674
688
|
if ((error = t->connect(t, url, remote->callbacks.credentials, remote->callbacks.payload, direction, flags)) != 0)
|
675
689
|
goto on_error;
|
676
690
|
|
@@ -812,20 +826,43 @@ static int ls_to_vector(git_vector *out, git_remote *remote)
|
|
812
826
|
return 0;
|
813
827
|
}
|
814
828
|
|
815
|
-
int git_remote_download(git_remote *remote)
|
829
|
+
int git_remote_download(git_remote *remote, const git_strarray *refspecs)
|
816
830
|
{
|
817
|
-
int error;
|
818
|
-
|
831
|
+
int error = -1;
|
832
|
+
size_t i;
|
833
|
+
git_vector refs, specs, *to_active;
|
819
834
|
|
820
835
|
assert(remote);
|
821
836
|
|
822
837
|
if (ls_to_vector(&refs, remote) < 0)
|
823
838
|
return -1;
|
824
839
|
|
840
|
+
if ((git_vector_init(&specs, 0, NULL)) < 0)
|
841
|
+
goto on_error;
|
842
|
+
|
843
|
+
remote->passed_refspecs = 0;
|
844
|
+
if (!refspecs || !refspecs->count) {
|
845
|
+
to_active = &remote->refspecs;
|
846
|
+
} else {
|
847
|
+
for (i = 0; i < refspecs->count; i++) {
|
848
|
+
if ((error = add_refspec_to(&specs, refspecs->strings[i], true)) < 0)
|
849
|
+
goto on_error;
|
850
|
+
}
|
851
|
+
|
852
|
+
to_active = &specs;
|
853
|
+
remote->passed_refspecs = 1;
|
854
|
+
}
|
855
|
+
|
856
|
+
free_refspecs(&remote->passive_refspecs);
|
857
|
+
if ((error = dwim_refspecs(&remote->passive_refspecs, &remote->refspecs, &refs)) < 0)
|
858
|
+
goto on_error;
|
859
|
+
|
825
860
|
free_refspecs(&remote->active_refspecs);
|
861
|
+
error = dwim_refspecs(&remote->active_refspecs, to_active, &refs);
|
826
862
|
|
827
|
-
error = dwim_refspecs(&remote->active_refspecs, &remote->refspecs, &refs);
|
828
863
|
git_vector_free(&refs);
|
864
|
+
free_refspecs(&specs);
|
865
|
+
git_vector_free(&specs);
|
829
866
|
|
830
867
|
if (error < 0)
|
831
868
|
return error;
|
@@ -834,10 +871,17 @@ int git_remote_download(git_remote *remote)
|
|
834
871
|
return error;
|
835
872
|
|
836
873
|
return git_fetch_download_pack(remote);
|
874
|
+
|
875
|
+
on_error:
|
876
|
+
git_vector_free(&refs);
|
877
|
+
free_refspecs(&specs);
|
878
|
+
git_vector_free(&specs);
|
879
|
+
return error;
|
837
880
|
}
|
838
881
|
|
839
882
|
int git_remote_fetch(
|
840
883
|
git_remote *remote,
|
884
|
+
const git_strarray *refspecs,
|
841
885
|
const git_signature *signature,
|
842
886
|
const char *reflog_message)
|
843
887
|
{
|
@@ -848,7 +892,7 @@ int git_remote_fetch(
|
|
848
892
|
if ((error = git_remote_connect(remote, GIT_DIRECTION_FETCH)) != 0)
|
849
893
|
return error;
|
850
894
|
|
851
|
-
error = git_remote_download(remote);
|
895
|
+
error = git_remote_download(remote, refspecs);
|
852
896
|
|
853
897
|
/* We don't need to be connected anymore */
|
854
898
|
git_remote_disconnect(remote);
|
@@ -890,21 +934,50 @@ static int remote_head_for_fetchspec_src(git_remote_head **out, git_vector *upda
|
|
890
934
|
return 0;
|
891
935
|
}
|
892
936
|
|
893
|
-
static int
|
937
|
+
static int ref_to_update(int *update, git_buf *remote_name, git_remote *remote, git_refspec *spec, const char *ref_name)
|
938
|
+
{
|
939
|
+
int error = 0;
|
940
|
+
git_repository *repo;
|
941
|
+
git_buf upstream_remote = GIT_BUF_INIT;
|
942
|
+
git_buf upstream_name = GIT_BUF_INIT;
|
943
|
+
|
944
|
+
repo = git_remote_owner(remote);
|
945
|
+
|
946
|
+
if ((!git_reference__is_branch(ref_name)) ||
|
947
|
+
!git_remote_name(remote) ||
|
948
|
+
(error = git_branch_upstream_remote(&upstream_remote, repo, ref_name) < 0) ||
|
949
|
+
git__strcmp(git_remote_name(remote), git_buf_cstr(&upstream_remote)) ||
|
950
|
+
(error = git_branch_upstream_name(&upstream_name, repo, ref_name)) < 0 ||
|
951
|
+
!git_refspec_dst_matches(spec, git_buf_cstr(&upstream_name)) ||
|
952
|
+
(error = git_refspec_rtransform(remote_name, spec, upstream_name.ptr)) < 0) {
|
953
|
+
/* Not an error if there is no upstream */
|
954
|
+
if (error == GIT_ENOTFOUND) {
|
955
|
+
giterr_clear();
|
956
|
+
error = 0;
|
957
|
+
}
|
958
|
+
|
959
|
+
*update = 0;
|
960
|
+
} else {
|
961
|
+
*update = 1;
|
962
|
+
}
|
963
|
+
|
964
|
+
git_buf_free(&upstream_remote);
|
965
|
+
git_buf_free(&upstream_name);
|
966
|
+
return error;
|
967
|
+
}
|
968
|
+
|
969
|
+
static int remote_head_for_ref(git_remote_head **out, git_remote *remote, git_refspec *spec, git_vector *update_heads, git_reference *ref)
|
894
970
|
{
|
895
971
|
git_reference *resolved_ref = NULL;
|
896
972
|
git_buf remote_name = GIT_BUF_INIT;
|
897
|
-
|
898
|
-
git_repository *repo;
|
973
|
+
git_config *config = NULL;
|
899
974
|
const char *ref_name;
|
900
|
-
int error = 0;
|
975
|
+
int error = 0, update;
|
901
976
|
|
902
977
|
assert(out && spec && ref);
|
903
978
|
|
904
979
|
*out = NULL;
|
905
980
|
|
906
|
-
repo = git_reference_owner(ref);
|
907
|
-
|
908
981
|
error = git_reference_resolve(&resolved_ref, ref);
|
909
982
|
|
910
983
|
/* If we're in an unborn branch, let's pretend nothing happened */
|
@@ -915,22 +988,15 @@ static int remote_head_for_ref(git_remote_head **out, git_refspec *spec, git_vec
|
|
915
988
|
ref_name = git_reference_name(resolved_ref);
|
916
989
|
}
|
917
990
|
|
918
|
-
if ((
|
919
|
-
(error = git_branch_upstream_name(&upstream_name, repo, ref_name)) < 0 ||
|
920
|
-
(error = git_refspec_rtransform(&remote_name, spec, upstream_name.ptr)) < 0) {
|
921
|
-
/* Not an error if there is no upstream */
|
922
|
-
if (error == GIT_ENOTFOUND)
|
923
|
-
error = 0;
|
924
|
-
|
991
|
+
if ((error = ref_to_update(&update, &remote_name, remote, spec, ref_name)) < 0)
|
925
992
|
goto cleanup;
|
926
|
-
}
|
927
993
|
|
928
|
-
|
994
|
+
if (update)
|
995
|
+
error = remote_head_for_fetchspec_src(out, update_heads, git_buf_cstr(&remote_name));
|
929
996
|
|
930
997
|
cleanup:
|
931
998
|
git_reference_free(resolved_ref);
|
932
|
-
|
933
|
-
git_buf_free(&upstream_name);
|
999
|
+
git_config_free(config);
|
934
1000
|
return error;
|
935
1001
|
}
|
936
1002
|
|
@@ -959,7 +1025,7 @@ static int git_remote_write_fetchhead(git_remote *remote, git_refspec *spec, git
|
|
959
1025
|
/* Determine what to merge: if refspec was a wildcard, just use HEAD */
|
960
1026
|
if (git_refspec_is_wildcard(spec)) {
|
961
1027
|
if ((error = git_reference_lookup(&head_ref, remote->repo, GIT_HEAD_FILE)) < 0 ||
|
962
|
-
(error = remote_head_for_ref(&merge_remote_ref, spec, update_heads, head_ref)) < 0)
|
1028
|
+
(error = remote_head_for_ref(&merge_remote_ref, remote, spec, update_heads, head_ref)) < 0)
|
963
1029
|
goto cleanup;
|
964
1030
|
} else {
|
965
1031
|
/* If we're fetching a single refspec, that's the only thing that should be in FETCH_HEAD. */
|
@@ -1036,24 +1102,26 @@ static int update_tips_for_spec(
|
|
1036
1102
|
if (!git_reference_is_valid_name(head->name))
|
1037
1103
|
continue;
|
1038
1104
|
|
1039
|
-
if (git_refspec_src_matches(
|
1040
|
-
if (
|
1041
|
-
goto on_error;
|
1042
|
-
} else if (remote->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_NONE) {
|
1105
|
+
if (git_refspec_src_matches(&tagspec, head->name)) {
|
1106
|
+
if (remote->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_NONE) {
|
1043
1107
|
|
1044
|
-
|
1045
|
-
|
1108
|
+
if (remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_AUTO)
|
1109
|
+
autotag = 1;
|
1046
1110
|
|
1047
|
-
|
1111
|
+
git_buf_clear(&refname);
|
1112
|
+
if (git_buf_puts(&refname, head->name) < 0)
|
1113
|
+
goto on_error;
|
1114
|
+
} else {
|
1048
1115
|
continue;
|
1049
|
-
|
1050
|
-
|
1051
|
-
if (
|
1116
|
+
}
|
1117
|
+
} else if (git_refspec_src_matches(spec, head->name) && spec->dst) {
|
1118
|
+
if (git_refspec_transform(&refname, spec, head->name) < 0)
|
1052
1119
|
goto on_error;
|
1053
1120
|
} else {
|
1054
1121
|
continue;
|
1055
1122
|
}
|
1056
1123
|
|
1124
|
+
/* In autotag mode, only create tags for objects already in db */
|
1057
1125
|
if (autotag && !git_odb_exists(odb, &head->oid))
|
1058
1126
|
continue;
|
1059
1127
|
|
@@ -1105,6 +1173,97 @@ on_error:
|
|
1105
1173
|
|
1106
1174
|
}
|
1107
1175
|
|
1176
|
+
/**
|
1177
|
+
* Iteration over the three vectors, with a pause whenever we find a match
|
1178
|
+
*
|
1179
|
+
* On each stop, we store the iteration stat in the inout i,j,k
|
1180
|
+
* parameters, and return the currently matching passive refspec as
|
1181
|
+
* well as the head which we matched.
|
1182
|
+
*/
|
1183
|
+
static int next_head(const git_remote *remote, git_vector *refs,
|
1184
|
+
git_refspec **out_spec, git_remote_head **out_head,
|
1185
|
+
size_t *out_i, size_t *out_j, size_t *out_k)
|
1186
|
+
{
|
1187
|
+
const git_vector *active, *passive;
|
1188
|
+
git_remote_head *head;
|
1189
|
+
git_refspec *spec, *passive_spec;
|
1190
|
+
size_t i, j, k;
|
1191
|
+
|
1192
|
+
active = &remote->active_refspecs;
|
1193
|
+
passive = &remote->passive_refspecs;
|
1194
|
+
|
1195
|
+
i = *out_i;
|
1196
|
+
j = *out_j;
|
1197
|
+
k = *out_k;
|
1198
|
+
|
1199
|
+
for (; i < refs->length; i++) {
|
1200
|
+
head = git_vector_get(refs, i);
|
1201
|
+
|
1202
|
+
if (!git_reference_is_valid_name(head->name))
|
1203
|
+
continue;
|
1204
|
+
|
1205
|
+
for (; j < active->length; j++) {
|
1206
|
+
spec = git_vector_get(active, j);
|
1207
|
+
|
1208
|
+
if (!git_refspec_src_matches(spec, head->name))
|
1209
|
+
continue;
|
1210
|
+
|
1211
|
+
for (; k < passive->length; k++) {
|
1212
|
+
passive_spec = git_vector_get(passive, k);
|
1213
|
+
|
1214
|
+
if (!git_refspec_src_matches(passive_spec, head->name))
|
1215
|
+
continue;
|
1216
|
+
|
1217
|
+
*out_spec = passive_spec;
|
1218
|
+
*out_head = head;
|
1219
|
+
*out_i = i;
|
1220
|
+
*out_j = j;
|
1221
|
+
*out_k = k + 1;
|
1222
|
+
return 0;
|
1223
|
+
|
1224
|
+
}
|
1225
|
+
k = 0;
|
1226
|
+
}
|
1227
|
+
j = 0;
|
1228
|
+
}
|
1229
|
+
|
1230
|
+
return GIT_ITEROVER;
|
1231
|
+
}
|
1232
|
+
|
1233
|
+
static int opportunistic_updates(const git_remote *remote, git_vector *refs, const git_signature *sig, const char *msg)
|
1234
|
+
{
|
1235
|
+
size_t i, j, k;
|
1236
|
+
git_refspec *spec;
|
1237
|
+
git_remote_head *head;
|
1238
|
+
git_reference *ref;
|
1239
|
+
git_buf refname = GIT_BUF_INIT;
|
1240
|
+
int error;
|
1241
|
+
|
1242
|
+
i = j = k = 0;
|
1243
|
+
|
1244
|
+
while ((error = next_head(remote, refs, &spec, &head, &i, &j, &k)) == 0) {
|
1245
|
+
/*
|
1246
|
+
* If we got here, there is a refspec which was used
|
1247
|
+
* for fetching which matches the source of one of the
|
1248
|
+
* passive refspecs, so we should update that
|
1249
|
+
* remote-tracking branch, but not add it to
|
1250
|
+
* FETCH_HEAD
|
1251
|
+
*/
|
1252
|
+
|
1253
|
+
if ((error = git_refspec_transform(&refname, spec, head->name)) < 0)
|
1254
|
+
return error;
|
1255
|
+
|
1256
|
+
error = git_reference_create(&ref, remote->repo, refname.ptr, &head->oid, true, sig, msg);
|
1257
|
+
git_buf_free(&refname);
|
1258
|
+
git_reference_free(ref);
|
1259
|
+
|
1260
|
+
if (error < 0)
|
1261
|
+
return error;
|
1262
|
+
}
|
1263
|
+
|
1264
|
+
return 0;
|
1265
|
+
}
|
1266
|
+
|
1108
1267
|
int git_remote_update_tips(
|
1109
1268
|
git_remote *remote,
|
1110
1269
|
const git_signature *signature,
|
@@ -1123,8 +1282,8 @@ int git_remote_update_tips(
|
|
1123
1282
|
goto out;
|
1124
1283
|
|
1125
1284
|
if (remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_ALL) {
|
1126
|
-
error = update_tips_for_spec(remote, &tagspec, &refs, signature, reflog_message)
|
1127
|
-
|
1285
|
+
if ((error = update_tips_for_spec(remote, &tagspec, &refs, signature, reflog_message)) < 0)
|
1286
|
+
goto out;
|
1128
1287
|
}
|
1129
1288
|
|
1130
1289
|
git_vector_foreach(&remote->active_refspecs, i, spec) {
|
@@ -1135,6 +1294,10 @@ int git_remote_update_tips(
|
|
1135
1294
|
goto out;
|
1136
1295
|
}
|
1137
1296
|
|
1297
|
+
/* only try to do opportunisitic updates if the refpec lists differ */
|
1298
|
+
if (remote->passed_refspecs)
|
1299
|
+
error = opportunistic_updates(remote, &refs, signature, reflog_message);
|
1300
|
+
|
1138
1301
|
out:
|
1139
1302
|
git_vector_free(&refs);
|
1140
1303
|
git_refspec__free(&tagspec);
|
@@ -1188,6 +1351,9 @@ void git_remote_free(git_remote *remote)
|
|
1188
1351
|
free_refspecs(&remote->active_refspecs);
|
1189
1352
|
git_vector_free(&remote->active_refspecs);
|
1190
1353
|
|
1354
|
+
free_refspecs(&remote->passive_refspecs);
|
1355
|
+
git_vector_free(&remote->passive_refspecs);
|
1356
|
+
|
1191
1357
|
git__free(remote->url);
|
1192
1358
|
git__free(remote->pushurl);
|
1193
1359
|
git__free(remote->name);
|
@@ -1240,13 +1406,6 @@ int git_remote_list(git_strarray *remotes_list, git_repository *repo)
|
|
1240
1406
|
return 0;
|
1241
1407
|
}
|
1242
1408
|
|
1243
|
-
void git_remote_check_cert(git_remote *remote, int check)
|
1244
|
-
{
|
1245
|
-
assert(remote);
|
1246
|
-
|
1247
|
-
remote->check_cert = check;
|
1248
|
-
}
|
1249
|
-
|
1250
1409
|
int git_remote_set_callbacks(git_remote *remote, const git_remote_callbacks *callbacks)
|
1251
1410
|
{
|
1252
1411
|
assert(remote && callbacks);
|
@@ -1259,6 +1418,7 @@ int git_remote_set_callbacks(git_remote *remote, const git_remote_callbacks *cal
|
|
1259
1418
|
return remote->transport->set_callbacks(remote->transport,
|
1260
1419
|
remote->callbacks.sideband_progress,
|
1261
1420
|
NULL,
|
1421
|
+
remote->callbacks.certificate_check,
|
1262
1422
|
remote->callbacks.payload);
|
1263
1423
|
|
1264
1424
|
return 0;
|
@@ -1271,18 +1431,20 @@ const git_remote_callbacks *git_remote_get_callbacks(git_remote *remote)
|
|
1271
1431
|
return &remote->callbacks;
|
1272
1432
|
}
|
1273
1433
|
|
1274
|
-
int git_remote_set_transport(
|
1434
|
+
int git_remote_set_transport(
|
1435
|
+
git_remote *remote,
|
1436
|
+
git_transport_cb transport_cb,
|
1437
|
+
void *payload)
|
1275
1438
|
{
|
1276
|
-
assert(remote
|
1277
|
-
|
1278
|
-
GITERR_CHECK_VERSION(transport, GIT_TRANSPORT_VERSION, "git_transport");
|
1439
|
+
assert(remote);
|
1279
1440
|
|
1280
1441
|
if (remote->transport) {
|
1281
1442
|
giterr_set(GITERR_NET, "A transport is already bound to this remote");
|
1282
1443
|
return -1;
|
1283
1444
|
}
|
1284
1445
|
|
1285
|
-
remote->
|
1446
|
+
remote->transport_cb = transport_cb;
|
1447
|
+
remote->transport_cb_payload = payload;
|
1286
1448
|
return 0;
|
1287
1449
|
}
|
1288
1450
|
|
@@ -1525,48 +1687,44 @@ static int rename_fetch_refspecs(git_vector *problems, git_remote *remote, const
|
|
1525
1687
|
return error;
|
1526
1688
|
}
|
1527
1689
|
|
1528
|
-
int git_remote_rename(git_strarray *out,
|
1690
|
+
int git_remote_rename(git_strarray *out, git_repository *repo, const char *name, const char *new_name)
|
1529
1691
|
{
|
1530
1692
|
int error;
|
1531
|
-
git_vector problem_refspecs;
|
1532
|
-
|
1693
|
+
git_vector problem_refspecs = GIT_VECTOR_INIT;
|
1694
|
+
git_remote *remote = NULL;
|
1533
1695
|
|
1534
|
-
assert(out &&
|
1696
|
+
assert(out && repo && name && new_name);
|
1535
1697
|
|
1536
|
-
if (
|
1537
|
-
|
1538
|
-
return GIT_EINVALIDSPEC;
|
1539
|
-
}
|
1698
|
+
if ((error = git_remote_lookup(&remote, repo, name)) < 0)
|
1699
|
+
return error;
|
1540
1700
|
|
1541
1701
|
if ((error = ensure_remote_name_is_valid(new_name)) < 0)
|
1542
|
-
|
1702
|
+
goto cleanup;
|
1543
1703
|
|
1544
|
-
if ((error = ensure_remote_doesnot_exist(
|
1545
|
-
|
1704
|
+
if ((error = ensure_remote_doesnot_exist(repo, new_name)) < 0)
|
1705
|
+
goto cleanup;
|
1546
1706
|
|
1547
|
-
if ((error = rename_remote_config_section(
|
1548
|
-
|
1707
|
+
if ((error = rename_remote_config_section(repo, name, new_name)) < 0)
|
1708
|
+
goto cleanup;
|
1549
1709
|
|
1550
|
-
if ((error = update_branch_remote_config_entry(
|
1551
|
-
|
1710
|
+
if ((error = update_branch_remote_config_entry(repo, name, new_name)) < 0)
|
1711
|
+
goto cleanup;
|
1552
1712
|
|
1553
|
-
if ((error = rename_remote_references(
|
1554
|
-
|
1713
|
+
if ((error = rename_remote_references(repo, name, new_name)) < 0)
|
1714
|
+
goto cleanup;
|
1555
1715
|
|
1556
1716
|
if ((error = rename_fetch_refspecs(&problem_refspecs, remote, new_name)) < 0)
|
1557
|
-
|
1717
|
+
goto cleanup;
|
1558
1718
|
|
1559
1719
|
out->count = problem_refspecs.length;
|
1560
1720
|
out->strings = (char **) problem_refspecs.contents;
|
1561
1721
|
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
tmp = remote->name;
|
1566
|
-
remote->name = dup;
|
1567
|
-
git__free(tmp);
|
1722
|
+
cleanup:
|
1723
|
+
if (error < 0)
|
1724
|
+
git_vector_free(&problem_refspecs);
|
1568
1725
|
|
1569
|
-
|
1726
|
+
git_remote_free(remote);
|
1727
|
+
return error;
|
1570
1728
|
}
|
1571
1729
|
|
1572
1730
|
int git_remote_update_fetchhead(git_remote *remote)
|
@@ -1643,27 +1801,14 @@ void git_remote_clear_refspecs(git_remote *remote)
|
|
1643
1801
|
git_vector_clear(&remote->refspecs);
|
1644
1802
|
}
|
1645
1803
|
|
1646
|
-
static int add_and_dwim(git_remote *remote, const char *str, int push)
|
1647
|
-
{
|
1648
|
-
git_refspec *spec;
|
1649
|
-
git_vector *vec;
|
1650
|
-
|
1651
|
-
if (add_refspec(remote, str, !push) < 0)
|
1652
|
-
return -1;
|
1653
|
-
|
1654
|
-
vec = &remote->refspecs;
|
1655
|
-
spec = git_vector_get(vec, vec->length - 1);
|
1656
|
-
return git_refspec__dwim_one(&remote->active_refspecs, spec, &remote->refs);
|
1657
|
-
}
|
1658
|
-
|
1659
1804
|
int git_remote_add_fetch(git_remote *remote, const char *refspec)
|
1660
1805
|
{
|
1661
|
-
return
|
1806
|
+
return add_refspec(remote, refspec, true);
|
1662
1807
|
}
|
1663
1808
|
|
1664
1809
|
int git_remote_add_push(git_remote *remote, const char *refspec)
|
1665
1810
|
{
|
1666
|
-
return
|
1811
|
+
return add_refspec(remote, refspec, false);
|
1667
1812
|
}
|
1668
1813
|
|
1669
1814
|
static int set_refspecs(git_remote *remote, git_strarray *array, int push)
|
@@ -1691,10 +1836,7 @@ static int set_refspecs(git_remote *remote, git_strarray *array, int push)
|
|
1691
1836
|
return -1;
|
1692
1837
|
}
|
1693
1838
|
|
1694
|
-
|
1695
|
-
git_vector_clear(&remote->active_refspecs);
|
1696
|
-
|
1697
|
-
return dwim_refspecs(&remote->active_refspecs, &remote->refspecs, &remote->refs);
|
1839
|
+
return 0;
|
1698
1840
|
}
|
1699
1841
|
|
1700
1842
|
int git_remote_set_fetch_refspecs(git_remote *remote, git_strarray *array)
|
@@ -1886,7 +2028,7 @@ static int remove_remote_tracking(git_repository *repo, const char *remote_name)
|
|
1886
2028
|
size_t i, count;
|
1887
2029
|
|
1888
2030
|
/* we want to use what's on the config, regardless of changes to the instance in memory */
|
1889
|
-
if ((error =
|
2031
|
+
if ((error = git_remote_lookup(&remote, repo, remote_name)) < 0)
|
1890
2032
|
return error;
|
1891
2033
|
|
1892
2034
|
count = git_remote_refspec_count(remote);
|
@@ -1905,29 +2047,15 @@ static int remove_remote_tracking(git_repository *repo, const char *remote_name)
|
|
1905
2047
|
return error;
|
1906
2048
|
}
|
1907
2049
|
|
1908
|
-
int git_remote_delete(
|
2050
|
+
int git_remote_delete(git_repository *repo, const char *name)
|
1909
2051
|
{
|
1910
2052
|
int error;
|
1911
|
-
git_repository *repo;
|
1912
2053
|
|
1913
|
-
assert(
|
2054
|
+
assert(repo && name);
|
1914
2055
|
|
1915
|
-
if (
|
1916
|
-
|
1917
|
-
|
1918
|
-
}
|
1919
|
-
|
1920
|
-
repo = git_remote_owner(remote);
|
1921
|
-
|
1922
|
-
if ((error = remove_branch_config_related_entries(repo,
|
1923
|
-
git_remote_name(remote))) < 0)
|
1924
|
-
return error;
|
1925
|
-
|
1926
|
-
if ((error = remove_remote_tracking(repo, git_remote_name(remote))) < 0)
|
1927
|
-
return error;
|
1928
|
-
|
1929
|
-
if ((error = rename_remote_config_section(
|
1930
|
-
repo, git_remote_name(remote), NULL)) < 0)
|
2056
|
+
if ((error = remove_branch_config_related_entries(repo, name)) < 0 ||
|
2057
|
+
(error = remove_remote_tracking(repo, name)) < 0 ||
|
2058
|
+
(error = rename_remote_config_section(repo, name, NULL)) < 0)
|
1931
2059
|
return error;
|
1932
2060
|
|
1933
2061
|
return 0;
|
@@ -1949,6 +2077,9 @@ int git_remote_default_branch(git_buf *out, git_remote *remote)
|
|
1949
2077
|
if (heads_len == 0)
|
1950
2078
|
return GIT_ENOTFOUND;
|
1951
2079
|
|
2080
|
+
if (strcmp(heads[0]->name, GIT_HEAD_FILE))
|
2081
|
+
return GIT_ENOTFOUND;
|
2082
|
+
|
1952
2083
|
git_buf_sanitize(out);
|
1953
2084
|
/* the first one must be HEAD so if that has the symref info, we're done */
|
1954
2085
|
if (heads[0]->symref_target)
|
@@ -1965,6 +2096,9 @@ int git_remote_default_branch(git_buf *out, git_remote *remote)
|
|
1965
2096
|
if (git_oid_cmp(head_id, &heads[i]->oid))
|
1966
2097
|
continue;
|
1967
2098
|
|
2099
|
+
if (git__prefixcmp(heads[i]->name, GIT_REFS_HEADS_DIR))
|
2100
|
+
continue;
|
2101
|
+
|
1968
2102
|
if (!guess) {
|
1969
2103
|
guess = heads[i];
|
1970
2104
|
continue;
|