Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 445be27

Browse files
committed
[clone] First version of writing references, but…
…there really should be control over where to write them exactly
1 parent 354e63f commit 445be27

10 files changed

Lines changed: 60 additions & 4 deletions

File tree

gitoxide-core/src/pack/receive.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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> {
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> {
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>(
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
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,14 @@ pub fn main() -> Result<()> {
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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ pub struct PackReceive {
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ pub fn main() -> Result<()> {
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<()> {
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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ pub enum Subcommands {
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
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ee3c97678e89db4eab7420b04aef51758359f152
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3f72b39ad1600e6dac63430c15e0d875e9d3f9d6
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
feae03400632392a7f38e5b2775f98a439f5eaf5
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
efa596d621559707b2d221f10490959b2decbc6c

tests/stateless-journey.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,15 @@ snapshot="$snapshot/plumbing"
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"

0 commit comments

Comments
 (0)