Commit: patch 9.2.0914: diff: undo after :diffget into an empty buffer leaves a line behind

Christian Brabandt <[email protected]> Wed, 5 Aug 2026 21:15:09 +0200
Newsgroups gmane.editors.vim.devel
Message-ID <[email protected]>
patch 9.2.0914: diff: undo after :diffget into an empty buffer leaves a line behind

Commit: https://github.com/vim/vim/commit/c44f35ca1a4d8c0c78f327800fe2677c91c6cecb
Author: Hirohito Higashi <[email protected]>
Date:   Wed Aug 5 19:05:25 2026 +0000

    patch 9.2.0914: diff: undo after :diffget into an empty buffer leaves a line behind
    
    Problem:  After :diffget into an empty buffer, undo does not restore the
              empty buffer, the last line stays behind (Narendran
              Gopalakrishnan)
    Solution: Include the empty line of the empty buffer in the undo
              information, it is deleted once the first line was obtained
              (Hirohito Higashi).
    
    fixes:  #20950
    closes: #20951
    
    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
    Signed-off-by: Hirohito Higashi <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/diff.c b/src/diff.c
index b38513693..4836922c9 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -4240,8 +4240,12 @@ ex_diffgetput(exarg_T *eap)
 	dfree = NULL;
 	lnum = dp->df_lnum[idx_to];
 	count = dp->df_count[idx_to];
+	// The empty line of an empty buffer is deleted below, include it in
+	// the undo information, otherwise undo leaves a line behind.
+	linenr_T undo_bot = lnum + count + (count == 0 && BUFEMPTY() ? 1 : 0);
+
 	if (dp->df_lnum[idx_cur] + dp->df_count[idx_cur] > eap->line1 + off
-		&& u_save(lnum - 1, lnum + count) != FAIL)
+		&& u_save(lnum - 1, undo_bot) != FAIL)
 	{
 	    // Inside the specified range and saving for undo worked.
 	    start_skip = 0;
diff --git a/src/testdir/test_diffmode.vim b/src/testdir/test_diffmode.vim
index 1a7840756..7fc4a3248 100644
--- a/src/testdir/test_diffmode.vim
+++ b/src/testdir/test_diffmode.vim
@@ -250,6 +250,24 @@ func Test_diffget_diffput()
   %bwipe!
 endfunc
 
+" Undo after getting lines into an empty buffer must leave it empty again
+func Test_diffget_undo_empty_buffer()
+  enew!
+  diffthis
+  new
+  call setline(1, ['1', '2'])
+  diffthis
+
+  wincmd p
+  normal do
+  call assert_equal(['1', '2'], getline(1, '$'))
+  undo
+  call assert_equal([''], getline(1, '$'))
+
+  windo diffoff
+  %bwipe!
+endfunc
+
 " Test putting two changes from one buffer to another
 func Test_diffput_two()
   new a
diff --git a/src/version.c b/src/version.c
index a5145fff9..1931bc906 100644
--- a/src/version.c
+++ b/src/version.c
@@ -763,6 +763,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    914,
 /**/
     913,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups "vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1wrh53-00EktN-Fm%40256bit.org.