Mercurial > public > mercurial-scm > hg-stable
annotate rust/hg-core/src/operations/cat.rs @ 48605:a809f1465a76
filemerge: set default labels a little earlier
By setting the default labels a little earlier, we can rely on them
always being set, as far as I can tell. It may actually even be fine
to rely on that even if we don't set them earlier, but it makes more
sense to me to do it.
Differential Revision: https://phab.mercurial-scm.org/D12015
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Thu, 20 Jan 2022 13:43:43 -0800 |
parents | 20d0d896183e |
children | 49131579db62 |
rev | line source |
---|---|
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 } |