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
@@ -12,16 +12,262 @@
|
|
12
12
|
#include "fs_path.h"
|
13
13
|
#include <ctype.h>
|
14
14
|
#if GIT_WIN32
|
15
|
-
#include "
|
15
|
+
# include "fs_path.h"
|
16
|
+
# include "win32/path_w32.h"
|
17
|
+
# include "win32/utf-conv.h"
|
16
18
|
#else
|
17
|
-
#include <unistd.h>
|
18
|
-
#include <pwd.h>
|
19
|
+
# include <unistd.h>
|
20
|
+
# include <pwd.h>
|
19
21
|
#endif
|
20
22
|
|
23
|
+
#ifdef GIT_WIN32
|
24
|
+
# define REG_GITFORWINDOWS_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1"
|
25
|
+
# define REG_GITFORWINDOWS_KEY_WOW64 L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1"
|
26
|
+
|
27
|
+
static int expand_win32_path(git_win32_path dest, const wchar_t *src)
|
28
|
+
{
|
29
|
+
DWORD len = ExpandEnvironmentStringsW(src, dest, GIT_WIN_PATH_UTF16);
|
30
|
+
|
31
|
+
if (!len || len > GIT_WIN_PATH_UTF16)
|
32
|
+
return -1;
|
33
|
+
|
34
|
+
return 0;
|
35
|
+
}
|
36
|
+
|
37
|
+
static int win32_path_to_utf8(git_str *dest, const wchar_t *src)
|
38
|
+
{
|
39
|
+
git_win32_utf8_path utf8_path;
|
40
|
+
|
41
|
+
if (git_win32_path_to_utf8(utf8_path, src) < 0) {
|
42
|
+
git_error_set(GIT_ERROR_OS, "unable to convert path to UTF-8");
|
43
|
+
return -1;
|
44
|
+
}
|
45
|
+
|
46
|
+
/* Convert backslashes to forward slashes */
|
47
|
+
git_fs_path_mkposix(utf8_path);
|
48
|
+
|
49
|
+
return git_str_sets(dest, utf8_path);
|
50
|
+
}
|
51
|
+
|
52
|
+
static git_win32_path mock_registry;
|
53
|
+
static bool mock_registry_set;
|
54
|
+
|
55
|
+
extern int git_win32__set_registry_system_dir(const wchar_t *mock_sysdir)
|
56
|
+
{
|
57
|
+
if (!mock_sysdir) {
|
58
|
+
mock_registry[0] = L'\0';
|
59
|
+
mock_registry_set = false;
|
60
|
+
} else {
|
61
|
+
size_t len = wcslen(mock_sysdir);
|
62
|
+
|
63
|
+
if (len > GIT_WIN_PATH_MAX) {
|
64
|
+
git_error_set(GIT_ERROR_INVALID, "mock path too long");
|
65
|
+
return -1;
|
66
|
+
}
|
67
|
+
|
68
|
+
wcscpy(mock_registry, mock_sysdir);
|
69
|
+
mock_registry_set = true;
|
70
|
+
}
|
71
|
+
|
72
|
+
return 0;
|
73
|
+
}
|
74
|
+
|
75
|
+
static int lookup_registry_key(
|
76
|
+
git_win32_path out,
|
77
|
+
const HKEY hive,
|
78
|
+
const wchar_t* key,
|
79
|
+
const wchar_t *value)
|
80
|
+
{
|
81
|
+
HKEY hkey;
|
82
|
+
DWORD type, size;
|
83
|
+
int error = GIT_ENOTFOUND;
|
84
|
+
|
85
|
+
/*
|
86
|
+
* Registry data may not be NUL terminated, provide room to do
|
87
|
+
* it ourselves.
|
88
|
+
*/
|
89
|
+
size = (DWORD)((sizeof(git_win32_path) - 1) * sizeof(wchar_t));
|
90
|
+
|
91
|
+
if (RegOpenKeyExW(hive, key, 0, KEY_READ, &hkey) != 0)
|
92
|
+
return GIT_ENOTFOUND;
|
93
|
+
|
94
|
+
if (RegQueryValueExW(hkey, value, NULL, &type, (LPBYTE)out, &size) == 0 &&
|
95
|
+
type == REG_SZ &&
|
96
|
+
size > 0 &&
|
97
|
+
size < sizeof(git_win32_path)) {
|
98
|
+
size_t wsize = size / sizeof(wchar_t);
|
99
|
+
size_t len = wsize - 1;
|
100
|
+
|
101
|
+
if (out[wsize - 1] != L'\0') {
|
102
|
+
len = wsize;
|
103
|
+
out[wsize] = L'\0';
|
104
|
+
}
|
105
|
+
|
106
|
+
if (out[len - 1] == L'\\')
|
107
|
+
out[len - 1] = L'\0';
|
108
|
+
|
109
|
+
if (_waccess(out, F_OK) == 0)
|
110
|
+
error = 0;
|
111
|
+
}
|
112
|
+
|
113
|
+
RegCloseKey(hkey);
|
114
|
+
return error;
|
115
|
+
}
|
116
|
+
|
117
|
+
static int find_sysdir_in_registry(git_win32_path out)
|
118
|
+
{
|
119
|
+
if (mock_registry_set) {
|
120
|
+
if (mock_registry[0] == L'\0')
|
121
|
+
return GIT_ENOTFOUND;
|
122
|
+
|
123
|
+
wcscpy(out, mock_registry);
|
124
|
+
return 0;
|
125
|
+
}
|
126
|
+
|
127
|
+
if (lookup_registry_key(out, HKEY_CURRENT_USER, REG_GITFORWINDOWS_KEY, L"InstallLocation") == 0 ||
|
128
|
+
lookup_registry_key(out, HKEY_CURRENT_USER, REG_GITFORWINDOWS_KEY_WOW64, L"InstallLocation") == 0 ||
|
129
|
+
lookup_registry_key(out, HKEY_LOCAL_MACHINE, REG_GITFORWINDOWS_KEY, L"InstallLocation") == 0 ||
|
130
|
+
lookup_registry_key(out, HKEY_LOCAL_MACHINE, REG_GITFORWINDOWS_KEY_WOW64, L"InstallLocation") == 0)
|
131
|
+
return 0;
|
132
|
+
|
133
|
+
return GIT_ENOTFOUND;
|
134
|
+
}
|
135
|
+
|
136
|
+
static int find_sysdir_in_path(git_win32_path out)
|
137
|
+
{
|
138
|
+
size_t out_len;
|
139
|
+
|
140
|
+
if (git_win32_path_find_executable(out, L"git.exe") < 0 &&
|
141
|
+
git_win32_path_find_executable(out, L"git.cmd") < 0)
|
142
|
+
return GIT_ENOTFOUND;
|
143
|
+
|
144
|
+
out_len = wcslen(out);
|
145
|
+
|
146
|
+
/* Trim the file name */
|
147
|
+
if (out_len <= CONST_STRLEN(L"git.exe"))
|
148
|
+
return GIT_ENOTFOUND;
|
149
|
+
|
150
|
+
out_len -= CONST_STRLEN(L"git.exe");
|
151
|
+
|
152
|
+
if (out_len && out[out_len - 1] == L'\\')
|
153
|
+
out_len--;
|
154
|
+
|
155
|
+
/*
|
156
|
+
* Git for Windows usually places the command in a 'bin' or
|
157
|
+
* 'cmd' directory, trim that.
|
158
|
+
*/
|
159
|
+
if (out_len >= CONST_STRLEN(L"\\bin") &&
|
160
|
+
wcsncmp(&out[out_len - CONST_STRLEN(L"\\bin")], L"\\bin", CONST_STRLEN(L"\\bin")) == 0)
|
161
|
+
out_len -= CONST_STRLEN(L"\\bin");
|
162
|
+
else if (out_len >= CONST_STRLEN(L"\\cmd") &&
|
163
|
+
wcsncmp(&out[out_len - CONST_STRLEN(L"\\cmd")], L"\\cmd", CONST_STRLEN(L"\\cmd")) == 0)
|
164
|
+
out_len -= CONST_STRLEN(L"\\cmd");
|
165
|
+
|
166
|
+
if (!out_len)
|
167
|
+
return GIT_ENOTFOUND;
|
168
|
+
|
169
|
+
out[out_len] = L'\0';
|
170
|
+
return 0;
|
171
|
+
}
|
172
|
+
|
173
|
+
static int find_win32_dirs(
|
174
|
+
git_str *out,
|
175
|
+
const wchar_t* tmpl[])
|
176
|
+
{
|
177
|
+
git_win32_path path16;
|
178
|
+
git_str buf = GIT_STR_INIT;
|
179
|
+
|
180
|
+
git_str_clear(out);
|
181
|
+
|
182
|
+
for (; *tmpl != NULL; tmpl++) {
|
183
|
+
if (!expand_win32_path(path16, *tmpl) &&
|
184
|
+
path16[0] != L'%' &&
|
185
|
+
!_waccess(path16, F_OK)) {
|
186
|
+
win32_path_to_utf8(&buf, path16);
|
187
|
+
|
188
|
+
if (buf.size)
|
189
|
+
git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr);
|
190
|
+
}
|
191
|
+
}
|
192
|
+
|
193
|
+
git_str_dispose(&buf);
|
194
|
+
|
195
|
+
return (git_str_oom(out) ? -1 : 0);
|
196
|
+
}
|
197
|
+
|
198
|
+
static int append_subdir(git_str *out, git_str *path, const char *subdir)
|
199
|
+
{
|
200
|
+
static const char* architecture_roots[] = {
|
201
|
+
"",
|
202
|
+
"mingw64",
|
203
|
+
"mingw32",
|
204
|
+
NULL
|
205
|
+
};
|
206
|
+
const char **root;
|
207
|
+
size_t orig_path_len = path->size;
|
208
|
+
|
209
|
+
for (root = architecture_roots; *root; root++) {
|
210
|
+
if ((*root[0] && git_str_joinpath(path, path->ptr, *root) < 0) ||
|
211
|
+
git_str_joinpath(path, path->ptr, subdir) < 0)
|
212
|
+
return -1;
|
213
|
+
|
214
|
+
if (git_fs_path_exists(path->ptr) &&
|
215
|
+
git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, path->ptr) < 0)
|
216
|
+
return -1;
|
217
|
+
|
218
|
+
git_str_truncate(path, orig_path_len);
|
219
|
+
}
|
220
|
+
|
221
|
+
return 0;
|
222
|
+
}
|
223
|
+
|
224
|
+
int git_win32__find_system_dirs(git_str *out, const char *subdir)
|
225
|
+
{
|
226
|
+
git_win32_path pathdir, regdir;
|
227
|
+
git_str path8 = GIT_STR_INIT;
|
228
|
+
bool has_pathdir, has_regdir;
|
229
|
+
int error;
|
230
|
+
|
231
|
+
has_pathdir = (find_sysdir_in_path(pathdir) == 0);
|
232
|
+
has_regdir = (find_sysdir_in_registry(regdir) == 0);
|
233
|
+
|
234
|
+
if (!has_pathdir && !has_regdir)
|
235
|
+
return 0;
|
236
|
+
|
237
|
+
/*
|
238
|
+
* Usually the git in the path is the same git in the registry,
|
239
|
+
* in this case there's no need to duplicate the paths.
|
240
|
+
*/
|
241
|
+
if (has_pathdir && has_regdir && wcscmp(pathdir, regdir) == 0)
|
242
|
+
has_regdir = false;
|
243
|
+
|
244
|
+
if (has_pathdir) {
|
245
|
+
if ((error = win32_path_to_utf8(&path8, pathdir)) < 0 ||
|
246
|
+
(error = append_subdir(out, &path8, subdir)) < 0)
|
247
|
+
goto done;
|
248
|
+
}
|
249
|
+
|
250
|
+
if (has_regdir) {
|
251
|
+
if ((error = win32_path_to_utf8(&path8, regdir)) < 0 ||
|
252
|
+
(error = append_subdir(out, &path8, subdir)) < 0)
|
253
|
+
goto done;
|
254
|
+
}
|
255
|
+
|
256
|
+
done:
|
257
|
+
git_str_dispose(&path8);
|
258
|
+
return error;
|
259
|
+
}
|
260
|
+
#endif /* WIN32 */
|
261
|
+
|
21
262
|
static int git_sysdir_guess_programdata_dirs(git_str *out)
|
22
263
|
{
|
23
264
|
#ifdef GIT_WIN32
|
24
|
-
|
265
|
+
static const wchar_t *programdata_tmpls[2] = {
|
266
|
+
L"%PROGRAMDATA%\\Git",
|
267
|
+
NULL,
|
268
|
+
};
|
269
|
+
|
270
|
+
return find_win32_dirs(out, programdata_tmpls);
|
25
271
|
#else
|
26
272
|
git_str_clear(out);
|
27
273
|
return 0;
|
@@ -75,10 +321,17 @@ out:
|
|
75
321
|
}
|
76
322
|
#endif
|
77
323
|
|
78
|
-
static int
|
324
|
+
static int git_sysdir_guess_home_dirs(git_str *out)
|
79
325
|
{
|
80
326
|
#ifdef GIT_WIN32
|
81
|
-
|
327
|
+
static const wchar_t *global_tmpls[4] = {
|
328
|
+
L"%HOME%\\",
|
329
|
+
L"%HOMEDRIVE%%HOMEPATH%\\",
|
330
|
+
L"%USERPROFILE%\\",
|
331
|
+
NULL,
|
332
|
+
};
|
333
|
+
|
334
|
+
return find_win32_dirs(out, global_tmpls);
|
82
335
|
#else
|
83
336
|
int error;
|
84
337
|
uid_t uid, euid;
|
@@ -114,10 +367,25 @@ static int git_sysdir_guess_global_dirs(git_str *out)
|
|
114
367
|
#endif
|
115
368
|
}
|
116
369
|
|
370
|
+
static int git_sysdir_guess_global_dirs(git_str *out)
|
371
|
+
{
|
372
|
+
return git_sysdir_guess_home_dirs(out);
|
373
|
+
}
|
374
|
+
|
117
375
|
static int git_sysdir_guess_xdg_dirs(git_str *out)
|
118
376
|
{
|
119
377
|
#ifdef GIT_WIN32
|
120
|
-
|
378
|
+
static const wchar_t *global_tmpls[7] = {
|
379
|
+
L"%XDG_CONFIG_HOME%\\git",
|
380
|
+
L"%APPDATA%\\git",
|
381
|
+
L"%LOCALAPPDATA%\\git",
|
382
|
+
L"%HOME%\\.config\\git",
|
383
|
+
L"%HOMEDRIVE%%HOMEPATH%\\.config\\git",
|
384
|
+
L"%USERPROFILE%\\.config\\git",
|
385
|
+
NULL,
|
386
|
+
};
|
387
|
+
|
388
|
+
return find_win32_dirs(out, global_tmpls);
|
121
389
|
#else
|
122
390
|
git_str env = GIT_STR_INIT;
|
123
391
|
int error;
|
@@ -171,6 +439,7 @@ static struct git_sysdir__dir git_sysdir__dirs[] = {
|
|
171
439
|
{ GIT_STR_INIT, git_sysdir_guess_xdg_dirs },
|
172
440
|
{ GIT_STR_INIT, git_sysdir_guess_programdata_dirs },
|
173
441
|
{ GIT_STR_INIT, git_sysdir_guess_template_dirs },
|
442
|
+
{ GIT_STR_INIT, git_sysdir_guess_home_dirs }
|
174
443
|
};
|
175
444
|
|
176
445
|
static void git_sysdir_global_shutdown(void)
|
@@ -350,6 +619,12 @@ int git_sysdir_find_template_dir(git_str *path)
|
|
350
619
|
path, NULL, GIT_SYSDIR_TEMPLATE, "template");
|
351
620
|
}
|
352
621
|
|
622
|
+
int git_sysdir_find_homedir(git_str *path)
|
623
|
+
{
|
624
|
+
return git_sysdir_find_in_dirlist(
|
625
|
+
path, NULL, GIT_SYSDIR_HOME, "home directory");
|
626
|
+
}
|
627
|
+
|
353
628
|
int git_sysdir_expand_global_file(git_str *path, const char *filename)
|
354
629
|
{
|
355
630
|
int error;
|
@@ -361,3 +636,15 @@ int git_sysdir_expand_global_file(git_str *path, const char *filename)
|
|
361
636
|
|
362
637
|
return error;
|
363
638
|
}
|
639
|
+
|
640
|
+
int git_sysdir_expand_homedir_file(git_str *path, const char *filename)
|
641
|
+
{
|
642
|
+
int error;
|
643
|
+
|
644
|
+
if ((error = git_sysdir_find_homedir(path)) == 0) {
|
645
|
+
if (filename)
|
646
|
+
error = git_str_joinpath(path, path->ptr, filename);
|
647
|
+
}
|
648
|
+
|
649
|
+
return error;
|
650
|
+
}
|
@@ -57,10 +57,22 @@ extern int git_sysdir_find_programdata_file(git_str *path, const char *filename)
|
|
57
57
|
extern int git_sysdir_find_template_dir(git_str *path);
|
58
58
|
|
59
59
|
/**
|
60
|
-
*
|
61
|
-
*
|
62
|
-
*
|
63
|
-
*
|
60
|
+
* Find the home directory. On Windows, this will look at the `HOME`,
|
61
|
+
* `HOMEPATH`, and `USERPROFILE` environment variables (in that order)
|
62
|
+
* and return the first path that is set and exists. On other systems,
|
63
|
+
* this will simply return the contents of the `HOME` environment variable.
|
64
|
+
*
|
65
|
+
* @param path buffer to write the full path into
|
66
|
+
* @return 0 if found, GIT_ENOTFOUND if not found, or -1 on other OS error
|
67
|
+
*/
|
68
|
+
extern int git_sysdir_find_homedir(git_str *path);
|
69
|
+
|
70
|
+
/**
|
71
|
+
* Expand the name of a "global" file -- by default inside the user's
|
72
|
+
* home directory, but can be overridden by the user configuration.
|
73
|
+
* Unlike `find_global_file` (above), this makes no attempt to check
|
74
|
+
* for the existence of the file, and is useful if you want the full
|
75
|
+
* path regardless of existence.
|
64
76
|
*
|
65
77
|
* @param path buffer to write the full path into
|
66
78
|
* @param filename name of file in the home directory
|
@@ -68,13 +80,25 @@ extern int git_sysdir_find_template_dir(git_str *path);
|
|
68
80
|
*/
|
69
81
|
extern int git_sysdir_expand_global_file(git_str *path, const char *filename);
|
70
82
|
|
83
|
+
/**
|
84
|
+
* Expand the name of a file in the user's home directory. This
|
85
|
+
* function makes no attempt to check for the existence of the file,
|
86
|
+
* and is useful if you want the full path regardless of existence.
|
87
|
+
*
|
88
|
+
* @param path buffer to write the full path into
|
89
|
+
* @param filename name of file in the home directory
|
90
|
+
* @return 0 on success or -1 on error
|
91
|
+
*/
|
92
|
+
extern int git_sysdir_expand_homedir_file(git_str *path, const char *filename);
|
93
|
+
|
71
94
|
typedef enum {
|
72
|
-
GIT_SYSDIR_SYSTEM
|
73
|
-
GIT_SYSDIR_GLOBAL
|
74
|
-
GIT_SYSDIR_XDG
|
95
|
+
GIT_SYSDIR_SYSTEM = 0,
|
96
|
+
GIT_SYSDIR_GLOBAL = 1,
|
97
|
+
GIT_SYSDIR_XDG = 2,
|
75
98
|
GIT_SYSDIR_PROGRAMDATA = 3,
|
76
|
-
GIT_SYSDIR_TEMPLATE
|
77
|
-
|
99
|
+
GIT_SYSDIR_TEMPLATE = 4,
|
100
|
+
GIT_SYSDIR_HOME = 5,
|
101
|
+
GIT_SYSDIR__MAX = 6
|
78
102
|
} git_sysdir_t;
|
79
103
|
|
80
104
|
/**
|
@@ -110,4 +134,12 @@ extern int git_sysdir_set(git_sysdir_t which, const char *paths);
|
|
110
134
|
*/
|
111
135
|
extern int git_sysdir_reset(void);
|
112
136
|
|
137
|
+
#ifdef GIT_WIN32
|
138
|
+
/** Sets the registry system dir to a mock; for testing. */
|
139
|
+
extern int git_win32__set_registry_system_dir(const wchar_t *mock_sysdir);
|
140
|
+
|
141
|
+
/** Find the given system dir; for testing. */
|
142
|
+
extern int git_win32__find_system_dirs(git_str *out, const char *subdir);
|
143
|
+
#endif
|
144
|
+
|
113
145
|
#endif
|
@@ -65,7 +65,11 @@ static int tag_error(const char *str)
|
|
65
65
|
return GIT_EINVALID;
|
66
66
|
}
|
67
67
|
|
68
|
-
static int tag_parse(
|
68
|
+
static int tag_parse(
|
69
|
+
git_tag *tag,
|
70
|
+
const char *buffer,
|
71
|
+
const char *buffer_end,
|
72
|
+
git_oid_t oid_type)
|
69
73
|
{
|
70
74
|
static const char *tag_types[] = {
|
71
75
|
NULL, "commit\n", "tree\n", "blob\n", "tag\n"
|
@@ -75,7 +79,8 @@ static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end)
|
|
75
79
|
unsigned int i;
|
76
80
|
int error;
|
77
81
|
|
78
|
-
if (
|
82
|
+
if (git_object__parse_oid_header(&tag->target,
|
83
|
+
&buffer, buffer_end, "object ", oid_type) < 0)
|
79
84
|
return tag_error("object field invalid");
|
80
85
|
|
81
86
|
if (buffer + 5 >= buffer_end)
|
@@ -160,18 +165,25 @@ static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end)
|
|
160
165
|
return 0;
|
161
166
|
}
|
162
167
|
|
163
|
-
int git_tag__parse_raw(
|
168
|
+
int git_tag__parse_raw(
|
169
|
+
void *_tag,
|
170
|
+
const char *data,
|
171
|
+
size_t size,
|
172
|
+
git_oid_t oid_type)
|
164
173
|
{
|
165
|
-
return tag_parse(_tag, data, data + size);
|
174
|
+
return tag_parse(_tag, data, data + size, oid_type);
|
166
175
|
}
|
167
176
|
|
168
|
-
int git_tag__parse(
|
177
|
+
int git_tag__parse(
|
178
|
+
void *_tag,
|
179
|
+
git_odb_object *odb_obj,
|
180
|
+
git_oid_t oid_type)
|
169
181
|
{
|
170
182
|
git_tag *tag = _tag;
|
171
183
|
const char *buffer = git_odb_object_data(odb_obj);
|
172
184
|
const char *buffer_end = buffer + git_odb_object_size(odb_obj);
|
173
185
|
|
174
|
-
return tag_parse(tag, buffer, buffer_end);
|
186
|
+
return tag_parse(tag, buffer, buffer_end, oid_type);
|
175
187
|
}
|
176
188
|
|
177
189
|
static int retrieve_tag_reference(
|
@@ -220,7 +232,9 @@ static int write_tag_annotation(
|
|
220
232
|
git_str tag = GIT_STR_INIT;
|
221
233
|
git_odb *odb;
|
222
234
|
|
223
|
-
|
235
|
+
if (git_object__write_oid_header(&tag, "object ", git_object_id(target)) < 0)
|
236
|
+
goto on_error;
|
237
|
+
|
224
238
|
git_str_printf(&tag, "type %s\n", git_object_type2string(git_object_type(target)));
|
225
239
|
git_str_printf(&tag, "tag %s\n", tag_name);
|
226
240
|
git_signature__writebuf(&tag, "tagger ", tagger);
|
@@ -296,8 +310,10 @@ static int git_tag_create__internal(
|
|
296
310
|
}
|
297
311
|
|
298
312
|
if (create_tag_annotation) {
|
299
|
-
if (write_tag_annotation(oid, repo, tag_name, target, tagger, message) < 0)
|
313
|
+
if (write_tag_annotation(oid, repo, tag_name, target, tagger, message) < 0) {
|
314
|
+
git_str_dispose(&ref_name);
|
300
315
|
return -1;
|
316
|
+
}
|
301
317
|
} else
|
302
318
|
git_oid_cpy(oid, git_object_id(target));
|
303
319
|
|
@@ -369,7 +385,7 @@ int git_tag_create_from_buffer(git_oid *oid, git_repository *repo, const char *b
|
|
369
385
|
return -1;
|
370
386
|
|
371
387
|
/* validate the buffer */
|
372
|
-
if (tag_parse(&tag, buffer, buffer + strlen(buffer)) < 0)
|
388
|
+
if (tag_parse(&tag, buffer, buffer + strlen(buffer), repo->oid_type) < 0)
|
373
389
|
return -1;
|
374
390
|
|
375
391
|
/* validate the target */
|
@@ -394,14 +410,17 @@ int git_tag_create_from_buffer(git_oid *oid, git_repository *repo, const char *b
|
|
394
410
|
/** Ensure the tag name doesn't conflict with an already existing
|
395
411
|
* reference unless overwriting has explicitly been requested **/
|
396
412
|
if (error == 0 && !allow_ref_overwrite) {
|
413
|
+
git_str_dispose(&ref_name);
|
397
414
|
git_error_set(GIT_ERROR_TAG, "tag already exists");
|
398
415
|
return GIT_EEXISTS;
|
399
416
|
}
|
400
417
|
|
401
418
|
/* write the buffer */
|
402
419
|
if ((error = git_odb_open_wstream(
|
403
|
-
&stream, odb, strlen(buffer), GIT_OBJECT_TAG)) < 0)
|
420
|
+
&stream, odb, strlen(buffer), GIT_OBJECT_TAG)) < 0) {
|
421
|
+
git_str_dispose(&ref_name);
|
404
422
|
return error;
|
423
|
+
}
|
405
424
|
|
406
425
|
if (!(error = git_odb_stream_write(stream, buffer, strlen(buffer))))
|
407
426
|
error = git_odb_stream_finalize_write(oid, stream);
|
@@ -25,7 +25,7 @@ struct git_tag {
|
|
25
25
|
};
|
26
26
|
|
27
27
|
void git_tag__free(void *tag);
|
28
|
-
int git_tag__parse(void *tag, git_odb_object *obj);
|
29
|
-
int git_tag__parse_raw(void *tag, const char *data, size_t size);
|
28
|
+
int git_tag__parse(void *tag, git_odb_object *obj, git_oid_t oid_type);
|
29
|
+
int git_tag__parse_raw(void *tag, const char *data, size_t size, git_oid_t oid_type);
|
30
30
|
|
31
31
|
#endif
|
@@ -655,6 +655,7 @@ static int http_action(
|
|
655
655
|
{
|
656
656
|
http_subtransport *transport = GIT_CONTAINER_OF(t, http_subtransport, parent);
|
657
657
|
git_remote_connect_options *connect_opts = &transport->owner->connect_opts;
|
658
|
+
git_http_client_options opts = {0};
|
658
659
|
http_stream *stream;
|
659
660
|
const http_service *service;
|
660
661
|
int error;
|
@@ -683,14 +684,14 @@ static int http_action(
|
|
683
684
|
stream = git__calloc(sizeof(http_stream), 1);
|
684
685
|
GIT_ERROR_CHECK_ALLOC(stream);
|
685
686
|
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
opts.server_certificate_check_payload = connect_opts->callbacks.payload;
|
691
|
-
opts.proxy_certificate_check_cb = connect_opts->proxy_opts.certificate_check;
|
692
|
-
opts.proxy_certificate_check_payload = connect_opts->proxy_opts.payload;
|
687
|
+
opts.server_certificate_check_cb = connect_opts->callbacks.certificate_check;
|
688
|
+
opts.server_certificate_check_payload = connect_opts->callbacks.payload;
|
689
|
+
opts.proxy_certificate_check_cb = connect_opts->proxy_opts.certificate_check;
|
690
|
+
opts.proxy_certificate_check_payload = connect_opts->proxy_opts.payload;
|
693
691
|
|
692
|
+
if (transport->http_client) {
|
693
|
+
git_http_client_set_options(transport->http_client, &opts);
|
694
|
+
} else {
|
694
695
|
if (git_http_client_new(&transport->http_client, &opts) < 0)
|
695
696
|
return -1;
|
696
697
|
}
|
@@ -1541,6 +1541,15 @@ int git_http_client_new(
|
|
1541
1541
|
return 0;
|
1542
1542
|
}
|
1543
1543
|
|
1544
|
+
/* Update the options of an existing httpclient instance. */
|
1545
|
+
void git_http_client_set_options(
|
1546
|
+
git_http_client *client,
|
1547
|
+
git_http_client_options *opts)
|
1548
|
+
{
|
1549
|
+
if (opts)
|
1550
|
+
memcpy(&client->opts, opts, sizeof(git_http_client_options));
|
1551
|
+
}
|
1552
|
+
|
1544
1553
|
GIT_INLINE(void) http_server_close(git_http_server *server)
|
1545
1554
|
{
|
1546
1555
|
if (server->stream) {
|
@@ -88,6 +88,16 @@ extern int git_http_client_new(
|
|
88
88
|
git_http_client **out,
|
89
89
|
git_http_client_options *opts);
|
90
90
|
|
91
|
+
/**
|
92
|
+
* Update the options of an existing httpclient instance.
|
93
|
+
*
|
94
|
+
* @param client the httpclient instance to modify
|
95
|
+
* @param opts new options or NULL to keep existing options
|
96
|
+
*/
|
97
|
+
extern void git_http_client_set_options(
|
98
|
+
git_http_client *client,
|
99
|
+
git_http_client_options *opts);
|
100
|
+
|
91
101
|
/*
|
92
102
|
* Sends a request to the host specified by the request URL. If the
|
93
103
|
* method is POST, either the content_length or the chunked flag must
|
@@ -266,6 +266,17 @@ static int local_capabilities(unsigned int *capabilities, git_transport *transpo
|
|
266
266
|
return 0;
|
267
267
|
}
|
268
268
|
|
269
|
+
#ifdef GIT_EXPERIMENTAL_SHA256
|
270
|
+
static int local_oid_type(git_oid_t *out, git_transport *transport)
|
271
|
+
{
|
272
|
+
transport_local *t = (transport_local *)transport;
|
273
|
+
|
274
|
+
*out = t->repo->oid_type;
|
275
|
+
|
276
|
+
return 0;
|
277
|
+
}
|
278
|
+
#endif
|
279
|
+
|
269
280
|
static int local_ls(const git_remote_head ***out, size_t *size, git_transport *transport)
|
270
281
|
{
|
271
282
|
transport_local *t = (transport_local *)transport;
|
@@ -732,6 +743,9 @@ int git_transport_local(git_transport **out, git_remote *owner, void *param)
|
|
732
743
|
t->parent.connect = local_connect;
|
733
744
|
t->parent.set_connect_opts = local_set_connect_opts;
|
734
745
|
t->parent.capabilities = local_capabilities;
|
746
|
+
#ifdef GIT_EXPERIMENTAL_SHA256
|
747
|
+
t->parent.oid_type = local_oid_type;
|
748
|
+
#endif
|
735
749
|
t->parent.negotiate_fetch = local_negotiate_fetch;
|
736
750
|
t->parent.download_pack = local_download_pack;
|
737
751
|
t->parent.push = local_push;
|
@@ -54,6 +54,12 @@ GIT_INLINE(int) git_smart__reset_stream(transport_smart *t, bool close_subtransp
|
|
54
54
|
return -1;
|
55
55
|
}
|
56
56
|
|
57
|
+
git__free(t->caps.object_format);
|
58
|
+
t->caps.object_format = NULL;
|
59
|
+
|
60
|
+
git__free(t->caps.agent);
|
61
|
+
t->caps.agent = NULL;
|
62
|
+
|
57
63
|
return 0;
|
58
64
|
}
|
59
65
|
|
@@ -242,6 +248,30 @@ static int git_smart__capabilities(unsigned int *capabilities, git_transport *tr
|
|
242
248
|
return 0;
|
243
249
|
}
|
244
250
|
|
251
|
+
#ifdef GIT_EXPERIMENTAL_SHA256
|
252
|
+
static int git_smart__oid_type(git_oid_t *out, git_transport *transport)
|
253
|
+
{
|
254
|
+
transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent);
|
255
|
+
|
256
|
+
*out = 0;
|
257
|
+
|
258
|
+
if (t->caps.object_format == NULL) {
|
259
|
+
*out = GIT_OID_DEFAULT;
|
260
|
+
} else {
|
261
|
+
*out = git_oid_type_fromstr(t->caps.object_format);
|
262
|
+
|
263
|
+
if (!*out) {
|
264
|
+
git_error_set(GIT_ERROR_INVALID,
|
265
|
+
"unknown object format '%s'",
|
266
|
+
t->caps.object_format);
|
267
|
+
return -1;
|
268
|
+
}
|
269
|
+
}
|
270
|
+
|
271
|
+
return 0;
|
272
|
+
}
|
273
|
+
#endif
|
274
|
+
|
245
275
|
static int git_smart__ls(const git_remote_head ***out, size_t *size, git_transport *transport)
|
246
276
|
{
|
247
277
|
transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent);
|
@@ -386,6 +416,8 @@ static void git_smart__free(git_transport *transport)
|
|
386
416
|
|
387
417
|
git_remote_connect_options_dispose(&t->connect_opts);
|
388
418
|
|
419
|
+
git__free(t->caps.object_format);
|
420
|
+
git__free(t->caps.agent);
|
389
421
|
git__free(t);
|
390
422
|
}
|
391
423
|
|
@@ -452,6 +484,9 @@ int git_transport_smart(git_transport **out, git_remote *owner, void *param)
|
|
452
484
|
t->parent.connect = git_smart__connect;
|
453
485
|
t->parent.set_connect_opts = git_smart__set_connect_opts;
|
454
486
|
t->parent.capabilities = git_smart__capabilities;
|
487
|
+
#ifdef GIT_EXPERIMENTAL_SHA256
|
488
|
+
t->parent.oid_type = git_smart__oid_type;
|
489
|
+
#endif
|
455
490
|
t->parent.close = git_smart__close;
|
456
491
|
t->parent.free = git_smart__free;
|
457
492
|
t->parent.negotiate_fetch = git_smart__negotiate_fetch;
|