Gdiff shows entire file change #91

Closed
jdelStrother opened this Issue Jul 6, 2011 · 49 comments

Projects

None yet

Heya,
I've been having occasional problems with Gdiff, where it shows the entire file as having changed. It's not due to whitespace or line endings - manually running 'git diff' just shows a couple of deleted lines with no change to the rest of the file.
If I restart MacVim and re-run Gdiff on the same file, it works perfectly.

Which sounds pretty odd to me... any suggestions how I can narrow it down further?

Owner
tpope commented Jul 6, 2011

First thing to check is if :diffupdate fixes it. Vim diff can get confused. :diffupdate fixes it. But this would be the first time I've known it to get confused when opening the file.

Thanks, I'll give it a try next time it occurs & let you know...

No luck with diffupdate. I did find that after closing all the buffers associated with fugitive and then reopening the file and diffing it again, then the problem would go away. Still not especially helpful, I know...

I have seen a similar issue, and I'd guess that it is actually causing what you're seeing here.

I find that if I do something like:

  1. Edit foo.c
  2. :Gdiff (normally by hitting D on :Gstatus)
  3. Commit foo.c
  4. Edit foo.c some more
  5. :Gdiff again (same way)

At this point, I now have two side-by-side buffers, but they show all of the changes from #1 and #4. This is because for whatever reason, the left pane does not updated from the index. If I switch to the left pane and then :e! to reload from the index, then the diff is right and shows only the edits in #4.

It looks like :Gdiff just needs to make sure to refresh the left pane on display.

Owner
tpope commented Aug 5, 2011

What is the value of :set hidden?? How about :set bufhidden??

hidden is enabled

In either pane of the diff, bufhidden is empty, it is set to delete in the
status window.

On Thu, Aug 4, 2011 at 11:07 PM, tpope <
reply@reply.github.com>wrote:

What is the value of :set hidden?? How about :set bufhidden??

Reply to this email directly or view it on GitHub:
#91 (comment)

Owner
tpope commented Aug 7, 2011

So 'hidden' is the problem. Hmmm . . .

Refreshing the buffer is simple enough. The problem is that will blow away any changes a user might have made to that buffer (say, in another tab). I can guard against that by checking 'modified', but that won't save undo history. For me, undo history is a rude and invasive thing to yank out from under me.

I recommend trying the following:

autocmd BufNewFile,BufRead fugitive://* set bufhidden=delete

This will effectively make it so index and historical buffers will automatically be deleted when they are hidden. I've had people request that be the default for a while now; this may just be the straw that breaks the camel's back.

Yes. This definitely fixes the problem. Thanks!

Apart from this bug, this is definitely an option I'd rather have on by
default as well.

On Sun, Aug 7, 2011 at 7:22 PM, tpope <
reply@reply.github.com>wrote:

So 'hidden' is the problem. Hmmm . . .

Refreshing the buffer is simple enough. The problem is that will blow away
any changes a user might have made to that buffer (say, in another tab). I
can guard against that by checking 'modified', but that won't save undo
history. For me, undo history is a rude and invasive thing to yank out from
under me.

I recommend trying the following:

autocmd BufNewFile,BufRead fugitive://* set bufhidden=delete

This will effectively make it so index and historical buffers will
automatically be deleted when they are hidden. I've had people request that
be the default for a while now; this may just be the straw that breaks the
camel's back.

Reply to this email directly or view it on GitHub:
#91 (comment)

I'm not sure if this is related, but if I do:

  1. :Gstatus
  2. Scroll to a changed file, hit 'D'
  3. Switch back to the already open :Gstatus window
  4. Scroll to another file, hit 'D'

The diff window now gets incredibly confused, doing things like marking
everything as changed but not showing changes. Also, :diffput errors out
saying that more than one diff window is open so it doesn't know what to do.

On Mon, Aug 8, 2011 at 3:45 PM, Matthew Schulkind mschulkind@gmail.comwrote:

Yes. This definitely fixes the problem. Thanks!

Apart from this bug, this is definitely an option I'd rather have on by
default as well.

On Sun, Aug 7, 2011 at 7:22 PM, tpope <
reply@reply.github.com>wrote:

So 'hidden' is the problem. Hmmm . . .

Refreshing the buffer is simple enough. The problem is that will blow away
any changes a user might have made to that buffer (say, in another tab). I
can guard against that by checking 'modified', but that won't save undo
history. For me, undo history is a rude and invasive thing to yank out from
under me.

I recommend trying the following:

autocmd BufNewFile,BufRead fugitive://* set bufhidden=delete

This will effectively make it so index and historical buffers will
automatically be deleted when they are hidden. I've had people request that
be the default for a while now; this may just be the straw that breaks the
camel's back.

Reply to this email directly or view it on GitHub:
#91 (comment)

Owner
tpope commented Aug 8, 2011

Are more than two diff windows actually open? Did this just start happening when you added that autocmd? Are you on the latest fugitive from GitHub?

Just updated to HEAD and now I can't seem to reproduced this. I'll open a
new issue if I notice this again.

Thanks.

On Mon, Aug 8, 2011 at 7:51 PM, tpope <
reply@reply.github.com>wrote:

Are more than two diff windows actually open? Did this just start happening
when you added that autocmd? Are you on the latest fugitive from GitHub?

Reply to this email directly or view it on GitHub:
#91 (comment)

@tpope tpope closed this Aug 9, 2011
Owner
tpope commented Aug 16, 2011

The latest commit changes bufhidden=delete to the default behavior.

ensonmj commented Aug 20, 2011

This problem occur with minibufexpl plugin, and when i remove minibufexpl, it's ok.
any suggestions about using all the two plugins in the same time?

Owner
tpope commented Aug 20, 2011

Back in the day on freenode's #vim, I remember "uninstall minibufexpl" being an effective solution to all sorts of weird problems. I think the only thing that's changed is far fewer people use it, what with Vim having proper tabs now.

I can't reproduce this particular issue, but I can certainly reproduce others. :Gdiff sets 'diff' in the -MiniBufExplorer- window rather than the original file, for instance. I'm not convinced this isn't a lost cause.

Owner
tpope commented Aug 20, 2011

For the record, are you using the old, official minibufexpl on vim.org, or the newer fork on GitHub that he recommends?

ensonmj commented Aug 21, 2011

I use vundle to clone the plugin from "https://github.com/fholgado/minibufexpl.vim"
and use the recommend setting
let g:miniBufExplMapWindowNavVim = 1
let g:miniBufExplMapWindowNavArrows = 1
let g:miniBufExplMapCTabSwitchBufs = 1
let g:miniBufExplModSelTarget = 1

silasb commented Oct 20, 2011

I also can't seem to get minibufexpl working with Gdiff.

melta commented Feb 28, 2012

I have the same problem.

I too have the same problem.

Owner
tpope commented Mar 6, 2012

@melta @sorin-ionescu are you having this issue with minibufexpl or without?

@tpope I do not have that plugin. Here's my vimrc.

Owner
tpope commented Mar 6, 2012

@sorin-ionescu I see nothing obviously problematic. See if you can reproduce the problem with a more minimal config.

@tpope I was afraid you were going to say that. :)

For the record, I have not seen this reoccur even a single time.

@tpope I have reduced the vimrc to bellow. I have also removed ~/.gitconfig in case that was the problem. It still happens. I have the latest Git installed.

set nocompatible
filetype off
set rtp+=~/.vim/bundle/vundle/
call vundle#rc()
Bundle 'gmarik/vundle'
Bundle 'tpope/vim-git'
Bundle 'tpope/vim-fugitive'
Owner
tpope commented Mar 14, 2012

@sorin-ionescu that looks pretty darn minimal. To confirm, that means no other plugins are loaded, correct?

Check :set diff? in each of the two buffers. What does it report?

@tpope That is the entire vimrc. They both report diff.

Screenshot

Owner
tpope commented Mar 14, 2012

Is there anything in that left buffer, or is it completely empty?

If there is something in it, check ':set fileformat?` in each and report back.

It's empty. It says fileformat=unix.

Owner
tpope commented Mar 14, 2012

Well that's the real problem. Can you open a new issue about files in the index not loading? Let's not pollute this issue any further.

I have no idea what is the problem. Please open the issue yourself.

senft commented May 13, 2013

I just encountered this problem (though in a slightly different flavor), too.
What I did:

  1. :Gstatus
  2. Hit "D" on the file I wanted to diff

What happened:
The HEAD version of the file appered in a buffer, but the buffer was diffed against the :Gstatus buffer (the two buffers were also "scroll-locked").

The problem was, like already mentioned the minibufexpl, plugin but also a little snippet I had in my .vimrc that moved preview-buffers to the bottom.

" Display preview at bottom
function! PreviewDown() 
   if !&previewwindow 
       silent! wincmd P 
   endif 
   if &previewwindow 
       silent! wincmd J 
       silent! wincmd p 
   endif 
endf 
au BufWinEnter * call PreviewDown() 

I removed both and diffing now works perfectly.

mMontu commented Jun 3, 2014

For some time I've been seen fugitive displaying incorrect diffs, i.e, highlight the entire buffer when just one line was changed. But it is hard to create a test procedure that consistently reproduces the bug. It happens on the latest version of fugitive.

I've noticed that the problem was related to opening several diffs on Gstatus, without closing the previous one. diffupdate doesn't helps. If each diff is reopened and closed, the problem disappears -- i.e., if the problem appears after issuing D on Gstatus for 3 different files, hitting D for each file again and issuing :q on the window containing the old version of the file makes the issue disappear.

Currently I have a vim session where the bug always appears; it is clear that the problem happens without any changes on git, as I can reproduce the bug just after restarting vim, without entering any git command. It happens after every restart of the session, but I'm still struggling to reproduce it on a smaller session where I could check for plugins/settings interference.

Contributor
qstrahl commented Jun 3, 2014

@mMontu, I don't know the exact cause of the issue, but the symptom is that you have some hidden buffers diff'd. You can fix it by doing :bufdo diffoff.

mMontu commented Jun 3, 2014

Indeed, it seems like it is diff the current file with hidden buffers. :bufdo diffo indeed corrects the problem.

As I'm able to reproduce the problem issuing D on two lines of Gstatus (only on the right order), I've tried D, :diffo!, D, and it indeed prevented the problem. But it also prevented the closing of the first compared file: after the first D, I had three windows: oldFile1 (diff), File1 (diff), Gstatus. After :diffo!, D, four windows: oldFile2 (diff), File2 (diff), File1, Gstatus.

Contributor
qstrahl commented Jun 3, 2014

Yeah, unfortunately not a general solution.

Corax26 commented Jun 10, 2014

I've had the same issue as @mMontu ever since I use fugitive, it's quite troublesome...

I don't even have 'hidden' set by the way. What I usually do is that I diff files from Gstatus using D one after the other (without exitting windows), and this works only for a few files (not always the same number) before failing and showing garbage. Doing a :bufdo diffoff isn't an option (too slow with many buffers), and isn't a good solution anyway since after doing it and another D, a third window is opened (not counting Gstatus).

Maybe pressing D in Gstatus could exit diff mode in all windows (which is way quicker than all buffers) in the first place?

Also having this issue constantly, glad to finally figure out WHY it is happening. I presume others are NOT using hidden buffers, otherwise this problem would come up more ?

Will try working without them for a while, as a workaround, but would be good to have something more solid around this use case (pressing D on a number of files in a row)

Owner
tpope commented Aug 12, 2014

The problem with hidden buffers was fixed years ago. There's something else in your mix.

Interesting. The :bufdo diffoff command certainly fixes up the issue, and since turning off hidden buffers, I've not been able to recreate the issue (albeit that was only for the last two hours).

I'll keep an eye on it, and if I see it again, raise a new issue, linking back to this one (rather than polluting an old, closed thread some more).

Corax26 commented Aug 12, 2014

Maybe the problem with hidden buffers was fixed, but clearly there's still another problem.
With a minimal vimrc (only nocp and pathogen to load fugitive), I can still reproduce the problem:

  • Open some file F1, and another F2 (which is in the index and has modifications) in another tab
  • While viewing F1, open Gstatus
  • Hit D on F2
  • Hit D on another file in Gstatus list

You will see that the second diff is all mixed up with the first diff (it show changes where there isn't any).

Owner
tpope commented Aug 12, 2014

Can't reproduce. You've got exactly 3 buffers, :Gstatus, the other file, and the other file's staged buffer, open in the first tab when you're finished, correct?

Corax26 commented Aug 12, 2014

This is precisely what I do (actually there's no need for a dummy F1 file, an empty buffer does it):

  • :tabe F2
  • gt
  • :Gstatus
  • <select F2, then D>
  • <select another modified file, then D>

After last step, my diff is messed up.

My ultra stripped down vimrc boils down to:

set nocompatible
runtime bundle/pathogen/autoload/pathogen.vim
execute pathogen#infect()

And the only plugins are pathogen and fugitive.

Owner
tpope commented Aug 12, 2014

Thanks for the gratuitous rephrasing but please verify the final arrangement as requested. Also, please provide your exact Vim version.

Corax26 commented Aug 12, 2014

I indeed have those 3 buffers opened in the first tab, plus F2 in the other tab.
I use vim 7.4.383, and this version of fugitive to be more verbose.

Owner
tpope commented Aug 12, 2014

Confirming it works fine on 7.4.273 on Linux. Can you check the value of

  • hidden
  • bufhidden in each of the 2 buffers when you first diff F2
  • bufhiddenin each of the 2 buffers when you diff the other file
  • bufhidden in the other tab when you diff the other file
  • diff in the other tab when you diff the other file
Corax26 commented Aug 12, 2014
  • nohidden
  • delete for the fugitive buffer (base version), and empty for the current modified file
  • same
  • empty, and nodiff

I've noticed something interesting. The problem only happens when the last buffer selected before selecting the Gstatus window again (between the two D) is the fugitive buffer, not when it is the current modified file.

Edit: something's important that I forgot to mention too (sorry about it), none of my file is staged, they're just modified and unstaged. I can't reproduce the bugs when they're staged (I thought it had already happened to me with staged files though).

Owner
tpope commented Aug 13, 2014

The "last buffer" criteria was enough of a clue for me to reproduce. :echo bufgetvar(<number>, '&diff') reveals that the buffer in the tab still has a diff flag somehow, which doesn't make sense because 'diff' is a window-local not a buffer-local option. (But I still don't fully understand what "window-local" means.) Feel free to open a new issue.

Corax26 commented Aug 13, 2014

Glad you've been able to reproduce it! I'll open a new issue.

Edit: new issue #534 opened

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment