Skip to content

Commit

Permalink
[ref #139] Allow 'git pack-ref --no-purge' essentially
Browse files Browse the repository at this point in the history
It's surprisingly easy to implement as well, neat.
  • Loading branch information
Byron committed Jul 28, 2021
1 parent e5fbc4c commit c32d8b7
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 6 deletions.
1 change: 1 addition & 0 deletions git-ref/src/store/file/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub struct Transaction<'s> {
store: &'s Store,
packed_transaction: Option<crate::store::packed::Transaction>,
updates: Option<Vec<transaction::Edit>>,
packed_refs: transaction::PackedRefs,
}

pub(in crate::store::file) fn path_to_name(path: impl Into<PathBuf>) -> bstr::BString {
Expand Down
27 changes: 27 additions & 0 deletions git-ref/src/store/file/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ use crate::{
use bstr::BString;
use git_hash::ObjectId;

/// How to handle packed refs during a transaction
#[derive(Debug, Clone, Copy)]
pub enum PackedRefs {
/// Only propagate deletions of references. This is the default
DeletionsOnly,
/// Propagate deletions as well as updates to references which are peeled, that is contain an object id
DeletionsAndNonSymbolicUpdates,
/// Propagate deletions as well as updates to references which are peeled, that is contain an object id. Furthermore delete the
/// reference which is originally updated if it exists. If it doesn't, the new value will be written into the packed ref right away.
DeletionsAndNonSymbolicUpdatesRemoveLooseSourceReference,
}

impl Default for PackedRefs {
fn default() -> Self {
PackedRefs::DeletionsOnly
}
}

#[derive(Debug)]
pub(in crate::store::file) struct Edit {
update: RefEdit,
Expand Down Expand Up @@ -46,10 +64,19 @@ impl file::Store {
store: self,
packed_transaction: None,
updates: None,
packed_refs: PackedRefs::default(),
}
}
}

impl<'s> Transaction<'s> {
/// Configure the way packed refs are handled during the transaction
pub fn packed_refs(mut self, packed_refs: PackedRefs) -> Self {
self.packed_refs = packed_refs;
self
}
}

///
pub mod prepare;

Expand Down
18 changes: 17 additions & 1 deletion git-ref/src/store/file/transaction/prepare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use crate::{
store::{
file,
file::loose,
file::{transaction::Edit, Transaction},
file::{
transaction::{Edit, PackedRefs},
Transaction,
},
},
transaction::{Change, Create, LogChange, RefEdit, RefEditsExt, RefLog},
};
Expand Down Expand Up @@ -215,6 +218,19 @@ impl<'s> Transaction<'s> {
if log_mode == RefLog::Only {
continue;
}
if matches!(
self.packed_refs,
PackedRefs::DeletionsAndNonSymbolicUpdates
| PackedRefs::DeletionsAndNonSymbolicUpdatesRemoveLooseSourceReference
) {
if let Change::Update {
new: Target::Peeled(_), ..
} = edit.update.change
{
edits_for_packed_transaction.push(edit.update.clone());
}
continue;
}
match edit.update.change {
Change::Update {
mode: Create::OrUpdate { previous: None },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use bstr::ByteSlice;
use git_hash::ObjectId;
use git_lock::acquire::Fail;
use git_ref::{
file::{transaction, WriteReflog},
file::{
transaction::{self, PackedRefs},
WriteReflog,
},
mutable::Target,
transaction::{Change, Create, LogChange, RefEdit, RefLog},
};
Expand Down Expand Up @@ -504,7 +507,7 @@ fn packed_refs_are_looked_up_when_checking_existing_values() -> crate::Result {
#[test]
#[ignore]
fn packed_refs_creation_with_packed_refs_mode_prune_removes_original_loose_refs() {
// Also: make sure tags are going to be peeled
// TODO: Also: make sure tags are going to be peeled
todo!("use file::Store::packed_transaction(), figure out how to incorporate this into loose transactions to support purge/purge-delete-original")
}

Expand Down Expand Up @@ -540,15 +543,15 @@ fn packed_refs_creation_with_packed_refs_mode_leave_keeps_original_loose_refs()

let edits = store
.transaction()
// .packed_refs(PackedRefs::Update)
.packed_refs(PackedRefs::DeletionsAndNonSymbolicUpdates)
.prepare(edits, git_lock::acquire::Fail::Immediately)
.unwrap()
.commit(&committer())
.unwrap();
assert_eq!(
edits.len(),
1,
"there really is just one ref that needs updating, symbolic refs are ignored if they don't change the value"
2,
"it claims to have performed all desired operations, even though some don't make it into the pack as 'side-car'"
);

assert_eq!(
Expand Down

0 comments on commit c32d8b7

Please sign in to comment.