Skip to content

Commit

Permalink
[clone] First version of writing references, but…
Browse files Browse the repository at this point in the history
…there really should be control over where to write them exactly
  • Loading branch information
Byron committed Sep 11, 2020
1 parent 354e63f commit 445be27
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 4 deletions.
39 changes: 35 additions & 4 deletions gitoxide-core/src/pack/receive.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use crate::{remote::refs::JsonRef, OutputFormat, Protocol};
use git_features::progress::Progress;
use git_object::owned;
use git_object::{bstr::ByteSlice, owned};
use git_odb::pack;
use git_protocol::fetch::{Action, Arguments, Ref, Response};
use std::{io, io::BufRead, path::PathBuf};
use std::{
io::{self, BufRead},
path::PathBuf,
};

pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=3;

Expand All @@ -16,6 +19,7 @@ pub struct Context<W: io::Write> {
struct CloneDelegate<W: io::Write> {
ctx: Context<W>,
directory: Option<PathBuf>,
write_refs: bool,
}

impl<W: io::Write> git_protocol::fetch::Delegate for CloneDelegate<W> {
Expand Down Expand Up @@ -43,8 +47,30 @@ impl<W: io::Write> git_protocol::fetch::Delegate for CloneDelegate<W> {
index_kind: pack::index::Kind::V2,
iteration_mode: pack::data::iter::Mode::Verify,
};
let outcome = pack::bundle::Bundle::write_stream_to_directory(input, self.directory.take(), progress, options)
let outcome = pack::bundle::Bundle::write_stream_to_directory(input, self.directory.clone(), progress, options)
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;

if let Some(directory) = self.directory.take() {
let assure_dir = |path: &git_object::bstr::BString| {
assert!(!path.starts_with_str("/"), "no ref start with a /, they are relative");
let path = directory.join(path.to_path_lossy());
std::fs::create_dir_all(path.parent().expect("multi-component path")).map(|_| path)
};
if self.write_refs {
for r in refs {
match r {
Ref::Symbolic { path, target, .. } => {
assure_dir(path).map(|path| (path, format!("ref: {}", target)))
}
Ref::Peeled { path, tag: object, .. } | Ref::Direct { path, object } => {
assure_dir(path).map(|path| (path, object.to_string()))
}
}
.and_then(|(path, content)| std::fs::write(path, content.as_bytes()))?;
}
}
}

match self.ctx.format {
OutputFormat::Human => drop(print(&mut self.ctx.out, outcome, refs)),
#[cfg(feature = "serde1")]
Expand Down Expand Up @@ -118,6 +144,7 @@ pub fn receive<P, W: io::Write>(
protocol: Option<Protocol>,
url: &str,
directory: Option<PathBuf>,
write_refs: bool,
progress: P,
ctx: Context<W>,
) -> anyhow::Result<()>
Expand All @@ -127,7 +154,11 @@ where
<<P as Progress>::SubProgress as Progress>::SubProgress: Send,
{
let transport = git_protocol::git_transport::client::connect(url.as_bytes(), protocol.unwrap_or_default().into())?;
let mut delegate = CloneDelegate { ctx, directory };
let mut delegate = CloneDelegate {
ctx,
directory,
write_refs,
};
git_protocol::fetch(transport, &mut delegate, git_protocol::credentials::helper, progress)?;
Ok(())
}
2 changes: 2 additions & 0 deletions src/plumbing/lean/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,14 @@ pub fn main() -> Result<()> {
protocol,
url,
directory,
write_refs,
}) => {
let (_handle, progress) = prepare(verbose, "pack-receive", core::pack::receive::PROGRESS_RANGE);
core::pack::receive(
protocol,
&url,
directory,
write_refs,
progress::DoOrDiscard::from(progress),
core::pack::receive::Context {
thread_limit,
Expand Down
4 changes: 4 additions & 0 deletions src/plumbing/lean/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ pub struct PackReceive {
#[argh(option, short = 'p')]
pub protocol: Option<core::Protocol>,

/// write references to the given directory as well, right next to the pack and index file.
#[argh(switch, short = 'r')]
pub write_refs: bool,

/// the URLs or path from which to receive the pack.
///
/// See here for a list of supported URLs: https://www.git-scm.com/docs/git-clone#_git_urls
Expand Down
2 changes: 2 additions & 0 deletions src/plumbing/pretty/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ pub fn main() -> Result<()> {
match cmd {
Subcommands::PackReceive {
protocol,
write_refs,
url,
directory,
} => prepare_and_run(
Expand All @@ -140,6 +141,7 @@ pub fn main() -> Result<()> {
protocol,
&url,
directory,
write_refs,
git_features::progress::DoOrDiscard::from(progress),
core::pack::receive::Context {
thread_limit,
Expand Down
4 changes: 4 additions & 0 deletions src/plumbing/pretty/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ pub enum Subcommands {
#[clap(long, short = "p")]
protocol: Option<core::Protocol>,

/// Write references to the given directory as well, right next to the pack and index file.
#[clap(long, short = "r")]
write_refs: bool,

/// The URLs or path from which to receive the pack.
///
/// See here for a list of supported URLs: https://www.git-scm.com/docs/git-clone#_git_urls
Expand Down
1 change: 1 addition & 0 deletions tests/snapshots/plumbing/pack-receive/repo-refs/heads/dev
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ee3c97678e89db4eab7420b04aef51758359f152
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3f72b39ad1600e6dac63430c15e0d875e9d3f9d6
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
feae03400632392a7f38e5b2775f98a439f5eaf5
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
efa596d621559707b2d221f10490959b2decbc6c
9 changes: 9 additions & 0 deletions tests/stateless-journey.sh
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,15 @@ snapshot="$snapshot/plumbing"
WITH_SNAPSHOT="$snapshot/ls-in-output-dir" \
expect_run $SUCCESSFULLY ls out/
}
(with "--write-refs set"
it "generates the correct output" && {
WITH_SNAPSHOT="$snapshot/file-v-any-with-output" \
expect_run $SUCCESSFULLY "$exe_plumbing" pack-receive -p 1 --write-refs .git out/
}
it "writes references into the refs folder of the output directory" && {
expect_snapshot "$snapshot/repo-refs" out/refs
}
)
)
if test "$kind" = "max"; then
(with "--format json"
Expand Down

0 comments on commit 445be27

Please sign in to comment.