rugged 0.24.0b12 → 0.24.0b13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/rugged/rugged.c +1 -0
- data/ext/rugged/rugged.h +3 -0
- data/ext/rugged/rugged_commit.c +72 -12
- data/ext/rugged/rugged_rebase.c +355 -0
- data/ext/rugged/rugged_reference.c +12 -0
- data/ext/rugged/rugged_repo.c +57 -1
- data/ext/rugged/rugged_revwalk.c +24 -0
- data/lib/rugged/commit.rb +4 -0
- data/lib/rugged/tag.rb +19 -0
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +3 -2
- data/vendor/libgit2/include/git2/commit.h +12 -0
- data/vendor/libgit2/include/git2/diff.h +1 -1
- data/vendor/libgit2/include/git2/merge.h +0 -8
- data/vendor/libgit2/include/git2/rebase.h +32 -2
- data/vendor/libgit2/include/git2/stash.h +1 -1
- data/vendor/libgit2/src/attr_file.c +3 -2
- data/vendor/libgit2/src/checkout.c +6 -3
- data/vendor/libgit2/src/commit.c +103 -12
- data/vendor/libgit2/src/curl_stream.c +5 -1
- data/vendor/libgit2/src/diff.c +4 -4
- data/vendor/libgit2/src/index.c +2 -2
- data/vendor/libgit2/src/iterator.c +3 -2
- data/vendor/libgit2/src/iterator.h +1 -0
- data/vendor/libgit2/src/merge.c +9 -10
- data/vendor/libgit2/src/pack-objects.c +8 -4
- data/vendor/libgit2/src/pack.c +2 -3
- data/vendor/libgit2/src/pack.h +0 -7
- data/vendor/libgit2/src/pathspec.c +1 -2
- data/vendor/libgit2/src/rebase.c +262 -118
- data/vendor/libgit2/src/stash.c +4 -4
- data/vendor/libgit2/src/submodule.c +3 -3
- data/vendor/libgit2/src/transports/winhttp.c +7 -2
- metadata +3 -2
@@ -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);
|
data/vendor/libgit2/src/diff.c
CHANGED
@@ -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 */
|
data/vendor/libgit2/src/index.c
CHANGED
@@ -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,
|
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
|
data/vendor/libgit2/src/merge.c
CHANGED
@@ -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)
|
104
|
-
|
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
|
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
|
}
|
data/vendor/libgit2/src/pack.c
CHANGED
@@ -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,
|
data/vendor/libgit2/src/pack.h
CHANGED
@@ -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
|
-
|
data/vendor/libgit2/src/rebase.c
CHANGED
@@ -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
|
-
|
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
|
-
|
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 (
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
682
|
-
|
683
|
-
|
684
|
-
(error =
|
685
|
-
|
686
|
-
|
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
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
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
|
-
|
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(¤t_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,
|
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(¤t_commit, rebase->repo, &operation->id)) < 0 ||
|
852
|
+
(error = git_commit_tree(¤t_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
|
-
|
824
|
-
|
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
|
-
|
827
|
-
default:
|
895
|
+
else
|
828
896
|
abort();
|
829
|
-
}
|
830
897
|
|
831
898
|
return error;
|
832
899
|
}
|
833
900
|
|
834
|
-
|
835
|
-
|
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
|
-
|
847
|
-
|
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, "
|
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 =
|
866
|
-
(error =
|
867
|
-
(error =
|
868
|
-
(error =
|
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(¤t_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 (
|
874
|
-
giterr_set(GITERR_REBASE, "
|
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
|
-
|
893
|
-
|
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",
|
1001
|
+
rebase->repo, NULL, "HEAD", git_commit_id(commit), "rebase")) < 0)
|
897
1002
|
goto done;
|
898
1003
|
|
899
|
-
git_oid_fmt(old_idstr,
|
900
|
-
git_oid_fmt(new_idstr,
|
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
|
-
|
932
|
-
|
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
|
-
|
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);
|