Commit d465e4e9 by Carlos Martín Nieto

revwalk: ignore wrong object type in glob pushes

Pushing a whole namespace can cause us to attempt to push non-committish
objects. Catch this situation and special-case it for ignoring this.
parent b4ef67d5
...@@ -110,6 +110,9 @@ GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *id); ...@@ -110,6 +110,9 @@ GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *id);
* A leading 'refs/' is implied if not present as well as a trailing * A leading 'refs/' is implied if not present as well as a trailing
* '/ *' if the glob lacks '?', '*' or '['. * '/ *' if the glob lacks '?', '*' or '['.
* *
* Any references matching this glob which do not point to a
* committish will be ignored.
*
* @param walk the walker being used for the traversal * @param walk the walker being used for the traversal
* @param glob the glob pattern references should match * @param glob the glob pattern references should match
* @return 0 or an error code * @return 0 or an error code
...@@ -149,6 +152,9 @@ GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *commit_id); ...@@ -149,6 +152,9 @@ GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *commit_id);
* A leading 'refs/' is implied if not present as well as a trailing * A leading 'refs/' is implied if not present as well as a trailing
* '/ *' if the glob lacks '?', '*' or '['. * '/ *' if the glob lacks '?', '*' or '['.
* *
* Any references matching this glob which do not point to a
* committish will be ignored.
*
* @param walk the walker being used for the traversal * @param walk the walker being used for the traversal
* @param glob the glob pattern references should match * @param glob the glob pattern references should match
* @return 0 or an error code * @return 0 or an error code
......
...@@ -110,7 +110,7 @@ static int process_commit_parents(git_revwalk *walk, git_commit_list_node *commi ...@@ -110,7 +110,7 @@ static int process_commit_parents(git_revwalk *walk, git_commit_list_node *commi
return error; return error;
} }
static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting) static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting, int from_glob)
{ {
git_oid commit_id; git_oid commit_id;
int error; int error;
...@@ -124,6 +124,10 @@ static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting) ...@@ -124,6 +124,10 @@ static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting)
git_object_free(oobj); git_object_free(oobj);
if (error == GIT_ENOTFOUND) { if (error == GIT_ENOTFOUND) {
/* If this comes from e.g. push_glob("tags"), ignore this */
if (from_glob)
return 0;
giterr_set(GITERR_INVALID, "Object is not a committish"); giterr_set(GITERR_INVALID, "Object is not a committish");
return -1; return -1;
} }
...@@ -151,24 +155,24 @@ static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting) ...@@ -151,24 +155,24 @@ static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting)
int git_revwalk_push(git_revwalk *walk, const git_oid *oid) int git_revwalk_push(git_revwalk *walk, const git_oid *oid)
{ {
assert(walk && oid); assert(walk && oid);
return push_commit(walk, oid, 0); return push_commit(walk, oid, 0, false);
} }
int git_revwalk_hide(git_revwalk *walk, const git_oid *oid) int git_revwalk_hide(git_revwalk *walk, const git_oid *oid)
{ {
assert(walk && oid); assert(walk && oid);
return push_commit(walk, oid, 1); return push_commit(walk, oid, 1, false);
} }
static int push_ref(git_revwalk *walk, const char *refname, int hide) static int push_ref(git_revwalk *walk, const char *refname, int hide, int from_glob)
{ {
git_oid oid; git_oid oid;
if (git_reference_name_to_id(&oid, walk->repo, refname) < 0) if (git_reference_name_to_id(&oid, walk->repo, refname) < 0)
return -1; return -1;
return push_commit(walk, &oid, hide); return push_commit(walk, &oid, hide, from_glob);
} }
struct push_cb_data { struct push_cb_data {
...@@ -179,7 +183,7 @@ struct push_cb_data { ...@@ -179,7 +183,7 @@ struct push_cb_data {
static int push_glob_cb(const char *refname, void *data_) static int push_glob_cb(const char *refname, void *data_)
{ {
struct push_cb_data *data = (struct push_cb_data *)data_; struct push_cb_data *data = (struct push_cb_data *)data_;
return push_ref(data->walk, refname, data->hide); return push_ref(data->walk, refname, data->hide, true);
} }
static int push_glob(git_revwalk *walk, const char *glob, int hide) static int push_glob(git_revwalk *walk, const char *glob, int hide)
...@@ -229,19 +233,19 @@ int git_revwalk_hide_glob(git_revwalk *walk, const char *glob) ...@@ -229,19 +233,19 @@ int git_revwalk_hide_glob(git_revwalk *walk, const char *glob)
int git_revwalk_push_head(git_revwalk *walk) int git_revwalk_push_head(git_revwalk *walk)
{ {
assert(walk); assert(walk);
return push_ref(walk, GIT_HEAD_FILE, 0); return push_ref(walk, GIT_HEAD_FILE, 0, false);
} }
int git_revwalk_hide_head(git_revwalk *walk) int git_revwalk_hide_head(git_revwalk *walk)
{ {
assert(walk); assert(walk);
return push_ref(walk, GIT_HEAD_FILE, 1); return push_ref(walk, GIT_HEAD_FILE, 1, false);
} }
int git_revwalk_push_ref(git_revwalk *walk, const char *refname) int git_revwalk_push_ref(git_revwalk *walk, const char *refname)
{ {
assert(walk && refname); assert(walk && refname);
return push_ref(walk, refname, 0); return push_ref(walk, refname, 0, false);
} }
int git_revwalk_push_range(git_revwalk *walk, const char *range) int git_revwalk_push_range(git_revwalk *walk, const char *range)
...@@ -258,10 +262,10 @@ int git_revwalk_push_range(git_revwalk *walk, const char *range) ...@@ -258,10 +262,10 @@ int git_revwalk_push_range(git_revwalk *walk, const char *range)
return GIT_EINVALIDSPEC; return GIT_EINVALIDSPEC;
} }
if ((error = push_commit(walk, git_object_id(revspec.from), 1))) if ((error = push_commit(walk, git_object_id(revspec.from), 1, false)))
goto out; goto out;
error = push_commit(walk, git_object_id(revspec.to), 0); error = push_commit(walk, git_object_id(revspec.to), 0, false);
out: out:
git_object_free(revspec.from); git_object_free(revspec.from);
...@@ -272,7 +276,7 @@ out: ...@@ -272,7 +276,7 @@ out:
int git_revwalk_hide_ref(git_revwalk *walk, const char *refname) int git_revwalk_hide_ref(git_revwalk *walk, const char *refname)
{ {
assert(walk && refname); assert(walk && refname);
return push_ref(walk, refname, 1); return push_ref(walk, refname, 1, false);
} }
static int revwalk_enqueue_timesort(git_revwalk *walk, git_commit_list_node *commit) static int revwalk_enqueue_timesort(git_revwalk *walk, git_commit_list_node *commit)
......
...@@ -255,10 +255,19 @@ void test_revwalk_basic__push_range(void) ...@@ -255,10 +255,19 @@ void test_revwalk_basic__push_range(void)
void test_revwalk_basic__push_mixed(void) void test_revwalk_basic__push_mixed(void)
{ {
git_oid oid;
int i = 0;
revwalk_basic_setup_walk(NULL); revwalk_basic_setup_walk(NULL);
git_revwalk_reset(_walk); git_revwalk_reset(_walk);
git_revwalk_sorting(_walk, 0); git_revwalk_sorting(_walk, 0);
cl_git_pass(git_revwalk_push_glob(_walk, "tags")); cl_git_pass(git_revwalk_push_glob(_walk, "tags"));
cl_git_pass(test_walk_only(_walk, commit_sorting_segment, 1));
while (git_revwalk_next(&oid, _walk) == 0) {
i++;
}
/* git rev-list --count --glob=tags #=> 9 */
cl_assert_equal_i(9, i);
} }
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