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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }