Skip to content

Commit

Permalink
Only use temp index if hunks are staged
Browse files Browse the repository at this point in the history
For big repos reading HEAD's tree into the temp index can apparently
take a while, so we should skip creating it if we can. Also, if we use a
temp index for unstaged hunks, then the original index will be
out-of-sync with any hunks that were committed via the temp index.

If you hit this, `git restore --staged` or `git read-tree HEAD^{tree}`
can be used to read the new HEAD's tree into the index.

In tests, if no staged changes are explicitly expected via the
`staged_want` param, fail if anything is in the index after calling
main().

Fixes #16
  • Loading branch information
torbiak committed Nov 25, 2020
1 parent 219f869 commit 0d2eb90
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
8 changes: 5 additions & 3 deletions git-autofixup
Original file line number Diff line number Diff line change
Expand Up @@ -553,9 +553,11 @@ sub main {
return 0;
}

# Limit the tempfile's lifetime to the execution of main().
local $ENV{GIT_INDEX_FILE}; # Throw away ENV changes between main() calls.
my $tempfile = create_temp_index();
local $ENV{GIT_INDEX_FILE}; # Throw away changes between main() calls.
if (is_index_dirty()) {
# Limit the tempfile's lifetime to the execution of main().
my $tempfile = create_temp_index();
}

for my $sha (@ordered_shas) {
my $fixup_hunks = $hunks_for->{$sha};
Expand Down
22 changes: 22 additions & 0 deletions t/autofixup.t
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ sub test_autofixup {
my $staged = $args->{staged};
my $log_want = defined($args->{log_want}) ? $args->{log_want}
: croak "wanted log output not given";
my $staged_want = $args->{staged_want};
my $unstaged_want = $args->{unstaged_want};
my $exit_code_want = $args->{exit_code};
my $autofixup_opts = $args->{autofixup_opts} || [];
Expand All @@ -90,6 +91,7 @@ sub test_autofixup {

my $exit_code_got;
my $log_got;
my $staged_got;
my $unstaged_got;
my $orig_dir = getcwd();
my $dir = File::Temp::tempdir(CLEANUP => 1);
Expand Down Expand Up @@ -126,6 +128,7 @@ sub test_autofixup {
run("git --no-pager log --format='%h %s' ${upstream_rev}..");
$exit_code_got = autofixup(@{$autofixup_opts}, $upstream_rev);
$log_got = git_log(${pre_fixup_rev});
$staged_got = diff('--cached');
if (defined($unstaged_want)) {
$unstaged_got = diff('HEAD');
}
Expand All @@ -144,6 +147,16 @@ sub test_autofixup {
$failed = 1;
}

if (!defined($staged_want) && $staged_got) {
diag("staged_got=<<EOF\n${staged_got}EOF\nno staged changes expected\n");
$failed = 1;
}
if (defined($staged_want) && $staged_want ne $staged_got) {
diag("staged_got=<<EOF\n${staged_got}EOF\nstaged_want=<<EOF\n${staged_want}EOF\n");
$failed = 1;
}


if (defined($unstaged_want) && $unstaged_want ne $unstaged_got) {
diag("unstaged_got=<<EOF\n${unstaged_got}EOF\nunstaged_want=<<EOF\n${unstaged_want}EOF\n");
$failed = 1;
Expand Down Expand Up @@ -752,5 +765,14 @@ index ae93045..16f9ec0 100644
@@ -1 +1 @@
-c1
+c2
EOF
, staged_want => <<'EOF'
diff --git a/b b/b
index c9c6af7..e6bfff5 100644
--- a/b
+++ b/b
@@ -1 +1 @@
-b1
+b2
EOF
});

0 comments on commit 0d2eb90

Please sign in to comment.