rugged 0.21.0 → 0.21.1b0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -5
  3. data/ext/rugged/extconf.rb +8 -8
  4. data/ext/rugged/rugged.h +1 -1
  5. data/ext/rugged/rugged_cred.c +23 -0
  6. data/ext/rugged/rugged_index.c +5 -1
  7. data/ext/rugged/rugged_remote.c +68 -0
  8. data/ext/rugged/rugged_repo.c +287 -5
  9. data/ext/rugged/rugged_tag_collection.c +70 -2
  10. data/ext/rugged/rugged_tree.c +29 -10
  11. data/lib/rugged.rb +1 -0
  12. data/lib/rugged/attributes.rb +41 -0
  13. data/lib/rugged/diff.rb +0 -1
  14. data/lib/rugged/diff/line.rb +1 -3
  15. data/lib/rugged/patch.rb +12 -2
  16. data/lib/rugged/version.rb +1 -1
  17. data/vendor/libgit2/CMakeLists.txt +11 -0
  18. data/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake +324 -0
  19. data/vendor/libgit2/deps/http-parser/http_parser.h +2 -0
  20. data/vendor/libgit2/deps/zlib/adler32.c +39 -29
  21. data/vendor/libgit2/deps/zlib/crc32.c +33 -50
  22. data/vendor/libgit2/deps/zlib/crc32.h +1 -1
  23. data/vendor/libgit2/deps/zlib/deflate.c +198 -65
  24. data/vendor/libgit2/deps/zlib/deflate.h +8 -4
  25. data/vendor/libgit2/deps/zlib/infback.c +640 -0
  26. data/vendor/libgit2/deps/zlib/inffast.c +3 -3
  27. data/vendor/libgit2/deps/zlib/inffixed.h +3 -3
  28. data/vendor/libgit2/deps/zlib/inflate.c +84 -52
  29. data/vendor/libgit2/deps/zlib/inftrees.c +15 -39
  30. data/vendor/libgit2/deps/zlib/trees.c +18 -36
  31. data/vendor/libgit2/deps/zlib/zconf.h +4 -0
  32. data/vendor/libgit2/deps/zlib/zlib.h +250 -95
  33. data/vendor/libgit2/deps/zlib/zutil.c +13 -10
  34. data/vendor/libgit2/deps/zlib/zutil.h +41 -62
  35. data/vendor/libgit2/include/git2/attr.h +16 -13
  36. data/vendor/libgit2/include/git2/buffer.h +16 -0
  37. data/vendor/libgit2/include/git2/checkout.h +12 -12
  38. data/vendor/libgit2/include/git2/cherrypick.h +15 -15
  39. data/vendor/libgit2/include/git2/clone.h +77 -69
  40. data/vendor/libgit2/include/git2/diff.h +7 -0
  41. data/vendor/libgit2/include/git2/errors.h +1 -0
  42. data/vendor/libgit2/include/git2/merge.h +16 -0
  43. data/vendor/libgit2/include/git2/oid.h +8 -4
  44. data/vendor/libgit2/include/git2/oidarray.h +40 -0
  45. data/vendor/libgit2/include/git2/remote.h +5 -24
  46. data/vendor/libgit2/include/git2/repository.h +4 -1
  47. data/vendor/libgit2/include/git2/reset.h +4 -0
  48. data/vendor/libgit2/include/git2/status.h +17 -14
  49. data/vendor/libgit2/include/git2/submodule.h +18 -0
  50. data/vendor/libgit2/include/git2/sys/transport.h +354 -0
  51. data/vendor/libgit2/include/git2/transport.h +34 -327
  52. data/vendor/libgit2/include/git2/types.h +16 -6
  53. data/vendor/libgit2/src/array.h +1 -1
  54. data/vendor/libgit2/src/attr_file.c +14 -1
  55. data/vendor/libgit2/src/blame.c +0 -1
  56. data/vendor/libgit2/src/buffer.c +67 -10
  57. data/vendor/libgit2/src/buffer.h +4 -2
  58. data/vendor/libgit2/src/cache.c +9 -9
  59. data/vendor/libgit2/src/cache.h +1 -1
  60. data/vendor/libgit2/src/checkout.c +118 -23
  61. data/vendor/libgit2/src/cherrypick.c +41 -44
  62. data/vendor/libgit2/src/clone.c +94 -56
  63. data/vendor/libgit2/src/config_file.c +4 -4
  64. data/vendor/libgit2/src/diff.c +21 -0
  65. data/vendor/libgit2/src/diff_file.c +1 -0
  66. data/vendor/libgit2/src/diff_print.c +11 -9
  67. data/vendor/libgit2/src/diff_tform.c +3 -1
  68. data/vendor/libgit2/src/errors.c +9 -7
  69. data/vendor/libgit2/src/fileops.c +5 -3
  70. data/vendor/libgit2/src/global.c +9 -1
  71. data/vendor/libgit2/src/global.h +1 -0
  72. data/vendor/libgit2/src/graph.c +2 -2
  73. data/vendor/libgit2/src/indexer.c +6 -1
  74. data/vendor/libgit2/src/merge.c +98 -144
  75. data/vendor/libgit2/src/merge.h +1 -1
  76. data/vendor/libgit2/src/netops.c +4 -0
  77. data/vendor/libgit2/src/oid.c +8 -0
  78. data/vendor/libgit2/src/oid.h +11 -0
  79. data/vendor/libgit2/src/oidarray.c +21 -0
  80. data/vendor/libgit2/src/oidarray.h +18 -0
  81. data/vendor/libgit2/src/pack.c +1 -4
  82. data/vendor/libgit2/src/path.c +93 -33
  83. data/vendor/libgit2/src/path.h +21 -0
  84. data/vendor/libgit2/src/pool.c +1 -1
  85. data/vendor/libgit2/src/posix.h +46 -28
  86. data/vendor/libgit2/src/refs.h +2 -2
  87. data/vendor/libgit2/src/refspec.c +54 -18
  88. data/vendor/libgit2/src/remote.c +31 -8
  89. data/vendor/libgit2/src/remote.h +3 -0
  90. data/vendor/libgit2/src/repository.c +27 -11
  91. data/vendor/libgit2/src/revert.c +4 -6
  92. data/vendor/libgit2/src/revparse.c +15 -18
  93. data/vendor/libgit2/src/revwalk.c +0 -3
  94. data/vendor/libgit2/src/signature.c +2 -2
  95. data/vendor/libgit2/src/stash.c +2 -1
  96. data/vendor/libgit2/src/status.c +11 -2
  97. data/vendor/libgit2/src/strnlen.h +2 -1
  98. data/vendor/libgit2/src/submodule.c +73 -33
  99. data/vendor/libgit2/src/thread-utils.h +0 -7
  100. data/vendor/libgit2/src/trace.h +9 -1
  101. data/vendor/libgit2/src/transport.c +93 -90
  102. data/vendor/libgit2/src/transports/auth.c +71 -0
  103. data/vendor/libgit2/src/transports/auth.h +63 -0
  104. data/vendor/libgit2/src/transports/auth_negotiate.c +275 -0
  105. data/vendor/libgit2/src/transports/auth_negotiate.h +27 -0
  106. data/vendor/libgit2/src/transports/cred.c +58 -0
  107. data/vendor/libgit2/src/transports/cred.h +14 -0
  108. data/vendor/libgit2/src/transports/cred_helpers.c +3 -0
  109. data/vendor/libgit2/src/transports/git.c +1 -0
  110. data/vendor/libgit2/src/transports/http.c +168 -76
  111. data/vendor/libgit2/src/transports/smart.h +1 -0
  112. data/vendor/libgit2/src/transports/smart_protocol.c +4 -2
  113. data/vendor/libgit2/src/transports/ssh.c +214 -38
  114. data/vendor/libgit2/src/transports/winhttp.c +26 -6
  115. data/vendor/libgit2/src/unix/posix.h +23 -9
  116. data/vendor/libgit2/src/unix/realpath.c +8 -7
  117. data/vendor/libgit2/src/util.c +2 -1
  118. data/vendor/libgit2/src/util.h +3 -3
  119. data/vendor/libgit2/src/win32/mingw-compat.h +5 -12
  120. data/vendor/libgit2/src/win32/msvc-compat.h +3 -32
  121. data/vendor/libgit2/src/win32/posix.h +20 -31
  122. data/vendor/libgit2/src/win32/posix_w32.c +33 -4
  123. metadata +81 -69
@@ -62,6 +62,9 @@ static unsigned int workdir_delta2status(
62
62
  case GIT_DELTA_UNTRACKED:
63
63
  st = GIT_STATUS_WT_NEW;
64
64
  break;
65
+ case GIT_DELTA_UNREADABLE:
66
+ st = GIT_STATUS_WT_UNREADABLE;
67
+ break;
65
68
  case GIT_DELTA_DELETED:
66
69
  st = GIT_STATUS_WT_DELETED;
67
70
  break;
@@ -310,6 +313,10 @@ int git_status_list_new(
310
313
  diffopt.flags = diffopt.flags | GIT_DIFF_IGNORE_SUBMODULES;
311
314
  if ((flags & GIT_STATUS_OPT_UPDATE_INDEX) != 0)
312
315
  diffopt.flags = diffopt.flags | GIT_DIFF_UPDATE_INDEX;
316
+ if ((flags & GIT_STATUS_OPT_INCLUDE_UNREADABLE) != 0)
317
+ diffopt.flags = diffopt.flags | GIT_DIFF_INCLUDE_UNREADABLE;
318
+ if ((flags & GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED) != 0)
319
+ diffopt.flags = diffopt.flags | GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED;
313
320
 
314
321
  if ((flags & GIT_STATUS_OPT_RENAMES_FROM_REWRITES) != 0)
315
322
  findopt.flags = findopt.flags |
@@ -329,8 +336,9 @@ int git_status_list_new(
329
336
 
330
337
  if (show != GIT_STATUS_SHOW_INDEX_ONLY) {
331
338
  if ((error = git_diff_index_to_workdir(
332
- &status->idx2wd, repo, index, &diffopt)) < 0)
339
+ &status->idx2wd, repo, index, &diffopt)) < 0) {
333
340
  goto done;
341
+ }
334
342
 
335
343
  if ((flags & GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR) != 0 &&
336
344
  (error = git_diff_find_similar(status->idx2wd, &findopt)) < 0)
@@ -407,8 +415,9 @@ int git_status_foreach_ext(
407
415
  size_t i;
408
416
  int error = 0;
409
417
 
410
- if ((error = git_status_list_new(&status, repo, opts)) < 0)
418
+ if ((error = git_status_list_new(&status, repo, opts)) < 0) {
411
419
  return error;
420
+ }
412
421
 
413
422
  git_vector_foreach(&status->paired, i, status_entry) {
414
423
  const char *path = status_entry->head_to_index ?
@@ -7,7 +7,8 @@
7
7
  #ifndef INCLUDE_strlen_h__
8
8
  #define INCLUDE_strlen_h__
9
9
 
10
- #if defined(__MINGW32__) || defined(__sun) || defined(__APPLE__) || defined(__MidnightBSD__)
10
+ #if defined(__MINGW32__) || defined(__sun) || defined(__APPLE__) || defined(__MidnightBSD__) ||\
11
+ (defined(_MSC_VER) && _MSC_VER < 1500)
11
12
  # define NO_STRNLEN
12
13
  #endif
13
14
 
@@ -306,6 +306,56 @@ void git_submodule_cache_free(git_repository *repo)
306
306
  submodule_cache_free(cache);
307
307
  }
308
308
 
309
+ static int submodule_repo_init(
310
+ git_repository **out,
311
+ git_repository *parent_repo,
312
+ const char *path,
313
+ const char *url,
314
+ bool use_gitlink)
315
+ {
316
+ int error = 0;
317
+ git_buf workdir = GIT_BUF_INIT, repodir = GIT_BUF_INIT;
318
+ git_repository_init_options initopt = GIT_REPOSITORY_INIT_OPTIONS_INIT;
319
+ git_repository *subrepo = NULL;
320
+
321
+ error = git_buf_joinpath(&workdir, git_repository_workdir(parent_repo), path);
322
+ if (error < 0)
323
+ goto cleanup;
324
+
325
+ initopt.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_NO_REINIT;
326
+ initopt.origin_url = url;
327
+
328
+ /* init submodule repository and add origin remote as needed */
329
+
330
+ /* New style: sub-repo goes in <repo-dir>/modules/<name>/ with a
331
+ * gitlink in the sub-repo workdir directory to that repository
332
+ *
333
+ * Old style: sub-repo goes directly into repo/<name>/.git/
334
+ */
335
+ if (use_gitlink) {
336
+ error = git_buf_join3(
337
+ &repodir, '/', git_repository_path(parent_repo), "modules", path);
338
+ if (error < 0)
339
+ goto cleanup;
340
+
341
+ initopt.workdir_path = workdir.ptr;
342
+ initopt.flags |=
343
+ GIT_REPOSITORY_INIT_NO_DOTGIT_DIR |
344
+ GIT_REPOSITORY_INIT_RELATIVE_GITLINK;
345
+
346
+ error = git_repository_init_ext(&subrepo, repodir.ptr, &initopt);
347
+ } else
348
+ error = git_repository_init_ext(&subrepo, workdir.ptr, &initopt);
349
+
350
+ cleanup:
351
+ git_buf_free(&workdir);
352
+ git_buf_free(&repodir);
353
+
354
+ *out = subrepo;
355
+
356
+ return error;
357
+ }
358
+
309
359
  int git_submodule_add_setup(
310
360
  git_submodule **out,
311
361
  git_repository *repo,
@@ -317,7 +367,6 @@ int git_submodule_add_setup(
317
367
  git_config_backend *mods = NULL;
318
368
  git_submodule *sm = NULL;
319
369
  git_buf name = GIT_BUF_INIT, real_url = GIT_BUF_INIT;
320
- git_repository_init_options initopt = GIT_REPOSITORY_INIT_OPTIONS_INIT;
321
370
  git_repository *subrepo = NULL;
322
371
 
323
372
  assert(repo && url && path);
@@ -371,41 +420,14 @@ int git_submodule_add_setup(
371
420
  if (error < 0)
372
421
  goto cleanup;
373
422
 
374
- /* New style: sub-repo goes in <repo-dir>/modules/<name>/ with a
375
- * gitlink in the sub-repo workdir directory to that repository
376
- *
377
- * Old style: sub-repo goes directly into repo/<name>/.git/
423
+ /* if the repo does not already exist, then init a new repo and add it.
424
+ * Otherwise, just add the existing repo.
378
425
  */
379
-
380
- initopt.flags = GIT_REPOSITORY_INIT_MKPATH |
381
- GIT_REPOSITORY_INIT_NO_REINIT;
382
- initopt.origin_url = real_url.ptr;
383
-
384
- if (git_path_exists(name.ptr) &&
385
- git_path_contains(&name, DOT_GIT))
386
- {
387
- /* repo appears to already exist - reinit? */
388
- }
389
- else if (use_gitlink) {
390
- git_buf repodir = GIT_BUF_INIT;
391
-
392
- error = git_buf_join3(
393
- &repodir, '/', git_repository_path(repo), "modules", path);
394
- if (error < 0)
426
+ if (!(git_path_exists(name.ptr) &&
427
+ git_path_contains(&name, DOT_GIT))) {
428
+ if ((error = submodule_repo_init(&subrepo, repo, path, real_url.ptr, use_gitlink)) < 0)
395
429
  goto cleanup;
396
-
397
- initopt.workdir_path = name.ptr;
398
- initopt.flags |= GIT_REPOSITORY_INIT_NO_DOTGIT_DIR;
399
-
400
- error = git_repository_init_ext(&subrepo, repodir.ptr, &initopt);
401
-
402
- git_buf_free(&repodir);
403
430
  }
404
- else {
405
- error = git_repository_init_ext(&subrepo, name.ptr, &initopt);
406
- }
407
- if (error < 0)
408
- goto cleanup;
409
431
 
410
432
  /* add submodule to hash and "reload" it */
411
433
 
@@ -437,6 +459,23 @@ cleanup:
437
459
  return error;
438
460
  }
439
461
 
462
+ int git_submodule_repo_init(
463
+ git_repository **out,
464
+ const git_submodule *sm,
465
+ int use_gitlink)
466
+ {
467
+ int error;
468
+ git_repository *sub_repo = NULL;
469
+
470
+ assert(out && sm);
471
+
472
+ error = submodule_repo_init(&sub_repo, sm->repo, sm->path, sm->url, use_gitlink);
473
+
474
+ *out = sub_repo;
475
+
476
+ return error;
477
+ }
478
+
440
479
  int git_submodule_add_finalize(git_submodule *sm)
441
480
  {
442
481
  int error;
@@ -1897,6 +1936,7 @@ static void submodule_get_index_status(unsigned int *status, git_submodule *sm)
1897
1936
  *status |= GIT_SUBMODULE_STATUS_INDEX_MODIFIED;
1898
1937
  }
1899
1938
 
1939
+
1900
1940
  static void submodule_get_wd_status(
1901
1941
  unsigned int *status,
1902
1942
  git_submodule *sm,
@@ -53,12 +53,6 @@ typedef struct {
53
53
 
54
54
  #endif
55
55
 
56
- #if defined(GIT_WIN32)
57
- #define git_thread_yield() Sleep(0)
58
- #else
59
- #define git_thread_yield() sched_yield()
60
- #endif
61
-
62
56
  /* Pthreads Mutex */
63
57
  #define git_mutex pthread_mutex_t
64
58
  #define git_mutex_init(a) pthread_mutex_init(a, NULL)
@@ -186,7 +180,6 @@ GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend)
186
180
  #define git_thread unsigned int
187
181
  #define git_thread_create(thread, attr, start_routine, arg) 0
188
182
  #define git_thread_join(id, status) (void)0
189
- #define git_thread_yield() (void)0
190
183
 
191
184
  /* Pthreads Mutex */
192
185
  #define git_mutex unsigned int
@@ -46,8 +46,16 @@ GIT_INLINE(void) git_trace__write_fmt(
46
46
 
47
47
  #else
48
48
 
49
+ GIT_INLINE(void) git_trace__null(
50
+ git_trace_level_t level,
51
+ const char *fmt, ...)
52
+ {
53
+ GIT_UNUSED(level);
54
+ GIT_UNUSED(fmt);
55
+ }
56
+
49
57
  #define git_trace_level() ((void)0)
50
- #define git_trace(lvl, ...) ((void)0)
58
+ #define git_trace git_trace__null
51
59
 
52
60
  #endif
53
61
 
@@ -9,11 +9,11 @@
9
9
  #include "git2/remote.h"
10
10
  #include "git2/net.h"
11
11
  #include "git2/transport.h"
12
+ #include "git2/sys/transport.h"
12
13
  #include "path.h"
13
14
 
14
15
  typedef struct transport_definition {
15
16
  char *prefix;
16
- unsigned priority;
17
17
  git_transport_cb fn;
18
18
  void *param;
19
19
  } transport_definition;
@@ -24,52 +24,55 @@ static git_smart_subtransport_definition git_subtransport_definition = { git_sma
24
24
  static git_smart_subtransport_definition ssh_subtransport_definition = { git_smart_subtransport_ssh, 0 };
25
25
  #endif
26
26
 
27
- static transport_definition local_transport_definition = { "file://", 1, git_transport_local, NULL };
28
- #ifdef GIT_SSH
29
- static transport_definition ssh_transport_definition = { "ssh://", 1, git_transport_smart, &ssh_subtransport_definition };
30
- #else
31
- static transport_definition dummy_transport_definition = { NULL, 1, git_transport_dummy, NULL };
32
- #endif
27
+ static transport_definition local_transport_definition = { "file://", git_transport_local, NULL };
33
28
 
34
29
  static transport_definition transports[] = {
35
- {"git://", 1, git_transport_smart, &git_subtransport_definition},
36
- {"http://", 1, git_transport_smart, &http_subtransport_definition},
37
- {"https://", 1, git_transport_smart, &http_subtransport_definition},
38
- {"file://", 1, git_transport_local, NULL},
30
+ { "git://", git_transport_smart, &git_subtransport_definition },
31
+ { "http://", git_transport_smart, &http_subtransport_definition },
32
+ #if defined(GIT_SSL) || defined(GIT_WINHTTP)
33
+ { "https://", git_transport_smart, &http_subtransport_definition },
34
+ #endif
35
+ { "file://", git_transport_local, NULL },
39
36
  #ifdef GIT_SSH
40
- {"ssh://", 1, git_transport_smart, &ssh_subtransport_definition},
37
+ { "ssh://", git_transport_smart, &ssh_subtransport_definition },
41
38
  #endif
42
- {NULL, 0, 0}
39
+ { NULL, 0, 0 }
43
40
  };
44
41
 
45
- static git_vector additional_transports = GIT_VECTOR_INIT;
42
+ static git_vector custom_transports = GIT_VECTOR_INIT;
46
43
 
47
44
  #define GIT_TRANSPORT_COUNT (sizeof(transports)/sizeof(transports[0])) - 1
48
45
 
49
- static int transport_find_fn(const char *url, git_transport_cb *callback, void **param)
46
+ static transport_definition * transport_find_by_url(const char *url)
50
47
  {
51
48
  size_t i = 0;
52
- unsigned priority = 0;
53
- transport_definition *definition = NULL, *definition_iter;
49
+ transport_definition *d;
54
50
 
55
- // First, check to see if it's an obvious URL, which a URL scheme
56
- for (i = 0; i < GIT_TRANSPORT_COUNT; ++i) {
57
- definition_iter = &transports[i];
51
+ /* Find a user transport who wants to deal with this URI */
52
+ git_vector_foreach(&custom_transports, i, d) {
53
+ if (strncasecmp(url, d->prefix, strlen(d->prefix)) == 0) {
54
+ return d;
55
+ }
56
+ }
58
57
 
59
- if (strncasecmp(url, definition_iter->prefix, strlen(definition_iter->prefix)))
60
- continue;
58
+ /* Find a system transport for this URI */
59
+ for (i = 0; i < GIT_TRANSPORT_COUNT; ++i) {
60
+ d = &transports[i];
61
61
 
62
- if (definition_iter->priority > priority)
63
- definition = definition_iter;
62
+ if (strncasecmp(url, d->prefix, strlen(d->prefix)) == 0) {
63
+ return d;
64
+ }
64
65
  }
65
66
 
66
- git_vector_foreach(&additional_transports, i, definition_iter) {
67
- if (strncasecmp(url, definition_iter->prefix, strlen(definition_iter->prefix)))
68
- continue;
67
+ return NULL;
68
+ }
69
69
 
70
- if (definition_iter->priority > priority)
71
- definition = definition_iter;
72
- }
70
+ static int transport_find_fn(
71
+ git_transport_cb *out,
72
+ const char *url,
73
+ void **param)
74
+ {
75
+ transport_definition *definition = transport_find_by_url(url);
73
76
 
74
77
  #ifdef GIT_WIN32
75
78
  /* On Windows, it might not be possible to discern between absolute local
@@ -86,12 +89,10 @@ static int transport_find_fn(const char *url, git_transport_cb *callback, void *
86
89
 
87
90
  /* It could be a SSH remote path. Check to see if there's a :
88
91
  * SSH is an unsupported transport mechanism in this version of libgit2 */
89
- if (!definition && strrchr(url, ':'))
90
- #ifdef GIT_SSH
91
- definition = &ssh_transport_definition;
92
- #else
93
- definition = &dummy_transport_definition;
94
- #endif
92
+ if (!definition && strrchr(url, ':')) {
93
+ // re-search transports again with ssh:// as url so that we can find a third party ssh transport
94
+ definition = transport_find_by_url("ssh://");
95
+ }
95
96
 
96
97
  #ifndef GIT_WIN32
97
98
  /* Check to see if the path points to a file on the local file system */
@@ -100,9 +101,9 @@ static int transport_find_fn(const char *url, git_transport_cb *callback, void *
100
101
  #endif
101
102
 
102
103
  if (!definition)
103
- return -1;
104
+ return GIT_ENOTFOUND;
104
105
 
105
- *callback = definition->fn;
106
+ *out = definition->fn;
106
107
  *param = definition->param;
107
108
 
108
109
  return 0;
@@ -112,15 +113,6 @@ static int transport_find_fn(const char *url, git_transport_cb *callback, void *
112
113
  * Public API *
113
114
  **************/
114
115
 
115
- int git_transport_dummy(git_transport **transport, git_remote *owner, void *param)
116
- {
117
- GIT_UNUSED(transport);
118
- GIT_UNUSED(owner);
119
- GIT_UNUSED(param);
120
- giterr_set(GITERR_NET, "This transport isn't implemented. Sorry");
121
- return -1;
122
- }
123
-
124
116
  int git_transport_new(git_transport **out, git_remote *owner, const char *url)
125
117
  {
126
118
  git_transport_cb fn;
@@ -128,83 +120,96 @@ int git_transport_new(git_transport **out, git_remote *owner, const char *url)
128
120
  void *param;
129
121
  int error;
130
122
 
131
- if (transport_find_fn(url, &fn, &param) < 0) {
123
+ if ((error = transport_find_fn(&fn, url, &param)) == GIT_ENOTFOUND) {
132
124
  giterr_set(GITERR_NET, "Unsupported URL protocol");
133
125
  return -1;
134
- }
126
+ } else if (error < 0)
127
+ return error;
135
128
 
136
- error = fn(&transport, owner, param);
137
- if (error < 0)
129
+ if ((error = fn(&transport, owner, param)) < 0)
138
130
  return error;
139
131
 
132
+ GITERR_CHECK_VERSION(transport, GIT_TRANSPORT_VERSION, "git_transport");
133
+
140
134
  *out = transport;
141
135
 
142
136
  return 0;
143
137
  }
144
138
 
145
139
  int git_transport_register(
146
- const char *prefix,
147
- unsigned priority,
140
+ const char *scheme,
148
141
  git_transport_cb cb,
149
142
  void *param)
150
143
  {
151
- transport_definition *d;
144
+ git_buf prefix = GIT_BUF_INIT;
145
+ transport_definition *d, *definition = NULL;
146
+ size_t i;
147
+ int error = 0;
152
148
 
153
- d = git__calloc(sizeof(transport_definition), 1);
154
- GITERR_CHECK_ALLOC(d);
149
+ assert(scheme);
150
+ assert(cb);
155
151
 
156
- d->prefix = git__strdup(prefix);
157
-
158
- if (!d->prefix)
152
+ if ((error = git_buf_printf(&prefix, "%s://", scheme)) < 0)
159
153
  goto on_error;
160
154
 
161
- d->priority = priority;
162
- d->fn = cb;
163
- d->param = param;
155
+ git_vector_foreach(&custom_transports, i, d) {
156
+ if (strcasecmp(d->prefix, prefix.ptr) == 0) {
157
+ error = GIT_EEXISTS;
158
+ goto on_error;
159
+ }
160
+ }
161
+
162
+ definition = git__calloc(1, sizeof(transport_definition));
163
+ GITERR_CHECK_ALLOC(definition);
164
164
 
165
- if (git_vector_insert(&additional_transports, d) < 0)
165
+ definition->prefix = git_buf_detach(&prefix);
166
+ definition->fn = cb;
167
+ definition->param = param;
168
+
169
+ if (git_vector_insert(&custom_transports, definition) < 0)
166
170
  goto on_error;
167
171
 
168
172
  return 0;
169
173
 
170
174
  on_error:
171
- git__free(d->prefix);
172
- git__free(d);
173
- return -1;
175
+ git_buf_free(&prefix);
176
+ git__free(definition);
177
+ return error;
174
178
  }
175
179
 
176
- int git_transport_unregister(
177
- const char *prefix,
178
- unsigned priority)
180
+ int git_transport_unregister(const char *scheme)
179
181
  {
182
+ git_buf prefix = GIT_BUF_INIT;
180
183
  transport_definition *d;
181
- unsigned i;
184
+ size_t i;
185
+ int error = 0;
186
+
187
+ assert(scheme);
188
+
189
+ if ((error = git_buf_printf(&prefix, "%s://", scheme)) < 0)
190
+ goto done;
182
191
 
183
- git_vector_foreach(&additional_transports, i, d) {
184
- if (d->priority == priority && !strcasecmp(d->prefix, prefix)) {
185
- if (git_vector_remove(&additional_transports, i) < 0)
186
- return -1;
192
+ git_vector_foreach(&custom_transports, i, d) {
193
+ if (strcasecmp(d->prefix, prefix.ptr) == 0) {
194
+ if ((error = git_vector_remove(&custom_transports, i)) < 0)
195
+ goto done;
187
196
 
188
197
  git__free(d->prefix);
189
198
  git__free(d);
190
199
 
191
- if (!additional_transports.length)
192
- git_vector_free(&additional_transports);
200
+ if (!custom_transports.length)
201
+ git_vector_free(&custom_transports);
193
202
 
194
- return 0;
203
+ error = 0;
204
+ goto done;
195
205
  }
196
206
  }
197
207
 
198
- return GIT_ENOTFOUND;
199
- }
208
+ error = GIT_ENOTFOUND;
200
209
 
201
- /* from remote.h */
202
- int git_remote_valid_url(const char *url)
203
- {
204
- git_transport_cb fn;
205
- void *param;
206
-
207
- return !transport_find_fn(url, &fn, &param);
210
+ done:
211
+ git_buf_free(&prefix);
212
+ return error;
208
213
  }
209
214
 
210
215
  int git_remote_supported_url(const char* url)
@@ -212,10 +217,8 @@ int git_remote_supported_url(const char* url)
212
217
  git_transport_cb fn;
213
218
  void *param;
214
219
 
215
- if (transport_find_fn(url, &fn, &param) < 0)
216
- return 0;
217
-
218
- return fn != &git_transport_dummy;
220
+ /* The only error we expect is ENOTFOUND */
221
+ return !transport_find_fn(&fn, url, &param);
219
222
  }
220
223
 
221
224
  int git_transport_init(git_transport *opts, unsigned int version)