Skip to content

Commit

Permalink
feat: Repository::is_shallow() to test if a repository is shallow.
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Mar 5, 2023
1 parent cf620f8 commit 2b677cf
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 5 deletions.
9 changes: 9 additions & 0 deletions gix/src/config/cache/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,15 @@ fn apply_environment_overrides(
},
],
),
(
"gitoxide",
Some(Cow::Borrowed("core".into())),
git_prefix,
&[{
let key = &gitoxide::Core::SHALLOW_FILE;
(env(key), key.name)
}],
),
(
"gitoxide",
Some(Cow::Borrowed("author".into())),
Expand Down
32 changes: 28 additions & 4 deletions gix/src/config/tree/sections/gitoxide.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use crate::config;
use crate::config::tree::{keys, Gitoxide, Key, Section};

impl Gitoxide {
/// The `gitoxide.allow` section.
pub const ALLOW: Allow = Allow;
/// The `gitoxide.author` section.
pub const AUTHOR: Author = Author;
/// The `gitoxide.core` section.
pub const CORE: Core = Core;
/// The `gitoxide.commit` section.
pub const COMMIT: Commit = Commit;
/// The `gitoxide.committer` section.
Expand Down Expand Up @@ -39,6 +42,7 @@ impl Section for Gitoxide {
&[
&Self::ALLOW,
&Self::AUTHOR,
&Self::CORE,
&Self::COMMIT,
&Self::COMMITTER,
&Self::HTTP,
Expand All @@ -56,6 +60,29 @@ mod subsections {
Tree,
};

/// The `Core` sub-section.
#[derive(Copy, Clone, Default)]
pub struct Core;

impl Core {
/// The `gitoxide.core.shallowFile` key.
pub const SHALLOW_FILE: keys::Path = keys::Path::new_path("shallowFile", &Gitoxide::CORE)
.with_environment_override("GIT_SHALLOW_FILE")
.with_deviation(
"relative file paths will always be made relative to the git-common-dir, whereas `git` keeps them as is.",
);
}

impl Section for Core {
fn name(&self) -> &str {
"core"
}

fn keys(&self) -> &[&dyn Key] {
&[&Self::SHALLOW_FILE]
}
}

/// The `Http` sub-section.
#[derive(Copy, Clone, Default)]
pub struct Http;
Expand Down Expand Up @@ -341,6 +368,7 @@ mod subsections {
}
}
}
pub use subsections::{Allow, Author, Commit, Committer, Core, Http, Https, Objects, Ssh, User};

pub mod validate {
use std::error::Error;
Expand All @@ -357,7 +385,3 @@ pub mod validate {
}
}
}

pub use subsections::{Allow, Author, Commit, Committer, Http, Https, Objects, Ssh, User};

use crate::config;
16 changes: 16 additions & 0 deletions gix/src/repository/location.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::borrow::Cow;
use std::path::PathBuf;

use crate::config::tree::{gitoxide, Key};
use gix_path::realpath::MAX_SYMLINKS;

impl crate::Repository {
Expand Down Expand Up @@ -41,6 +43,20 @@ impl crate::Repository {
crate::path::install_dir()
}

/// Return the path to the `shallow` file which contains hashes, one per line, that describe commits that don't have their
/// parents within this repository.
pub fn shallow_file(&self) -> PathBuf {
let shallow_name = self
.config
.resolved
.string_filter_by_key(
gitoxide::Core::SHALLOW_FILE.logical_name().as_str(),
&mut self.filter_config_section(),
)
.unwrap_or(Cow::Borrowed("shallow".into()));
self.common_dir().join(gix_path::from_bstr(shallow_name))
}

/// Returns the relative path which is the components between the working tree and the current working dir (CWD).
/// Note that there may be `None` if there is no work tree, even though the `PathBuf` will be empty
/// if the CWD is at the root of the work tree.
Expand Down
7 changes: 7 additions & 0 deletions gix/src/repository/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,11 @@ impl crate::Repository {
None
}
}

/// Return `true` if the repository is a shallow clone, i.e. contains history only up to a certain depth.
pub fn is_shallow(&self) -> bool {
self.shallow_file()
.symlink_metadata()
.map_or(false, |m| m.is_file() && m.len() > 0)
}
}
Git LFS file not shown
28 changes: 28 additions & 0 deletions gix/tests/fixtures/make_shallow_repo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash
set -eu -o pipefail

mkdir base
(cd base
git init -q

git checkout -b main
touch a && git add a
git commit -q -m c1
echo 1 >> a
git commit -q -am c2
echo 1 >> a
git commit -q -am c3
)

mkdir empty
(cd empty
git init -q

git checkout -b main
touch a && git add a
git commit -q -m c1
touch .git/shallow
)

git clone --depth 1 --bare file://$PWD/base shallow.git
git clone --depth 1 file://$PWD/base shallow
15 changes: 14 additions & 1 deletion gix/tests/repository/open.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ mod with_overrides {
.set("GIT_SSL_VERSION", "tlsv1.3")
.set("GIT_SSH_VARIANT", "ssh-variant-env")
.set("GIT_SSH_COMMAND", "ssh-command-env")
.set("GIT_SSH", "ssh-command-fallback-env");
.set("GIT_SSH", "ssh-command-fallback-env")
.set("GIT_SHALLOW_FILE", "shallow-file-env");
let mut opts = gix::open::Options::isolated()
.cli_overrides([
"http.userAgent=agent-from-cli",
Expand All @@ -206,6 +207,7 @@ mod with_overrides {
"core.sshCommand=ssh-command-cli",
"gitoxide.ssh.commandWithoutShellFallback=ssh-command-fallback-cli",
"gitoxide.http.proxyAuthMethod=proxy-auth-method-cli",
"gitoxide.core.shallowFile=shallow-file-cli",
])
.config_overrides([
"http.userAgent=agent-from-api",
Expand All @@ -217,6 +219,7 @@ mod with_overrides {
"core.sshCommand=ssh-command-api",
"gitoxide.ssh.commandWithoutShellFallback=ssh-command-fallback-api",
"gitoxide.http.proxyAuthMethod=proxy-auth-method-api",
"gitoxide.core.shallowFile=shallow-file-api",
]);
opts.permissions.env.git_prefix = Permission::Allow;
opts.permissions.env.http_transport = Permission::Allow;
Expand All @@ -229,6 +232,16 @@ mod with_overrides {
"config always refers to the local one for safety"
);
let config = repo.config_snapshot();
assert_eq!(
config
.strings_by_key("gitoxide.core.shallowFile")
.expect("at least one value"),
[
cow_bstr("shallow-file-cli"),
cow_bstr("shallow-file-api"),
cow_bstr("shallow-file-env")
]
);
assert_eq!(
config.strings_by_key("http.userAgent").expect("at least one value"),
[
Expand Down
22 changes: 22 additions & 0 deletions gix/tests/repository/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,25 @@ fn revert_sequence() -> Result {

Ok(())
}

mod shallow {
use crate::util::named_subrepo_opts;

#[test]
fn without() -> crate::Result {
for name in ["base", "empty"] {
let repo = named_subrepo_opts("make_shallow_repo.sh", name, gix::open::Options::isolated())?;
assert!(!repo.is_shallow());
}
Ok(())
}

#[test]
fn with() -> crate::Result {
for name in ["shallow.git", "shallow"] {
let repo = named_subrepo_opts("make_shallow_repo.sh", name, gix::open::Options::isolated())?;
assert!(repo.is_shallow());
}
Ok(())
}
}

0 comments on commit 2b677cf

Please sign in to comment.