rugged 0.24.0b12 → 0.24.0b13

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.
@@ -79,6 +79,7 @@ static int curls_certificate(git_cert **out, git_stream *stream)
79
79
  for (slist = certinfo->certinfo[0]; slist; slist = slist->next) {
80
80
  char *str = git__strdup(slist->data);
81
81
  GITERR_CHECK_ALLOC(str);
82
+ git_vector_insert(&strings, str);
82
83
  }
83
84
 
84
85
  /* Copy the contents of the vector into a strarray so we can expose them */
@@ -207,11 +208,14 @@ int git_curl_stream_new(git_stream **out, const char *host, const char *port)
207
208
  handle = curl_easy_init();
208
209
  if (handle == NULL) {
209
210
  giterr_set(GITERR_NET, "failed to create curl handle");
211
+ git__free(st);
210
212
  return -1;
211
213
  }
212
214
 
213
- if ((error = git__strtol32(&iport, port, NULL, 10)) < 0)
215
+ if ((error = git__strtol32(&iport, port, NULL, 10)) < 0) {
216
+ git__free(st);
214
217
  return error;
218
+ }
215
219
 
216
220
  curl_easy_setopt(handle, CURLOPT_URL, host);
217
221
  curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, st->curl_error);
@@ -1371,7 +1371,7 @@ int git_diff_tree_to_index(
1371
1371
 
1372
1372
  DIFF_FROM_ITERATORS(
1373
1373
  git_iterator_for_tree(&a, old_tree, &a_opts), iflag,
1374
- git_iterator_for_index(&b, index, &b_opts), iflag
1374
+ git_iterator_for_index(&b, repo, index, &b_opts), iflag
1375
1375
  );
1376
1376
 
1377
1377
  /* if index is in case-insensitive order, re-sort deltas to match */
@@ -1395,7 +1395,7 @@ int git_diff_index_to_workdir(
1395
1395
  return error;
1396
1396
 
1397
1397
  DIFF_FROM_ITERATORS(
1398
- git_iterator_for_index(&a, index, &a_opts),
1398
+ git_iterator_for_index(&a, repo, index, &a_opts),
1399
1399
  GIT_ITERATOR_INCLUDE_CONFLICTS,
1400
1400
 
1401
1401
  git_iterator_for_workdir(&b, repo, index, NULL, &b_opts),
@@ -1472,8 +1472,8 @@ int git_diff_index_to_index(
1472
1472
  assert(diff && old_index && new_index);
1473
1473
 
1474
1474
  DIFF_FROM_ITERATORS(
1475
- git_iterator_for_index(&a, old_index, &a_opts), GIT_ITERATOR_DONT_IGNORE_CASE,
1476
- git_iterator_for_index(&b, new_index, &b_opts), GIT_ITERATOR_DONT_IGNORE_CASE
1475
+ git_iterator_for_index(&a, repo, old_index, &a_opts), GIT_ITERATOR_DONT_IGNORE_CASE,
1476
+ git_iterator_for_index(&b, repo, new_index, &b_opts), GIT_ITERATOR_DONT_IGNORE_CASE
1477
1477
  );
1478
1478
 
1479
1479
  /* if index is in case-insensitive order, re-sort deltas to match */
@@ -2907,8 +2907,8 @@ int git_index_read_index(
2907
2907
 
2908
2908
  opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
2909
2909
 
2910
- if ((error = git_iterator_for_index(&index_iterator, index, &opts)) < 0 ||
2911
- (error = git_iterator_for_index(&new_iterator, (git_index *)new_index, &opts)) < 0)
2910
+ if ((error = git_iterator_for_index(&index_iterator, git_index_owner(index), index, &opts)) < 0 ||
2911
+ (error = git_iterator_for_index(&new_iterator, git_index_owner(new_index), (git_index *)new_index, &opts)) < 0)
2912
2912
  goto done;
2913
2913
 
2914
2914
  if (((error = git_iterator_current(&old_entry, index_iterator)) < 0 &&
@@ -1080,6 +1080,7 @@ static void index_iterator__free(git_iterator *self)
1080
1080
 
1081
1081
  int git_iterator_for_index(
1082
1082
  git_iterator **iter,
1083
+ git_repository *repo,
1083
1084
  git_index *index,
1084
1085
  git_iterator_options *options)
1085
1086
  {
@@ -1093,7 +1094,7 @@ int git_iterator_for_index(
1093
1094
  }
1094
1095
  ii->index = index;
1095
1096
 
1096
- ITERATOR_BASE_INIT(ii, index, INDEX, git_index_owner(index));
1097
+ ITERATOR_BASE_INIT(ii, index, INDEX, repo);
1097
1098
 
1098
1099
  if ((error = iterator__update_ignore_case((git_iterator *)ii, options ? options->flags : 0)) < 0) {
1099
1100
  git_iterator_free((git_iterator *)ii);
@@ -2071,7 +2072,7 @@ int git_iterator_advance_over_with_status(
2071
2072
 
2072
2073
  if (!error)
2073
2074
  continue;
2074
-
2075
+
2075
2076
  else if (error == GIT_ENOTFOUND) {
2076
2077
  /* we entered this directory only hoping to find child matches to
2077
2078
  * our pathlist (eg, this is `foo` and we had a pathlist entry for
@@ -95,6 +95,7 @@ extern int git_iterator_for_tree(
95
95
  */
96
96
  extern int git_iterator_for_index(
97
97
  git_iterator **out,
98
+ git_repository *repo,
98
99
  git_index *index,
99
100
  git_iterator_options *options);
100
101
 
@@ -1985,9 +1985,6 @@ static int create_virtual_base(
1985
1985
  git_index *index = NULL;
1986
1986
  git_merge_options virtual_opts = GIT_MERGE_OPTIONS_INIT;
1987
1987
 
1988
- result = git__calloc(1, sizeof(git_annotated_commit));
1989
- GITERR_CHECK_ALLOC(result);
1990
-
1991
1988
  /* Conflicts in the merge base creation do not propagate to conflicts
1992
1989
  * in the result; the conflicted base will act as the common ancestor.
1993
1990
  */
@@ -2001,6 +1998,8 @@ static int create_virtual_base(
2001
1998
  recursion_level + 1, &virtual_opts)) < 0)
2002
1999
  return -1;
2003
2000
 
2001
+ result = git__calloc(1, sizeof(git_annotated_commit));
2002
+ GITERR_CHECK_ALLOC(result);
2004
2003
  result->type = GIT_ANNOTATED_COMMIT_VIRTUAL;
2005
2004
  result->index = index;
2006
2005
 
@@ -2084,9 +2083,9 @@ static int iterator_for_annotated_commit(
2084
2083
  opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
2085
2084
 
2086
2085
  if (commit == NULL) {
2087
- error = git_iterator_for_nothing(out, &opts);
2086
+ error = git_iterator_for_nothing(out, &opts);
2088
2087
  } else if (commit->type == GIT_ANNOTATED_COMMIT_VIRTUAL) {
2089
- error = git_iterator_for_index(out, commit->index, &opts);
2088
+ error = git_iterator_for_index(out, git_index_owner(commit->index), commit->index, &opts);
2090
2089
  } else {
2091
2090
  if (!commit->tree &&
2092
2091
  (error = git_commit_tree(&commit->tree, commit->commit)) < 0)
@@ -2428,7 +2427,7 @@ static int write_merge_msg(
2428
2427
  assert(repo && heads);
2429
2428
 
2430
2429
  entries = git__calloc(heads_len, sizeof(struct merge_msg_entry));
2431
- GITERR_CHECK_ALLOC(entries);
2430
+ GITERR_CHECK_ALLOC(entries);
2432
2431
 
2433
2432
  if (git_vector_init(&matching, heads_len, NULL) < 0) {
2434
2433
  git__free(entries);
@@ -2482,7 +2481,7 @@ static int write_merge_msg(
2482
2481
 
2483
2482
  if (matching.length)
2484
2483
  sep =',';
2485
-
2484
+
2486
2485
  if ((error = merge_msg_entries(&matching, entries, heads_len, msg_entry_is_tag)) < 0 ||
2487
2486
  (error = merge_msg_write_tags(&file, &matching, sep)) < 0)
2488
2487
  goto cleanup;
@@ -2683,8 +2682,8 @@ static int merge_check_index(size_t *conflicts, git_repository *repo, git_index
2683
2682
  iter_opts.pathlist.strings = (char **)staged_paths.contents;
2684
2683
  iter_opts.pathlist.count = staged_paths.length;
2685
2684
 
2686
- if ((error = git_iterator_for_index(&iter_repo, index_repo, &iter_opts)) < 0 ||
2687
- (error = git_iterator_for_index(&iter_new, index_new, &iter_opts)) < 0 ||
2685
+ if ((error = git_iterator_for_index(&iter_repo, repo, index_repo, &iter_opts)) < 0 ||
2686
+ (error = git_iterator_for_index(&iter_new, repo, index_new, &iter_opts)) < 0 ||
2688
2687
  (error = git_diff__from_iterators(&index_diff_list, repo, iter_repo, iter_new, &opts)) < 0)
2689
2688
  goto done;
2690
2689
 
@@ -2760,7 +2759,7 @@ int git_merge__check_result(git_repository *repo, git_index *index_new)
2760
2759
 
2761
2760
  if ((error = git_repository_head_tree(&head_tree, repo)) < 0 ||
2762
2761
  (error = git_iterator_for_tree(&iter_head, head_tree, &iter_opts)) < 0 ||
2763
- (error = git_iterator_for_index(&iter_new, index_new, &iter_opts)) < 0 ||
2762
+ (error = git_iterator_for_index(&iter_new, repo, index_new, &iter_opts)) < 0 ||
2764
2763
  (error = git_diff__from_iterators(&merged_list, repo, iter_head, iter_new, &opts)) < 0)
2765
2764
  goto done;
2766
2765
 
@@ -91,7 +91,7 @@ static unsigned name_hash(const char *name)
91
91
  static int packbuilder_config(git_packbuilder *pb)
92
92
  {
93
93
  git_config *config;
94
- int ret;
94
+ int ret = 0;
95
95
  int64_t val;
96
96
 
97
97
  if ((ret = git_repository_config_snapshot(&config, pb->repo)) < 0)
@@ -100,8 +100,10 @@ static int packbuilder_config(git_packbuilder *pb)
100
100
  #define config_get(KEY,DST,DFLT) do { \
101
101
  ret = git_config_get_int64(&val, config, KEY); \
102
102
  if (!ret) (DST) = val; \
103
- else if (ret == GIT_ENOTFOUND) (DST) = (DFLT); \
104
- else if (ret < 0) return -1; } while (0)
103
+ else if (ret == GIT_ENOTFOUND) { \
104
+ (DST) = (DFLT); \
105
+ ret = 0; \
106
+ } else if (ret < 0) goto out; } while (0)
105
107
 
106
108
  config_get("pack.deltaCacheSize", pb->max_delta_cache_size,
107
109
  GIT_PACK_DELTA_CACHE_SIZE);
@@ -113,9 +115,10 @@ static int packbuilder_config(git_packbuilder *pb)
113
115
 
114
116
  #undef config_get
115
117
 
118
+ out:
116
119
  git_config_free(config);
117
120
 
118
- return 0;
121
+ return ret;
119
122
  }
120
123
 
121
124
  int git_packbuilder_new(git_packbuilder **out, git_repository *repo)
@@ -605,6 +608,7 @@ static git_pobject **compute_write_order(git_packbuilder *pb)
605
608
  }
606
609
 
607
610
  if (wo_end != pb->nr_objects) {
611
+ git__free(wo);
608
612
  giterr_set(GITERR_INVALID, "invalid write order");
609
613
  return NULL;
610
614
  }
@@ -21,7 +21,7 @@ GIT__USE_OIDMAP
21
21
 
22
22
  static int packfile_open(struct git_pack_file *p);
23
23
  static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n);
24
- int packfile_unpack_compressed(
24
+ static int packfile_unpack_compressed(
25
25
  git_rawobj *obj,
26
26
  struct git_pack_file *p,
27
27
  git_mwindow **w_curs,
@@ -790,7 +790,6 @@ int git_packfile_stream_open(git_packfile_stream *obj, struct git_pack_file *p,
790
790
  obj->zstream.next_out = Z_NULL;
791
791
  st = inflateInit(&obj->zstream);
792
792
  if (st != Z_OK) {
793
- git__free(obj);
794
793
  giterr_set(GITERR_ZLIB, "failed to init packfile stream");
795
794
  return -1;
796
795
  }
@@ -843,7 +842,7 @@ void git_packfile_stream_free(git_packfile_stream *obj)
843
842
  inflateEnd(&obj->zstream);
844
843
  }
845
844
 
846
- int packfile_unpack_compressed(
845
+ static int packfile_unpack_compressed(
847
846
  git_rawobj *obj,
848
847
  struct git_pack_file *p,
849
848
  git_mwindow **w_curs,
@@ -138,13 +138,6 @@ int git_packfile_resolve_header(
138
138
  git_off_t offset);
139
139
 
140
140
  int git_packfile_unpack(git_rawobj *obj, struct git_pack_file *p, git_off_t *obj_offset);
141
- int packfile_unpack_compressed(
142
- git_rawobj *obj,
143
- struct git_pack_file *p,
144
- git_mwindow **w_curs,
145
- git_off_t *curpos,
146
- size_t size,
147
- git_otype type);
148
141
 
149
142
  int git_packfile_stream_open(git_packfile_stream *obj, struct git_pack_file *p, git_off_t curpos);
150
143
  ssize_t git_packfile_stream_read(git_packfile_stream *obj, void *buffer, size_t len);
@@ -550,7 +550,7 @@ int git_pathspec_match_index(
550
550
 
551
551
  iter_opts.flags = pathspec_match_iter_flags(flags);
552
552
 
553
- if (!(error = git_iterator_for_index(&iter, index, &iter_opts))) {
553
+ if (!(error = git_iterator_for_index(&iter, git_index_owner(index), index, &iter_opts))) {
554
554
  error = pathspec_match_from_iterator(out, iter, flags, ps);
555
555
  git_iterator_free(iter);
556
556
  }
@@ -718,4 +718,3 @@ const char * git_pathspec_match_list_failed_entry(
718
718
 
719
719
  return entry ? *entry : NULL;
720
720
  }
721
-
@@ -63,17 +63,23 @@ struct git_rebase {
63
63
  char *state_path;
64
64
 
65
65
  int head_detached : 1,
66
+ inmemory : 1,
66
67
  quiet : 1,
67
68
  started : 1;
68
69
 
69
- char *orig_head_name;
70
+ git_array_t(git_rebase_operation) operations;
71
+ size_t current;
72
+
73
+ /* Used by in-memory rebase */
74
+ git_index *index;
75
+ git_commit *last_commit;
76
+
77
+ /* Used by regular (not in-memory) merge-style rebase */
70
78
  git_oid orig_head_id;
79
+ char *orig_head_name;
71
80
 
72
81
  git_oid onto_id;
73
82
  char *onto_name;
74
-
75
- git_array_t(git_rebase_operation) operations;
76
- size_t current;
77
83
  };
78
84
 
79
85
  #define GIT_REBASE_STATE_INIT {0}
@@ -393,6 +399,9 @@ done:
393
399
 
394
400
  static int rebase_cleanup(git_rebase *rebase)
395
401
  {
402
+ if (!rebase || rebase->inmemory)
403
+ return 0;
404
+
396
405
  return git_path_isdir(rebase->state_path) ?
397
406
  git_futils_rmdir_r(rebase->state_path, NULL, GIT_RMDIR_REMOVE_FILES) :
398
407
  0;
@@ -600,62 +609,66 @@ static int rebase_init_merge(
600
609
  const git_annotated_commit *branch,
601
610
  const git_annotated_commit *upstream,
602
611
  const git_annotated_commit *onto)
603
- {
604
- if (rebase_init_operations(rebase, repo, branch, upstream, onto) < 0)
605
- return -1;
606
-
607
- rebase->onto_name = git__strdup(rebase_onto_name(onto));
608
- GITERR_CHECK_ALLOC(rebase->onto_name);
609
-
610
- return 0;
611
- }
612
-
613
- static int rebase_init(
614
- git_rebase *rebase,
615
- git_repository *repo,
616
- const git_annotated_commit *branch,
617
- const git_annotated_commit *upstream,
618
- const git_annotated_commit *onto)
619
612
  {
620
613
  git_reference *head_ref = NULL;
621
- git_annotated_commit *head_branch = NULL;
614
+ git_commit *onto_commit = NULL;
615
+ git_buf reflog = GIT_BUF_INIT;
622
616
  git_buf state_path = GIT_BUF_INIT;
623
617
  int error;
624
618
 
619
+ GIT_UNUSED(upstream);
620
+
625
621
  if ((error = git_buf_joinpath(&state_path, repo->path_repository, REBASE_MERGE_DIR)) < 0)
626
622
  goto done;
627
623
 
628
- if (!branch) {
629
- if ((error = git_repository_head(&head_ref, repo)) < 0 ||
630
- (error = git_annotated_commit_from_ref(&head_branch, repo, head_ref)) < 0)
631
- goto done;
632
-
633
- branch = head_branch;
634
- }
635
-
636
- rebase->repo = repo;
637
- rebase->type = GIT_REBASE_TYPE_MERGE;
638
624
  rebase->state_path = git_buf_detach(&state_path);
625
+ GITERR_CHECK_ALLOC(rebase->state_path);
626
+
639
627
  rebase->orig_head_name = git__strdup(branch->ref_name ? branch->ref_name : ORIG_DETACHED_HEAD);
628
+ GITERR_CHECK_ALLOC(rebase->orig_head_name);
629
+
630
+ rebase->onto_name = git__strdup(rebase_onto_name(onto));
631
+ GITERR_CHECK_ALLOC(rebase->onto_name);
632
+
640
633
  rebase->quiet = rebase->options.quiet;
641
634
 
642
635
  git_oid_cpy(&rebase->orig_head_id, git_annotated_commit_id(branch));
643
636
  git_oid_cpy(&rebase->onto_id, git_annotated_commit_id(onto));
644
637
 
645
- if (!rebase->orig_head_name || !rebase->state_path)
646
- return -1;
647
-
648
- error = rebase_init_merge(rebase, repo, branch, upstream, onto);
649
-
650
- git_buf_free(&state_path);
638
+ if ((error = rebase_setupfiles(rebase)) < 0 ||
639
+ (error = git_buf_printf(&reflog,
640
+ "rebase: checkout %s", rebase_onto_name(onto))) < 0 ||
641
+ (error = git_commit_lookup(
642
+ &onto_commit, repo, git_annotated_commit_id(onto))) < 0 ||
643
+ (error = git_checkout_tree(repo,
644
+ (git_object *)onto_commit, &rebase->options.checkout_options)) < 0 ||
645
+ (error = git_reference_create(&head_ref, repo, GIT_HEAD_FILE,
646
+ git_annotated_commit_id(onto), 1, reflog.ptr)) < 0)
647
+ goto done;
651
648
 
652
649
  done:
653
650
  git_reference_free(head_ref);
654
- git_annotated_commit_free(head_branch);
651
+ git_commit_free(onto_commit);
652
+ git_buf_free(&reflog);
653
+ git_buf_free(&state_path);
655
654
 
656
655
  return error;
657
656
  }
658
657
 
658
+ static int rebase_init_inmemory(
659
+ git_rebase *rebase,
660
+ git_repository *repo,
661
+ const git_annotated_commit *branch,
662
+ const git_annotated_commit *upstream,
663
+ const git_annotated_commit *onto)
664
+ {
665
+ GIT_UNUSED(branch);
666
+ GIT_UNUSED(upstream);
667
+
668
+ return git_commit_lookup(
669
+ &rebase->last_commit, repo, git_annotated_commit_id(onto));
670
+ }
671
+
659
672
  int git_rebase_init(
660
673
  git_rebase **out,
661
674
  git_repository *repo,
@@ -665,9 +678,9 @@ int git_rebase_init(
665
678
  const git_rebase_options *given_opts)
666
679
  {
667
680
  git_rebase *rebase = NULL;
668
- git_buf reflog = GIT_BUF_INIT;
669
- git_commit *onto_commit = NULL;
681
+ git_annotated_commit *head_branch = NULL;
670
682
  git_reference *head_ref = NULL;
683
+ bool inmemory = (given_opts && given_opts->inmemory);
671
684
  int error;
672
685
 
673
686
  assert(repo && (upstream || onto));
@@ -677,39 +690,51 @@ int git_rebase_init(
677
690
  if (!onto)
678
691
  onto = upstream;
679
692
 
680
- if ((error = rebase_check_versions(given_opts)) < 0 ||
681
- (error = git_repository__ensure_not_bare(repo, "rebase")) < 0 ||
682
- (error = rebase_ensure_not_in_progress(repo)) < 0 ||
683
- (error = rebase_ensure_not_dirty(repo, true, true, GIT_ERROR)) < 0 ||
684
- (error = git_commit_lookup(
685
- &onto_commit, repo, git_annotated_commit_id(onto))) < 0)
686
- return error;
693
+ if ((error = rebase_check_versions(given_opts)) < 0)
694
+ goto done;
695
+
696
+ if (!inmemory) {
697
+ if ((error = git_repository__ensure_not_bare(repo, "rebase")) < 0 ||
698
+ (error = rebase_ensure_not_in_progress(repo)) < 0 ||
699
+ (error = rebase_ensure_not_dirty(repo, true, true, GIT_ERROR)) < 0)
700
+ goto done;
701
+ }
702
+
703
+ if (!branch) {
704
+ if ((error = git_repository_head(&head_ref, repo)) < 0 ||
705
+ (error = git_annotated_commit_from_ref(&head_branch, repo, head_ref)) < 0)
706
+ goto done;
707
+
708
+ branch = head_branch;
709
+ }
687
710
 
688
711
  rebase = rebase_alloc(given_opts);
712
+ GITERR_CHECK_ALLOC(rebase);
689
713
 
690
- if ((error = rebase_init(
691
- rebase, repo, branch, upstream, onto)) < 0 ||
692
- (error = rebase_setupfiles(rebase)) < 0 ||
693
- (error = git_buf_printf(&reflog,
694
- "rebase: checkout %s", rebase_onto_name(onto))) < 0 ||
695
- (error = git_checkout_tree(
696
- repo, (git_object *)onto_commit, &rebase->options.checkout_options)) < 0 ||
697
- (error = git_reference_create(&head_ref, repo, GIT_HEAD_FILE,
698
- git_annotated_commit_id(onto), 1, reflog.ptr)) < 0)
714
+ rebase->repo = repo;
715
+ rebase->inmemory = inmemory;
716
+ rebase->type = GIT_REBASE_TYPE_MERGE;
717
+
718
+ if ((error = rebase_init_operations(rebase, repo, branch, upstream, onto)) < 0)
699
719
  goto done;
700
720
 
701
- *out = rebase;
721
+ if (inmemory)
722
+ error = rebase_init_inmemory(rebase, repo, branch, upstream, onto);
723
+ else
724
+ rebase_init_merge(rebase, repo, branch ,upstream, onto);
725
+
726
+ if (error == 0)
727
+ *out = rebase;
702
728
 
703
729
  done:
704
730
  git_reference_free(head_ref);
731
+ git_annotated_commit_free(head_branch);
732
+
705
733
  if (error < 0) {
706
734
  rebase_cleanup(rebase);
707
735
  git_rebase_free(rebase);
708
736
  }
709
737
 
710
- git_commit_free(onto_commit);
711
- git_buf_free(&reflog);
712
-
713
738
  return error;
714
739
  }
715
740
 
@@ -764,9 +789,6 @@ static int rebase_next_merge(
764
789
 
765
790
  *out = NULL;
766
791
 
767
- if ((error = rebase_movenext(rebase)) < 0)
768
- goto done;
769
-
770
792
  operation = git_array_get(rebase->operations, rebase->current);
771
793
 
772
794
  if ((error = git_commit_lookup(&current_commit, rebase->repo, &operation->id)) < 0 ||
@@ -791,7 +813,7 @@ static int rebase_next_merge(
791
813
  if ((error = git_indexwriter_init_for_operation(&indexwriter, rebase->repo, &checkout_opts.checkout_strategy)) < 0 ||
792
814
  (error = rebase_setupfile(rebase, MSGNUM_FILE, -1, "%" PRIuZ "\n", rebase->current+1)) < 0 ||
793
815
  (error = rebase_setupfile(rebase, CURRENT_FILE, -1, "%.*s\n", GIT_OID_HEXSZ, current_idstr)) < 0 ||
794
- (error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, NULL)) < 0 ||
816
+ (error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, &rebase->options.merge_options)) < 0 ||
795
817
  (error = git_merge__check_result(rebase->repo, index)) < 0 ||
796
818
  (error = git_checkout_index(rebase->repo, index, &checkout_opts)) < 0 ||
797
819
  (error = git_indexwriter_commit(&indexwriter)) < 0)
@@ -812,6 +834,49 @@ done:
812
834
  return error;
813
835
  }
814
836
 
837
+ static int rebase_next_inmemory(
838
+ git_rebase_operation **out,
839
+ git_rebase *rebase)
840
+ {
841
+ git_commit *current_commit = NULL, *parent_commit = NULL;
842
+ git_tree *current_tree = NULL, *head_tree = NULL, *parent_tree = NULL;
843
+ git_rebase_operation *operation;
844
+ git_index *index = NULL;
845
+ int error;
846
+
847
+ *out = NULL;
848
+
849
+ operation = git_array_get(rebase->operations, rebase->current);
850
+
851
+ if ((error = git_commit_lookup(&current_commit, rebase->repo, &operation->id)) < 0 ||
852
+ (error = git_commit_tree(&current_tree, current_commit)) < 0 ||
853
+ (error = git_commit_parent(&parent_commit, current_commit, 0)) < 0 ||
854
+ (error = git_commit_tree(&parent_tree, parent_commit)) < 0 ||
855
+ (error = git_commit_tree(&head_tree, rebase->last_commit)) < 0 ||
856
+ (error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, &rebase->options.merge_options)) < 0)
857
+ goto done;
858
+
859
+ if (!rebase->index) {
860
+ rebase->index = index;
861
+ index = NULL;
862
+ } else {
863
+ if ((error = git_index_read_index(rebase->index, index)) < 0)
864
+ goto done;
865
+ }
866
+
867
+ *out = operation;
868
+
869
+ done:
870
+ git_commit_free(current_commit);
871
+ git_commit_free(parent_commit);
872
+ git_tree_free(current_tree);
873
+ git_tree_free(head_tree);
874
+ git_tree_free(parent_tree);
875
+ git_index_free(index);
876
+
877
+ return error;
878
+ }
879
+
815
880
  int git_rebase_next(
816
881
  git_rebase_operation **out,
817
882
  git_rebase *rebase)
@@ -820,66 +885,67 @@ int git_rebase_next(
820
885
 
821
886
  assert(out && rebase);
822
887
 
823
- switch (rebase->type) {
824
- case GIT_REBASE_TYPE_MERGE:
888
+ if ((error = rebase_movenext(rebase)) < 0)
889
+ return error;
890
+
891
+ if (rebase->inmemory)
892
+ error = rebase_next_inmemory(out, rebase);
893
+ else if (rebase->type == GIT_REBASE_TYPE_MERGE)
825
894
  error = rebase_next_merge(out, rebase);
826
- break;
827
- default:
895
+ else
828
896
  abort();
829
- }
830
897
 
831
898
  return error;
832
899
  }
833
900
 
834
- static int rebase_commit_merge(
835
- git_oid *commit_id,
901
+ int git_rebase_inmemory_index(
902
+ git_index **out,
903
+ git_rebase *rebase)
904
+ {
905
+ assert(out && rebase && rebase->index);
906
+
907
+ GIT_REFCOUNT_INC(rebase->index);
908
+ *out = rebase->index;
909
+
910
+ return 0;
911
+ }
912
+
913
+ static int rebase_commit__create(
914
+ git_commit **out,
836
915
  git_rebase *rebase,
916
+ git_index *index,
917
+ git_commit *parent_commit,
837
918
  const git_signature *author,
838
919
  const git_signature *committer,
839
920
  const char *message_encoding,
840
921
  const char *message)
841
922
  {
842
- git_index *index = NULL;
843
- git_reference *head = NULL;
844
- git_commit *current_commit = NULL, *head_commit = NULL, *commit = NULL;
845
923
  git_rebase_operation *operation;
846
- git_tree *head_tree = NULL, *tree = NULL;
847
- git_diff *diff = NULL;
848
- git_oid tree_id;
849
- git_buf reflog_msg = GIT_BUF_INIT;
850
- char old_idstr[GIT_OID_HEXSZ], new_idstr[GIT_OID_HEXSZ];
924
+ git_commit *current_commit = NULL, *commit = NULL;
925
+ git_tree *parent_tree = NULL, *tree = NULL;
926
+ git_oid tree_id, commit_id;
851
927
  int error;
852
928
 
853
929
  operation = git_array_get(rebase->operations, rebase->current);
854
- assert(operation);
855
-
856
- if ((error = git_repository_index(&index, rebase->repo)) < 0)
857
- goto done;
858
930
 
859
931
  if (git_index_has_conflicts(index)) {
860
- giterr_set(GITERR_REBASE, "Conflicts have not been resolved");
932
+ giterr_set(GITERR_REBASE, "conflicts have not been resolved");
861
933
  error = GIT_EUNMERGED;
862
934
  goto done;
863
935
  }
864
936
 
865
- if ((error = rebase_ensure_not_dirty(rebase->repo, false, true, GIT_EUNMERGED)) < 0 ||
866
- (error = git_commit_lookup(&current_commit, rebase->repo, &operation->id)) < 0 ||
867
- (error = git_repository_head(&head, rebase->repo)) < 0 ||
868
- (error = git_reference_peel((git_object **)&head_commit, head, GIT_OBJ_COMMIT)) < 0 ||
869
- (error = git_commit_tree(&head_tree, head_commit)) < 0 ||
870
- (error = git_diff_tree_to_index(&diff, rebase->repo, head_tree, index, NULL)) < 0)
937
+ if ((error = git_commit_lookup(&current_commit, rebase->repo, &operation->id)) < 0 ||
938
+ (error = git_commit_tree(&parent_tree, parent_commit)) < 0 ||
939
+ (error = git_index_write_tree_to(&tree_id, index, rebase->repo)) < 0 ||
940
+ (error = git_tree_lookup(&tree, rebase->repo, &tree_id)) < 0)
871
941
  goto done;
872
942
 
873
- if (git_diff_num_deltas(diff) == 0) {
874
- giterr_set(GITERR_REBASE, "This patch has already been applied");
943
+ if (git_oid_equal(&tree_id, git_tree_id(parent_tree))) {
944
+ giterr_set(GITERR_REBASE, "this patch has already been applied");
875
945
  error = GIT_EAPPLIED;
876
946
  goto done;
877
947
  }
878
948
 
879
- if ((error = git_index_write_tree(&tree_id, index)) < 0 ||
880
- (error = git_tree_lookup(&tree, rebase->repo, &tree_id)) < 0)
881
- goto done;
882
-
883
949
  if (!author)
884
950
  author = git_commit_author(current_commit);
885
951
 
@@ -888,30 +954,100 @@ static int rebase_commit_merge(
888
954
  message = git_commit_message(current_commit);
889
955
  }
890
956
 
891
- if ((error = git_commit_create(commit_id, rebase->repo, NULL, author,
892
- committer, message_encoding, message, tree, 1,
893
- (const git_commit **)&head_commit)) < 0 ||
894
- (error = git_commit_lookup(&commit, rebase->repo, commit_id)) < 0 ||
957
+ if ((error = git_commit_create(&commit_id, rebase->repo, NULL, author,
958
+ committer, message_encoding, message, tree, 1,
959
+ (const git_commit **)&parent_commit)) < 0 ||
960
+ (error = git_commit_lookup(&commit, rebase->repo, &commit_id)) < 0)
961
+ goto done;
962
+
963
+ *out = commit;
964
+
965
+ done:
966
+ if (error < 0)
967
+ git_commit_free(commit);
968
+
969
+ git_commit_free(current_commit);
970
+ git_tree_free(parent_tree);
971
+ git_tree_free(tree);
972
+
973
+ return error;
974
+ }
975
+
976
+ static int rebase_commit_merge(
977
+ git_oid *commit_id,
978
+ git_rebase *rebase,
979
+ const git_signature *author,
980
+ const git_signature *committer,
981
+ const char *message_encoding,
982
+ const char *message)
983
+ {
984
+ git_rebase_operation *operation;
985
+ git_reference *head = NULL;
986
+ git_commit *head_commit = NULL, *commit = NULL;
987
+ git_index *index = NULL;
988
+ char old_idstr[GIT_OID_HEXSZ], new_idstr[GIT_OID_HEXSZ];
989
+ int error;
990
+
991
+ operation = git_array_get(rebase->operations, rebase->current);
992
+ assert(operation);
993
+
994
+ if ((error = rebase_ensure_not_dirty(rebase->repo, false, true, GIT_EUNMERGED)) < 0 ||
995
+ (error = git_repository_head(&head, rebase->repo)) < 0 ||
996
+ (error = git_reference_peel((git_object **)&head_commit, head, GIT_OBJ_COMMIT)) < 0 ||
997
+ (error = git_repository_index(&index, rebase->repo)) < 0 ||
998
+ (error = rebase_commit__create(&commit, rebase, index, head_commit,
999
+ author, committer, message_encoding, message)) < 0 ||
895
1000
  (error = git_reference__update_for_commit(
896
- rebase->repo, NULL, "HEAD", commit_id, "rebase")) < 0)
1001
+ rebase->repo, NULL, "HEAD", git_commit_id(commit), "rebase")) < 0)
897
1002
  goto done;
898
1003
 
899
- git_oid_fmt(old_idstr, git_commit_id(current_commit));
900
- git_oid_fmt(new_idstr, commit_id);
1004
+ git_oid_fmt(old_idstr, &operation->id);
1005
+ git_oid_fmt(new_idstr, git_commit_id(commit));
901
1006
 
902
- error = rebase_setupfile(rebase, REWRITTEN_FILE, O_CREAT|O_WRONLY|O_APPEND,
903
- "%.*s %.*s\n", GIT_OID_HEXSZ, old_idstr, GIT_OID_HEXSZ, new_idstr);
1007
+ if ((error = rebase_setupfile(rebase, REWRITTEN_FILE, O_CREAT|O_WRONLY|O_APPEND,
1008
+ "%.*s %.*s\n", GIT_OID_HEXSZ, old_idstr, GIT_OID_HEXSZ, new_idstr)) < 0)
1009
+ goto done;
1010
+
1011
+ git_oid_cpy(commit_id, git_commit_id(commit));
904
1012
 
905
1013
  done:
906
- git_buf_free(&reflog_msg);
907
- git_commit_free(commit);
908
- git_diff_free(diff);
909
- git_tree_free(tree);
910
- git_tree_free(head_tree);
911
- git_commit_free(head_commit);
912
- git_commit_free(current_commit);
913
- git_reference_free(head);
914
1014
  git_index_free(index);
1015
+ git_reference_free(head);
1016
+ git_commit_free(head_commit);
1017
+ git_commit_free(commit);
1018
+ return error;
1019
+ }
1020
+
1021
+ static int rebase_commit_inmemory(
1022
+ git_oid *commit_id,
1023
+ git_rebase *rebase,
1024
+ const git_signature *author,
1025
+ const git_signature *committer,
1026
+ const char *message_encoding,
1027
+ const char *message)
1028
+ {
1029
+ git_rebase_operation *operation;
1030
+ git_commit *commit = NULL;
1031
+ int error = 0;
1032
+
1033
+ operation = git_array_get(rebase->operations, rebase->current);
1034
+
1035
+ assert(operation);
1036
+ assert(rebase->index);
1037
+ assert(rebase->last_commit);
1038
+
1039
+ if ((error = rebase_commit__create(&commit, rebase, rebase->index,
1040
+ rebase->last_commit, author, committer, message_encoding, message)) < 0)
1041
+ goto done;
1042
+
1043
+ git_commit_free(rebase->last_commit);
1044
+ rebase->last_commit = commit;
1045
+
1046
+ git_oid_cpy(commit_id, git_commit_id(commit));
1047
+
1048
+ done:
1049
+ if (error < 0)
1050
+ git_commit_free(commit);
915
1051
 
916
1052
  return error;
917
1053
  }
@@ -928,14 +1064,14 @@ int git_rebase_commit(
928
1064
 
929
1065
  assert(rebase && committer);
930
1066
 
931
- switch (rebase->type) {
932
- case GIT_REBASE_TYPE_MERGE:
1067
+ if (rebase->inmemory)
1068
+ error = rebase_commit_inmemory(
1069
+ id, rebase, author, committer, message_encoding, message);
1070
+ else if (rebase->type == GIT_REBASE_TYPE_MERGE)
933
1071
  error = rebase_commit_merge(
934
1072
  id, rebase, author, committer, message_encoding, message);
935
- break;
936
- default:
1073
+ else
937
1074
  abort();
938
- }
939
1075
 
940
1076
  return error;
941
1077
  }
@@ -948,6 +1084,9 @@ int git_rebase_abort(git_rebase *rebase)
948
1084
 
949
1085
  assert(rebase);
950
1086
 
1087
+ if (rebase->inmemory)
1088
+ return 0;
1089
+
951
1090
  error = rebase->head_detached ?
952
1091
  git_reference_create(&orig_head_ref, rebase->repo, GIT_HEAD_FILE,
953
1092
  &rebase->orig_head_id, 1, "rebase: aborting") :
@@ -1125,6 +1264,9 @@ int git_rebase_finish(
1125
1264
 
1126
1265
  assert(rebase);
1127
1266
 
1267
+ if (rebase->inmemory)
1268
+ return 0;
1269
+
1128
1270
  git_oid_fmt(onto, &rebase->onto_id);
1129
1271
 
1130
1272
  if ((error = git_buf_printf(&branch_msg, "rebase finished: %s onto %.*s",
@@ -1182,6 +1324,8 @@ void git_rebase_free(git_rebase *rebase)
1182
1324
  if (rebase == NULL)
1183
1325
  return;
1184
1326
 
1327
+ git_index_free(rebase->index);
1328
+ git_commit_free(rebase->last_commit);
1185
1329
  git__free(rebase->onto_name);
1186
1330
  git__free(rebase->orig_head_name);
1187
1331
  git__free(rebase->state_path);