Skip to content

Commit 1d4a7f5

Browse files
committed
feat: ability to change the fetch url of a remote
The remote has a couple of "builder" methods to change is fields, e.g. `push_url` for setting the push url. A builder method for changing the fetch url of a remote was missing. This makes it impossible to fully replicate the functionality of `git remote set-url`.
1 parent 81c0c16 commit 1d4a7f5

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

gix/src/remote/build.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,31 @@ use crate::{bstr::BStr, remote, Remote};
22

33
/// Builder methods
44
impl Remote<'_> {
5+
/// Set the `url` to be used when fetching data from a remote.
6+
pub fn with_url<Url, E>(self, url: Url) -> Result<Self, remote::init::Error>
7+
where
8+
Url: TryInto<gix_url::Url, Error = E>,
9+
gix_url::parse::Error: From<E>,
10+
{
11+
self.url_inner(
12+
url.try_into().map_err(|err| remote::init::Error::Url(err.into()))?,
13+
true,
14+
)
15+
}
16+
17+
/// Set the `url` to be used when fetching data from a remote, without applying rewrite rules in case these could be faulty,
18+
/// eliminating one failure mode.
19+
pub fn with_url_without_url_rewrite<Url, E>(self, url: Url) -> Result<Self, remote::init::Error>
20+
where
21+
Url: TryInto<gix_url::Url, Error = E>,
22+
gix_url::parse::Error: From<E>,
23+
{
24+
self.url_inner(
25+
url.try_into().map_err(|err| remote::init::Error::Url(err.into()))?,
26+
false,
27+
)
28+
}
29+
530
/// Set the `url` to be used when pushing data to a remote.
631
pub fn push_url<Url, E>(self, url: Url) -> Result<Self, remote::init::Error>
732
where
@@ -50,6 +75,19 @@ impl Remote<'_> {
5075
Ok(self)
5176
}
5277

78+
fn url_inner(mut self, url: gix_url::Url, should_rewrite_urls: bool) -> Result<Self, remote::init::Error> {
79+
self.url = url.into();
80+
81+
let (fetch_url_alias, _) = if should_rewrite_urls {
82+
remote::init::rewrite_urls(&self.repo.config, self.url.as_ref(), None)
83+
} else {
84+
Ok((None, None))
85+
}?;
86+
self.url_alias = fetch_url_alias;
87+
88+
Ok(self)
89+
}
90+
5391
/// Add `specs` as refspecs for `direction` to our list if they are unique, or ignore them otherwise.
5492
pub fn with_refspecs<Spec>(
5593
mut self,

gix/tests/gix/repository/remote.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ mod remote_at {
2020
);
2121
assert_eq!(remote.url(Direction::Fetch).unwrap().to_bstring(), fetch_url);
2222

23+
let new_fetch_url = "https://host.xz/byron/gitoxide";
24+
remote = remote.with_url(new_fetch_url)?;
25+
assert_eq!(remote.url(Direction::Fetch).unwrap().to_bstring(), new_fetch_url);
26+
2327
for (spec, direction) in [
2428
("refs/heads/push", Direction::Push),
2529
("refs/heads/fetch", Direction::Fetch),
@@ -57,6 +61,18 @@ mod remote_at {
5761
"push is the same as fetch was rewritten"
5862
);
5963

64+
let remote = remote.with_url("https://github.com/foobar/gitoxide")?;
65+
assert_eq!(
66+
remote.url(Direction::Fetch).unwrap().to_bstring(),
67+
rewritten_fetch_url,
68+
"fetch was rewritten"
69+
);
70+
assert_eq!(
71+
remote.url(Direction::Push).unwrap().to_bstring(),
72+
rewritten_fetch_url,
73+
"push is the same as fetch was rewritten"
74+
);
75+
6076
let remote = repo
6177
.remote_at("https://github.com/foobar/gitoxide".to_owned())?
6278
.push_url("file://dev/null".to_owned())?;
@@ -87,6 +103,18 @@ mod remote_at {
87103
"push is the same as fetch was rewritten"
88104
);
89105

106+
let remote = remote.with_url_without_url_rewrite("https://github.com/foobaz/gitoxide")?;
107+
assert_eq!(
108+
remote.url(Direction::Fetch).unwrap().to_bstring(),
109+
"https://github.com/foobaz/gitoxide",
110+
"fetch was rewritten"
111+
);
112+
assert_eq!(
113+
remote.url(Direction::Push).unwrap().to_bstring(),
114+
"https://github.com/foobaz/gitoxide",
115+
"push is the same as fetch was rewritten"
116+
);
117+
90118
let remote = repo
91119
.remote_at_without_url_rewrite("https://github.com/foobar/gitoxide".to_owned())?
92120
.push_url_without_url_rewrite("file://dev/null".to_owned())?;
@@ -96,6 +124,19 @@ mod remote_at {
96124
"file://dev/null",
97125
"push-url rewrite rules are not applied"
98126
);
127+
128+
let remote = remote
129+
.with_url_without_url_rewrite("https://github.com/foobaz/gitoxide".to_owned())?
130+
.push_url_without_url_rewrite("file://dev/null".to_owned())?;
131+
assert_eq!(
132+
remote.url(Direction::Fetch).unwrap().to_bstring(),
133+
"https://github.com/foobaz/gitoxide"
134+
);
135+
assert_eq!(
136+
remote.url(Direction::Push).unwrap().to_bstring(),
137+
"file://dev/null",
138+
"push-url rewrite rules are not applied"
139+
);
99140
Ok(())
100141
}
101142
}

0 commit comments

Comments
 (0)