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 @@
1use crate::{remote::refs::JsonRef, OutputFormat, Protocol};1use crate::{remote::refs::JsonRef, OutputFormat, Protocol};
2use git_features::progress::Progress;2use git_features::progress::Progress;
3use git_object::owned;3use git_object::{bstr::ByteSlice, owned};
4use git_odb::pack;4use git_odb::pack;
5use git_protocol::fetch::{Action, Arguments, Ref, Response};5use git_protocol::fetch::{Action, Arguments, Ref, Response};
6use std::{io, io::BufRead, path::PathBuf};6use std::{
7 io::{self, BufRead},
8 path::PathBuf,
9};
7 10
8pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=3;11pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=3;
9 12
@@ -16,6 +19,7 @@ pub struct Context<W: io::Write> { · 6 unmodified lines
16struct CloneDelegate<W: io::Write> {19struct CloneDelegate<W: io::Write> {
17 ctx: Context<W>,20 ctx: Context<W>,
18 directory: Option<PathBuf>,21 directory: Option<PathBuf>,
22 write_refs: bool,
19}23}
20 24
21impl<W: io::Write> git_protocol::fetch::Delegate for CloneDelegate<W> {25impl<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 index_kind: pack::index::Kind::V2,47 index_kind: pack::index::Kind::V2,
44 iteration_mode: pack::data::iter::Mode::Verify,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 .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;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 match self.ctx.format {74 match self.ctx.format {
49 OutputFormat::Human => drop(print(&mut self.ctx.out, outcome, refs)),75 OutputFormat::Human => drop(print(&mut self.ctx.out, outcome, refs)),
50 #[cfg(feature = "serde1")]76 #[cfg(feature = "serde1")]
@@ -118,6 +144,7 @@ pub fn receive<P, W: io::Write>( · 67 unmodified lines
118 protocol: Option<Protocol>,144 protocol: Option<Protocol>,
119 url: &str,145 url: &str,
120 directory: Option<PathBuf>,146 directory: Option<PathBuf>,
147 write_refs: bool,
121 progress: P,148 progress: P,
122 ctx: Context<W>,149 ctx: Context<W>,
123) -> anyhow::Result<()>150) -> anyhow::Result<()>
@@ -127,7 +154,11 @@ where · 3 unmodified lines
127 <<P as Progress>::SubProgress as Progress>::SubProgress: Send,154 <<P as Progress>::SubProgress as Progress>::SubProgress: Send,
128{155{
129 let transport = git_protocol::git_transport::client::connect(url.as_bytes(), protocol.unwrap_or_default().into())?;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 git_protocol::fetch(transport, &mut delegate, git_protocol::credentials::helper, progress)?;162 git_protocol::fetch(transport, &mut delegate, git_protocol::credentials::helper, progress)?;
132 Ok(())163 Ok(())
133}164}
src/plumbing/lean/main.rs+2−0
@@ -53,12 +53,14 @@ pub fn main() -> Result<()> { · 52 unmodified lines
53 protocol,53 protocol,
54 url,54 url,
55 directory,55 directory,
56 write_refs,
56 }) => {57 }) => {
57 let (_handle, progress) = prepare(verbose, "pack-receive", core::pack::receive::PROGRESS_RANGE);58 let (_handle, progress) = prepare(verbose, "pack-receive", core::pack::receive::PROGRESS_RANGE);
58 core::pack::receive(59 core::pack::receive(
59 protocol,60 protocol,
60 &url,61 &url,
61 directory,62 directory,
63 write_refs,
62 progress::DoOrDiscard::from(progress),64 progress::DoOrDiscard::from(progress),
63 core::pack::receive::Context {65 core::pack::receive::Context {
64 thread_limit,66 thread_limit,
src/plumbing/lean/options.rs+4−0
@@ -92,6 +92,10 @@ pub struct PackReceive { · 91 unmodified lines
92 #[argh(option, short = 'p')]92 #[argh(option, short = 'p')]
93 pub protocol: Option<core::Protocol>,93 pub protocol: Option<core::Protocol>,
94 94
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
95 /// the URLs or path from which to receive the pack.99 /// the URLs or path from which to receive the pack.
96 ///100 ///
97 /// See here for a list of supported URLs: https://www.git-scm.com/docs/git-clone#_git_urls101 /// 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
127 match cmd {127 match cmd {
128 Subcommands::PackReceive {128 Subcommands::PackReceive {
129 protocol,129 protocol,
130 write_refs,
130 url,131 url,
131 directory,132 directory,
132 } => prepare_and_run(133 } => prepare_and_run(
@@ -140,6 +141,7 @@ pub fn main() -> Result<()> { · 7 unmodified lines
140 protocol,141 protocol,
141 &url,142 &url,
142 directory,143 directory,
144 write_refs,
143 git_features::progress::DoOrDiscard::from(progress),145 git_features::progress::DoOrDiscard::from(progress),
144 core::pack::receive::Context {146 core::pack::receive::Context {
145 thread_limit,147 thread_limit,
src/plumbing/pretty/options.rs+4−0
@@ -49,6 +49,10 @@ pub enum Subcommands { · 48 unmodified lines
49 #[clap(long, short = "p")]49 #[clap(long, short = "p")]
50 protocol: Option<core::Protocol>,50 protocol: Option<core::Protocol>,
51 51
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
52 /// The URLs or path from which to receive the pack.56 /// The URLs or path from which to receive the pack.
53 ///57 ///
54 /// See here for a list of supported URLs: https://www.git-scm.com/docs/git-clone#_git_urls58 /// 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 @@
1ee3c97678e89db4eab7420b04aef51758359f152
tests/snapshots/plumbing/pack-receive/repo-refs/heads/master+1−0
@@ -0,0 +1 @@
13f72b39ad1600e6dac63430c15e0d875e9d3f9d6
tests/snapshots/plumbing/pack-receive/repo-refs/tags/annotated+1−0
@@ -0,0 +1 @@
1feae03400632392a7f38e5b2775f98a439f5eaf5
tests/snapshots/plumbing/pack-receive/repo-refs/tags/unannotated+1−0
@@ -0,0 +1 @@
1efa596d621559707b2d221f10490959b2decbc6c
tests/stateless-journey.sh+9−0
@@ -106,6 +106,15 @@ snapshot="$snapshot/plumbing" · 105 unmodified lines
106 WITH_SNAPSHOT="$snapshot/ls-in-output-dir" \106 WITH_SNAPSHOT="$snapshot/ls-in-output-dir" \
107 expect_run $SUCCESSFULLY ls out/107 expect_run $SUCCESSFULLY ls out/
108 }108 }
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 )
109 )118 )
110 if test "$kind" = "max"; then119 if test "$kind" = "max"; then
111 (with "--format json"120 (with "--format json"