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
616628dd
Unverified
Commit
616628dd
authored
Jan 17, 2022
by
Edward Thomson
Committed by
GitHub
Jan 17, 2022
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'main' into typos
parents
90df4302
2bfd8ddc
Hide whitespace changes
Inline
Side-by-side
Showing
38 changed files
with
1176 additions
and
596 deletions
+1176
-596
ci/test.sh
+9
-8
docs/api-stability.md
+63
-0
include/git2/remote.h
+177
-33
include/git2/status.h
+6
-0
include/git2/sys/transport.h
+14
-33
src/checkout.c
+5
-5
src/config_file.c
+14
-3
src/diff_tform.c
+1
-1
src/fetch.c
+4
-11
src/fetch.h
+1
-1
src/net.c
+4
-2
src/net.h
+1
-0
src/pack-objects.h
+4
-4
src/proxy.c
+4
-1
src/proxy.h
+1
-1
src/push.c
+23
-28
src/push.h
+4
-16
src/rebase.c
+4
-4
src/remote.c
+313
-116
src/remote.h
+9
-9
src/status.c
+3
-0
src/transports/http.c
+36
-14
src/transports/local.c
+79
-81
src/transports/smart.c
+29
-134
src/transports/smart.h
+15
-25
src/transports/smart_protocol.c
+11
-8
src/transports/ssh.c
+13
-5
src/transports/winhttp.c
+15
-21
src/worktree.h
+1
-1
tests/config/conditionals.c
+25
-0
tests/network/url/redirect.c
+40
-22
tests/online/clone.c
+64
-0
tests/online/fetch.c
+57
-9
tests/resources/renames/.gitted/objects/41/a766bb079e18ff6a24571831bd751168799a02
+2
-0
tests/resources/renames/.gitted/objects/ba/8b004914491b129b4feff51b5fd8553b8e8156
+0
-0
tests/resources/renames/.gitted/objects/e5/6d39ca6d946331aa79c9c443d46c8a6ed4f550
+0
-0
tests/resources/renames/.gitted/refs/heads/case-insensitive-status
+1
-0
tests/status/renames.c
+124
-0
No files found.
ci/test.sh
View file @
616628dd
...
...
@@ -83,7 +83,7 @@ echo "##########################################################################
if
[
-z
"
$SKIP_GITDAEMON_TESTS
"
]
;
then
echo
"Starting git daemon..."
GITDAEMON_DIR
=
`
mktemp
-d
${
TMPDIR
}
/gitdaemon.XXXXXXXX
`
git init
--bare
"
${
GITDAEMON_DIR
}
/test.git"
git init
--bare
"
${
GITDAEMON_DIR
}
/test.git"
>
/dev/null
git daemon
--listen
=
localhost
--export-all
--enable
=
receive-pack
--base-path
=
"
${
GITDAEMON_DIR
}
"
"
${
GITDAEMON_DIR
}
"
2>/dev/null &
GITDAEMON_PID
=
$!
disown
$GITDAEMON_PID
...
...
@@ -101,8 +101,8 @@ if [ -z "$SKIP_PROXY_TESTS" ]; then
java
-jar
poxyproxy.jar
--address
127.0.0.1
--port
8090
--credentials
foo:bar
--auth-type
ntlm
--quiet
&
fi
if
[
-z
"
$SKIP_NTLM_TESTS
"
]
;
then
curl
--location
--silent
--show-error
https://github.com/ethomson/poxygit/releases/download/v0.
4.0/poxygit-0.4.0
.jar
>
poxygit.jar
if
[
-z
"
$SKIP_NTLM_TESTS
"
-o
-z
"
$SKIP_ONLINE_TESTS
"
]
;
then
curl
--location
--silent
--show-error
https://github.com/ethomson/poxygit/releases/download/v0.
5.1/poxygit-0.5.1
.jar
>
poxygit.jar
echo
""
echo
"Starting HTTP server..."
...
...
@@ -112,10 +112,11 @@ if [ -z "$SKIP_NTLM_TESTS" ]; then
fi
if
[
-z
"
$SKIP_SSH_TESTS
"
]
;
then
echo
""
echo
"Starting ssh daemon..."
HOME
=
`
mktemp
-d
${
TMPDIR
}
/home.XXXXXXXX
`
SSHD_DIR
=
`
mktemp
-d
${
TMPDIR
}
/sshd.XXXXXXXX
`
git init
--bare
"
${
SSHD_DIR
}
/test.git"
git init
--bare
"
${
SSHD_DIR
}
/test.git"
>
/dev/null
cat
>
"
${
SSHD_DIR
}
/sshd_config"
<<-
EOF
Port 2222
ListenAddress 0.0.0.0
...
...
@@ -188,9 +189,11 @@ if [ -z "$SKIP_ONLINE_TESTS" ]; then
echo
"## Running (online) tests"
echo
"##############################################################################"
export
GITTEST_FLAKY_RETRY
=
5
export
GITTEST_REMOTE_REDIRECT_INITIAL
=
"http://localhost:9000/initial-redirect/libgit2/TestGitRepository"
export
GITTEST_REMOTE_REDIRECT_SUBSEQUENT
=
"http://localhost:9000/subsequent-redirect/libgit2/TestGitRepository"
run_test online
unset
GITTEST_FLAKY_RETRY
unset
GITTEST_REMOTE_REDIRECT_INITIAL
unset
GITTEST_REMOTE_REDIRECT_SUBSEQUENT
# Run the online tests that immutably change global state separately
# to avoid polluting the test environment.
...
...
@@ -231,9 +234,7 @@ if [ -z "$SKIP_PROXY_TESTS" ]; then
export
GITTEST_REMOTE_PROXY_HOST
=
"localhost:8090"
export
GITTEST_REMOTE_PROXY_USER
=
"foo"
export
GITTEST_REMOTE_PROXY_PASS
=
"bar"
export
GITTEST_FLAKY_RETRY
=
5
run_test proxy
unset
GITTEST_FLAKY_RETRY
unset
GITTEST_REMOTE_PROXY_HOST
unset
GITTEST_REMOTE_PROXY_USER
unset
GITTEST_REMOTE_PROXY_PASS
...
...
docs/api-stability.md
0 → 100644
View file @
616628dd
The maintainers of the libgit2 project believe that having a stable API
to program against is important for our users and the ecosystem - whether
you're building against the libgit2 C APIs directly, creating a wrapper to
a managed language, or programming against one of those managed wrappers
like LibGit2Sharp or Rugged.
Our API stability considerations are:
*
Our standard API is considered stable through a major release.
*
We define our "standard API" to be anything included in the "git2.h"
header - in other words, anything defined in a header in the
`git2`
directory.
*
APIs will maintain their signature and will not be removed within a
major release, but new APIs may be added.
*
Any APIs may be marked as deprecated within a major release, but will
not be removed until the next major release (at the earliest). You
may define
`GIT_DEPRECATE_HARD`
to produce compiler warnings if you
target these deprecated APIs.
*
We consider API compatibility to be against the C APIs. That means
that we may use macros to keep API compatibility - for example, if we
rename a structure from
`git_widget_options`
to
`git_foobar_options`
then we would
`#define git_widget_options git_foobar_options`
to retain
API compatibility. Note that this does _not_ provide ABI compatibility.
*
Our systems API is only considered stable through a _minor_ release.
*
We define our "systems API" to be anything included in the
`git2/sys`
directory. These are not "standard" APIs but are mechanisms to extend
libgit2 by adding new extensions - for example, a custom HTTPS transport,
TLS engine, or merge strategy.
*
Additionally, the cmake options and the resulting constants that it
produces to be "systems API".
*
Generally these mechanism are well defined and will not need significant
changes, but are considered a part of the library itself and may need
*
Systems API changes will be noted specially within a release's changelog.
*
Our ABI is only considered stable through a _minor_ release.
*
Our ABI consists of actual symbol names in the library, the function
signatures, and the actual layout of structures. These are only
stable within minor releases, they are not stable within major releases
(yet).
*
Since many FFIs use ABIs directly (for example, .NET P/Invoke or Rust),
this instability is unfortunate.
*
In a future major release, we will begin providing ABI stability
throughout the major release cycle.
*
ABI changes will be noted specially within a release's changelog.
*
Point releases are _generally_ only for bugfixes, and generally do _not_
include new features. This means that point releases generally do _not_
include new APIs. Point releases will never break API, systems API or
ABI compatibility.
include/git2/remote.h
View file @
616628dd
...
...
@@ -42,6 +42,30 @@ GIT_EXTERN(int) git_remote_create(
const
char
*
url
);
/**
* Remote redirection settings; whether redirects to another host
* are permitted. By default, git will follow a redirect on the
* initial request (`/info/refs`), but not subsequent requests.
*/
typedef
enum
{
/**
* Do not follow any off-site redirects at any stage of
* the fetch or push.
*/
GIT_REMOTE_REDIRECT_NONE
=
(
1
<<
0
),
/**
* Allow off-site redirects only upon the initial request.
* This is the default.
*/
GIT_REMOTE_REDIRECT_INITIAL
=
(
1
<<
1
),
/**
* Allow redirects at any stage in the fetch or push.
*/
GIT_REMOTE_REDIRECT_ALL
=
(
1
<<
2
)
}
git_remote_redirect_t
;
/**
* Remote creation options flags
*/
typedef
enum
{
...
...
@@ -345,23 +369,6 @@ GIT_EXTERN(size_t) git_remote_refspec_count(const git_remote *remote);
GIT_EXTERN
(
const
git_refspec
*
)
git_remote_get_refspec
(
const
git_remote
*
remote
,
size_t
n
);
/**
* Open a connection to a remote
*
* The transport is selected based on the URL. The direction argument
* is due to a limitation of the git protocol (over TCP or SSH) which
* starts up a specific binary which can only do the one or the other.
*
* @param remote the remote to connect to
* @param direction GIT_DIRECTION_FETCH if you want to fetch or
* GIT_DIRECTION_PUSH if you want to push
* @param callbacks the callbacks to use for this connection
* @param proxy_opts proxy settings
* @param custom_headers extra HTTP headers to use in this connection
* @return 0 or an error code
*/
GIT_EXTERN
(
int
)
git_remote_connect
(
git_remote
*
remote
,
git_direction
direction
,
const
git_remote_callbacks
*
callbacks
,
const
git_proxy_options
*
proxy_opts
,
const
git_strarray
*
custom_headers
);
/**
* Get the remote repository's reference advertisement list
*
* Get the list of references with which the server responds to a new
...
...
@@ -735,6 +742,13 @@ typedef struct {
git_proxy_options
proxy_opts
;
/**
* Whether to allow off-site redirects. If this is not
* specified, the `http.followRedirects` configuration setting
* will be consulted.
*/
git_remote_redirect_t
follow_redirects
;
/**
* Extra headers for this fetch operation
*/
git_strarray
custom_headers
;
...
...
@@ -786,6 +800,13 @@ typedef struct {
git_proxy_options
proxy_opts
;
/**
* Whether to allow off-site redirects. If this is not
* specified, the `http.followRedirects` configuration setting
* will be consulted.
*/
git_remote_redirect_t
follow_redirects
;
/**
* Extra headers for this push operation
*/
git_strarray
custom_headers
;
...
...
@@ -809,7 +830,100 @@ GIT_EXTERN(int) git_push_options_init(
unsigned
int
version
);
/**
* Download and index the packfile
* Remote creation options structure
*
* Initialize with `GIT_REMOTE_CREATE_OPTIONS_INIT`. Alternatively, you can
* use `git_remote_create_options_init`.
*
*/
typedef
struct
{
unsigned
int
version
;
/** Callbacks to use for this connection */
git_remote_callbacks
callbacks
;
/** HTTP Proxy settings */
git_proxy_options
proxy_opts
;
/**
* Whether to allow off-site redirects. If this is not
* specified, the `http.followRedirects` configuration setting
* will be consulted.
*/
git_remote_redirect_t
follow_redirects
;
/** Extra HTTP headers to use in this connection */
git_strarray
custom_headers
;
}
git_remote_connect_options
;
#define GIT_REMOTE_CONNECT_OPTIONS_VERSION 1
#define GIT_REMOTE_CONNECT_OPTIONS_INIT { \
GIT_REMOTE_CONNECT_OPTIONS_VERSION, \
GIT_REMOTE_CALLBACKS_INIT, \
GIT_PROXY_OPTIONS_INIT }
/**
* Initialize git_remote_connect_options structure.
*
* Initializes a `git_remote_connect_options` with default values.
* Equivalent to creating an instance with
* `GIT_REMOTE_CONNECT_OPTIONS_INIT`.
*
* @param opts The `git_remote_connect_options` struct to initialize.
* @param version The struct version; pass `GIT_REMOTE_CONNECT_OPTIONS_VERSION`.
* @return Zero on success; -1 on failure.
*/
GIT_EXTERN
(
int
)
git_remote_connect_options_init
(
git_remote_connect_options
*
opts
,
unsigned
int
version
);
/**
* Open a connection to a remote.
*
* The transport is selected based on the URL; the direction argument
* is due to a limitation of the git protocol which starts up a
* specific binary which can only do the one or the other.
*
* @param remote the remote to connect to
* @param direction GIT_DIRECTION_FETCH if you want to fetch or
* GIT_DIRECTION_PUSH if you want to push
* @param callbacks the callbacks to use for this connection
* @param proxy_opts proxy settings
* @param custom_headers extra HTTP headers to use in this connection
* @return 0 or an error code
*/
GIT_EXTERN
(
int
)
git_remote_connect
(
git_remote
*
remote
,
git_direction
direction
,
const
git_remote_callbacks
*
callbacks
,
const
git_proxy_options
*
proxy_opts
,
const
git_strarray
*
custom_headers
);
/**
* Open a connection to a remote with extended options.
*
* The transport is selected based on the URL; the direction argument
* is due to a limitation of the git protocol which starts up a
* specific binary which can only do the one or the other.
*
* The given options structure will form the defaults for connection
* options and callback setup. Callers may override these defaults
* by specifying `git_fetch_options` or `git_push_options` in
* subsequent calls.
*
* @param remote the remote to connect to
* @param direction GIT_DIRECTION_FETCH if you want to fetch or
* GIT_DIRECTION_PUSH if you want to push
* @param opts the remote connection options
* @return 0 or an error code
*/
GIT_EXTERN
(
int
)
git_remote_connect_ext
(
git_remote
*
remote
,
git_direction
direction
,
const
git_remote_connect_options
*
opts
);
/**
* Download and index the packfile.
*
* Connect to the remote if it hasn't been done yet, negotiate with
* the remote git which objects are missing, download and index the
...
...
@@ -818,19 +932,31 @@ GIT_EXTERN(int) git_push_options_init(
* The .idx file will be created and both it and the packfile with be
* renamed to their final name.
*
* If options are specified and this remote is already connected then
* the existing remote connection options will be discarded and the
* remote will now use the new options.
*
* @param remote the remote
* @param refspecs the refspecs to use for this negotiation and
* download. Use NULL or an empty array to use the base refspecs
* @param opts the options to use for this fetch
* @param opts the options to use for this fetch
or NULL
* @return 0 or an error code
*/
GIT_EXTERN
(
int
)
git_remote_download
(
git_remote
*
remote
,
const
git_strarray
*
refspecs
,
const
git_fetch_options
*
opts
);
GIT_EXTERN
(
int
)
git_remote_download
(
git_remote
*
remote
,
const
git_strarray
*
refspecs
,
const
git_fetch_options
*
opts
);
/**
* Create a packfile and send it to the server
*
* Connect to the remote if it hasn't been done yet, negotiate with
* the remote git which objects are missing, create a packfile with the missing objects and send it.
* the remote git which objects are missing, create a packfile with
* the missing objects and send it.
*
* If options are specified and this remote is already connected then
* the existing remote connection options will be discarded and the
* remote will now use the new options.
*
* @param remote the remote
* @param refspecs the refspecs to use for this negotiation and
...
...
@@ -838,17 +964,23 @@ GIT_EXTERN(int) git_push_options_init(
* @param opts the options to use for this push
* @return 0 or an error code
*/
GIT_EXTERN
(
int
)
git_remote_upload
(
git_remote
*
remote
,
const
git_strarray
*
refspecs
,
const
git_push_options
*
opts
);
GIT_EXTERN
(
int
)
git_remote_upload
(
git_remote
*
remote
,
const
git_strarray
*
refspecs
,
const
git_push_options
*
opts
);
/**
* Update the tips to the new state
* Update the tips to the new state.
*
* If callbacks are not specified then the callbacks specified to
* `git_remote_connect` will be used (if it was called).
*
* @param remote the remote to update
* @param reflog_message The message to insert into the reflogs. If
* NULL and fetching, the default is "fetch <name>", where <name> is
* the name of the remote (or its url, for in-memory remotes). This
* parameter is ignored when pushing.
* @param callbacks pointer to the callback structure to use
* @param callbacks pointer to the callback structure to use
or NULL
* @param update_fetchhead whether to write to FETCH_HEAD. Pass 1 to behave like git.
* @param download_tags what the behaviour for downloading tags is for this fetch. This is
* ignored for push. This must be the same value passed to `git_remote_download()`.
...
...
@@ -862,15 +994,19 @@ GIT_EXTERN(int) git_remote_update_tips(
const
char
*
reflog_message
);
/**
* Download new data and update tips
* Download new data and update tips
.
*
* Convenience function to connect to a remote, download the data,
* disconnect and update the remote-tracking branches.
*
* If options are specified and this remote is already connected then
* the existing remote connection options will be discarded and the
* remote will now use the new options.
*
* @param remote the remote to fetch from
* @param refspecs the refspecs to use for this fetch. Pass NULL or an
* empty array to use the base refspecs.
* @param opts options to use for this fetch
* @param opts options to use for this fetch
or NULL
* @param reflog_message The message to insert into the reflogs. If NULL, the
* default is "fetch"
* @return 0 or an error code
...
...
@@ -882,27 +1018,35 @@ GIT_EXTERN(int) git_remote_fetch(
const
char
*
reflog_message
);
/**
* Prune tracking refs that are no longer present on remote
* Prune tracking refs that are no longer present on remote.
*
* If callbacks are not specified then the callbacks specified to
* `git_remote_connect` will be used (if it was called).
*
* @param remote the remote to prune
* @param callbacks callbacks to use for this prune
* @return 0 or an error code
*/
GIT_EXTERN
(
int
)
git_remote_prune
(
git_remote
*
remote
,
const
git_remote_callbacks
*
callbacks
);
GIT_EXTERN
(
int
)
git_remote_prune
(
git_remote
*
remote
,
const
git_remote_callbacks
*
callbacks
);
/**
* Perform a push
* Perform a push
.
*
* Perform all the steps from a push.
* If options are specified and this remote is already connected then
* the existing remote connection options will be discarded and the
* remote will now use the new options.
*
* @param remote the remote to push to
* @param refspecs the refspecs to use for pushing. If NULL or an empty
* array, the configured refspecs will be used
* @param opts options to use for this push
*/
GIT_EXTERN
(
int
)
git_remote_push
(
git_remote
*
remote
,
const
git_strarray
*
refspecs
,
const
git_push_options
*
opts
);
GIT_EXTERN
(
int
)
git_remote_push
(
git_remote
*
remote
,
const
git_strarray
*
refspecs
,
const
git_push_options
*
opts
);
/**
* Get the statistics structure that is filled in by the fetch operation.
...
...
include/git2/status.h
View file @
616628dd
...
...
@@ -250,6 +250,12 @@ typedef struct {
* working directory and index; defaults to HEAD.
*/
git_tree
*
baseline
;
/**
* Threshold above which similar files will be considered renames.
* This is equivalent to the -M option. Defaults to 50.
*/
uint16_t
rename_threshold
;
}
git_status_options
;
#define GIT_STATUS_OPTIONS_VERSION 1
...
...
include/git2/sys/transport.h
View file @
616628dd
...
...
@@ -24,31 +24,9 @@
GIT_BEGIN_DECL
/**
* Flags to pass to transport
*
* Currently unused.
*/
typedef
enum
{
GIT_TRANSPORTFLAGS_NONE
=
0
}
git_transport_flags_t
;
struct
git_transport
{
unsigned
int
version
;
/**< The struct version */
/** Set progress and error callbacks */
int
GIT_CALLBACK
(
set_callbacks
)(
git_transport
*
transport
,
git_transport_message_cb
progress_cb
,
git_transport_message_cb
error_cb
,
git_transport_certificate_check_cb
certificate_check_cb
,
void
*
payload
);
/** Set custom headers for HTTP requests */
int
GIT_CALLBACK
(
set_custom_headers
)(
git_transport
*
transport
,
const
git_strarray
*
custom_headers
);
/**
* Connect the transport to the remote repository, using the given
* direction.
...
...
@@ -56,11 +34,17 @@ struct git_transport {
int
GIT_CALLBACK
(
connect
)(
git_transport
*
transport
,
const
char
*
url
,
git_credential_acquire_cb
cred_acquire_cb
,
void
*
cred_acquire_payload
,
const
git_proxy_options
*
proxy_opts
,
int
direction
,
int
flags
);
const
git_remote_connect_options
*
connect_opts
);
/**
* Resets the connect options for the given transport. This
* is useful for updating settings or callbacks for an already
* connected transport.
*/
int
GIT_CALLBACK
(
set_connect_opts
)(
git_transport
*
transport
,
const
git_remote_connect_options
*
connect_opts
);
/**
* Get the list of available references in the remote repository.
...
...
@@ -75,7 +59,9 @@ struct git_transport {
git_transport
*
transport
);
/** Executes the push whose context is in the git_push object. */
int
GIT_CALLBACK
(
push
)(
git_transport
*
transport
,
git_push
*
push
,
const
git_remote_callbacks
*
callbacks
);
int
GIT_CALLBACK
(
push
)(
git_transport
*
transport
,
git_push
*
push
);
/**
* Negotiate a fetch with the remote repository.
...
...
@@ -99,16 +85,11 @@ struct git_transport {
int
GIT_CALLBACK
(
download_pack
)(
git_transport
*
transport
,
git_repository
*
repo
,
git_indexer_progress
*
stats
,
git_indexer_progress_cb
progress_cb
,
void
*
progress_payload
);
git_indexer_progress
*
stats
);
/** Checks to see if the transport is connected */
int
GIT_CALLBACK
(
is_connected
)(
git_transport
*
transport
);
/** Reads the flags value previously passed into connect() */
int
GIT_CALLBACK
(
read_flags
)(
git_transport
*
transport
,
int
*
flags
);
/** Cancels any outstanding transport operation */
void
GIT_CALLBACK
(
cancel
)(
git_transport
*
transport
);
...
...
src/checkout.c
View file @
616628dd
...
...
@@ -81,11 +81,11 @@ typedef struct {
const
git_index_entry
*
ours
;
const
git_index_entry
*
theirs
;
int
name_collision
:
1
,
directoryfile
:
1
,
one_to_two
:
1
,
binary
:
1
,
submodule
:
1
;
unsigned
int
name_collision
:
1
,
directoryfile
:
1
,
one_to_two
:
1
,
binary
:
1
,
submodule
:
1
;
}
checkout_conflictdata
;
static
int
checkout_notify
(
...
...
src/config_file.c
View file @
616628dd
...
...
@@ -724,14 +724,25 @@ static const struct {
static
int
parse_conditional_include
(
config_file_parse_data
*
parse_data
,
const
char
*
section
,
const
char
*
file
)
{
char
*
condition
;
size_t
i
;
size_t
section_len
,
i
;
int
error
=
0
,
matches
;
if
(
!
parse_data
->
repo
||
!
file
)
return
0
;
condition
=
git__substrdup
(
section
+
strlen
(
"includeIf."
),
strlen
(
section
)
-
strlen
(
"includeIf."
)
-
strlen
(
".path"
));
section_len
=
strlen
(
section
);
/*
* We checked that the string starts with `includeIf.` and ends
* in `.path` to get here. Make sure it consists of more.
*/
if
(
section_len
<
CONST_STRLEN
(
"includeIf."
)
+
CONST_STRLEN
(
".path"
))
return
0
;
condition
=
git__substrdup
(
section
+
CONST_STRLEN
(
"includeIf."
),
section_len
-
CONST_STRLEN
(
"includeIf."
)
-
CONST_STRLEN
(
".path"
));
GIT_ERROR_CHECK_ALLOC
(
condition
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
conditions
);
i
++
)
{
if
(
git__prefixcmp
(
condition
,
conditions
[
i
].
prefix
))
...
...
src/diff_tform.c
View file @
616628dd
...
...
@@ -375,7 +375,7 @@ static int apply_splits_and_deletes(
size_t
i
;
git_diff_delta
*
delta
;
if
(
git_vector_init
(
&
onto
,
expected_size
,
git_diff_delta_
_cmp
)
<
0
)
if
(
git_vector_init
(
&
onto
,
expected_size
,
diff
->
deltas
.
_cmp
)
<
0
)
return
-
1
;
/* build new delta list without TO_DELETE and splitting TO_SPLIT */
...
...
src/fetch.c
View file @
616628dd
...
...
@@ -87,10 +87,10 @@ static int filter_wants(git_remote *remote, const git_fetch_options *opts)
goto
cleanup
;
}
if
(
git_repository_odb__weakptr
(
&
odb
,
remote
->
repo
)
<
0
)
if
(
(
error
=
git_repository_odb__weakptr
(
&
odb
,
remote
->
repo
)
)
<
0
)
goto
cleanup
;
if
(
git_remote_ls
((
const
git_remote_head
***
)
&
heads
,
&
heads_len
,
remote
)
<
0
)
if
(
(
error
=
git_remote_ls
((
const
git_remote_head
***
)
&
heads
,
&
heads_len
,
remote
)
)
<
0
)
goto
cleanup
;
for
(
i
=
0
;
i
<
heads_len
;
i
++
)
{
...
...
@@ -134,21 +134,14 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts)
remote
->
refs
.
length
);
}
int
git_fetch_download_pack
(
git_remote
*
remote
,
const
git_remote_callbacks
*
callbacks
)
int
git_fetch_download_pack
(
git_remote
*
remote
)
{
git_transport
*
t
=
remote
->
transport
;
git_indexer_progress_cb
progress
=
NULL
;
void
*
payload
=
NULL
;
if
(
!
remote
->
need_pack
)
return
0
;
if
(
callbacks
)
{
progress
=
callbacks
->
transfer_progress
;
payload
=
callbacks
->
payload
;
}
return
t
->
download_pack
(
t
,
remote
->
repo
,
&
remote
->
stats
,
progress
,
payload
);
return
t
->
download_pack
(
t
,
remote
->
repo
,
&
remote
->
stats
);
}
int
git_fetch_options_init
(
git_fetch_options
*
opts
,
unsigned
int
version
)
...
...
src/fetch.h
View file @
616628dd
...
...
@@ -15,7 +15,7 @@
int
git_fetch_negotiate
(
git_remote
*
remote
,
const
git_fetch_options
*
opts
);
int
git_fetch_download_pack
(
git_remote
*
remote
,
const
git_remote_callbacks
*
callbacks
);
int
git_fetch_download_pack
(
git_remote
*
remote
);
int
git_fetch_setup_walk
(
git_revwalk
**
out
,
git_repository
*
repo
);
...
...
src/net.c
View file @
616628dd
...
...
@@ -315,6 +315,7 @@ static void remove_service_suffix(
int
git_net_url_apply_redirect
(
git_net_url
*
url
,
const
char
*
redirect_location
,
bool
allow_offsite
,
const
char
*
service_suffix
)
{
git_net_url
tmp
=
GIT_NET_URL_INIT
;
...
...
@@ -339,8 +340,8 @@ int git_net_url_apply_redirect(
/* Validate that this is a legal redirection */
if
(
original
->
scheme
&&
strcmp
(
original
->
scheme
,
tmp
.
scheme
)
!=
0
&&
strcmp
(
tmp
.
scheme
,
"https"
)
!=
0
)
{
strcmp
(
original
->
scheme
,
tmp
.
scheme
)
!=
0
&&
strcmp
(
tmp
.
scheme
,
"https"
)
!=
0
)
{
git_error_set
(
GIT_ERROR_NET
,
"cannot redirect from '%s' to '%s'"
,
original
->
scheme
,
tmp
.
scheme
);
...
...
@@ -349,6 +350,7 @@ int git_net_url_apply_redirect(
}
if
(
original
->
host
&&
!
allow_offsite
&&
git__strcasecmp
(
original
->
host
,
tmp
.
host
)
!=
0
)
{
git_error_set
(
GIT_ERROR_NET
,
"cannot redirect from '%s' to '%s'"
,
original
->
host
,
tmp
.
host
);
...
...
src/net.h
View file @
616628dd
...
...
@@ -46,6 +46,7 @@ extern bool git_net_url_is_ipv6(git_net_url *url);
extern
int
git_net_url_apply_redirect
(
git_net_url
*
url
,
const
char
*
redirect_location
,
bool
allow_offsite
,
const
char
*
service_suffix
);
/** Swaps the contents of one URL for another. */
...
...
src/pack-objects.h
View file @
616628dd
...
...
@@ -46,10 +46,10 @@ typedef struct git_pobject {
size_t
delta_size
;
size_t
z_delta_size
;
int
written
:
1
,
recursing
:
1
,
tagged
:
1
,
filled
:
1
;
unsigned
int
written
:
1
,
recursing
:
1
,
tagged
:
1
,
filled
:
1
;
}
git_pobject
;
struct
git_packbuilder
{
...
...
src/proxy.c
View file @
616628dd
...
...
@@ -39,8 +39,11 @@ int git_proxy_options_dup(git_proxy_options *tgt, const git_proxy_options *src)
return
0
;
}
void
git_proxy_options_
clear
(
git_proxy_options
*
opts
)
void
git_proxy_options_
dispose
(
git_proxy_options
*
opts
)
{
if
(
!
opts
)
return
;
git__free
((
char
*
)
opts
->
url
);
opts
->
url
=
NULL
;
}
src/proxy.h
View file @
616628dd
...
...
@@ -12,6 +12,6 @@
#include "git2/proxy.h"
extern
int
git_proxy_options_dup
(
git_proxy_options
*
tgt
,
const
git_proxy_options
*
src
);
extern
void
git_proxy_options_
clear
(
git_proxy_options
*
opts
);
extern
void
git_proxy_options_
dispose
(
git_proxy_options
*
opts
);
#endif
src/push.c
View file @
616628dd
...
...
@@ -29,19 +29,26 @@ static int push_status_ref_cmp(const void *a, const void *b)
return
strcmp
(
push_status_a
->
ref
,
push_status_b
->
ref
);
}
int
git_push_new
(
git_push
**
out
,
git_remote
*
remote
)
int
git_push_new
(
git_push
**
out
,
git_remote
*
remote
,
const
git_push_options
*
opts
)
{
git_push
*
p
;
*
out
=
NULL
;
GIT_ERROR_CHECK_VERSION
(
opts
,
GIT_PUSH_OPTIONS_VERSION
,
"git_push_options"
);
p
=
git__calloc
(
1
,
sizeof
(
*
p
));
GIT_ERROR_CHECK_ALLOC
(
p
);
p
->
repo
=
remote
->
repo
;
p
->
remote
=
remote
;
p
->
report_status
=
1
;
p
->
pb_parallelism
=
1
;
p
->
pb_parallelism
=
opts
?
opts
->
pb_parallelism
:
1
;
if
(
opts
)
{
GIT_ERROR_CHECK_VERSION
(
&
opts
->
callbacks
,
GIT_REMOTE_CALLBACKS_VERSION
,
"git_remote_callbacks"
);
memcpy
(
&
p
->
callbacks
,
&
opts
->
callbacks
,
sizeof
(
git_remote_callbacks
));
}
if
(
git_vector_init
(
&
p
->
specs
,
0
,
push_spec_rref_cmp
)
<
0
)
{
git__free
(
p
);
...
...
@@ -65,20 +72,6 @@ int git_push_new(git_push **out, git_remote *remote)
return
0
;
}
int
git_push_set_options
(
git_push
*
push
,
const
git_push_options
*
opts
)
{
if
(
!
push
||
!
opts
)
return
-
1
;
GIT_ERROR_CHECK_VERSION
(
opts
,
GIT_PUSH_OPTIONS_VERSION
,
"git_push_options"
);
push
->
pb_parallelism
=
opts
->
pb_parallelism
;
push
->
connection
.
custom_headers
=
&
opts
->
custom_headers
;
push
->
connection
.
proxy
=
&
opts
->
proxy_opts
;
return
0
;
}
static
void
free_refspec
(
push_spec
*
spec
)
{
if
(
spec
==
NULL
)
...
...
@@ -291,7 +284,7 @@ static int queue_objects(git_push *push)
if
(
git_oid_equal
(
&
spec
->
loid
,
&
spec
->
roid
))
continue
;
/* up-to-date */
if
(
git_odb_read_header
(
&
size
,
&
type
,
push
->
repo
->
_odb
,
&
spec
->
loid
)
<
0
)
if
(
(
error
=
git_odb_read_header
(
&
size
,
&
type
,
push
->
repo
->
_odb
,
&
spec
->
loid
)
)
<
0
)
goto
on_error
;
if
(
type
==
GIT_OBJECT_TAG
)
{
...
...
@@ -301,19 +294,19 @@ static int queue_objects(git_push *push)
goto
on_error
;
if
(
git_object_type
(
target
)
==
GIT_OBJECT_COMMIT
)
{
if
(
git_revwalk_push
(
rw
,
git_object_id
(
target
))
<
0
)
{
if
(
(
error
=
git_revwalk_push
(
rw
,
git_object_id
(
target
)
))
<
0
)
{
git_object_free
(
target
);
goto
on_error
;
}
}
else
{
if
(
git_packbuilder_insert
(
push
->
pb
,
git_object_id
(
target
),
NULL
)
<
0
)
{
if
(
(
error
=
git_packbuilder_insert
(
push
->
pb
,
git_object_id
(
target
),
NULL
)
)
<
0
)
{
git_object_free
(
target
);
goto
on_error
;
}
}
git_object_free
(
target
);
}
else
if
(
git_revwalk_push
(
rw
,
&
spec
->
loid
)
<
0
)
}
else
if
(
(
error
=
git_revwalk_push
(
rw
,
&
spec
->
loid
)
)
<
0
)
goto
on_error
;
if
(
!
spec
->
refspec
.
force
)
{
...
...
@@ -411,10 +404,11 @@ static int calculate_work(git_push *push)
return
0
;
}
static
int
do_push
(
git_push
*
push
,
const
git_remote_callbacks
*
callbacks
)
static
int
do_push
(
git_push
*
push
)
{
int
error
=
0
;
git_transport
*
transport
=
push
->
remote
->
transport
;
git_remote_callbacks
*
callbacks
=
&
push
->
callbacks
;
if
(
!
transport
->
push
)
{
git_error_set
(
GIT_ERROR_NET
,
"remote transport doesn't support push"
);
...
...
@@ -446,7 +440,7 @@ static int do_push(git_push *push, const git_remote_callbacks *callbacks)
goto
on_error
;
if
((
error
=
queue_objects
(
push
))
<
0
||
(
error
=
transport
->
push
(
transport
,
push
,
callbacks
))
<
0
)
(
error
=
transport
->
push
(
transport
,
push
))
<
0
)
goto
on_error
;
on_error:
...
...
@@ -472,16 +466,17 @@ static int filter_refs(git_remote *remote)
return
0
;
}
int
git_push_finish
(
git_push
*
push
,
const
git_remote_callbacks
*
callbacks
)
int
git_push_finish
(
git_push
*
push
)
{
int
error
;
if
(
!
git_remote_connected
(
push
->
remote
)
&&
(
error
=
git_remote__connect
(
push
->
remote
,
GIT_DIRECTION_PUSH
,
callbacks
,
&
push
->
connection
))
<
0
)
return
error
;
if
(
!
git_remote_connected
(
push
->
remote
))
{
git_error_set
(
GIT_ERROR_NET
,
"remote is disconnected"
);
return
-
1
;
}
if
((
error
=
filter_refs
(
push
->
remote
))
<
0
||
(
error
=
do_push
(
push
,
callbacks
))
<
0
)
(
error
=
do_push
(
push
))
<
0
)
return
error
;
if
(
!
push
->
unpack_ok
)
{
...
...
src/push.h
View file @
616628dd
...
...
@@ -41,7 +41,7 @@ struct git_push {
/* options */
unsigned
pb_parallelism
;
git_remote_c
onnection_opts
connection
;
git_remote_c
allbacks
callbacks
;
};
/**
...
...
@@ -56,22 +56,11 @@ void git_push_status_free(push_status *status);
*
* @param out New push object
* @param remote Remote instance
* @param opts Push options or NULL
*
* @return 0 or an error code
*/
int
git_push_new
(
git_push
**
out
,
git_remote
*
remote
);
/**
* Set options on a push object
*
* @param push The push object
* @param opts The options to set on the push object
*
* @return 0 or an error code
*/
int
git_push_set_options
(
git_push
*
push
,
const
git_push_options
*
opts
);
int
git_push_new
(
git_push
**
out
,
git_remote
*
remote
,
const
git_push_options
*
opts
);
/**
* Add a refspec to be pushed
...
...
@@ -104,11 +93,10 @@ int git_push_update_tips(git_push *push, const git_remote_callbacks *callbacks);
* order to find out which updates were accepted or rejected.
*
* @param push The push object
* @param callbacks the callbacks to use for this connection
*
* @return 0 or an error code
*/
int
git_push_finish
(
git_push
*
push
,
const
git_remote_callbacks
*
callbacks
);
int
git_push_finish
(
git_push
*
push
);
/**
* Invoke callback `cb' on each status entry
...
...
src/rebase.c
View file @
616628dd
...
...
@@ -64,10 +64,10 @@ struct git_rebase {
git_rebase_t
type
;
char
*
state_path
;
int
head_detached
:
1
,
inmemory
:
1
,
quiet
:
1
,
started
:
1
;
unsigned
int
head_detached
:
1
,
inmemory
:
1
,
quiet
:
1
,
started
:
1
;
git_array_t
(
git_rebase_operation
)
operations
;
size_t
current
;
...
...
src/remote.c
View file @
616628dd
...
...
@@ -16,6 +16,7 @@
#include "refspec.h"
#include "fetchhead.h"
#include "push.h"
#include "proxy.h"
#include "git2/config.h"
#include "git2/types.h"
...
...
@@ -756,54 +757,200 @@ int git_remote__urlfordirection(
return
resolve_url
(
url_out
,
url
,
direction
,
callbacks
);
}
static
int
remote_transport_set_callbacks
(
git_transport
*
t
,
const
git_remote_callbacks
*
cbs
)
int
git_remote_connect_options_init
(
git_remote_connect_options
*
opts
,
unsigned
int
version
)
{
if
(
!
t
->
set_callbacks
||
!
cbs
)
GIT_INIT_STRUCTURE_FROM_TEMPLATE
(
opts
,
version
,
git_remote_connect_options
,
GIT_REMOTE_CONNECT_OPTIONS_INIT
);
return
0
;
}
int
git_remote_connect_options_dup
(
git_remote_connect_options
*
dst
,
const
git_remote_connect_options
*
src
)
{
memcpy
(
dst
,
src
,
sizeof
(
git_remote_connect_options
));
if
(
git_proxy_options_dup
(
&
dst
->
proxy_opts
,
&
src
->
proxy_opts
)
<
0
||
git_strarray_copy
(
&
dst
->
custom_headers
,
&
src
->
custom_headers
)
<
0
)
return
-
1
;
return
0
;
}
void
git_remote_connect_options_dispose
(
git_remote_connect_options
*
opts
)
{
if
(
!
opts
)
return
;
git_strarray_dispose
(
&
opts
->
custom_headers
);
git_proxy_options_dispose
(
&
opts
->
proxy_opts
);
}
static
size_t
http_header_name_length
(
const
char
*
http_header
)
{
const
char
*
colon
=
strchr
(
http_header
,
':'
);
if
(
!
colon
)
return
0
;
return
colon
-
http_header
;
}
static
bool
is_malformed_http_header
(
const
char
*
http_header
)
{
const
char
*
c
;
size_t
name_len
;
/* Disallow \r and \n */
if
((
c
=
strchr
(
http_header
,
'\r'
))
!=
NULL
)
return
true
;
if
((
c
=
strchr
(
http_header
,
'\n'
))
!=
NULL
)
return
true
;
/* Require a header name followed by : */
if
((
name_len
=
http_header_name_length
(
http_header
))
<
1
)
return
true
;
return
t
->
set_callbacks
(
t
,
cbs
->
sideband_progress
,
NULL
,
cbs
->
certificate_check
,
cbs
->
payload
);
return
false
;
}
static
int
set_transport_custom_headers
(
git_transport
*
t
,
const
git_strarray
*
custom_headers
)
static
char
*
forbidden_custom_headers
[]
=
{
"User-Agent"
,
"Host"
,
"Accept"
,
"Content-Type"
,
"Transfer-Encoding"
,
"Content-Length"
,
};
static
bool
is_forbidden_custom_header
(
const
char
*
custom_header
)
{
if
(
!
t
->
set_custom_headers
)
unsigned
long
i
;
size_t
name_len
=
http_header_name_length
(
custom_header
);
/* Disallow headers that we set */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
forbidden_custom_headers
);
i
++
)
if
(
strncmp
(
forbidden_custom_headers
[
i
],
custom_header
,
name_len
)
==
0
)
return
true
;
return
false
;
}
static
int
validate_custom_headers
(
const
git_strarray
*
custom_headers
)
{
size_t
i
;
if
(
!
custom_headers
)
return
0
;
return
t
->
set_custom_headers
(
t
,
custom_headers
);
for
(
i
=
0
;
i
<
custom_headers
->
count
;
i
++
)
{
if
(
is_malformed_http_header
(
custom_headers
->
strings
[
i
]))
{
git_error_set
(
GIT_ERROR_INVALID
,
"custom HTTP header '%s' is malformed"
,
custom_headers
->
strings
[
i
]);
return
-
1
;
}
if
(
is_forbidden_custom_header
(
custom_headers
->
strings
[
i
]))
{
git_error_set
(
GIT_ERROR_INVALID
,
"custom HTTP header '%s' is already set by libgit2"
,
custom_headers
->
strings
[
i
]);
return
-
1
;
}
}
return
0
;
}
int
git_remote__connect
(
git_remote
*
remote
,
git_direction
direction
,
const
git_remote_callbacks
*
callbacks
,
const
git_remote_connection_opts
*
conn
)
static
int
lookup_redirect_config
(
git_remote_redirect_t
*
out
,
git_repository
*
repo
)
{
git_transport
*
t
;
git_config
*
config
;
const
char
*
value
;
int
bool_value
,
error
=
0
;
if
(
!
repo
)
{
*
out
=
GIT_REMOTE_REDIRECT_INITIAL
;
return
0
;
}
if
((
error
=
git_repository_config_snapshot
(
&
config
,
repo
))
<
0
)
goto
done
;
if
((
error
=
git_config_get_string
(
&
value
,
config
,
"http.followRedirects"
))
<
0
)
{
if
(
error
==
GIT_ENOTFOUND
)
{
*
out
=
GIT_REMOTE_REDIRECT_INITIAL
;
error
=
0
;
}
goto
done
;
}
if
(
git_config_parse_bool
(
&
bool_value
,
value
)
==
0
)
{
*
out
=
bool_value
?
GIT_REMOTE_REDIRECT_ALL
:
GIT_REMOTE_REDIRECT_NONE
;
}
else
if
(
strcasecmp
(
value
,
"initial"
)
==
0
)
{
*
out
=
GIT_REMOTE_REDIRECT_INITIAL
;
}
else
{
git_error_set
(
GIT_ERROR_CONFIG
,
"invalid configuration setting '%s' for 'http.followRedirects'"
,
value
);
error
=
-
1
;
}
done:
git_config_free
(
config
);
return
error
;
}
int
git_remote_connect_options_normalize
(
git_remote_connect_options
*
dst
,
git_repository
*
repo
,
const
git_remote_connect_options
*
src
)
{
git_remote_connect_options_dispose
(
dst
);
git_remote_connect_options_init
(
dst
,
GIT_REMOTE_CONNECT_OPTIONS_VERSION
);
if
(
src
)
{
GIT_ERROR_CHECK_VERSION
(
src
,
GIT_REMOTE_CONNECT_OPTIONS_VERSION
,
"git_remote_connect_options"
);
GIT_ERROR_CHECK_VERSION
(
&
src
->
callbacks
,
GIT_REMOTE_CALLBACKS_VERSION
,
"git_remote_callbacks"
);
GIT_ERROR_CHECK_VERSION
(
&
src
->
proxy_opts
,
GIT_PROXY_OPTIONS_VERSION
,
"git_proxy_options"
);
if
(
validate_custom_headers
(
&
src
->
custom_headers
)
<
0
||
git_remote_connect_options_dup
(
dst
,
src
)
<
0
)
return
-
1
;
}
if
(
dst
->
follow_redirects
==
0
)
{
if
(
lookup_redirect_config
(
&
dst
->
follow_redirects
,
repo
)
<
0
)
return
-
1
;
}
return
0
;
}
int
git_remote_connect_ext
(
git_remote
*
remote
,
git_direction
direction
,
const
git_remote_connect_options
*
given_opts
)
{
git_remote_connect_options
opts
=
GIT_REMOTE_CONNECT_OPTIONS_INIT
;
git_str
url
=
GIT_STR_INIT
;
int
flags
=
GIT_TRANSPORTFLAGS_NONE
;
git_transport
*
t
;
int
error
;
void
*
payload
=
NULL
;
git_credential_acquire_cb
credentials
=
NULL
;
git_transport_cb
transport
=
NULL
;
GIT_ASSERT_ARG
(
remote
);
if
(
callbacks
)
{
GIT_ERROR_CHECK_VERSION
(
callbacks
,
GIT_REMOTE_CALLBACKS_VERSION
,
"git_remote_callbacks"
);
credentials
=
callbacks
->
credentials
;
transport
=
callbacks
->
transport
;
payload
=
callbacks
->
payload
;
}
if
(
given_opts
)
memcpy
(
&
opts
,
given_opts
,
sizeof
(
git_remote_connect_options
));
if
(
conn
->
proxy
)
GIT_ERROR_CHECK_VERSION
(
conn
->
proxy
,
GIT_PROXY_OPTIONS_VERSION
,
"git_proxy_options"
);
GIT_ERROR_CHECK_VERSION
(
&
opts
.
callbacks
,
GIT_REMOTE_CALLBACKS_VERSION
,
"git_remote_callbacks"
);
GIT_ERROR_CHECK_VERSION
(
&
opts
.
proxy_opts
,
GIT_PROXY_OPTIONS_VERSION
,
"git_proxy_options"
);
t
=
remote
->
transport
;
if
((
error
=
git_remote__urlfordirection
(
&
url
,
remote
,
direction
,
callbacks
))
<
0
)
if
((
error
=
git_remote__urlfordirection
(
&
url
,
remote
,
direction
,
&
opts
.
callbacks
))
<
0
)
goto
on_error
;
/* If we don't have a transport object yet, and the caller specified a
* custom transport factory, use that */
if
(
!
t
&&
transport
&&
(
error
=
transport
(
&
t
,
remote
,
payload
))
<
0
)
if
(
!
t
&&
opts
.
callbacks
.
transport
&&
(
error
=
opts
.
callbacks
.
transport
(
&
t
,
remote
,
opts
.
callbacks
.
payload
))
<
0
)
goto
on_error
;
/* If we still don't have a transport, then use the global
...
...
@@ -811,11 +958,7 @@ int git_remote__connect(git_remote *remote, git_direction direction, const git_r
if
(
!
t
&&
(
error
=
git_transport_new
(
&
t
,
remote
,
url
.
ptr
))
<
0
)
goto
on_error
;
if
((
error
=
set_transport_custom_headers
(
t
,
conn
->
custom_headers
))
!=
0
)
goto
on_error
;
if
((
error
=
remote_transport_set_callbacks
(
t
,
callbacks
))
<
0
||
(
error
=
t
->
connect
(
t
,
url
.
ptr
,
credentials
,
payload
,
conn
->
proxy
,
direction
,
flags
))
!=
0
)
if
((
error
=
t
->
connect
(
t
,
url
.
ptr
,
direction
,
&
opts
))
!=
0
)
goto
on_error
;
remote
->
transport
=
t
;
...
...
@@ -836,14 +979,25 @@ on_error:
return
error
;
}
int
git_remote_connect
(
git_remote
*
remote
,
git_direction
direction
,
const
git_remote_callbacks
*
callbacks
,
const
git_proxy_options
*
proxy
,
const
git_strarray
*
custom_headers
)
int
git_remote_connect
(
git_remote
*
remote
,
git_direction
direction
,
const
git_remote_callbacks
*
callbacks
,
const
git_proxy_options
*
proxy
,
const
git_strarray
*
custom_headers
)
{
git_remote_connection_opts
conn
;
git_remote_connect_options
opts
=
GIT_REMOTE_CONNECT_OPTIONS_INIT
;
if
(
callbacks
)
memcpy
(
&
opts
.
callbacks
,
callbacks
,
sizeof
(
git_remote_callbacks
));
if
(
proxy
)
memcpy
(
&
opts
.
proxy_opts
,
proxy
,
sizeof
(
git_proxy_options
));
conn
.
proxy
=
proxy
;
conn
.
custom_headers
=
custom_headers
;
if
(
custom_headers
)
memcpy
(
&
opts
.
custom_headers
,
custom_headers
,
sizeof
(
git_strarray
))
;
return
git_remote_
_connect
(
remote
,
direction
,
callbacks
,
&
conn
);
return
git_remote_
connect_ext
(
remote
,
direction
,
&
opts
);
}
int
git_remote_ls
(
const
git_remote_head
***
out
,
size_t
*
size
,
git_remote
*
remote
)
...
...
@@ -1057,38 +1211,50 @@ static int ls_to_vector(git_vector *out, git_remote *remote)
return
0
;
}
int
git_remote_download
(
git_remote
*
remote
,
const
git_strarray
*
refspecs
,
const
git_fetch_options
*
opts
)
{
int
error
=
-
1
;
size_t
i
;
git_vector
*
to_active
,
specs
=
GIT_VECTOR_INIT
,
refs
=
GIT_VECTOR_INIT
;
const
git_remote_callbacks
*
cbs
=
NULL
;
const
git_strarray
*
custom_headers
=
NULL
;
const
git_proxy_options
*
proxy
=
NULL
;
GIT_ASSERT_ARG
(
remote
);
if
(
!
remote
->
repo
)
{
git_error_set
(
GIT_ERROR_INVALID
,
"cannot download detached remote"
);
return
-
1
;
#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; \
}
if
(
opts
)
{
GIT_ERROR_CHECK_VERSION
(
&
opts
->
callbacks
,
GIT_REMOTE_CALLBACKS_VERSION
,
"git_remote_callbacks"
);
cbs
=
&
opts
->
callbacks
;
custom_headers
=
&
opts
->
custom_headers
;
GIT_ERROR_CHECK_VERSION
(
&
opts
->
proxy_opts
,
GIT_PROXY_OPTIONS_VERSION
,
"git_proxy_options"
);
proxy
=
&
opts
->
proxy_opts
;
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
,
git_remote_connect_options
*
opts
)
{
if
(
!
git_remote_connected
(
remote
))
{
return
git_remote_connect_ext
(
remote
,
direction
,
opts
);
}
else
{
return
remote
->
transport
->
set_connect_opts
(
remote
->
transport
,
opts
);
}
}
if
(
!
git_remote_connected
(
remote
)
&&
(
error
=
git_remote_connect
(
remote
,
GIT_DIRECTION_FETCH
,
cbs
,
proxy
,
custom_headers
))
<
0
)
goto
on_error
;
/* Download from an already connected remote. */
static
int
git_remote__download
(
git_remote
*
remote
,
const
git_strarray
*
refspecs
,
const
git_fetch_options
*
opts
)
{
git_vector
*
to_active
,
specs
=
GIT_VECTOR_INIT
,
refs
=
GIT_VECTOR_INIT
;
size_t
i
;
int
error
;
if
(
ls_to_vector
(
&
refs
,
remote
)
<
0
)
return
-
1
;
if
((
git_vector_init
(
&
specs
,
0
,
NULL
))
<
0
)
if
((
error
=
git_vector_init
(
&
specs
,
0
,
NULL
))
<
0
)
goto
on_error
;
remote
->
passed_refspecs
=
0
;
...
...
@@ -1116,7 +1282,7 @@ int git_remote_download(git_remote *remote, const git_strarray *refspecs, const
git_vector_free
(
&
specs
);
if
(
error
<
0
)
return
error
;
goto
on_
error
;
if
(
remote
->
push
)
{
git_push_free
(
remote
->
push
);
...
...
@@ -1124,9 +1290,9 @@ int git_remote_download(git_remote *remote, const git_strarray *refspecs, const
}
if
((
error
=
git_fetch_negotiate
(
remote
,
opts
))
<
0
)
return
error
;
goto
on_
error
;
return
git_fetch_download_pack
(
remote
,
cbs
);
error
=
git_fetch_download_pack
(
remote
);
on_error
:
git_vector_free
(
&
refs
);
...
...
@@ -1135,41 +1301,69 @@ on_error:
return
error
;
}
int
git_remote_download
(
git_remote
*
remote
,
const
git_strarray
*
refspecs
,
const
git_fetch_options
*
opts
)
{
git_remote_connect_options
connect_opts
=
GIT_REMOTE_CONNECT_OPTIONS_INIT
;
int
error
;
GIT_ASSERT_ARG
(
remote
);
if
(
!
remote
->
repo
)
{
git_error_set
(
GIT_ERROR_INVALID
,
"cannot download detached remote"
);
return
-
1
;
}
if
(
connect_opts_from_fetch_opts
(
&
connect_opts
,
remote
,
opts
)
<
0
)
return
-
1
;
if
((
error
=
connect_or_reset_options
(
remote
,
GIT_DIRECTION_FETCH
,
&
connect_opts
))
<
0
)
return
error
;
return
git_remote__download
(
remote
,
refspecs
,
opts
);
}
int
git_remote_fetch
(
git_remote
*
remote
,
const
git_strarray
*
refspecs
,
const
git_fetch_options
*
opts
,
const
char
*
reflog_message
)
git_remote
*
remote
,
const
git_strarray
*
refspecs
,
const
git_fetch_options
*
opts
,
const
char
*
reflog_message
)
{
int
error
,
update_fetchhead
=
1
;
git_remote_autotag_option_t
tagopt
=
remote
->
download_tags
;
bool
prune
=
false
;
git_str
reflog_msg_buf
=
GIT_STR_INIT
;
const
git_remote_callbacks
*
cbs
=
NULL
;
git_remote_connection_opts
conn
=
GIT_REMOTE_CONNECTION_OPTIONS_INIT
;
git_remote_connect_options
connect_opts
=
GIT_REMOTE_CONNECT_OPTIONS_INIT
;
GIT_ASSERT_ARG
(
remote
);
if
(
!
remote
->
repo
)
{
git_error_set
(
GIT_ERROR_INVALID
,
"cannot download detached remote"
);
return
-
1
;
}
if
(
connect_opts_from_fetch_opts
(
&
connect_opts
,
remote
,
opts
)
<
0
)
return
-
1
;
if
((
error
=
connect_or_reset_options
(
remote
,
GIT_DIRECTION_FETCH
,
&
connect_opts
))
<
0
)
return
error
;
if
(
opts
)
{
GIT_ERROR_CHECK_VERSION
(
&
opts
->
callbacks
,
GIT_REMOTE_CALLBACKS_VERSION
,
"git_remote_callbacks"
);
cbs
=
&
opts
->
callbacks
;
conn
.
custom_headers
=
&
opts
->
custom_headers
;
update_fetchhead
=
opts
->
update_fetchhead
;
tagopt
=
opts
->
download_tags
;
GIT_ERROR_CHECK_VERSION
(
&
opts
->
proxy_opts
,
GIT_PROXY_OPTIONS_VERSION
,
"git_proxy_options"
);
conn
.
proxy
=
&
opts
->
proxy_opts
;
}
/* Connect and download everything */
if
((
error
=
git_remote__connect
(
remote
,
GIT_DIRECTION_FETCH
,
cbs
,
&
conn
))
!=
0
)
return
error
;
error
=
git_remote_download
(
remote
,
refspecs
,
opts
);
error
=
git_remote__download
(
remote
,
refspecs
,
opts
);
/* We don't need to be connected anymore */
git_remote_disconnect
(
remote
);
/* If the download failed, return the error */
if
(
error
!=
0
)
return
error
;
goto
done
;
/* Default reflog message */
if
(
reflog_message
)
...
...
@@ -1180,10 +1374,10 @@ int git_remote_fetch(
}
/* Create "remote/foo" branches for all remote branches */
error
=
git_remote_update_tips
(
remote
,
cb
s
,
update_fetchhead
,
tagopt
,
git_str_cstr
(
&
reflog_msg_buf
));
error
=
git_remote_update_tips
(
remote
,
&
connect_opts
.
callback
s
,
update_fetchhead
,
tagopt
,
git_str_cstr
(
&
reflog_msg_buf
));
git_str_dispose
(
&
reflog_msg_buf
);
if
(
error
<
0
)
return
error
;
goto
done
;
if
(
opts
&&
opts
->
prune
==
GIT_FETCH_PRUNE
)
prune
=
true
;
...
...
@@ -1195,8 +1389,10 @@ int git_remote_fetch(
prune
=
remote
->
prune_refs
;
if
(
prune
)
error
=
git_remote_prune
(
remote
,
cb
s
);
error
=
git_remote_prune
(
remote
,
&
connect_opts
.
callback
s
);
done
:
git_remote_connect_options_dispose
(
&
connect_opts
);
return
error
;
}
...
...
@@ -2619,14 +2815,26 @@ done:
return
error
;
}
int
git_remote_upload
(
git_remote
*
remote
,
const
git_strarray
*
refspecs
,
const
git_push_options
*
opts
)
GIT_INLINE
(
int
)
connect_opts_from_push_opts
(
git_remote_connect_options
*
out
,
git_remote
*
remote
,
const
git_push_options
*
push_opts
)
{
size_t
i
;
int
error
;
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
,
const
git_push_options
*
opts
)
{
git_remote_connect_options
connect_opts
=
GIT_REMOTE_CONNECT_OPTIONS_INIT
;
git_push
*
push
;
git_refspec
*
spec
;
const
git_remote_callbacks
*
cbs
=
NULL
;
git_remote_connection_opts
conn
=
GIT_REMOTE_CONNECTION_OPTIONS_INIT
;
size_t
i
;
int
error
;
GIT_ASSERT_ARG
(
remote
);
...
...
@@ -2635,14 +2843,10 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi
return
-
1
;
}
if
(
opts
)
{
cbs
=
&
opts
->
callbacks
;
conn
.
custom_headers
=
&
opts
->
custom_headers
;
conn
.
proxy
=
&
opts
->
proxy_opts
;
}
if
((
error
=
connect_opts_from_push_opts
(
&
connect_opts
,
remote
,
opts
))
<
0
)
goto
cleanup
;
if
(
!
git_remote_connected
(
remote
)
&&
(
error
=
git_remote__connect
(
remote
,
GIT_DIRECTION_PUSH
,
cbs
,
&
conn
))
<
0
)
if
((
error
=
connect_or_reset_options
(
remote
,
GIT_DIRECTION_PUSH
,
&
connect_opts
))
<
0
)
goto
cleanup
;
free_refspecs
(
&
remote
->
active_refspecs
);
...
...
@@ -2654,14 +2858,11 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi
remote
->
push
=
NULL
;
}
if
((
error
=
git_push_new
(
&
remote
->
push
,
remote
))
<
0
)
return
error
;
if
((
error
=
git_push_new
(
&
remote
->
push
,
remote
,
opts
))
<
0
)
goto
cleanup
;
push
=
remote
->
push
;
if
(
opts
&&
(
error
=
git_push_set_options
(
push
,
opts
))
<
0
)
goto
cleanup
;
if
(
refspecs
&&
refspecs
->
count
>
0
)
{
for
(
i
=
0
;
i
<
refspecs
->
count
;
i
++
)
{
if
((
error
=
git_push_add_refspec
(
push
,
refspecs
->
strings
[
i
]))
<
0
)
...
...
@@ -2676,23 +2877,25 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi
}
}
if
((
error
=
git_push_finish
(
push
,
cbs
))
<
0
)
if
((
error
=
git_push_finish
(
push
))
<
0
)
goto
cleanup
;
if
(
c
bs
&&
cbs
->
push_update_reference
&&
(
error
=
git_push_status_foreach
(
push
,
c
bs
->
push_update_reference
,
cbs
->
payload
))
<
0
)
if
(
c
onnect_opts
.
callbacks
.
push_update_reference
&&
(
error
=
git_push_status_foreach
(
push
,
c
onnect_opts
.
callbacks
.
push_update_reference
,
connect_opts
.
callbacks
.
payload
))
<
0
)
goto
cleanup
;
cleanup
:
git_remote_connect_options_dispose
(
&
connect_opts
);
return
error
;
}
int
git_remote_push
(
git_remote
*
remote
,
const
git_strarray
*
refspecs
,
const
git_push_options
*
opts
)
int
git_remote_push
(
git_remote
*
remote
,
const
git_strarray
*
refspecs
,
const
git_push_options
*
opts
)
{
git_remote_connect_options
connect_opts
=
GIT_REMOTE_CONNECT_OPTIONS_INIT
;
int
error
;
const
git_remote_callbacks
*
cbs
=
NULL
;
const
git_strarray
*
custom_headers
=
NULL
;
const
git_proxy_options
*
proxy
=
NULL
;
GIT_ASSERT_ARG
(
remote
);
...
...
@@ -2701,23 +2904,17 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_
return
-
1
;
}
if
(
opts
)
{
GIT_ERROR_CHECK_VERSION
(
&
opts
->
callbacks
,
GIT_REMOTE_CALLBACKS_VERSION
,
"git_remote_callbacks"
);
cbs
=
&
opts
->
callbacks
;
custom_headers
=
&
opts
->
custom_headers
;
GIT_ERROR_CHECK_VERSION
(
&
opts
->
proxy_opts
,
GIT_PROXY_OPTIONS_VERSION
,
"git_proxy_options"
);
proxy
=
&
opts
->
proxy_opts
;
}
if
((
error
=
git_remote_connect
(
remote
,
GIT_DIRECTION_PUSH
,
cbs
,
proxy
,
custom_headers
))
<
0
)
return
error
;
if
(
connect_opts_from_push_opts
(
&
connect_opts
,
remote
,
opts
)
<
0
)
return
-
1
;
if
((
error
=
git_remote_upload
(
remote
,
refspecs
,
opts
))
<
0
)
return
error
;
goto
done
;
error
=
git_remote_update_tips
(
remote
,
cb
s
,
0
,
0
,
NULL
);
error
=
git_remote_update_tips
(
remote
,
&
connect_opts
.
callback
s
,
0
,
0
,
NULL
);
done
:
git_remote_disconnect
(
remote
);
git_remote_connect_options_dispose
(
&
connect_opts
);
return
error
;
}
...
...
src/remote.h
View file @
616628dd
...
...
@@ -37,15 +37,6 @@ struct git_remote {
int
passed_refspecs
;
};
typedef
struct
git_remote_connection_opts
{
const
git_strarray
*
custom_headers
;
const
git_proxy_options
*
proxy
;
}
git_remote_connection_opts
;
#define GIT_REMOTE_CONNECTION_OPTIONS_INIT { NULL, NULL }
int
git_remote__connect
(
git_remote
*
remote
,
git_direction
direction
,
const
git_remote_callbacks
*
callbacks
,
const
git_remote_connection_opts
*
conn
);
int
git_remote__urlfordirection
(
git_str
*
url_out
,
struct
git_remote
*
remote
,
int
direction
,
const
git_remote_callbacks
*
callbacks
);
int
git_remote__http_proxy
(
char
**
out
,
git_remote
*
remote
,
git_net_url
*
url
);
...
...
@@ -54,4 +45,13 @@ git_refspec *git_remote__matching_dst_refspec(git_remote *remote, const char *re
int
git_remote__default_branch
(
git_str
*
out
,
git_remote
*
remote
);
int
git_remote_connect_options_dup
(
git_remote_connect_options
*
dst
,
const
git_remote_connect_options
*
src
);
int
git_remote_connect_options_normalize
(
git_remote_connect_options
*
dst
,
git_repository
*
repo
,
const
git_remote_connect_options
*
src
);
void
git_remote_connect_options_dispose
(
git_remote_connect_options
*
opts
);
#endif
src/status.c
View file @
616628dd
...
...
@@ -336,6 +336,9 @@ int git_status_list_new(
GIT_DIFF_FIND_RENAMES_FROM_REWRITES
|
GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY
;
if
(
opts
!=
NULL
&&
opts
->
rename_threshold
!=
0
)
findopt
.
rename_threshold
=
opts
->
rename_threshold
;
if
(
show
!=
GIT_STATUS_SHOW_WORKDIR_ONLY
)
{
if
((
error
=
git_diff_tree_to_index
(
&
status
->
head2idx
,
repo
,
head
,
index
,
&
diffopt
))
<
0
)
...
...
src/transports/http.c
View file @
616628dd
...
...
@@ -38,7 +38,8 @@ typedef struct {
const
char
*
url
;
const
char
*
request_type
;
const
char
*
response_type
;
unsigned
chunked
:
1
;
unsigned
int
initial
:
1
,
chunked
:
1
;
}
http_service
;
typedef
struct
{
...
...
@@ -70,24 +71,28 @@ static const http_service upload_pack_ls_service = {
GIT_HTTP_METHOD_GET
,
"/info/refs?service=git-upload-pack"
,
NULL
,
"application/x-git-upload-pack-advertisement"
,
1
,
0
};
static
const
http_service
upload_pack_service
=
{
GIT_HTTP_METHOD_POST
,
"/git-upload-pack"
,
"application/x-git-upload-pack-request"
,
"application/x-git-upload-pack-result"
,
0
,
0
};
static
const
http_service
receive_pack_ls_service
=
{
GIT_HTTP_METHOD_GET
,
"/info/refs?service=git-receive-pack"
,
NULL
,
"application/x-git-receive-pack-advertisement"
,
1
,
0
};
static
const
http_service
receive_pack_service
=
{
GIT_HTTP_METHOD_POST
,
"/git-receive-pack"
,
"application/x-git-receive-pack-request"
,
"application/x-git-receive-pack-result"
,
0
,
1
};
...
...
@@ -174,6 +179,7 @@ GIT_INLINE(int) handle_remote_auth(
git_http_response
*
response
)
{
http_subtransport
*
transport
=
OWNING_SUBTRANSPORT
(
stream
);
git_remote_connect_options
*
connect_opts
=
&
transport
->
owner
->
connect_opts
;
if
(
response
->
server_auth_credtypes
==
0
)
{
git_error_set
(
GIT_ERROR_HTTP
,
"server requires authentication that we do not support"
);
...
...
@@ -187,8 +193,8 @@ GIT_INLINE(int) handle_remote_auth(
transport
->
owner
->
url
,
response
->
server_auth_schemetypes
,
response
->
server_auth_credtypes
,
transport
->
owner
->
cred_acquire_cb
,
transport
->
owner
->
cred_acquire_
payload
);
connect_opts
->
callbacks
.
credentials
,
connect_opts
->
callbacks
.
payload
);
}
GIT_INLINE
(
int
)
handle_proxy_auth
(
...
...
@@ -196,6 +202,7 @@ GIT_INLINE(int) handle_proxy_auth(
git_http_response
*
response
)
{
http_subtransport
*
transport
=
OWNING_SUBTRANSPORT
(
stream
);
git_remote_connect_options
*
connect_opts
=
&
transport
->
owner
->
connect_opts
;
if
(
response
->
proxy_auth_credtypes
==
0
)
{
git_error_set
(
GIT_ERROR_HTTP
,
"proxy requires authentication that we do not support"
);
...
...
@@ -206,13 +213,26 @@ GIT_INLINE(int) handle_proxy_auth(
return
handle_auth
(
&
transport
->
proxy
,
SERVER_TYPE_PROXY
,
transport
->
owner
->
proxy
.
url
,
connect_opts
->
proxy_opts
.
url
,
response
->
server_auth_schemetypes
,
response
->
proxy_auth_credtypes
,
transport
->
owner
->
proxy
.
credentials
,
transport
->
owner
->
proxy
.
payload
);
connect_opts
->
proxy_opts
.
credentials
,
connect_opts
->
proxy_opts
.
payload
);
}
static
bool
allow_redirect
(
http_stream
*
stream
)
{
http_subtransport
*
transport
=
OWNING_SUBTRANSPORT
(
stream
);
switch
(
transport
->
owner
->
connect_opts
.
follow_redirects
)
{
case
GIT_REMOTE_REDIRECT_INITIAL
:
return
(
stream
->
service
->
initial
==
1
);
case
GIT_REMOTE_REDIRECT_ALL
:
return
true
;
default
:
return
false
;
}
}
static
int
handle_response
(
bool
*
complete
,
...
...
@@ -231,7 +251,7 @@ static int handle_response(
return
-
1
;
}
if
(
git_net_url_apply_redirect
(
&
transport
->
server
.
url
,
response
->
location
,
stream
->
service
->
url
)
<
0
)
{
if
(
git_net_url_apply_redirect
(
&
transport
->
server
.
url
,
response
->
location
,
allow_redirect
(
stream
),
stream
->
service
->
url
)
<
0
)
{
return
-
1
;
}
...
...
@@ -286,6 +306,7 @@ static int lookup_proxy(
bool
*
out_use
,
http_subtransport
*
transport
)
{
git_remote_connect_options
*
connect_opts
=
&
transport
->
owner
->
connect_opts
;
const
char
*
proxy
;
git_remote
*
remote
;
char
*
config
=
NULL
;
...
...
@@ -294,9 +315,9 @@ static int lookup_proxy(
*
out_use
=
false
;
git_net_url_dispose
(
&
transport
->
proxy
.
url
);
switch
(
transport
->
owner
->
proxy
.
type
)
{
switch
(
connect_opts
->
proxy_opts
.
type
)
{
case
GIT_PROXY_SPECIFIED
:
proxy
=
transport
->
owner
->
proxy
.
url
;
proxy
=
connect_opts
->
proxy_opts
.
url
;
break
;
case
GIT_PROXY_AUTO
:
...
...
@@ -345,7 +366,7 @@ static int generate_request(
request
->
credentials
=
transport
->
server
.
cred
;
request
->
proxy
=
use_proxy
?
&
transport
->
proxy
.
url
:
NULL
;
request
->
proxy_credentials
=
transport
->
proxy
.
cred
;
request
->
custom_headers
=
&
transport
->
owner
->
custom_headers
;
request
->
custom_headers
=
&
transport
->
owner
->
c
onnect_opts
.
c
ustom_headers
;
if
(
stream
->
service
->
method
==
GIT_HTTP_METHOD_POST
)
{
request
->
chunked
=
stream
->
service
->
chunked
;
...
...
@@ -633,6 +654,7 @@ static int http_action(
git_smart_service_t
action
)
{
http_subtransport
*
transport
=
GIT_CONTAINER_OF
(
t
,
http_subtransport
,
parent
);
git_remote_connect_options
*
connect_opts
=
&
transport
->
owner
->
connect_opts
;
http_stream
*
stream
;
const
http_service
*
service
;
int
error
;
...
...
@@ -664,10 +686,10 @@ static int http_action(
if
(
!
transport
->
http_client
)
{
git_http_client_options
opts
=
{
0
};
opts
.
server_certificate_check_cb
=
transport
->
owner
->
certificate_check_cb
;
opts
.
server_certificate_check_payload
=
transport
->
owner
->
message_cb_
payload
;
opts
.
proxy_certificate_check_cb
=
transport
->
owner
->
proxy
.
certificate_check
;
opts
.
proxy_certificate_check_payload
=
transport
->
owner
->
proxy
.
payload
;
opts
.
server_certificate_check_cb
=
connect_opts
->
callbacks
.
certificate_check
;
opts
.
server_certificate_check_payload
=
connect_opts
->
callbacks
.
payload
;
opts
.
proxy_certificate_check_cb
=
connect_opts
->
proxy_opts
.
certificate_check
;
opts
.
proxy_certificate_check_payload
=
connect_opts
->
proxy_opts
.
payload
;
if
(
git_http_client_new
(
&
transport
->
http_client
,
&
opts
)
<
0
)
return
-
1
;
...
...
src/transports/local.c
View file @
616628dd
...
...
@@ -34,12 +34,9 @@ typedef struct {
git_remote
*
owner
;
char
*
url
;
int
direction
;
int
flags
;
git_atomic32
cancelled
;
git_repository
*
repo
;
git_transport_message_cb
progress_cb
;
git_transport_message_cb
error_cb
;
void
*
message_cb_payload
;
git_remote_connect_options
connect_opts
;
git_vector
refs
;
unsigned
connected
:
1
,
have_refs
:
1
;
...
...
@@ -200,30 +197,26 @@ on_error:
static
int
local_connect
(
git_transport
*
transport
,
const
char
*
url
,
git_credential_acquire_cb
cred_acquire_cb
,
void
*
cred_acquire_payload
,
const
git_proxy_options
*
proxy
,
int
direction
,
int
flags
)
int
direction
,
const
git_remote_connect_options
*
connect_opts
)
{
git_repository
*
repo
;
int
error
;
transport_local
*
t
=
(
transport_local
*
)
transport
;
transport_local
*
t
=
(
transport_local
*
)
transport
;
const
char
*
path
;
git_str
buf
=
GIT_STR_INIT
;
GIT_UNUSED
(
cred_acquire_cb
);
GIT_UNUSED
(
cred_acquire_payload
);
GIT_UNUSED
(
proxy
);
if
(
t
->
connected
)
return
0
;
if
(
git_remote_connect_options_normalize
(
&
t
->
connect_opts
,
t
->
owner
->
repo
,
connect_opts
)
<
0
)
return
-
1
;
free_heads
(
&
t
->
refs
);
t
->
url
=
git__strdup
(
url
);
GIT_ERROR_CHECK_ALLOC
(
t
->
url
);
t
->
direction
=
direction
;
t
->
flags
=
flags
;
/* 'url' may be a url or path; convert to a path */
if
((
error
=
git_fs_path_from_url_or_path
(
&
buf
,
url
))
<
0
)
{
...
...
@@ -249,6 +242,20 @@ static int local_connect(
return
0
;
}
static
int
local_set_connect_opts
(
git_transport
*
transport
,
const
git_remote_connect_options
*
connect_opts
)
{
transport_local
*
t
=
(
transport_local
*
)
transport
;
if
(
!
t
->
connected
)
{
git_error_set
(
GIT_ERROR_NET
,
"cannot reconfigure a transport that is not connected"
);
return
-
1
;
}
return
git_remote_connect_options_normalize
(
&
t
->
connect_opts
,
t
->
owner
->
repo
,
connect_opts
);
}
static
int
local_ls
(
const
git_remote_head
***
out
,
size_t
*
size
,
git_transport
*
transport
)
{
transport_local
*
t
=
(
transport_local
*
)
transport
;
...
...
@@ -337,10 +344,10 @@ static int transfer_to_push_transfer(const git_indexer_progress *stats, void *pa
static
int
local_push
(
git_transport
*
transport
,
git_push
*
push
,
const
git_remote_callbacks
*
cbs
)
git_push
*
push
)
{
transport_local
*
t
=
(
transport_local
*
)
transport
;
git_remote_callbacks
*
cbs
=
&
t
->
connect_opts
.
callbacks
;
git_repository
*
remote_repo
=
NULL
;
push_spec
*
spec
;
char
*
url
=
NULL
;
...
...
@@ -349,8 +356,6 @@ static int local_push(
int
error
;
size_t
j
;
GIT_UNUSED
(
cbs
);
/* 'push->remote->url' may be a url or path; convert to a path */
if
((
error
=
git_fs_path_from_url_or_path
(
&
buf
,
push
->
remote
->
url
))
<
0
)
{
git_str_dispose
(
&
buf
);
...
...
@@ -440,12 +445,11 @@ static int local_push(
}
if
(
push
->
specs
.
length
)
{
int
flags
=
t
->
flags
;
url
=
git__strdup
(
t
->
url
);
if
(
!
url
||
t
->
parent
.
close
(
&
t
->
parent
)
<
0
||
t
->
parent
.
connect
(
&
t
->
parent
,
url
,
NULL
,
NULL
,
NULL
,
GIT_DIRECTION_PUSH
,
flags
))
GIT_DIRECTION_PUSH
,
NULL
))
goto
on_error
;
}
...
...
@@ -482,7 +486,7 @@ static int local_counting(int stage, unsigned int current, unsigned int total, v
transport_local
*
t
=
payload
;
int
error
;
if
(
!
t
->
progress_cb
)
if
(
!
t
->
connect_opts
.
callbacks
.
sideband_progress
)
return
0
;
if
(
stage
==
GIT_PACKBUILDER_ADDING_OBJECTS
)
{
...
...
@@ -500,9 +504,19 @@ static int local_counting(int stage, unsigned int current, unsigned int total, v
if
(
git_str_oom
(
&
progress_info
))
return
-
1
;
error
=
t
->
progress_cb
(
git_str_cstr
(
&
progress_info
),
(
int
)
git_str_len
(
&
progress_info
),
t
->
message_cb_payload
);
git_str_dispose
(
&
progress_info
);
if
(
progress_info
.
size
>
INT_MAX
)
{
git_error_set
(
GIT_ERROR_NET
,
"remote sent overly large progress data"
);
git_str_dispose
(
&
progress_info
);
return
-
1
;
}
error
=
t
->
connect_opts
.
callbacks
.
sideband_progress
(
progress_info
.
ptr
,
(
int
)
progress_info
.
size
,
t
->
connect_opts
.
callbacks
.
payload
);
git_str_dispose
(
&
progress_info
);
return
error
;
}
...
...
@@ -532,9 +546,7 @@ static int foreach_reference_cb(git_reference *reference, void *payload)
static
int
local_download_pack
(
git_transport
*
transport
,
git_repository
*
repo
,
git_indexer_progress
*
stats
,
git_indexer_progress_cb
progress_cb
,
void
*
progress_payload
)
git_indexer_progress
*
stats
)
{
transport_local
*
t
=
(
transport_local
*
)
transport
;
git_revwalk
*
walk
=
NULL
;
...
...
@@ -545,9 +557,11 @@ static int local_download_pack(
git_odb_writepack
*
writepack
=
NULL
;
git_odb
*
odb
=
NULL
;
git_str
progress_info
=
GIT_STR_INIT
;
foreach_data
data
=
{
0
};
if
((
error
=
git_revwalk_new
(
&
walk
,
t
->
repo
))
<
0
)
goto
cleanup
;
git_revwalk_sorting
(
walk
,
GIT_SORT_TIME
);
if
((
error
=
git_packbuilder_new
(
&
pack
,
t
->
repo
))
<
0
)
...
...
@@ -583,44 +597,56 @@ static int local_download_pack(
if
((
error
=
git_packbuilder_insert_walk
(
pack
,
walk
)))
goto
cleanup
;
if
((
error
=
git_str_printf
(
&
progress_info
,
counting_objects_fmt
,
git_packbuilder_object_count
(
pack
)))
<
0
)
goto
cleanup
;
if
(
t
->
progress_cb
&&
(
error
=
t
->
progress_cb
(
git_str_cstr
(
&
progress_info
),
(
int
)
git_str_len
(
&
progress_info
),
t
->
message_cb_payload
))
<
0
)
goto
cleanup
;
if
(
t
->
connect_opts
.
callbacks
.
sideband_progress
)
{
if
((
error
=
git_str_printf
(
&
progress_info
,
counting_objects_fmt
,
git_packbuilder_object_count
(
pack
)))
<
0
||
(
error
=
t
->
connect_opts
.
callbacks
.
sideband_progress
(
progress_info
.
ptr
,
(
int
)
progress_info
.
size
,
t
->
connect_opts
.
callbacks
.
payload
))
<
0
)
goto
cleanup
;
}
/* Walk the objects, building a packfile */
if
((
error
=
git_repository_odb__weakptr
(
&
odb
,
repo
))
<
0
)
goto
cleanup
;
/* One last one with the newline */
git_str_clear
(
&
progress_info
);
git_str_printf
(
&
progress_info
,
counting_objects_fmt
,
git_packbuilder_object_count
(
pack
));
if
((
error
=
git_str_putc
(
&
progress_info
,
'\n'
))
<
0
)
goto
cleanup
;
if
(
t
->
progress_cb
&&
(
error
=
t
->
progress_cb
(
git_str_cstr
(
&
progress_info
),
(
int
)
git_str_len
(
&
progress_info
),
t
->
message_cb_payload
))
<
0
)
goto
cleanup
;
if
(
t
->
connect_opts
.
callbacks
.
sideband_progress
)
{
git_str_clear
(
&
progress_info
);
if
((
error
=
git_str_printf
(
&
progress_info
,
counting_objects_fmt
,
git_packbuilder_object_count
(
pack
)))
<
0
||
(
error
=
git_str_putc
(
&
progress_info
,
'\n'
))
<
0
||
(
error
=
t
->
connect_opts
.
callbacks
.
sideband_progress
(
progress_info
.
ptr
,
(
int
)
progress_info
.
size
,
t
->
connect_opts
.
callbacks
.
payload
))
<
0
)
goto
cleanup
;
}
if
((
error
=
git_odb_write_pack
(
&
writepack
,
odb
,
progress_cb
,
progress_payload
))
!=
0
)
if
((
error
=
git_odb_write_pack
(
&
writepack
,
odb
,
t
->
connect_opts
.
callbacks
.
transfer_progress
,
t
->
connect_opts
.
callbacks
.
payload
))
<
0
)
goto
cleanup
;
/* Write the data to the ODB */
{
foreach_data
data
=
{
0
};
data
.
stats
=
stats
;
data
.
progress_cb
=
progress_cb
;
data
.
progress_payload
=
progress_payload
;
data
.
writepack
=
writepack
;
data
.
stats
=
stats
;
data
.
progress_cb
=
t
->
connect_opts
.
callbacks
.
transfer_progress
;
data
.
progress_payload
=
t
->
connect_opts
.
callbacks
.
payload
;
data
.
writepack
=
writepack
;
/* autodetect */
git_packbuilder_set_threads
(
pack
,
0
);
/* autodetect */
git_packbuilder_set_threads
(
pack
,
0
);
if
((
error
=
git_packbuilder_foreach
(
pack
,
foreach_cb
,
&
data
))
!=
0
)
goto
cleanup
;
}
if
((
error
=
git_packbuilder_foreach
(
pack
,
foreach_cb
,
&
data
))
!=
0
)
goto
cleanup
;
error
=
writepack
->
commit
(
writepack
,
stats
);
...
...
@@ -632,24 +658,6 @@ cleanup:
return
error
;
}
static
int
local_set_callbacks
(
git_transport
*
transport
,
git_transport_message_cb
progress_cb
,
git_transport_message_cb
error_cb
,
git_transport_certificate_check_cb
certificate_check_cb
,
void
*
message_cb_payload
)
{
transport_local
*
t
=
(
transport_local
*
)
transport
;
GIT_UNUSED
(
certificate_check_cb
);
t
->
progress_cb
=
progress_cb
;
t
->
error_cb
=
error_cb
;
t
->
message_cb_payload
=
message_cb_payload
;
return
0
;
}
static
int
local_is_connected
(
git_transport
*
transport
)
{
transport_local
*
t
=
(
transport_local
*
)
transport
;
...
...
@@ -657,15 +665,6 @@ static int local_is_connected(git_transport *transport)
return
t
->
connected
;
}
static
int
local_read_flags
(
git_transport
*
transport
,
int
*
flags
)
{
transport_local
*
t
=
(
transport_local
*
)
transport
;
*
flags
=
t
->
flags
;
return
0
;
}
static
void
local_cancel
(
git_transport
*
transport
)
{
transport_local
*
t
=
(
transport_local
*
)
transport
;
...
...
@@ -720,8 +719,8 @@ int git_transport_local(git_transport **out, git_remote *owner, void *param)
GIT_ERROR_CHECK_ALLOC
(
t
);
t
->
parent
.
version
=
GIT_TRANSPORT_VERSION
;
t
->
parent
.
set_callbacks
=
local_set_callbacks
;
t
->
parent
.
connect
=
local_connect
;
t
->
parent
.
set_connect_opts
=
local_set_connect_opts
;
t
->
parent
.
negotiate_fetch
=
local_negotiate_fetch
;
t
->
parent
.
download_pack
=
local_download_pack
;
t
->
parent
.
push
=
local_push
;
...
...
@@ -729,7 +728,6 @@ int git_transport_local(git_transport **out, git_remote *owner, void *param)
t
->
parent
.
free
=
local_free
;
t
->
parent
.
ls
=
local_ls
;
t
->
parent
.
is_connected
=
local_is_connected
;
t
->
parent
.
read_flags
=
local_read_flags
;
t
->
parent
.
cancel
=
local_cancel
;
if
((
error
=
git_vector_init
(
&
t
->
refs
,
0
,
NULL
))
<
0
)
{
...
...
src/transports/smart.c
View file @
616628dd
...
...
@@ -56,101 +56,6 @@ GIT_INLINE(int) git_smart__reset_stream(transport_smart *t, bool close_subtransp
return
0
;
}
static
int
git_smart__set_callbacks
(
git_transport
*
transport
,
git_transport_message_cb
progress_cb
,
git_transport_message_cb
error_cb
,
git_transport_certificate_check_cb
certificate_check_cb
,
void
*
message_cb_payload
)
{
transport_smart
*
t
=
GIT_CONTAINER_OF
(
transport
,
transport_smart
,
parent
);
t
->
progress_cb
=
progress_cb
;
t
->
error_cb
=
error_cb
;
t
->
certificate_check_cb
=
certificate_check_cb
;
t
->
message_cb_payload
=
message_cb_payload
;
return
0
;
}
static
size_t
http_header_name_length
(
const
char
*
http_header
)
{
const
char
*
colon
=
strchr
(
http_header
,
':'
);
if
(
!
colon
)
return
0
;
return
colon
-
http_header
;
}
static
bool
is_malformed_http_header
(
const
char
*
http_header
)
{
const
char
*
c
;
size_t
name_len
;
/* Disallow \r and \n */
c
=
strchr
(
http_header
,
'\r'
);
if
(
c
)
return
true
;
c
=
strchr
(
http_header
,
'\n'
);
if
(
c
)
return
true
;
/* Require a header name followed by : */
name_len
=
http_header_name_length
(
http_header
);
if
(
name_len
<
1
)
return
true
;
return
false
;
}
static
char
*
forbidden_custom_headers
[]
=
{
"User-Agent"
,
"Host"
,
"Accept"
,
"Content-Type"
,
"Transfer-Encoding"
,
"Content-Length"
,
};
static
bool
is_forbidden_custom_header
(
const
char
*
custom_header
)
{
unsigned
long
i
;
size_t
name_len
=
http_header_name_length
(
custom_header
);
/* Disallow headers that we set */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
forbidden_custom_headers
);
i
++
)
if
(
strncmp
(
forbidden_custom_headers
[
i
],
custom_header
,
name_len
)
==
0
)
return
true
;
return
false
;
}
static
int
git_smart__set_custom_headers
(
git_transport
*
transport
,
const
git_strarray
*
custom_headers
)
{
transport_smart
*
t
=
GIT_CONTAINER_OF
(
transport
,
transport_smart
,
parent
);
size_t
i
;
if
(
t
->
custom_headers
.
count
)
git_strarray_dispose
(
&
t
->
custom_headers
);
if
(
!
custom_headers
)
return
0
;
for
(
i
=
0
;
i
<
custom_headers
->
count
;
i
++
)
{
if
(
is_malformed_http_header
(
custom_headers
->
strings
[
i
]))
{
git_error_set
(
GIT_ERROR_INVALID
,
"custom HTTP header '%s' is malformed"
,
custom_headers
->
strings
[
i
]);
return
-
1
;
}
if
(
is_forbidden_custom_header
(
custom_headers
->
strings
[
i
]))
{
git_error_set
(
GIT_ERROR_INVALID
,
"custom HTTP header '%s' is already set by libgit2"
,
custom_headers
->
strings
[
i
]);
return
-
1
;
}
}
return
git_strarray_copy
(
&
t
->
custom_headers
,
custom_headers
);
}
int
git_smart__update_heads
(
transport_smart
*
t
,
git_vector
*
symrefs
)
{
size_t
i
;
...
...
@@ -206,11 +111,8 @@ static void free_symrefs(git_vector *symrefs)
static
int
git_smart__connect
(
git_transport
*
transport
,
const
char
*
url
,
git_credential_acquire_cb
cred_acquire_cb
,
void
*
cred_acquire_payload
,
const
git_proxy_options
*
proxy
,
int
direction
,
int
flag
s
)
const
git_remote_connect_options
*
connect_opt
s
)
{
transport_smart
*
t
=
GIT_CONTAINER_OF
(
transport
,
transport_smart
,
parent
);
git_smart_subtransport_stream
*
stream
;
...
...
@@ -223,24 +125,19 @@ static int git_smart__connect(
if
(
git_smart__reset_stream
(
t
,
true
)
<
0
)
return
-
1
;
if
(
git_remote_connect_options_normalize
(
&
t
->
connect_opts
,
t
->
owner
->
repo
,
connect_opts
)
<
0
)
return
-
1
;
t
->
url
=
git__strdup
(
url
);
GIT_ERROR_CHECK_ALLOC
(
t
->
url
);
git_proxy_options_clear
(
&
t
->
proxy
);
if
(
git_proxy_options_dup
(
&
t
->
proxy
,
proxy
)
<
0
)
return
-
1
;
t
->
direction
=
direction
;
t
->
flags
=
flags
;
t
->
cred_acquire_cb
=
cred_acquire_cb
;
t
->
cred_acquire_payload
=
cred_acquire_payload
;
if
(
GIT_DIRECTION_FETCH
==
t
->
direction
)
if
(
GIT_DIRECTION_FETCH
==
t
->
direction
)
{
service
=
GIT_SERVICE_UPLOADPACK_LS
;
else
if
(
GIT_DIRECTION_PUSH
==
t
->
direction
)
}
else
if
(
GIT_DIRECTION_PUSH
==
t
->
direction
)
{
service
=
GIT_SERVICE_RECEIVEPACK_LS
;
else
{
}
else
{
git_error_set
(
GIT_ERROR_NET
,
"invalid direction"
);
return
-
1
;
}
...
...
@@ -315,6 +212,20 @@ cleanup:
return
error
;
}
static
int
git_smart__set_connect_opts
(
git_transport
*
transport
,
const
git_remote_connect_options
*
opts
)
{
transport_smart
*
t
=
GIT_CONTAINER_OF
(
transport
,
transport_smart
,
parent
);
if
(
!
t
->
connected
)
{
git_error_set
(
GIT_ERROR_NET
,
"cannot reconfigure a transport that is not connected"
);
return
-
1
;
}
return
git_remote_connect_options_normalize
(
&
t
->
connect_opts
,
t
->
owner
->
repo
,
opts
);
}
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
);
...
...
@@ -401,15 +312,6 @@ static int git_smart__is_connected(git_transport *transport)
return
t
->
connected
;
}
static
int
git_smart__read_flags
(
git_transport
*
transport
,
int
*
flags
)
{
transport_smart
*
t
=
GIT_CONTAINER_OF
(
transport
,
transport_smart
,
parent
);
*
flags
=
t
->
flags
;
return
0
;
}
static
int
git_smart__close
(
git_transport
*
transport
)
{
transport_smart
*
t
=
GIT_CONTAINER_OF
(
transport
,
transport_smart
,
parent
);
...
...
@@ -465,9 +367,8 @@ static void git_smart__free(git_transport *transport)
git_pkt_free
(
p
);
git_vector_free
(
refs
);
git__free
((
char
*
)
t
->
proxy
.
url
);
git_
strarray_dispose
(
&
t
->
custom_header
s
);
git_
remote_connect_options_dispose
(
&
t
->
connect_opt
s
);
git__free
(
t
);
}
...
...
@@ -482,34 +383,30 @@ static int ref_name_cmp(const void *a, const void *b)
int
git_transport_smart_certificate_check
(
git_transport
*
transport
,
git_cert
*
cert
,
int
valid
,
const
char
*
hostname
)
{
transport_smart
*
t
=
GIT_CONTAINER_OF
(
transport
,
transport_smart
,
parent
);
git_remote_connect_options
*
connect_opts
=
&
t
->
connect_opts
;
GIT_ASSERT_ARG
(
transport
);
GIT_ASSERT_ARG
(
cert
);
GIT_ASSERT_ARG
(
hostname
);
if
(
!
t
->
certificate_check_cb
)
if
(
!
connect_opts
->
callbacks
.
certificate_check
)
return
GIT_PASSTHROUGH
;
return
t
->
certificate_check_cb
(
cert
,
valid
,
hostname
,
t
->
message_cb_
payload
);
return
connect_opts
->
callbacks
.
certificate_check
(
cert
,
valid
,
hostname
,
connect_opts
->
callbacks
.
payload
);
}
int
git_transport_smart_credentials
(
git_credential
**
out
,
git_transport
*
transport
,
const
char
*
user
,
int
methods
)
{
transport_smart
*
t
=
GIT_CONTAINER_OF
(
transport
,
transport_smart
,
parent
);
git_remote_connect_options
*
connect_opts
=
&
t
->
connect_opts
;
GIT_ASSERT_ARG
(
out
);
GIT_ASSERT_ARG
(
transport
);
if
(
!
t
->
cred_acquire_cb
)
if
(
!
connect_opts
->
callbacks
.
credentials
)
return
GIT_PASSTHROUGH
;
return
t
->
cred_acquire_cb
(
out
,
t
->
url
,
user
,
methods
,
t
->
cred_acquire_payload
);
}
int
git_transport_smart_proxy_options
(
git_proxy_options
*
out
,
git_transport
*
transport
)
{
transport_smart
*
t
=
GIT_CONTAINER_OF
(
transport
,
transport_smart
,
parent
);
return
git_proxy_options_dup
(
out
,
&
t
->
proxy
);
return
connect_opts
->
callbacks
.
credentials
(
out
,
t
->
url
,
user
,
methods
,
connect_opts
->
callbacks
.
payload
);
}
int
git_transport_smart
(
git_transport
**
out
,
git_remote
*
owner
,
void
*
param
)
...
...
@@ -524,9 +421,8 @@ int git_transport_smart(git_transport **out, git_remote *owner, void *param)
GIT_ERROR_CHECK_ALLOC
(
t
);
t
->
parent
.
version
=
GIT_TRANSPORT_VERSION
;
t
->
parent
.
set_callbacks
=
git_smart__set_callbacks
;
t
->
parent
.
set_custom_headers
=
git_smart__set_custom_headers
;
t
->
parent
.
connect
=
git_smart__connect
;
t
->
parent
.
set_connect_opts
=
git_smart__set_connect_opts
;
t
->
parent
.
close
=
git_smart__close
;
t
->
parent
.
free
=
git_smart__free
;
t
->
parent
.
negotiate_fetch
=
git_smart__negotiate_fetch
;
...
...
@@ -534,7 +430,6 @@ int git_transport_smart(git_transport **out, git_remote *owner, void *param)
t
->
parent
.
push
=
git_smart__push
;
t
->
parent
.
ls
=
git_smart__ls
;
t
->
parent
.
is_connected
=
git_smart__is_connected
;
t
->
parent
.
read_flags
=
git_smart__read_flags
;
t
->
parent
.
cancel
=
git_smart__cancel
;
t
->
owner
=
owner
;
...
...
src/transports/smart.h
View file @
616628dd
...
...
@@ -119,16 +119,16 @@ typedef struct {
}
git_pkt_unpack
;
typedef
struct
transport_smart_caps
{
int
common
:
1
,
ofs_delta
:
1
,
multi_ack
:
1
,
multi_ack_detailed
:
1
,
side_band
:
1
,
side_band_64k
:
1
,
include_tag
:
1
,
delete_refs
:
1
,
report_status
:
1
,
thin_pack
:
1
;
unsigned
int
common
:
1
,
ofs_delta
:
1
,
multi_ack
:
1
,
multi_ack_detailed
:
1
,
side_band
:
1
,
side_band_64k
:
1
,
include_tag
:
1
,
delete_refs
:
1
,
report_status
:
1
,
thin_pack
:
1
;
}
transport_smart_caps
;
typedef
int
(
*
packetsize_cb
)(
size_t
received
,
void
*
payload
);
...
...
@@ -137,16 +137,8 @@ typedef struct {
git_transport
parent
;
git_remote
*
owner
;
char
*
url
;
git_credential_acquire_cb
cred_acquire_cb
;
void
*
cred_acquire_payload
;
git_proxy_options
proxy
;
git_remote_connect_options
connect_opts
;
int
direction
;
int
flags
;
git_transport_message_cb
progress_cb
;
git_transport_message_cb
error_cb
;
git_transport_certificate_check_cb
certificate_check_cb
;
void
*
message_cb_payload
;
git_strarray
custom_headers
;
git_smart_subtransport
*
wrapped
;
git_smart_subtransport_stream
*
current_stream
;
transport_smart_caps
caps
;
...
...
@@ -157,8 +149,8 @@ typedef struct {
packetsize_cb
packetsize_cb
;
void
*
packetsize_payload
;
unsigned
rpc
:
1
,
have_refs
:
1
,
connected
:
1
;
have_refs
:
1
,
connected
:
1
;
gitno_buffer
buffer
;
char
buffer_data
[
65536
];
}
transport_smart
;
...
...
@@ -166,7 +158,7 @@ typedef struct {
/* smart_protocol.c */
int
git_smart__store_refs
(
transport_smart
*
t
,
int
flushes
);
int
git_smart__detect_caps
(
git_pkt_ref
*
pkt
,
transport_smart_caps
*
caps
,
git_vector
*
symrefs
);
int
git_smart__push
(
git_transport
*
transport
,
git_push
*
push
,
const
git_remote_callbacks
*
cbs
);
int
git_smart__push
(
git_transport
*
transport
,
git_push
*
push
);
int
git_smart__negotiate_fetch
(
git_transport
*
transport
,
...
...
@@ -177,9 +169,7 @@ int git_smart__negotiate_fetch(
int
git_smart__download_pack
(
git_transport
*
transport
,
git_repository
*
repo
,
git_indexer_progress
*
stats
,
git_indexer_progress_cb
progress_cb
,
void
*
progress_payload
);
git_indexer_progress
*
stats
);
/* smart.c */
int
git_smart__negotiation_step
(
git_transport
*
transport
,
void
*
data
,
size_t
len
);
...
...
src/transports/smart_protocol.c
View file @
616628dd
...
...
@@ -512,9 +512,7 @@ static int network_packetsize(size_t received, void *payload)
int
git_smart__download_pack
(
git_transport
*
transport
,
git_repository
*
repo
,
git_indexer_progress
*
stats
,
git_indexer_progress_cb
progress_cb
,
void
*
progress_payload
)
git_indexer_progress
*
stats
)
{
transport_smart
*
t
=
(
transport_smart
*
)
transport
;
gitno_buffer
*
buf
=
&
t
->
buffer
;
...
...
@@ -523,6 +521,10 @@ int git_smart__download_pack(
int
error
=
0
;
struct
network_packetsize_payload
npp
=
{
0
};
// TODO
git_indexer_progress_cb
progress_cb
=
t
->
connect_opts
.
callbacks
.
transfer_progress
;
void
*
progress_payload
=
t
->
connect_opts
.
callbacks
.
payload
;
memset
(
stats
,
0
,
sizeof
(
git_indexer_progress
));
if
(
progress_cb
)
{
...
...
@@ -568,7 +570,7 @@ int git_smart__download_pack(
git_error_clear
();
error
=
GIT_EUSER
;
}
else
if
(
pkt
->
type
==
GIT_PKT_PROGRESS
)
{
if
(
t
->
progress_cb
)
{
if
(
t
->
connect_opts
.
callbacks
.
sideband_progress
)
{
git_pkt_progress
*
p
=
(
git_pkt_progress
*
)
pkt
;
if
(
p
->
len
>
INT_MAX
)
{
...
...
@@ -577,7 +579,7 @@ int git_smart__download_pack(
goto
done
;
}
error
=
t
->
progress_cb
(
p
->
data
,
(
int
)
p
->
len
,
t
->
message_cb_
payload
);
error
=
t
->
connect_opts
.
callbacks
.
sideband_progress
(
p
->
data
,
(
int
)
p
->
len
,
t
->
connect_opts
.
callbacks
.
payload
);
}
}
else
if
(
pkt
->
type
==
GIT_PKT_DATA
)
{
git_pkt_data
*
p
=
(
git_pkt_data
*
)
pkt
;
...
...
@@ -811,7 +813,7 @@ static int parse_report(transport_smart *transport, git_push *push)
error
=
-
1
;
break
;
case
GIT_PKT_PROGRESS
:
if
(
transport
->
progress_cb
)
{
if
(
transport
->
connect_opts
.
callbacks
.
sideband_progress
)
{
git_pkt_progress
*
p
=
(
git_pkt_progress
*
)
pkt
;
if
(
p
->
len
>
INT_MAX
)
{
...
...
@@ -820,7 +822,7 @@ static int parse_report(transport_smart *transport, git_push *push)
goto
done
;
}
error
=
transport
->
progress_cb
(
p
->
data
,
(
int
)
p
->
len
,
transport
->
message_cb_
payload
);
error
=
transport
->
connect_opts
.
callbacks
.
sideband_progress
(
p
->
data
,
(
int
)
p
->
len
,
transport
->
connect_opts
.
callbacks
.
payload
);
}
break
;
default:
...
...
@@ -987,9 +989,10 @@ static int stream_thunk(void *buf, size_t size, void *data)
return
error
;
}
int
git_smart__push
(
git_transport
*
transport
,
git_push
*
push
,
const
git_remote_callbacks
*
cbs
)
int
git_smart__push
(
git_transport
*
transport
,
git_push
*
push
)
{
transport_smart
*
t
=
(
transport_smart
*
)
transport
;
git_remote_callbacks
*
cbs
=
&
t
->
connect_opts
.
callbacks
;
struct
push_packbuilder_payload
packbuilder_payload
=
{
0
};
git_str
pktline
=
GIT_STR_INIT
;
int
error
=
0
,
need_pack
=
0
;
...
...
src/transports/ssh.c
View file @
616628dd
...
...
@@ -441,11 +441,15 @@ static int request_creds(git_credential **out, ssh_subtransport *t, const char *
int
error
,
no_callback
=
0
;
git_credential
*
cred
=
NULL
;
if
(
!
t
->
owner
->
c
red_acquire_cb
)
{
if
(
!
t
->
owner
->
c
onnect_opts
.
callbacks
.
credentials
)
{
no_callback
=
1
;
}
else
{
error
=
t
->
owner
->
cred_acquire_cb
(
&
cred
,
t
->
owner
->
url
,
user
,
auth_methods
,
t
->
owner
->
cred_acquire_payload
);
error
=
t
->
owner
->
connect_opts
.
callbacks
.
credentials
(
&
cred
,
t
->
owner
->
url
,
user
,
auth_methods
,
t
->
owner
->
connect_opts
.
callbacks
.
payload
);
if
(
error
==
GIT_PASSTHROUGH
)
{
no_callback
=
1
;
...
...
@@ -558,7 +562,7 @@ post_extract:
if
((
error
=
_git_ssh_session_create
(
&
session
,
s
->
io
))
<
0
)
goto
done
;
if
(
t
->
owner
->
c
ertificate_check_cb
!=
NULL
)
{
if
(
t
->
owner
->
c
onnect_opts
.
callbacks
.
certificate_check
!=
NULL
)
{
git_cert_hostkey
cert
=
{{
0
}},
*
cert_ptr
;
const
char
*
key
;
size_t
cert_len
;
...
...
@@ -632,7 +636,11 @@ post_extract:
cert_ptr
=
&
cert
;
error
=
t
->
owner
->
certificate_check_cb
((
git_cert
*
)
cert_ptr
,
0
,
urldata
.
host
,
t
->
owner
->
message_cb_payload
);
error
=
t
->
owner
->
connect_opts
.
callbacks
.
certificate_check
(
(
git_cert
*
)
cert_ptr
,
0
,
urldata
.
host
,
t
->
owner
->
connect_opts
.
callbacks
.
payload
);
if
(
error
<
0
&&
error
!=
GIT_PASSTHROUGH
)
{
if
(
!
git_error_last
())
...
...
src/transports/winhttp.c
View file @
616628dd
...
...
@@ -293,14 +293,14 @@ static int certificate_check(winhttp_stream *s, int valid)
git_cert_x509
cert
;
/* If there is no override, we should fail if WinHTTP doesn't think it's fine */
if
(
t
->
owner
->
c
ertificate_check_cb
==
NULL
&&
!
valid
)
{
if
(
t
->
owner
->
c
onnect_opts
.
callbacks
.
certificate_check
==
NULL
&&
!
valid
)
{
if
(
!
git_error_last
())
git_error_set
(
GIT_ERROR_HTTP
,
"unknown certificate check failure"
);
return
GIT_ECERTIFICATE
;
}
if
(
t
->
owner
->
c
ertificate_check_cb
==
NULL
||
git__strcmp
(
t
->
server
.
url
.
scheme
,
"https"
)
!=
0
)
if
(
t
->
owner
->
c
onnect_opts
.
callbacks
.
certificate_check
==
NULL
||
git__strcmp
(
t
->
server
.
url
.
scheme
,
"https"
)
!=
0
)
return
0
;
if
(
!
WinHttpQueryOption
(
s
->
request
,
WINHTTP_OPTION_SERVER_CERT_CONTEXT
,
&
cert_ctx
,
&
cert_ctx_size
))
{
...
...
@@ -312,7 +312,7 @@ static int certificate_check(winhttp_stream *s, int valid)
cert
.
parent
.
cert_type
=
GIT_CERT_X509
;
cert
.
data
=
cert_ctx
->
pbCertEncoded
;
cert
.
len
=
cert_ctx
->
cbCertEncoded
;
error
=
t
->
owner
->
c
ertificate_check_cb
((
git_cert
*
)
&
cert
,
valid
,
t
->
server
.
url
.
host
,
t
->
owner
->
message_cb_
payload
);
error
=
t
->
owner
->
c
onnect_opts
.
callbacks
.
certificate_check
((
git_cert
*
)
&
cert
,
valid
,
t
->
server
.
url
.
host
,
t
->
owner
->
connect_opts
.
callbacks
.
payload
);
CertFreeCertificateContext
(
cert_ctx
);
if
(
error
==
GIT_PASSTHROUGH
)
...
...
@@ -426,7 +426,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
goto
on_error
;
}
proxy_opts
=
&
t
->
owner
->
proxy
;
proxy_opts
=
&
t
->
owner
->
connect_opts
.
proxy_opts
;
if
(
proxy_opts
->
type
==
GIT_PROXY_AUTO
)
{
/* Set proxy if necessary */
if
(
git_remote__http_proxy
(
&
proxy_url
,
t
->
owner
->
owner
,
&
t
->
server
.
url
)
<
0
)
...
...
@@ -560,10 +560,10 @@ static int winhttp_stream_connect(winhttp_stream *s)
}
}
for
(
i
=
0
;
i
<
t
->
owner
->
custom_headers
.
count
;
i
++
)
{
if
(
t
->
owner
->
custom_headers
.
strings
[
i
])
{
for
(
i
=
0
;
i
<
t
->
owner
->
c
onnect_opts
.
c
ustom_headers
.
count
;
i
++
)
{
if
(
t
->
owner
->
c
onnect_opts
.
c
ustom_headers
.
strings
[
i
])
{
git_str_clear
(
&
buf
);
git_str_puts
(
&
buf
,
t
->
owner
->
custom_headers
.
strings
[
i
]);
git_str_puts
(
&
buf
,
t
->
owner
->
c
onnect_opts
.
c
ustom_headers
.
strings
[
i
]);
if
(
git__utf8_to_16
(
ct
,
MAX_CONTENT_TYPE_LEN
,
git_str_cstr
(
&
buf
))
<
0
)
{
git_error_set
(
GIT_ERROR_OS
,
"failed to convert custom header to wide characters"
);
goto
on_error
;
...
...
@@ -577,14 +577,6 @@ static int winhttp_stream_connect(winhttp_stream *s)
}
}
/* If requested, disable certificate validation */
if
(
strcmp
(
t
->
server
.
url
.
scheme
,
"https"
)
==
0
)
{
int
flags
;
if
(
t
->
owner
->
parent
.
read_flags
(
&
t
->
owner
->
parent
,
&
flags
)
<
0
)
goto
on_error
;
}
if
((
error
=
apply_credentials
(
s
->
request
,
&
t
->
server
.
url
,
WINHTTP_AUTH_TARGET_SERVER
,
t
->
server
.
cred
,
t
->
server
.
auth_mechanisms
))
<
0
)
goto
on_error
;
...
...
@@ -1197,8 +1189,10 @@ replay:
winhttp_stream_close
(
s
);
if
(
!
git__prefixcmp_icase
(
location8
,
prefix_https
))
{
bool
follow
=
(
t
->
owner
->
connect_opts
.
follow_redirects
!=
GIT_REMOTE_REDIRECT_NONE
);
/* Upgrade to secure connection; disconnect and start over */
if
(
git_net_url_apply_redirect
(
&
t
->
server
.
url
,
location8
,
s
->
service_url
)
<
0
)
{
if
(
git_net_url_apply_redirect
(
&
t
->
server
.
url
,
location8
,
follow
,
s
->
service_url
)
<
0
)
{
git__free
(
location8
);
return
-
1
;
}
...
...
@@ -1218,8 +1212,8 @@ replay:
int
error
=
acquire_credentials
(
s
->
request
,
&
t
->
server
,
t
->
owner
->
url
,
t
->
owner
->
c
red_acquire_cb
,
t
->
owner
->
c
red_acquire_
payload
);
t
->
owner
->
c
onnect_opts
.
callbacks
.
credentials
,
t
->
owner
->
c
onnect_opts
.
callbacks
.
payload
);
if
(
error
<
0
)
{
return
error
;
...
...
@@ -1231,9 +1225,9 @@ replay:
}
else
if
(
status_code
==
HTTP_STATUS_PROXY_AUTH_REQ
)
{
int
error
=
acquire_credentials
(
s
->
request
,
&
t
->
proxy
,
t
->
owner
->
proxy
.
url
,
t
->
owner
->
proxy
.
credentials
,
t
->
owner
->
proxy
.
payload
);
t
->
owner
->
connect_opts
.
proxy_opts
.
url
,
t
->
owner
->
connect_opts
.
proxy_opts
.
credentials
,
t
->
owner
->
connect_opts
.
proxy_opts
.
payload
);
if
(
error
<
0
)
{
return
error
;
...
...
src/worktree.h
View file @
616628dd
...
...
@@ -31,7 +31,7 @@ struct git_worktree {
/* Path to the parent's working directory */
char
*
parent_path
;
int
locked
:
1
;
unsigned
int
locked
:
1
;
};
char
*
git_worktree__read_link
(
const
char
*
base
,
const
char
*
file
);
...
...
tests/config/conditionals.c
View file @
616628dd
...
...
@@ -148,3 +148,28 @@ void test_config_conditionals__onbranch(void)
assert_condition_includes
(
"onbranch"
,
"dir*"
,
false
);
assert_condition_includes
(
"onbranch"
,
"dir/*"
,
false
);
}
void
test_config_conditionals__empty
(
void
)
{
git_buf
value
=
GIT_BUF_INIT
;
git_str
buf
=
GIT_STR_INIT
;
git_config
*
cfg
;
cl_git_pass
(
git_str_puts
(
&
buf
,
"[includeIf]
\n
"
));
cl_git_pass
(
git_str_puts
(
&
buf
,
"path = other
\n
"
));
cl_git_mkfile
(
"empty_standard_repo/.git/config"
,
buf
.
ptr
);
cl_git_mkfile
(
"empty_standard_repo/.git/other"
,
"[foo]
\n
bar=baz
\n
"
);
_repo
=
cl_git_sandbox_reopen
();
git_str_dispose
(
&
buf
);
cl_git_pass
(
git_repository_config
(
&
cfg
,
_repo
));
cl_git_fail_with
(
GIT_ENOTFOUND
,
git_config_get_string_buf
(
&
value
,
cfg
,
"foo.bar"
));
git_str_dispose
(
&
buf
);
git_buf_dispose
(
&
value
);
git_config_free
(
cfg
);
}
tests/network/url/redirect.c
View file @
616628dd
...
...
@@ -17,9 +17,9 @@ void test_network_url_redirect__cleanup(void)
void
test_network_url_redirect__redirect_http
(
void
)
{
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"http://example.com/foo/bar/baz"
));
"http://example.com/foo/bar/baz"
));
cl_git_pass
(
git_net_url_apply_redirect
(
&
conndata
,
"http://example.com/foo/bar/baz"
,
"bar/baz"
));
"http://example.com/foo/bar/baz"
,
false
,
"bar/baz"
));
cl_assert_equal_s
(
conndata
.
scheme
,
"http"
);
cl_assert_equal_s
(
conndata
.
host
,
"example.com"
);
cl_assert_equal_s
(
conndata
.
port
,
"80"
);
...
...
@@ -31,9 +31,9 @@ void test_network_url_redirect__redirect_http(void)
void
test_network_url_redirect__redirect_ssl
(
void
)
{
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"https://example.com/foo/bar/baz"
));
"https://example.com/foo/bar/baz"
));
cl_git_pass
(
git_net_url_apply_redirect
(
&
conndata
,
"https://example.com/foo/bar/baz"
,
"bar/baz"
));
"https://example.com/foo/bar/baz"
,
false
,
"bar/baz"
));
cl_assert_equal_s
(
conndata
.
scheme
,
"https"
);
cl_assert_equal_s
(
conndata
.
host
,
"example.com"
);
cl_assert_equal_s
(
conndata
.
port
,
"443"
);
...
...
@@ -45,9 +45,9 @@ void test_network_url_redirect__redirect_ssl(void)
void
test_network_url_redirect__redirect_leaves_root_path
(
void
)
{
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"https://example.com/foo/bar/baz"
));
"https://example.com/foo/bar/baz"
));
cl_git_pass
(
git_net_url_apply_redirect
(
&
conndata
,
"https://example.com/foo/bar/baz"
,
"/foo/bar/baz"
));
"https://example.com/foo/bar/baz"
,
false
,
"/foo/bar/baz"
));
cl_assert_equal_s
(
conndata
.
scheme
,
"https"
);
cl_assert_equal_s
(
conndata
.
host
,
"example.com"
);
cl_assert_equal_s
(
conndata
.
port
,
"443"
);
...
...
@@ -59,9 +59,9 @@ void test_network_url_redirect__redirect_leaves_root_path(void)
void
test_network_url_redirect__redirect_encoded_username_password
(
void
)
{
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"https://user%2fname:pass%40word%zyx%v@example.com/foo/bar/baz"
));
"https://user%2fname:pass%40word%zyx%v@example.com/foo/bar/baz"
));
cl_git_pass
(
git_net_url_apply_redirect
(
&
conndata
,
"https://user%2fname:pass%40word%zyx%v@example.com/foo/bar/baz"
,
"bar/baz"
));
"https://user%2fname:pass%40word%zyx%v@example.com/foo/bar/baz"
,
false
,
"bar/baz"
));
cl_assert_equal_s
(
conndata
.
scheme
,
"https"
);
cl_assert_equal_s
(
conndata
.
host
,
"example.com"
);
cl_assert_equal_s
(
conndata
.
port
,
"443"
);
...
...
@@ -70,27 +70,42 @@ void test_network_url_redirect__redirect_encoded_username_password(void)
cl_assert_equal_s
(
conndata
.
password
,
"pass@word%zyx%v"
);
}
void
test_network_url_redirect__redirect_cross_host_allowed
(
void
)
{
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"https://bar.com/bar/baz"
));
cl_git_pass
(
git_net_url_apply_redirect
(
&
conndata
,
"https://foo.com/bar/baz"
,
true
,
NULL
));
cl_assert_equal_s
(
conndata
.
scheme
,
"https"
);
cl_assert_equal_s
(
conndata
.
host
,
"foo.com"
);
cl_assert_equal_s
(
conndata
.
port
,
"443"
);
cl_assert_equal_s
(
conndata
.
path
,
"/bar/baz"
);
cl_assert_equal_p
(
conndata
.
username
,
NULL
);
cl_assert_equal_p
(
conndata
.
password
,
NULL
);
}
void
test_network_url_redirect__redirect_cross_host_denied
(
void
)
{
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"https://bar.com/bar/baz"
));
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"https://bar.com/bar/baz"
));
cl_git_fail_with
(
git_net_url_apply_redirect
(
&
conndata
,
"https://foo.com/bar/baz"
,
NULL
),
-
1
);
"https://foo.com/bar/baz"
,
false
,
NULL
),
-
1
);
}
void
test_network_url_redirect__redirect_http_downgrade_denied
(
void
)
{
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"https://foo.com/bar/baz"
));
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"https://foo.com/bar/baz"
));
cl_git_fail_with
(
git_net_url_apply_redirect
(
&
conndata
,
"http://foo.com/bar/baz"
,
NULL
),
-
1
);
"http://foo.com/bar/baz"
,
true
,
NULL
),
-
1
);
}
void
test_network_url_redirect__redirect_relative
(
void
)
{
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"http://foo.com/bar/baz/biff"
));
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"http://foo.com/bar/baz/biff"
));
cl_git_pass
(
git_net_url_apply_redirect
(
&
conndata
,
"/zap/baz/biff?bam"
,
NULL
));
"/zap/baz/biff?bam"
,
true
,
NULL
));
cl_assert_equal_s
(
conndata
.
scheme
,
"http"
);
cl_assert_equal_s
(
conndata
.
host
,
"foo.com"
);
cl_assert_equal_s
(
conndata
.
port
,
"80"
);
...
...
@@ -101,9 +116,10 @@ void test_network_url_redirect__redirect_relative(void)
void
test_network_url_redirect__redirect_relative_ssl
(
void
)
{
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"https://foo.com/bar/baz/biff"
));
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"https://foo.com/bar/baz/biff"
));
cl_git_pass
(
git_net_url_apply_redirect
(
&
conndata
,
"/zap/baz/biff?bam"
,
NULL
));
"/zap/baz/biff?bam"
,
true
,
NULL
));
cl_assert_equal_s
(
conndata
.
scheme
,
"https"
);
cl_assert_equal_s
(
conndata
.
host
,
"foo.com"
);
cl_assert_equal_s
(
conndata
.
port
,
"443"
);
...
...
@@ -114,16 +130,18 @@ void test_network_url_redirect__redirect_relative_ssl(void)
void
test_network_url_redirect__service_query_no_query_params_in_location
(
void
)
{
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"https://foo.com/bar/info/refs?service=git-upload-pack"
));
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"https://foo.com/bar/info/refs?service=git-upload-pack"
));
cl_git_pass
(
git_net_url_apply_redirect
(
&
conndata
,
"/baz/info/refs"
,
"/info/refs?service=git-upload-pack"
));
"/baz/info/refs"
,
true
,
"/info/refs?service=git-upload-pack"
));
cl_assert_equal_s
(
conndata
.
path
,
"/baz"
);
}
void
test_network_url_redirect__service_query_with_query_params_in_location
(
void
)
{
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"https://foo.com/bar/info/refs?service=git-upload-pack"
));
cl_git_pass
(
git_net_url_parse
(
&
conndata
,
"https://foo.com/bar/info/refs?service=git-upload-pack"
));
cl_git_pass
(
git_net_url_apply_redirect
(
&
conndata
,
"/baz/info/refs?service=git-upload-pack"
,
"/info/refs?service=git-upload-pack"
));
"/baz/info/refs?service=git-upload-pack"
,
true
,
"/info/refs?service=git-upload-pack"
));
cl_assert_equal_s
(
conndata
.
path
,
"/baz"
);
}
tests/online/clone.c
View file @
616628dd
...
...
@@ -32,6 +32,8 @@ static char *_remote_proxy_user = NULL;
static
char
*
_remote_proxy_pass
=
NULL
;
static
char
*
_remote_proxy_selfsigned
=
NULL
;
static
char
*
_remote_expectcontinue
=
NULL
;
static
char
*
_remote_redirect_initial
=
NULL
;
static
char
*
_remote_redirect_subsequent
=
NULL
;
static
int
_orig_proxies_need_reset
=
0
;
static
char
*
_orig_http_proxy
=
NULL
;
...
...
@@ -78,6 +80,8 @@ void test_online_clone__initialize(void)
_remote_proxy_pass
=
cl_getenv
(
"GITTEST_REMOTE_PROXY_PASS"
);
_remote_proxy_selfsigned
=
cl_getenv
(
"GITTEST_REMOTE_PROXY_SELFSIGNED"
);
_remote_expectcontinue
=
cl_getenv
(
"GITTEST_REMOTE_EXPECTCONTINUE"
);
_remote_redirect_initial
=
cl_getenv
(
"GITTEST_REMOTE_REDIRECT_INITIAL"
);
_remote_redirect_subsequent
=
cl_getenv
(
"GITTEST_REMOTE_REDIRECT_SUBSEQUENT"
);
if
(
_remote_expectcontinue
)
git_libgit2_opts
(
GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE
,
1
);
...
...
@@ -92,6 +96,8 @@ void test_online_clone__cleanup(void)
g_repo
=
NULL
;
}
cl_fixture_cleanup
(
"./foo"
);
cl_fixture_cleanup
(
"./initial"
);
cl_fixture_cleanup
(
"./subsequent"
);
git__free
(
_remote_url
);
git__free
(
_remote_user
);
...
...
@@ -107,6 +113,8 @@ void test_online_clone__cleanup(void)
git__free
(
_remote_proxy_pass
);
git__free
(
_remote_proxy_selfsigned
);
git__free
(
_remote_expectcontinue
);
git__free
(
_remote_redirect_initial
);
git__free
(
_remote_redirect_subsequent
);
if
(
_orig_proxies_need_reset
)
{
cl_setenv
(
"HTTP_PROXY"
,
_orig_http_proxy
);
...
...
@@ -938,3 +946,59 @@ void test_online_clone__path_whitespace(void)
cl_git_pass
(
git_clone
(
&
g_repo
,
"https://libgit2@dev.azure.com/libgit2/test/_git/spaces%20in%20the%20name"
,
"./foo"
,
&
g_options
));
cl_assert
(
git_fs_path_exists
(
"./foo/master.txt"
));
}
void
test_online_clone__redirect_default_succeeds_for_initial
(
void
)
{
git_clone_options
options
=
GIT_CLONE_OPTIONS_INIT
;
if
(
!
_remote_redirect_initial
||
!
_remote_redirect_subsequent
)
cl_skip
();
cl_git_pass
(
git_clone
(
&
g_repo
,
_remote_redirect_initial
,
"./initial"
,
&
options
));
}
void
test_online_clone__redirect_default_fails_for_subsequent
(
void
)
{
git_clone_options
options
=
GIT_CLONE_OPTIONS_INIT
;
if
(
!
_remote_redirect_initial
||
!
_remote_redirect_subsequent
)
cl_skip
();
cl_git_fail
(
git_clone
(
&
g_repo
,
_remote_redirect_subsequent
,
"./fail"
,
&
options
));
}
void
test_online_clone__redirect_none
(
void
)
{
git_clone_options
options
=
GIT_CLONE_OPTIONS_INIT
;
if
(
!
_remote_redirect_initial
)
cl_skip
();
options
.
fetch_opts
.
follow_redirects
=
GIT_REMOTE_REDIRECT_NONE
;
cl_git_fail
(
git_clone
(
&
g_repo
,
_remote_redirect_initial
,
"./fail"
,
&
options
));
}
void
test_online_clone__redirect_initial_succeeds_for_initial
(
void
)
{
git_clone_options
options
=
GIT_CLONE_OPTIONS_INIT
;
if
(
!
_remote_redirect_initial
||
!
_remote_redirect_subsequent
)
cl_skip
();
options
.
fetch_opts
.
follow_redirects
=
GIT_REMOTE_REDIRECT_INITIAL
;
cl_git_pass
(
git_clone
(
&
g_repo
,
_remote_redirect_initial
,
"./initial"
,
&
options
));
}
void
test_online_clone__redirect_initial_fails_for_subsequent
(
void
)
{
git_clone_options
options
=
GIT_CLONE_OPTIONS_INIT
;
if
(
!
_remote_redirect_initial
||
!
_remote_redirect_subsequent
)
cl_skip
();
options
.
fetch_opts
.
follow_redirects
=
GIT_REMOTE_REDIRECT_INITIAL
;
cl_git_fail
(
git_clone
(
&
g_repo
,
_remote_redirect_subsequent
,
"./fail"
,
&
options
));
}
tests/online/fetch.c
View file @
616628dd
...
...
@@ -7,15 +7,19 @@ static char *_remote_proxy_scheme = NULL;
static
char
*
_remote_proxy_host
=
NULL
;
static
char
*
_remote_proxy_user
=
NULL
;
static
char
*
_remote_proxy_pass
=
NULL
;
static
char
*
_remote_redirect_initial
=
NULL
;
static
char
*
_remote_redirect_subsequent
=
NULL
;
void
test_online_fetch__initialize
(
void
)
{
cl_git_pass
(
git_repository_init
(
&
_repo
,
"./fetch"
,
0
));
_remote_proxy_scheme
=
cl_getenv
(
"GITTEST_REMOTE_PROXY_SCHEME"
);
_remote_proxy_host
=
cl_getenv
(
"GITTEST_REMOTE_PROXY_HOST"
);
_remote_proxy_user
=
cl_getenv
(
"GITTEST_REMOTE_PROXY_USER"
);
_remote_proxy_pass
=
cl_getenv
(
"GITTEST_REMOTE_PROXY_PASS"
);
_remote_proxy_scheme
=
cl_getenv
(
"GITTEST_REMOTE_PROXY_SCHEME"
);
_remote_proxy_host
=
cl_getenv
(
"GITTEST_REMOTE_PROXY_HOST"
);
_remote_proxy_user
=
cl_getenv
(
"GITTEST_REMOTE_PROXY_USER"
);
_remote_proxy_pass
=
cl_getenv
(
"GITTEST_REMOTE_PROXY_PASS"
);
_remote_redirect_initial
=
cl_getenv
(
"GITTEST_REMOTE_REDIRECT_INITIAL"
);
_remote_redirect_subsequent
=
cl_getenv
(
"GITTEST_REMOTE_REDIRECT_SUBSEQUENT"
);
}
void
test_online_fetch__cleanup
(
void
)
...
...
@@ -24,11 +28,14 @@ void test_online_fetch__cleanup(void)
_repo
=
NULL
;
cl_fixture_cleanup
(
"./fetch"
);
git__free
(
_remote_proxy_scheme
);
git__free
(
_remote_proxy_host
);
git__free
(
_remote_proxy_user
);
git__free
(
_remote_proxy_pass
);
cl_fixture_cleanup
(
"./redirected"
);
git__free
(
_remote_proxy_scheme
);
git__free
(
_remote_proxy_host
);
git__free
(
_remote_proxy_user
);
git__free
(
_remote_proxy_pass
);
git__free
(
_remote_redirect_initial
);
git__free
(
_remote_redirect_subsequent
);
}
static
int
update_tips
(
const
char
*
refname
,
const
git_oid
*
a
,
const
git_oid
*
b
,
void
*
data
)
...
...
@@ -247,3 +254,44 @@ void test_online_fetch__proxy(void)
git_remote_free
(
remote
);
git_str_dispose
(
&
url
);
}
static
int
do_redirected_fetch
(
const
char
*
url
,
const
char
*
name
,
const
char
*
config
)
{
git_repository
*
repo
;
git_remote
*
remote
;
int
error
;
cl_git_pass
(
git_repository_init
(
&
repo
,
"./redirected"
,
0
));
cl_fixture_cleanup
(
name
);
if
(
config
)
cl_repo_set_string
(
repo
,
"http.followRedirects"
,
config
);
cl_git_pass
(
git_remote_create
(
&
remote
,
repo
,
name
,
url
));
error
=
git_remote_fetch
(
remote
,
NULL
,
NULL
,
NULL
);
git_remote_free
(
remote
);
git_repository_free
(
repo
);
cl_fixture_cleanup
(
"./redirected"
);
return
error
;
}
void
test_online_fetch__redirect_config
(
void
)
{
if
(
!
_remote_redirect_initial
||
!
_remote_redirect_subsequent
)
cl_skip
();
/* config defaults */
cl_git_pass
(
do_redirected_fetch
(
_remote_redirect_initial
,
"initial"
,
NULL
));
cl_git_fail
(
do_redirected_fetch
(
_remote_redirect_subsequent
,
"subsequent"
,
NULL
));
/* redirect=initial */
cl_git_pass
(
do_redirected_fetch
(
_remote_redirect_initial
,
"initial"
,
"initial"
));
cl_git_fail
(
do_redirected_fetch
(
_remote_redirect_subsequent
,
"subsequent"
,
"initial"
));
/* redirect=false */
cl_git_fail
(
do_redirected_fetch
(
_remote_redirect_initial
,
"initial"
,
"false"
));
cl_git_fail
(
do_redirected_fetch
(
_remote_redirect_subsequent
,
"subsequent"
,
"false"
));
}
tests/resources/renames/.gitted/objects/41/a766bb079e18ff6a24571831bd751168799a02
0 → 100644
View file @
616628dd
File added
tests/resources/renames/.gitted/objects/ba/8b004914491b129b4feff51b5fd8553b8e8156
0 → 100644
View file @
616628dd
File added
tests/resources/renames/.gitted/objects/e5/6d39ca6d946331aa79c9c443d46c8a6ed4f550
0 → 100644
View file @
616628dd
File added
tests/resources/renames/.gitted/refs/heads/case-insensitive-status
0 → 100644
View file @
616628dd
41a766bb079e18ff6a24571831bd751168799a02
tests/status/renames.c
View file @
616628dd
...
...
@@ -718,3 +718,127 @@ void test_status_renames__precomposed_unicode_toggle_is_rename(void)
#endif
}
void
test_status_renames__rename_threshold
(
void
)
{
git_index
*
index
;
git_status_list
*
statuslist
;
git_status_options
opts
=
GIT_STATUS_OPTIONS_INIT
;
_rename_helper
(
g_repo
,
"ikeepsix.txt"
,
"newname.txt"
,
"Line 1
\n
"
\
"Line 2
\n
"
\
"Line 3
\n
"
\
"Line 4
\n
"
\
"Line 5
\n
"
\
"Line 6
\n
"
\
"Line 7
\n
"
\
"Line 8
\n
"
\
"Line 9
\n
"
);
opts
.
flags
|=
GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR
;
opts
.
flags
|=
GIT_STATUS_OPT_INCLUDE_UNTRACKED
;
cl_git_pass
(
git_repository_index
(
&
index
,
g_repo
));
/* Default threshold */
{
struct
status_entry
expected
[]
=
{
{
GIT_STATUS_WT_RENAMED
|
GIT_STATUS_WT_MODIFIED
,
"ikeepsix.txt"
,
"newname.txt"
},
};
cl_git_pass
(
git_status_list_new
(
&
statuslist
,
g_repo
,
&
opts
));
check_status
(
statuslist
,
expected
,
1
);
git_status_list_free
(
statuslist
);
}
/* Threshold set to 90 */
{
struct
status_entry
expected
[]
=
{
{
GIT_STATUS_WT_DELETED
,
"ikeepsix.txt"
,
NULL
},
{
GIT_STATUS_WT_NEW
,
"newname.txt"
,
NULL
}
};
opts
.
rename_threshold
=
90
;
cl_git_pass
(
git_status_list_new
(
&
statuslist
,
g_repo
,
&
opts
));
check_status
(
statuslist
,
expected
,
2
);
git_status_list_free
(
statuslist
);
}
/* Threshold set to 25 */
{
struct
status_entry
expected
[]
=
{
{
GIT_STATUS_WT_RENAMED
|
GIT_STATUS_WT_MODIFIED
,
"ikeepsix.txt"
,
"newname.txt"
},
};
opts
.
rename_threshold
=
25
;
cl_git_pass
(
git_status_list_new
(
&
statuslist
,
g_repo
,
&
opts
));
check_status
(
statuslist
,
expected
,
1
);
git_status_list_free
(
statuslist
);
}
git_index_free
(
index
);
}
void
test_status_renames__case_insensitive_h2i_and_i2wc
(
void
)
{
git_status_list
*
statuslist
;
git_status_options
opts
=
GIT_STATUS_OPTIONS_INIT
;
git_reference
*
head
,
*
test_branch
;
git_checkout_options
checkout_opts
=
GIT_CHECKOUT_OPTIONS_INIT
;
git_str
path_to_delete
=
GIT_STR_INIT
;
git_str
path_to_edit
=
GIT_STR_INIT
;
git_index
*
index
;
git_strarray
paths
=
{
NULL
,
0
};
struct
status_entry
expected
[]
=
{
{
GIT_STATUS_INDEX_RENAMED
|
GIT_STATUS_WT_MODIFIED
,
"sixserving.txt"
,
"sixserving-renamed.txt"
},
{
GIT_STATUS_INDEX_DELETED
,
"Wow.txt"
,
"Wow.txt"
}
};
/* Checkout the correct branch */
checkout_opts
.
checkout_strategy
=
GIT_CHECKOUT_FORCE
;
cl_git_pass
(
git_reference_lookup
(
&
head
,
g_repo
,
"HEAD"
));
cl_git_pass
(
git_reference_symbolic_set_target
(
&
test_branch
,
head
,
"refs/heads/case-insensitive-status"
,
NULL
));
cl_git_pass
(
git_checkout_head
(
g_repo
,
&
checkout_opts
));
cl_git_pass
(
git_repository_index
(
&
index
,
g_repo
));
/* Rename sixserving.txt, delete Wow.txt, and stage those changes */
rename_file
(
g_repo
,
"sixserving.txt"
,
"sixserving-renamed.txt"
);
cl_git_pass
(
git_str_joinpath
(
&
path_to_delete
,
git_repository_workdir
(
g_repo
),
"Wow.txt"
));
cl_git_rmfile
(
path_to_delete
.
ptr
);
cl_git_pass
(
git_index_add_all
(
index
,
&
paths
,
GIT_INDEX_ADD_FORCE
,
NULL
,
NULL
));
cl_git_pass
(
git_index_write
(
index
));
/* Change content of sixserving-renamed.txt */
cl_git_pass
(
git_str_joinpath
(
&
path_to_edit
,
git_repository_workdir
(
g_repo
),
"sixserving-renamed.txt"
));
cl_git_append2file
(
path_to_edit
.
ptr
,
"New content
\n
"
);
/* Run status */
opts
.
flags
|=
GIT_STATUS_OPT_INCLUDE_UNTRACKED
;
opts
.
flags
|=
GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR
;
opts
.
flags
|=
GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX
;
opts
.
flags
|=
GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY
;
cl_git_pass
(
git_status_list_new
(
&
statuslist
,
g_repo
,
&
opts
));
check_status
(
statuslist
,
expected
,
2
);
git_status_list_free
(
statuslist
);
git_index_free
(
index
);
git_str_dispose
(
&
path_to_delete
);
git_str_dispose
(
&
path_to_edit
);
git_reference_free
(
head
);
git_reference_free
(
test_branch
);
}
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