diff --git a/rust/hg-core/src/operations/cat.rs b/rust/hg-core/src/operations/cat.rs --- a/rust/hg-core/src/operations/cat.rs +++ b/rust/hg-core/src/operations/cat.rs @@ -26,6 +26,8 @@ IoError(std::io::Error), /// The revision has not been found. InvalidRevision, + /// Found more than one revision whose ID match the requested prefix + AmbiguousPrefix, /// A `revlog` file is corrupted. CorruptedRevlog, /// The `revlog` format version is not supported. @@ -55,6 +57,7 @@ CatRevErrorKind::UnsuportedRevlogVersion(version) } RevlogError::InvalidRevision => CatRevErrorKind::InvalidRevision, + RevlogError::AmbiguousPrefix => CatRevErrorKind::AmbiguousPrefix, RevlogError::Corrupted => CatRevErrorKind::CorruptedRevlog, RevlogError::UnknowDataFormat(format) => { CatRevErrorKind::UnknowRevlogDataFormat(format) diff --git a/rust/hg-core/src/operations/debugdata.rs b/rust/hg-core/src/operations/debugdata.rs --- a/rust/hg-core/src/operations/debugdata.rs +++ b/rust/hg-core/src/operations/debugdata.rs @@ -24,6 +24,8 @@ IoError(std::io::Error), /// The revision has not been found. InvalidRevision, + /// Found more than one revision whose ID match the requested prefix + AmbiguousPrefix, /// A `revlog` file is corrupted. CorruptedRevlog, /// The `revlog` format version is not supported. @@ -69,6 +71,9 @@ RevlogError::InvalidRevision => { DebugDataErrorKind::InvalidRevision } + RevlogError::AmbiguousPrefix => { + DebugDataErrorKind::AmbiguousPrefix + } RevlogError::Corrupted => DebugDataErrorKind::CorruptedRevlog, RevlogError::UnknowDataFormat(format) => { DebugDataErrorKind::UnknowRevlogDataFormat(format) diff --git a/rust/hg-core/src/operations/list_tracked_files.rs b/rust/hg-core/src/operations/list_tracked_files.rs --- a/rust/hg-core/src/operations/list_tracked_files.rs +++ b/rust/hg-core/src/operations/list_tracked_files.rs @@ -86,6 +86,8 @@ IoError(std::io::Error), /// The revision has not been found. InvalidRevision, + /// Found more than one revision whose ID match the requested prefix + AmbiguousPrefix, /// A `revlog` file is corrupted. CorruptedRevlog, /// The `revlog` format version is not supported. @@ -119,6 +121,9 @@ RevlogError::InvalidRevision => { ListRevTrackedFilesErrorKind::InvalidRevision } + RevlogError::AmbiguousPrefix => { + ListRevTrackedFilesErrorKind::AmbiguousPrefix + } RevlogError::Corrupted => { ListRevTrackedFilesErrorKind::CorruptedRevlog } diff --git a/rust/hg-core/src/revlog/revlog.rs b/rust/hg-core/src/revlog/revlog.rs --- a/rust/hg-core/src/revlog/revlog.rs +++ b/rust/hg-core/src/revlog/revlog.rs @@ -21,6 +21,8 @@ IoError(std::io::Error), UnsuportedVersion(u16), InvalidRevision, + /// Found more than one entry whose ID match the requested prefix + AmbiguousPrefix, Corrupted, UnknowDataFormat(u8), } @@ -93,14 +95,21 @@ pub fn get_node_rev(&self, node: &[u8]) -> Result { // This is brute force. But it is fast enough for now. // Optimization will come later. + let mut found_by_prefix = None; for rev in (0..self.len() as Revision).rev() { let index_entry = self.index.get_entry(rev).ok_or(RevlogError::Corrupted)?; - if node == index_entry.hash() { + if index_entry.hash() == node { return Ok(rev); } + if index_entry.hash().starts_with(node) { + if found_by_prefix.is_some() { + return Err(RevlogError::AmbiguousPrefix); + } + found_by_prefix = Some(rev) + } } - Err(RevlogError::InvalidRevision) + found_by_prefix.ok_or(RevlogError::InvalidRevision) } /// Return the full data associated to a revision. diff --git a/rust/rhg/src/commands/cat.rs b/rust/rhg/src/commands/cat.rs --- a/rust/rhg/src/commands/cat.rs +++ b/rust/rhg/src/commands/cat.rs @@ -75,6 +75,13 @@ )) .into(), )), + CatRevErrorKind::AmbiguousPrefix => CommandErrorKind::Abort(Some( + utf8_to_local(&format!( + "abort: ambiguous revision identifier {}\n", + rev + )) + .into(), + )), CatRevErrorKind::UnsuportedRevlogVersion(version) => { CommandErrorKind::Abort(Some( utf8_to_local(&format!( diff --git a/rust/rhg/src/commands/debugdata.rs b/rust/rhg/src/commands/debugdata.rs --- a/rust/rhg/src/commands/debugdata.rs +++ b/rust/rhg/src/commands/debugdata.rs @@ -55,6 +55,15 @@ .into(), )), }, + DebugDataErrorKind::AmbiguousPrefix => CommandError { + kind: CommandErrorKind::Abort(Some( + utf8_to_local(&format!( + "abort: ambiguous revision identifier{}\n", + rev + )) + .into(), + )), + }, DebugDataErrorKind::UnsuportedRevlogVersion(version) => CommandError { kind: CommandErrorKind::Abort(Some( utf8_to_local(&format!( diff --git a/rust/rhg/src/commands/files.rs b/rust/rhg/src/commands/files.rs --- a/rust/rhg/src/commands/files.rs +++ b/rust/rhg/src/commands/files.rs @@ -91,6 +91,15 @@ .into(), )) } + ListRevTrackedFilesErrorKind::AmbiguousPrefix => { + CommandErrorKind::Abort(Some( + utf8_to_local(&format!( + "abort: ambiguous revision identifier {}\n", + rev + )) + .into(), + )) + } ListRevTrackedFilesErrorKind::UnsuportedRevlogVersion(version) => { CommandErrorKind::Abort(Some( utf8_to_local(&format!( diff --git a/tests/test-rhg.t b/tests/test-rhg.t --- a/tests/test-rhg.t +++ b/tests/test-rhg.t @@ -74,31 +74,49 @@ $ rm -rf repository $ hg init repository $ cd repository - $ for i in 1 2 3; do - > echo $i >> file$i - > hg add file$i - > hg commit -m "commit $i" -q + $ for i in 1 2 3 4 5 6; do + > echo $i >> file-$i + > hg add file-$i + > hg commit -m "Commit $i" -q > done $ rhg debugdata -c 2 - e36fa63d37a576b27a69057598351db6ee5746bd + 8d0267cb034247ebfa5ee58ce59e22e57a492297 test 0 0 - file3 + file-3 - commit 3 (no-eol) + Commit 3 (no-eol) $ rhg debugdata -m 2 - file1\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc) - file2\x005d9299349fc01ddd25d0070d149b124d8f10411e (esc) - file3\x002661d26c649684b482d10f91960cc3db683c38b4 (esc) + file-1\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc) + file-2\x005d9299349fc01ddd25d0070d149b124d8f10411e (esc) + file-3\x002661d26c649684b482d10f91960cc3db683c38b4 (esc) Debuging with full node id $ rhg debugdata -c `hg log -r 0 -T '{node}'` - c8e64718e1ca0312eeee0f59d37f8dc612793856 + d1d1c679d3053e8926061b6f45ca52009f011e3f test 0 0 - file1 + file-1 - commit 1 (no-eol) + Commit 1 (no-eol) + +Specifying revisions by changeset ID + $ hg log -T '{node}\n' + c6ad58c44207b6ff8a4fbbca7045a5edaa7e908b + d654274993d0149eecc3cc03214f598320211900 + f646af7e96481d3a5470b695cf30ad8e3ab6c575 + cf8b83f14ead62b374b6e91a0e9303b85dfd9ed7 + 91c6f6e73e39318534dc415ea4e8a09c99cd74d6 + 6ae9681c6d30389694d8701faf24b583cf3ccafe + $ rhg files -r cf8b83 + file-1 + file-2 + file-3 + $ rhg cat -r cf8b83 file-2 + 2 + $ rhg cat -r c file-2 + abort: invalid revision identifier c + [255] Cat files $ cd $TESTTMP @@ -116,26 +134,6 @@ $ rhg cat -r 1 copy_of_original original content -Specifying revisions by changeset ID - $ hg log - changeset: 1:41263439dc17 - tag: tip - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add copy of original - - changeset: 0:1c9e69808da7 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: add original - - $ rhg files -r 41263439dc17 - abort: invalid revision identifier 41263439dc17 - [255] - $ rhg cat -r 41263439dc17 original - abort: invalid revision identifier 41263439dc17 - [255] - Requirements $ rhg debugrequirements dotencode