From f861282a2e5aeda0934219635d8f87ca3840a813 Mon Sep 17 00:00:00 2001 From: Christian Schilling Date: Wed, 29 Oct 2025 00:44:06 +0100 Subject: [PATCH] Improve support for sparse cache. With the addition of a notes backed cache we will have the possibility of avoiding a "cold start" by transferring just the notes to another repo. To keep the amount of extra data small the notes cache is kept sparse: Not all commits have and entry and also in shards by sequence number, as old entries are unlikely to be relevant. The old traversal logic did not perform very well with sparse cache. Especially "find_known" proved to be a bottleneck. So the traversal is revised now to work better in the sparse cache case. Change: cache-sparse-shards --- josh-core/src/cache.rs | 106 ++++++++++++++++-- josh-core/src/cache_notes.rs | 67 ++++++++--- josh-core/src/cache_sled.rs | 15 ++- josh-core/src/cache_stack.rs | 18 +-- josh-core/src/filter/mod.rs | 46 ++------ josh-core/src/history.rs | 68 ++++------- tests/experimental/indexer.t | 1 + tests/filter/ambiguous_merge.t | 3 + tests/filter/cmdline.t | 11 +- tests/filter/commit_message_raw.t | 1 + tests/filter/compose_shadow_dir_same_name.t | 1 + tests/filter/deleted_dir.t | 2 + tests/filter/empty_head.t | 3 + tests/filter/empty_orphan.t | 4 + tests/filter/empty_reimport.t | 2 + tests/filter/exclude_compose.t | 3 + tests/filter/file.t | 8 +- tests/filter/gpgsig.t | 2 + tests/filter/hide_view.t | 3 + tests/filter/hook_notes.t | 1 + tests/filter/infofile.t | 4 + tests/filter/join.t | 1 + tests/filter/linear.t | 6 +- tests/filter/moved_dir.t | 3 + tests/filter/prefix.t | 1 + tests/filter/prune_trivial_merge.t | 2 + tests/filter/rev.t | 13 ++- tests/filter/reverse_hide.t | 3 + tests/filter/reverse_hide_edit.t | 2 + .../filter/reverse_hide_edit_missing_change.t | 2 + tests/filter/reverse_merge.t | 3 + tests/filter/reverse_split.t | 2 + tests/filter/roundtrip_custom_header.t | 2 + tests/filter/squash.t | 5 + tests/filter/squash_empty_initial.t | 2 + tests/filter/submodule.t | 2 + tests/filter/subtree_prefix.t | 6 + tests/filter/workspace_combine_filter.t | 2 + tests/filter/workspace_discover.t | 2 + tests/filter/workspace_exclude.t | 2 + tests/filter/workspace_implicit_filter.t | 1 + tests/filter/workspace_modify_chain.t | 2 + tests/filter/workspace_multiple_globs.t | 1 + tests/filter/workspace_redirect.t | 5 +- tests/filter/workspace_single_file.t | 2 + tests/filter/workspace_trailing_slash.t | 2 + tests/filter/workspace_unique.t | 1 + 47 files changed, 325 insertions(+), 119 deletions(-) diff --git a/josh-core/src/cache.rs b/josh-core/src/cache.rs index 77e4aaf19..e2262fb2e 100644 --- a/josh-core/src/cache.rs +++ b/josh-core/src/cache.rs @@ -9,9 +9,20 @@ use std::sync::{LazyLock, RwLock}; pub(crate) const CACHE_VERSION: u64 = 24; pub trait CacheBackend: Send + Sync { - fn read(&self, filter: filter::Filter, from: git2::Oid) -> JoshResult>; - - fn write(&self, filter: filter::Filter, from: git2::Oid, to: git2::Oid) -> JoshResult<()>; + fn read( + &self, + filter: filter::Filter, + from: git2::Oid, + sequence_number: u128, + ) -> JoshResult>; + + fn write( + &self, + filter: filter::Filter, + from: git2::Oid, + to: git2::Oid, + sequence_number: u128, + ) -> JoshResult<()>; } pub trait FilterHook { @@ -323,6 +334,11 @@ impl Transaction { } pub fn insert(&self, filter: filter::Filter, from: git2::Oid, to: git2::Oid, store: bool) { + let sequence_number = if filter != filter::sequence_number() { + compute_sequence_number(self, from).expect("compute_sequence_number failed") + } else { + 0 + }; let mut t2 = self.t2.borrow_mut(); t2.commit_map .entry(filter.id()) @@ -334,14 +350,13 @@ impl Transaction { // the history length by a very large factor. if store || from.as_bytes()[0] == 0 { t2.cache - .write_all(filter, from, to) + .write_all(filter, from, to, sequence_number) .expect("Failed to write cache"); } } pub fn get_missing(&self) -> Vec<(filter::Filter, git2::Oid)> { let mut missing = self.t2.borrow().missing.clone(); - missing.sort_by_key(|(f, i)| (filter::nesting(*f), *f, *i)); missing.dedup(); missing.retain(|(f, i)| !self.known(*f, *i)); self.t2.borrow_mut().missing = missing.clone(); @@ -358,7 +373,9 @@ impl Transaction { } else { let mut t2 = self.t2.borrow_mut(); t2.misses += 1; - t2.missing.push((filter, from)); + if !t2.missing.contains(&(filter, from)) { + t2.missing.insert(0, (filter, from)); + } None } } @@ -367,6 +384,11 @@ impl Transaction { if filter == filter::nop() { return Some(from); } + let sequence_number = if filter != filter::sequence_number() { + compute_sequence_number(self, from).expect("compute_sequence_number failed") + } else { + 0 + }; let t2 = self.t2.borrow_mut(); if let Some(m) = t2.commit_map.get(&filter.id()) { if let Some(oid) = m.get(&from).cloned() { @@ -376,7 +398,7 @@ impl Transaction { let oid = t2 .cache - .read_propagate(filter, from) + .read_propagate(filter, from, sequence_number) .expect("Failed to read from cache backend"); let oid = if let Some(oid) = oid { Some(oid) } else { None }; @@ -385,6 +407,9 @@ impl Transaction { if oid == git2::Oid::zero() { return Some(oid); } + if filter == filter::sequence_number() { + return Some(oid); + } if self.repo.odb().unwrap().exists(oid) { // Only report an object as cached if it exists in the object database. @@ -396,3 +421,70 @@ impl Transaction { None } } + +/// Encode a `u128` into a 20-byte git OID (SHA-1 sized). +/// The high 4 bytes of the OID are zero; the low 16 bytes +/// contain the big-endian integer. +pub fn oid_from_u128(n: u128) -> git2::Oid { + let mut bytes = [0u8; 20]; + // place the 16 integer bytes at the end (big-endian) + bytes[20 - 16..].copy_from_slice(&n.to_be_bytes()); + // Safe: length is exactly 20 + git2::Oid::from_bytes(&bytes).expect("20-byte OID construction cannot fail") +} + +/// Decode a `u128` previously encoded by `oid_from_u128`. +pub fn u128_from_oid(oid: git2::Oid) -> u128 { + let b = oid.as_bytes(); + let mut n = [0u8; 16]; + n.copy_from_slice(&b[20 - 16..]); // take the last 16 bytes + u128::from_be_bytes(n) +} + +pub fn compute_sequence_number( + transaction: &cache::Transaction, + input: git2::Oid, +) -> JoshResult { + if let Some(count) = transaction.get(filter::sequence_number(), input) { + return Ok(u128_from_oid(count)); + } + + let commit = transaction.repo().find_commit(input)?; + if let Some(p) = commit.parent_ids().next() { + if let Some(count) = transaction.get(filter::sequence_number(), p) { + let pc = u128_from_oid(count); + transaction.insert( + filter::sequence_number(), + input, + oid_from_u128(pc + 1), + true, + ); + return Ok(pc + 1); + } + } + + let mut walk = transaction.repo().revwalk()?; + walk.set_sorting(git2::Sort::REVERSE | git2::Sort::TOPOLOGICAL)?; + walk.push(input)?; + + for c in walk { + let commit = transaction.repo().find_commit(c?)?; + let pc = if let Some(p) = commit.parent_ids().next() { + compute_sequence_number(transaction, p)? + } else { + 0 + }; + + transaction.insert( + filter::sequence_number(), + commit.id(), + oid_from_u128(pc + 1), + true, + ); + } + if let Some(count) = transaction.get(filter::sequence_number(), input) { + Ok(u128_from_oid(count)) + } else { + Err(josh_error("missing sequence_number")) + } +} diff --git a/josh-core/src/cache_notes.rs b/josh-core/src/cache_notes.rs index 1096000ae..b2c6abf2c 100644 --- a/josh-core/src/cache_notes.rs +++ b/josh-core/src/cache_notes.rs @@ -1,5 +1,6 @@ use crate::JoshResult; use crate::cache::{CACHE_VERSION, CacheBackend}; +use crate::filter; use crate::filter::Filter; pub struct NotesCacheBackend { @@ -15,24 +16,53 @@ impl NotesCacheBackend { } } -fn is_note_eligible(oid: git2::Oid) -> bool { - oid.as_bytes()[0] == 0 +// The notes cache is meant to be sparse. That is, not all entries are actually persisted. +// This makes it smaller and faster to download. +// It is expected that on any node (server, proxy, local repo) a full "dense" local cache +// is used in addition to the sparse note cache. +// The note cache is mostly only used for initial "cold starts" or longer "catch up". +// For incremental filtering it's fine re-filter commits and rely on the local "dense" cache. +// We store entries for 1% of all commits, and additionally all merges and orphans. +fn is_note_eligible(repo: &git2::Repository, oid: git2::Oid, sequence_number: u128) -> bool { + let parent_count = if let Ok(c) = repo.find_commit(oid) { + c.parent_ids().count() + } else { + return false; + }; + + sequence_number % 100 == 0 || parent_count != 1 } -fn note_path(key: git2::Oid) -> String { - format!("refs/josh/{}/{}", CACHE_VERSION, key) +// To additionally limit the size of the note trees the cache is also sharded by sequence +// number in groups of 10000. Note that this does not limit the number of entried per bucket +// as branches mean many commits share the same sequence number. +fn note_path(key: git2::Oid, sequence_number: u128) -> String { + format!( + "refs/josh/{}/{}/{}", + CACHE_VERSION, + sequence_number / 10000, + key, + ) } impl CacheBackend for NotesCacheBackend { - fn read(&self, filter: Filter, from: git2::Oid) -> JoshResult> { + fn read( + &self, + filter: Filter, + from: git2::Oid, + sequence_number: u128, + ) -> JoshResult> { + if filter == filter::sequence_number() { + return Ok(None); + } let repo = self.repo.lock()?; - let key = crate::filter::as_tree(&repo, filter)?; - - if !is_note_eligible(from) { + if !is_note_eligible(&repo, from, sequence_number) { return Ok(None); } - if let Ok(note) = repo.find_note(Some(¬e_path(key)), from) { + let key = crate::filter::as_tree(&*repo, filter)?; + + if let Ok(note) = repo.find_note(Some(¬e_path(key, sequence_number)), from) { let message = note.message().unwrap_or(""); let result = git2::Oid::from_str(message)?; @@ -42,20 +72,29 @@ impl CacheBackend for NotesCacheBackend { } } - fn write(&self, filter: Filter, from: git2::Oid, to: git2::Oid) -> JoshResult<()> { - let repo = self.repo.lock()?; - let key = crate::filter::as_tree(&repo, filter)?; + fn write( + &self, + filter: Filter, + from: git2::Oid, + to: git2::Oid, + sequence_number: u128, + ) -> JoshResult<()> { + if filter == filter::sequence_number() { + return Ok(()); + } - if !is_note_eligible(from) { + let repo = self.repo.lock()?; + if !is_note_eligible(&*repo, from, sequence_number) { return Ok(()); } + let key = crate::filter::as_tree(&*repo, filter)?; let signature = crate::cache::josh_commit_signature()?; repo.note( &signature, &signature, - Some(¬e_path(key)), + Some(¬e_path(key, sequence_number)), from, &to.to_string(), true, diff --git a/josh-core/src/cache_sled.rs b/josh-core/src/cache_sled.rs index d7bd595a6..9ea94e352 100644 --- a/josh-core/src/cache_sled.rs +++ b/josh-core/src/cache_sled.rs @@ -80,7 +80,12 @@ fn insert_sled_tree(filter: Filter) -> sled::Tree { } impl CacheBackend for SledCacheBackend { - fn read(&self, filter: Filter, from: git2::Oid) -> JoshResult> { + fn read( + &self, + filter: Filter, + from: git2::Oid, + _sequence_number: u128, + ) -> JoshResult> { let mut trees = self.trees.lock()?; let tree = trees .entry(filter.id()) @@ -94,7 +99,13 @@ impl CacheBackend for SledCacheBackend { } } - fn write(&self, filter: Filter, from: git2::Oid, to: git2::Oid) -> JoshResult<()> { + fn write( + &self, + filter: Filter, + from: git2::Oid, + to: git2::Oid, + _sequence_number: u128, + ) -> JoshResult<()> { let mut trees = self.trees.lock()?; let tree = trees .entry(filter.id()) diff --git a/josh-core/src/cache_stack.rs b/josh-core/src/cache_stack.rs index 8b71b4382..613fbe97a 100644 --- a/josh-core/src/cache_stack.rs +++ b/josh-core/src/cache_stack.rs @@ -33,9 +33,10 @@ impl CacheStack { filter: filter::Filter, from: git2::Oid, to: git2::Oid, + sequence_number: u128, ) -> JoshResult<()> { for backend in &self.backends { - backend.write(filter, from, to)?; + backend.write(filter, from, to, sequence_number)?; } Ok(()) @@ -51,16 +52,19 @@ impl CacheStack { &self, filter: filter::Filter, from: git2::Oid, + sequence_number: u128, ) -> JoshResult> { let values = self .backends .iter() .enumerate() - .find_map(|(index, backend)| match backend.read(filter, from) { - Ok(None) => None, - Ok(Some(oid)) => Some(Ok((index, oid))), - Err(e) => Some(Err(e)), - }); + .find_map( + |(index, backend)| match backend.read(filter, from, sequence_number) { + Ok(None) => None, + Ok(Some(oid)) => Some(Ok((index, oid))), + Err(e) => Some(Err(e)), + }, + ); let (index, oid) = match values { // None of the backends had the value @@ -74,7 +78,7 @@ impl CacheStack { self.backends .iter() .take(index) - .try_for_each(|backend| backend.write(filter, from, oid))?; + .try_for_each(|backend| backend.write(filter, from, oid, sequence_number))?; Ok(Some(oid)) } diff --git a/josh-core/src/filter/mod.rs b/josh-core/src/filter/mod.rs index 09bc74897..777db2d3c 100644 --- a/josh-core/src/filter/mod.rs +++ b/josh-core/src/filter/mod.rs @@ -51,6 +51,10 @@ impl Filter { } } +pub fn sequence_number() -> Filter { + Filter(git2::Oid::zero()) +} + impl std::fmt::Debug for Filter { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { to_op(*self).fmt(f) @@ -224,6 +228,9 @@ fn to_filter(op: Op) -> Filter { } fn to_op(filter: Filter) -> Op { + if filter == sequence_number() { + return Op::Nop; + } FILTERS .lock() .unwrap() @@ -391,36 +398,6 @@ fn pretty2(op: &Op, indent: usize, compose: bool) -> String { } } -pub fn nesting(filter: Filter) -> usize { - nesting2(&to_op(filter)) -} - -fn nesting2(op: &Op) -> usize { - match op { - Op::Compose(filters) => 1 + filters.iter().map(|f| nesting(*f)).fold(0, |a, b| a.max(b)), - Op::Exclude(filter) | Op::Pin(filter) => 1 + nesting(*filter), - Op::Workspace(_) => usize::MAX / 2, // divide by 2 to make sure there is enough headroom to avoid overflows - Op::Hook(_) => usize::MAX / 2, // divide by 2 to make sure there is enough headroom to avoid overflows - Op::Chain(a, b) => 1 + nesting(*a).max(nesting(*b)), - Op::Subtract(a, b) => 1 + nesting(*a).max(nesting(*b)), - Op::Rev(filters) => { - 1 + filters - .values() - .map(|filter| nesting(*filter)) - .max() - .unwrap_or(0) - } - Op::Join(filters) => { - 1 + filters - .values() - .map(|filter| nesting(*filter)) - .max() - .unwrap_or(0) - } - _ => 0, - } -} - pub fn lazy_refs(filter: Filter) -> Vec { lazy_refs2(&to_op(filter)) } @@ -550,6 +527,9 @@ fn resolve_refs2(refs: &std::collections::HashMap, op: &Op) - /// Compact, single line string representation of a filter so that `parse(spec(F)) == F` /// Note that this is will not be the best human readable representation. For that see `pretty(...)` pub fn spec(filter: Filter) -> String { + if filter == sequence_number() { + return "sequence_number".to_string(); + } let filter = opt::simplify(filter); spec2(&to_op(filter)) } @@ -1261,13 +1241,7 @@ pub fn apply_to_commit( let missing = transaction.get_missing(); - // Since 'missing' is sorted by nesting, the first is always the minimal - let minimal_nesting = missing.first().map(|(f, _)| nesting(*f)).unwrap_or(0); - for (f, i) in missing { - if nesting(f) != minimal_nesting { - break; - } history::walk2(f, i, transaction)?; } } diff --git a/josh-core/src/history.rs b/josh-core/src/history.rs index cf0a3b743..0629de311 100644 --- a/josh-core/src/history.rs +++ b/josh-core/src/history.rs @@ -8,15 +8,13 @@ pub fn walk2( ) -> JoshResult<()> { rs_tracing::trace_scoped!("walk2","spec":filter::spec(filter), "id": input.to_string()); - ok_or!(transaction.repo().find_commit(input), { - return Ok(()); - }); - if transaction.known(filter, input) { return Ok(()); } - let (known, n_new) = find_known(filter, input, transaction)?; + ok_or!(transaction.repo().find_commit(input), { + return Ok(()); + }); let walk = { let mut walk = transaction.repo().revwalk()?; @@ -24,51 +22,52 @@ pub fn walk2( walk.simplify_first_parent()?; } walk.set_sorting(git2::Sort::REVERSE | git2::Sort::TOPOLOGICAL)?; + walk.push(input)?; - for k in known.iter() { - walk.hide(*k)?; - } walk }; + let mut hide_callback = |id| { + let k = transaction.known(filter, id); + k + }; + let walk = walk.with_hide_callback(&mut hide_callback)?; log::info!( "Walking {} new commits for:\n{}\n", - n_new, + 0, filter::pretty(filter, 4), ); - let mut n_commits = 0; - let mut n_misses = transaction.misses(); + let mut n_in = 0; + let mut n_out = 0; let walks = transaction.new_walk(); for original_commit_id in walk { - if !filter::apply_to_commit3( + if filter::apply_to_commit3( filter, &transaction.repo().find_commit(original_commit_id?)?, transaction, )? { - break; + n_out += 1; } - n_commits += 1; - if n_commits % 1000 == 0 { + n_in += 1; + if n_in % 1000 == 0 { log::debug!( - "{} {} commits filtered, {} misses", + "{} {} commits filtered, {} written", " ->".repeat(walks), - n_commits, - transaction.misses() - n_misses, + n_in, + n_out, ); - n_misses = transaction.misses(); } } log::info!( - "{} {} commits filtered, {} misses", + "{} {} commits filtered, {} written", " ->".repeat(walks), - n_commits, - transaction.misses() - n_misses, + n_in, + n_out, ); - transaction.end_walk(); Ok(()) @@ -166,29 +165,6 @@ pub fn find_original( Ok(git2::Oid::zero()) } -fn find_known( - filter: filter::Filter, - input: git2::Oid, - transaction: &cache::Transaction, -) -> JoshResult<(Vec, usize)> { - log::debug!("find_known"); - let mut known = vec![]; - let mut walk = transaction.repo().revwalk()?; - walk.push(input)?; - - let n_new = walk - .with_hide_callback(&mut |id| { - let k = transaction.known(filter, id); - if k { - known.push(id) - } - k - })? - .count(); - log::debug!("/find_known {}", n_new); - Ok((known, n_new)) -} - // takes everything from base except its tree and replaces it with the tree // given pub fn rewrite_commit( diff --git a/tests/experimental/indexer.t b/tests/experimental/indexer.t index d91f25e36..8efb6b437 100644 --- a/tests/experimental/indexer.t +++ b/tests/experimental/indexer.t @@ -20,6 +20,7 @@ $ josh-filter -s :INDEX --update refs/heads/index [3] :INDEX + [3] sequence_number [6] _trigram_index $ josh-filter :/ --search "Another" diff --git a/tests/filter/ambiguous_merge.t b/tests/filter/ambiguous_merge.t index 55a223473..b89f59e0d 100644 --- a/tests/filter/ambiguous_merge.t +++ b/tests/filter/ambiguous_merge.t @@ -39,6 +39,7 @@ $ josh-filter -s ::sub1/ branch1 --update refs/heads/hidden_branch1 [2] :prefix=sub1 [3] :/sub1 + [5] sequence_number $ git checkout hidden_branch1 Switched to branch 'hidden_branch1' $ git log --graph --oneline --decorate @@ -54,6 +55,7 @@ $ josh-filter -s ::sub1/ master --update refs/heads/hidden_master [3] :prefix=sub1 [4] :/sub1 + [7] sequence_number $ git checkout hidden_master Switched to branch 'hidden_master' $ git log --graph --oneline --decorate @@ -86,6 +88,7 @@ $ josh-filter -s ::sub1/ --reverse master --update refs/heads/hidden_master [3] :prefix=sub1 [4] :/sub1 + [7] sequence_number $ git checkout master Switched to branch 'master' diff --git a/tests/filter/cmdline.t b/tests/filter/cmdline.t index 1f8a88e61..172a5f51d 100644 --- a/tests/filter/cmdline.t +++ b/tests/filter/cmdline.t @@ -36,6 +36,7 @@ $ josh-filter -s c=:/sub1 --update refs/josh/filter/libs/master libs/master [2] :/sub1 [2] :prefix=c + [4] sequence_number $ git log --graph --pretty=%s josh/filter/libs/master * add file2 * add file1 @@ -45,6 +46,7 @@ [2] :/sub1 [2] :/sub2 [2] :prefix=c + [7] sequence_number $ git log --graph --pretty=%s josh/filter/libs/foo * add file3 @@ -63,6 +65,13 @@ |-- heads | `-- master |-- josh + | |-- 24 + | | `-- 0 + | | |-- 5a4a73be0065ab74681f8302fd032224a32ffaed + | | |-- c37f9b5c5d2022cce0acbae87682f3eb5cdf29fb + | | |-- d14715b1358e12e9fb4132036e06049fd1ddf88f + | | |-- d6fc41eeb18ee6e3acf23e9a49bd4f10136d1db0 + | | `-- fcdb5e527e610ecf5ad7e25a5b388fffc2af7240 | `-- filter | `-- libs | |-- foo @@ -74,7 +83,7 @@ | `-- master `-- tags - 8 directories, 6 files + 10 directories, 11 files $ git read-tree HEAD josh/filter/libs/master josh/filter/libs/foo $ git commit -m "sync" diff --git a/tests/filter/commit_message_raw.t b/tests/filter/commit_message_raw.t index d352f924e..208acbc26 100644 --- a/tests/filter/commit_message_raw.t +++ b/tests/filter/commit_message_raw.t @@ -13,6 +13,7 @@ $ josh-filter -s c=:prefix=pre master --update refs/josh/filter/master [1] :prefix=c [1] :prefix=pre + [2] sequence_number $ git cat-file commit master tree 2f407f8ecb16a66b85e2c84d3889720b7a0e3762 author Josh 1112911993 +0000 diff --git a/tests/filter/compose_shadow_dir_same_name.t b/tests/filter/compose_shadow_dir_same_name.t index 9602b9455..b4c1bd5dd 100644 --- a/tests/filter/compose_shadow_dir_same_name.t +++ b/tests/filter/compose_shadow_dir_same_name.t @@ -92,6 +92,7 @@ :/xx :/sub/xx ] + [3] sequence_number $ git diff ${EMPTY_TREE}..FILTERED_HEAD diff --git a/file1 b/file1 new file mode 100644 diff --git a/tests/filter/deleted_dir.t b/tests/filter/deleted_dir.t index a5d4c658b..0b08e0150 100644 --- a/tests/filter/deleted_dir.t +++ b/tests/filter/deleted_dir.t @@ -19,6 +19,7 @@ in that subtree repo should have an empty tree $ josh-filter -s c=:/sub1 master --update refs/josh/filter/master [2] :/sub1 [2] :prefix=c + [4] sequence_number $ git log refs/josh/filter/master --graph --pretty=%s * add file2 @@ -36,6 +37,7 @@ in that subtree repo should have an empty tree $ josh-filter -s c=:/sub1 master --update refs/josh/filter/master [3] :/sub1 [3] :prefix=c + [6] sequence_number $ git log refs/josh/filter/master --graph --pretty=%s * rm sub1 diff --git a/tests/filter/empty_head.t b/tests/filter/empty_head.t index 03a5975c2..6d11db7d3 100644 --- a/tests/filter/empty_head.t +++ b/tests/filter/empty_head.t @@ -20,6 +20,7 @@ $ josh-filter -s :/sub1 master --update refs/josh/filter/master [2] :/sub1 + [3] sequence_number $ git log --graph --pretty=%s josh/filter/master * add file2 * add file1 @@ -27,6 +28,7 @@ $ josh-filter -s :/sub2 master --update refs/josh/filter/master [2] :/sub1 [2] :/sub2 + [3] sequence_number $ git log --graph --pretty=%s josh/filter/master * add file3 @@ -38,5 +40,6 @@ Warning: reference refs/josh/filter/master wasn't updated [2] :/sub1 [2] :/sub2 + [4] sequence_number $ git log --graph --pretty=%s josh/filter/master * add file3 diff --git a/tests/filter/empty_orphan.t b/tests/filter/empty_orphan.t index fb7647d26..95eb2f026 100644 --- a/tests/filter/empty_orphan.t +++ b/tests/filter/empty_orphan.t @@ -22,6 +22,7 @@ Empty root commits from unrelated parts of the tree should not be included $ josh-filter -s c=:/sub1 master --update refs/josh/filter/master [3] :/sub1 [3] :prefix=c + [6] sequence_number $ git log refs/josh/filter/master --graph --pretty=%s * add file3 @@ -83,6 +84,7 @@ Empty root commits from unrelated parts of the tree should not be included $ josh-filter -s c=:/sub1 master [3] :prefix=c [5] :/sub1 + [10] sequence_number $ git log FILTERED_HEAD --graph --pretty=%s * add file3 @@ -98,6 +100,7 @@ Empty root commits from unrelated parts of the tree should not be included [5] :/sub1 [5] :exclude[::sub1/] [6] :prefix=c + [10] sequence_number $ git log FILTERED_HEAD --graph --pretty=%s * add some_other_file @@ -113,6 +116,7 @@ Empty root commits from unrelated parts of the tree should not be included [5] :/sub1 [5] :exclude[::sub1/] [6] :prefix=c + [12] sequence_number $ git ls-tree --name-only -r FILTERED_HEAD x/c/some_file diff --git a/tests/filter/empty_reimport.t b/tests/filter/empty_reimport.t index 3021af81e..86ac5a3fd 100644 --- a/tests/filter/empty_reimport.t +++ b/tests/filter/empty_reimport.t @@ -40,6 +40,7 @@ $ josh-filter -s c=:/pre master --update refs/josh/filter/master [2] :prefix=c [4] :/pre + [7] sequence_number $ git log josh/filter/master --graph --pretty=%s * change on other 2 @@ -82,6 +83,7 @@ $ josh-filter -s c=:/pre master --update refs/josh/filter/master [5] :prefix=c [7] :/pre + [14] sequence_number $ git log josh/filter/master --graph --pretty=%s * Merge branch 'other_branch' diff --git a/tests/filter/exclude_compose.t b/tests/filter/exclude_compose.t index cbfa187fc..0dc2aa8e3 100644 --- a/tests/filter/exclude_compose.t +++ b/tests/filter/exclude_compose.t @@ -21,6 +21,7 @@ $ josh-filter -s :exclude[::sub2/] master --update refs/heads/hidden [2] :exclude[::sub2/] + [3] sequence_number $ git checkout -q hidden 1> /dev/null $ tree . @@ -44,6 +45,7 @@ ::sub2/ ] [2] :exclude[::sub2/] + [3] sequence_number $ git checkout -q refs/josh/filtered $ tree @@ -60,6 +62,7 @@ ] [2] :exclude[::sub2/] [3] :exclude[:/sub3:prefix=sub1] + [3] sequence_number $ git checkout -q refs/josh/filtered $ tree diff --git a/tests/filter/file.t b/tests/filter/file.t index 11b435f09..7b445eed5 100644 --- a/tests/filter/file.t +++ b/tests/filter/file.t @@ -33,6 +33,7 @@ c = :/sub1 a/b = :/sub2 ] + [4] sequence_number $ git log --graph --pretty=%s FILTERED_HEAD * add file3 * add file2 @@ -43,6 +44,7 @@ c = :/sub1 a/b = :/sub2 ] + [5] sequence_number $ git log --graph --pretty=%s FILTERED_HEAD * initial @@ -50,7 +52,11 @@ .git/refs/ |-- heads | `-- master + |-- josh + | `-- 24 + | `-- 0 + | `-- 8d28f139b3f76b91bc4e6146a5943eb1635bfb11 `-- tags - 3 directories, 1 file + 6 directories, 2 files diff --git a/tests/filter/gpgsig.t b/tests/filter/gpgsig.t index cfdd817e8..8fe4b2b79 100644 --- a/tests/filter/gpgsig.t +++ b/tests/filter/gpgsig.t @@ -39,11 +39,13 @@ If 0b4cf6c9efbbda1eada39fa9c1d21d2525b027bb shows up then the signature was lost Remove the signature, the shas are different. $ josh-filter :unsign refs/heads/master --update refs/heads/filtered -s [1] :unsign + [1] sequence_number $ git rev-parse master filtered cb22ebb8e47b109f7add68b1043e561e0db09802 0b4cf6c9efbbda1eada39fa9c1d21d2525b027bb $ josh-filter --reverse :unsign refs/heads/double-filtered --update refs/heads/filtered -s [1] :unsign + [1] sequence_number $ git rev-parse master double-filtered cb22ebb8e47b109f7add68b1043e561e0db09802 cb22ebb8e47b109f7add68b1043e561e0db09802 diff --git a/tests/filter/hide_view.t b/tests/filter/hide_view.t index e20ba1b59..ec51249f8 100644 --- a/tests/filter/hide_view.t +++ b/tests/filter/hide_view.t @@ -36,6 +36,7 @@ $ josh-filter -s c=:exclude[::sub1/] master --update refs/josh/filter/master [1] :prefix=c [2] :exclude[::sub1/] + [4] sequence_number $ git checkout josh/filter/master 2> /dev/null $ git log --graph --pretty=%s * add file3 @@ -51,6 +52,7 @@ [2] :exclude[::sub1/] [2] :exclude[::sub1/file2] [3] :prefix=c + [5] sequence_number $ git checkout josh/filter/master 2> /dev/null $ git log --graph --pretty=%s * add file3 @@ -70,6 +72,7 @@ [2] :exclude[::sub1/file2] [2] :exclude[::sub2/file3] [4] :prefix=c + [5] sequence_number $ git checkout josh/filter/master 2> /dev/null $ git log --graph --pretty=%s * add file2 diff --git a/tests/filter/hook_notes.t b/tests/filter/hook_notes.t index 9253d884b..50794fb15 100644 --- a/tests/filter/hook_notes.t +++ b/tests/filter/hook_notes.t @@ -25,6 +25,7 @@ $ josh-filter -s :hook=commits HEAD --update refs/josh/filtered [2] ::b [3] :hook="commits" + [3] sequence_number $ git log --graph --pretty=%s refs/josh/filtered * add f3 diff --git a/tests/filter/infofile.t b/tests/filter/infofile.t index d2a41e65a..26ef765a6 100644 --- a/tests/filter/infofile.t +++ b/tests/filter/infofile.t @@ -25,6 +25,7 @@ $ josh-filter -s c=:/sub1 master --update refs/josh/filter/master [2] :/sub1 [2] :prefix=c + [6] sequence_number $ git log --graph --pretty=%s josh/filter/master * add file2 * add file1 @@ -33,6 +34,7 @@ Warning: reference refs/josh/filter/master wasn't updated [2] :/sub1 [2] :prefix=c + [6] sequence_number $ git log --graph --pretty=%s josh/filter/master * add file2 * add file1 @@ -41,6 +43,7 @@ [2] :/sub1 [2] :/sub2 [3] :prefix=c + [7] sequence_number $ git log --graph --pretty=%s josh/filter/master * add file3 @@ -53,5 +56,6 @@ [2] :/sub1 [2] :/sub2 [3] :prefix=c + [8] sequence_number $ git log --graph --pretty=%s josh/filter/master * add file3 diff --git a/tests/filter/join.t b/tests/filter/join.t index 1a21dfca7..a08cfdd2f 100644 --- a/tests/filter/join.t +++ b/tests/filter/join.t @@ -8,6 +8,7 @@ Initial commit Apply prefix filter $ josh-filter -s :prefix=subtree refs/heads/master --update refs/heads/filtered [1] :prefix=subtree + [1] sequence_number $ git log --graph --pretty=%s refs/heads/filtered * add file1 diff --git a/tests/filter/linear.t b/tests/filter/linear.t index 27f8538f9..6f287362e 100644 --- a/tests/filter/linear.t +++ b/tests/filter/linear.t @@ -32,7 +32,8 @@ * add file1 $ josh-filter -s :linear refs/heads/master --update refs/heads/filtered - [3] :linear + [4] :linear + [4] sequence_number $ git log --graph --pretty=%s refs/heads/filtered * Merge branch 'branch2' @@ -57,7 +58,8 @@ * add file1 $ josh-filter -s :linear refs/heads/master --update refs/heads/filtered --reverse - [3] :linear + [4] :linear + [4] sequence_number $ git log --graph --pretty=%s refs/heads/master * mod file2 diff --git a/tests/filter/moved_dir.t b/tests/filter/moved_dir.t index c594ee6a2..bbc24b640 100644 --- a/tests/filter/moved_dir.t +++ b/tests/filter/moved_dir.t @@ -19,6 +19,7 @@ in that subtree repo should have an empty tree $ josh-filter -s c=:/sub1 master --update refs/josh/filter/master [2] :/sub1 [2] :prefix=c + [4] sequence_number $ git log refs/josh/filter/master --graph --pretty=%s * add file2 @@ -38,6 +39,7 @@ in that subtree repo should have an empty tree $ josh-filter -s c=:/sub1 master --update refs/josh/filter/master [3] :/sub1 [3] :prefix=c + [6] sequence_number $ git log refs/josh/filter/master --graph --pretty=%s * mv sub1 @@ -52,6 +54,7 @@ in that subtree repo should have an empty tree $ josh-filter -s c=:/sub1 master --update refs/josh/filter/master2 [3] :/sub1 [3] :prefix=c + [7] sequence_number $ git log refs/josh/filter/master2 --graph --pretty=%s * mv sub1 * add file2 diff --git a/tests/filter/prefix.t b/tests/filter/prefix.t index dae646ece..1c5a98216 100644 --- a/tests/filter/prefix.t +++ b/tests/filter/prefix.t @@ -8,6 +8,7 @@ Initial commit Apply prefix filter $ josh-filter -s :prefix=subtree refs/heads/master --update refs/heads/filtered [1] :prefix=subtree + [1] sequence_number $ git log --graph --pretty=%s refs/heads/filtered * add file1 diff --git a/tests/filter/prune_trivial_merge.t b/tests/filter/prune_trivial_merge.t index d52ca62ca..9572b366f 100644 --- a/tests/filter/prune_trivial_merge.t +++ b/tests/filter/prune_trivial_merge.t @@ -35,6 +35,7 @@ $ josh-filter -s ::file1 [4] ::file1 + [5] sequence_number $ git log --graph --pretty=%s FILTERED_HEAD * Merge branch 'branch1' |\ @@ -45,6 +46,7 @@ $ josh-filter -s ::file1:prune=trivial-merge [3] :prune=trivial-merge [4] ::file1 + [6] sequence_number $ git log --graph --pretty=%s FILTERED_HEAD * empty commit diff --git a/tests/filter/rev.t b/tests/filter/rev.t index d44906acc..e48451dad 100644 --- a/tests/filter/rev.t +++ b/tests/filter/rev.t @@ -39,6 +39,7 @@ $ josh-filter -s :prefix=x/y --update refs/heads/filtered [5] :prefix=x [5] :prefix=y + [10] sequence_number $ git log --graph --decorate --pretty=%H:%T refs/heads/filtered * 37f8b29c9e892ea0eb7abac2759ddc6fb0337203:dcbbddf47649f8e73f59fae92896c0d2cd02b6ec |\ @@ -51,6 +52,7 @@ $ josh-filter -s ":rev(ffffffffffffffffffffffffffffffffffffffff:prefix=x/y)" --update refs/heads/filtered [5] :prefix=x [5] :prefix=y + [10] sequence_number ERROR: `:rev(...)` with nonexistent OID: ffffffffffffffffffffffffffffffffffffffff [1] @@ -58,6 +60,7 @@ [5] :prefix=x [5] :prefix=y [5] :rev(975d4c4975912729482cc864d321c5196a969271:prefix=x/y) + [10] sequence_number $ git log --graph --decorate --pretty=%H:%T refs/heads/filtered * 54651c29aa86e8512a7b9d39e3b8ea26da644247:5f47d9fdffdc726bb8ebcfea67531d2574243c5d |\ @@ -73,6 +76,7 @@ [5] :prefix=y [5] :rev(975d4c4975912729482cc864d321c5196a969271:prefix=x/y) [5] :rev(e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) + [10] sequence_number $ git log --graph --decorate --pretty=%H:%T refs/heads/filtered * 5fe60a2d55b652822b3d3f25410714e9053ba72b:5f47d9fdffdc726bb8ebcfea67531d2574243c5d |\ @@ -95,6 +99,7 @@ [5] :rev(975d4c4975912729482cc864d321c5196a969271:prefix=x/y) [5] :rev(975d4c4975912729482cc864d321c5196a969271:prefix=x/y,e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) [5] :rev(e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) + [10] sequence_number $ git log --graph --decorate --pretty=%H:%T refs/heads/filtered * 63fea1234f375bd09019b676da8291f28d2ddb43:5f47d9fdffdc726bb8ebcfea67531d2574243c5d |\ @@ -121,6 +126,7 @@ [5] :rev(975d4c4975912729482cc864d321c5196a969271:prefix=x/z,e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) [5] :rev(e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) [6] :prefix=x + [11] sequence_number $ cat > filter.josh < :rev( > e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y @@ -140,6 +146,7 @@ [5] :rev(975d4c4975912729482cc864d321c5196a969271:prefix=x/z,e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) [5] :rev(e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) [6] :prefix=x + [11] sequence_number $ git log --graph --decorate --pretty=%H:%T refs/heads/filtered * 1c4fe25dc386c77adaae12d6b1cd3abfa296fc3c:5f47d9fdffdc726bb8ebcfea67531d2574243c5d |\ @@ -155,13 +162,14 @@ [2] :rev(0000000000000000000000000000000000000000:prefix=x/y,975d4c4975912729482cc864d321c5196a969271:prefix=x/z) [2] :rev(0000000000000000000000000000000000000000:prefix=x/y,e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) [2] :rev(0000000000000000000000000000000000000000:prefix=x/z,e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) - [3] :linear + [5] :linear [5] :prefix=y [5] :rev(975d4c4975912729482cc864d321c5196a969271:prefix=x/y) [5] :rev(975d4c4975912729482cc864d321c5196a969271:prefix=x/y,e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) [5] :rev(975d4c4975912729482cc864d321c5196a969271:prefix=x/z,e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) [5] :rev(e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) [6] :prefix=x + [11] sequence_number $ git log --graph --decorate --pretty=%H:%T refs/heads/filtered * f8e8bc9daf54340c9fce647be467d2577b623bbe:5f47d9fdffdc726bb8ebcfea67531d2574243c5d * e707f76bb6a1390f28b2162da5b5eb6933009070:5d8a699f74b48c9c595f4615dd3755244e11d176 @@ -195,14 +203,15 @@ [2] :rev(0000000000000000000000000000000000000000:prefix=x/y,e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) [2] :rev(0000000000000000000000000000000000000000:prefix=x/z,e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) [2] :rev(0000000000000000000000000000000000000000:prefix=y,0b4cf6c9efbbda1eada39fa9c1d21d2525b027bb:prefix=z) - [3] :linear [3] :rev(0000000000000000000000000000000000000000:prefix=x,0b4cf6c9efbbda1eada39fa9c1d21d2525b027bb:prefix=z,e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=y) + [5] :linear [5] :prefix=y [5] :rev(975d4c4975912729482cc864d321c5196a969271:prefix=x/y) [5] :rev(975d4c4975912729482cc864d321c5196a969271:prefix=x/y,e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) [5] :rev(975d4c4975912729482cc864d321c5196a969271:prefix=x/z,e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) [5] :rev(e707f76bb6a1390f28b2162da5b5eb6933009070:prefix=x/y) [6] :prefix=x + [12] sequence_number $ git log --graph --decorate --pretty=%H:%T refs/heads/filtered * 2944f04c33ea037f7696282bf20b2e570524552e:047b1b6f39e8d95b62ef7f136189005d0e3c80b3 diff --git a/tests/filter/reverse_hide.t b/tests/filter/reverse_hide.t index dc54f0a1a..37ee2d6c0 100644 --- a/tests/filter/reverse_hide.t +++ b/tests/filter/reverse_hide.t @@ -16,6 +16,7 @@ $ josh-filter -s :exclude[::sub2/] master --update refs/heads/hidden [1] :exclude[::sub2/] + [2] sequence_number $ git checkout hidden 1> /dev/null Switched to branch 'hidden' $ tree @@ -33,6 +34,7 @@ $ josh-filter -s :exclude[::sub2/] --reverse master --update refs/heads/hidden [1] :exclude[::sub2/] + [2] sequence_number $ git checkout master Switched to branch 'master' @@ -67,6 +69,7 @@ $ josh-filter -s :exclude[::sub2/] --reverse master --update refs/heads/hidden [2] :exclude[::sub2/] + [3] sequence_number $ git log --graph --pretty=%s refs/heads/master * empty commit * add sub1/file3 diff --git a/tests/filter/reverse_hide_edit.t b/tests/filter/reverse_hide_edit.t index e3c63db88..404de8d7f 100644 --- a/tests/filter/reverse_hide_edit.t +++ b/tests/filter/reverse_hide_edit.t @@ -16,6 +16,7 @@ $ josh-filter -s :exclude[::sub2/] master --update refs/heads/hidden [1] :exclude[::sub2/] + [2] sequence_number $ git checkout hidden 1> /dev/null Switched to branch 'hidden' $ tree @@ -33,6 +34,7 @@ $ josh-filter -s :exclude[::sub2/] --reverse master --update refs/heads/hidden [1] :exclude[::sub2/] + [2] sequence_number $ git checkout master Switched to branch 'master' diff --git a/tests/filter/reverse_hide_edit_missing_change.t b/tests/filter/reverse_hide_edit_missing_change.t index 8c145d09d..0ec12fe70 100644 --- a/tests/filter/reverse_hide_edit_missing_change.t +++ b/tests/filter/reverse_hide_edit_missing_change.t @@ -29,6 +29,7 @@ $ josh-filter -s :exclude[::sub2/] master --update refs/heads/hidden [1] :exclude[::sub2/] + [2] sequence_number $ git checkout hidden 1> /dev/null Switched to branch 'hidden' $ tree @@ -48,6 +49,7 @@ $ josh-filter -s :exclude[::sub2/] --reverse master --update refs/heads/hidden [1] :exclude[::sub2/] + [2] sequence_number $ git checkout master Switched to branch 'master' diff --git a/tests/filter/reverse_merge.t b/tests/filter/reverse_merge.t index 01a65ca0a..46e369964 100644 --- a/tests/filter/reverse_merge.t +++ b/tests/filter/reverse_merge.t @@ -26,6 +26,7 @@ $ josh-filter -s :exclude[::sub2/] branch1 --update refs/heads/hidden_branch1 [2] :exclude[::sub2/] + [2] sequence_number $ git checkout hidden_branch1 Switched to branch 'hidden_branch1' $ tree @@ -40,6 +41,7 @@ $ josh-filter -s :exclude[::sub2/] master --update refs/heads/hidden_master [3] :exclude[::sub2/] + [3] sequence_number $ git checkout hidden_master Switched to branch 'hidden_master' $ tree @@ -73,6 +75,7 @@ $ josh-filter -s :exclude[::sub2/] --reverse master --update refs/heads/hidden_master [3] :exclude[::sub2/] + [3] sequence_number $ git checkout master Switched to branch 'master' diff --git a/tests/filter/reverse_split.t b/tests/filter/reverse_split.t index 6e9d5c1b0..d5ac7bcef 100644 --- a/tests/filter/reverse_split.t +++ b/tests/filter/reverse_split.t @@ -18,6 +18,7 @@ a = ::*.a :prefix=rest ] + [2] sequence_number $ git checkout filtered 1> /dev/null Switched to branch 'filtered' $ tree @@ -42,6 +43,7 @@ a = ::*.a :prefix=rest ] + [2] sequence_number $ git checkout master Switched to branch 'master' diff --git a/tests/filter/roundtrip_custom_header.t b/tests/filter/roundtrip_custom_header.t index 919e57886..f436cad48 100644 --- a/tests/filter/roundtrip_custom_header.t +++ b/tests/filter/roundtrip_custom_header.t @@ -130,3 +130,5 @@ Write a custom header into the commit (h/t https://github.com/Byron/gitoxide/blo f2fd7b2 (HEAD -> master, re-filtered) second 73007fa initial 7d7c929 initial + 9340c45 Notes added by 'git_note_create' from libgit2 + 56a1fe0 Notes added by 'git_note_create' from libgit2 diff --git a/tests/filter/squash.t b/tests/filter/squash.t index 2760b0f8d..dc30e4dd5 100644 --- a/tests/filter/squash.t +++ b/tests/filter/squash.t @@ -30,6 +30,7 @@ $ josh-filter -s --squash-pattern "refs/tags/*" --update refs/heads/filtered Warning: reference refs/heads/filtered wasn't updated + [5] sequence_number $ git log --graph --decorate --pretty=oneline refs/heads/filtered fatal: ambiguous argument 'refs/heads/filtered': unknown revision or path not in the working tree. @@ -45,6 +46,7 @@ This one tag is an annotated tag, to make sure those are handled as well [1] :squash( 1d69b7d2651f744be3416f2ad526aeccefb99310:"refs/tags/tag_a" ) + [7] sequence_number $ git log --graph --decorate --pretty=oneline refs/heads/filtered * 977cc3ee14c0d6163ba63bd96f4aeedd43916ba7 (tag: filtered/tag_a, filtered) refs/tags/tag_a @@ -73,6 +75,7 @@ This one tag is an annotated tag, to make sure those are handled as well 977cc3ee14c0d6163ba63bd96f4aeedd43916ba7:"refs/tags/filtered/tag_a" ) [4] :author="New Author";"new@e.mail" + [11] sequence_number $ git log --graph --decorate --pretty=oneline refs/heads/filtered * be41caf35896090033cfd103e06aae721a3ce541 (tag: filtered/tag_a, filtered) refs/tags/tag_a @@ -115,6 +118,7 @@ This one tag is an annotated tag, to make sure those are handled as well a68763bdf2f45a44304067954855749e366a5533:"refs/tags/filtered/filtered/tag_a" be41caf35896090033cfd103e06aae721a3ce541:"refs/tags/filtered/tag_a" ) + [16] sequence_number $ git log --graph --pretty=%an:%ae-%cn:%ce refs/heads/filtered * Josh:josh@example.com-New Author:new@e.mail |\ @@ -181,6 +185,7 @@ This one tag is an annotated tag, to make sure those are handled as well be41caf35896090033cfd103e06aae721a3ce541:"refs/tags/filtered/tag_a" ) [6] :author="New Author";"new@e.mail" + [19] sequence_number $ git log --graph --decorate --pretty=oneline refs/heads/filtered * 2826b9a173c7a7d5c83d9ae2614de89c77205d83 (filtered) refs/tags/tag_a diff --git a/tests/filter/squash_empty_initial.t b/tests/filter/squash_empty_initial.t index b597b7f04..af32b7595 100644 --- a/tests/filter/squash_empty_initial.t +++ b/tests/filter/squash_empty_initial.t @@ -37,6 +37,7 @@ $ josh-filter -s --squash-pattern "refs/tags/*" --update refs/heads/filtered Warning: reference refs/heads/filtered wasn't updated + [5] sequence_number $ git log --graph --decorate --pretty=oneline refs/heads/filtered fatal: ambiguous argument 'refs/heads/filtered': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: @@ -50,6 +51,7 @@ [1] :squash( 882f2656a5075936eb37bfefde740e0b453e4479:"refs/tags/tag_a" ) + [7] sequence_number $ git log --graph --decorate --pretty=oneline refs/heads/filtered * 977cc3ee14c0d6163ba63bd96f4aeedd43916ba7 (tag: filtered/tag_a, filtered) refs/tags/tag_a diff --git a/tests/filter/submodule.t b/tests/filter/submodule.t index e9a2188af..c72816b2d 100644 --- a/tests/filter/submodule.t +++ b/tests/filter/submodule.t @@ -25,9 +25,11 @@ $ josh-filter -s :/libs master --update refs/josh/filter/master [1] :/libs + [2] sequence_number $ git ls-tree --name-only -r refs/josh/filter/master $ josh-filter -s c=:/libs master --update refs/josh/filter/master Warning: reference refs/josh/filter/master wasn't updated [1] :/libs [1] :prefix=c + [2] sequence_number $ git ls-tree --name-only -r refs/josh/filter/master diff --git a/tests/filter/subtree_prefix.t b/tests/filter/subtree_prefix.t index dc3455aea..f496e784d 100644 --- a/tests/filter/subtree_prefix.t +++ b/tests/filter/subtree_prefix.t @@ -44,6 +44,7 @@ Rewrite the subtree part of the history $ josh-filter -s ":rev($SUBTREE_TIP:prefix=subtree)" refs/heads/master --update refs/heads/filtered [1] :prefix=subtree [4] :rev(c036f944faafb865e0585e4fa5e005afa0aeea3f:prefix=subtree) + [4] sequence_number $ git log --graph --pretty=%s refs/heads/filtered * subtree edit from main repo @@ -70,6 +71,7 @@ Extract the subtree history [1] :prefix=subtree [4] :/subtree [4] :rev(c036f944faafb865e0585e4fa5e005afa0aeea3f:prefix=subtree) + [7] sequence_number $ git checkout subtree Switched to branch 'subtree' $ cat file2 @@ -83,6 +85,7 @@ Work in the subtree, and sync that back. [1] :prefix=subtree [4] :/subtree [4] :rev(c036f944faafb865e0585e4fa5e005afa0aeea3f:prefix=subtree) + [7] sequence_number $ git log --graph --pretty=%s refs/heads/master * add even more content * subtree edit from main repo @@ -105,6 +108,7 @@ And then re-extract, which should re-construct the same subtree. [1] :prefix=subtree [5] :/subtree [5] :rev(c036f944faafb865e0585e4fa5e005afa0aeea3f:prefix=subtree) + [9] sequence_number $ test $(git rev-parse subtree) = $(git rev-parse subtree2) Simulate a feature branch on the main repo that crosses subtree changes @@ -179,6 +183,7 @@ And finally, sync first from main to sub and then back. [1] :prefix=subtree [9] :/subtree [9] :rev(c036f944faafb865e0585e4fa5e005afa0aeea3f:prefix=subtree) + [17] sequence_number $ git log --graph --pretty=%H:%s refs/heads/master * 6ac0ba56575859cfaacd5818084333e532ffc442:Merge branch 'subtree-sync' into subtree @@ -225,6 +230,7 @@ taken back into the main history. [1] :prefix=subtree [13] :/subtree [13] :rev(c036f944faafb865e0585e4fa5e005afa0aeea3f:prefix=subtree) + [25] sequence_number $ git ls-tree --name-only -r refs/heads/master feature1 feature2 diff --git a/tests/filter/workspace_combine_filter.t b/tests/filter/workspace_combine_filter.t index c27fa8ffb..cabd731e5 100644 --- a/tests/filter/workspace_combine_filter.t +++ b/tests/filter/workspace_combine_filter.t @@ -56,6 +56,7 @@ ] [2] :prefix=x [2] :workspace=ws + [4] sequence_number $ git log --graph --pretty=%s FILTERED_HEAD * add ws @@ -92,6 +93,7 @@ blub = :/sub1 ] [3] :prefix=xyz + [7] sequence_number $ git log --graph --pretty=%s FILTERED_HEAD * add ws diff --git a/tests/filter/workspace_discover.t b/tests/filter/workspace_discover.t index cb76163f8..5401d4889 100644 --- a/tests/filter/workspace_discover.t +++ b/tests/filter/workspace_discover.t @@ -65,6 +65,7 @@ ] [2] :workspace=ws [2] :workspace=ws2 + [9] sequence_number $ cat > workspace.josh < :/sub1::file1 @@ -101,3 +102,4 @@ ] [2] :workspace=ws [2] :workspace=ws2 + [10] sequence_number diff --git a/tests/filter/workspace_exclude.t b/tests/filter/workspace_exclude.t index 8c24a4051..9d20f30bd 100644 --- a/tests/filter/workspace_exclude.t +++ b/tests/filter/workspace_exclude.t @@ -29,6 +29,7 @@ ::sub2/subsub/ ] [2] :workspace=ws + [3] sequence_number $ git log --graph --pretty=%s refs/heads/filtered * add ws @@ -59,6 +60,7 @@ ::sub2/subsub/ ] [2] :workspace=ws + [3] sequence_number $ git checkout master Switched to branch 'master' diff --git a/tests/filter/workspace_implicit_filter.t b/tests/filter/workspace_implicit_filter.t index 784678438..e887c4168 100644 --- a/tests/filter/workspace_implicit_filter.t +++ b/tests/filter/workspace_implicit_filter.t @@ -28,6 +28,7 @@ ::sub2/subsub/ ] [2] :workspace=ws + [3] sequence_number $ git log --graph --pretty=%s refs/josh/master * add ws diff --git a/tests/filter/workspace_modify_chain.t b/tests/filter/workspace_modify_chain.t index 89d9c7b70..6801de9f0 100644 --- a/tests/filter/workspace_modify_chain.t +++ b/tests/filter/workspace_modify_chain.t @@ -29,6 +29,7 @@ [1] :prefix=subsub [2] :workspace=ws [3] :/sub2 + [7] sequence_number $ git log --graph --pretty=%s refs/heads/filtered * add file2 @@ -53,6 +54,7 @@ [1] :prefix=subsub [2] :workspace=ws [3] :/sub2 + [7] sequence_number $ git checkout master Switched to branch 'master' diff --git a/tests/filter/workspace_multiple_globs.t b/tests/filter/workspace_multiple_globs.t index 8f1889275..1440142b9 100644 --- a/tests/filter/workspace_multiple_globs.t +++ b/tests/filter/workspace_multiple_globs.t @@ -33,6 +33,7 @@ b = ::**/file1 ] [2] :workspace=ws + [3] sequence_number $ git log --graph --pretty=%s refs/josh/master * add ws diff --git a/tests/filter/workspace_redirect.t b/tests/filter/workspace_redirect.t index 64458ad6b..32becdfff 100644 --- a/tests/filter/workspace_redirect.t +++ b/tests/filter/workspace_redirect.t @@ -53,16 +53,18 @@ ::sub2/subsub/ ] [3] :workspace=ws + [7] sequence_number $ josh-filter -s :workspace=ws_new master --update refs/heads/filtered_new [1] :prefix=b - [1] :workspace=ws_new [2] :/sub3 [2] :[ a = :/sub1 ::sub2/subsub/ ] + [2] :workspace=ws_new [3] :workspace=ws [5] :exclude[::ws_new] + [7] sequence_number $ git log --graph --pretty=%s refs/heads/filtered * edit ws @@ -188,3 +190,4 @@ [4] :exclude[::ws] [4] :workspace=ws [6] :exclude[::ws_new] + [10] sequence_number diff --git a/tests/filter/workspace_single_file.t b/tests/filter/workspace_single_file.t index 896ac7356..048807017 100644 --- a/tests/filter/workspace_single_file.t +++ b/tests/filter/workspace_single_file.t @@ -46,6 +46,7 @@ ::sub2/subsub/ ] [2] :workspace=ws + [4] sequence_number $ git log --graph --pretty=%s refs/josh/master * add ws @@ -86,6 +87,7 @@ ] [2] :workspace=ws [2] :workspace=ws2 + [4] sequence_number $ git log --graph --pretty=%s refs/josh/master * add ws2 diff --git a/tests/filter/workspace_trailing_slash.t b/tests/filter/workspace_trailing_slash.t index 19146136e..cd3eaf973 100644 --- a/tests/filter/workspace_trailing_slash.t +++ b/tests/filter/workspace_trailing_slash.t @@ -28,6 +28,7 @@ a/b = :/sub2 ] [2] :workspace=ws + [3] sequence_number $ git log --graph --pretty=%s refs/josh/master * add ws @@ -48,6 +49,7 @@ a/b = :/sub2 ] [3] :workspace=ws + [4] sequence_number $ git log --graph --pretty=%s refs/josh/master * add trailing slash diff --git a/tests/filter/workspace_unique.t b/tests/filter/workspace_unique.t index cf20e025c..80ea10baf 100644 --- a/tests/filter/workspace_unique.t +++ b/tests/filter/workspace_unique.t @@ -38,6 +38,7 @@ so the workspace.josh will still appear in the root of the workspace b = ::ws/workspace.josh ] [2] :workspace=ws + [3] sequence_number $ git log --graph --pretty=%s refs/josh/master * add ws