rugged 1.5.1 → 1.6.2

Sign up to get free protection for your applications and to get access to all the features.
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;