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
ac587e75
Commit
ac587e75
authored
May 31, 2015
by
Carlos Martín Nieto
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3048 from pks-t/insteadof
Implementation of url.*.insteadOf
parents
a5670d4f
9e88a823
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
164 additions
and
5 deletions
+164
-5
CHANGELOG.md
+4
-0
include/git2/remote.h
+6
-0
src/remote.c
+70
-5
tests/remote/insteadof.c
+72
-0
tests/resources/testrepo2/.gitted/config
+12
-0
No files found.
CHANGELOG.md
View file @
ac587e75
...
...
@@ -61,6 +61,10 @@ support for HTTPS connections insead of OpenSSL.
`git_off_t`
instead of
`size_t`
for the size of the blob, which
allows putting large files into the odb on 32-bit systems.
*
The remote's push and pull URLs now honor the url.$URL.insteadOf
configuration. This allows modifying URL prefixes to a custom
value via gitconfig.
### API additions
*
The
`git_merge_options`
gained a
`file_flags`
member.
...
...
include/git2/remote.h
View file @
ac587e75
...
...
@@ -120,6 +120,9 @@ GIT_EXTERN(const char *) git_remote_name(const git_remote *remote);
/**
* Get the remote's url
*
* If url.*.insteadOf has been configured for this URL, it will
* return the modified URL.
*
* @param remote the remote
* @return a pointer to the url
*/
...
...
@@ -128,6 +131,9 @@ GIT_EXTERN(const char *) git_remote_url(const git_remote *remote);
/**
* Get the remote's url for pushing
*
* If url.*.pushInsteadOf has been configured for this URL, it
* will return the modified URL.
*
* @param remote the remote
* @return a pointer to the url or NULL if no special url for pushing is set
*/
...
...
src/remote.c
View file @
ac587e75
...
...
@@ -28,6 +28,7 @@
static
int
dwim_refspecs
(
git_vector
*
out
,
git_vector
*
refspecs
,
git_vector
*
refs
);
static
int
lookup_remote_prune_config
(
git_remote
*
remote
,
git_config
*
config
,
const
char
*
name
);
char
*
apply_insteadof
(
git_config
*
config
,
const
char
*
url
,
int
direction
);
static
int
add_refspec_to
(
git_vector
*
vector
,
const
char
*
string
,
bool
is_fetch
)
{
...
...
@@ -207,7 +208,7 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
canonicalize_url
(
&
canonical_url
,
url
)
<
0
)
goto
on_error
;
remote
->
url
=
git_buf_detach
(
&
canonical_url
);
remote
->
url
=
apply_insteadof
(
repo
->
_config
,
canonical_url
.
ptr
,
GIT_DIRECTION_FETCH
);
if
(
name
!=
NULL
)
{
remote
->
name
=
git__strdup
(
name
);
...
...
@@ -216,7 +217,7 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
if
((
error
=
git_buf_printf
(
&
var
,
CONFIG_URL_FMT
,
name
))
<
0
)
goto
on_error
;
if
((
error
=
git_config_set_string
(
config
,
var
.
ptr
,
remote
->
url
))
<
0
)
if
((
error
=
git_config_set_string
(
config
,
var
.
ptr
,
canonical_url
.
ptr
))
<
0
)
goto
on_error
;
}
...
...
@@ -341,7 +342,7 @@ int git_remote_dup(git_remote **dest, git_remote *source)
if
(
source
->
url
!=
NULL
)
{
remote
->
url
=
git__strdup
(
source
->
url
);
GITERR_CHECK_ALLOC
(
remote
->
url
);
GITERR_CHECK_ALLOC
(
remote
->
url
);
}
if
(
source
->
pushurl
!=
NULL
)
{
...
...
@@ -456,7 +457,7 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name)
remote
->
download_tags
=
GIT_REMOTE_DOWNLOAD_TAGS_AUTO
;
if
(
found
&&
strlen
(
val
)
>
0
)
{
remote
->
url
=
git__strdup
(
val
);
remote
->
url
=
apply_insteadof
(
config
,
val
,
GIT_DIRECTION_FETCH
);
GITERR_CHECK_ALLOC
(
remote
->
url
);
}
...
...
@@ -476,7 +477,7 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name)
}
if
(
found
&&
strlen
(
val
)
>
0
)
{
remote
->
pushurl
=
git__strdup
(
val
);
remote
->
pushurl
=
apply_insteadof
(
config
,
val
,
GIT_DIRECTION_PUSH
);
GITERR_CHECK_ALLOC
(
remote
->
pushurl
);
}
...
...
@@ -2421,3 +2422,67 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_
git_remote_disconnect
(
remote
);
return
error
;
}
#define PREFIX "url"
#define SUFFIX_FETCH "insteadof"
#define SUFFIX_PUSH "pushinsteadof"
char
*
apply_insteadof
(
git_config
*
config
,
const
char
*
url
,
int
direction
)
{
size_t
match_length
,
prefix_length
,
suffix_length
;
char
*
replacement
=
NULL
;
const
char
*
regexp
;
git_buf
result
=
GIT_BUF_INIT
;
git_config_entry
*
entry
;
git_config_iterator
*
iter
;
assert
(
config
);
assert
(
url
);
assert
(
direction
==
GIT_DIRECTION_FETCH
||
direction
==
GIT_DIRECTION_PUSH
);
/* Add 1 to prefix/suffix length due to the additional escaped dot */
prefix_length
=
strlen
(
PREFIX
)
+
1
;
if
(
direction
==
GIT_DIRECTION_FETCH
)
{
regexp
=
PREFIX
"
\\
..*
\\
."
SUFFIX_FETCH
;
suffix_length
=
strlen
(
SUFFIX_FETCH
)
+
1
;
}
else
{
regexp
=
PREFIX
"
\\
..*
\\
."
SUFFIX_PUSH
;
suffix_length
=
strlen
(
SUFFIX_PUSH
)
+
1
;
}
git_config_iterator_glob_new
(
&
iter
,
config
,
regexp
);
match_length
=
0
;
while
(
git_config_next
(
&
entry
,
iter
)
==
0
)
{
size_t
n
,
replacement_length
;
/* Check if entry value is a prefix of URL */
if
(
git__prefixcmp
(
url
,
entry
->
value
))
continue
;
/* Check if entry value is longer than previous
* prefixes */
if
((
n
=
strlen
(
entry
->
value
))
<=
match_length
)
continue
;
git__free
(
replacement
);
match_length
=
n
;
/* Cut off prefix and suffix of the value */
replacement_length
=
strlen
(
entry
->
name
)
-
(
prefix_length
+
suffix_length
);
replacement
=
git__strndup
(
entry
->
name
+
prefix_length
,
replacement_length
);
}
git_config_iterator_free
(
iter
);
if
(
match_length
==
0
)
return
git__strdup
(
url
);
git_buf_printf
(
&
result
,
"%s%s"
,
replacement
,
url
+
match_length
);
git__free
(
replacement
);
return
result
.
ptr
;
}
tests/remote/insteadof.c
0 → 100644
View file @
ac587e75
#include "clar_libgit2.h"
#include "remote.h"
#include "repository.h"
#define REPO_PATH "testrepo2/.gitted"
#define REMOTE_ORIGIN "origin"
#define REMOTE_INSTEADOF "insteadof-test"
static
git_repository
*
g_repo
;
static
git_remote
*
g_remote
;
void
test_remote_insteadof__initialize
(
void
)
{
g_repo
=
NULL
;
g_remote
=
NULL
;
}
void
test_remote_insteadof__cleanup
(
void
)
{
git_repository_free
(
g_repo
);
git_remote_free
(
g_remote
);
}
void
test_remote_insteadof__url_insteadof_not_applicable
(
void
)
{
cl_git_pass
(
git_repository_open
(
&
g_repo
,
cl_fixture
(
REPO_PATH
)));
cl_git_pass
(
git_remote_lookup
(
&
g_remote
,
g_repo
,
REMOTE_ORIGIN
));
cl_assert_equal_s
(
git_remote_url
(
g_remote
),
"https://github.com/libgit2/false.git"
);
}
void
test_remote_insteadof__url_insteadof_applicable
(
void
)
{
cl_git_pass
(
git_repository_open
(
&
g_repo
,
cl_fixture
(
REPO_PATH
)));
cl_git_pass
(
git_remote_lookup
(
&
g_remote
,
g_repo
,
REMOTE_INSTEADOF
));
cl_assert_equal_s
(
git_remote_url
(
g_remote
),
"http://github.com/libgit2/libgit2"
);
}
void
test_remote_insteadof__pushurl_insteadof_not_applicable
(
void
)
{
cl_git_pass
(
git_repository_open
(
&
g_repo
,
cl_fixture
(
REPO_PATH
)));
cl_git_pass
(
git_remote_lookup
(
&
g_remote
,
g_repo
,
REMOTE_ORIGIN
));
cl_assert_equal_p
(
git_remote_pushurl
(
g_remote
),
NULL
);
}
void
test_remote_insteadof__pushurl_insteadof_applicable
(
void
)
{
cl_git_pass
(
git_repository_open
(
&
g_repo
,
cl_fixture
(
REPO_PATH
)));
cl_git_pass
(
git_remote_lookup
(
&
g_remote
,
g_repo
,
REMOTE_INSTEADOF
));
cl_assert_equal_s
(
git_remote_pushurl
(
g_remote
),
"git@github.com:libgit2/libgit2"
);
}
void
test_remote_insteadof__anonymous_remote
(
void
)
{
cl_git_pass
(
git_repository_open
(
&
g_repo
,
cl_fixture
(
REPO_PATH
)));
cl_git_pass
(
git_remote_create_anonymous
(
&
g_remote
,
g_repo
,
"http://example.com/libgit2/libgit2"
));
cl_assert_equal_s
(
git_remote_url
(
g_remote
),
"http://github.com/libgit2/libgit2"
);
cl_assert_equal_p
(
git_remote_pushurl
(
g_remote
),
NULL
);
}
tests/resources/testrepo2/.gitted/config
View file @
ac587e75
...
...
@@ -8,7 +8,19 @@
[remote "origin"]
url = https://github.com/libgit2/false.git
fetch = +refs/heads/*:refs/remotes/origin/*
[remote "insteadof-test"]
url = http://example.com/libgit2/libgit2
pushurl = http://github.com/libgit2/libgit2
fetch = +refs/heads/*:refs/remotes/test/*
[branch "master"]
remote = origin
merge = refs/heads/master
rebase = true
[url "longer-non-prefix-match"]
insteadOf = ttp://example.com/li
[url "shorter-prefix"]
insteadOf = http://example.co
[url "http://github.com"]
insteadOf = http://example.com
[url "git@github.com:"]
pushInsteadOf = http://github.com/
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