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
53fcd5b8
Commit
53fcd5b8
authored
Dec 02, 2022
by
Edward Thomson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
transport: teach transports about oid types and SHA256
parent
0006ff63
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
298 additions
and
83 deletions
+298
-83
include/git2/sys/transport.h
+12
-0
src/libgit2/clone.c
+25
-1
src/libgit2/fetch.c
+0
-4
src/libgit2/indexer.c
+41
-15
src/libgit2/remote.c
+32
-32
src/libgit2/remote.h
+32
-0
src/libgit2/streams/socket.c
+3
-1
src/libgit2/transports/local.c
+14
-0
src/libgit2/transports/smart.c
+35
-0
src/libgit2/transports/smart.h
+4
-0
src/libgit2/transports/smart_pkt.c
+60
-28
src/libgit2/transports/smart_protocol.c
+27
-2
src/util/hash.h
+13
-0
No files found.
include/git2/sys/transport.h
View file @
53fcd5b8
...
...
@@ -57,6 +57,18 @@ struct git_transport {
unsigned
int
*
capabilities
,
git_transport
*
transport
);
#ifdef GIT_EXPERIMENTAL_SHA256
/**
* Gets the object type for the remote repository.
*
* This function may be called after a successful call to
* `connect()`.
*/
int
GIT_CALLBACK
(
oid_type
)(
git_oid_t
*
object_type
,
git_transport
*
transport
);
#endif
/**
* Get the list of available references in the remote repository.
*
...
...
src/libgit2/clone.c
View file @
53fcd5b8
...
...
@@ -393,12 +393,19 @@ static int checkout_branch(git_repository *repo, git_remote *remote, const git_c
return
error
;
}
static
int
clone_into
(
git_repository
*
repo
,
git_remote
*
_remote
,
const
git_fetch_options
*
opts
,
const
git_checkout_options
*
co_opts
,
const
char
*
branch
)
static
int
clone_into
(
git_repository
*
repo
,
git_remote
*
_remote
,
const
git_fetch_options
*
opts
,
const
git_checkout_options
*
co_opts
,
const
char
*
branch
)
{
int
error
;
git_str
reflog_message
=
GIT_STR_INIT
;
git_remote_connect_options
connect_opts
=
GIT_REMOTE_CONNECT_OPTIONS_INIT
;
git_fetch_options
fetch_opts
;
git_remote
*
remote
;
git_oid_t
oid_type
;
GIT_ASSERT_ARG
(
repo
);
GIT_ASSERT_ARG
(
_remote
);
...
...
@@ -414,8 +421,25 @@ static int clone_into(git_repository *repo, git_remote *_remote, const git_fetch
memcpy
(
&
fetch_opts
,
opts
,
sizeof
(
git_fetch_options
));
fetch_opts
.
update_fetchhead
=
0
;
fetch_opts
.
download_tags
=
GIT_REMOTE_DOWNLOAD_TAGS_ALL
;
if
((
error
=
git_remote_connect_options__from_fetch_opts
(
&
connect_opts
,
remote
,
&
fetch_opts
))
<
0
)
return
error
;
git_str_printf
(
&
reflog_message
,
"clone: from %s"
,
git_remote_url
(
remote
));
/*
* Connect to the server so that we can identify the remote
* object format.
*/
if
((
error
=
git_remote_connect_ext
(
remote
,
GIT_DIRECTION_FETCH
,
&
connect_opts
))
<
0
)
goto
cleanup
;
if
((
error
=
git_remote_oid_type
(
&
oid_type
,
remote
))
<
0
||
(
error
=
git_repository__set_objectformat
(
repo
,
oid_type
))
<
0
)
goto
cleanup
;
if
((
error
=
git_remote_fetch
(
remote
,
NULL
,
&
fetch_opts
,
git_str_cstr
(
&
reflog_message
)))
!=
0
)
goto
cleanup
;
...
...
src/libgit2/fetch.c
View file @
53fcd5b8
...
...
@@ -95,7 +95,6 @@ static int filter_wants(git_remote *remote, const git_fetch_options *opts)
git_remote_head
**
heads
;
git_refspec
tagspec
,
head
,
*
spec
;
int
error
=
0
;
git_odb
*
odb
;
size_t
i
,
heads_len
;
unsigned
int
remote_caps
;
unsigned
int
oid_mask
=
GIT_REMOTE_CAPABILITY_TIP_OID
|
...
...
@@ -126,9 +125,6 @@ static int filter_wants(git_remote *remote, const git_fetch_options *opts)
goto
cleanup
;
}
if
((
error
=
git_repository_odb__weakptr
(
&
odb
,
remote
->
repo
))
<
0
)
goto
cleanup
;
if
((
error
=
git_remote_ls
((
const
git_remote_head
***
)
&
heads
,
&
heads_len
,
remote
))
<
0
||
(
error
=
git_remote_capabilities
(
&
remote_caps
,
remote
))
<
0
)
goto
cleanup
;
...
...
src/libgit2/indexer.c
View file @
53fcd5b8
...
...
@@ -56,8 +56,8 @@ struct git_indexer {
git_vector
deltas
;
unsigned
int
fanout
[
256
];
git_hash_ctx
hash_ctx
;
unsigned
char
checksum
[
GIT_HASH_
SHA1
_SIZE
];
char
name
[(
GIT_HASH_
SHA1
_SIZE
*
2
)
+
1
];
unsigned
char
checksum
[
GIT_HASH_
MAX
_SIZE
];
char
name
[(
GIT_HASH_
MAX
_SIZE
*
2
)
+
1
];
git_indexer_progress_cb
progress_cb
;
void
*
progress_payload
;
char
objbuf
[
8
*
1024
];
...
...
@@ -69,7 +69,7 @@ struct git_indexer {
git_odb
*
odb
;
/* Fields for calculating the packfile trailer (hash of everything before it) */
char
inbuf
[
GIT_
OID
_MAX_SIZE
];
char
inbuf
[
GIT_
HASH
_MAX_SIZE
];
size_t
inbuf_len
;
git_hash_ctx
trailer
;
};
...
...
@@ -137,6 +137,20 @@ int git_indexer_init_options(git_indexer_options *opts, unsigned int version)
}
#endif
GIT_INLINE
(
git_hash_algorithm_t
)
indexer_hash_algorithm
(
git_indexer
*
idx
)
{
switch
(
idx
->
oid_type
)
{
case
GIT_OID_SHA1
:
return
GIT_HASH_ALGORITHM_SHA1
;
#ifdef GIT_EXPERIMENTAL_SHA256
case
GIT_OID_SHA256
:
return
GIT_HASH_ALGORITHM_SHA256
;
#endif
}
return
GIT_HASH_ALGORITHM_NONE
;
}
static
int
indexer_new
(
git_indexer
**
out
,
const
char
*
prefix
,
...
...
@@ -149,6 +163,7 @@ static int indexer_new(
git_indexer
*
idx
;
git_str
path
=
GIT_STR_INIT
,
tmp_path
=
GIT_STR_INIT
;
static
const
char
suff
[]
=
"/pack"
;
git_hash_algorithm_t
checksum_type
;
int
error
,
fd
=
-
1
;
if
(
in_opts
)
...
...
@@ -163,8 +178,10 @@ static int indexer_new(
idx
->
mode
=
mode
?
mode
:
GIT_PACK_FILE_MODE
;
git_str_init
(
&
idx
->
entry_data
,
0
);
if
((
error
=
git_hash_ctx_init
(
&
idx
->
hash_ctx
,
GIT_HASH_ALGORITHM_SHA1
))
<
0
||
(
error
=
git_hash_ctx_init
(
&
idx
->
trailer
,
GIT_HASH_ALGORITHM_SHA1
))
<
0
||
checksum_type
=
indexer_hash_algorithm
(
idx
);
if
((
error
=
git_hash_ctx_init
(
&
idx
->
hash_ctx
,
checksum_type
))
<
0
||
(
error
=
git_hash_ctx_init
(
&
idx
->
trailer
,
checksum_type
))
<
0
||
(
error
=
git_oidmap_new
(
&
idx
->
expected_oids
))
<
0
)
goto
cleanup
;
...
...
@@ -182,8 +199,7 @@ static int indexer_new(
if
(
fd
<
0
)
goto
cleanup
;
/* TODO: SHA256 */
error
=
git_packfile_alloc
(
&
idx
->
pack
,
git_str_cstr
(
&
tmp_path
),
0
);
error
=
git_packfile_alloc
(
&
idx
->
pack
,
git_str_cstr
(
&
tmp_path
),
oid_type
);
git_str_dispose
(
&
tmp_path
);
if
(
error
<
0
)
...
...
@@ -614,7 +630,7 @@ static int do_progress_callback(git_indexer *idx, git_indexer_progress *stats)
return
0
;
}
/* Hash everything but the
last 20B of input
*/
/* Hash everything but the
checksum trailer
*/
static
void
hash_partially
(
git_indexer
*
idx
,
const
uint8_t
*
data
,
size_t
size
)
{
size_t
to_expell
,
to_keep
;
...
...
@@ -623,7 +639,10 @@ static void hash_partially(git_indexer *idx, const uint8_t *data, size_t size)
if
(
size
==
0
)
return
;
/* Easy case, dump the buffer and the data minus the last 20 bytes */
/*
* Easy case, dump the buffer and the data minus the trailing
* checksum (SHA1 or SHA256).
*/
if
(
size
>=
oid_size
)
{
git_hash_update
(
&
idx
->
trailer
,
idx
->
inbuf
,
idx
->
inbuf_len
);
git_hash_update
(
&
idx
->
trailer
,
data
,
size
-
oid_size
);
...
...
@@ -761,12 +780,14 @@ static int read_stream_object(git_indexer *idx, git_indexer_progress *stats)
{
git_packfile_stream
*
stream
=
&
idx
->
stream
;
off64_t
entry_start
=
idx
->
off
;
size_t
entry_size
;
size_t
oid_size
,
entry_size
;
git_object_t
type
;
git_mwindow
*
w
=
NULL
;
int
error
;
if
(
idx
->
pack
->
mwf
.
size
<=
idx
->
off
+
20
)
oid_size
=
git_oid_size
(
idx
->
oid_type
);
if
(
idx
->
pack
->
mwf
.
size
<=
idx
->
off
+
(
long
long
)
oid_size
)
return
GIT_EBUFS
;
if
(
!
idx
->
have_stream
)
{
...
...
@@ -963,15 +984,17 @@ static int inject_object(git_indexer *idx, git_oid *id)
git_odb_object
*
obj
=
NULL
;
struct
entry
*
entry
=
NULL
;
struct
git_pack_entry
*
pentry
=
NULL
;
unsigned
char
empty_checksum
[
GIT_HASH_
SHA1
_SIZE
]
=
{
0
};
unsigned
char
empty_checksum
[
GIT_HASH_
MAX
_SIZE
]
=
{
0
};
unsigned
char
hdr
[
64
];
git_str
buf
=
GIT_STR_INIT
;
off64_t
entry_start
;
const
void
*
data
;
size_t
len
,
hdr_len
;
size_t
checksum_size
=
GIT_HASH_SHA1_SIZE
;
size_t
checksum_size
;
int
error
;
checksum_size
=
git_hash_size
(
indexer_hash_algorithm
(
idx
));
if
((
error
=
seek_back_trailer
(
idx
))
<
0
)
goto
cleanup
;
...
...
@@ -1205,10 +1228,10 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
struct
git_pack_idx_header
hdr
;
git_str
filename
=
GIT_STR_INIT
;
struct
entry
*
entry
;
unsigned
char
checksum
[
GIT_HASH_
SHA1
_SIZE
];
unsigned
char
checksum
[
GIT_HASH_
MAX
_SIZE
];
git_filebuf
index_file
=
{
0
};
void
*
packfile_trailer
;
size_t
checksum_size
=
GIT_HASH_SHA1_SIZE
;
size_t
checksum_size
;
bool
mismatch
;
if
(
!
idx
->
parsed_header
)
{
...
...
@@ -1216,6 +1239,9 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
return
-
1
;
}
checksum_size
=
git_hash_size
(
indexer_hash_algorithm
(
idx
));
GIT_ASSERT
(
checksum_size
);
/* Test for this before resolve_deltas(), as it plays with idx->off */
if
(
idx
->
off
+
(
ssize_t
)
checksum_size
<
idx
->
pack
->
mwf
.
size
)
{
git_error_set
(
GIT_ERROR_INDEXER
,
"unexpected data at the end of the pack"
);
...
...
src/libgit2/remote.c
View file @
53fcd5b8
...
...
@@ -1026,6 +1026,24 @@ int git_remote_capabilities(unsigned int *out, git_remote *remote)
return
remote
->
transport
->
capabilities
(
out
,
remote
->
transport
);
}
int
git_remote_oid_type
(
git_oid_t
*
out
,
git_remote
*
remote
)
{
GIT_ASSERT_ARG
(
remote
);
if
(
!
remote
->
transport
)
{
git_error_set
(
GIT_ERROR_NET
,
"this remote has never connected"
);
*
out
=
0
;
return
-
1
;
}
#ifdef GIT_EXPERIMENTAL_SHA256
return
remote
->
transport
->
oid_type
(
out
,
remote
->
transport
);
#else
*
out
=
GIT_OID_SHA1
;
return
0
;
#endif
}
static
int
lookup_config
(
char
**
out
,
git_config
*
cfg
,
const
char
*
name
)
{
git_config_entry
*
ce
=
NULL
;
...
...
@@ -1225,24 +1243,6 @@ static int ls_to_vector(git_vector *out, git_remote *remote)
return
0
;
}
#define copy_opts(out, in) \
if (in) { \
(out)->callbacks = (in)->callbacks; \
(out)->proxy_opts = (in)->proxy_opts; \
(out)->custom_headers = (in)->custom_headers; \
(out)->follow_redirects = (in)->follow_redirects; \
}
GIT_INLINE
(
int
)
connect_opts_from_fetch_opts
(
git_remote_connect_options
*
out
,
git_remote
*
remote
,
const
git_fetch_options
*
fetch_opts
)
{
git_remote_connect_options
tmp
=
GIT_REMOTE_CONNECT_OPTIONS_INIT
;
copy_opts
(
&
tmp
,
fetch_opts
);
return
git_remote_connect_options_normalize
(
out
,
remote
->
repo
,
&
tmp
);
}
static
int
connect_or_reset_options
(
git_remote
*
remote
,
int
direction
,
...
...
@@ -1330,7 +1330,8 @@ int git_remote_download(
return
-
1
;
}
if
(
connect_opts_from_fetch_opts
(
&
connect_opts
,
remote
,
opts
)
<
0
)
if
(
git_remote_connect_options__from_fetch_opts
(
&
connect_opts
,
remote
,
opts
)
<
0
)
return
-
1
;
if
((
error
=
connect_or_reset_options
(
remote
,
GIT_DIRECTION_FETCH
,
&
connect_opts
))
<
0
)
...
...
@@ -1350,6 +1351,8 @@ int git_remote_fetch(
bool
prune
=
false
;
git_str
reflog_msg_buf
=
GIT_STR_INIT
;
git_remote_connect_options
connect_opts
=
GIT_REMOTE_CONNECT_OPTIONS_INIT
;
unsigned
int
capabilities
;
git_oid_t
oid_type
;
GIT_ASSERT_ARG
(
remote
);
...
...
@@ -1358,7 +1361,8 @@ int git_remote_fetch(
return
-
1
;
}
if
(
connect_opts_from_fetch_opts
(
&
connect_opts
,
remote
,
opts
)
<
0
)
if
(
git_remote_connect_options__from_fetch_opts
(
&
connect_opts
,
remote
,
opts
)
<
0
)
return
-
1
;
if
((
error
=
connect_or_reset_options
(
remote
,
GIT_DIRECTION_FETCH
,
&
connect_opts
))
<
0
)
...
...
@@ -1369,6 +1373,10 @@ int git_remote_fetch(
tagopt
=
opts
->
download_tags
;
}
if
((
error
=
git_remote_capabilities
(
&
capabilities
,
remote
))
<
0
||
(
error
=
git_remote_oid_type
(
&
oid_type
,
remote
))
<
0
)
return
error
;
/* Connect and download everything */
error
=
git_remote__download
(
remote
,
refspecs
,
opts
);
...
...
@@ -2896,16 +2904,6 @@ done:
return
error
;
}
GIT_INLINE
(
int
)
connect_opts_from_push_opts
(
git_remote_connect_options
*
out
,
git_remote
*
remote
,
const
git_push_options
*
push_opts
)
{
git_remote_connect_options
tmp
=
GIT_REMOTE_CONNECT_OPTIONS_INIT
;
copy_opts
(
&
tmp
,
push_opts
);
return
git_remote_connect_options_normalize
(
out
,
remote
->
repo
,
&
tmp
);
}
int
git_remote_upload
(
git_remote
*
remote
,
const
git_strarray
*
refspecs
,
...
...
@@ -2924,7 +2922,8 @@ int git_remote_upload(
return
-
1
;
}
if
((
error
=
connect_opts_from_push_opts
(
&
connect_opts
,
remote
,
opts
))
<
0
)
if
((
error
=
git_remote_connect_options__from_push_opts
(
&
connect_opts
,
remote
,
opts
))
<
0
)
goto
cleanup
;
if
((
error
=
connect_or_reset_options
(
remote
,
GIT_DIRECTION_PUSH
,
&
connect_opts
))
<
0
)
...
...
@@ -2985,7 +2984,8 @@ int git_remote_push(
return
-
1
;
}
if
(
connect_opts_from_push_opts
(
&
connect_opts
,
remote
,
opts
)
<
0
)
if
(
git_remote_connect_options__from_push_opts
(
&
connect_opts
,
remote
,
opts
)
<
0
)
return
-
1
;
if
((
error
=
git_remote_upload
(
remote
,
refspecs
,
opts
))
<
0
)
...
...
src/libgit2/remote.h
View file @
53fcd5b8
...
...
@@ -56,5 +56,37 @@ int git_remote_connect_options_normalize(
const
git_remote_connect_options
*
src
);
int
git_remote_capabilities
(
unsigned
int
*
out
,
git_remote
*
remote
);
int
git_remote_oid_type
(
git_oid_t
*
out
,
git_remote
*
remote
);
#define git_remote_connect_options__copy_opts(out, in) \
if (in) { \
(out)->callbacks = (in)->callbacks; \
(out)->proxy_opts = (in)->proxy_opts; \
(out)->custom_headers = (in)->custom_headers; \
(out)->follow_redirects = (in)->follow_redirects; \
}
GIT_INLINE
(
int
)
git_remote_connect_options__from_fetch_opts
(
git_remote_connect_options
*
out
,
git_remote
*
remote
,
const
git_fetch_options
*
fetch_opts
)
{
git_remote_connect_options
tmp
=
GIT_REMOTE_CONNECT_OPTIONS_INIT
;
git_remote_connect_options__copy_opts
(
&
tmp
,
fetch_opts
);
return
git_remote_connect_options_normalize
(
out
,
remote
->
repo
,
&
tmp
);
}
GIT_INLINE
(
int
)
git_remote_connect_options__from_push_opts
(
git_remote_connect_options
*
out
,
git_remote
*
remote
,
const
git_push_options
*
push_opts
)
{
git_remote_connect_options
tmp
=
GIT_REMOTE_CONNECT_OPTIONS_INIT
;
git_remote_connect_options__copy_opts
(
&
tmp
,
push_opts
);
return
git_remote_connect_options_normalize
(
out
,
remote
->
repo
,
&
tmp
);
}
#undef git_remote_connect_options__copy_opts
#endif
src/libgit2/streams/socket.c
View file @
53fcd5b8
...
...
@@ -135,9 +135,11 @@ static ssize_t socket_write(git_stream *stream, const char *data, size_t len, in
git_socket_stream
*
st
=
(
git_socket_stream
*
)
stream
;
ssize_t
written
;
assert
(
flags
==
0
);
errno
=
0
;
if
((
written
=
p_send
(
st
->
s
,
data
,
len
,
flags
))
<
0
)
{
if
((
written
=
p_send
(
st
->
s
,
data
,
len
,
0
))
<
0
)
{
net_set_error
(
"error sending data"
);
return
-
1
;
}
...
...
src/libgit2/transports/local.c
View file @
53fcd5b8
...
...
@@ -266,6 +266,17 @@ static int local_capabilities(unsigned int *capabilities, git_transport *transpo
return
0
;
}
#ifdef GIT_EXPERIMENTAL_SHA256
static
int
local_oid_type
(
git_oid_t
*
out
,
git_transport
*
transport
)
{
transport_local
*
t
=
(
transport_local
*
)
transport
;
*
out
=
t
->
repo
->
oid_type
;
return
0
;
}
#endif
static
int
local_ls
(
const
git_remote_head
***
out
,
size_t
*
size
,
git_transport
*
transport
)
{
transport_local
*
t
=
(
transport_local
*
)
transport
;
...
...
@@ -732,6 +743,9 @@ int git_transport_local(git_transport **out, git_remote *owner, void *param)
t
->
parent
.
connect
=
local_connect
;
t
->
parent
.
set_connect_opts
=
local_set_connect_opts
;
t
->
parent
.
capabilities
=
local_capabilities
;
#ifdef GIT_EXPERIMENTAL_SHA256
t
->
parent
.
oid_type
=
local_oid_type
;
#endif
t
->
parent
.
negotiate_fetch
=
local_negotiate_fetch
;
t
->
parent
.
download_pack
=
local_download_pack
;
t
->
parent
.
push
=
local_push
;
...
...
src/libgit2/transports/smart.c
View file @
53fcd5b8
...
...
@@ -54,6 +54,12 @@ GIT_INLINE(int) git_smart__reset_stream(transport_smart *t, bool close_subtransp
return
-
1
;
}
git__free
(
t
->
caps
.
object_format
);
t
->
caps
.
object_format
=
NULL
;
git__free
(
t
->
caps
.
agent
);
t
->
caps
.
agent
=
NULL
;
return
0
;
}
...
...
@@ -242,6 +248,30 @@ static int git_smart__capabilities(unsigned int *capabilities, git_transport *tr
return
0
;
}
#ifdef GIT_EXPERIMENTAL_SHA256
static
int
git_smart__oid_type
(
git_oid_t
*
out
,
git_transport
*
transport
)
{
transport_smart
*
t
=
GIT_CONTAINER_OF
(
transport
,
transport_smart
,
parent
);
*
out
=
0
;
if
(
t
->
caps
.
object_format
==
NULL
)
{
*
out
=
GIT_OID_DEFAULT
;
}
else
{
*
out
=
git_oid_type_fromstr
(
t
->
caps
.
object_format
);
if
(
!*
out
)
{
git_error_set
(
GIT_ERROR_INVALID
,
"unknown object format '%s'"
,
t
->
caps
.
object_format
);
return
-
1
;
}
}
return
0
;
}
#endif
static
int
git_smart__ls
(
const
git_remote_head
***
out
,
size_t
*
size
,
git_transport
*
transport
)
{
transport_smart
*
t
=
GIT_CONTAINER_OF
(
transport
,
transport_smart
,
parent
);
...
...
@@ -386,6 +416,8 @@ static void git_smart__free(git_transport *transport)
git_remote_connect_options_dispose
(
&
t
->
connect_opts
);
git__free
(
t
->
caps
.
object_format
);
git__free
(
t
->
caps
.
agent
);
git__free
(
t
);
}
...
...
@@ -452,6 +484,9 @@ int git_transport_smart(git_transport **out, git_remote *owner, void *param)
t
->
parent
.
connect
=
git_smart__connect
;
t
->
parent
.
set_connect_opts
=
git_smart__set_connect_opts
;
t
->
parent
.
capabilities
=
git_smart__capabilities
;
#ifdef GIT_EXPERIMENTAL_SHA256
t
->
parent
.
oid_type
=
git_smart__oid_type
;
#endif
t
->
parent
.
close
=
git_smart__close
;
t
->
parent
.
free
=
git_smart__free
;
t
->
parent
.
negotiate_fetch
=
git_smart__negotiate_fetch
;
...
...
src/libgit2/transports/smart.h
View file @
53fcd5b8
...
...
@@ -32,6 +32,8 @@
#define GIT_CAP_SYMREF "symref"
#define GIT_CAP_WANT_TIP_SHA1 "allow-tip-sha1-in-want"
#define GIT_CAP_WANT_REACHABLE_SHA1 "allow-reachable-sha1-in-want"
#define GIT_CAP_OBJECT_FORMAT "object-format="
#define GIT_CAP_AGENT "agent="
extern
bool
git_smart__ofs_delta_enabled
;
...
...
@@ -133,6 +135,8 @@ typedef struct transport_smart_caps {
thin_pack
:
1
,
want_tip_sha1
:
1
,
want_reachable_sha1
:
1
;
char
*
object_format
;
char
*
agent
;
}
transport_smart_caps
;
typedef
int
(
*
packetsize_cb
)(
size_t
received
,
void
*
payload
);
...
...
src/libgit2/transports/smart_pkt.c
View file @
53fcd5b8
...
...
@@ -21,11 +21,14 @@
#include <ctype.h>
#define PKT_LEN_SIZE 4
static
const
char
pkt_done_str
[]
=
"0009done
\n
"
;
static
const
char
pkt_flush_str
[]
=
"0000"
;
static
const
char
pkt_have_prefix
[]
=
"0032have "
;
static
const
char
pkt_want_prefix
[]
=
"0032want "
;
#define PKT_DONE_STR "0009done\n"
#define PKT_FLUSH_STR "0000"
#define PKT_HAVE_PREFIX "have "
#define PKT_WANT_PREFIX "want "
#define PKT_LEN_SIZE 4
#define PKT_MAX_SIZE 0xffff
#define PKT_MAX_WANTLEN (PKT_LEN_SIZE + CONST_STRLEN(PKT_WANT_PREFIX) + GIT_OID_MAX_HEXSIZE + 1)
static
int
flush_pkt
(
git_pkt
**
out
)
{
...
...
@@ -598,16 +601,20 @@ void git_pkt_free(git_pkt *pkt)
int
git_pkt_buffer_flush
(
git_str
*
buf
)
{
return
git_str_put
(
buf
,
pkt_flush_str
,
strlen
(
pkt_flush_str
));
return
git_str_put
(
buf
,
PKT_FLUSH_STR
,
CONST_STRLEN
(
PKT_FLUSH_STR
));
}
static
int
buffer_want_with_caps
(
const
git_remote_head
*
head
,
transport_smart_caps
*
caps
,
git_str
*
buf
)
static
int
buffer_want_with_caps
(
const
git_remote_head
*
head
,
transport_smart_caps
*
caps
,
git_oid_t
oid_type
,
git_str
*
buf
)
{
git_str
str
=
GIT_STR_INIT
;
char
oid
[
GIT_OID_MAX_HEXSIZE
+
1
]
=
{
0
}
;
char
oid
[
GIT_OID_MAX_HEXSIZE
]
;
size_t
oid_hexsize
,
len
;
oid_hexsize
=
git_oid_hexsize
(
head
->
oid
.
type
);
oid_hexsize
=
git_oid_hexsize
(
oid_
type
);
git_oid_fmt
(
oid
,
&
head
->
oid
);
/* Prefer multi_ack_detailed */
...
...
@@ -634,18 +641,19 @@ static int buffer_want_with_caps(const git_remote_head *head, transport_smart_ca
if
(
git_str_oom
(
&
str
))
return
-
1
;
len
=
strlen
(
"XXXXwant "
)
+
oid_hexsize
+
1
/* NUL */
+
git_str_len
(
&
str
)
+
1
/* LF */
;
if
(
len
>
0xffff
)
{
if
(
str
.
size
>
(
PKT_MAX_SIZE
-
(
PKT_MAX_WANTLEN
+
1
)))
{
git_error_set
(
GIT_ERROR_NET
,
"tried to produce packet with invalid
length %"
PRIuZ
,
len
);
"tried to produce packet with invalid
caps length %"
PRIuZ
,
str
.
size
);
return
-
1
;
}
len
=
PKT_LEN_SIZE
+
CONST_STRLEN
(
PKT_WANT_PREFIX
)
+
oid_hexsize
+
1
/* NUL */
+
git_str_len
(
&
str
)
+
1
/* LF */
;
git_str_grow_by
(
buf
,
len
);
git_str_printf
(
buf
,
"%04x
want %.*s %s
\n
"
,
(
unsigned
int
)
len
,
"%04x
%s%.*s %s
\n
"
,
(
unsigned
int
)
len
,
PKT_WANT_PREFIX
,
(
int
)
oid_hexsize
,
oid
,
git_str_cstr
(
&
str
));
git_str_dispose
(
&
str
);
...
...
@@ -665,8 +673,21 @@ int git_pkt_buffer_wants(
transport_smart_caps
*
caps
,
git_str
*
buf
)
{
size_t
i
=
0
;
const
git_remote_head
*
head
;
char
oid
[
GIT_OID_MAX_HEXSIZE
];
git_oid_t
oid_type
;
size_t
oid_hexsize
,
want_len
,
i
=
0
;
#ifdef GIT_EXPERIMENTAL_SHA256
oid_type
=
count
>
0
?
refs
[
0
]
->
oid
.
type
:
GIT_OID_SHA1
;
#else
oid_type
=
GIT_OID_SHA1
;
#endif
oid_hexsize
=
git_oid_hexsize
(
oid_type
);
want_len
=
PKT_LEN_SIZE
+
CONST_STRLEN
(
PKT_WANT_PREFIX
)
+
oid_hexsize
+
1
/* LF */
;
if
(
caps
->
common
)
{
for
(;
i
<
count
;
++
i
)
{
...
...
@@ -675,15 +696,13 @@ int git_pkt_buffer_wants(
break
;
}
if
(
buffer_want_with_caps
(
refs
[
i
],
caps
,
buf
)
<
0
)
if
(
buffer_want_with_caps
(
refs
[
i
],
caps
,
oid_type
,
buf
)
<
0
)
return
-
1
;
i
++
;
}
for
(;
i
<
count
;
++
i
)
{
char
oid
[
GIT_OID_MAX_HEXSIZE
];
head
=
refs
[
i
];
if
(
head
->
local
)
...
...
@@ -691,9 +710,9 @@ int git_pkt_buffer_wants(
git_oid_fmt
(
oid
,
&
head
->
oid
);
git_str_p
ut
(
buf
,
pkt_want_prefix
,
strlen
(
pkt_want_prefix
));
git_str_put
(
buf
,
oid
,
git_oid_hexsize
(
head
->
oid
.
type
));
git_str_putc
(
buf
,
'\n'
);
git_str_p
rintf
(
buf
,
"%04x%s%.*s
\n
"
,
(
unsigned
int
)
want_len
,
PKT_WANT_PREFIX
,
(
int
)
oid_hexsize
,
oid
);
if
(
git_str_oom
(
buf
))
return
-
1
;
...
...
@@ -704,14 +723,27 @@ int git_pkt_buffer_wants(
int
git_pkt_buffer_have
(
git_oid
*
oid
,
git_str
*
buf
)
{
char
oidhex
[
GIT_OID_SHA1_HEXSIZE
+
1
];
memset
(
oidhex
,
0x0
,
sizeof
(
oidhex
));
git_oid_fmt
(
oidhex
,
oid
);
return
git_str_printf
(
buf
,
"%s%s
\n
"
,
pkt_have_prefix
,
oidhex
);
char
oid_str
[
GIT_OID_MAX_HEXSIZE
];
git_oid_t
oid_type
;
size_t
oid_hexsize
,
have_len
;
#ifdef GIT_EXPERIMENTAL_SHA256
oid_type
=
oid
->
type
;
#else
oid_type
=
GIT_OID_SHA1
;
#endif
oid_hexsize
=
git_oid_hexsize
(
oid_type
);
have_len
=
PKT_LEN_SIZE
+
CONST_STRLEN
(
PKT_HAVE_PREFIX
)
+
oid_hexsize
+
1
/* LF */
;
git_oid_fmt
(
oid_str
,
oid
);
return
git_str_printf
(
buf
,
"%04x%s%.*s
\n
"
,
(
unsigned
int
)
have_len
,
PKT_HAVE_PREFIX
,
(
int
)
oid_hexsize
,
oid_str
);
}
int
git_pkt_buffer_done
(
git_str
*
buf
)
{
return
git_str_put
s
(
buf
,
pkt_done_str
);
return
git_str_put
(
buf
,
PKT_DONE_STR
,
CONST_STRLEN
(
PKT_DONE_STR
)
);
}
src/libgit2/transports/smart_protocol.c
View file @
53fcd5b8
...
...
@@ -134,9 +134,12 @@ on_invalid:
return
-
1
;
}
int
git_smart__detect_caps
(
git_pkt_ref
*
pkt
,
transport_smart_caps
*
caps
,
git_vector
*
symrefs
)
int
git_smart__detect_caps
(
git_pkt_ref
*
pkt
,
transport_smart_caps
*
caps
,
git_vector
*
symrefs
)
{
const
char
*
ptr
;
const
char
*
ptr
,
*
start
;
/* No refs or capabilities, odd but not a problem */
if
(
pkt
==
NULL
||
pkt
->
capabilities
==
NULL
)
...
...
@@ -218,6 +221,28 @@ int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vec
continue
;
}
if
(
!
git__prefixcmp
(
ptr
,
GIT_CAP_OBJECT_FORMAT
))
{
ptr
+=
strlen
(
GIT_CAP_OBJECT_FORMAT
);
start
=
ptr
;
ptr
=
strchr
(
ptr
,
' '
);
if
((
caps
->
object_format
=
git__strndup
(
start
,
(
ptr
-
start
)))
==
NULL
)
return
-
1
;
continue
;
}
if
(
!
git__prefixcmp
(
ptr
,
GIT_CAP_AGENT
))
{
ptr
+=
strlen
(
GIT_CAP_AGENT
);
start
=
ptr
;
ptr
=
strchr
(
ptr
,
' '
);
if
((
caps
->
agent
=
git__strndup
(
start
,
(
ptr
-
start
)))
==
NULL
)
return
-
1
;
continue
;
}
/* We don't know this capability, so skip it */
ptr
=
strchr
(
ptr
,
' '
);
}
...
...
src/util/hash.h
View file @
53fcd5b8
...
...
@@ -23,6 +23,8 @@ typedef enum {
GIT_HASH_ALGORITHM_SHA256
}
git_hash_algorithm_t
;
#define GIT_HASH_MAX_SIZE GIT_HASH_SHA256_SIZE
typedef
struct
git_hash_ctx
{
union
{
git_hash_sha1_ctx
sha1
;
...
...
@@ -45,4 +47,15 @@ int git_hash_vec(unsigned char *out, git_str_vec *vec, size_t n, git_hash_algori
int
git_hash_fmt
(
char
*
out
,
unsigned
char
*
hash
,
size_t
hash_len
);
GIT_INLINE
(
size_t
)
git_hash_size
(
git_hash_algorithm_t
algorithm
)
{
switch
(
algorithm
)
{
case
GIT_HASH_ALGORITHM_SHA1
:
return
GIT_HASH_SHA1_SIZE
;
case
GIT_HASH_ALGORITHM_SHA256
:
return
GIT_HASH_SHA256_SIZE
;
default
:
return
0
;
}
}
#endif
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