revwalk: expose more ways of scheduling commits Before we can tweak the revwalk to be more efficent when negotiating, we need to add an "insertion mode" option. Since there's already an implicit set of those, make it visible, at least privately.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
diff --git a/src/revwalk.c b/src/revwalk.c
index 935bd4d..38f4083 100644
--- a/src/revwalk.c
+++ b/src/revwalk.c
@@ -38,7 +38,7 @@ git_commit_list_node *git_revwalk__commit_lookup(
return commit;
}
-static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting, int from_glob)
+int git_revwalk__push_commit(git_revwalk *walk, const git_oid *oid, const git_revwalk__push_options *opts)
{
git_oid commit_id;
int error;
@@ -54,7 +54,7 @@ static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting,
if (error == GIT_ENOTFOUND || error == GIT_EINVALIDSPEC || error == GIT_EPEEL) {
/* If this comes from e.g. push_glob("tags"), ignore this */
- if (from_glob)
+ if (opts->from_glob)
return 0;
git_error_set(GIT_ERROR_INVALID, "object is not a committish");
@@ -74,14 +74,14 @@ static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting,
if (commit->uninteresting)
return 0;
- if (uninteresting) {
+ if (opts->uninteresting) {
walk->limited = 1;
walk->did_hide = 1;
} else {
walk->did_push = 1;
}
- commit->uninteresting = uninteresting;
+ commit->uninteresting = opts->uninteresting;
list = walk->user_input;
if (git_commit_list_insert(commit, &list) == NULL) {
git_error_set_oom();
@@ -95,29 +95,36 @@ static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting,
int git_revwalk_push(git_revwalk *walk, const git_oid *oid)
{
+ git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT;
+
assert(walk && oid);
- return push_commit(walk, oid, 0, false);
+
+ return git_revwalk__push_commit(walk, oid, &opts);
}
int git_revwalk_hide(git_revwalk *walk, const git_oid *oid)
{
+ git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT;
assert(walk && oid);
- return push_commit(walk, oid, 1, false);
+
+ opts.uninteresting = 1;
+ return git_revwalk__push_commit(walk, oid, &opts);
}
-static int push_ref(git_revwalk *walk, const char *refname, int hide, int from_glob)
+int git_revwalk__push_ref(git_revwalk *walk, const char *refname, const git_revwalk__push_options *opts)
{
git_oid oid;
if (git_reference_name_to_id(&oid, walk->repo, refname) < 0)
return -1;
- return push_commit(walk, &oid, hide, from_glob);
+ return git_revwalk__push_commit(walk, &oid, opts);
}
-static int push_glob(git_revwalk *walk, const char *glob, int hide)
+int git_revwalk__push_glob(git_revwalk *walk, const char *glob, const git_revwalk__push_options *given_opts)
{
+ git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT;
int error = 0;
git_buf buf = GIT_BUF_INIT;
git_reference *ref;
@@ -126,6 +133,9 @@ static int push_glob(git_revwalk *walk, const char *glob, int hide)
assert(walk && glob);
+ if (given_opts)
+ memcpy(&opts, given_opts, sizeof(opts));
+
/* refs/ is implied if not given in the glob */
if (git__prefixcmp(glob, GIT_REFS_DIR) != 0)
git_buf_joinpath(&buf, GIT_REFS_DIR, glob);
@@ -141,8 +151,9 @@ static int push_glob(git_revwalk *walk, const char *glob, int hide)
if ((error = git_reference_iterator_glob_new(&iter, walk->repo, buf.ptr)) < 0)
goto out;
+ opts.from_glob = true;
while ((error = git_reference_next(&ref, iter)) == 0) {
- error = push_ref(walk, git_reference_name(ref), hide, true);
+ error = git_revwalk__push_ref(walk, git_reference_name(ref), &opts);
git_reference_free(ref);
if (error < 0)
break;
@@ -158,36 +169,49 @@ out:
int git_revwalk_push_glob(git_revwalk *walk, const char *glob)
{
+ git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT;
assert(walk && glob);
- return push_glob(walk, glob, 0);
+
+ return git_revwalk__push_glob(walk, glob, &opts);
}
int git_revwalk_hide_glob(git_revwalk *walk, const char *glob)
{
+ git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT;
assert(walk && glob);
- return push_glob(walk, glob, 1);
+
+ opts.uninteresting = 1;
+ return git_revwalk__push_glob(walk, glob, &opts);
}
int git_revwalk_push_head(git_revwalk *walk)
{
+ git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT;
assert(walk);
- return push_ref(walk, GIT_HEAD_FILE, 0, false);
+
+ return git_revwalk__push_ref(walk, GIT_HEAD_FILE, &opts);
}
int git_revwalk_hide_head(git_revwalk *walk)
{
+ git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT;
assert(walk);
- return push_ref(walk, GIT_HEAD_FILE, 1, false);
+
+ opts.uninteresting = 1;
+ return git_revwalk__push_ref(walk, GIT_HEAD_FILE, &opts);
}
int git_revwalk_push_ref(git_revwalk *walk, const char *refname)
{
+ git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT;
assert(walk && refname);
- return push_ref(walk, refname, 0, false);
+
+ return git_revwalk__push_ref(walk, refname, &opts);
}
int git_revwalk_push_range(git_revwalk *walk, const char *range)
{
+ git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT;
git_revspec revspec;
int error = 0;
@@ -207,10 +231,12 @@ int git_revwalk_push_range(git_revwalk *walk, const char *range)
goto out;
}
- if ((error = push_commit(walk, git_object_id(revspec.from), 1, false)))
+ opts.uninteresting = 1;
+ if ((error = git_revwalk__push_commit(walk, git_object_id(revspec.from), &opts)))
goto out;
- error = push_commit(walk, git_object_id(revspec.to), 0, false);
+ opts.uninteresting = 0;
+ error = git_revwalk__push_commit(walk, git_object_id(revspec.to), &opts);
out:
git_object_free(revspec.from);
@@ -220,8 +246,10 @@ out:
int git_revwalk_hide_ref(git_revwalk *walk, const char *refname)
{
+ git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT;
assert(walk && refname);
- return push_ref(walk, refname, 1, false);
+ opts.uninteresting = 1;
+ return git_revwalk__push_ref(walk, refname, &opts);
}
static int revwalk_enqueue_timesort(git_revwalk *walk, git_commit_list_node *commit)
diff --git a/src/revwalk.h b/src/revwalk.h
index 923a2bc..852ab8b 100644
--- a/src/revwalk.h
+++ b/src/revwalk.h
@@ -50,4 +50,23 @@ struct git_revwalk {
git_commit_list_node *git_revwalk__commit_lookup(git_revwalk *walk, const git_oid *oid);
+typedef struct {
+ int uninteresting;
+ int from_glob;
+} git_revwalk__push_options;
+
+#define GIT_REVWALK__PUSH_OPTIONS_INIT { 0 }
+
+int git_revwalk__push_commit(git_revwalk *walk,
+ const git_oid *oid,
+ const git_revwalk__push_options *opts);
+
+int git_revwalk__push_ref(git_revwalk *walk,
+ const char *refname,
+ const git_revwalk__push_options *opts);
+
+int git_revwalk__push_glob(git_revwalk *walk,
+ const char *glob,
+ const git_revwalk__push_options *given_opts);
+
#endif