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.
parent 39d18fe6
......@@ -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)
......
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment