rugged 0.25.0b8 → 0.25.0b9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9436b2f4df762f300fb1103b01d8f80c4973441a
4
- data.tar.gz: fffa3a995093034dac0762800d16fb6d6fa9d38b
3
+ metadata.gz: 446553349654cfec5239ed7c7bbb2d3cc57034fb
4
+ data.tar.gz: 0e580f2767fe9eefac9073fc31f9d53eb997669b
5
5
  SHA512:
6
- metadata.gz: afad4fb30f5ba7c31ba25714422e2941df978bfd3df5c72d2510ce2c5372769bb74ee5ab0e24115d1e52a19dd84fbf3289453d187253a9f1f63fb6cd294d6c95
7
- data.tar.gz: 7f5c92919ec876e1ba8a3c042fe9de29b632c4d5be8ed327c9e2226c6424d401b132b25f347c52000c7a1287d0958c7ff59a9768af4c2da3c4fe066a5ec776e4
6
+ metadata.gz: c6ce0b1c7541b0250884c74acb03932c2d15b978b85e816328e3d12daab134e1500289674aa2652aaad68c81144fc573a6de3f8b04837c81165e7b31179535ae
7
+ data.tar.gz: 5cc83ce5093f126becab5c0647efe98664f3fe03bdd9c4c6ea0845ef75e541bbdfc63e9edd5caa92ecb76681f11ac73333d247e7506f0ef71a63f508b4f55ac7
@@ -77,7 +77,7 @@ else
77
77
  # in $LIBS or the final linking stage won't pick them up
78
78
  if windows?
79
79
  $LDFLAGS << " " + "-L#{Dir.pwd}/deps/winhttp"
80
- $LIBS << " -lwinhttp -lcrypt32 -lrpcrt4 -lole32"
80
+ $LIBS << " -lwinhttp -lcrypt32 -lrpcrt4 -lole32 -lz"
81
81
  else
82
82
  pcfile = File.join(LIBGIT2_DIR, "build", "libgit2.pc")
83
83
  $LDFLAGS << " " + `pkg-config --libs --static #{pcfile}`.strip
@@ -428,6 +428,87 @@ void rugged_rb_ary_to_strarray(VALUE rb_array, git_strarray *str_array)
428
428
  }
429
429
  }
430
430
 
431
+ void rugged_parse_merge_file_options(git_merge_file_options *opts, VALUE rb_options)
432
+ {
433
+ VALUE rb_value;
434
+
435
+ Check_Type(rb_options, T_HASH);
436
+
437
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("ancestor_label"));
438
+ if (!NIL_P(rb_value)) {
439
+ Check_Type(rb_value, T_STRING);
440
+ opts->ancestor_label = StringValueCStr(rb_value);
441
+ }
442
+
443
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("our_label"));
444
+ if (!NIL_P(rb_value)) {
445
+ Check_Type(rb_value, T_STRING);
446
+ opts->our_label = StringValueCStr(rb_value);
447
+ }
448
+
449
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("their_label"));
450
+ if (!NIL_P(rb_value)) {
451
+ Check_Type(rb_value, T_STRING);
452
+ opts->their_label = StringValueCStr(rb_value);
453
+ }
454
+
455
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("favor"));
456
+ if (!NIL_P(rb_value)) {
457
+ ID id_favor;
458
+
459
+ Check_Type(rb_value, T_SYMBOL);
460
+ id_favor = SYM2ID(rb_value);
461
+
462
+ if (id_favor == rb_intern("normal")) {
463
+ opts->favor = GIT_MERGE_FILE_FAVOR_NORMAL;
464
+ } else if (id_favor == rb_intern("ours")) {
465
+ opts->favor = GIT_MERGE_FILE_FAVOR_OURS;
466
+ } else if (id_favor == rb_intern("theirs")) {
467
+ opts->favor = GIT_MERGE_FILE_FAVOR_THEIRS;
468
+ } else if (id_favor == rb_intern("union")) {
469
+ opts->favor = GIT_MERGE_FILE_FAVOR_UNION;
470
+ } else {
471
+ rb_raise(rb_eTypeError,
472
+ "Invalid favor mode. Expected `:normal`, `:ours`, `:theirs` or `:union`");
473
+ }
474
+ }
475
+
476
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("style"));
477
+ if (!NIL_P(rb_value)) {
478
+ ID id_style;
479
+
480
+ Check_Type(rb_value, T_SYMBOL);
481
+ id_style = SYM2ID(rb_value);
482
+
483
+ if (id_style == rb_intern("standard")) {
484
+ opts->flags |= GIT_MERGE_FILE_STYLE_MERGE;
485
+ } else if (id_style == rb_intern("diff3")) {
486
+ opts->flags |= GIT_MERGE_FILE_STYLE_DIFF3;
487
+ } else {
488
+ rb_raise(rb_eTypeError,
489
+ "Invalid style mode. Expected `:standard`, or `:diff3`");
490
+ }
491
+ } else {
492
+ opts->flags |= GIT_MERGE_FILE_STYLE_MERGE;
493
+ }
494
+
495
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("simplify")))) {
496
+ opts->flags |= GIT_MERGE_FILE_SIMPLIFY_ALNUM;
497
+ }
498
+ }
499
+
500
+ VALUE rb_merge_file_result_fromC(const git_merge_file_result *result)
501
+ {
502
+ VALUE rb_result = rb_hash_new();
503
+
504
+ rb_hash_aset(rb_result, CSTR2SYM("automergeable"), result->automergeable ? Qtrue : Qfalse);
505
+ rb_hash_aset(rb_result, CSTR2SYM("path"), result->path ? rb_str_new_utf8(result->path) : Qnil);
506
+ rb_hash_aset(rb_result, CSTR2SYM("filemode"), INT2FIX(result->mode));
507
+ rb_hash_aset(rb_result, CSTR2SYM("data"), rb_str_new(result->ptr, result->len));
508
+
509
+ return rb_result;
510
+ }
511
+
431
512
  void Init_rugged(void)
432
513
  {
433
514
  rb_mRugged = rb_define_module("Rugged");
@@ -96,10 +96,12 @@ VALUE rugged_diff_hunk_new(VALUE owner, size_t hunk_idx, const git_diff_hunk *hu
96
96
  VALUE rugged_diff_line_new(const git_diff_line *line);
97
97
  VALUE rugged_remote_new(VALUE owner, git_remote *remote);
98
98
  VALUE rb_git_delta_file_fromC(const git_diff_file *file);
99
+ VALUE rb_merge_file_result_fromC(const git_merge_file_result *results);
99
100
 
100
101
  void rugged_parse_diff_options(git_diff_options *opts, VALUE rb_options);
101
102
  void rugged_parse_merge_options(git_merge_options *opts, VALUE rb_options);
102
103
  void rugged_parse_checkout_options(git_checkout_options *opts, VALUE rb_options);
104
+ void rugged_parse_merge_file_options(git_merge_file_options *opts, VALUE rb_options);
103
105
 
104
106
  void rugged_cred_extract(git_cred **cred, int allowed_types, VALUE rb_credential);
105
107
 
@@ -157,6 +159,7 @@ struct rugged_remote_cb_payload
157
159
  VALUE transfer_progress;
158
160
  VALUE update_tips;
159
161
  VALUE credentials;
162
+ VALUE certificate_check;
160
163
  VALUE result;
161
164
  int exception;
162
165
  };
@@ -551,6 +551,108 @@ static VALUE rb_git_blob_to_buffer(int argc, VALUE *argv, VALUE self)
551
551
  return rb_ret;
552
552
  }
553
553
 
554
+ #define RUGGED_MERGE_FILE_INPUT_INIT { GIT_MERGE_FILE_INPUT_INIT }
555
+
556
+ typedef struct {
557
+ git_merge_file_input parent;
558
+ int has_id;
559
+ git_oid id;
560
+ } rugged_merge_file_input;
561
+
562
+ static void rugged_parse_merge_file_input(rugged_merge_file_input *input, git_repository *repo, VALUE rb_input)
563
+ {
564
+ VALUE rb_value;
565
+
566
+ Check_Type(rb_input, T_HASH);
567
+
568
+ if (!NIL_P(rb_value = rb_hash_aref(rb_input, CSTR2SYM("content")))) {
569
+ input->parent.ptr = RSTRING_PTR(rb_value);
570
+ input->parent.size = RSTRING_LEN(rb_value);
571
+ } else if (!NIL_P(rb_value = rb_hash_aref(rb_input, CSTR2SYM("oid")))) {
572
+ if (!repo)
573
+ rb_raise(rb_eArgError, "Rugged repository is required when file input is `:oid`.");
574
+
575
+ rugged_exception_check(git_oid_fromstr(&input->id, RSTRING_PTR(rb_value)));
576
+ input->has_id = 1;
577
+ } else {
578
+ rb_raise(rb_eArgError, "File input must have `:content` or `:oid`.");
579
+ }
580
+
581
+ rb_value = rb_hash_aref(rb_input, CSTR2SYM("filemode"));
582
+ if (!NIL_P(rb_value))
583
+ input->parent.mode = FIX2UINT(rb_value);
584
+
585
+ rb_value = rb_hash_aref(rb_input, CSTR2SYM("path"));
586
+ if (!NIL_P(rb_value)) {
587
+ Check_Type(rb_value, T_STRING);
588
+ input->parent.path = RSTRING_PTR(rb_value);
589
+ }
590
+ }
591
+
592
+ static int rugged_load_merge_file_input(git_blob **out, git_repository *repo, rugged_merge_file_input *input)
593
+ {
594
+ int error;
595
+
596
+ if (!input->has_id)
597
+ return 0;
598
+
599
+ if ((error = git_blob_lookup(out, repo, &input->id)) < 0)
600
+ return error;
601
+
602
+ input->parent.ptr = git_blob_rawcontent(*out);
603
+ input->parent.size = git_blob_rawsize(*out);
604
+
605
+ return 0;
606
+ }
607
+
608
+ static VALUE rb_git_blob_merge_files(int argc, VALUE *argv, VALUE klass)
609
+ {
610
+ VALUE rb_repo, rb_ancestor, rb_ours, rb_theirs, rb_options, rb_result;
611
+
612
+ git_repository *repo = NULL;
613
+ rugged_merge_file_input ancestor = RUGGED_MERGE_FILE_INPUT_INIT,
614
+ ours = RUGGED_MERGE_FILE_INPUT_INIT,
615
+ theirs = RUGGED_MERGE_FILE_INPUT_INIT;
616
+ git_blob *ancestor_blob = NULL, *our_blob = NULL, *their_blob = NULL;
617
+ git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
618
+ git_merge_file_result result = {0};
619
+ int error;
620
+
621
+ rb_scan_args(argc, argv, "41", &rb_repo, &rb_ancestor, &rb_ours, &rb_theirs, &rb_options);
622
+
623
+ if (!NIL_P(rb_repo)) {
624
+ rugged_check_repo(rb_repo);
625
+ Data_Get_Struct(rb_repo, git_repository, repo);
626
+ }
627
+
628
+ if (!NIL_P(rb_options))
629
+ rugged_parse_merge_file_options(&opts, rb_options);
630
+
631
+ if (!NIL_P(rb_ancestor))
632
+ rugged_parse_merge_file_input(&ancestor, repo, rb_ancestor);
633
+ if (!NIL_P(rb_ours))
634
+ rugged_parse_merge_file_input(&ours, repo, rb_ours);
635
+ if (!NIL_P(rb_theirs))
636
+ rugged_parse_merge_file_input(&theirs, repo, rb_theirs);
637
+
638
+ if ((error = rugged_load_merge_file_input(&ancestor_blob, repo, &ancestor)) < 0 ||
639
+ (error = rugged_load_merge_file_input(&our_blob, repo, &ours)) < 0 ||
640
+ (error = rugged_load_merge_file_input(&their_blob, repo, &theirs)) < 0 ||
641
+ (error = git_merge_file(&result, &ancestor.parent, &ours.parent, &theirs.parent, &opts)) < 0)
642
+ goto done;
643
+
644
+ rb_result = rb_merge_file_result_fromC(&result);
645
+
646
+ done:
647
+ git_blob_free(ancestor_blob);
648
+ git_blob_free(our_blob);
649
+ git_blob_free(their_blob);
650
+ git_merge_file_result_free(&result);
651
+
652
+ rugged_exception_check(error);
653
+ return rb_result;
654
+ }
655
+
554
656
  static VALUE rb_git_blob_sig_new(int argc, VALUE *argv, VALUE klass)
555
657
  {
556
658
  int error, opts = 0;
@@ -622,6 +724,7 @@ void Init_rugged_blob(void)
622
724
  rb_define_singleton_method(rb_cRuggedBlob, "from_io", rb_git_blob_from_io, -1);
623
725
 
624
726
  rb_define_singleton_method(rb_cRuggedBlob, "to_buffer", rb_git_blob_to_buffer, -1);
727
+ rb_define_singleton_method(rb_cRuggedBlob, "merge_files", rb_git_blob_merge_files, -1);
625
728
 
626
729
  rb_cRuggedBlobSig = rb_define_class_under(rb_cRuggedBlob, "HashSignature", rb_cObject);
627
730
  rb_define_singleton_method(rb_cRuggedBlobSig, "new", rb_git_blob_sig_new, -1);
@@ -952,76 +952,6 @@ static VALUE rb_git_conflict_get(VALUE self, VALUE rb_path)
952
952
  return rb_result;
953
953
  }
954
954
 
955
- void rugged_parse_merge_file_options(git_merge_file_options *opts, VALUE rb_options)
956
- {
957
- if (!NIL_P(rb_options)) {
958
- VALUE rb_value;
959
- Check_Type(rb_options, T_HASH);
960
-
961
- rb_value = rb_hash_aref(rb_options, CSTR2SYM("ancestor_label"));
962
- if (!NIL_P(rb_value)) {
963
- Check_Type(rb_value, T_STRING);
964
- opts->ancestor_label = StringValueCStr(rb_value);
965
- }
966
-
967
- rb_value = rb_hash_aref(rb_options, CSTR2SYM("our_label"));
968
- if (!NIL_P(rb_value)) {
969
- Check_Type(rb_value, T_STRING);
970
- opts->our_label = StringValueCStr(rb_value);
971
- }
972
-
973
- rb_value = rb_hash_aref(rb_options, CSTR2SYM("their_label"));
974
- if (!NIL_P(rb_value)) {
975
- Check_Type(rb_value, T_STRING);
976
- opts->their_label = StringValueCStr(rb_value);
977
- }
978
-
979
- rb_value = rb_hash_aref(rb_options, CSTR2SYM("favor"));
980
- if (!NIL_P(rb_value)) {
981
- ID id_favor;
982
-
983
- Check_Type(rb_value, T_SYMBOL);
984
- id_favor = SYM2ID(rb_value);
985
-
986
- if (id_favor == rb_intern("normal")) {
987
- opts->favor = GIT_MERGE_FILE_FAVOR_NORMAL;
988
- } else if (id_favor == rb_intern("ours")) {
989
- opts->favor = GIT_MERGE_FILE_FAVOR_OURS;
990
- } else if (id_favor == rb_intern("theirs")) {
991
- opts->favor = GIT_MERGE_FILE_FAVOR_THEIRS;
992
- } else if (id_favor == rb_intern("union")) {
993
- opts->favor = GIT_MERGE_FILE_FAVOR_UNION;
994
- } else {
995
- rb_raise(rb_eTypeError,
996
- "Invalid favor mode. Expected `:normal`, `:ours`, `:theirs` or `:union`");
997
- }
998
- }
999
-
1000
- rb_value = rb_hash_aref(rb_options, CSTR2SYM("style"));
1001
- if (!NIL_P(rb_value)) {
1002
- ID id_style;
1003
-
1004
- Check_Type(rb_value, T_SYMBOL);
1005
- id_style = SYM2ID(rb_value);
1006
-
1007
- if (id_style == rb_intern("standard")) {
1008
- opts->flags |= GIT_MERGE_FILE_STYLE_MERGE;
1009
- } else if (id_style == rb_intern("diff3")) {
1010
- opts->flags |= GIT_MERGE_FILE_STYLE_DIFF3;
1011
- } else {
1012
- rb_raise(rb_eTypeError,
1013
- "Invalid style mode. Expected `:standard`, or `:diff3`");
1014
- }
1015
- } else {
1016
- opts->flags |= GIT_MERGE_FILE_STYLE_MERGE;
1017
- }
1018
-
1019
- if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("simplify")))) {
1020
- opts->flags |= GIT_MERGE_FILE_SIMPLIFY_ALNUM;
1021
- }
1022
- }
1023
- }
1024
-
1025
955
  /*
1026
956
  * call-seq:
1027
957
  * index.merge_file(path[, options]) -> merge_file or nil
@@ -1061,8 +991,7 @@ void rugged_parse_merge_file_options(git_merge_file_options *opts, VALUE rb_opti
1061
991
 
1062
992
  static VALUE rb_git_merge_file(int argc, VALUE *argv, VALUE self)
1063
993
  {
1064
- VALUE rb_path, rb_options;
1065
- VALUE rb_result = rb_hash_new();
994
+ VALUE rb_path, rb_options, rb_result;
1066
995
  VALUE rb_repo = rugged_owner(self);
1067
996
 
1068
997
  git_repository *repo;
@@ -1074,10 +1003,8 @@ static VALUE rb_git_merge_file(int argc, VALUE *argv, VALUE self)
1074
1003
 
1075
1004
  rb_scan_args(argc, argv, "1:", &rb_path, &rb_options);
1076
1005
 
1077
- if (!NIL_P(rb_options)) {
1078
- Check_Type(rb_options, T_HASH);
1006
+ if (!NIL_P(rb_options))
1079
1007
  rugged_parse_merge_file_options(&opts, rb_options);
1080
- }
1081
1008
 
1082
1009
  Check_Type(rb_path, T_STRING);
1083
1010
 
@@ -1092,14 +1019,15 @@ static VALUE rb_git_merge_file(int argc, VALUE *argv, VALUE self)
1092
1019
  else
1093
1020
  rugged_exception_check(error);
1094
1021
 
1022
+ if (ours == NULL)
1023
+ rb_raise(rb_eRuntimeError, "The conflict does not have a stage 2 entry");
1024
+ else if (theirs == NULL)
1025
+ rb_raise(rb_eRuntimeError, "The conflict does not have a stage 3 entry");
1026
+
1095
1027
  error = git_merge_file_from_index(&merge_file_result, repo, ancestor, ours, theirs, &opts);
1096
1028
  rugged_exception_check(error);
1097
1029
 
1098
- rb_hash_aset(rb_result, CSTR2SYM("automergeable"), merge_file_result.automergeable ? Qtrue : Qfalse);
1099
- rb_hash_aset(rb_result, CSTR2SYM("path"), rb_path);
1100
- rb_hash_aset(rb_result, CSTR2SYM("filemode"), INT2FIX(merge_file_result.mode));
1101
- rb_hash_aset(rb_result, CSTR2SYM("data"), rb_str_new(merge_file_result.ptr, merge_file_result.len));
1102
-
1030
+ rb_result = rb_merge_file_result_fromC(&merge_file_result);
1103
1031
  git_merge_file_result_free(&merge_file_result);
1104
1032
 
1105
1033
  return rb_result;
@@ -29,8 +29,6 @@ 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, NULL, push_update_reference_cb, NULL}
33
-
34
32
  static int progress_cb(const char *str, int len, void *data)
35
33
  {
36
34
  struct rugged_remote_cb_payload *payload = data;
@@ -96,6 +94,27 @@ static int update_tips_cb(const char *refname, const git_oid *src, const git_oid
96
94
  return payload->exception ? GIT_ERROR : GIT_OK;
97
95
  }
98
96
 
97
+ static int certificate_check_cb(git_cert *cert, int valid, const char *host, void *data)
98
+ {
99
+ struct rugged_remote_cb_payload *payload = data;
100
+ VALUE args = rb_ary_new2(3);
101
+ VALUE ret;
102
+
103
+ if (NIL_P(payload->certificate_check))
104
+ return valid ? 0 : GIT_ECERTIFICATE;
105
+
106
+ rb_ary_push(args, payload->certificate_check);
107
+ rb_ary_push(args, valid ? Qtrue : Qfalse);
108
+ rb_ary_push(args, rb_str_new_utf8(host));
109
+
110
+ ret = rb_protect(rugged__block_yield_splat, args, &payload->exception);
111
+
112
+ if (payload->exception)
113
+ return GIT_ERROR;
114
+
115
+ return rugged_parse_bool(ret) ? GIT_OK : GIT_ECERTIFICATE;
116
+ }
117
+
99
118
  struct extract_cred_args
100
119
  {
101
120
  VALUE rb_callback;
@@ -155,11 +174,9 @@ static int credentials_cb(
155
174
  return payload->exception ? GIT_ERROR : GIT_OK;
156
175
  }
157
176
 
158
- #define CALLABLE_OR_RAISE(ret, rb_options, name) \
159
- do { \
160
- ret = rb_hash_aref(rb_options, CSTR2SYM(name)); \
161
- \
162
- if (!NIL_P(ret) && !rb_respond_to(ret, rb_intern("call"))) \
177
+ #define CALLABLE_OR_RAISE(ret, name) \
178
+ do { \
179
+ if (!rb_respond_to(ret, rb_intern("call"))) \
163
180
  rb_raise(rb_eArgError, "Expected a Proc or an object that responds to #call (:" name " )."); \
164
181
  } while (0);
165
182
 
@@ -168,16 +185,39 @@ void rugged_remote_init_callbacks_and_payload_from_options(
168
185
  git_remote_callbacks *callbacks,
169
186
  struct rugged_remote_cb_payload *payload)
170
187
  {
171
- git_remote_callbacks prefilled = RUGGED_REMOTE_CALLBACKS_INIT;
172
-
173
- prefilled.payload = payload;
174
- memcpy(callbacks, &prefilled, sizeof(git_remote_callbacks));
188
+ callbacks->payload = payload;
189
+ callbacks->push_update_reference = push_update_reference_cb;
175
190
 
176
191
  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");
192
+ payload->progress = rb_hash_aref(rb_options, CSTR2SYM("progress"));
193
+ if (!NIL_P(payload->progress)) {
194
+ CALLABLE_OR_RAISE(payload->progress, "progress");
195
+ callbacks->sideband_progress = progress_cb;
196
+ }
197
+
198
+ payload->credentials = rb_hash_aref(rb_options, CSTR2SYM("credentials"));
199
+ if (!NIL_P(payload->credentials)) {
200
+ CALLABLE_OR_RAISE(payload->credentials, "credentials");
201
+ callbacks->credentials = credentials_cb;
202
+ }
203
+
204
+ payload->certificate_check = rb_hash_aref(rb_options, CSTR2SYM("certificate_check"));
205
+ if (!NIL_P(payload->certificate_check)) {
206
+ CALLABLE_OR_RAISE(payload->certificate_check, "certificate_check");
207
+ callbacks->certificate_check = certificate_check_cb;
208
+ }
209
+
210
+ payload->transfer_progress = rb_hash_aref(rb_options, CSTR2SYM("transfer_progress"));
211
+ if (!NIL_P(payload->transfer_progress)) {
212
+ CALLABLE_OR_RAISE(payload->transfer_progress, "transfer_progress");
213
+ callbacks->transfer_progress = transfer_progress_cb;
214
+ }
215
+
216
+ payload->update_tips = rb_hash_aref(rb_options, CSTR2SYM("update_tips"));
217
+ if (!NIL_P(payload->update_tips)) {
218
+ CALLABLE_OR_RAISE(payload->update_tips, "update_tips");
219
+ callbacks->update_tips = update_tips_cb;
220
+ }
181
221
  }
182
222
  }
183
223
 
@@ -274,7 +314,7 @@ static VALUE rb_git_remote_ls(int argc, VALUE *argv, VALUE self)
274
314
  git_strarray custom_headers = {0};
275
315
  const git_remote_head **heads;
276
316
 
277
- struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
317
+ struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
278
318
 
279
319
  VALUE rb_options;
280
320
 
@@ -471,7 +511,7 @@ static VALUE rb_git_remote_check_connection(int argc, VALUE *argv, VALUE self)
471
511
  git_remote *remote;
472
512
  git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
473
513
  git_strarray custom_headers = {0};
474
- struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
514
+ struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
475
515
  VALUE rb_direction, rb_options;
476
516
  ID id_direction;
477
517
  int error, direction;
@@ -537,6 +577,11 @@ static VALUE rb_git_remote_check_connection(int argc, VALUE *argv, VALUE self)
537
577
  * A callback that will be executed each time a reference is updated locally. It will be
538
578
  * passed the +refname+, +old_oid+ and +new_oid+.
539
579
  *
580
+ * :certificate_check ::
581
+ * A callback that will be executed each time we validate a certificate using https. It
582
+ * will be passed the +valid+, +host_name+ and the callback should return a true/false to
583
+ * indicate if the certificate has been validated.
584
+ *
540
585
  * :message ::
541
586
  * The message to insert into the reflogs. Defaults to "fetch".
542
587
  *
@@ -559,7 +604,7 @@ static VALUE rb_git_remote_fetch(int argc, VALUE *argv, VALUE self)
559
604
  git_strarray refspecs;
560
605
  git_fetch_options opts = GIT_FETCH_OPTIONS_INIT;
561
606
  const git_transfer_progress *stats;
562
- struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
607
+ struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
563
608
 
564
609
  char *log_message = NULL;
565
610
  int error;
@@ -650,7 +695,7 @@ static VALUE rb_git_remote_push(int argc, VALUE *argv, VALUE self)
650
695
 
651
696
  int error = 0;
652
697
 
653
- struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, rb_hash_new(), 0 };
698
+ struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, rb_hash_new(), 0 };
654
699
 
655
700
  rb_scan_args(argc, argv, "01:", &rb_refspecs, &rb_options);
656
701
 
@@ -485,7 +485,7 @@ static VALUE rb_git_repo_clone_at(int argc, VALUE *argv, VALUE klass)
485
485
  {
486
486
  VALUE url, local_path, rb_options_hash;
487
487
  git_clone_options options = GIT_CLONE_OPTIONS_INIT;
488
- struct rugged_remote_cb_payload remote_payload = { Qnil, Qnil, Qnil, Qnil, 0 };
488
+ struct rugged_remote_cb_payload remote_payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
489
489
  git_repository *repo;
490
490
  int error;
491
491
 
@@ -1,3 +1,3 @@
1
1
  module Rugged
2
- Version = VERSION = '0.25.0b8'
2
+ Version = VERSION = '0.25.0b9'
3
3
  end
@@ -20,6 +20,7 @@ SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Mo
20
20
 
21
21
  INCLUDE(CheckLibraryExists)
22
22
  INCLUDE(CheckFunctionExists)
23
+ INCLUDE(CheckSymbolExists)
23
24
  INCLUDE(CheckStructHasMember)
24
25
  INCLUDE(AddCFlagIfSupported)
25
26
  INCLUDE(FindPkgConfig)
@@ -286,6 +287,7 @@ ELSE ()
286
287
  IF (CURL_FOUND)
287
288
  ADD_DEFINITIONS(-DGIT_CURL)
288
289
  INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIRS})
290
+ LINK_DIRECTORIES(${CURL_LIBRARY_DIRS})
289
291
  LINK_LIBRARIES(${CURL_LIBRARIES})
290
292
  LIST(APPEND LIBGIT2_PC_LIBS ${CURL_LDFLAGS})
291
293
  ENDIF()
@@ -506,6 +508,11 @@ ELSE ()
506
508
  ENDIF ()
507
509
  ENDIF()
508
510
 
511
+ CHECK_SYMBOL_EXISTS(regcomp_l "xlocale.h" HAVE_REGCOMP_L)
512
+ IF (HAVE_REGCOMP_L)
513
+ ADD_DEFINITIONS(-DHAVE_REGCOMP_L)
514
+ ENDIF ()
515
+
509
516
  CHECK_FUNCTION_EXISTS(futimens HAVE_FUTIMENS)
510
517
  IF (HAVE_FUTIMENS)
511
518
  ADD_DEFINITIONS(-DHAVE_FUTIMENS)
@@ -490,6 +490,14 @@ typedef struct {
490
490
 
491
491
  /** Structure describing the binary contents of a diff. */
492
492
  typedef struct {
493
+ /**
494
+ * Whether there is data in this binary structure or not. If this
495
+ * is `1`, then this was produced and included binary content. If
496
+ * this is `0` then this was generated knowing only that a binary
497
+ * file changed but without providing the data, probably from a patch
498
+ * that said `Binary files a/file.txt and b/file.txt differ`.
499
+ */
500
+ unsigned int contains_data;
493
501
  git_diff_binary_file old_file; /**< The contents of the old file. */
494
502
  git_diff_binary_file new_file; /**< The contents of the new file. */
495
503
  } git_diff_binary;
@@ -0,0 +1,31 @@
1
+ /*
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+ #ifndef INCLUDE_git_time_h__
8
+ #define INCLUDE_git_time_h__
9
+
10
+ #include "git2/common.h"
11
+
12
+ GIT_BEGIN_DECL
13
+
14
+ /**
15
+ * Return a monotonic time value, useful for measuring running time
16
+ * and setting up timeouts.
17
+ *
18
+ * The returned value is an arbitrary point in time -- it can only be
19
+ * used when comparing it to another `git_time_monotonic` call.
20
+ *
21
+ * The time is returned in seconds, with a decimal fraction that differs
22
+ * on accuracy based on the underlying system, but should be least
23
+ * accurate to Nanoseconds.
24
+ *
25
+ * This function cannot fail.
26
+ */
27
+ GIT_EXTERN(double) git_time_monotonic(void);
28
+
29
+ GIT_END_DECL
30
+ #endif
31
+
@@ -291,7 +291,15 @@ static int apply_binary(
291
291
  git_patch *patch)
292
292
  {
293
293
  git_buf reverse = GIT_BUF_INIT;
294
- int error;
294
+ int error = 0;
295
+
296
+ if (!patch->binary.contains_data) {
297
+ error = apply_err("patch does not contain binary data");
298
+ goto done;
299
+ }
300
+
301
+ if (!patch->binary.old_file.datalen && !patch->binary.new_file.datalen)
302
+ goto done;
295
303
 
296
304
  /* first, apply the new_file delta to the given source */
297
305
  if ((error = apply_binary_delta(out, source, source_len,
@@ -212,6 +212,10 @@ static bool checkout_is_workdir_modified(
212
212
  if (baseitem->size && wditem->file_size != baseitem->size)
213
213
  return true;
214
214
 
215
+ /* if the workdir item is a directory, it cannot be a modified file */
216
+ if (S_ISDIR(wditem->mode))
217
+ return false;
218
+
215
219
  if (git_diff__oid_for_entry(&oid, data->diff, wditem, wditem->mode, NULL) < 0)
216
220
  return false;
217
221
 
@@ -478,7 +478,7 @@ int git_config_iterator_glob_new(git_config_iterator **out, const git_config *cf
478
478
  iter = git__calloc(1, sizeof(all_iter));
479
479
  GITERR_CHECK_ALLOC(iter);
480
480
 
481
- if ((result = regcomp(&iter->regex, regexp, REG_EXTENDED)) != 0) {
481
+ if ((result = p_regcomp(&iter->regex, regexp, REG_EXTENDED)) != 0) {
482
482
  giterr_set_regex(&iter->regex, result);
483
483
  git__free(iter);
484
484
  return -1;
@@ -512,7 +512,7 @@ int git_config_backend_foreach_match(
512
512
  int error = 0;
513
513
 
514
514
  if (regexp != NULL) {
515
- if ((error = regcomp(&regex, regexp, REG_EXTENDED)) != 0) {
515
+ if ((error = p_regcomp(&regex, regexp, REG_EXTENDED)) != 0) {
516
516
  giterr_set_regex(&regex, error);
517
517
  regfree(&regex);
518
518
  return -1;
@@ -1003,7 +1003,7 @@ int git_config_multivar_iterator_new(git_config_iterator **out, const git_config
1003
1003
  goto on_error;
1004
1004
 
1005
1005
  if (regexp != NULL) {
1006
- error = regcomp(&iter->regex, regexp, REG_EXTENDED);
1006
+ error = p_regcomp(&iter->regex, regexp, REG_EXTENDED);
1007
1007
  if (error != 0) {
1008
1008
  giterr_set_regex(&iter->regex, error);
1009
1009
  error = -1;
@@ -570,7 +570,7 @@ static int config_set_multivar(
570
570
  if ((result = git_config__normalize_name(name, &key)) < 0)
571
571
  return result;
572
572
 
573
- result = regcomp(&preg, regexp, REG_EXTENDED);
573
+ result = p_regcomp(&preg, regexp, REG_EXTENDED);
574
574
  if (result != 0) {
575
575
  giterr_set_regex(&preg, result);
576
576
  result = -1;
@@ -657,7 +657,7 @@ static int config_delete_multivar(git_config_backend *cfg, const char *name, con
657
657
 
658
658
  refcounted_strmap_free(map);
659
659
 
660
- result = regcomp(&preg, regexp, REG_EXTENDED);
660
+ result = p_regcomp(&preg, regexp, REG_EXTENDED);
661
661
  if (result != 0) {
662
662
  giterr_set_regex(&preg, result);
663
663
  result = -1;
@@ -1957,4 +1957,3 @@ done:
1957
1957
  git_buf_free(&reader->buffer);
1958
1958
  return result;
1959
1959
  }
1960
-
@@ -114,7 +114,7 @@ static int diff_driver_add_patterns(
114
114
  if (error < 0)
115
115
  break;
116
116
 
117
- if ((error = regcomp(&pat->re, buf.ptr, regex_flags)) != 0) {
117
+ if ((error = p_regcomp(&pat->re, buf.ptr, regex_flags)) != 0) {
118
118
  /*
119
119
  * TODO: issue a warning
120
120
  */
@@ -210,7 +210,7 @@ static int git_diff_driver_builtin(
210
210
  goto done;
211
211
 
212
212
  if (ddef->words &&
213
- (error = regcomp(
213
+ (error = p_regcomp(
214
214
  &drv->word_pattern, ddef->words, ddef->flags | REG_EXTENDED)))
215
215
  {
216
216
  error = giterr_set_regex(&drv->word_pattern, error);
@@ -314,7 +314,7 @@ static int git_diff_driver_load(
314
314
  goto done;
315
315
  if (!ce || !ce->value)
316
316
  /* no diff.<driver>.wordregex, so just continue */;
317
- else if (!(error = regcomp(&drv->word_pattern, ce->value, REG_EXTENDED)))
317
+ else if (!(error = p_regcomp(&drv->word_pattern, ce->value, REG_EXTENDED)))
318
318
  found_driver = true;
319
319
  else {
320
320
  /* TODO: warn about bad regex instead of failure */
@@ -519,4 +519,3 @@ void git_diff_find_context_clear(git_diff_find_context_payload *payload)
519
519
  payload->driver = NULL;
520
520
  }
521
521
  }
522
-
@@ -500,7 +500,6 @@ static int diff_print_patch_file_binary_noshow(
500
500
  &new_path, new_pfx, delta->new_file.path)) < 0)
501
501
  goto done;
502
502
 
503
-
504
503
  pi->line.num_lines = 1;
505
504
  error = diff_delta_format_with_paths(
506
505
  pi->buf, delta, "Binary files %s and %s differ\n",
@@ -521,13 +520,13 @@ static int diff_print_patch_file_binary(
521
520
  size_t pre_binary_size;
522
521
  int error;
523
522
 
524
- if ((pi->flags & GIT_DIFF_SHOW_BINARY) == 0)
523
+ if (delta->status == GIT_DELTA_UNMODIFIED)
524
+ return 0;
525
+
526
+ if ((pi->flags & GIT_DIFF_SHOW_BINARY) == 0 || !binary->contains_data)
525
527
  return diff_print_patch_file_binary_noshow(
526
528
  pi, delta, old_pfx, new_pfx);
527
529
 
528
- if (binary->new_file.datalen == 0 && binary->old_file.datalen == 0)
529
- return 0;
530
-
531
530
  pre_binary_size = pi->buf->size;
532
531
  git_buf_printf(pi->buf, "GIT binary patch\n");
533
532
  pi->line.num_lines++;
@@ -563,8 +562,11 @@ static int diff_print_patch_file(
563
562
  bool binary = (delta->flags & GIT_DIFF_FLAG_BINARY) ||
564
563
  (pi->flags & GIT_DIFF_FORCE_BINARY);
565
564
  bool show_binary = !!(pi->flags & GIT_DIFF_SHOW_BINARY);
566
- int id_strlen = binary && show_binary ?
567
- GIT_OID_HEXSZ : pi->id_strlen;
565
+ int id_strlen = pi->id_strlen;
566
+
567
+ if (binary && show_binary)
568
+ id_strlen = delta->old_file.id_abbrev ? delta->old_file.id_abbrev :
569
+ delta->new_file.id_abbrev;
568
570
 
569
571
  GIT_UNUSED(progress);
570
572
 
@@ -17,6 +17,9 @@ int git_patch__invoke_callbacks(
17
17
  if (file_cb)
18
18
  error = file_cb(patch->delta, 0, payload);
19
19
 
20
+ if (error)
21
+ return error;
22
+
20
23
  if ((patch->delta->flags & GIT_DIFF_FLAG_BINARY) != 0) {
21
24
  if (binary_cb)
22
25
  error = binary_cb(patch->delta, &patch->binary, payload);
@@ -342,7 +342,7 @@ done:
342
342
 
343
343
  static int diff_binary(git_patch_generated_output *output, git_patch_generated *patch)
344
344
  {
345
- git_diff_binary binary = {{0}};
345
+ git_diff_binary binary = {0};
346
346
  const char *old_data = patch->ofile.map.data;
347
347
  const char *new_data = patch->nfile.map.data;
348
348
  size_t old_len = patch->ofile.map.len,
@@ -352,6 +352,8 @@ static int diff_binary(git_patch_generated_output *output, git_patch_generated *
352
352
  /* Only load contents if the user actually wants to diff
353
353
  * binary files. */
354
354
  if (patch->base.diff_opts.flags & GIT_DIFF_SHOW_BINARY) {
355
+ binary.contains_data = 1;
356
+
355
357
  /* Create the old->new delta (as the "new" side of the patch),
356
358
  * and the new->old delta (as the "old" side)
357
359
  */
@@ -492,8 +494,17 @@ static int diff_single_generate(patch_generated_with_delta *pd, git_xdiff_output
492
494
  patch_generated_init_common(patch);
493
495
 
494
496
  if (pd->delta.status == GIT_DELTA_UNMODIFIED &&
495
- !(patch->ofile.opts_flags & GIT_DIFF_INCLUDE_UNMODIFIED))
497
+ !(patch->ofile.opts_flags & GIT_DIFF_INCLUDE_UNMODIFIED)) {
498
+
499
+ /* Even empty patches are flagged as binary, and even though
500
+ * there's no difference, we flag this as "containing data"
501
+ * (the data is known to be empty, as opposed to wholly unknown).
502
+ */
503
+ if (patch->base.diff_opts.flags & GIT_DIFF_SHOW_BINARY)
504
+ patch->base.binary.contains_data = 1;
505
+
496
506
  return error;
507
+ }
497
508
 
498
509
  error = patch_generated_invoke_file_callback(patch, (git_patch_generated_output *)xo);
499
510
 
@@ -74,8 +74,8 @@ static int parse_advance_expected(
74
74
  return 0;
75
75
  }
76
76
 
77
- #define parse_advance_expected_s(ctx, str) \
78
- parse_advance_expected(ctx, str, sizeof(str) - 1)
77
+ #define parse_advance_expected_str(ctx, str) \
78
+ parse_advance_expected(ctx, str, strlen(str))
79
79
 
80
80
  static int parse_advance_ws(git_patch_parse_ctx *ctx)
81
81
  {
@@ -220,7 +220,7 @@ static int parse_header_git_index(
220
220
  {
221
221
  if (parse_header_oid(&patch->base.delta->old_file.id,
222
222
  &patch->base.delta->old_file.id_abbrev, ctx) < 0 ||
223
- parse_advance_expected_s(ctx, "..") < 0 ||
223
+ parse_advance_expected_str(ctx, "..") < 0 ||
224
224
  parse_header_oid(&patch->base.delta->new_file.id,
225
225
  &patch->base.delta->new_file.id_abbrev, ctx) < 0)
226
226
  return -1;
@@ -336,7 +336,7 @@ static int parse_header_percent(uint16_t *out, git_patch_parse_ctx *ctx)
336
336
 
337
337
  parse_advance_chars(ctx, (end - ctx->line));
338
338
 
339
- if (parse_advance_expected_s(ctx, "%") < 0)
339
+ if (parse_advance_expected_str(ctx, "%") < 0)
340
340
  return -1;
341
341
 
342
342
  if (val > 100)
@@ -379,6 +379,7 @@ static const header_git_op header_git_ops[] = {
379
379
  { "diff --git ", NULL },
380
380
  { "@@ -", NULL },
381
381
  { "GIT binary patch", NULL },
382
+ { "Binary files ", NULL },
382
383
  { "--- ", parse_header_git_oldpath },
383
384
  { "+++ ", parse_header_git_newpath },
384
385
  { "index ", parse_header_git_index },
@@ -404,7 +405,7 @@ static int parse_header_git(
404
405
  int error = 0;
405
406
 
406
407
  /* Parse the diff --git line */
407
- if (parse_advance_expected_s(ctx, "diff --git ") < 0)
408
+ if (parse_advance_expected_str(ctx, "diff --git ") < 0)
408
409
  return parse_err("corrupt git diff header at line %d", ctx->line_num);
409
410
 
410
411
  if (parse_header_path(&patch->header_old_path, ctx) < 0)
@@ -443,7 +444,7 @@ static int parse_header_git(
443
444
  goto done;
444
445
 
445
446
  parse_advance_ws(ctx);
446
- parse_advance_expected_s(ctx, "\n");
447
+ parse_advance_expected_str(ctx, "\n");
447
448
 
448
449
  if (ctx->line_len > 0) {
449
450
  error = parse_err("trailing data at line %d", ctx->line_num);
@@ -505,27 +506,27 @@ static int parse_hunk_header(
505
506
  hunk->hunk.old_lines = 1;
506
507
  hunk->hunk.new_lines = 1;
507
508
 
508
- if (parse_advance_expected_s(ctx, "@@ -") < 0 ||
509
+ if (parse_advance_expected_str(ctx, "@@ -") < 0 ||
509
510
  parse_int(&hunk->hunk.old_start, ctx) < 0)
510
511
  goto fail;
511
512
 
512
513
  if (ctx->line_len > 0 && ctx->line[0] == ',') {
513
- if (parse_advance_expected_s(ctx, ",") < 0 ||
514
+ if (parse_advance_expected_str(ctx, ",") < 0 ||
514
515
  parse_int(&hunk->hunk.old_lines, ctx) < 0)
515
516
  goto fail;
516
517
  }
517
518
 
518
- if (parse_advance_expected_s(ctx, " +") < 0 ||
519
+ if (parse_advance_expected_str(ctx, " +") < 0 ||
519
520
  parse_int(&hunk->hunk.new_start, ctx) < 0)
520
521
  goto fail;
521
522
 
522
523
  if (ctx->line_len > 0 && ctx->line[0] == ',') {
523
- if (parse_advance_expected_s(ctx, ",") < 0 ||
524
+ if (parse_advance_expected_str(ctx, ",") < 0 ||
524
525
  parse_int(&hunk->hunk.new_lines, ctx) < 0)
525
526
  goto fail;
526
527
  }
527
528
 
528
- if (parse_advance_expected_s(ctx, " @@") < 0)
529
+ if (parse_advance_expected_str(ctx, " @@") < 0)
529
530
  goto fail;
530
531
 
531
532
  parse_advance_line(ctx);
@@ -782,7 +783,7 @@ static int parse_patch_binary(
782
783
  {
783
784
  int error;
784
785
 
785
- if (parse_advance_expected_s(ctx, "GIT binary patch") < 0 ||
786
+ if (parse_advance_expected_str(ctx, "GIT binary patch") < 0 ||
786
787
  parse_advance_nl(ctx) < 0)
787
788
  return parse_err("corrupt git binary header at line %d", ctx->line_num);
788
789
 
@@ -804,6 +805,24 @@ static int parse_patch_binary(
804
805
  return parse_err("corrupt git binary patch separator at line %d",
805
806
  ctx->line_num);
806
807
 
808
+ patch->base.binary.contains_data = 1;
809
+ patch->base.delta->flags |= GIT_DIFF_FLAG_BINARY;
810
+ return 0;
811
+ }
812
+
813
+ static int parse_patch_binary_nodata(
814
+ git_patch_parsed *patch,
815
+ git_patch_parse_ctx *ctx)
816
+ {
817
+ if (parse_advance_expected_str(ctx, "Binary files ") < 0 ||
818
+ parse_advance_expected_str(ctx, patch->header_old_path) < 0 ||
819
+ parse_advance_expected_str(ctx, " and ") < 0 ||
820
+ parse_advance_expected_str(ctx, patch->header_new_path) < 0 ||
821
+ parse_advance_expected_str(ctx, " differ") < 0 ||
822
+ parse_advance_nl(ctx) < 0)
823
+ return parse_err("corrupt git binary header at line %d", ctx->line_num);
824
+
825
+ patch->base.binary.contains_data = 0;
807
826
  patch->base.delta->flags |= GIT_DIFF_FLAG_BINARY;
808
827
  return 0;
809
828
  }
@@ -840,6 +859,8 @@ static int parse_patch_body(
840
859
  {
841
860
  if (parse_ctx_contains_s(ctx, "GIT binary patch"))
842
861
  return parse_patch_binary(patch, ctx);
862
+ else if (parse_ctx_contains_s(ctx, "Binary files "))
863
+ return parse_patch_binary_nodata(patch, ctx);
843
864
  else
844
865
  return parse_patch_hunks(patch, ctx);
845
866
  }
@@ -53,8 +53,10 @@ int git_refspec__parse(git_refspec *refspec, const char *input, bool is_fetch)
53
53
 
54
54
  if (rhs) {
55
55
  size_t rlen = strlen(++rhs);
56
- is_glob = (1 <= rlen && strchr(rhs, '*'));
57
- refspec->dst = git__strndup(rhs, rlen);
56
+ if (rlen || !is_fetch) {
57
+ is_glob = (1 <= rlen && strchr(rhs, '*'));
58
+ refspec->dst = git__strndup(rhs, rlen);
59
+ }
58
60
  }
59
61
 
60
62
  llen = (rhs ? (size_t)(rhs - lhs - 1) : strlen(lhs));
@@ -50,7 +50,7 @@ static int build_regex(regex_t *regex, const char *pattern)
50
50
  return GIT_EINVALIDSPEC;
51
51
  }
52
52
 
53
- error = regcomp(regex, pattern, REG_EXTENDED);
53
+ error = p_regcomp(regex, pattern, REG_EXTENDED);
54
54
  if (!error)
55
55
  return 0;
56
56
 
@@ -80,4 +80,14 @@ GIT_INLINE(int) p_futimes(int f, const struct p_timeval t[2])
80
80
  # define p_futimes futimes
81
81
  #endif
82
82
 
83
+ #ifdef HAVE_REGCOMP_L
84
+ #include <xlocale.h>
85
+ GIT_INLINE(int) p_regcomp(regex_t *preg, const char *pattern, int cflags)
86
+ {
87
+ return regcomp_l(preg, pattern, cflags, (locale_t) 0);
88
+ }
89
+ #else
90
+ # define p_regcomp regcomp
91
+ #endif
92
+
83
93
  #endif
@@ -783,6 +783,11 @@ int git__utf8_iterate(const uint8_t *str, int str_len, int32_t *dst)
783
783
  return length;
784
784
  }
785
785
 
786
+ double git_time_monotonic(void)
787
+ {
788
+ return git__timer();
789
+ }
790
+
786
791
  #ifdef GIT_WIN32
787
792
  int git__getenv(git_buf *out, const char *name)
788
793
  {
@@ -57,4 +57,7 @@ extern int p_lstat_posixly(const char *filename, struct stat *buf);
57
57
  extern struct tm * p_localtime_r(const time_t *timer, struct tm *result);
58
58
  extern struct tm * p_gmtime_r(const time_t *timer, struct tm *result);
59
59
 
60
+ /* Use the bundled regcomp */
61
+ #define p_regcomp regcomp
62
+
60
63
  #endif
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rugged
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.25.0b8
4
+ version: 0.25.0b9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Chacon
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-09-02 00:00:00.000000000 Z
12
+ date: 2016-10-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler
@@ -231,6 +231,7 @@ files:
231
231
  - vendor/libgit2/include/git2/sys/remote.h
232
232
  - vendor/libgit2/include/git2/sys/repository.h
233
233
  - vendor/libgit2/include/git2/sys/stream.h
234
+ - vendor/libgit2/include/git2/sys/time.h
234
235
  - vendor/libgit2/include/git2/sys/transport.h
235
236
  - vendor/libgit2/include/git2/tag.h
236
237
  - vendor/libgit2/include/git2/trace.h