git-storage: return previous targets

The Updated values only tell the updated value of the target. It can
be useful to also return the previous value, e.g. for reporting,
hooks, etc.

Add `Option<Oid>` to the Update::Direct and Update::Symbolic variants.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
This commit is contained in:
Fintan Halpenny
2022-09-27 12:32:20 +01:00
parent e6f36318cd
commit 5898c0ffde
2 changed files with 28 additions and 10 deletions
+24 -9
View File
@@ -290,10 +290,14 @@ impl<'a, S> Transaction<'a, S> {
previous,
reflog,
})),
Policy::Allow => Ok(Either::Right(self.direct_edit(&name, target, &reflog)?)),
Policy::Allow => Ok(Either::Right(
self.direct_edit(&name, target, given, &reflog)?,
)),
},
// It was an fast-forward so we go ahead and make the edit
None => Ok(Either::Right(self.direct_edit(&name, target, &reflog)?)),
None => Ok(Either::Right(
self.direct_edit(&name, target, given, &reflog)?,
)),
}
}
@@ -314,7 +318,7 @@ impl<'a, S> Transaction<'a, S> {
/// a. if it's direct then make the edit depending on the fast-forward
/// status.
/// b. if it's symbolic then this is an error.
pub fn symbolic<'b>(
pub fn symbolic<'b: 'a>(
&mut self,
name: Qualified<'b>,
target: SymrefTarget<'b>,
@@ -323,6 +327,10 @@ impl<'a, S> Transaction<'a, S> {
reflog: String,
) -> Result<Either<Update<'b>, Vec<Updated>>, error::Update> {
let src = self.refdb.find_reference(&name)?;
let prev = src
.as_ref()
.map(|src| refdb::resolve(self.refdb.as_raw(), src))
.transpose()?;
match src {
Some(src) => match src.target {
Target::Direct { .. } if matches!(type_change, Policy::Abort) => {
@@ -345,19 +353,19 @@ impl<'a, S> Transaction<'a, S> {
let is_ff = target.target != dst
&& self.is_ff(&target.name, target.target, dst)?;
Ok(Either::Right(
self.symbolic_edit(name, target, &reflog, is_ff)?,
self.symbolic_edit(name, target, prev, &reflog, is_ff)?,
))
},
Target::Symbolic { .. } => Err(error::Update::TargetSymbolic(dst.name)),
},
None => Ok(Either::Right(
self.symbolic_edit(name, target, &reflog, true)?,
self.symbolic_edit(name, target, prev, &reflog, true)?,
)),
}
},
},
None => Ok(Either::Right(
self.symbolic_edit(name, target, &reflog, true)?,
self.symbolic_edit(name, target, prev, &reflog, true)?,
)),
}
}
@@ -422,6 +430,7 @@ impl<'a, S> Transaction<'a, S> {
&mut self,
reference: R,
target: Oid,
prev: Option<Oid>,
reflog: &str,
) -> Result<Updated, error::Transaction>
where
@@ -448,13 +457,15 @@ impl<'a, S> Transaction<'a, S> {
Ok(Updated::Direct {
name: reference.to_owned(),
target,
previous: prev,
})
}
pub fn symbolic_edit<R>(
&mut self,
reference: R,
target: SymrefTarget,
target: SymrefTarget<'a>,
prev: Option<Oid>,
reflog: &str,
is_ff: bool,
) -> Result<Vec<Updated>, error::Transaction>
@@ -465,7 +476,10 @@ impl<'a, S> Transaction<'a, S> {
self.lock(reference)?;
self.lock(&target.name)?;
let SymrefTarget { name: dst, target } = target;
let SymrefTarget {
name: dst,
target: dst_target,
} = target;
let mut edits = Vec::with_capacity(2);
let info = self.refdb.info();
@@ -477,7 +491,7 @@ impl<'a, S> Transaction<'a, S> {
source: err,
})?;
if is_ff {
let direct = self.direct_edit(&dst, target, reflog)?;
let direct = self.direct_edit(&dst, dst_target, prev, reflog)?;
edits.push(direct);
}
@@ -491,6 +505,7 @@ impl<'a, S> Transaction<'a, S> {
edits.push(Updated::Symbolic {
name: reference.to_owned(),
target: dst.into(),
previous: prev,
});
Ok(edits)
}
+4 -1
View File
@@ -99,7 +99,6 @@ pub struct SymrefTarget<'a> {
pub target: Oid,
}
// TODO: include the previous values
/// The successful result of an [`Update`] applied to the refdb.
#[derive(Debug, Clone)]
pub enum Updated {
@@ -109,6 +108,8 @@ pub enum Updated {
name: RefString,
/// The new `target` of the reference that was updated.
target: Oid,
/// The previous target of the reference, if it existed.
previous: Option<Oid>,
},
/// The [`Update::Symbolic`] was succesful.
Symbolic {
@@ -116,6 +117,8 @@ pub enum Updated {
name: RefString,
/// The new `target` of the reference that was updated.
target: RefString,
/// The previous peeled target of the reference, if it existed.
previous: Option<Oid>,
},
/// The [`Update::Remove`] was succesful.
Removed {