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
bdaa40d3
Commit
bdaa40d3
authored
Oct 01, 2012
by
Vicent Martí
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #957 from carlosmn/include-tag
Include tag
parents
2af1c266
3230a44f
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
177 additions
and
93 deletions
+177
-93
include/git2/refspec.h
+0
-8
include/git2/remote.h
+24
-0
src/fetch.c
+16
-9
src/pkt.c
+3
-0
src/protocol.c
+6
-0
src/refs.c
+6
-4
src/refspec.c
+2
-27
src/refspec.h
+4
-0
src/remote.c
+95
-43
src/remote.h
+2
-1
src/transport.h
+3
-1
tests-clar/network/refspecs.c
+1
-0
tests-clar/refs/create.c
+15
-0
No files found.
include/git2/refspec.h
View file @
bdaa40d3
...
...
@@ -20,14 +20,6 @@
GIT_BEGIN_DECL
/**
* Parse a refspec string and create a refspec object
*
* @param refspec pointer to the refspec structure to be used
* @param str the refspec as a string
*/
GIT_EXTERN
(
int
)
git_refspec_parse
(
git_refspec
*
refspec
,
const
char
*
str
);
/**
* Get the source specifier
*
* @param refspec the refspec
...
...
include/git2/remote.h
View file @
bdaa40d3
...
...
@@ -304,6 +304,30 @@ struct git_remote_callbacks {
*/
GIT_EXTERN
(
void
)
git_remote_set_callbacks
(
git_remote
*
remote
,
git_remote_callbacks
*
callbacks
);
enum
{
GIT_REMOTE_DOWNLOAD_TAGS_UNSET
,
GIT_REMOTE_DOWNLOAD_TAGS_NONE
,
GIT_REMOTE_DOWNLOAD_TAGS_AUTO
,
GIT_REMOTE_DOWNLOAD_TAGS_ALL
};
/**
* Retrieve the tag auto-follow setting
*
* @param remote the remote to query
* @return the auto-follow setting
*/
GIT_EXTERN
(
int
)
git_remote_autotag
(
git_remote
*
remote
);
/**
* Set the tag auto-follow setting
*
* @param remote the remote to configure
* @param value a GIT_REMOTE_DOWNLOAD_TAGS value
*/
GIT_EXTERN
(
void
)
git_remote_set_autotag
(
git_remote
*
remote
,
int
value
);
/** @} */
GIT_END_DECL
#endif
src/fetch.c
View file @
bdaa40d3
...
...
@@ -21,7 +21,7 @@
struct
filter_payload
{
git_remote
*
remote
;
const
git_refspec
*
spec
;
const
git_refspec
*
spec
,
*
tagspec
;
git_odb
*
odb
;
int
found_head
;
};
...
...
@@ -29,18 +29,21 @@ struct filter_payload {
static
int
filter_ref__cb
(
git_remote_head
*
head
,
void
*
payload
)
{
struct
filter_payload
*
p
=
payload
;
int
match
=
0
;
if
(
!
p
->
found_head
&&
strcmp
(
head
->
name
,
GIT_HEAD_FILE
)
==
0
)
{
p
->
found_head
=
1
;
}
else
{
/* If it doesn't match the refpec, we don't want it */
if
(
!
git_refspec_src_matches
(
p
->
spec
,
head
->
name
))
if
(
!
git_reference_is_valid_name
(
head
->
name
))
return
0
;
/* Don't even try to ask for the annotation target */
if
(
!
git__suffixcmp
(
head
->
name
,
"^{}"
))
if
(
!
p
->
found_head
&&
strcmp
(
head
->
name
,
GIT_HEAD_FILE
)
==
0
)
p
->
found_head
=
1
;
else
if
(
git_refspec_src_matches
(
p
->
spec
,
head
->
name
))
match
=
1
;
else
if
(
p
->
remote
->
download_tags
==
GIT_REMOTE_DOWNLOAD_TAGS_ALL
&&
git_refspec_src_matches
(
p
->
tagspec
,
head
->
name
))
match
=
1
;
if
(
!
match
)
return
0
;
}
/* If we have the object, mark it so we don't ask for it */
if
(
git_odb_exists
(
p
->
odb
,
&
head
->
oid
))
...
...
@@ -54,8 +57,11 @@ static int filter_ref__cb(git_remote_head *head, void *payload)
static
int
filter_wants
(
git_remote
*
remote
)
{
struct
filter_payload
p
;
git_refspec
tagspec
;
git_vector_clear
(
&
remote
->
refs
);
if
(
git_refspec__parse
(
&
tagspec
,
GIT_REFSPEC_TAGS
,
true
)
<
0
)
return
-
1
;
/*
* The fetch refspec can be NULL, and what this means is that the
...
...
@@ -64,6 +70,7 @@ static int filter_wants(git_remote *remote)
* HEAD, which will be stored in FETCH_HEAD after the fetch.
*/
p
.
spec
=
git_remote_fetchspec
(
remote
);
p
.
tagspec
=
&
tagspec
;
p
.
found_head
=
0
;
p
.
remote
=
remote
;
...
...
src/pkt.c
View file @
bdaa40d3
...
...
@@ -354,6 +354,9 @@ static int buffer_want_with_caps(git_remote_head *head, git_transport_caps *caps
if
(
caps
->
multi_ack
)
git_buf_puts
(
&
str
,
GIT_CAP_MULTI_ACK
" "
);
if
(
caps
->
include_tag
)
git_buf_puts
(
&
str
,
GIT_CAP_INCLUDE_TAG
" "
);
if
(
git_buf_oom
(
&
str
))
return
-
1
;
...
...
src/protocol.c
View file @
bdaa40d3
...
...
@@ -80,6 +80,12 @@ int git_protocol_detect_caps(git_pkt_ref *pkt, git_transport_caps *caps)
continue
;
}
if
(
!
git__prefixcmp
(
ptr
,
GIT_CAP_INCLUDE_TAG
))
{
caps
->
common
=
caps
->
include_tag
=
1
;
ptr
+=
strlen
(
GIT_CAP_INCLUDE_TAG
);
continue
;
}
/* Keep side-band check after side-band-64k */
if
(
!
git__prefixcmp
(
ptr
,
GIT_CAP_SIDE_BAND_64K
))
{
caps
->
common
=
caps
->
side_band_64k
=
1
;
...
...
src/refs.c
View file @
bdaa40d3
...
...
@@ -1199,6 +1199,7 @@ int git_reference_create_symbolic(
{
char
normalized
[
GIT_REFNAME_MAX
];
git_reference
*
ref
=
NULL
;
int
error
;
if
(
git_reference__normalize_name_lax
(
normalized
,
...
...
@@ -1206,8 +1207,8 @@ int git_reference_create_symbolic(
name
)
<
0
)
return
-
1
;
if
(
reference_can_write
(
repo
,
normalized
,
NULL
,
force
)
<
0
)
return
-
1
;
if
(
(
error
=
reference_can_write
(
repo
,
normalized
,
NULL
,
force
)
)
<
0
)
return
error
;
if
(
reference_alloc
(
&
ref
,
repo
,
normalized
)
<
0
)
return
-
1
;
...
...
@@ -1236,6 +1237,7 @@ int git_reference_create_oid(
const
git_oid
*
id
,
int
force
)
{
int
error
;
git_reference
*
ref
=
NULL
;
char
normalized
[
GIT_REFNAME_MAX
];
...
...
@@ -1245,8 +1247,8 @@ int git_reference_create_oid(
name
)
<
0
)
return
-
1
;
if
(
reference_can_write
(
repo
,
normalized
,
NULL
,
force
)
<
0
)
return
-
1
;
if
(
(
error
=
reference_can_write
(
repo
,
normalized
,
NULL
,
force
)
)
<
0
)
return
error
;
if
(
reference_alloc
(
&
ref
,
repo
,
name
)
<
0
)
return
-
1
;
...
...
src/refspec.c
View file @
bdaa40d3
...
...
@@ -125,35 +125,10 @@ int git_refspec__parse(git_refspec *refspec, const char *input, bool is_fetch)
return
-
1
;
}
int
git_refspec_parse
(
git_refspec
*
refspec
,
const
char
*
str
)
void
git_refspec__free
(
git_refspec
*
refspec
)
{
char
*
delim
;
memset
(
refspec
,
0x0
,
sizeof
(
git_refspec
));
if
(
*
str
==
'+'
)
{
refspec
->
force
=
1
;
str
++
;
}
delim
=
strchr
(
str
,
':'
);
if
(
delim
==
NULL
)
{
refspec
->
src
=
git__strdup
(
str
);
GITERR_CHECK_ALLOC
(
refspec
->
src
);
return
0
;
}
refspec
->
src
=
git__strndup
(
str
,
delim
-
str
);
GITERR_CHECK_ALLOC
(
refspec
->
src
);
refspec
->
dst
=
git__strdup
(
delim
+
1
);
if
(
refspec
->
dst
==
NULL
)
{
git__free
(
refspec
->
src
);
refspec
->
src
=
NULL
;
return
-
1
;
}
return
0
;
git__free
(
refspec
->
dst
);
}
const
char
*
git_refspec_src
(
const
git_refspec
*
refspec
)
...
...
src/refspec.h
View file @
bdaa40d3
...
...
@@ -19,12 +19,16 @@ struct git_refspec {
matching
:
1
;
};
#define GIT_REFSPEC_TAGS "refs/tags
/*:refs/tags/*"
int git_refspec_parse(struct git_refspec *refspec, const char *str);
int git_refspec__parse(
struct git_refspec *refspec,
const char *str,
bool is_fetch);
void git_refspec__free(git_refspec *refspec);
/**
* Transform a reference to its target following the refspec's rules,
* and writes the results into a git_buf.
...
...
src/remote.c
View file @
bdaa40d3
...
...
@@ -18,41 +18,42 @@
#include <regex.h>
static
int
refspec_parse
(
git_refspec
*
refspec
,
const
char
*
str
)
static
int
parse_remote_refspec
(
git_config
*
cfg
,
git_refspec
*
refspec
,
const
char
*
var
,
bool
is_fetch
)
{
char
*
delim
;
int
error
;
const
char
*
val
;
memset
(
refspec
,
0x0
,
sizeof
(
git_refspec
));
if
((
error
=
git_config_get_string
(
&
val
,
cfg
,
var
))
<
0
)
return
error
;
if
(
*
str
==
'+'
)
{
refspec
->
force
=
1
;
str
++
;
}
return
git_refspec__parse
(
refspec
,
val
,
is_fetch
);
}
delim
=
strchr
(
str
,
':'
);
if
(
delim
==
NULL
)
{
giterr_set
(
GITERR_NET
,
"Invalid refspec, missing ':'"
)
;
return
-
1
;
}
static
int
download_tags_value
(
git_remote
*
remote
,
git_config
*
cfg
)
{
const
char
*
val
;
git_buf
buf
=
GIT_BUF_INIT
;
int
error
;
refspec
->
src
=
git__strndup
(
str
,
delim
-
str
);
GITERR_CHECK_ALLOC
(
refspec
->
src
)
;
if
(
remote
->
download_tags
!=
GIT_REMOTE_DOWNLOAD_TAGS_UNSET
)
return
0
;
refspec
->
dst
=
git__strdup
(
delim
+
1
);
GITERR_CHECK_ALLOC
(
refspec
->
dst
);
/* This is the default, let's see if we need to change it */
remote
->
download_tags
=
GIT_REMOTE_DOWNLOAD_TAGS_AUTO
;
if
(
git_buf_printf
(
&
buf
,
"remote.%s.tagopt"
,
remote
->
name
)
<
0
)
return
-
1
;
return
0
;
}
error
=
git_config_get_string
(
&
val
,
cfg
,
git_buf_cstr
(
&
buf
));
git_buf_free
(
&
buf
);
if
(
!
error
&&
!
strcmp
(
val
,
"--no-tags"
))
remote
->
download_tags
=
GIT_REMOTE_DOWNLOAD_TAGS_NONE
;
else
if
(
!
error
&&
!
strcmp
(
val
,
"--tags"
))
remote
->
download_tags
=
GIT_REMOTE_DOWNLOAD_TAGS_ALL
;
static
int
parse_remote_refspec
(
git_config
*
cfg
,
git_refspec
*
refspec
,
const
char
*
var
)
{
int
error
;
const
char
*
val
;
if
(
error
==
GIT_ENOTFOUND
)
error
=
0
;
if
((
error
=
git_config_get_string
(
&
val
,
cfg
,
var
))
<
0
)
return
error
;
return
refspec_parse
(
refspec
,
val
);
}
int
git_remote_new
(
git_remote
**
out
,
git_repository
*
repo
,
const
char
*
name
,
const
char
*
url
,
const
char
*
fetch
)
...
...
@@ -81,7 +82,7 @@ int git_remote_new(git_remote **out, git_repository *repo, const char *name, con
}
if
(
fetch
!=
NULL
)
{
if
(
refspec_parse
(
&
remote
->
fetch
,
fetch
)
<
0
)
if
(
git_refspec__parse
(
&
remote
->
fetch
,
fetch
,
true
)
<
0
)
goto
on_error
;
}
...
...
@@ -157,7 +158,7 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
goto
cleanup
;
}
error
=
parse_remote_refspec
(
config
,
&
remote
->
fetch
,
git_buf_cstr
(
&
buf
));
error
=
parse_remote_refspec
(
config
,
&
remote
->
fetch
,
git_buf_cstr
(
&
buf
)
,
true
);
if
(
error
==
GIT_ENOTFOUND
)
error
=
0
;
...
...
@@ -172,7 +173,7 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
goto
cleanup
;
}
error
=
parse_remote_refspec
(
config
,
&
remote
->
push
,
git_buf_cstr
(
&
buf
));
error
=
parse_remote_refspec
(
config
,
&
remote
->
push
,
git_buf_cstr
(
&
buf
)
,
false
);
if
(
error
==
GIT_ENOTFOUND
)
error
=
0
;
...
...
@@ -181,6 +182,9 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
goto
cleanup
;
}
if
(
download_tags_value
(
remote
,
config
)
<
0
)
goto
cleanup
;
*
out
=
remote
;
cleanup:
...
...
@@ -317,11 +321,10 @@ int git_remote_set_fetchspec(git_remote *remote, const char *spec)
assert
(
remote
&&
spec
);
if
(
refspec_parse
(
&
refspec
,
spec
)
<
0
)
if
(
git_refspec__parse
(
&
refspec
,
spec
,
true
)
<
0
)
return
-
1
;
git__free
(
remote
->
fetch
.
src
);
git__free
(
remote
->
fetch
.
dst
);
git_refspec__free
(
&
remote
->
fetch
);
remote
->
fetch
.
src
=
refspec
.
src
;
remote
->
fetch
.
dst
=
refspec
.
dst
;
...
...
@@ -340,11 +343,10 @@ int git_remote_set_pushspec(git_remote *remote, const char *spec)
assert
(
remote
&&
spec
);
if
(
refspec_parse
(
&
refspec
,
spec
)
<
0
)
if
(
git_refspec__parse
(
&
refspec
,
spec
,
false
)
<
0
)
return
-
1
;
git__free
(
remote
->
push
.
src
);
git__free
(
remote
->
push
.
dst
);
git_refspec__free
(
&
remote
->
push
);
remote
->
push
.
src
=
refspec
.
src
;
remote
->
push
.
dst
=
refspec
.
dst
;
...
...
@@ -445,25 +447,35 @@ int git_remote_download(git_remote *remote, git_off_t *bytes, git_indexer_stats
int
git_remote_update_tips
(
git_remote
*
remote
)
{
int
error
=
0
;
int
error
=
0
,
autotag
;
unsigned
int
i
=
0
;
git_buf
refname
=
GIT_BUF_INIT
;
git_oid
old
;
git_pkt
*
pkt
;
git_odb
*
odb
;
git_vector
*
refs
;
git_remote_head
*
head
;
git_reference
*
ref
;
struct
git_refspec
*
spec
;
git_refspec
tagspec
;
assert
(
remote
);
refs
=
&
remote
->
refs
;
refs
=
&
remote
->
transport
->
refs
;
spec
=
&
remote
->
fetch
;
if
(
refs
->
length
==
0
)
return
0
;
if
(
git_repository_odb
(
&
odb
,
remote
->
repo
)
<
0
)
return
-
1
;
if
(
git_refspec__parse
(
&
tagspec
,
GIT_REFSPEC_TAGS
,
true
)
<
0
)
return
-
1
;
/* HEAD is only allowed to be the first in the list */
head
=
refs
->
contents
[
0
];
pkt
=
refs
->
contents
[
0
];
head
=
&
((
git_pkt_ref
*
)
pkt
)
->
head
;
if
(
!
strcmp
(
head
->
name
,
GIT_HEAD_FILE
))
{
if
(
git_reference_create_oid
(
&
ref
,
remote
->
repo
,
GIT_FETCH_HEAD_FILE
,
&
head
->
oid
,
1
)
<
0
)
return
-
1
;
...
...
@@ -473,10 +485,38 @@ int git_remote_update_tips(git_remote *remote)
}
for
(;
i
<
refs
->
length
;
++
i
)
{
head
=
refs
->
contents
[
i
];
autotag
=
0
;
git_pkt
*
pkt
=
refs
->
contents
[
i
];
if
(
pkt
->
type
==
GIT_PKT_REF
)
head
=
&
((
git_pkt_ref
*
)
pkt
)
->
head
;
else
continue
;
/* Ignore malformed ref names (which also saves us from tag^{} */
if
(
!
git_reference_is_valid_name
(
head
->
name
))
continue
;
if
(
git_refspec_src_matches
(
spec
,
head
->
name
))
{
if
(
git_refspec_transform_r
(
&
refname
,
spec
,
head
->
name
)
<
0
)
goto
on_error
;
}
else
if
(
remote
->
download_tags
!=
GIT_REMOTE_DOWNLOAD_TAGS_NONE
)
{
if
(
remote
->
download_tags
!=
GIT_REMOTE_DOWNLOAD_TAGS_ALL
)
autotag
=
1
;
if
(
!
git_refspec_src_matches
(
&
tagspec
,
head
->
name
))
continue
;
git_buf_clear
(
&
refname
);
if
(
git_buf_puts
(
&
refname
,
head
->
name
)
<
0
)
goto
on_error
;
}
else
{
continue
;
}
if
(
autotag
&&
!
git_odb_exists
(
odb
,
&
head
->
oid
))
continue
;
error
=
git_reference_name_to_oid
(
&
old
,
remote
->
repo
,
refname
.
ptr
);
if
(
error
<
0
&&
error
!=
GIT_ENOTFOUND
)
...
...
@@ -488,7 +528,9 @@ int git_remote_update_tips(git_remote *remote)
if
(
!
git_oid_cmp
(
&
old
,
&
head
->
oid
))
continue
;
if
(
git_reference_create_oid
(
&
ref
,
remote
->
repo
,
refname
.
ptr
,
&
head
->
oid
,
1
)
<
0
)
/* In autotag mode, don't overwrite any locally-existing tags */
error
=
git_reference_create_oid
(
&
ref
,
remote
->
repo
,
refname
.
ptr
,
&
head
->
oid
,
!
autotag
);
if
(
error
<
0
&&
error
!=
GIT_EEXISTS
)
goto
on_error
;
git_reference_free
(
ref
);
...
...
@@ -499,10 +541,12 @@ int git_remote_update_tips(git_remote *remote)
}
}
git_refspec__free
(
&
tagspec
);
git_buf_free
(
&
refname
);
return
0
;
on_error:
git_refspec__free
(
&
tagspec
);
git_buf_free
(
&
refname
);
return
-
1
;
...
...
@@ -536,10 +580,8 @@ void git_remote_free(git_remote *remote)
git_vector_free
(
&
remote
->
refs
);
git__free
(
remote
->
fetch
.
src
);
git__free
(
remote
->
fetch
.
dst
);
git__free
(
remote
->
push
.
src
);
git__free
(
remote
->
push
.
dst
);
git_refspec__free
(
&
remote
->
fetch
);
git_refspec__free
(
&
remote
->
push
);
git__free
(
remote
->
url
);
git__free
(
remote
->
pushurl
);
git__free
(
remote
->
name
);
...
...
@@ -655,3 +697,13 @@ void git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callback
remote
->
transport
->
cb_data
=
remote
->
callbacks
.
data
;
}
}
int
git_remote_autotag
(
git_remote
*
remote
)
{
return
remote
->
download_tags
;
}
void
git_remote_set_autotag
(
git_remote
*
remote
,
int
value
)
{
remote
->
download_tags
=
value
;
}
src/remote.h
View file @
bdaa40d3
...
...
@@ -24,7 +24,8 @@ struct git_remote {
git_repository
*
repo
;
git_remote_callbacks
callbacks
;
unsigned
int
need_pack
:
1
,
check_cert
;
download_tags
:
2
,
/* There are four possible values */
check_cert
:
1
;
};
const
char
*
git_remote__urlfordirection
(
struct
git_remote
*
remote
,
int
direction
);
...
...
src/transport.h
View file @
bdaa40d3
...
...
@@ -23,13 +23,15 @@
#define GIT_CAP_MULTI_ACK "multi_ack"
#define GIT_CAP_SIDE_BAND "side-band"
#define GIT_CAP_SIDE_BAND_64K "side-band-64k"
#define GIT_CAP_INCLUDE_TAG "include-tag"
typedef
struct
git_transport_caps
{
int
common
:
1
,
ofs_delta
:
1
,
multi_ack
:
1
,
side_band
:
1
,
side_band_64k
:
1
;
side_band_64k
:
1
,
include_tag
:
1
;
}
git_transport_caps
;
#ifdef GIT_SSL
...
...
tests-clar/network/refspecs.c
View file @
bdaa40d3
...
...
@@ -8,6 +8,7 @@ static void assert_refspec(unsigned int direction, const char *input, bool is_ex
int
error
;
error
=
git_refspec__parse
(
&
refspec
,
input
,
direction
==
GIT_DIR_FETCH
);
git_refspec__free
(
&
refspec
);
if
(
is_expected_to_be_valid
)
cl_assert_equal_i
(
0
,
error
);
...
...
tests-clar/refs/create.c
View file @
bdaa40d3
...
...
@@ -147,3 +147,18 @@ void test_refs_create__oid_unknown(void)
/* Ensure the reference can't be looked-up... */
cl_git_fail
(
git_reference_lookup
(
&
looked_up_ref
,
g_repo
,
new_head
));
}
void
test_refs_create__propagate_eexists
(
void
)
{
int
error
;
git_oid
oid
;
git_reference
*
ref
;
/* Make sure it works for oid and for symbolic both */
git_oid_fromstr
(
&
oid
,
current_master_tip
);
error
=
git_reference_create_oid
(
&
ref
,
g_repo
,
current_head_target
,
&
oid
,
false
);
cl_assert
(
error
==
GIT_EEXISTS
);
error
=
git_reference_create_symbolic
(
&
ref
,
g_repo
,
"HEAD"
,
current_head_target
,
false
);
cl_assert
(
error
==
GIT_EEXISTS
);
}
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