Skip to content

Commit

Permalink
support for deletion (#450)
Browse files Browse the repository at this point in the history
Even though for now everything is without validation
  • Loading branch information
Byron committed Aug 6, 2022
1 parent 701d46f commit 966a9e9
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 17 deletions.
9 changes: 6 additions & 3 deletions git-refspec/src/parse.rs
Expand Up @@ -36,10 +36,13 @@ pub(crate) mod function {
let src = (!src.is_empty()).then(|| src.as_bstr());
let dst = (!dst.is_empty()).then(|| dst.as_bstr());
match (src, dst) {
(None, None) => {}
(None, None) => (None, None), // match all
(None, Some(dst)) => match operation {
Operation::Push => (None, Some(dst)),
Operation::Fetch => (Some("HEAD".into()), Some(dst)),
},
_ => todo!("src or dst handling"),
};
(src, dst)
}
}
None => todo!("no colon"),
};
Expand Down
17 changes: 16 additions & 1 deletion git-refspec/src/spec.rs
@@ -1,5 +1,5 @@
use crate::types::Push;
use crate::{Instruction, Mode, Operation, RefSpec, RefSpecRef};
use crate::{Fetch, Instruction, Mode, Operation, RefSpec, RefSpecRef};
use bstr::BStr;

/// Access
Expand All @@ -15,14 +15,29 @@ impl RefSpecRef<'_> {
item.contains(&b'*')
}
match (self.op, self.mode, self.src, self.dst) {
(Operation::Fetch, Mode::Normal | Mode::Force, Some(src), Some(dst)) => {
Instruction::Fetch(Fetch::AndUpdateSingle {
src,
dst,
allow_non_fast_forward: matches!(self.mode, Mode::Force),
})
}
(Operation::Push, Mode::Normal | Mode::Force, Some(src), None) => Instruction::Push(Push::Single {
src,
dst: src,
allow_non_fast_forward: matches!(self.mode, Mode::Force),
}),
(Operation::Push, Mode::Normal | Mode::Force, None, Some(dst)) => {
Instruction::Push(Push::Delete { ref_or_pattern: dst })
}
(Operation::Push, Mode::Normal | Mode::Force, None, None) => Instruction::Push(Push::AllMatchingBranches {
allow_non_fast_forward: matches!(self.mode, Mode::Force),
}),
(Operation::Fetch, Mode::Normal | Mode::Force, None, None) => {
Instruction::Fetch(Fetch::AllMatchingBranches {
allow_non_fast_forward: matches!(self.mode, Mode::Force),
})
}
(Operation::Push, Mode::Normal | Mode::Force, Some(src), Some(dst)) if has_pattern(src) => {
Instruction::Push(Push::MultipleWithGlob {
src,
Expand Down
5 changes: 5 additions & 0 deletions git-refspec/src/types.rs
Expand Up @@ -70,6 +70,11 @@ pub enum Push<'a> {

#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)]
pub enum Fetch<'a> {
/// TODO: figure out what this actually does - it's valid for sure and only fetches HEAD -> FETCH_HEAD apparently
AllMatchingBranches {
/// Unclear what this does, but it's allowed
allow_non_fast_forward: bool,
},
Only {
/// The ref name to fetch on the remote side, without updating the local side.
src: &'a BStr,
Expand Down
Git LFS file not shown
6 changes: 6 additions & 0 deletions git-refspec/tests/fixtures/make_baseline.sh
Expand Up @@ -84,6 +84,12 @@ baseline fetch 'HEAD:'
baseline push ':refs/remotes/frotz/deleteme'
baseline fetch ':refs/remotes/frotz/HEAD-to-me'

baseline push ':a'
baseline push '+:a'

baseline fetch ':a'
baseline fetch '+:a'

baseline fetch 'refs/heads/*/for-linus:refs/remotes/mine/*-blah'
baseline push 'refs/heads/*/for-linus:refs/remotes/mine/*-blah'

Expand Down
80 changes: 69 additions & 11 deletions git-refspec/tests/parse/mod.rs
Expand Up @@ -31,7 +31,10 @@ fn baseline() {
match res {
Ok(res) => match (res.is_ok(), err_code == 0) {
(true, true) | (false, false) => {}
_ => mismatch += 1,
_ => {
eprintln!("{res:?} {err_code}");
mismatch += 1;
}
},
Err(_) => {
panics += 1;
Expand All @@ -40,8 +43,11 @@ fn baseline() {
}
if panics != 0 || mismatch != 0 {
panic!(
"Out of {} baseline entries, got {} mismatches and {} panics",
count, mismatch, panics
"Out of {} baseline entries, got {} right, ({} mismatches and {} panics)",
count,
count - (mismatch + panics),
mismatch,
panics
);
}
}
Expand All @@ -68,11 +74,51 @@ mod invalid {
}
}

mod fetch {}
mod fetch {
use crate::parse::{assert_parse, b};
use git_refspec::{Fetch, Instruction};

#[test]
fn empty_lhs_colon_rhs_fetches_head_to_destination() {
assert_parse(
":a",
Instruction::Fetch(Fetch::AndUpdateSingle {
src: b("HEAD"),
dst: b("a"),
allow_non_fast_forward: false,
}),
);

assert_parse(
"+:a",
Instruction::Fetch(Fetch::AndUpdateSingle {
src: b("HEAD"),
dst: b("a"),
allow_non_fast_forward: true,
}),
);
}

#[test]
fn colon_alone_is_for_fetching_into_fetchhead() {
assert_parse(
":",
Instruction::Fetch(Fetch::AllMatchingBranches {
allow_non_fast_forward: false,
}),
);
assert_parse(
"+:",
Instruction::Fetch(Fetch::AllMatchingBranches {
allow_non_fast_forward: true,
}),
);
}
}

mod push {
use crate::parse::assert_parse;
use git_refspec::{Instruction, Push};
use crate::parse::{assert_parse, b};
use git_refspec::{Instruction, Mode, Push};

#[test]
fn colon_alone_is_for_pushing_matching_refs() {
Expand All @@ -89,23 +135,35 @@ mod invalid {
}),
);
}

#[test]
fn delete() {
assert_parse(":a", Instruction::Push(Push::Delete { ref_or_pattern: b("a") }));
let spec = assert_parse("+:a", Instruction::Push(Push::Delete { ref_or_pattern: b("a") }));
assert_eq!(
spec.mode(),
Mode::Force,
"force is set, even though it has no effect in the actual instruction"
);
}
}
}

mod util {
use git_refspec::{Instruction, Operation, RefSpecRef};

// pub fn b(input: &str) -> &bstr::BStr {
// input.into()
// }
pub fn b(input: &str) -> &bstr::BStr {
input.into()
}

pub fn try_parse(spec: &str, op: Operation) -> Result<RefSpecRef<'_>, git_refspec::parse::Error> {
git_refspec::parse(spec.into(), op)
}

pub fn assert_parse(spec: &str, expected: Instruction<'_>) {
pub fn assert_parse<'a>(spec: &'a str, expected: Instruction<'_>) -> RefSpecRef<'a> {
let spec = try_parse(spec, expected.operation()).expect("no error");
assert_eq!(spec.instruction(), expected)
assert_eq!(spec.instruction(), expected);
spec
}
}
pub use util::*;

0 comments on commit 966a9e9

Please sign in to comment.