rugged 1.5.1 → 1.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/rugged/extconf.rb +2 -2
- data/ext/rugged/rugged_blame.c +2 -0
- data/ext/rugged/rugged_blob.c +3 -0
- data/ext/rugged/rugged_commit.c +1 -0
- data/ext/rugged/rugged_config.c +2 -0
- data/ext/rugged/rugged_diff.c +1 -0
- data/ext/rugged/rugged_index.c +2 -0
- data/ext/rugged/rugged_patch.c +1 -0
- data/ext/rugged/rugged_rebase.c +1 -0
- data/ext/rugged/rugged_reference.c +1 -0
- data/ext/rugged/rugged_remote.c +1 -0
- data/ext/rugged/rugged_repo.c +5 -2
- data/ext/rugged/rugged_revwalk.c +5 -1
- data/ext/rugged/rugged_submodule.c +1 -0
- data/ext/rugged/rugged_tag.c +1 -0
- data/ext/rugged/rugged_tree.c +4 -0
- data/lib/rugged/index.rb +1 -1
- data/lib/rugged/tree.rb +1 -1
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +5 -1
- data/vendor/libgit2/COPYING +30 -0
- data/vendor/libgit2/cmake/ExperimentalFeatures.cmake +23 -0
- data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +2 -0
- data/vendor/libgit2/include/git2/common.h +13 -6
- data/vendor/libgit2/include/git2/deprecated.h +6 -0
- data/vendor/libgit2/include/git2/diff.h +1 -1
- data/vendor/libgit2/include/git2/experimental.h +20 -0
- data/vendor/libgit2/include/git2/indexer.h +29 -0
- data/vendor/libgit2/include/git2/object.h +28 -2
- data/vendor/libgit2/include/git2/odb.h +58 -7
- data/vendor/libgit2/include/git2/odb_backend.h +106 -18
- data/vendor/libgit2/include/git2/oid.h +115 -15
- data/vendor/libgit2/include/git2/repository.h +20 -1
- data/vendor/libgit2/include/git2/stash.h +60 -6
- data/vendor/libgit2/include/git2/strarray.h +0 -13
- data/vendor/libgit2/include/git2/sys/odb_backend.h +1 -1
- data/vendor/libgit2/include/git2/sys/transport.h +12 -0
- data/vendor/libgit2/include/git2/version.h +4 -4
- data/vendor/libgit2/include/git2.h +1 -0
- data/vendor/libgit2/src/CMakeLists.txt +0 -6
- data/vendor/libgit2/src/cli/CMakeLists.txt +5 -2
- data/vendor/libgit2/src/cli/cmd_hash_object.c +27 -8
- data/vendor/libgit2/src/cli/opt.c +1 -1
- data/vendor/libgit2/src/libgit2/CMakeLists.txt +24 -15
- data/vendor/libgit2/src/libgit2/annotated_commit.c +1 -1
- data/vendor/libgit2/src/libgit2/annotated_commit.h +1 -1
- data/vendor/libgit2/src/libgit2/attr_file.c +1 -1
- data/vendor/libgit2/src/libgit2/attrcache.c +1 -1
- data/vendor/libgit2/src/libgit2/blame.c +2 -0
- data/vendor/libgit2/src/libgit2/blob.c +4 -2
- data/vendor/libgit2/src/libgit2/blob.h +2 -2
- data/vendor/libgit2/src/libgit2/branch.c +2 -2
- data/vendor/libgit2/src/libgit2/cherrypick.c +3 -3
- data/vendor/libgit2/src/libgit2/clone.c +31 -2
- data/vendor/libgit2/src/libgit2/commit.c +52 -17
- data/vendor/libgit2/src/libgit2/commit.h +25 -7
- data/vendor/libgit2/src/libgit2/commit_graph.c +47 -32
- data/vendor/libgit2/src/libgit2/commit_graph.h +3 -0
- data/vendor/libgit2/src/libgit2/commit_list.c +6 -2
- data/vendor/libgit2/src/libgit2/config.c +1 -1
- data/vendor/libgit2/src/libgit2/config_file.c +2 -2
- data/vendor/libgit2/src/libgit2/describe.c +8 -8
- data/vendor/libgit2/src/libgit2/diff.c +5 -1
- data/vendor/libgit2/src/libgit2/diff_file.c +15 -6
- data/vendor/libgit2/src/libgit2/diff_generate.c +17 -12
- data/vendor/libgit2/src/libgit2/diff_print.c +5 -5
- data/vendor/libgit2/src/libgit2/diff_tform.c +4 -0
- data/vendor/libgit2/src/libgit2/email.c +2 -2
- data/vendor/libgit2/src/libgit2/experimental.h.in +13 -0
- data/vendor/libgit2/src/libgit2/fetch.c +3 -6
- data/vendor/libgit2/src/libgit2/fetchhead.c +4 -4
- data/vendor/libgit2/src/libgit2/ident.c +3 -3
- data/vendor/libgit2/src/libgit2/index.c +13 -12
- data/vendor/libgit2/src/libgit2/indexer.c +107 -44
- data/vendor/libgit2/src/libgit2/iterator.c +4 -2
- data/vendor/libgit2/src/libgit2/libgit2.c +19 -0
- data/vendor/libgit2/src/libgit2/merge.c +3 -3
- data/vendor/libgit2/src/libgit2/midx.c +16 -15
- data/vendor/libgit2/src/libgit2/mwindow.c +5 -2
- data/vendor/libgit2/src/libgit2/mwindow.h +4 -1
- data/vendor/libgit2/src/libgit2/notes.c +5 -5
- data/vendor/libgit2/src/libgit2/object.c +89 -25
- data/vendor/libgit2/src/libgit2/object.h +12 -3
- data/vendor/libgit2/src/libgit2/odb.c +213 -50
- data/vendor/libgit2/src/libgit2/odb.h +43 -4
- data/vendor/libgit2/src/libgit2/odb_loose.c +128 -70
- data/vendor/libgit2/src/libgit2/odb_pack.c +96 -44
- data/vendor/libgit2/src/libgit2/oid.c +134 -76
- data/vendor/libgit2/src/libgit2/oid.h +183 -9
- data/vendor/libgit2/src/libgit2/pack-objects.c +15 -4
- data/vendor/libgit2/src/libgit2/pack.c +92 -69
- data/vendor/libgit2/src/libgit2/pack.h +29 -15
- data/vendor/libgit2/src/libgit2/parse.c +4 -3
- data/vendor/libgit2/src/libgit2/patch_parse.c +5 -5
- data/vendor/libgit2/src/libgit2/push.c +13 -3
- data/vendor/libgit2/src/libgit2/reader.c +1 -1
- data/vendor/libgit2/src/libgit2/rebase.c +19 -18
- data/vendor/libgit2/src/libgit2/refdb_fs.c +70 -39
- data/vendor/libgit2/src/libgit2/reflog.c +7 -5
- data/vendor/libgit2/src/libgit2/reflog.h +1 -2
- data/vendor/libgit2/src/libgit2/refs.c +2 -0
- data/vendor/libgit2/src/libgit2/remote.c +38 -37
- data/vendor/libgit2/src/libgit2/remote.h +40 -0
- data/vendor/libgit2/src/libgit2/repository.c +212 -36
- data/vendor/libgit2/src/libgit2/repository.h +9 -0
- data/vendor/libgit2/src/libgit2/reset.c +2 -2
- data/vendor/libgit2/src/libgit2/revert.c +4 -4
- data/vendor/libgit2/src/libgit2/revparse.c +23 -7
- data/vendor/libgit2/src/libgit2/revwalk.c +5 -1
- data/vendor/libgit2/src/libgit2/stash.c +201 -26
- data/vendor/libgit2/src/libgit2/strarray.c +1 -0
- data/vendor/libgit2/src/libgit2/strarray.h +25 -0
- data/vendor/libgit2/src/libgit2/streams/openssl.c +1 -1
- data/vendor/libgit2/src/libgit2/streams/openssl_dynamic.c +7 -3
- data/vendor/libgit2/src/libgit2/streams/socket.c +4 -1
- data/vendor/libgit2/src/libgit2/submodule.c +6 -2
- data/vendor/libgit2/src/libgit2/sysdir.c +294 -7
- data/vendor/libgit2/src/libgit2/sysdir.h +41 -9
- data/vendor/libgit2/src/libgit2/tag.c +29 -10
- data/vendor/libgit2/src/libgit2/tag.h +2 -2
- data/vendor/libgit2/src/libgit2/threadstate.h +1 -1
- data/vendor/libgit2/src/libgit2/transports/http.c +8 -7
- data/vendor/libgit2/src/libgit2/transports/httpclient.c +9 -0
- data/vendor/libgit2/src/libgit2/transports/httpclient.h +10 -0
- data/vendor/libgit2/src/libgit2/transports/local.c +14 -0
- data/vendor/libgit2/src/libgit2/transports/smart.c +35 -0
- data/vendor/libgit2/src/libgit2/transports/smart.h +10 -1
- data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +153 -41
- data/vendor/libgit2/src/libgit2/transports/smart_protocol.c +42 -12
- data/vendor/libgit2/src/libgit2/transports/ssh.c +62 -65
- data/vendor/libgit2/src/libgit2/transports/winhttp.c +9 -4
- data/vendor/libgit2/src/libgit2/tree-cache.c +4 -4
- data/vendor/libgit2/src/libgit2/tree.c +22 -16
- data/vendor/libgit2/src/libgit2/tree.h +2 -2
- data/vendor/libgit2/src/libgit2/worktree.c +5 -0
- data/vendor/libgit2/src/util/CMakeLists.txt +6 -1
- data/vendor/libgit2/src/util/fs_path.c +1 -1
- data/vendor/libgit2/src/util/futils.c +0 -3
- data/vendor/libgit2/src/util/git2_util.h +2 -2
- data/vendor/libgit2/src/util/hash/openssl.c +4 -3
- data/vendor/libgit2/src/util/hash/rfc6234/sha.h +0 -112
- data/vendor/libgit2/src/util/hash.h +13 -0
- data/vendor/libgit2/src/util/net.c +338 -84
- data/vendor/libgit2/src/util/net.h +7 -0
- data/vendor/libgit2/src/util/posix.h +2 -0
- data/vendor/libgit2/src/util/rand.c +4 -0
- data/vendor/libgit2/src/util/regexp.c +3 -3
- data/vendor/libgit2/src/util/thread.h +20 -19
- data/vendor/libgit2/src/util/util.h +1 -0
- metadata +7 -5
- data/vendor/libgit2/src/util/win32/findfile.c +0 -286
- data/vendor/libgit2/src/util/win32/findfile.h +0 -22
- /data/vendor/libgit2/src/{features.h.in → util/git2_features.h.in} +0 -0
@@ -17,6 +17,7 @@
|
|
17
17
|
#include "refspec.h"
|
18
18
|
#include "vector.h"
|
19
19
|
#include "net.h"
|
20
|
+
#include "proxy.h"
|
20
21
|
|
21
22
|
#define GIT_REMOTE_ORIGIN "origin"
|
22
23
|
|
@@ -56,5 +57,44 @@ int git_remote_connect_options_normalize(
|
|
56
57
|
const git_remote_connect_options *src);
|
57
58
|
|
58
59
|
int git_remote_capabilities(unsigned int *out, git_remote *remote);
|
60
|
+
int git_remote_oid_type(git_oid_t *out, git_remote *remote);
|
61
|
+
|
62
|
+
|
63
|
+
#define git_remote_connect_options__copy_opts(out, in) \
|
64
|
+
if (in) { \
|
65
|
+
(out)->callbacks = (in)->callbacks; \
|
66
|
+
(out)->proxy_opts = (in)->proxy_opts; \
|
67
|
+
(out)->custom_headers = (in)->custom_headers; \
|
68
|
+
(out)->follow_redirects = (in)->follow_redirects; \
|
69
|
+
}
|
70
|
+
|
71
|
+
GIT_INLINE(int) git_remote_connect_options__from_fetch_opts(
|
72
|
+
git_remote_connect_options *out,
|
73
|
+
git_remote *remote,
|
74
|
+
const git_fetch_options *fetch_opts)
|
75
|
+
{
|
76
|
+
git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT;
|
77
|
+
git_remote_connect_options__copy_opts(&tmp, fetch_opts);
|
78
|
+
return git_remote_connect_options_normalize(out, remote->repo, &tmp);
|
79
|
+
}
|
80
|
+
|
81
|
+
GIT_INLINE(int) git_remote_connect_options__from_push_opts(
|
82
|
+
git_remote_connect_options *out,
|
83
|
+
git_remote *remote,
|
84
|
+
const git_push_options *push_opts)
|
85
|
+
{
|
86
|
+
git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT;
|
87
|
+
git_remote_connect_options__copy_opts(&tmp, push_opts);
|
88
|
+
return git_remote_connect_options_normalize(out, remote->repo, &tmp);
|
89
|
+
}
|
90
|
+
|
91
|
+
#undef git_remote_connect_options__copy_opts
|
92
|
+
|
93
|
+
GIT_INLINE(void) git_remote_connect_options__dispose(
|
94
|
+
git_remote_connect_options *opts)
|
95
|
+
{
|
96
|
+
git_proxy_options_dispose(&opts->proxy_opts);
|
97
|
+
git_strarray_dispose(&opts->custom_headers);
|
98
|
+
}
|
59
99
|
|
60
100
|
#endif
|
@@ -67,6 +67,7 @@ static const struct {
|
|
67
67
|
static int check_repositoryformatversion(int *version, git_config *config);
|
68
68
|
static int check_extensions(git_config *config, int version);
|
69
69
|
static int load_global_config(git_config **config);
|
70
|
+
static int load_objectformat(git_repository *repo, git_config *config);
|
70
71
|
|
71
72
|
#define GIT_COMMONDIR_FILE "commondir"
|
72
73
|
#define GIT_GITDIR_FILE "gitdir"
|
@@ -75,8 +76,8 @@ static int load_global_config(git_config **config);
|
|
75
76
|
|
76
77
|
#define GIT_BRANCH_DEFAULT "master"
|
77
78
|
|
78
|
-
#define
|
79
|
-
#define
|
79
|
+
#define GIT_REPO_VERSION_DEFAULT 0
|
80
|
+
#define GIT_REPO_VERSION_MAX 1
|
80
81
|
|
81
82
|
git_str git_repository__reserved_names_win32[] = {
|
82
83
|
{ DOT_GIT, 0, CONST_STRLEN(DOT_GIT) },
|
@@ -240,7 +241,7 @@ GIT_INLINE(int) validate_repo_path(git_str *path)
|
|
240
241
|
*/
|
241
242
|
static size_t suffix_len =
|
242
243
|
CONST_STRLEN("objects/pack/pack-.pack.lock") +
|
243
|
-
|
244
|
+
GIT_OID_MAX_HEXSIZE;
|
244
245
|
|
245
246
|
return git_fs_path_validate_str_length_with_suffix(
|
246
247
|
path, suffix_len);
|
@@ -495,12 +496,47 @@ static int validate_ownership_cb(const git_config_entry *entry, void *payload)
|
|
495
496
|
{
|
496
497
|
validate_ownership_data *data = payload;
|
497
498
|
|
498
|
-
if (strcmp(entry->value, "") == 0)
|
499
|
+
if (strcmp(entry->value, "") == 0) {
|
499
500
|
*data->is_safe = false;
|
500
|
-
|
501
|
-
if (git_fs_path_prettify_dir(&data->tmp, entry->value, NULL) == 0 &&
|
502
|
-
strcmp(data->tmp.ptr, data->repo_path) == 0)
|
501
|
+
} else if (strcmp(entry->value, "*") == 0) {
|
503
502
|
*data->is_safe = true;
|
503
|
+
} else {
|
504
|
+
const char *test_path = entry->value;
|
505
|
+
|
506
|
+
#ifdef GIT_WIN32
|
507
|
+
/*
|
508
|
+
* Git for Windows does some truly bizarre things with
|
509
|
+
* paths that start with a forward slash; and expects you
|
510
|
+
* to escape that with `%(prefix)`. This syntax generally
|
511
|
+
* means to add the prefix that Git was installed to -- eg
|
512
|
+
* `/usr/local` -- unless it's an absolute path, in which
|
513
|
+
* case the leading `%(prefix)/` is just removed. And Git
|
514
|
+
* for Windows expects you to use this syntax for absolute
|
515
|
+
* Unix-style paths (in "Git Bash" or Windows Subsystem for
|
516
|
+
* Linux).
|
517
|
+
*
|
518
|
+
* Worse, the behavior used to be that a leading `/` was
|
519
|
+
* not absolute. It would indicate that Git for Windows
|
520
|
+
* should add the prefix. So `//` is required for absolute
|
521
|
+
* Unix-style paths. Yes, this is truly horrifying.
|
522
|
+
*
|
523
|
+
* Emulate that behavior, I guess, but only for absolute
|
524
|
+
* paths. We won't deal with the Git install prefix. Also,
|
525
|
+
* give WSL users an escape hatch where they don't have to
|
526
|
+
* think about this and can use the literal path that the
|
527
|
+
* filesystem APIs provide (`//wsl.localhost/...`).
|
528
|
+
*/
|
529
|
+
if (strncmp(test_path, "%(prefix)//", strlen("%(prefix)//")) == 0)
|
530
|
+
test_path += strlen("%(prefix)/");
|
531
|
+
else if (strncmp(test_path, "//", 2) == 0 &&
|
532
|
+
strncmp(test_path, "//wsl.localhost/", strlen("//wsl.localhost/")) != 0)
|
533
|
+
test_path++;
|
534
|
+
#endif
|
535
|
+
|
536
|
+
if (git_fs_path_prettify_dir(&data->tmp, test_path, NULL) == 0 &&
|
537
|
+
strcmp(data->tmp.ptr, data->repo_path) == 0)
|
538
|
+
*data->is_safe = true;
|
539
|
+
}
|
504
540
|
|
505
541
|
return 0;
|
506
542
|
}
|
@@ -521,6 +557,9 @@ static int validate_ownership_config(bool *is_safe, const char *path)
|
|
521
557
|
validate_ownership_cb,
|
522
558
|
&ownership_data);
|
523
559
|
|
560
|
+
if (error == GIT_ENOTFOUND)
|
561
|
+
error = 0;
|
562
|
+
|
524
563
|
git_config_free(config);
|
525
564
|
git_str_dispose(&ownership_data.tmp);
|
526
565
|
|
@@ -541,6 +580,9 @@ static int validate_ownership_path(bool *is_safe, const char *path)
|
|
541
580
|
if (error == GIT_ENOTFOUND) {
|
542
581
|
*is_safe = true;
|
543
582
|
error = 0;
|
583
|
+
} else if (error == GIT_EINVALID) {
|
584
|
+
*is_safe = false;
|
585
|
+
error = 0;
|
544
586
|
}
|
545
587
|
|
546
588
|
return error;
|
@@ -727,6 +769,43 @@ out:
|
|
727
769
|
return error;
|
728
770
|
}
|
729
771
|
|
772
|
+
static int obtain_config_and_set_oid_type(
|
773
|
+
git_config **config_ptr,
|
774
|
+
git_repository *repo)
|
775
|
+
{
|
776
|
+
int error;
|
777
|
+
git_config *config = NULL;
|
778
|
+
int version = 0;
|
779
|
+
|
780
|
+
/*
|
781
|
+
* We'd like to have the config, but git doesn't particularly
|
782
|
+
* care if it's not there, so we need to deal with that.
|
783
|
+
*/
|
784
|
+
|
785
|
+
error = git_repository_config_snapshot(&config, repo);
|
786
|
+
if (error < 0 && error != GIT_ENOTFOUND)
|
787
|
+
goto out;
|
788
|
+
|
789
|
+
if (config &&
|
790
|
+
(error = check_repositoryformatversion(&version, config)) < 0)
|
791
|
+
goto out;
|
792
|
+
|
793
|
+
if ((error = check_extensions(config, version)) < 0)
|
794
|
+
goto out;
|
795
|
+
|
796
|
+
if (version > 0) {
|
797
|
+
if ((error = load_objectformat(repo, config)) < 0)
|
798
|
+
goto out;
|
799
|
+
} else {
|
800
|
+
repo->oid_type = GIT_OID_SHA1;
|
801
|
+
}
|
802
|
+
|
803
|
+
out:
|
804
|
+
*config_ptr = config;
|
805
|
+
|
806
|
+
return error;
|
807
|
+
}
|
808
|
+
|
730
809
|
int git_repository_open_bare(
|
731
810
|
git_repository **repo_ptr,
|
732
811
|
const char *bare_path)
|
@@ -735,6 +814,7 @@ int git_repository_open_bare(
|
|
735
814
|
git_repository *repo = NULL;
|
736
815
|
bool is_valid;
|
737
816
|
int error;
|
817
|
+
git_config *config;
|
738
818
|
|
739
819
|
if ((error = git_fs_path_prettify_dir(&path, bare_path, NULL)) < 0 ||
|
740
820
|
(error = is_valid_repository_path(&is_valid, &path, &common_path)) < 0)
|
@@ -760,8 +840,15 @@ int git_repository_open_bare(
|
|
760
840
|
repo->is_worktree = 0;
|
761
841
|
repo->workdir = NULL;
|
762
842
|
|
843
|
+
if ((error = obtain_config_and_set_oid_type(&config, repo)) < 0)
|
844
|
+
goto cleanup;
|
845
|
+
|
763
846
|
*repo_ptr = repo;
|
764
|
-
|
847
|
+
|
848
|
+
cleanup:
|
849
|
+
git_config_free(config);
|
850
|
+
|
851
|
+
return error;
|
765
852
|
}
|
766
853
|
|
767
854
|
static int _git_repository_open_ext_from_env(
|
@@ -843,7 +930,7 @@ static int _git_repository_open_ext_from_env(
|
|
843
930
|
else if (error < 0)
|
844
931
|
goto error;
|
845
932
|
else {
|
846
|
-
error =
|
933
|
+
error = git_odb__open(&odb, git_str_cstr(&object_dir_buf), NULL);
|
847
934
|
if (error < 0)
|
848
935
|
goto error;
|
849
936
|
}
|
@@ -968,7 +1055,6 @@ int git_repository_open_ext(
|
|
968
1055
|
gitlink = GIT_STR_INIT, commondir = GIT_STR_INIT;
|
969
1056
|
git_repository *repo = NULL;
|
970
1057
|
git_config *config = NULL;
|
971
|
-
int version = 0;
|
972
1058
|
|
973
1059
|
if (flags & GIT_REPOSITORY_OPEN_FROM_ENV)
|
974
1060
|
return _git_repository_open_ext_from_env(repo_ptr, start_path);
|
@@ -1001,19 +1087,8 @@ int git_repository_open_ext(
|
|
1001
1087
|
goto cleanup;
|
1002
1088
|
repo->is_worktree = is_worktree;
|
1003
1089
|
|
1004
|
-
|
1005
|
-
|
1006
|
-
* care if it's not there, so we need to deal with that.
|
1007
|
-
*/
|
1008
|
-
|
1009
|
-
error = git_repository_config_snapshot(&config, repo);
|
1010
|
-
if (error < 0 && error != GIT_ENOTFOUND)
|
1011
|
-
goto cleanup;
|
1012
|
-
|
1013
|
-
if (config && (error = check_repositoryformatversion(&version, config)) < 0)
|
1014
|
-
goto cleanup;
|
1015
|
-
|
1016
|
-
if ((error = check_extensions(config, version)) < 0)
|
1090
|
+
error = obtain_config_and_set_oid_type(&config, repo);
|
1091
|
+
if (error < 0)
|
1017
1092
|
goto cleanup;
|
1018
1093
|
|
1019
1094
|
if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0) {
|
@@ -1264,11 +1339,14 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
|
|
1264
1339
|
*out = git_atomic_load(repo->_odb);
|
1265
1340
|
if (*out == NULL) {
|
1266
1341
|
git_str odb_path = GIT_STR_INIT;
|
1342
|
+
git_odb_options odb_opts = GIT_ODB_OPTIONS_INIT;
|
1267
1343
|
git_odb *odb;
|
1268
1344
|
|
1345
|
+
odb_opts.oid_type = repo->oid_type;
|
1346
|
+
|
1269
1347
|
if ((error = git_repository__item_path(&odb_path, repo,
|
1270
1348
|
GIT_REPOSITORY_ITEM_OBJECTS)) < 0 ||
|
1271
|
-
(error =
|
1349
|
+
(error = git_odb__new(&odb, &odb_opts)) < 0)
|
1272
1350
|
return error;
|
1273
1351
|
|
1274
1352
|
GIT_REFCOUNT_OWN(odb, repo);
|
@@ -1526,6 +1604,7 @@ static int check_repositoryformatversion(int *version, git_config *config)
|
|
1526
1604
|
int error;
|
1527
1605
|
|
1528
1606
|
error = git_config_get_int32(version, config, "core.repositoryformatversion");
|
1607
|
+
|
1529
1608
|
/* git ignores this if the config variable isn't there */
|
1530
1609
|
if (error == GIT_ENOTFOUND)
|
1531
1610
|
return 0;
|
@@ -1533,10 +1612,15 @@ static int check_repositoryformatversion(int *version, git_config *config)
|
|
1533
1612
|
if (error < 0)
|
1534
1613
|
return -1;
|
1535
1614
|
|
1536
|
-
if (
|
1615
|
+
if (*version < 0) {
|
1616
|
+
git_error_set(GIT_ERROR_REPOSITORY,
|
1617
|
+
"invalid repository version %d", *version);
|
1618
|
+
}
|
1619
|
+
|
1620
|
+
if (GIT_REPO_VERSION_MAX < *version) {
|
1537
1621
|
git_error_set(GIT_ERROR_REPOSITORY,
|
1538
1622
|
"unsupported repository version %d; only versions up to %d are supported",
|
1539
|
-
*version,
|
1623
|
+
*version, GIT_REPO_VERSION_MAX);
|
1540
1624
|
return -1;
|
1541
1625
|
}
|
1542
1626
|
|
@@ -1544,7 +1628,8 @@ static int check_repositoryformatversion(int *version, git_config *config)
|
|
1544
1628
|
}
|
1545
1629
|
|
1546
1630
|
static const char *builtin_extensions[] = {
|
1547
|
-
"noop"
|
1631
|
+
"noop",
|
1632
|
+
"objectformat"
|
1548
1633
|
};
|
1549
1634
|
|
1550
1635
|
static git_vector user_extensions = GIT_VECTOR_INIT;
|
@@ -1608,6 +1693,79 @@ static int check_extensions(git_config *config, int version)
|
|
1608
1693
|
return git_config_foreach_match(config, "^extensions\\.", check_valid_extension, NULL);
|
1609
1694
|
}
|
1610
1695
|
|
1696
|
+
static int load_objectformat(git_repository *repo, git_config *config)
|
1697
|
+
{
|
1698
|
+
git_config_entry *entry = NULL;
|
1699
|
+
int error;
|
1700
|
+
|
1701
|
+
if ((error = git_config_get_entry(&entry, config, "extensions.objectformat")) < 0) {
|
1702
|
+
if (error == GIT_ENOTFOUND) {
|
1703
|
+
repo->oid_type = GIT_OID_SHA1;
|
1704
|
+
git_error_clear();
|
1705
|
+
error = 0;
|
1706
|
+
}
|
1707
|
+
|
1708
|
+
goto done;
|
1709
|
+
}
|
1710
|
+
|
1711
|
+
if ((repo->oid_type = git_oid_type_fromstr(entry->value)) == 0) {
|
1712
|
+
git_error_set(GIT_ERROR_REPOSITORY,
|
1713
|
+
"unknown object format '%s'", entry->value);
|
1714
|
+
error = GIT_EINVALID;
|
1715
|
+
}
|
1716
|
+
|
1717
|
+
done:
|
1718
|
+
git_config_entry_free(entry);
|
1719
|
+
return error;
|
1720
|
+
}
|
1721
|
+
|
1722
|
+
int git_repository__set_objectformat(
|
1723
|
+
git_repository *repo,
|
1724
|
+
git_oid_t oid_type)
|
1725
|
+
{
|
1726
|
+
git_config *cfg;
|
1727
|
+
|
1728
|
+
/*
|
1729
|
+
* Older clients do not necessarily understand the
|
1730
|
+
* `objectformat` extension, even when it's set to an
|
1731
|
+
* object format that they understand (SHA1). Do not set
|
1732
|
+
* the objectformat extension unless we're not using the
|
1733
|
+
* default object format.
|
1734
|
+
*/
|
1735
|
+
if (oid_type == GIT_OID_DEFAULT)
|
1736
|
+
return 0;
|
1737
|
+
|
1738
|
+
if (!git_repository_is_empty(repo) && repo->oid_type != oid_type) {
|
1739
|
+
git_error_set(GIT_ERROR_REPOSITORY,
|
1740
|
+
"cannot change object id type of existing repository");
|
1741
|
+
return -1;
|
1742
|
+
}
|
1743
|
+
|
1744
|
+
if (git_repository_config__weakptr(&cfg, repo) < 0)
|
1745
|
+
return -1;
|
1746
|
+
|
1747
|
+
if (git_config_set_int32(cfg,
|
1748
|
+
"core.repositoryformatversion", 1) < 0 ||
|
1749
|
+
git_config_set_string(cfg, "extensions.objectformat",
|
1750
|
+
git_oid_type_name(oid_type)) < 0)
|
1751
|
+
return -1;
|
1752
|
+
|
1753
|
+
/*
|
1754
|
+
* During repo init, we may create some backends with the
|
1755
|
+
* default oid type. Clear them so that we create them with
|
1756
|
+
* the proper oid type.
|
1757
|
+
*/
|
1758
|
+
if (repo->oid_type != oid_type) {
|
1759
|
+
set_index(repo, NULL);
|
1760
|
+
set_odb(repo, NULL);
|
1761
|
+
set_refdb(repo, NULL);
|
1762
|
+
|
1763
|
+
repo->oid_type = oid_type;
|
1764
|
+
}
|
1765
|
+
|
1766
|
+
return 0;
|
1767
|
+
}
|
1768
|
+
|
1611
1769
|
int git_repository__extensions(char ***out, size_t *out_len)
|
1612
1770
|
{
|
1613
1771
|
git_vector extensions;
|
@@ -1886,19 +2044,21 @@ static int repo_init_config(
|
|
1886
2044
|
const char *repo_dir,
|
1887
2045
|
const char *work_dir,
|
1888
2046
|
uint32_t flags,
|
1889
|
-
uint32_t mode
|
2047
|
+
uint32_t mode,
|
2048
|
+
git_oid_t oid_type)
|
1890
2049
|
{
|
1891
2050
|
int error = 0;
|
1892
2051
|
git_str cfg_path = GIT_STR_INIT, worktree_path = GIT_STR_INIT;
|
1893
2052
|
git_config *config = NULL;
|
1894
2053
|
bool is_bare = ((flags & GIT_REPOSITORY_INIT_BARE) != 0);
|
1895
2054
|
bool is_reinit = ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0);
|
1896
|
-
int version =
|
2055
|
+
int version = GIT_REPO_VERSION_DEFAULT;
|
1897
2056
|
|
1898
2057
|
if ((error = repo_local_config(&config, &cfg_path, NULL, repo_dir)) < 0)
|
1899
2058
|
goto cleanup;
|
1900
2059
|
|
1901
|
-
if (is_reinit &&
|
2060
|
+
if (is_reinit &&
|
2061
|
+
(error = check_repositoryformatversion(&version, config)) < 0)
|
1902
2062
|
goto cleanup;
|
1903
2063
|
|
1904
2064
|
if ((error = check_extensions(config, version)) < 0)
|
@@ -1909,7 +2069,7 @@ static int repo_init_config(
|
|
1909
2069
|
goto cleanup; } while (0)
|
1910
2070
|
|
1911
2071
|
SET_REPO_CONFIG(bool, "core.bare", is_bare);
|
1912
|
-
SET_REPO_CONFIG(int32, "core.repositoryformatversion",
|
2072
|
+
SET_REPO_CONFIG(int32, "core.repositoryformatversion", version);
|
1913
2073
|
|
1914
2074
|
if ((error = repo_init_fs_configs(
|
1915
2075
|
config, cfg_path.ptr, repo_dir, work_dir, !is_reinit)) < 0)
|
@@ -1942,6 +2102,11 @@ static int repo_init_config(
|
|
1942
2102
|
SET_REPO_CONFIG(bool, "receive.denyNonFastforwards", true);
|
1943
2103
|
}
|
1944
2104
|
|
2105
|
+
if (oid_type != GIT_OID_SHA1) {
|
2106
|
+
SET_REPO_CONFIG(int32, "core.repositoryformatversion", 1);
|
2107
|
+
SET_REPO_CONFIG(string, "extensions.objectformat", git_oid_type_name(oid_type));
|
2108
|
+
}
|
2109
|
+
|
1945
2110
|
cleanup:
|
1946
2111
|
git_str_dispose(&cfg_path);
|
1947
2112
|
git_str_dispose(&worktree_path);
|
@@ -2422,6 +2587,7 @@ int git_repository_init_ext(
|
|
2422
2587
|
common_path = GIT_STR_INIT;
|
2423
2588
|
const char *wd;
|
2424
2589
|
bool is_valid;
|
2590
|
+
git_oid_t oid_type = GIT_OID_DEFAULT;
|
2425
2591
|
int error;
|
2426
2592
|
|
2427
2593
|
GIT_ASSERT_ARG(out);
|
@@ -2430,6 +2596,11 @@ int git_repository_init_ext(
|
|
2430
2596
|
|
2431
2597
|
GIT_ERROR_CHECK_VERSION(opts, GIT_REPOSITORY_INIT_OPTIONS_VERSION, "git_repository_init_options");
|
2432
2598
|
|
2599
|
+
#ifdef GIT_EXPERIMENTAL_SHA256
|
2600
|
+
if (opts->oid_type)
|
2601
|
+
oid_type = opts->oid_type;
|
2602
|
+
#endif
|
2603
|
+
|
2433
2604
|
if ((error = repo_init_directories(&repo_path, &wd_path, given_repo, opts)) < 0)
|
2434
2605
|
goto out;
|
2435
2606
|
|
@@ -2448,13 +2619,13 @@ int git_repository_init_ext(
|
|
2448
2619
|
|
2449
2620
|
opts->flags |= GIT_REPOSITORY_INIT__IS_REINIT;
|
2450
2621
|
|
2451
|
-
if ((error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode)) < 0)
|
2622
|
+
if ((error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode, oid_type)) < 0)
|
2452
2623
|
goto out;
|
2453
2624
|
|
2454
2625
|
/* TODO: reinitialize the templates */
|
2455
2626
|
} else {
|
2456
2627
|
if ((error = repo_init_structure(repo_path.ptr, wd, opts)) < 0 ||
|
2457
|
-
(error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode)) < 0 ||
|
2628
|
+
(error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode, oid_type)) < 0 ||
|
2458
2629
|
(error = repo_init_head(repo_path.ptr, opts->initial_head)) < 0)
|
2459
2630
|
goto out;
|
2460
2631
|
}
|
@@ -2917,14 +3088,14 @@ int git_repository__set_orig_head(git_repository *repo, const git_oid *orig_head
|
|
2917
3088
|
{
|
2918
3089
|
git_filebuf file = GIT_FILEBUF_INIT;
|
2919
3090
|
git_str file_path = GIT_STR_INIT;
|
2920
|
-
char orig_head_str[
|
3091
|
+
char orig_head_str[GIT_OID_MAX_HEXSIZE];
|
2921
3092
|
int error = 0;
|
2922
3093
|
|
2923
3094
|
git_oid_fmt(orig_head_str, orig_head);
|
2924
3095
|
|
2925
3096
|
if ((error = git_str_joinpath(&file_path, repo->gitdir, GIT_ORIG_HEAD_FILE)) == 0 &&
|
2926
3097
|
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) == 0 &&
|
2927
|
-
(error = git_filebuf_printf(&file, "%.*s\n",
|
3098
|
+
(error = git_filebuf_printf(&file, "%.*s\n", (int)git_oid_hexsize(repo->oid_type), orig_head_str)) == 0)
|
2928
3099
|
error = git_filebuf_commit(&file);
|
2929
3100
|
|
2930
3101
|
if (error < 0)
|
@@ -3037,7 +3208,7 @@ int git_repository_hashfile(
|
|
3037
3208
|
goto cleanup;
|
3038
3209
|
}
|
3039
3210
|
|
3040
|
-
error = git_odb__hashfd_filtered(out, fd, (size_t)len, type, fl);
|
3211
|
+
error = git_odb__hashfd_filtered(out, fd, (size_t)len, type, repo->oid_type, fl);
|
3041
3212
|
|
3042
3213
|
cleanup:
|
3043
3214
|
if (fd >= 0)
|
@@ -3384,3 +3555,8 @@ int git_repository_submodule_cache_clear(git_repository *repo)
|
|
3384
3555
|
repo->submodule_cache = NULL;
|
3385
3556
|
return error;
|
3386
3557
|
}
|
3558
|
+
|
3559
|
+
git_oid_t git_repository_oid_type(git_repository *repo)
|
3560
|
+
{
|
3561
|
+
return repo ? repo->oid_type : 0;
|
3562
|
+
}
|
@@ -153,6 +153,7 @@ struct git_repository {
|
|
153
153
|
|
154
154
|
unsigned is_bare:1;
|
155
155
|
unsigned is_worktree:1;
|
156
|
+
git_oid_t oid_type;
|
156
157
|
|
157
158
|
unsigned int lru_counter;
|
158
159
|
|
@@ -256,4 +257,12 @@ int git_repository__extensions(char ***out, size_t *out_len);
|
|
256
257
|
int git_repository__set_extensions(const char **extensions, size_t len);
|
257
258
|
void git_repository__free_extensions(void);
|
258
259
|
|
260
|
+
/*
|
261
|
+
* Set the object format (OID type) for a repository; this will set
|
262
|
+
* both the configuration and the internal value for the oid type.
|
263
|
+
*/
|
264
|
+
int git_repository__set_objectformat(
|
265
|
+
git_repository *repo,
|
266
|
+
git_oid_t oid_type);
|
267
|
+
|
259
268
|
#endif
|
@@ -188,9 +188,9 @@ int git_reset(
|
|
188
188
|
git_reset_t reset_type,
|
189
189
|
const git_checkout_options *checkout_opts)
|
190
190
|
{
|
191
|
-
char to[
|
191
|
+
char to[GIT_OID_SHA1_HEXSIZE + 1];
|
192
192
|
|
193
|
-
git_oid_tostr(to,
|
193
|
+
git_oid_tostr(to, GIT_OID_SHA1_HEXSIZE + 1, git_object_id(target));
|
194
194
|
return reset(repo, target, to, reset_type, checkout_opts);
|
195
195
|
}
|
196
196
|
|
@@ -107,10 +107,10 @@ static int revert_state_cleanup(git_repository *repo)
|
|
107
107
|
|
108
108
|
static int revert_seterr(git_commit *commit, const char *fmt)
|
109
109
|
{
|
110
|
-
char commit_oidstr[
|
110
|
+
char commit_oidstr[GIT_OID_SHA1_HEXSIZE + 1];
|
111
111
|
|
112
112
|
git_oid_fmt(commit_oidstr, git_commit_id(commit));
|
113
|
-
commit_oidstr[
|
113
|
+
commit_oidstr[GIT_OID_SHA1_HEXSIZE] = '\0';
|
114
114
|
|
115
115
|
git_error_set(GIT_ERROR_REVERT, fmt, commit_oidstr);
|
116
116
|
|
@@ -176,7 +176,7 @@ int git_revert(
|
|
176
176
|
git_revert_options opts;
|
177
177
|
git_reference *our_ref = NULL;
|
178
178
|
git_commit *our_commit = NULL;
|
179
|
-
char commit_oidstr[
|
179
|
+
char commit_oidstr[GIT_OID_SHA1_HEXSIZE + 1];
|
180
180
|
const char *commit_msg;
|
181
181
|
git_str their_label = GIT_STR_INIT;
|
182
182
|
git_index *index = NULL;
|
@@ -192,7 +192,7 @@ int git_revert(
|
|
192
192
|
return error;
|
193
193
|
|
194
194
|
git_oid_fmt(commit_oidstr, git_commit_id(commit));
|
195
|
-
commit_oidstr[
|
195
|
+
commit_oidstr[GIT_OID_SHA1_HEXSIZE] = '\0';
|
196
196
|
|
197
197
|
if ((commit_msg = git_commit_summary(commit)) == NULL) {
|
198
198
|
error = -1;
|
@@ -15,21 +15,28 @@
|
|
15
15
|
|
16
16
|
#include "git2.h"
|
17
17
|
|
18
|
-
static int maybe_sha_or_abbrev(
|
18
|
+
static int maybe_sha_or_abbrev(
|
19
|
+
git_object **out,
|
20
|
+
git_repository *repo,
|
21
|
+
const char *spec,
|
22
|
+
size_t speclen)
|
19
23
|
{
|
20
24
|
git_oid oid;
|
21
25
|
|
22
|
-
if (
|
26
|
+
if (git_oid__fromstrn(&oid, spec, speclen, repo->oid_type) < 0)
|
23
27
|
return GIT_ENOTFOUND;
|
24
28
|
|
25
29
|
return git_object_lookup_prefix(out, repo, &oid, speclen, GIT_OBJECT_ANY);
|
26
30
|
}
|
27
31
|
|
28
|
-
static int maybe_sha(
|
32
|
+
static int maybe_sha(
|
33
|
+
git_object **out,
|
34
|
+
git_repository *repo,
|
35
|
+
const char *spec)
|
29
36
|
{
|
30
37
|
size_t speclen = strlen(spec);
|
31
38
|
|
32
|
-
if (speclen !=
|
39
|
+
if (speclen != git_oid_hexsize(repo->oid_type))
|
33
40
|
return GIT_ENOTFOUND;
|
34
41
|
|
35
42
|
return maybe_sha_or_abbrev(out, repo, spec, speclen);
|
@@ -110,8 +117,8 @@ static int revparse_lookup_object(
|
|
110
117
|
if (error != GIT_ENOTFOUND)
|
111
118
|
return error;
|
112
119
|
|
113
|
-
if ((strlen(spec) <
|
114
|
-
|
120
|
+
if ((strlen(spec) < git_oid_hexsize(repo->oid_type)) &&
|
121
|
+
((error = maybe_abbrev(object_out, repo, spec)) != GIT_ENOTFOUND))
|
115
122
|
return error;
|
116
123
|
|
117
124
|
if ((error = maybe_describe(object_out, repo, spec)) != GIT_ENOTFOUND)
|
@@ -268,7 +275,16 @@ static int retrieve_revobject_from_reflog(git_object **out, git_reference **base
|
|
268
275
|
int error = -1;
|
269
276
|
|
270
277
|
if (*base_ref == NULL) {
|
271
|
-
|
278
|
+
/*
|
279
|
+
* When HEAD@{n} is specified, do not use dwim, which would resolve the
|
280
|
+
* reference (to the current branch that HEAD is pointing to).
|
281
|
+
*/
|
282
|
+
if (position > 0 && strcmp(identifier, GIT_HEAD_FILE) == 0)
|
283
|
+
error = git_reference_lookup(&ref, repo, GIT_HEAD_FILE);
|
284
|
+
else
|
285
|
+
error = git_reference_dwim(&ref, repo, identifier);
|
286
|
+
|
287
|
+
if (error < 0)
|
272
288
|
return error;
|
273
289
|
} else {
|
274
290
|
ref = *base_ref;
|
@@ -121,8 +121,12 @@ int git_revwalk__push_ref(git_revwalk *walk, const char *refname, const git_revw
|
|
121
121
|
{
|
122
122
|
git_oid oid;
|
123
123
|
|
124
|
-
|
124
|
+
int error = git_reference_name_to_id(&oid, walk->repo, refname);
|
125
|
+
if (opts->from_glob && (error == GIT_ENOTFOUND || error == GIT_EINVALIDSPEC || error == GIT_EPEEL)) {
|
126
|
+
return 0;
|
127
|
+
} else if (error < 0) {
|
125
128
|
return -1;
|
129
|
+
}
|
126
130
|
|
127
131
|
return git_revwalk__push_commit(walk, &oid, opts);
|
128
132
|
}
|