Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
git2
Commits
df70de07
Commit
df70de07
authored
Feb 05, 2014
by
Russell Belfer
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2094 from libgit2/cmn/push-non-commit
Add flexibility to the revwalk API
parents
daeac29a
c74077d1
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
91 additions
and
36 deletions
+91
-36
include/git2/revwalk.h
+10
-4
src/revparse.c
+1
-2
src/revwalk.c
+42
-30
tests/revwalk/basic.c
+38
-0
No files found.
include/git2/revwalk.h
View file @
df70de07
...
...
@@ -87,7 +87,7 @@ GIT_EXTERN(void) git_revwalk_reset(git_revwalk *walker);
/**
* Mark a commit to start traversal from.
*
* The given OID must belong to a commit on the walked
* The given OID must belong to a commit
tish
on the walked
* repository.
*
* The given commit will be used as one of the roots
...
...
@@ -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
* '/\*' 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 glob the glob pattern references should match
* @return 0 or an error code
...
...
@@ -127,7 +130,7 @@ GIT_EXTERN(int) git_revwalk_push_head(git_revwalk *walk);
/**
* Mark a commit (and its ancestors) uninteresting for the output.
*
* The given OID must belong to a commit on the walked
* The given OID must belong to a commit
tish
on the walked
* repository.
*
* The resolved commit and all its parents will be hidden from the
...
...
@@ -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
* '/\*' 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 glob the glob pattern references should match
* @return 0 or an error code
...
...
@@ -166,7 +172,7 @@ GIT_EXTERN(int) git_revwalk_hide_head(git_revwalk *walk);
/**
* Push the OID pointed to by a reference
*
* The reference must point to a commit.
* The reference must point to a commit
tish
.
*
* @param walk the walker being used for the traversal
* @param refname the reference to push
...
...
@@ -177,7 +183,7 @@ GIT_EXTERN(int) git_revwalk_push_ref(git_revwalk *walk, const char *refname);
/**
* Hide the OID pointed to by a reference
*
* The reference must point to a commit.
* The reference must point to a commit
tish
.
*
* @param walk the walker being used for the traversal
* @param refname the reference to hide
...
...
src/revparse.c
View file @
df70de07
...
...
@@ -490,8 +490,7 @@ static int handle_grep_syntax(git_object **out, git_repository *repo, const git_
git_revwalk_sorting
(
walk
,
GIT_SORT_TIME
);
if
(
spec_oid
==
NULL
)
{
// TODO: @carlosmn: The glob should be refs/* but this makes git_revwalk_next() fails
if
((
error
=
git_revwalk_push_glob
(
walk
,
GIT_REFS_HEADS_DIR
"*"
))
<
0
)
if
((
error
=
git_revwalk_push_glob
(
walk
,
"refs/*"
))
<
0
)
goto
cleanup
;
}
else
if
((
error
=
git_revwalk_push
(
walk
,
spec_oid
))
<
0
)
goto
cleanup
;
...
...
src/revwalk.c
View file @
df70de07
...
...
@@ -110,25 +110,34 @@ static int process_commit_parents(git_revwalk *walk, git_commit_list_node *commi
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
;
int
error
;
git_object
*
obj
;
git_otype
type
;
git_object
*
obj
,
*
oobj
;
git_commit_list_node
*
commit
;
if
((
error
=
git_object_lookup
(
&
obj
,
walk
->
repo
,
oid
,
GIT_OBJ_ANY
))
<
0
)
if
((
error
=
git_object_lookup
(
&
o
o
bj
,
walk
->
repo
,
oid
,
GIT_OBJ_ANY
))
<
0
)
return
error
;
type
=
git_object_type
(
obj
);
git_object_free
(
obj
);
error
=
git_object_peel
(
&
obj
,
oobj
,
GIT_OBJ_COMMIT
);
git_object_free
(
oobj
);
if
(
error
==
GIT_ENOTFOUND
)
{
/* If this comes from e.g. push_glob("tags"), ignore this */
if
(
from_glob
)
return
0
;
if
(
type
!=
GIT_OBJ_COMMIT
)
{
giterr_set
(
GITERR_INVALID
,
"Object is no commit object"
);
giterr_set
(
GITERR_INVALID
,
"Object is not a committish"
);
return
-
1
;
}
if
(
error
<
0
)
return
error
;
git_oid_cpy
(
&
commit_id
,
git_object_id
(
obj
));
git_object_free
(
obj
);
commit
=
git_revwalk__commit_lookup
(
walk
,
o
id
);
commit
=
git_revwalk__commit_lookup
(
walk
,
&
commit_
id
);
if
(
commit
==
NULL
)
return
-
1
;
/* error already reported by failed lookup */
...
...
@@ -146,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
)
{
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
)
{
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
;
if
(
git_reference_name_to_id
(
&
oid
,
walk
->
repo
,
refname
)
<
0
)
return
-
1
;
return
push_commit
(
walk
,
&
oid
,
hide
);
return
push_commit
(
walk
,
&
oid
,
hide
,
from_glob
);
}
struct
push_cb_data
{
...
...
@@ -171,17 +180,12 @@ struct push_cb_data {
int
hide
;
};
static
int
push_glob_cb
(
const
char
*
refname
,
void
*
data_
)
{
struct
push_cb_data
*
data
=
(
struct
push_cb_data
*
)
data_
;
return
push_ref
(
data
->
walk
,
refname
,
data
->
hide
);
}
static
int
push_glob
(
git_revwalk
*
walk
,
const
char
*
glob
,
int
hide
)
{
int
error
=
0
;
git_buf
buf
=
GIT_BUF_INIT
;
struct
push_cb_data
data
;
git_reference
*
ref
;
git_reference_iterator
*
iter
;
size_t
wildcard
;
assert
(
walk
&&
glob
);
...
...
@@ -199,12 +203,20 @@ static int push_glob(git_revwalk *walk, const char *glob, int hide)
if
(
!
glob
[
wildcard
])
git_buf_put
(
&
buf
,
"/*"
,
2
);
data
.
walk
=
walk
;
data
.
hide
=
hide
;
if
((
error
=
git_reference_iterator_glob_new
(
&
iter
,
walk
->
repo
,
buf
.
ptr
))
<
0
)
goto
out
;
error
=
git_reference_foreach_glob
(
walk
->
repo
,
git_buf_cstr
(
&
buf
),
push_glob_cb
,
&
data
);
while
((
error
=
git_reference_next
(
&
ref
,
iter
))
==
0
)
{
error
=
push_ref
(
walk
,
git_reference_name
(
ref
),
hide
,
true
);
git_reference_free
(
ref
);
if
(
error
<
0
)
break
;
}
git_reference_iterator_free
(
iter
);
if
(
error
==
GIT_ITEROVER
)
error
=
0
;
out:
git_buf_free
(
&
buf
);
return
error
;
}
...
...
@@ -224,19 +236,19 @@ int git_revwalk_hide_glob(git_revwalk *walk, const char *glob)
int
git_revwalk_push_head
(
git_revwalk
*
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
)
{
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
)
{
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
)
...
...
@@ -253,10 +265,10 @@ int git_revwalk_push_range(git_revwalk *walk, const char *range)
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
;
error
=
push_commit
(
walk
,
git_object_id
(
revspec
.
to
),
0
);
error
=
push_commit
(
walk
,
git_object_id
(
revspec
.
to
),
0
,
false
);
out:
git_object_free
(
revspec
.
from
);
...
...
@@ -267,7 +279,7 @@ out:
int
git_revwalk_hide_ref
(
git_revwalk
*
walk
,
const
char
*
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
)
...
...
tests/revwalk/basic.c
View file @
df70de07
...
...
@@ -252,3 +252,41 @@ void test_revwalk_basic__push_range(void)
cl_git_pass
(
git_revwalk_push_range
(
_walk
,
"9fd738e~2..9fd738e"
));
cl_git_pass
(
test_walk_only
(
_walk
,
commit_sorting_segment
,
1
));
}
void
test_revwalk_basic__push_mixed
(
void
)
{
git_oid
oid
;
int
i
=
0
;
revwalk_basic_setup_walk
(
NULL
);
git_revwalk_reset
(
_walk
);
git_revwalk_sorting
(
_walk
,
0
);
cl_git_pass
(
git_revwalk_push_glob
(
_walk
,
"tags"
));
while
(
git_revwalk_next
(
&
oid
,
_walk
)
==
0
)
{
i
++
;
}
/* git rev-list --count --glob=tags #=> 9 */
cl_assert_equal_i
(
9
,
i
);
}
void
test_revwalk_basic__push_all
(
void
)
{
git_oid
oid
;
int
i
=
0
;
revwalk_basic_setup_walk
(
NULL
);
git_revwalk_reset
(
_walk
);
git_revwalk_sorting
(
_walk
,
0
);
cl_git_pass
(
git_revwalk_push_glob
(
_walk
,
"*"
));
while
(
git_revwalk_next
(
&
oid
,
_walk
)
==
0
)
{
i
++
;
}
/* git rev-list --count --all #=> 15 */
cl_assert_equal_i
(
15
,
i
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment