19

Let's say I'm at state A in my document. I then make changes B, C, and D (in order).

Is there a way I can keep changes B and D, but skip C?

Or, let's say I'm at state A in my document. I make change B, undo it, and then make changes C and D (so Vim has an undo tree with two branches). I then change my mind and decide I want to use B and D but not C.

How can I do this in Vim? I have the gundo.vim plugin installed, but I haven't used it that much.

Samuel Rossille
  • 18,940
  • 18
  • 62
  • 90
Kevin Burke
  • 61,194
  • 76
  • 188
  • 305
  • Interesting question mode. I usually trick around with g- and g+ and a whole lot of yank/put. I'd be most curious what people come up with – sehe Apr 24 '11 at 21:16
  • 1
    I'm not sure this is possible in Vim. Change C can be based on B. What you basically want is a way to store a specific states of the document with edits, and the ability to then merge different states. Sounds like what source core revisions systems can do when doing "merge" operations. I think you will need to get into practice of using named buffers and/or saving alternative versions of the file if you need jump quickly between revisions. – ewh Apr 24 '11 at 21:37
  • I can imagine only one way to do this automatically: import the whole undo tree into some VCS and then use it to skip changes (for example, `git rebase -i` provides a way to remove some commit even if it has children). But I have never seen such plugins, so you will have to write it by yourself. – ZyX Apr 25 '11 at 14:48
  • 1
    Yeah, it sounds like an editor that stores every step in a good VCS like Mercurial or Git. I honestly don't think `vim` or any other editor can do it. Except `emacs`, of course, where you can do it by using a git plugin and scripting a little :-) –  Apr 25 '11 at 20:41
  • sounds like an interactive undo/redo type thingy!?!? – yasouser Apr 26 '11 at 18:55
  • 1
    I don't think you can do this, but Gundo might be of some help for grabbing the lines you want: http://sjl.bitbucket.org/gundo.vim/ – Austin Taylor Apr 27 '11 at 02:18

2 Answers2

2

Well, I'll take a stab at this and say: No, I don't think there's a way to do exactly what you want with vim.

gundo.vim adds a nice interface to vim's undo, but doesn't change its core capabilities. So I took a look at the official vim docs to see if there's any hints to whether it is capable of this:

Nothing about merging two branches together. I think ewh and ZyX are right: to get a general solution for merging B with D, vim would need either for

  1. Bram to add it as a separate feature in a future version
  2. someone to implement it in a plugin by integrating with something that can already do merges (like git/hg)

You can of course try to do it manually by having files with versions B, C and D as well as a few diffs open.


Note: If I misunderstood and you weren't wondering about a general solution and are looking for help with a specific instance of this, let me know and I'll see what I can do :)

Nick Knowlson
  • 7,185
  • 6
  • 47
  • 63
1

Is there a way I can keep changes B and D, but skip C?

You're at state D. :w file.ext_D

Backtrack to state C. :w file_ext_C

Backtrack to state B. :w file.ext_B

:!kdiff3 file.ext_B file.ext_C file.ext_D

This gives a 3 way merge of the differences, but still you'd have to manually go in and choose every red line in D for each merge conflict. Not exactly an easy solution.

If instead you do

:!kdiff3 file.ext_C file.ext_B file.ext_D

Then the merge happens automatically (except for individual lines with multiple changes)

For more complicated scenarios it gets tougher.

Note: I'm not sure how a revision control tool is much help. You're basically doing something like creating a patch between B and D, and then subtracting the patch from C to D from it. It seems to me that revision control systems are usually designed to manage merges between different sources of changes, not changes along a single branch.

kdiff3 is available at: http://kdiff3.sourceforge.net/

  • 1
    WHY kdiff3? This _is_ vim, so it has diff. If you want to just merge, use meld or any cli program that integrates easily. Re: `... how a revision tool is much help [...] not [...] a single branch`: Work with microcommits much? The whole git apply --interactive concept, possibly even it's index feature is geared towards this very need – sehe Apr 28 '11 at 14:24