rugged 0.22.0b5 → 0.22.1b1

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +19 -3
  3. data/ext/rugged/extconf.rb +21 -5
  4. data/ext/rugged/rugged.c +1 -0
  5. data/ext/rugged/rugged.h +8 -0
  6. data/ext/rugged/rugged_backend.c +34 -0
  7. data/ext/rugged/rugged_branch_collection.c +1 -0
  8. data/ext/rugged/rugged_remote.c +37 -86
  9. data/ext/rugged/rugged_remote_collection.c +2 -1
  10. data/ext/rugged/rugged_repo.c +149 -24
  11. data/ext/rugged/rugged_revwalk.c +1 -2
  12. data/ext/rugged/rugged_submodule.c +1 -1
  13. data/ext/rugged/rugged_tree.c +69 -5
  14. data/lib/rugged/version.rb +1 -1
  15. data/vendor/libgit2/CMakeLists.txt +2 -1
  16. data/vendor/libgit2/include/git2.h +0 -1
  17. data/vendor/libgit2/include/git2/checkout.h +8 -0
  18. data/vendor/libgit2/include/git2/merge.h +8 -0
  19. data/vendor/libgit2/include/git2/push.h +0 -110
  20. data/vendor/libgit2/include/git2/remote.h +30 -1
  21. data/vendor/libgit2/include/git2/revert.h +1 -1
  22. data/vendor/libgit2/include/git2/submodule.h +80 -1
  23. data/vendor/libgit2/include/git2/sys/index.h +2 -2
  24. data/vendor/libgit2/include/git2/{threads.h → sys/openssl.h} +10 -12
  25. data/vendor/libgit2/include/git2/sys/refs.h +11 -0
  26. data/vendor/libgit2/include/git2/tree.h +1 -1
  27. data/vendor/libgit2/include/git2/version.h +3 -3
  28. data/vendor/libgit2/src/attr_file.c +3 -1
  29. data/vendor/libgit2/src/buffer.c +2 -1
  30. data/vendor/libgit2/src/checkout.c +135 -39
  31. data/vendor/libgit2/src/checkout.h +7 -0
  32. data/vendor/libgit2/src/config_file.c +5 -7
  33. data/vendor/libgit2/src/crlf.c +2 -0
  34. data/vendor/libgit2/src/describe.c +6 -2
  35. data/vendor/libgit2/src/diff.c +1 -0
  36. data/vendor/libgit2/src/fileops.c +87 -19
  37. data/vendor/libgit2/src/fileops.h +18 -0
  38. data/vendor/libgit2/src/global.c +1 -1
  39. data/vendor/libgit2/src/ident.c +2 -0
  40. data/vendor/libgit2/src/index.c +4 -4
  41. data/vendor/libgit2/src/merge.c +3 -1
  42. data/vendor/libgit2/src/notes.c +1 -1
  43. data/vendor/libgit2/src/pack.c +1 -0
  44. data/vendor/libgit2/src/path.c +17 -12
  45. data/vendor/libgit2/src/path.h +17 -3
  46. data/vendor/libgit2/src/push.h +110 -0
  47. data/vendor/libgit2/src/rebase.c +4 -2
  48. data/vendor/libgit2/src/remote.c +237 -16
  49. data/vendor/libgit2/src/remote.h +2 -0
  50. data/vendor/libgit2/src/repository.c +7 -3
  51. data/vendor/libgit2/src/submodule.c +229 -18
  52. data/vendor/libgit2/src/transports/local.c +61 -2
  53. data/vendor/libgit2/src/transports/smart_protocol.c +5 -3
  54. data/vendor/libgit2/src/tree.c +2 -2
  55. data/vendor/libgit2/src/util.h +13 -2
  56. data/vendor/libgit2/src/win32/mingw-compat.h +2 -0
  57. data/vendor/libgit2/src/win32/path_w32.h +2 -0
  58. metadata +4 -4
  59. data/vendor/libgit2/cmake/Modules/FindLIBSSH2.cmake +0 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 096ce237a96fe39032ff6e26839007148fb90ea8
4
- data.tar.gz: 4a8b6154d4ef9c9be73f6c473d8edcd7eede1747
3
+ metadata.gz: a920e7f6ad886a0730f1b80b91990956469eb3c8
4
+ data.tar.gz: bc69152690eeea81ab3f2e0749a967de27b3107c
5
5
  SHA512:
6
- metadata.gz: 340fe46665f934cb4925d9ac63153107e322f06335753c753f09314515658ae8fd50d127084afc22904d9ee6730e9f933b27a9e8043fc8fc7df484ac722cc553
7
- data.tar.gz: ce7e75586a31232cda3b5a61c7742ba9a1d5f82b6f9fad14d6da8d346f73e44505195ee8a5d50a444ec04218f25701665133fe0a31b67ec378e5ca877dc2cdbe
6
+ metadata.gz: f26e34ae5df319b467d5348039255f0d4e1c8d885b6d11ec65511664b1e2a1d468369305dd383ab8084bc8566f12ab95caa2cade4698f9742d0d69ffff338323
7
+ data.tar.gz: e38f35f6abf4d6f08797c966c7e3a40508b771ed3f29c72e1dac56f4787c981ff9848a25142ff057924a2a53d139f22f33fa84f0b0e4a546951697e0c6917330
data/README.md CHANGED
@@ -27,7 +27,7 @@ If you want to build Rugged with HTTPS and SSH support, check out the list of op
27
27
  If you're using bundler and want to bundle `libgit2` with Rugged, you can use the `:submodules` option:
28
28
 
29
29
  ```ruby
30
- gem 'rugged', git: 'git://github.com/libgit2/rugged.git', branch: 'development', submodules: true
30
+ gem 'rugged', git: 'git://github.com/libgit2/rugged.git', submodules: true
31
31
  ```
32
32
 
33
33
  To load Rugged, you'll usually want to add something like this:
@@ -267,11 +267,11 @@ You can also write trees with the `TreeBuilder`:
267
267
 
268
268
  ```ruby
269
269
  oid = repo.write("This is a blob.", :blob)
270
- builder = Rugged::Tree::Builder.new
270
+ builder = Rugged::Tree::Builder.new(repo)
271
271
  builder << { :type => :blob, :name => "README.md", :oid => oid, :filemode => 0100644 }
272
272
 
273
273
  options = {}
274
- options[:tree] = builder.write(repo)
274
+ options[:tree] = builder.write
275
275
 
276
276
  options[:author] = { :email => "testuser@github.com", :name => 'Test Author', :time => Time.now }
277
277
  options[:committer] = { :email => "testuser@github.com", :name => 'Test Author', :time => Time.now }
@@ -569,6 +569,22 @@ Rugged.raw_to_hex("\277\336Y\315\320\337\254\035\211(\024\366j\225d\032\275\212\
569
569
 
570
570
  ---
571
571
 
572
+ ### Alternative backends
573
+
574
+ You can store bare repositories in alternative backends instead of storing on disk. (see
575
+ `redbadger/rugged-redis` for an example of how a rugged backend works).
576
+
577
+ ```ruby
578
+ a_backend = Rugged::InMemory::Backend.new(opt1: 'setting', opt2: 'setting')
579
+
580
+ repo = Rugged::Repository.init_at('repo_name', :bare, backend: a_backend)
581
+
582
+ # or
583
+
584
+ repo = Rugged::Repository.bare('repo_name', backend: a_backend)
585
+ ```
586
+ ---
587
+
572
588
  ## Contributing
573
589
 
574
590
  Fork libgit2/rugged on GitHub, make it awesomer (preferably in a branch named
@@ -19,15 +19,34 @@ if !(MAKE = find_executable('gmake') || find_executable('make'))
19
19
  abort "ERROR: GNU make is required to build Rugged."
20
20
  end
21
21
 
22
+ CWD = File.expand_path(File.dirname(__FILE__))
23
+ LIBGIT2_DIR = File.join(CWD, '..', '..', 'vendor', 'libgit2')
24
+
22
25
  if arg_config("--use-system-libraries", !!ENV['RUGGED_USE_SYSTEM_LIBRARIES'])
23
26
  puts "Building Rugged using system libraries.\n"
24
27
 
25
28
  dir_config('git2').any? or pkg_config('libgit2')
26
29
 
27
- try_compile(<<-SRC) or abort "libgit2 version is not compatible"
30
+ major = minor = nil
31
+
32
+ File.readlines(File.join(LIBGIT2_DIR, "include", "git2", "version.h")).each do |line|
33
+ if !major && (matches = line.match(/^#define LIBGIT2_VER_MAJOR ([0-9]+)$/))
34
+ major = matches[1]
35
+ next
36
+ end
37
+
38
+ if !minor && (matches = line.match(/^#define LIBGIT2_VER_MINOR ([0-9]+)$/))
39
+ minor = matches[1]
40
+ next
41
+ end
42
+
43
+ break if major && minor
44
+ end
45
+
46
+ try_compile(<<-SRC) or abort "libgit2 version is not compatible, expected ~> #{major}.#{minor}.0"
28
47
  #include <git2/version.h>
29
48
 
30
- #if LIBGIT2_SOVERSION != 21
49
+ #if LIBGIT2_VER_MAJOR != #{major} || LIBGIT2_VER_MINOR != #{minor}
31
50
  #error libgit2 version is not compatible
32
51
  #endif
33
52
  SRC
@@ -40,9 +59,6 @@ else
40
59
  abort "ERROR: pkg-config is required to build Rugged."
41
60
  end
42
61
 
43
- CWD = File.expand_path(File.dirname(__FILE__))
44
- LIBGIT2_DIR = File.join(CWD, '..', '..', 'vendor', 'libgit2')
45
-
46
62
  Dir.chdir(LIBGIT2_DIR) do
47
63
  Dir.mkdir("build") if !Dir.exists?("build")
48
64
 
@@ -456,6 +456,7 @@ void Init_rugged(void)
456
456
  Init_rugged_diff_line();
457
457
  Init_rugged_blame();
458
458
  Init_rugged_cred();
459
+ Init_rugged_backend();
459
460
 
460
461
  /*
461
462
  * Sort the repository contents in no particular ordering;
@@ -74,6 +74,7 @@ void Init_rugged_diff_hunk(void);
74
74
  void Init_rugged_diff_line(void);
75
75
  void Init_rugged_blame(void);
76
76
  void Init_rugged_cred(void);
77
+ void Init_rugged_backend(void);
77
78
 
78
79
  VALUE rb_git_object_init(git_otype type, int argc, VALUE *argv, VALUE self);
79
80
 
@@ -153,6 +154,7 @@ struct rugged_remote_cb_payload
153
154
  VALUE transfer_progress;
154
155
  VALUE update_tips;
155
156
  VALUE credentials;
157
+ VALUE result;
156
158
  int exception;
157
159
  };
158
160
 
@@ -174,4 +176,10 @@ static inline VALUE rugged_create_oid(const git_oid *oid)
174
176
  return rb_str_new(out, 40);
175
177
  }
176
178
 
179
+
180
+ typedef struct _rugged_backend {
181
+ int (* odb_backend)(git_odb_backend **backend_out, struct _rugged_backend *backend, const char* path);
182
+ int (* refdb_backend)(git_refdb_backend **backend_out, struct _rugged_backend *backend, const char* path);
183
+ } rugged_backend;
184
+
177
185
  #endif
@@ -0,0 +1,34 @@
1
+ /*
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2014 GitHub, Inc
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ * THE SOFTWARE.
23
+ */
24
+
25
+ #include "rugged.h"
26
+
27
+ extern VALUE rb_mRugged;
28
+
29
+ VALUE rb_cRuggedBackend;
30
+
31
+ void Init_rugged_backend(void)
32
+ {
33
+ rb_cRuggedBackend = rb_define_class_under(rb_mRugged, "Backend", rb_cObject);
34
+ }
@@ -235,6 +235,7 @@ static VALUE each_branch(int argc, VALUE *argv, VALUE self, int branch_names_onl
235
235
  Data_Get_Struct(rb_repo, git_repository, repo);
236
236
 
237
237
  error = git_branch_iterator_new(&iter, repo, filter);
238
+ rugged_exception_check(error);
238
239
 
239
240
  if (branch_names_only) {
240
241
  git_reference *branch;
@@ -29,7 +29,7 @@ extern VALUE rb_cRuggedRepo;
29
29
  extern VALUE rb_eRuggedError;
30
30
  VALUE rb_cRuggedRemote;
31
31
 
32
- #define RUGGED_REMOTE_CALLBACKS_INIT {1, progress_cb, NULL, credentials_cb, NULL, transfer_progress_cb, update_tips_cb, NULL}
32
+ #define RUGGED_REMOTE_CALLBACKS_INIT {1, progress_cb, NULL, credentials_cb, NULL, transfer_progress_cb, update_tips_cb, NULL, NULL, push_update_reference_cb, NULL}
33
33
 
34
34
  static int progress_cb(const char *str, int len, void *data)
35
35
  {
@@ -69,6 +69,15 @@ static int transfer_progress_cb(const git_transfer_progress *stats, void *data)
69
69
  return payload->exception ? GIT_ERROR : GIT_OK;
70
70
  }
71
71
 
72
+ static int push_update_reference_cb(const char *refname, const char *status, void *data) {
73
+ struct rugged_remote_cb_payload *payload = data;
74
+
75
+ if (status != NULL)
76
+ rb_hash_aset(payload->result, rb_str_new_utf8(refname), rb_str_new_utf8(status));
77
+
78
+ return GIT_OK;
79
+ }
80
+
72
81
  static int update_tips_cb(const char *refname, const git_oid *src, const git_oid *dest, void *data)
73
82
  {
74
83
  struct rugged_remote_cb_payload *payload = data;
@@ -164,10 +173,12 @@ void rugged_remote_init_callbacks_and_payload_from_options(
164
173
  prefilled.payload = payload;
165
174
  memcpy(callbacks, &prefilled, sizeof(git_remote_callbacks));
166
175
 
167
- CALLABLE_OR_RAISE(payload->update_tips, rb_options, "update_tips");
168
- CALLABLE_OR_RAISE(payload->progress, rb_options, "progress");
169
- CALLABLE_OR_RAISE(payload->transfer_progress, rb_options, "transfer_progress");
170
- CALLABLE_OR_RAISE(payload->credentials, rb_options, "credentials");
176
+ if (!NIL_P(rb_options)) {
177
+ CALLABLE_OR_RAISE(payload->update_tips, rb_options, "update_tips");
178
+ CALLABLE_OR_RAISE(payload->progress, rb_options, "progress");
179
+ CALLABLE_OR_RAISE(payload->transfer_progress, rb_options, "transfer_progress");
180
+ CALLABLE_OR_RAISE(payload->credentials, rb_options, "credentials");
181
+ }
171
182
  }
172
183
 
173
184
  static void rb_git_remote__free(git_remote *remote)
@@ -237,7 +248,7 @@ static VALUE rb_git_remote_ls(int argc, VALUE *argv, VALUE self)
237
248
  git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
238
249
  const git_remote_head **heads;
239
250
 
240
- struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
251
+ struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
241
252
 
242
253
  VALUE rb_options;
243
254
 
@@ -251,8 +262,7 @@ static VALUE rb_git_remote_ls(int argc, VALUE *argv, VALUE self)
251
262
  if (!rb_block_given_p())
252
263
  return rb_funcall(self, rb_intern("to_enum"), 2, CSTR2SYM("ls"), rb_options);
253
264
 
254
- if (!NIL_P(rb_options))
255
- rugged_remote_init_callbacks_and_payload_from_options(rb_options, &callbacks, &payload);
265
+ rugged_remote_init_callbacks_and_payload_from_options(rb_options, &callbacks, &payload);
256
266
 
257
267
  if ((error = git_remote_set_callbacks(remote, &callbacks)) ||
258
268
  (error = git_remote_connect(remote, GIT_DIRECTION_FETCH)) ||
@@ -527,7 +537,7 @@ static VALUE rb_git_remote_check_connection(int argc, VALUE *argv, VALUE self)
527
537
  {
528
538
  git_remote *remote;
529
539
  git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
530
- struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
540
+ struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
531
541
  VALUE rb_direction, rb_options;
532
542
  ID id_direction;
533
543
  int error, direction;
@@ -544,8 +554,7 @@ static VALUE rb_git_remote_check_connection(int argc, VALUE *argv, VALUE self)
544
554
  else
545
555
  rb_raise(rb_eTypeError, "Invalid direction. Expected :fetch or :push");
546
556
 
547
- if (!NIL_P(rb_options))
548
- rugged_remote_init_callbacks_and_payload_from_options(rb_options, &callbacks, &payload);
557
+ rugged_remote_init_callbacks_and_payload_from_options(rb_options, &callbacks, &payload);
549
558
 
550
559
  if ((error = git_remote_set_callbacks(remote, &callbacks)) < 0)
551
560
  goto cleanup;
@@ -618,7 +627,7 @@ static VALUE rb_git_remote_fetch(int argc, VALUE *argv, VALUE self)
618
627
  git_signature *signature = NULL;
619
628
  git_strarray refspecs;
620
629
  git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
621
- struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
630
+ struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
622
631
 
623
632
  char *log_message = NULL;
624
633
  int error;
@@ -633,6 +642,8 @@ static VALUE rb_git_remote_fetch(int argc, VALUE *argv, VALUE self)
633
642
  rugged_check_repo(rb_repo);
634
643
  Data_Get_Struct(rb_repo, git_repository, repo);
635
644
 
645
+ rugged_remote_init_callbacks_and_payload_from_options(rb_options, &callbacks, &payload);
646
+
636
647
  if (!NIL_P(rb_options)) {
637
648
  VALUE rb_val = rb_hash_aref(rb_options, CSTR2SYM("signature"));
638
649
  if (!NIL_P(rb_val))
@@ -641,8 +652,6 @@ static VALUE rb_git_remote_fetch(int argc, VALUE *argv, VALUE self)
641
652
  rb_val = rb_hash_aref(rb_options, CSTR2SYM("message"));
642
653
  if (!NIL_P(rb_val))
643
654
  log_message = StringValueCStr(rb_val);
644
-
645
- rugged_remote_init_callbacks_and_payload_from_options(rb_options, &callbacks, &payload);
646
655
  }
647
656
 
648
657
  if ((error = git_remote_set_callbacks(remote, &callbacks)))
@@ -674,15 +683,6 @@ static VALUE rb_git_remote_fetch(int argc, VALUE *argv, VALUE self)
674
683
  return rb_result;
675
684
  }
676
685
 
677
- static int push_status_cb(const char *ref, const char *msg, void *payload)
678
- {
679
- VALUE rb_result_hash = (VALUE)payload;
680
- if (msg != NULL)
681
- rb_hash_aset(rb_result_hash, rb_str_new_utf8(ref), rb_str_new_utf8(msg));
682
-
683
- return GIT_OK;
684
- }
685
-
686
686
  /*
687
687
  * call-seq:
688
688
  * remote.push(refspecs = nil, options = {}) -> hash
@@ -721,36 +721,30 @@ static VALUE rb_git_remote_push(int argc, VALUE *argv, VALUE self)
721
721
  {
722
722
  VALUE rb_refspecs, rb_options, rb_val;
723
723
  VALUE rb_repo = rugged_owner(self);
724
- VALUE rb_exception = Qnil, rb_result = rb_hash_new();
725
724
 
726
725
  git_repository *repo;
727
- git_remote *remote, *tmp_remote = NULL;
726
+ git_remote *remote;
728
727
  git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
729
- git_push *push = NULL;
730
728
  git_signature *signature = NULL;
729
+ git_strarray refspecs;
730
+ git_push_options opts = GIT_PUSH_OPTIONS_INIT;
731
731
 
732
- int error = 0, i = 0;
732
+ int error = 0;
733
733
  char *log_message = NULL;
734
734
 
735
- struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, 0 };
735
+ struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, rb_hash_new(), 0 };
736
736
 
737
737
  rb_scan_args(argc, argv, "01:", &rb_refspecs, &rb_options);
738
738
 
739
- if (!NIL_P(rb_refspecs)) {
740
- Check_Type(rb_refspecs, T_ARRAY);
741
- for (i = 0; i < RARRAY_LEN(rb_refspecs); ++i) {
742
- VALUE rb_refspec = rb_ary_entry(rb_refspecs, i);
743
- Check_Type(rb_refspec, T_STRING);
744
- }
745
- }
739
+ rugged_rb_ary_to_strarray(rb_refspecs, &refspecs);
746
740
 
747
741
  rugged_check_repo(rb_repo);
748
742
  Data_Get_Struct(rb_repo, git_repository, repo);
749
743
  Data_Get_Struct(self, git_remote, remote);
750
744
 
751
- if (!NIL_P(rb_options)) {
752
- rugged_remote_init_callbacks_and_payload_from_options(rb_options, &callbacks, &payload);
745
+ rugged_remote_init_callbacks_and_payload_from_options(rb_options, &callbacks, &payload);
753
746
 
747
+ if (!NIL_P(rb_options)) {
754
748
  rb_val = rb_hash_aref(rb_options, CSTR2SYM("message"));
755
749
  if (!NIL_P(rb_val))
756
750
  log_message = StringValueCStr(rb_val);
@@ -760,64 +754,21 @@ static VALUE rb_git_remote_push(int argc, VALUE *argv, VALUE self)
760
754
  signature = rugged_signature_get(rb_val, repo);
761
755
  }
762
756
 
763
- // Create a temporary remote that we use for pushing
764
- if ((error = git_remote_dup(&tmp_remote, remote)) ||
765
- (error = git_remote_set_callbacks(tmp_remote, &callbacks)))
757
+ if ((error = git_remote_set_callbacks(remote, &callbacks)))
766
758
  goto cleanup;
767
759
 
768
- if (!NIL_P(rb_refspecs)) {
769
- git_remote_clear_refspecs(tmp_remote);
770
-
771
- for (i = 0; !error && i < RARRAY_LEN(rb_refspecs); ++i) {
772
- VALUE rb_refspec = rb_ary_entry(rb_refspecs, i);
773
-
774
- if ((error = git_remote_add_push(tmp_remote, StringValueCStr(rb_refspec))))
775
- goto cleanup;
776
- }
777
- }
778
-
779
- if ((error = git_push_new(&push, tmp_remote)))
780
- goto cleanup;
781
-
782
- // TODO: Get rid of this once git_remote_push lands in libgit2.
783
- {
784
- git_strarray push_refspecs;
785
- size_t i;
786
-
787
- if ((error = git_remote_get_push_refspecs(&push_refspecs, tmp_remote)))
788
- goto cleanup;
789
-
790
- if (push_refspecs.count == 0) {
791
- rb_exception = rb_exc_new2(rb_eRuggedError, "no pushspecs are configured for the given remote");
792
- goto cleanup;
793
- }
794
-
795
- for (i = 0; !error && i < push_refspecs.count; ++i) {
796
- error = git_push_add_refspec(push, push_refspecs.strings[i]);
797
- }
798
-
799
- git_strarray_free(&push_refspecs);
800
- if (error) goto cleanup;
801
- }
802
-
803
- if ((error = git_push_finish(push)))
804
- goto cleanup;
805
-
806
- if ((error = git_push_status_foreach(push, &push_status_cb, (void *)rb_result)) ||
807
- (error = git_push_update_tips(push, signature, log_message)))
808
- goto cleanup;
760
+ error = git_remote_push(remote, &refspecs, &opts, signature, log_message);
809
761
 
810
762
  cleanup:
811
- git_push_free(push);
812
- git_remote_free(tmp_remote);
763
+ xfree(refspecs.strings);
813
764
  git_signature_free(signature);
814
765
 
815
- if (!NIL_P(rb_exception))
816
- rb_exc_raise(rb_exception);
766
+ if (payload.exception)
767
+ rb_jump_tag(payload.exception);
817
768
 
818
769
  rugged_exception_check(error);
819
770
 
820
- return rb_result;
771
+ return payload.result;
821
772
  }
822
773
 
823
774
  void Init_rugged_remote(void)
@@ -251,7 +251,8 @@ static VALUE rb_git_remote_collection_rename(VALUE self, VALUE rb_name_or_remote
251
251
  {
252
252
  VALUE rb_repo = rugged_owner(self);
253
253
  git_repository *repo;
254
- int i, error, exception;
254
+ size_t i;
255
+ int error, exception;
255
256
  git_strarray problems;
256
257
 
257
258
  if (!rb_block_given_p())
@@ -24,6 +24,9 @@
24
24
 
25
25
  #include "rugged.h"
26
26
  #include <git2/sys/repository.h>
27
+ #include <git2/sys/odb_backend.h>
28
+ #include <git2/sys/refdb_backend.h>
29
+ #include <git2/refs.h>
27
30
 
28
31
  extern VALUE rb_mRugged;
29
32
  extern VALUE rb_eRuggedError;
@@ -35,6 +38,7 @@ extern VALUE rb_cRuggedCommit;
35
38
  extern VALUE rb_cRuggedTag;
36
39
  extern VALUE rb_cRuggedTree;
37
40
  extern VALUE rb_cRuggedReference;
41
+ extern VALUE rb_cRuggedBackend;
38
42
 
39
43
  extern VALUE rb_cRuggedCredPlaintext;
40
44
  extern VALUE rb_cRuggedCredSshKey;
@@ -182,9 +186,78 @@ static void load_alternates(git_repository *repo, VALUE rb_alternates)
182
186
  rugged_exception_check(error);
183
187
  }
184
188
 
189
+ static void rugged_repo_new_with_backend(git_repository **repo, VALUE rb_path, VALUE rb_backend)
190
+ {
191
+ char *path;
192
+
193
+ git_odb *odb = NULL;
194
+ git_odb_backend *odb_backend = NULL;
195
+ git_refdb *refdb = NULL;
196
+ git_refdb_backend *refdb_backend = NULL;
197
+ git_reference *head = NULL;
198
+ rugged_backend *backend;
199
+
200
+ int error = 0;
201
+
202
+ Check_Type(rb_path, T_STRING);
203
+ path = StringValueCStr(rb_path);
204
+
205
+ if (rb_obj_is_kind_of(rb_backend, rb_cRuggedBackend) == Qfalse) {
206
+ rb_raise(rb_eRuggedError, "Backend must be an instance of Rugged::Backend");
207
+ }
208
+
209
+ Data_Get_Struct(rb_backend, rugged_backend, backend);
210
+
211
+ error = git_odb_new(&odb);
212
+ if (error) goto cleanup;
213
+
214
+ error = backend->odb_backend(&odb_backend, backend, path);
215
+ if (error) goto cleanup;
216
+
217
+ error = git_odb_add_backend(odb, odb_backend, 1);
218
+ if (error) goto cleanup;
219
+
220
+ error = git_repository_wrap_odb(repo, odb);
221
+ if (error) goto cleanup;
222
+
223
+ error = git_refdb_new(&refdb, *repo);
224
+ if (error) goto cleanup;
225
+
226
+ error = backend->refdb_backend(&refdb_backend, backend, path);
227
+ if (error) goto cleanup;
228
+
229
+ error = git_refdb_set_backend(refdb, refdb_backend);
230
+ if (error) goto cleanup;
231
+
232
+ git_repository_set_refdb(*repo, refdb);
233
+
234
+ error = git_reference_lookup(&head, *repo, "HEAD");
235
+
236
+ if (error == GIT_ENOTFOUND) {
237
+ giterr_clear();
238
+ error = git_reference_symbolic_create(&head, *repo, "HEAD", "refs/heads/master", 0, NULL, NULL);
239
+ }
240
+
241
+ if (!error) {
242
+ git_reference_free(head);
243
+ return;
244
+ }
245
+
246
+ cleanup:
247
+ git_repository_free(*repo);
248
+ git_odb_free(odb);
249
+ git_refdb_free(refdb);
250
+
251
+ if (odb_backend != NULL) odb_backend->free(odb_backend);
252
+ if (refdb_backend != NULL) refdb_backend->free(refdb_backend);
253
+
254
+ rugged_exception_check(error);
255
+ }
256
+
185
257
  /*
186
258
  * call-seq:
187
- * Repository.bare(path[, alternates]) -> repository
259
+ * Repository.bare(path[, alternates]) -> repository OR
260
+ * Repository.bare(path[, options]) -> repository
188
261
  *
189
262
  * Open a bare Git repository at +path+ and return a +Repository+
190
263
  * object representing it.
@@ -193,23 +266,52 @@ static void load_alternates(git_repository *repo, VALUE rb_alternates)
193
266
  * any +.git+ directory discovery, won't try to load the config options to
194
267
  * determine whether the repository is bare and won't try to load the workdir.
195
268
  *
196
- * Optionally, you can pass a list of alternate object folders.
269
+ * Optionally, you can pass a list of alternate object folders or an options Hash.
197
270
  *
198
271
  * Rugged::Repository.bare(path, ['./other/repo/.git/objects'])
272
+ * Rugged::Repository.bare(path, opts)
273
+ *
274
+ * The following options can be passed in the +options+ Hash:
275
+ *
276
+ * :backend ::
277
+ * A Rugged::Backend instance
278
+ * :alternates ::
279
+ * A list of alternate object folders.
280
+ * Rugged::Repository.bare(path, :alternates => ['./other/repo/.git/objects'])
199
281
  */
200
282
  static VALUE rb_git_repo_open_bare(int argc, VALUE *argv, VALUE klass)
201
283
  {
202
- git_repository *repo;
284
+ git_repository *repo = NULL;
203
285
  int error = 0;
204
- VALUE rb_path, rb_alternates;
286
+ VALUE rb_path, rb_options, rb_alternates = 0;
205
287
 
206
- rb_scan_args(argc, argv, "11", &rb_path, &rb_alternates);
207
- Check_Type(rb_path, T_STRING);
288
+ rb_scan_args(argc, argv, "11", &rb_path, &rb_options);
208
289
 
209
- error = git_repository_open_bare(&repo, StringValueCStr(rb_path));
210
- rugged_exception_check(error);
290
+ if (!NIL_P(rb_options) && TYPE(rb_options) == T_ARRAY)
291
+ rb_alternates = rb_options;
292
+
293
+ if (!NIL_P(rb_options) && TYPE(rb_options) == T_HASH) {
294
+ /* Check for `:backend` */
295
+ VALUE rb_backend = rb_hash_aref(rb_options, CSTR2SYM("backend"));
296
+
297
+ if (!NIL_P(rb_backend)) {
298
+ rugged_repo_new_with_backend(&repo, rb_path, rb_backend);
299
+ }
211
300
 
212
- load_alternates(repo, rb_alternates);
301
+ /* Check for `:alternates` */
302
+ rb_alternates = rb_hash_aref(rb_options, CSTR2SYM("alternates"));
303
+ }
304
+
305
+ if (!repo) {
306
+ Check_Type(rb_path, T_STRING);
307
+
308
+ error = git_repository_open_bare(&repo, StringValueCStr(rb_path));
309
+ rugged_exception_check(error);
310
+ }
311
+
312
+ if (rb_alternates) {
313
+ load_alternates(repo, rb_alternates);
314
+ }
213
315
 
214
316
  return rugged_repo_new(klass, repo);
215
317
  }
@@ -235,7 +337,7 @@ static VALUE rb_git_repo_open_bare(int argc, VALUE *argv, VALUE klass)
235
337
  *
236
338
  * Examples:
237
339
  *
238
- * Rugged::Repository.new('~/test/.git') #=> #<Rugged::Repository:0x108849488>
340
+ * Rugged::Repository.new('test/.git') #=> #<Rugged::Repository:0x108849488>
239
341
  * Rugged::Repository.new(path, :alternates => ['./other/repo/.git/objects'])
240
342
  */
241
343
  static VALUE rb_git_repo_new(int argc, VALUE *argv, VALUE klass)
@@ -260,7 +362,7 @@ static VALUE rb_git_repo_new(int argc, VALUE *argv, VALUE klass)
260
362
 
261
363
  /*
262
364
  * call-seq:
263
- * Repository.init_at(path, is_bare = false) -> repository
365
+ * Repository.init_at(path, is_bare = false, opts = {}) -> repository
264
366
  *
265
367
  * Initialize a Git repository in +path+. This implies creating all the
266
368
  * necessary files on the FS, or re-initializing an already existing
@@ -272,19 +374,36 @@ static VALUE rb_git_repo_new(int argc, VALUE *argv, VALUE klass)
272
374
  * of +path+. Non-bare repositories are created in a +.git+ folder and
273
375
  * use +path+ as working directory.
274
376
  *
275
- * Rugged::Repository.init_at('~/repository', :bare) #=> #<Rugged::Repository:0x108849488>
377
+ * The following options can be passed in the +options+ Hash:
378
+ *
379
+ * :backend ::
380
+ * A Rugged::Backend instance
381
+ *
382
+ *
383
+ * Rugged::Repository.init_at('repository', :bare) #=> #<Rugged::Repository:0x108849488>
276
384
  */
277
385
  static VALUE rb_git_repo_init_at(int argc, VALUE *argv, VALUE klass)
278
386
  {
279
- git_repository *repo;
280
- VALUE rb_path, rb_is_bare;
387
+ git_repository *repo = NULL;
388
+ VALUE rb_path, rb_is_bare, rb_options;
389
+ int error;
281
390
 
282
- rb_scan_args(argc, argv, "11", &rb_path, &rb_is_bare);
391
+ rb_scan_args(argc, argv, "11:", &rb_path, &rb_is_bare, &rb_options);
283
392
  Check_Type(rb_path, T_STRING);
284
393
 
285
- rugged_exception_check(
286
- git_repository_init(&repo, StringValueCStr(rb_path), RTEST(rb_is_bare))
287
- );
394
+ if (!NIL_P(rb_options)) {
395
+ /* Check for `:backend` */
396
+ VALUE rb_backend = rb_hash_aref(rb_options, CSTR2SYM("backend"));
397
+
398
+ if (rb_backend && !NIL_P(rb_backend)) {
399
+ rugged_repo_new_with_backend(&repo, rb_path, rb_backend);
400
+ }
401
+ }
402
+
403
+ if(!repo) {
404
+ error = git_repository_init(&repo, StringValueCStr(rb_path), RTEST(rb_is_bare));
405
+ rugged_exception_check(error);
406
+ }
288
407
 
289
408
  return rugged_repo_new(klass, repo);
290
409
  }
@@ -526,19 +645,21 @@ static VALUE rb_git_repo_merge_base(VALUE self, VALUE rb_args)
526
645
  */
527
646
  static VALUE rb_git_repo_merge_bases(VALUE self, VALUE rb_args)
528
647
  {
529
- int error = GIT_OK, i;
648
+ int error = GIT_OK;
649
+ size_t i, len = (size_t)RARRAY_LEN(rb_args);
530
650
  git_repository *repo;
531
651
  git_oidarray bases = {NULL, 0};
532
- git_oid *input_array = xmalloc(sizeof(git_oid) * RARRAY_LEN(rb_args));
533
- int len = (int)RARRAY_LEN(rb_args);
652
+ git_oid *input_array;
534
653
 
535
654
  VALUE rb_bases;
536
655
 
537
656
  if (len < 2)
538
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 2+)", len);
657
+ rb_raise(rb_eArgError, "wrong number of arguments (%ld for 2+)", RARRAY_LEN(rb_args));
539
658
 
540
659
  Data_Get_Struct(self, git_repository, repo);
541
660
 
661
+ input_array = xmalloc(sizeof(git_oid) * len);
662
+
542
663
  for (i = 0; !error && i < len; ++i) {
543
664
  error = rugged_oid_get(&input_array[i], repo, rb_ary_entry(rb_args, i));
544
665
  }
@@ -585,7 +706,7 @@ static VALUE rb_git_repo_merge_bases(VALUE self, VALUE rb_args)
585
706
  * :fastforward ::
586
707
  * The given commit is a fast-forward from HEAD and no merge needs to be
587
708
  * performed. HEAD can simply be set to the given commit.
588
- *
709
+ *
589
710
  * :unborn ::
590
711
  * The HEAD of the current repository is "unborn" and does not point to
591
712
  * a valid commit. No merge can be performed, but the caller may wish
@@ -1116,8 +1237,12 @@ static VALUE rb_git_repo_get_head(VALUE self)
1116
1237
  static VALUE rb_git_repo_path(VALUE self)
1117
1238
  {
1118
1239
  git_repository *repo;
1240
+ const char *path;
1241
+
1119
1242
  Data_Get_Struct(self, git_repository, repo);
1120
- return rb_str_new_utf8(git_repository_path(repo));
1243
+ path = git_repository_path(repo);
1244
+
1245
+ return path ? rb_str_new_utf8(path) : Qnil;
1121
1246
  }
1122
1247
 
1123
1248
  /*