Skip to content

Commit 8ac2dcc

Browse files
committed
feat: add push.default config key
1 parent 3e13152 commit 8ac2dcc

File tree

6 files changed

+124
-2
lines changed

6 files changed

+124
-2
lines changed

gix/src/config/tree/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ pub(crate) mod root {
5151
pub const PACK: sections::Pack = sections::Pack;
5252
/// The `protocol` section.
5353
pub const PROTOCOL: sections::Protocol = sections::Protocol;
54+
/// The `push` section.
55+
pub const PUSH: sections::Push = sections::Push;
5456
/// The `remote` section.
5557
pub const REMOTE: sections::Remote = sections::Remote;
5658
/// The `safe` section.
@@ -83,6 +85,7 @@ pub(crate) mod root {
8385
&Self::MAILMAP,
8486
&Self::PACK,
8587
&Self::PROTOCOL,
88+
&Self::PUSH,
8689
&Self::REMOTE,
8790
&Self::SAFE,
8891
&Self::SSH,
@@ -95,9 +98,9 @@ pub(crate) mod root {
9598

9699
mod sections;
97100
pub use sections::{
98-
branch, checkout, core, credential, extensions, fetch, gitoxide, http, index, protocol, remote, ssh, Author,
101+
branch, checkout, core, credential, extensions, fetch, gitoxide, http, index, protocol, push, remote, ssh, Author,
99102
Branch, Checkout, Clone, Committer, Core, Credential, Extensions, Fetch, Gitoxide, Http, Index, Init, Mailmap,
100-
Pack, Protocol, Remote, Safe, Ssh, Url, User,
103+
Pack, Protocol, Push, Remote, Safe, Ssh, Url, User,
101104
};
102105
#[cfg(feature = "blob-diff")]
103106
pub use sections::{diff, Diff};

gix/src/config/tree/sections/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ pub mod pack;
8686
pub struct Protocol;
8787
pub mod protocol;
8888

89+
/// The `push` top-level section.
90+
#[derive(Copy, Clone, Default)]
91+
pub struct Push;
92+
pub mod push;
93+
8994
/// The `remote` top-level section.
9095
#[derive(Copy, Clone, Default)]
9196
pub struct Remote;

gix/src/config/tree/sections/push.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use crate::{
2+
config,
3+
config::tree::{keys, Key, Push, Section},
4+
};
5+
6+
impl Push {
7+
/// The `push.default` key
8+
pub const DEFAULT: Default = Default::new_with_validate("default", &config::Tree::PUSH, validate::Default);
9+
}
10+
11+
impl Section for Push {
12+
fn name(&self) -> &str {
13+
"push"
14+
}
15+
16+
fn keys(&self) -> &[&dyn Key] {
17+
&[&Self::DEFAULT]
18+
}
19+
}
20+
21+
/// The `remote.<name>.tagOpt` key type.
22+
pub type Default = keys::Any<validate::Default>;
23+
24+
mod default {
25+
use std::borrow::Cow;
26+
27+
use crate::{
28+
bstr::{BStr, ByteSlice},
29+
config,
30+
config::tree::push::Default,
31+
push,
32+
};
33+
34+
impl Default {
35+
/// Try to interpret `value` as `push.default`.
36+
pub fn try_into_default(
37+
&'static self,
38+
value: Cow<'_, BStr>,
39+
) -> Result<push::Default, config::key::GenericErrorWithValue> {
40+
Ok(match value.as_ref().as_bytes() {
41+
b"nothing" => push::Default::Nothing,
42+
b"current" => push::Default::Current,
43+
b"upstream" | b"tracking" => push::Default::Upstream,
44+
b"simple" => push::Default::Simple,
45+
b"matching" => push::Default::Matching,
46+
_ => return Err(config::key::GenericErrorWithValue::from_value(self, value.into_owned())),
47+
})
48+
}
49+
}
50+
}
51+
52+
mod validate {
53+
pub struct Default;
54+
use std::{borrow::Cow, error::Error};
55+
56+
use crate::{bstr::BStr, config::tree::keys::Validate};
57+
58+
impl Validate for Default {
59+
fn validate(&self, value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
60+
super::Push::DEFAULT.try_into_default(Cow::Borrowed(value))?;
61+
Ok(())
62+
}
63+
}
64+
}

gix/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ pub mod tag;
187187

188188
///
189189
pub mod progress;
190+
///
191+
pub mod push;
190192

191193
///
192194
pub mod diff;

gix/src/push.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/// All possible values of `push.default`.
2+
#[derive(Default, Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash, Debug)]
3+
pub enum Default {
4+
/// Do not push anything unless a refspec is provided explicitly.
5+
///
6+
/// This is for safety.
7+
Nothing,
8+
/// Push the current branch to update a remote branch with the same name.
9+
Current,
10+
/// Push the current branch to the branch it would fetch from and merge with,
11+
/// i.e. what is configured in `branch.<name>.merge`, retrievable with
12+
/// the `@{upstream}` refspec.
13+
Upstream,
14+
/// Push the current branch with the same name to the remote.
15+
/// This is the same as [`Current`](Default::Current), but fails if
16+
/// `branch.<name>.merge` is set to a branch that is named differently.
17+
#[default]
18+
Simple,
19+
/// Push *all* branches to their similarly named counterpart on the remote.
20+
Matching,
21+
}

gix/tests/config/tree.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,33 @@ mod ssh {
145145
}
146146
}
147147

148+
mod push {
149+
use crate::config::tree::bcow;
150+
use gix::config::tree::Push;
151+
use gix::push;
152+
153+
#[test]
154+
fn default() -> crate::Result {
155+
for (actual, expected) in [
156+
("nothing", push::Default::Nothing),
157+
("current", push::Default::Current),
158+
("upstream", push::Default::Upstream),
159+
("tracking", push::Default::Upstream),
160+
("simple", push::Default::Simple),
161+
("matching", push::Default::Matching),
162+
] {
163+
assert_eq!(Push::DEFAULT.try_into_default(bcow(actual))?, expected);
164+
}
165+
166+
assert_eq!(
167+
Push::DEFAULT.try_into_default(bcow("Nothing")).unwrap_err().to_string(),
168+
"The key \"push.default=Nothing\" was invalid",
169+
"case-sensitive comparisons"
170+
);
171+
Ok(())
172+
}
173+
}
174+
148175
mod fetch {
149176

150177
#[test]

0 commit comments

Comments
 (0)