…there really should be control over where to write them exactly
Showing the changes to gitoxide-core/src (1 of 10 files). Show all
Unified · Split
| @@ -1,9 +1,12 @@ | ||
| 1 | 1 | use crate::{remote::refs::JsonRef, OutputFormat, Protocol}; |
| 2 | 2 | use git_features::progress::Progress; |
| 3 | −use git_object::owned; | |
| 3 | +use git_object::{bstr::ByteSlice, owned}; | |
| 4 | 4 | use git_odb::pack; |
| 5 | 5 | use git_protocol::fetch::{Action, Arguments, Ref, Response}; |
| 6 | −use std::{io, io::BufRead, path::PathBuf}; | |
| 6 | +use std::{ | |
| 7 | + io::{self, BufRead}, | |
| 8 | + path::PathBuf, | |
| 9 | +}; | |
| 7 | 10 | |
| 8 | 11 | pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=3; |
| 9 | 12 | |
| @@ -16,6 +19,7 @@ pub struct Context<W: io::Write> { · 6 unmodified lines | ||
| 16 | 19 | struct CloneDelegate<W: io::Write> { |
| 17 | 20 | ctx: Context<W>, |
| 18 | 21 | directory: Option<PathBuf>, |
| 22 | + write_refs: bool, | |
| 19 | 23 | } |
| 20 | 24 | |
| 21 | 25 | impl<W: io::Write> git_protocol::fetch::Delegate for CloneDelegate<W> { |
| @@ -43,8 +47,30 @@ impl<W: io::Write> git_protocol::fetch::Delegate for CloneDelegate<W> { · 21 unmodified lines | ||
| 43 | 47 | index_kind: pack::index::Kind::V2, |
| 44 | 48 | iteration_mode: pack::data::iter::Mode::Verify, |
| 45 | 49 | }; |
| 46 | − let outcome = pack::bundle::Bundle::write_stream_to_directory(input, self.directory.take(), progress, options) | |
| 50 | + let outcome = pack::bundle::Bundle::write_stream_to_directory(input, self.directory.clone(), progress, options) | |
| 47 | 51 | .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; |
| 52 | + | |
| 53 | + if let Some(directory) = self.directory.take() { | |
| 54 | + let assure_dir = |path: &git_object::bstr::BString| { | |
| 55 | + assert!(!path.starts_with_str("/"), "no ref start with a /, they are relative"); | |
| 56 | + let path = directory.join(path.to_path_lossy()); | |
| 57 | + std::fs::create_dir_all(path.parent().expect("multi-component path")).map(|_| path) | |
| 58 | + }; | |
| 59 | + if self.write_refs { | |
| 60 | + for r in refs { | |
| 61 | + match r { | |
| 62 | + Ref::Symbolic { path, target, .. } => { | |
| 63 | + assure_dir(path).map(|path| (path, format!("ref: {}", target))) | |
| 64 | + } | |
| 65 | + Ref::Peeled { path, tag: object, .. } | Ref::Direct { path, object } => { | |
| 66 | + assure_dir(path).map(|path| (path, object.to_string())) | |
| 67 | + } | |
| 68 | + } | |
| 69 | + .and_then(|(path, content)| std::fs::write(path, content.as_bytes()))?; | |
| 70 | + } | |
| 71 | + } | |
| 72 | + } | |
| 73 | + | |
| 48 | 74 | match self.ctx.format { |
| 49 | 75 | OutputFormat::Human => drop(print(&mut self.ctx.out, outcome, refs)), |
| 50 | 76 | #[cfg(feature = "serde1")] |
| @@ -118,6 +144,7 @@ pub fn receive<P, W: io::Write>( · 67 unmodified lines | ||
| 118 | 144 | protocol: Option<Protocol>, |
| 119 | 145 | url: &str, |
| 120 | 146 | directory: Option<PathBuf>, |
| 147 | + write_refs: bool, | |
| 121 | 148 | progress: P, |
| 122 | 149 | ctx: Context<W>, |
| 123 | 150 | ) -> anyhow::Result<()> |
| @@ -127,7 +154,11 @@ where · 3 unmodified lines | ||
| 127 | 154 | <<P as Progress>::SubProgress as Progress>::SubProgress: Send, |
| 128 | 155 | { |
| 129 | 156 | let transport = git_protocol::git_transport::client::connect(url.as_bytes(), protocol.unwrap_or_default().into())?; |
| 130 | − let mut delegate = CloneDelegate { ctx, directory }; | |
| 157 | + let mut delegate = CloneDelegate { | |
| 158 | + ctx, | |
| 159 | + directory, | |
| 160 | + write_refs, | |
| 161 | + }; | |
| 131 | 162 | git_protocol::fetch(transport, &mut delegate, git_protocol::credentials::helper, progress)?; |
| 132 | 163 | Ok(()) |
| 133 | 164 | } |