When trying to stage changes to file which has also pending `chmod +x`,
`git add -p` produces lots of 'Use of uninitialized value ...' warnings
and fails to do the job:
$ echo content >> file
$ chmod +x file
$ git add -p
diff --git a/file b/file
index e69de29..d95f3ad
--- a/file
+++ b/file
old mode 100644
new mode 100755
Stage mode change [y,n,q,a,d,/,j,J,g,?]? y
@@ -0,0 +1 @@
+content
Stage this hunk [y,n,q,a,d,/,K,g,e,?]? y
Use of uninitialized value $o_ofs in addition (+) at /home/kirr/local/git/libexec/git-core/git-add--interactive line 776.
Use of uninitialized value $ofs in numeric le (<=) at /home/kirr/local/git/libexec/git-core/git-add--interactive line 806.
Use of uninitialized value $o0_ofs in concatenation (.) or string at /home/kirr/local/git/libexec/git-core/git-add--interactive line 830.
Use of uninitialized value $n0_ofs in concatenation (.) or string at /home/kirr/local/git/libexec/git-core/git-add--interactive line 830.
Use of uninitialized value $o_ofs in addition (+) at /home/kirr/local/git/libexec/git-core/git-add--interactive line 776.
fatal: corrupt patch at line 5
diff --git a/file b/file
index e69de29..d95f3ad
--- a/file
+++ b/file
@@ -,0 + @@
+content
Cc: Jeff King <redacted>
Cc: Thomas Rast <redacted>
Signed-off-by: Kirill Smelkov <redacted>
---
t/t3701-add-interactive.sh | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
@@ -163,6 +163,17 @@ test_expect_success FILEMODE 'stage mode but not hunk' 'gitdifffile|grep"+content"'++test_expect_failureFILEMODE'stage mode and hunk''+gitreset--hard&&+echocontent>>file&&+chmod+xfile&&+printf"y\\ny\\n"|gitadd-p&&+gitdiff--cachedfile|grep"new mode"&&+gitdiff--cachedfile|grep"+content"&&+test-z"$(gitdifffile)"+'+# end of tests disabled when filemode is not usable test_expect_success'setup again''
From: Thomas Rast <hidden> Date: 2016-06-15 22:47:14
In 0392513 (add-interactive: refactor mode hunk handling, 2009-04-16),
we merged the interaction loops for mode changes and hunk staging.
This was fine at the time, because 0beee4c (git-add--interactive:
remove hunk coalescing, 2008-07-02) removed hunk coalescing.
However, in 7a26e65 (Revert "git-add--interactive: remove hunk
coalescing", 2009-05-16), we resurrected it. Since then, the code
would attempt in vain to merge mode changes with diff hunks,
corrupting both in the process.
We add a check to the coalescing loop to ensure it only looks at diff
hunks, thus skipping mode changes.
Noticed-by: Kirill Smelkov [off-list ref]
Signed-off-by: Thomas Rast <redacted>
---
git-add--interactive.perl | 4 ++++
t/t3701-add-interactive.sh | 2 +-
2 files changed, 5 insertions(+), 1 deletions(-)
@@ -164,7 +164,7 @@ test_expect_success FILEMODE 'stage mode but not hunk' ''-test_expect_failureFILEMODE'stage mode and hunk''+test_expect_successFILEMODE'stage mode and hunk''gitreset--hard&&echocontent>>file&&chmod+xfile&&
From: Jeff King <hidden> Date: 2016-06-15 22:47:14
On Sat, Aug 15, 2009 at 03:56:39PM +0200, Thomas Rast wrote:
In 0392513 (add-interactive: refactor mode hunk handling, 2009-04-16),
we merged the interaction loops for mode changes and hunk staging.
This was fine at the time, because 0beee4c (git-add--interactive:
remove hunk coalescing, 2008-07-02) removed hunk coalescing.
However, in 7a26e65 (Revert "git-add--interactive: remove hunk
coalescing", 2009-05-16), we resurrected it. Since then, the code
would attempt in vain to merge mode changes with diff hunks,
corrupting both in the process.
Thanks for the writeup; I bisected the problem to 7a26e65, as well, but
hadn't yet figured out what was going on. :)
Hmm. I am not too familiar with the coalesce_overlapping_hunks code, but
it looks like we peek at $out[-1] based on $last_o_ctx, assuming that
$last_o_ctx comes from the last hunk pushed (either because we just
pushed it, or we merged into it). So a non-hunk in the middle of some
coalescing hunks is going to violate that assumption.
As it is now, I think we always put the 'mode' hunk at the very
beginning, so that shouldn't happen (and IIRC, that order is preserved
throughout). So maybe it is not worth worrying about. But an alternate
patch is below.
---
Hmm. I am not too familiar with the coalesce_overlapping_hunks code, but
it looks like we peek at $out[-1] based on $last_o_ctx, assuming that
$last_o_ctx comes from the last hunk pushed (either because we just
pushed it, or we merged into it). So a non-hunk in the middle of some
coalescing hunks is going to violate that assumption.
As it is now, I think we always put the 'mode' hunk at the very
beginning, so that shouldn't happen (and IIRC, that order is preserved
throughout). So maybe it is not worth worrying about. But an alternate
patch is below.
Hmm. I briefly considered worrying about futureproofing, but then
decided it wasn't worth it since we also rely on
coalesce_overlapping_hunks only being run over the hunks of a single
file. But since you already went to the lengths of doing it, feel
free to take the explanation in my commit message and add my Acked-by
:-)
--
Thomas Rast
trast@{inf,student}.ethz.ch
From: Junio C Hamano <hidden> Date: 2016-06-15 22:47:14
Thomas Rast [off-list ref] writes:
Hmm. I briefly considered worrying about futureproofing, but then
decided it wasn't worth it since we also rely on
coalesce_overlapping_hunks only being run over the hunks of a single
file.
On Sat, Aug 15, 2009 at 11:19:24AM -0700, Junio C Hamano wrote:
Thomas Rast [off-list ref] writes:
quoted
Hmm. I briefly considered worrying about futureproofing, but then
decided it wasn't worth it since we also rely on
coalesce_overlapping_hunks only being run over the hunks of a single
file.