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