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

Unified · Split

10 files
  1. gitoxide-core/src/pack/receive.rs +35 −4
  2. src/plumbing/lean/main.rs +2 −0
  3. src/plumbing/lean/options.rs +4 −0
  4. src/plumbing/pretty/main.rs +2 −0
  5. src/plumbing/pretty/options.rs +4 −0
  6. tests/snapshots/plumbing/pack-receive/repo-refs/heads/dev +1 −0
  7. tests/snapshots/plumbing/pack-receive/repo-refs/heads/master +1 −0
  8. tests/snapshots/plumbing/pack-receive/repo-refs/tags/annotated +1 −0
  9. tests/snapshots/plumbing/pack-receive/repo-refs/tags/unannotated +1 −0
  10. tests/stateless-journey.sh +9 −0
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 }
src/plumbing/lean/main.rs+2−0
@@ -53,12 +53,14 @@ pub fn main() -> Result<()> { · 52 unmodified lines
5353 protocol,
5454 url,
5555 directory,
56+ write_refs,
5657 }) => {
5758 let (_handle, progress) = prepare(verbose, "pack-receive", core::pack::receive::PROGRESS_RANGE);
5859 core::pack::receive(
5960 protocol,
6061 &url,
6162 directory,
63+ write_refs,
6264 progress::DoOrDiscard::from(progress),
6365 core::pack::receive::Context {
6466 thread_limit,
src/plumbing/lean/options.rs+4−0
@@ -92,6 +92,10 @@ pub struct PackReceive { · 91 unmodified lines
9292 #[argh(option, short = 'p')]
9393 pub protocol: Option<core::Protocol>,
9494
95+ /// write references to the given directory as well, right next to the pack and index file.
96+ #[argh(switch, short = 'r')]
97+ pub write_refs: bool,
98+
9599 /// the URLs or path from which to receive the pack.
96100 ///
97101 /// See here for a list of supported URLs: https://www.git-scm.com/docs/git-clone#_git_urls
src/plumbing/pretty/main.rs+2−0
@@ -127,6 +127,7 @@ pub fn main() -> Result<()> { · 126 unmodified lines
127127 match cmd {
128128 Subcommands::PackReceive {
129129 protocol,
130+ write_refs,
130131 url,
131132 directory,
132133 } => prepare_and_run(
@@ -140,6 +141,7 @@ pub fn main() -> Result<()> { · 7 unmodified lines
140141 protocol,
141142 &url,
142143 directory,
144+ write_refs,
143145 git_features::progress::DoOrDiscard::from(progress),
144146 core::pack::receive::Context {
145147 thread_limit,
src/plumbing/pretty/options.rs+4−0
@@ -49,6 +49,10 @@ pub enum Subcommands { · 48 unmodified lines
4949 #[clap(long, short = "p")]
5050 protocol: Option<core::Protocol>,
5151
52+ /// Write references to the given directory as well, right next to the pack and index file.
53+ #[clap(long, short = "r")]
54+ write_refs: bool,
55+
5256 /// The URLs or path from which to receive the pack.
5357 ///
5458 /// See here for a list of supported URLs: https://www.git-scm.com/docs/git-clone#_git_urls
tests/snapshots/plumbing/pack-receive/repo-refs/heads/dev+1−0
@@ -0,0 +1 @@
1+ee3c97678e89db4eab7420b04aef51758359f152
tests/snapshots/plumbing/pack-receive/repo-refs/heads/master+1−0
@@ -0,0 +1 @@
1+3f72b39ad1600e6dac63430c15e0d875e9d3f9d6
tests/snapshots/plumbing/pack-receive/repo-refs/tags/annotated+1−0
@@ -0,0 +1 @@
1+feae03400632392a7f38e5b2775f98a439f5eaf5
tests/snapshots/plumbing/pack-receive/repo-refs/tags/unannotated+1−0
@@ -0,0 +1 @@
1+efa596d621559707b2d221f10490959b2decbc6c
tests/stateless-journey.sh+9−0
@@ -106,6 +106,15 @@ snapshot="$snapshot/plumbing" · 105 unmodified lines
106106 WITH_SNAPSHOT="$snapshot/ls-in-output-dir" \
107107 expect_run $SUCCESSFULLY ls out/
108108 }
109+ (with "--write-refs set"
110+ it "generates the correct output" && {
111+ WITH_SNAPSHOT="$snapshot/file-v-any-with-output" \
112+ expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 1 --write-refs .git out/
113+ }
114+ it "writes references into the refs folder of the output directory" && {
115+ expect_snapshot "$snapshot/repo-refs" out/refs
116+ }
117+ )
109118 )
110119 if test "$kind" = "max"; then
111120 (with "--format json"