rugged 0.24.0b12 → 0.24.0b13

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