History

[clone] First version of writing references, but…

…there really should be control over where to write them exactly

Sebastian Thiel committed 6 years ago

Commit 445be271 parent 354e63f10 files · +60 −4Browse files

Showing the changes to gitoxide-core/src (1 of 10 files). Show all

Unified · Split

gitoxide-core/src/pack/receive.rs+35−4
@@ -1,9 +1,12 @@
11 use crate::{remote::refs::JsonRef, OutputFormat, Protocol};
22 use git_features::progress::Progress;
3−use git_object::owned;
3+use git_object::{bstr::ByteSlice, owned};
44 use git_odb::pack;
55 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+};
710
811 pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=3;
912
@@ -16,6 +19,7 @@ pub struct Context<W: io::Write> { · 6 unmodified lines
1619 struct CloneDelegate<W: io::Write> {
1720 ctx: Context<W>,
1821 directory: Option<PathBuf>,
22+ write_refs: bool,
1923 }
2024
2125 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
4347 index_kind: pack::index::Kind::V2,
4448 iteration_mode: pack::data::iter::Mode::Verify,
4549 };
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)
4751 .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+
4874 match self.ctx.format {
4975 OutputFormat::Human => drop(print(&mut self.ctx.out, outcome, refs)),
5076 #[cfg(feature = "serde1")]
@@ -118,6 +144,7 @@ pub fn receive<P, W: io::Write>( · 67 unmodified lines
118144 protocol: Option<Protocol>,
119145 url: &str,
120146 directory: Option<PathBuf>,
147+ write_refs: bool,
121148 progress: P,
122149 ctx: Context<W>,
123150 ) -> anyhow::Result<()>
@@ -127,7 +154,11 @@ where · 3 unmodified lines
127154 <<P as Progress>::SubProgress as Progress>::SubProgress: Send,
128155 {
129156 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+ };
131162 git_protocol::fetch(transport, &mut delegate, git_protocol::credentials::helper, progress)?;
132163 Ok(())
133164 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t