Skip to content

repo state tests prior to merge #392

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Apr 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- name: Setup dependencies (macos)
if: startsWith(matrix.os, 'macos')
run:
brew install tree openssl
brew install tree openssl gnu-sed
- name: "cargo check default features"
if: startsWith(matrix.os, 'windows')
uses: actions-rs/cargo@v1
Expand Down
35 changes: 35 additions & 0 deletions git-repository/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,41 @@ pub mod init {
}
}

/// Not to be confused with 'status'.
pub mod state {
/// Tell what operation is currently in progress.
#[derive(Debug, PartialEq)]
pub enum InProgress {
/// A mailbox is being applied.
// TODO: test
ApplyMailbox,
/// A rebase is happening while a mailbox is being applied.
// TODO: test
ApplyMailboxRebase,
/// A git bisect operation has not yet been concluded.
// TODO: test
Bisect,
/// A cherry pick operation.
CherryPick,
/// A cherry pick with multiple commits pending.
// TODO: test
CherryPickSequence,
/// A merge operation.
// TODO: test
Merge,
/// A rebase operation.
// TODO: test
Rebase,
/// An interactive rebase operation.
RebaseInteractive,
/// A revert operation.
Revert,
/// A revert operation with multiple commits pending.
// TODO: test
RevertSequence,
}
}

///
pub mod discover {
use crate::{path, ThreadSafeRepository};
Expand Down
2 changes: 2 additions & 0 deletions git-repository/src/repository/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ mod location;

mod snapshots;

mod state;

mod impls;

mod cache;
Expand Down
42 changes: 42 additions & 0 deletions git-repository/src/repository/state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use crate::state;

impl crate::Repository {
/// Returns the status of an in progress operation on a repository or [`None`]
/// if no operation is currently in progress.
pub fn in_progress_operation(&self) -> Option<state::InProgress> {
let git_dir = self.path();

// This is modeled on the logic from wt_status_get_state in git's wt-status.c and
// ps1 from git-prompt.sh.

if git_dir.join("rebase-apply/applying").is_file() {
Some(state::InProgress::ApplyMailbox)
} else if git_dir.join("rebase-apply/rebasing").is_file() {
Some(state::InProgress::Rebase)
} else if git_dir.join("rebase-apply").is_dir() {
Some(state::InProgress::ApplyMailboxRebase)
} else if git_dir.join("rebase-merge/interactive").is_file() {
Some(state::InProgress::RebaseInteractive)
} else if git_dir.join("rebase-merge").is_dir() {
Some(state::InProgress::Rebase)
} else if git_dir.join("CHERRY_PICK_HEAD").is_file() {
if git_dir.join("todo").is_file() {
Some(state::InProgress::CherryPickSequence)
} else {
Some(state::InProgress::CherryPick)
}
} else if git_dir.join("MERGE_HEAD").is_file() {
Some(state::InProgress::Merge)
} else if git_dir.join("BISECT_LOG").is_file() {
Some(state::InProgress::Bisect)
} else if git_dir.join("REVERT_HEAD").is_file() {
if git_dir.join("todo").is_file() {
Some(state::InProgress::RevertSequence)
} else {
Some(state::InProgress::Revert)
}
} else {
None
}
}
}
4 changes: 0 additions & 4 deletions git-repository/tests/easy/mod.rs

This file was deleted.

43 changes: 0 additions & 43 deletions git-repository/tests/easy/reference.rs

This file was deleted.

Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
20 changes: 20 additions & 0 deletions git-repository/tests/fixtures/make_cherry_pick_repo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash
set -eu -o pipefail

git init -q

touch file
git add file
git commit -m first file

git checkout -b other-branch
echo other-branch > file
git commit -m file.other file

git checkout main
echo main > file
git add file
git commit -m file.main file

# This should fail and leave us in a cherry-pick state
git cherry-pick other-branch || true
16 changes: 16 additions & 0 deletions git-repository/tests/fixtures/make_rebase_i_repo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash
set -eu -o pipefail

git init -q

touch 1 2 3
git add 1
git commit -m 1 1
git add 2
git commit -m 2 2
git add 3
git commit -m 3 3

# NOTE: Starting around git 2.35.0 --preserve-merges was renamed to --rebase-merges
# however --preserve-merges first appeared in git 2.18. That should cover most use cases.
EDITOR="sed -i.bak 's/pick/edit/g'" git rebase --rebase-merges --interactive HEAD~2
13 changes: 13 additions & 0 deletions git-repository/tests/fixtures/make_revert_repo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash
set -eu -o pipefail

git init -q

touch 1 2 3
git add 1
git commit -m 1 1
git add 2
git commit -m 2 2
git add 3
git commit -m 3 3
git revert --no-commit HEAD~1
11 changes: 9 additions & 2 deletions git-repository/tests/repo.rs → git-repository/tests/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ fn repo(name: &str) -> crate::Result<ThreadSafeRepository> {
Ok(ThreadSafeRepository::open(repo_path)?)
}

fn repo_rw(name: &str) -> crate::Result<(git_repository::Repository, tempfile::TempDir)> {
fn named_repo(name: &str) -> crate::Result<Repository> {
let repo_path = git_testtools::scripted_fixture_repo_read_only(name)?;
Ok(ThreadSafeRepository::open(repo_path)?.to_thread_local())
}

fn repo_rw(name: &str) -> crate::Result<(Repository, tempfile::TempDir)> {
let repo_path = git_testtools::scripted_fixture_repo_writable(name)?;
Ok((
ThreadSafeRepository::discover(repo_path.path())?.to_thread_local(),
Expand All @@ -24,6 +29,8 @@ fn basic_rw_repo() -> crate::Result<(Repository, tempfile::TempDir)> {
}

mod discover;
mod easy;
mod id;
mod init;
mod object;
mod reference;
mod repository;
File renamed without changes.
File renamed without changes.
43 changes: 43 additions & 0 deletions git-repository/tests/reference/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,46 @@ mod log {
);
}
}
mod find {
use std::convert::TryInto;

use git_ref as refs;
use git_testtools::hex_to_id;

fn repo() -> crate::Result<git_repository::Repository> {
crate::repo("make_references_repo.sh").map(Into::into)
}

#[test]
fn and_peel() -> crate::Result {
let repo = repo()?;
let mut packed_tag_ref = repo.try_find_reference("dt1")?.expect("tag to exist");
assert_eq!(packed_tag_ref.name(), "refs/tags/dt1".try_into()?);

assert_eq!(
packed_tag_ref.inner.target,
refs::Target::Peeled(hex_to_id("4c3f4cce493d7beb45012e478021b5f65295e5a3")),
"it points to a tag object"
);

let object = packed_tag_ref.peel_to_id_in_place()?;
let the_commit = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03");
assert_eq!(object, the_commit, "it is assumed to be fully peeled");
assert_eq!(
object,
packed_tag_ref.peel_to_id_in_place()?,
"peeling again yields the same object"
);

let mut symbolic_ref = repo.find_reference("multi-link-target1")?;
assert_eq!(symbolic_ref.name(), "refs/heads/multi-link-target1".try_into()?);
assert_eq!(symbolic_ref.peel_to_id_in_place()?, the_commit);
assert_eq!(
symbolic_ref.name(),
"refs/remotes/origin/multi-link-target3".try_into()?,
"it follows symbolic refs, too"
);
assert_eq!(symbolic_ref.into_fully_peeled_id()?, the_commit, "idempotency");
Ok(())
}
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
mod object;
mod reference;
mod state;
41 changes: 41 additions & 0 deletions git-repository/tests/repository/state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use crate::{named_repo, Result};
use git_repository as git;

#[test]
fn cherry_pick() -> Result {
let repo = named_repo("make_cherry_pick_repo.sh")?;

let head = repo.head()?;
let head_name = head.referent_name().expect("no detached head").shorten();
assert_eq!(head_name, "main");

assert_eq!(repo.in_progress_operation(), Some(git::state::InProgress::CherryPick));
Ok(())
}

#[test]
fn rebase_interactive() -> Result {
let repo = named_repo("make_rebase_i_repo.sh")?;

let head = repo.head()?;
assert!(head.is_detached());
assert_eq!(
repo.in_progress_operation(),
Some(git::state::InProgress::RebaseInteractive)
);

Ok(())
}

#[test]
fn revert() -> Result {
let repo = named_repo("make_revert_repo.sh")?;

let head = repo.head()?;
let head_name = head.referent_name().expect("no detached head").shorten();
assert_eq!(head_name, "main");

assert_eq!(repo.in_progress_operation(), Some(git::state::InProgress::Revert));

Ok(())
}
4 changes: 3 additions & 1 deletion tests/tools/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,11 @@ pub fn scripted_fixture_repo_read_only_with_args(
.env("GIT_COMMITTER_DATE", "2000-01-02 00:00:00 +0000")
.env("GIT_COMMITTER_EMAIL", "[email protected]")
.env("GIT_COMMITTER_NAME", "committer")
.env("GIT_CONFIG_COUNT", "1")
.env("GIT_CONFIG_COUNT", "2")
.env("GIT_CONFIG_KEY_0", "commit.gpgsign")
.env("GIT_CONFIG_VALUE_0", "false")
.env("GIT_CONFIG_KEY_1", "init.defaultBranch")
.env("GIT_CONFIG_VALUE_1", "main")
.output()?;
assert!(
output.status.success(),
Expand Down