rust/hg-core/src/operations/cat.rs
author Simon Sapin <simon.sapin@octobus.net>
Wed, 27 Jan 2021 14:45:25 +0100
changeset 46443 43d63979a75e
parent 46437 b274aa2f20fd
child 46744 b1f2c2b336ec
permissions -rw-r--r--
rust: use HgError in RevlogError and Vfs Differential Revision: https://phab.mercurial-scm.org/D9897
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
45541
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: 46135
diff changeset
     8
use std::path::PathBuf;
45541
522ec3dc44b9 hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
     9
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46135
diff changeset
    10
use crate::repo::Repo;
45541
522ec3dc44b9 hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    11
use crate::revlog::changelog::Changelog;
46135
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    12
use crate::revlog::manifest::Manifest;
45541
522ec3dc44b9 hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    13
use crate::revlog::path_encode::path_encode;
522ec3dc44b9 hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    14
use crate::revlog::revlog::Revlog;
522ec3dc44b9 hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    15
use crate::revlog::revlog::RevlogError;
46033
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 46032
diff changeset
    16
use crate::revlog::Node;
45806
7252f5237352 hg-core: fix path encoding usage
Antoine cezar<acezar@chwitlabs.fr>
parents: 45804
diff changeset
    17
use crate::utils::files::get_path_from_bytes;
7252f5237352 hg-core: fix path encoding usage
Antoine cezar<acezar@chwitlabs.fr>
parents: 45804
diff changeset
    18
use crate::utils::hg_path::{HgPath, HgPathBuf};
45541
522ec3dc44b9 hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    19
45804
6991f3014311 rhg: strip copied files metadata from `cat` output
Antoine cezar<acezar@chwitlabs.fr>
parents: 45541
diff changeset
    20
const METADATA_DELIMITER: [u8; 2] = [b'\x01', b'\n'];
6991f3014311 rhg: strip copied files metadata from `cat` output
Antoine cezar<acezar@chwitlabs.fr>
parents: 45541
diff changeset
    21
45541
522ec3dc44b9 hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    22
/// List files under Mercurial control at a given revision.
46135
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    23
///
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    24
/// * `root`: Repository root
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    25
/// * `rev`: The revision to cat the files from.
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    26
/// * `files`: The files to output.
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    27
pub fn cat(
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46135
diff changeset
    28
    repo: &Repo,
46433
4b381dbbf8b7 rhg: centralize parsing of `--rev` CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46431
diff changeset
    29
    revset: &str,
46135
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    30
    files: &[HgPathBuf],
46437
b274aa2f20fd rust: remove three enums that were identical to `RevlogError`
Simon Sapin <simon.sapin@octobus.net>
parents: 46434
diff changeset
    31
) -> Result<Vec<u8>, RevlogError> {
46433
4b381dbbf8b7 rhg: centralize parsing of `--rev` CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46431
diff changeset
    32
    let rev = crate::revset::resolve_single(revset, repo)?;
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46135
diff changeset
    33
    let changelog = Changelog::open(repo)?;
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46135
diff changeset
    34
    let manifest = Manifest::open(repo)?;
46433
4b381dbbf8b7 rhg: centralize parsing of `--rev` CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46431
diff changeset
    35
    let changelog_entry = changelog.get_rev(rev)?;
46443
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46437
diff changeset
    36
    let manifest_node =
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46437
diff changeset
    37
        Node::from_hex_for_repo(&changelog_entry.manifest_node()?)?;
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46167
diff changeset
    38
    let manifest_entry = manifest.get_node(manifest_node.into())?;
46135
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    39
    let mut bytes = vec![];
45541
522ec3dc44b9 hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    40
46135
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    41
    for (manifest_file, node_bytes) in manifest_entry.files_with_nodes() {
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    42
        for cat_file in files.iter() {
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    43
            if cat_file.as_bytes() == manifest_file.as_bytes() {
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46135
diff changeset
    44
                let index_path = store_path(manifest_file, b".i");
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46135
diff changeset
    45
                let data_path = store_path(manifest_file, b".d");
45541
522ec3dc44b9 hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    46
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46135
diff changeset
    47
                let file_log =
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46135
diff changeset
    48
                    Revlog::open(repo, &index_path, Some(&data_path))?;
46443
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46437
diff changeset
    49
                let file_node = Node::from_hex_for_repo(node_bytes)?;
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46167
diff changeset
    50
                let file_rev = file_log.get_node_rev(file_node.into())?;
46135
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    51
                let data = file_log.get_rev_data(file_rev)?;
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    52
                if data.starts_with(&METADATA_DELIMITER) {
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    53
                    let end_delimiter_position = data
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    54
                        [METADATA_DELIMITER.len()..]
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    55
                        .windows(METADATA_DELIMITER.len())
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    56
                        .position(|bytes| bytes == METADATA_DELIMITER);
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    57
                    if let Some(position) = end_delimiter_position {
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    58
                        let offset = METADATA_DELIMITER.len() * 2;
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    59
                        bytes.extend(data[position + offset..].iter());
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    60
                    }
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    61
                } else {
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    62
                    bytes.extend(data);
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    63
                }
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    64
            }
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    65
        }
45541
522ec3dc44b9 hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    66
    }
522ec3dc44b9 hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    67
46135
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46134
diff changeset
    68
    Ok(bytes)
45541
522ec3dc44b9 hg-core: add a `CatRev` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    69
}
45806
7252f5237352 hg-core: fix path encoding usage
Antoine cezar<acezar@chwitlabs.fr>
parents: 45804
diff changeset
    70
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46135
diff changeset
    71
fn store_path(hg_path: &HgPath, suffix: &[u8]) -> PathBuf {
45806
7252f5237352 hg-core: fix path encoding usage
Antoine cezar<acezar@chwitlabs.fr>
parents: 45804
diff changeset
    72
    let encoded_bytes =
7252f5237352 hg-core: fix path encoding usage
Antoine cezar<acezar@chwitlabs.fr>
parents: 45804
diff changeset
    73
        path_encode(&[b"data/", hg_path.as_bytes(), suffix].concat());
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46135
diff changeset
    74
    get_path_from_bytes(&encoded_bytes).into()
45806
7252f5237352 hg-core: fix path encoding usage
Antoine cezar<acezar@chwitlabs.fr>
parents: 45804
diff changeset
    75
}