rugged 1.5.1 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/extconf.rb +2 -2
  3. data/ext/rugged/rugged_blame.c +2 -0
  4. data/ext/rugged/rugged_blob.c +3 -0
  5. data/ext/rugged/rugged_commit.c +1 -0
  6. data/ext/rugged/rugged_config.c +2 -0
  7. data/ext/rugged/rugged_diff.c +1 -0
  8. data/ext/rugged/rugged_index.c +2 -0
  9. data/ext/rugged/rugged_patch.c +1 -0
  10. data/ext/rugged/rugged_rebase.c +1 -0
  11. data/ext/rugged/rugged_reference.c +1 -0
  12. data/ext/rugged/rugged_remote.c +1 -0
  13. data/ext/rugged/rugged_repo.c +5 -2
  14. data/ext/rugged/rugged_revwalk.c +5 -1
  15. data/ext/rugged/rugged_submodule.c +1 -0
  16. data/ext/rugged/rugged_tag.c +1 -0
  17. data/ext/rugged/rugged_tree.c +4 -0
  18. data/lib/rugged/index.rb +1 -1
  19. data/lib/rugged/tree.rb +1 -1
  20. data/lib/rugged/version.rb +1 -1
  21. data/vendor/libgit2/CMakeLists.txt +5 -1
  22. data/vendor/libgit2/COPYING +30 -0
  23. data/vendor/libgit2/cmake/ExperimentalFeatures.cmake +23 -0
  24. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +2 -0
  25. data/vendor/libgit2/include/git2/common.h +13 -6
  26. data/vendor/libgit2/include/git2/deprecated.h +6 -0
  27. data/vendor/libgit2/include/git2/diff.h +1 -1
  28. data/vendor/libgit2/include/git2/experimental.h +20 -0
  29. data/vendor/libgit2/include/git2/indexer.h +29 -0
  30. data/vendor/libgit2/include/git2/object.h +28 -2
  31. data/vendor/libgit2/include/git2/odb.h +58 -7
  32. data/vendor/libgit2/include/git2/odb_backend.h +106 -18
  33. data/vendor/libgit2/include/git2/oid.h +115 -15
  34. data/vendor/libgit2/include/git2/repository.h +20 -1
  35. data/vendor/libgit2/include/git2/stash.h +60 -6
  36. data/vendor/libgit2/include/git2/strarray.h +0 -13
  37. data/vendor/libgit2/include/git2/sys/odb_backend.h +1 -1
  38. data/vendor/libgit2/include/git2/sys/transport.h +12 -0
  39. data/vendor/libgit2/include/git2/version.h +4 -4
  40. data/vendor/libgit2/include/git2.h +1 -0
  41. data/vendor/libgit2/src/CMakeLists.txt +0 -6
  42. data/vendor/libgit2/src/cli/CMakeLists.txt +6 -2
  43. data/vendor/libgit2/src/cli/cmd_hash_object.c +27 -8
  44. data/vendor/libgit2/src/cli/opt.c +1 -1
  45. data/vendor/libgit2/src/libgit2/CMakeLists.txt +25 -15
  46. data/vendor/libgit2/src/libgit2/annotated_commit.c +1 -1
  47. data/vendor/libgit2/src/libgit2/annotated_commit.h +1 -1
  48. data/vendor/libgit2/src/libgit2/attr_file.c +1 -1
  49. data/vendor/libgit2/src/libgit2/attrcache.c +1 -1
  50. data/vendor/libgit2/src/libgit2/blame.c +2 -0
  51. data/vendor/libgit2/src/libgit2/blob.c +4 -2
  52. data/vendor/libgit2/src/libgit2/blob.h +2 -2
  53. data/vendor/libgit2/src/libgit2/branch.c +2 -2
  54. data/vendor/libgit2/src/libgit2/cherrypick.c +3 -3
  55. data/vendor/libgit2/src/libgit2/clone.c +31 -2
  56. data/vendor/libgit2/src/libgit2/commit.c +52 -17
  57. data/vendor/libgit2/src/libgit2/commit.h +25 -7
  58. data/vendor/libgit2/src/libgit2/commit_graph.c +47 -32
  59. data/vendor/libgit2/src/libgit2/commit_graph.h +3 -0
  60. data/vendor/libgit2/src/libgit2/commit_list.c +6 -2
  61. data/vendor/libgit2/src/libgit2/config.c +1 -1
  62. data/vendor/libgit2/src/libgit2/config_file.c +2 -2
  63. data/vendor/libgit2/src/libgit2/describe.c +8 -8
  64. data/vendor/libgit2/src/libgit2/diff.c +5 -1
  65. data/vendor/libgit2/src/libgit2/diff_file.c +15 -6
  66. data/vendor/libgit2/src/libgit2/diff_generate.c +17 -12
  67. data/vendor/libgit2/src/libgit2/diff_print.c +5 -5
  68. data/vendor/libgit2/src/libgit2/diff_tform.c +4 -0
  69. data/vendor/libgit2/src/libgit2/email.c +2 -2
  70. data/vendor/libgit2/src/libgit2/experimental.h.in +13 -0
  71. data/vendor/libgit2/src/libgit2/fetch.c +3 -6
  72. data/vendor/libgit2/src/libgit2/fetchhead.c +4 -4
  73. data/vendor/libgit2/src/libgit2/ident.c +3 -3
  74. data/vendor/libgit2/src/libgit2/index.c +11 -9
  75. data/vendor/libgit2/src/libgit2/indexer.c +107 -44
  76. data/vendor/libgit2/src/libgit2/iterator.c +4 -2
  77. data/vendor/libgit2/src/libgit2/libgit2.c +19 -0
  78. data/vendor/libgit2/src/libgit2/merge.c +3 -3
  79. data/vendor/libgit2/src/libgit2/midx.c +16 -15
  80. data/vendor/libgit2/src/libgit2/mwindow.c +5 -2
  81. data/vendor/libgit2/src/libgit2/mwindow.h +4 -1
  82. data/vendor/libgit2/src/libgit2/notes.c +5 -5
  83. data/vendor/libgit2/src/libgit2/object.c +89 -25
  84. data/vendor/libgit2/src/libgit2/object.h +12 -3
  85. data/vendor/libgit2/src/libgit2/odb.c +194 -50
  86. data/vendor/libgit2/src/libgit2/odb.h +43 -4
  87. data/vendor/libgit2/src/libgit2/odb_loose.c +128 -70
  88. data/vendor/libgit2/src/libgit2/odb_pack.c +96 -44
  89. data/vendor/libgit2/src/libgit2/oid.c +134 -76
  90. data/vendor/libgit2/src/libgit2/oid.h +183 -9
  91. data/vendor/libgit2/src/libgit2/pack-objects.c +15 -4
  92. data/vendor/libgit2/src/libgit2/pack.c +90 -66
  93. data/vendor/libgit2/src/libgit2/pack.h +29 -15
  94. data/vendor/libgit2/src/libgit2/parse.c +4 -3
  95. data/vendor/libgit2/src/libgit2/patch_parse.c +5 -5
  96. data/vendor/libgit2/src/libgit2/push.c +13 -3
  97. data/vendor/libgit2/src/libgit2/reader.c +1 -1
  98. data/vendor/libgit2/src/libgit2/rebase.c +19 -18
  99. data/vendor/libgit2/src/libgit2/refdb_fs.c +70 -39
  100. data/vendor/libgit2/src/libgit2/reflog.c +7 -5
  101. data/vendor/libgit2/src/libgit2/reflog.h +1 -2
  102. data/vendor/libgit2/src/libgit2/refs.c +2 -0
  103. data/vendor/libgit2/src/libgit2/remote.c +38 -37
  104. data/vendor/libgit2/src/libgit2/remote.h +40 -0
  105. data/vendor/libgit2/src/libgit2/repository.c +212 -36
  106. data/vendor/libgit2/src/libgit2/repository.h +9 -0
  107. data/vendor/libgit2/src/libgit2/reset.c +2 -2
  108. data/vendor/libgit2/src/libgit2/revert.c +4 -4
  109. data/vendor/libgit2/src/libgit2/revparse.c +23 -7
  110. data/vendor/libgit2/src/libgit2/revwalk.c +5 -1
  111. data/vendor/libgit2/src/libgit2/stash.c +201 -26
  112. data/vendor/libgit2/src/libgit2/strarray.c +1 -0
  113. data/vendor/libgit2/src/libgit2/strarray.h +25 -0
  114. data/vendor/libgit2/src/libgit2/streams/openssl.c +1 -1
  115. data/vendor/libgit2/src/libgit2/streams/openssl_dynamic.c +7 -3
  116. data/vendor/libgit2/src/libgit2/streams/socket.c +4 -1
  117. data/vendor/libgit2/src/libgit2/submodule.c +6 -2
  118. data/vendor/libgit2/src/libgit2/sysdir.c +294 -7
  119. data/vendor/libgit2/src/libgit2/sysdir.h +39 -9
  120. data/vendor/libgit2/src/libgit2/tag.c +29 -10
  121. data/vendor/libgit2/src/libgit2/tag.h +2 -2
  122. data/vendor/libgit2/src/libgit2/threadstate.h +1 -1
  123. data/vendor/libgit2/src/libgit2/transports/http.c +8 -7
  124. data/vendor/libgit2/src/libgit2/transports/httpclient.c +9 -0
  125. data/vendor/libgit2/src/libgit2/transports/httpclient.h +10 -0
  126. data/vendor/libgit2/src/libgit2/transports/local.c +14 -0
  127. data/vendor/libgit2/src/libgit2/transports/smart.c +35 -0
  128. data/vendor/libgit2/src/libgit2/transports/smart.h +10 -1
  129. data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +153 -41
  130. data/vendor/libgit2/src/libgit2/transports/smart_protocol.c +42 -12
  131. data/vendor/libgit2/src/libgit2/transports/ssh.c +62 -65
  132. data/vendor/libgit2/src/libgit2/transports/winhttp.c +9 -4
  133. data/vendor/libgit2/src/libgit2/tree-cache.c +4 -4
  134. data/vendor/libgit2/src/libgit2/tree.c +22 -16
  135. data/vendor/libgit2/src/libgit2/tree.h +2 -2
  136. data/vendor/libgit2/src/libgit2/worktree.c +5 -0
  137. data/vendor/libgit2/src/util/CMakeLists.txt +7 -1
  138. data/vendor/libgit2/src/util/fs_path.c +1 -1
  139. data/vendor/libgit2/src/util/futils.c +0 -3
  140. data/vendor/libgit2/src/util/git2_util.h +2 -2
  141. data/vendor/libgit2/src/util/hash/openssl.c +4 -3
  142. data/vendor/libgit2/src/util/hash/rfc6234/sha.h +0 -112
  143. data/vendor/libgit2/src/util/hash.h +13 -0
  144. data/vendor/libgit2/src/util/net.c +338 -84
  145. data/vendor/libgit2/src/util/net.h +7 -0
  146. data/vendor/libgit2/src/util/posix.h +2 -0
  147. data/vendor/libgit2/src/util/rand.c +4 -0
  148. data/vendor/libgit2/src/util/regexp.c +3 -3
  149. data/vendor/libgit2/src/util/thread.h +20 -19
  150. data/vendor/libgit2/src/util/util.h +1 -0
  151. metadata +7 -5
  152. data/vendor/libgit2/src/util/win32/findfile.c +0 -286
  153. data/vendor/libgit2/src/util/win32/findfile.h +0 -22
  154. /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 "win32/findfile.h"
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
- return git_win32__find_programdata_dirs(out);
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 git_sysdir_guess_global_dirs(git_str *out)
324
+ static int git_sysdir_guess_home_dirs(git_str *out)
79
325
  {
80
326
  #ifdef GIT_WIN32
81
- return git_win32__find_global_dirs(out);
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
- return git_win32__find_xdg_dirs(out);
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
- * Expand the name of a "global" file (i.e. one in a user's home
61
- * directory). Unlike `find_global_file` (above), this makes no
62
- * attempt to check for the existence of the file, and is useful if
63
- * you want the full path regardless of existence.
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 = 0,
73
- GIT_SYSDIR_GLOBAL = 1,
74
- GIT_SYSDIR_XDG = 2,
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 = 4,
77
- GIT_SYSDIR__MAX = 5
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,10 @@ 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
+ /** Sets the registry system dir to a mock; for testing. */
138
+ extern int git_win32__set_registry_system_dir(const wchar_t *mock_sysdir);
139
+
140
+ /** Find the given system dir; for testing. */
141
+ extern int git_win32__find_system_dirs(git_str *out, const char *subdir);
142
+
113
143
  #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(git_tag *tag, const char *buffer, const char *buffer_end)
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 (git_oid__parse(&tag->target, &buffer, buffer_end, "object ") < 0)
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(void *_tag, const char *data, size_t size)
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(void *_tag, git_odb_object *odb_obj)
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
- git_oid__writebuf(&tag, "object ", git_object_id(target));
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
@@ -13,7 +13,7 @@ typedef struct {
13
13
  git_error *last_error;
14
14
  git_error error_t;
15
15
  git_str error_buf;
16
- char oid_fmt[GIT_OID_HEXSZ+1];
16
+ char oid_fmt[GIT_OID_SHA1_HEXSIZE+1];
17
17
  } git_threadstate;
18
18
 
19
19
  extern int git_threadstate_global_init(void);
@@ -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
- if (!transport->http_client) {
687
- git_http_client_options opts = {0};
688
-
689
- opts.server_certificate_check_cb = connect_opts->callbacks.certificate_check;
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;