Skip to content

Commit c26867c

Browse files
committed
Use stupid index and worktree status checks
This relates to sparse checkout support (#195). Conflict checks and index/worktree cleanness checks are converted to using Stupid::statuses() for all StGit commands. This eliminates a common class of problem that can prevent StGit from working in a sparse checkout worktree.
1 parent 1b6b2e2 commit c26867c

File tree

18 files changed

+70
-133
lines changed

18 files changed

+70
-133
lines changed

src/cmd/branch.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,8 @@ fn run(matches: &ArgMatches) -> Result<()> {
249249
Err(anyhow!("{target_branchname} is already the current branch"))
250250
} else {
251251
if !matches.contains_id("merge") {
252-
repo.check_worktree_clean()?;
252+
let statuses = repo.stupid().statuses(None)?;
253+
statuses.check_worktree_clean()?;
253254
}
254255
let target_branch = repo.get_branch(Some(target_branchname))?;
255256
switch_to(matches, &repo, &target_branch)
@@ -426,10 +427,12 @@ fn create(repo: git2::Repository, matches: &ArgMatches) -> Result<()> {
426427
let new_branchname = get_one_str(matches, "new-branch").expect("required argument");
427428

428429
repo.check_repository_state()?;
429-
repo.check_conflicts()?;
430+
let stupid = repo.stupid();
431+
let statuses = stupid.statuses(None)?;
432+
statuses.check_conflicts()?;
430433

431434
let parent_branch = if let Some(committish) = get_one_str(matches, "committish") {
432-
repo.check_worktree_clean()?;
435+
statuses.check_worktree_clean()?;
433436
let mut parent_branch = None;
434437
if let Ok(local_parent_branch) = repo.find_branch(committish, git2::BranchType::Local) {
435438
parent_branch = Some(local_parent_branch);
@@ -523,9 +526,11 @@ fn clone(repo: git2::Repository, matches: &ArgMatches) -> Result<()> {
523526
format!("{current_branchname}-{suffix}")
524527
};
525528

526-
repo.check_worktree_clean()?;
529+
let stupid = repo.stupid();
530+
let statuses = stupid.statuses(None)?;
531+
statuses.check_worktree_clean()?;
527532
repo.check_repository_state()?;
528-
repo.check_conflicts()?;
533+
statuses.check_conflicts()?;
529534

530535
if let Ok(stack) = Stack::from_branch(&repo, None) {
531536
stack.check_head_top_mismatch()?;
@@ -539,9 +544,9 @@ fn clone(repo: git2::Repository, matches: &ArgMatches) -> Result<()> {
539544
false,
540545
&format!("clone from {current_branchname}"),
541546
)?;
542-
repo.stupid().branch_copy(None, &new_branchname)?;
547+
stupid.branch_copy(None, &new_branchname)?;
543548
} else {
544-
repo.stupid().branch_copy(None, &new_branchname)?;
549+
stupid.branch_copy(None, &new_branchname)?;
545550
Stack::initialize(&repo, Some(&new_branchname))?;
546551
};
547552

src/cmd/delete.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::{
1111
patchrange,
1212
repo::RepositoryExtended,
1313
stack::{Error, Stack, StackStateAccess},
14+
stupid::Stupid,
1415
};
1516

1617
use super::StGitCommand;
@@ -99,7 +100,8 @@ fn run(matches: &ArgMatches) -> Result<()> {
99100
}
100101

101102
repo.check_repository_state()?;
102-
repo.check_conflicts()?;
103+
let statuses = repo.stupid().statuses(None)?;
104+
statuses.check_conflicts()?;
103105
stack.check_head_top_mismatch()?;
104106
// TODO: compat: these are not checked in Python version. How well is
105107
// this handled here?

src/cmd/export.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use clap::Arg;
1616
use crate::{
1717
commit::CommitExtended,
1818
patchrange,
19-
repo::RepositoryExtended,
2019
signature::TimeExtended,
2120
stack::{Error, Stack, StackStateAccess},
2221
stupid::Stupid,
@@ -129,7 +128,13 @@ fn run(matches: &clap::ArgMatches) -> Result<()> {
129128
let stupid = repo.stupid();
130129
let config = repo.config()?;
131130

132-
if opt_branch.is_none() && repo.check_worktree_clean().is_err() {
131+
if opt_branch.is_none()
132+
&& repo
133+
.stupid()
134+
.statuses(None)?
135+
.check_worktree_clean()
136+
.is_err()
137+
{
133138
crate::print_warning_message(
134139
matches,
135140
"Local changes in the tree; you might want to commit them first",

src/cmd/float.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::{
1616
patchrange,
1717
repo::RepositoryExtended,
1818
stack::{Stack, StackStateAccess},
19+
stupid::Stupid,
1920
};
2021

2122
use super::StGitCommand;
@@ -72,13 +73,15 @@ fn make() -> clap::Command<'static> {
7273
fn run(matches: &ArgMatches) -> Result<()> {
7374
let repo = git2::Repository::open_from_env()?;
7475
let stack = Stack::from_branch(&repo, None)?;
76+
let stupid = repo.stupid();
7577

7678
let opt_noapply = matches.contains_id("noapply");
7779
let opt_keep = matches.contains_id("keep");
7880
let opt_series = matches.get_one::<PathBuf>("series").map(|p| p.as_path());
7981

8082
repo.check_repository_state()?;
81-
repo.check_conflicts()?;
83+
let statuses = stupid.statuses(None)?;
84+
statuses.check_conflicts()?;
8285
stack.check_head_top_mismatch()?;
8386

8487
let patches: Vec<PatchName> = if let Some(series_path) = opt_series {
@@ -95,7 +98,7 @@ fn run(matches: &ArgMatches) -> Result<()> {
9598
}
9699

97100
if !opt_keep && (!opt_noapply || patches.iter().any(|pn| stack.is_applied(pn))) {
98-
repo.check_index_and_worktree_clean()?;
101+
statuses.check_index_and_worktree_clean()?;
99102
}
100103

101104
let (applied, unapplied) = if opt_noapply {

src/cmd/fold.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use anyhow::Result;
88
use clap::{Arg, ArgGroup};
99

1010
use crate::{
11-
repo::RepositoryExtended,
1211
revspec::parse_stgit_revision,
1312
stack::{Error, Stack, StackStateAccess},
1413
stupid::Stupid,
@@ -84,8 +83,10 @@ fn make() -> clap::Command<'static> {
8483
fn run(matches: &clap::ArgMatches) -> Result<()> {
8584
let repo = git2::Repository::open_from_env()?;
8685
let stack = Stack::from_branch(&repo, None)?;
86+
let stupid = repo.stupid();
8787

88-
repo.check_index_and_worktree_clean()?;
88+
let statuses = stupid.statuses(None)?;
89+
statuses.check_index_and_worktree_clean()?;
8990
stack.check_head_top_mismatch()?;
9091

9192
if stack.applied().is_empty() {

src/cmd/goto.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::{
1313
patchrange,
1414
repo::RepositoryExtended,
1515
stack::{Stack, StackStateAccess},
16+
stupid::Stupid,
1617
};
1718

1819
use super::StGitCommand;
@@ -44,16 +45,18 @@ fn make() -> clap::Command<'static> {
4445
fn run(matches: &ArgMatches) -> Result<()> {
4546
let repo = git2::Repository::open_from_env()?;
4647
let stack = Stack::from_branch(&repo, None)?;
48+
let stupid = repo.stupid();
4749

4850
let patch_arg = matches.get_one::<PatchName>("patch").unwrap();
4951
let opt_keep = matches.contains_id("keep");
5052
let opt_merged = matches.contains_id("merged");
5153

5254
repo.check_repository_state()?;
53-
repo.check_conflicts()?;
55+
let statuses = stupid.statuses(None)?;
56+
statuses.check_conflicts()?;
5457
stack.check_head_top_mismatch()?;
5558
if !opt_keep {
56-
repo.check_index_and_worktree_clean()?;
59+
statuses.check_index_and_worktree_clean()?;
5760
}
5861

5962
let patchname = match patchrange::parse_single(patch_arg, &stack, patchrange::Allow::Visible) {

src/cmd/import.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use crate::{
1515
color::get_color_stdout,
1616
patchedit,
1717
patchname::PatchName,
18-
repo::RepositoryExtended,
1918
signature::{self, SignatureExtended},
2019
stack::{Stack, StackStateAccess},
2120
stupid::{Stupid, StupidContext},
@@ -193,6 +192,7 @@ fn make() -> clap::Command<'static> {
193192
fn run(matches: &clap::ArgMatches) -> Result<()> {
194193
let repo = git2::Repository::open_from_env()?;
195194
let stack = Stack::from_branch(&repo, None)?;
195+
let stupid = repo.stupid();
196196

197197
let source_path = if matches.contains_id("url") {
198198
None
@@ -205,9 +205,10 @@ fn run(matches: &clap::ArgMatches) -> Result<()> {
205205

206206
std::env::set_current_dir(repo.workdir().unwrap())?;
207207

208-
repo.check_index_and_worktree_clean()?;
208+
let statuses = stupid.statuses(None)?;
209+
statuses.check_index_and_worktree_clean()?;
209210
stack.check_head_top_mismatch()?;
210-
repo.stupid().update_index_refresh()?;
211+
//stupid.update_index_refresh()?;
211212

212213
if cfg!(feature = "import-url") && matches.contains_id("url") {
213214
import_url(stack, matches)

src/cmd/new.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::{
1616
repo::RepositoryExtended,
1717
signature::SignatureExtended,
1818
stack::{Stack, StackStateAccess},
19+
stupid::Stupid,
1920
};
2021

2122
pub(super) fn get_command() -> (&'static str, super::StGitCommand) {
@@ -133,9 +134,11 @@ fn run(matches: &ArgMatches) -> Result<()> {
133134
let repo = git2::Repository::open_from_env()?;
134135
let branch_name: Option<&str> = None;
135136
let stack = Stack::from_branch(&repo, branch_name)?;
137+
let stupid = repo.stupid();
136138

137139
repo.check_repository_state()?;
138-
repo.check_conflicts()?;
140+
let statuses = stupid.statuses(None)?;
141+
statuses.check_conflicts()?;
139142
stack.check_head_top_mismatch()?;
140143

141144
let patchname = if let Some(patchname) = matches.get_one::<PatchName>("patchname").cloned() {

src/cmd/pick.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use crate::{
1616
commit::RepositoryCommitExtended,
1717
patchname::PatchName,
1818
patchrange,
19-
repo::RepositoryExtended,
2019
revspec::{parse_branch_and_spec, parse_stgit_revision},
2120
signature::SignatureExtended,
2221
stack::{Stack, StackStateAccess},
@@ -147,7 +146,9 @@ fn run(matches: &clap::ArgMatches) -> Result<()> {
147146
}
148147

149148
if !matches.contains_id("noapply") {
150-
repo.check_index_and_worktree_clean()?;
149+
repo.stupid()
150+
.statuses(None)?
151+
.check_index_and_worktree_clean()?;
151152
stack.check_head_top_mismatch()?;
152153
}
153154

src/cmd/pull.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use clap::{Arg, ArgMatches};
1010
use crate::{
1111
color::get_color_stdout,
1212
print_info_message,
13-
repo::RepositoryExtended,
1413
revspec::parse_stgit_revision,
1514
stack::{Stack, StackStateAccess},
1615
stupid::Stupid,
@@ -148,7 +147,7 @@ fn run(matches: &ArgMatches) -> Result<()> {
148147
));
149148
}
150149

151-
repo.check_index_and_worktree_clean()?;
150+
stupid.statuses(None)?.check_index_and_worktree_clean()?;
152151
stack.check_head_top_mismatch()?;
153152

154153
let applied = stack.applied().to_vec();

0 commit comments

Comments
 (0)