author | Matt Harbison <matt_harbison@yahoo.com> |
Mon, 18 Apr 2022 16:18:33 -0400 | |
changeset 49136 | a7fe96abcf56 |
parent 48569 | 20d0d896183e |
child 49998 | 49131579db62 |
permissions | -rw-r--r-- |
45547
522ec3dc44b9
hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
1 |
// list_tracked_files.rs |
522ec3dc44b9
hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
2 |
// |
522ec3dc44b9
hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
3 |
// Copyright 2020 Antoine Cezar <antoine.cezar@octobus.net> |
522ec3dc44b9
hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
4 |
// |
522ec3dc44b9
hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
5 |
// This software may be used and distributed according to the terms of the |
522ec3dc44b9
hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
6 |
// GNU General Public License version 2 or any later version. |
522ec3dc44b9
hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
7 |
|
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
46136
diff
changeset
|
8 |
use crate::repo::Repo; |
45547
522ec3dc44b9
hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
9 |
use crate::revlog::revlog::RevlogError; |
46037
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
46036
diff
changeset
|
10 |
use crate::revlog::Node; |
47989
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47988
diff
changeset
|
11 |
|
48237
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
12 |
use crate::utils::hg_path::HgPath; |
45547
522ec3dc44b9
hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
13 |
|
48391
10c32e1b892a
rhg: Propogate manifest parse errors instead of panicking
Simon Sapin <simon.sapin@octobus.net>
parents:
48249
diff
changeset
|
14 |
use crate::errors::HgError; |
48392
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
15 |
use crate::manifest::Manifest; |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
16 |
use crate::manifest::ManifestEntry; |
48237
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
17 |
use itertools::put_back; |
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
18 |
use itertools::PutBack; |
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
19 |
use std::cmp::Ordering; |
48236
6b5773f89183
rhg: faster hg cat when many files are requested
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
47997
diff
changeset
|
20 |
|
48249
027ebad952ac
rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48246
diff
changeset
|
21 |
pub struct CatOutput<'a> { |
46757
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
22 |
/// Whether any file in the manifest matched the paths given as CLI |
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
23 |
/// arguments |
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
24 |
pub found_any: bool, |
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
25 |
/// The contents of matching files, in manifest order |
48249
027ebad952ac
rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48246
diff
changeset
|
26 |
pub results: Vec<(&'a HgPath, Vec<u8>)>, |
46757
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
27 |
/// Which of the CLI arguments did not match any manifest file |
48249
027ebad952ac
rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48246
diff
changeset
|
28 |
pub missing: Vec<&'a HgPath>, |
46757
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
29 |
/// The node ID that the given revset was resolved to |
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
30 |
pub node: Node, |
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
31 |
} |
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
32 |
|
48237
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
33 |
// Find an item in an iterator over a sorted collection. |
48392
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
34 |
fn find_item<'a>( |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
35 |
i: &mut PutBack<impl Iterator<Item = Result<ManifestEntry<'a>, HgError>>>, |
48391
10c32e1b892a
rhg: Propogate manifest parse errors instead of panicking
Simon Sapin <simon.sapin@octobus.net>
parents:
48249
diff
changeset
|
36 |
needle: &HgPath, |
48392
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
37 |
) -> Result<Option<Node>, HgError> { |
48237
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
38 |
loop { |
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
39 |
match i.next() { |
48391
10c32e1b892a
rhg: Propogate manifest parse errors instead of panicking
Simon Sapin <simon.sapin@octobus.net>
parents:
48249
diff
changeset
|
40 |
None => return Ok(None), |
10c32e1b892a
rhg: Propogate manifest parse errors instead of panicking
Simon Sapin <simon.sapin@octobus.net>
parents:
48249
diff
changeset
|
41 |
Some(result) => { |
48392
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
42 |
let entry = result?; |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
43 |
match needle.as_bytes().cmp(entry.path.as_bytes()) { |
48391
10c32e1b892a
rhg: Propogate manifest parse errors instead of panicking
Simon Sapin <simon.sapin@octobus.net>
parents:
48249
diff
changeset
|
44 |
Ordering::Less => { |
48392
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
45 |
i.put_back(Ok(entry)); |
48391
10c32e1b892a
rhg: Propogate manifest parse errors instead of panicking
Simon Sapin <simon.sapin@octobus.net>
parents:
48249
diff
changeset
|
46 |
return Ok(None); |
10c32e1b892a
rhg: Propogate manifest parse errors instead of panicking
Simon Sapin <simon.sapin@octobus.net>
parents:
48249
diff
changeset
|
47 |
} |
10c32e1b892a
rhg: Propogate manifest parse errors instead of panicking
Simon Sapin <simon.sapin@octobus.net>
parents:
48249
diff
changeset
|
48 |
Ordering::Greater => continue, |
48392
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
49 |
Ordering::Equal => return Ok(Some(entry.node_id()?)), |
48237
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
50 |
} |
48391
10c32e1b892a
rhg: Propogate manifest parse errors instead of panicking
Simon Sapin <simon.sapin@octobus.net>
parents:
48249
diff
changeset
|
51 |
} |
48237
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
52 |
} |
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
53 |
} |
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
54 |
} |
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
55 |
|
48392
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
56 |
fn find_files_in_manifest<'query>( |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
57 |
manifest: &Manifest, |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
58 |
query: impl Iterator<Item = &'query HgPath>, |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
59 |
) -> Result<(Vec<(&'query HgPath, Node)>, Vec<&'query HgPath>), HgError> { |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
60 |
let mut manifest = put_back(manifest.iter()); |
48237
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
61 |
let mut res = vec![]; |
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
62 |
let mut missing = vec![]; |
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
63 |
|
48249
027ebad952ac
rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48246
diff
changeset
|
64 |
for file in query { |
48391
10c32e1b892a
rhg: Propogate manifest parse errors instead of panicking
Simon Sapin <simon.sapin@octobus.net>
parents:
48249
diff
changeset
|
65 |
match find_item(&mut manifest, file)? { |
48237
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
66 |
None => missing.push(file), |
48249
027ebad952ac
rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48246
diff
changeset
|
67 |
Some(item) => res.push((file, item)), |
48237
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
68 |
} |
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
69 |
} |
48391
10c32e1b892a
rhg: Propogate manifest parse errors instead of panicking
Simon Sapin <simon.sapin@octobus.net>
parents:
48249
diff
changeset
|
70 |
return Ok((res, missing)); |
48237
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
71 |
} |
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
72 |
|
46757
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
73 |
/// Output the given revision of files |
46136
dca9cb99971c
rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46135
diff
changeset
|
74 |
/// |
dca9cb99971c
rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46135
diff
changeset
|
75 |
/// * `root`: Repository root |
dca9cb99971c
rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46135
diff
changeset
|
76 |
/// * `rev`: The revision to cat the files from. |
dca9cb99971c
rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46135
diff
changeset
|
77 |
/// * `files`: The files to output. |
46757
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
78 |
pub fn cat<'a>( |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
46136
diff
changeset
|
79 |
repo: &Repo, |
46501
4b381dbbf8b7
rhg: centralize parsing of `--rev` CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
80 |
revset: &str, |
48249
027ebad952ac
rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48246
diff
changeset
|
81 |
mut files: Vec<&'a HgPath>, |
027ebad952ac
rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48246
diff
changeset
|
82 |
) -> Result<CatOutput<'a>, RevlogError> { |
46501
4b381dbbf8b7
rhg: centralize parsing of `--rev` CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
83 |
let rev = crate::revset::resolve_single(revset, repo)?; |
47992
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47989
diff
changeset
|
84 |
let manifest = repo.manifest_for_rev(rev)?; |
47988
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47987
diff
changeset
|
85 |
let node = *repo |
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47987
diff
changeset
|
86 |
.changelog()? |
46757
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
87 |
.node_from_rev(rev) |
47988
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47987
diff
changeset
|
88 |
.expect("should succeed when repo.manifest did"); |
48249
027ebad952ac
rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48246
diff
changeset
|
89 |
let mut results: Vec<(&'a HgPath, Vec<u8>)> = vec![]; |
46757
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
90 |
let mut found_any = false; |
48237
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
91 |
|
48236
6b5773f89183
rhg: faster hg cat when many files are requested
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
47997
diff
changeset
|
92 |
files.sort_unstable(); |
6b5773f89183
rhg: faster hg cat when many files are requested
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
47997
diff
changeset
|
93 |
|
48237
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
94 |
let (found, missing) = find_files_in_manifest( |
48392
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
95 |
&manifest, |
48249
027ebad952ac
rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48246
diff
changeset
|
96 |
files.into_iter().map(|f| f.as_ref()), |
48391
10c32e1b892a
rhg: Propogate manifest parse errors instead of panicking
Simon Sapin <simon.sapin@octobus.net>
parents:
48249
diff
changeset
|
97 |
)?; |
45547
522ec3dc44b9
hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
98 |
|
48392
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
99 |
for (file_path, file_node) in found { |
48237
0cc69017d47f
rhg: stop manifest traversal when no more files are needed
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48236
diff
changeset
|
100 |
found_any = true; |
48249
027ebad952ac
rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48246
diff
changeset
|
101 |
let file_log = repo.filelog(file_path)?; |
027ebad952ac
rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48246
diff
changeset
|
102 |
results.push(( |
027ebad952ac
rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48246
diff
changeset
|
103 |
file_path, |
48569
20d0d896183e
rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
104 |
file_log.data_for_node(file_node)?.into_file_data()?, |
48249
027ebad952ac
rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48246
diff
changeset
|
105 |
)); |
45547
522ec3dc44b9
hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
106 |
} |
522ec3dc44b9
hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
107 |
|
46757
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
108 |
Ok(CatOutput { |
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
109 |
found_any, |
48249
027ebad952ac
rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48246
diff
changeset
|
110 |
results, |
46757
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
111 |
missing, |
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
112 |
node, |
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46511
diff
changeset
|
113 |
}) |
45547
522ec3dc44b9
hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
114 |
} |