Skip to main content

git_xcrypt/commands/
process.rs

1//! `git-xcrypt process` — the entry point git itself calls.
2//!
3//! Registered by `init` as `filter.git-xcrypt.process`. Everything it writes to
4//! `stdout` is protocol; diagnostics go to `stderr` and nowhere else.
5
6use std::io;
7
8use crate::Result;
9use crate::commands::filter::{self, Context};
10use crate::git::repo::Repo;
11
12/// Serves git's filter protocol until the stream closes.
13///
14/// # Errors
15///
16/// [`crate::Error::Config`] when the repository or `.git-xcrypt` cannot be read,
17/// [`crate::Error::Io`] on a broken pipe.
18pub fn run() -> Result<()> {
19    let repo = Repo::discover_from_cwd()?;
20    let mut context = Context::load(&repo)?;
21
22    let mut input = io::stdin().lock();
23    // `BufWriter`, not the bare lock: `StdoutLock` is line buffered, and
24    // ciphertext is uniformly random, so roughly one byte in 256 is `\n` and
25    // would force a syscall. This is the path whose entire justification is the
26    // 22× measurement. `pktline::write_flush` still forces the real flush at
27    // every point the protocol requires one.
28    let mut output = io::BufWriter::new(io::stdout().lock());
29    filter::run(&mut context, &mut input, &mut output)
30}