Three-way-merge - different philosophies? - user-interface

I've been a user of UltraCompare Pro since it first came out, and I think it's a very full-featured compare and merge tool. However, since I have been looking more closely into DVCS, I found that it handles three-way merges differently than (most?) other tools out there. So I wonder why that is, and whether I'm missing something because of it.
In UltraCompare, there are three merge panels (let's call them base, local and other). All the merge action happens within these panels. In practice, this means that I do my work on the middle pane (local), merging changes from the right (other) or maybe from the common ancestor on the left (base). The middle pane is modified during the session and then saved - and committed as the result of the merge. The fourth pane (Output window) only contains information about the diff result.
(source: ultraedit.com)
In other tools, it appears that the three panes only exist in a read-only state, and that the fourth, bottom pane (output) is the place where all the merging happens. What are the reasons to have an extra merge window? Is it easier to keep track of all the changes? Or is it just like that because everybody has always been doing it this way, so we're copying that behavior? What's your opinion on this?
(source: hginit.com)
I'm not sure whether there exists a best or correct answer, so I haven't yet made this question CW, but I'll defer to your opinion here as well.

Seems straightforward to me, you might very well want to keep an unchanged ‘local’ version visible when you are making your changes.
original local other merged
bar= foo+1 bar= foo+2 bof= foo+2
zot= foo+1
... ... ... ...
print foo print bar print foo+1 print bar??
Both local and other have introduced a new variable bar. Merge the first change to bof/zot, go for a cup of tea, come back and try to merge the print. Wait, what was bar in local? If the original local isn't there, that information's gone, and you're scrabbling about with another text editor to work out what's happened.
This is a contrived example but this sort of thing can easily happen for any set of changes you can't keep all in your head and do in one go. In general, a 3WM always has two variable elements, change A and change B. To reproduce all the information in that, you need four views for all the possible permutations of: 0 (the original), A, B, and AB (the merge).

Project: Merge is a comparison and merge tool I've written for XML. I looked at the standard 4-pane approach and almost instantly discarded it as being a very wasteful way of displaying data. A point amply proven in the screenshots above where nearly all panes are showing exactly the same data multiple times.
I therefore developed a single pane approach for displaying all input files and showing which of them contributes to the output. (Or where the differences are when comparing files.) While I haven't allowed completely free form editing of text (mostly due to how the XML nodes are managed and referenced) some parts of the merge output can be edited more or less as you would in a regular text editor. (My editor keyboard shortcuts closely follow those of Visual Studio as far as navigation is concerned.) Most notably character data, comments, and attribute values. You can also cut and paste XML nodes in their entirety. (But obviously only as text to external applications.)
The following screenshot shows a three-way merge with most changes appearing in the 'left' file, and an unresolved conflict below the selected change:

Personally, I like the free perforce merge tool (p4merge). It also has 4 windows - top middle for the original (before branching), left for destination branch, right for source branch and the bottom part is editable.
I like this better than your option 1, as all 3 original files may have important information that can influence the merge.

There are basically two ways to display differences between two files:
Two panels side by side
One panel
Graphically:
aaa aaa
bbb ···
··· ccc
ddd ddd
and
aaa
-bbb
+ccc
ddd
Some program use the first one (e.g. WinMerge) and some programs allow to choose (e.g. TortoiseMerge or Google Project Hosting). It's probably a matter of taste but I find the second one more intuitive when you want to track changes. However, you need two panels when you want to edit changes.
When doing three-way merges, the different layouts come from this. Ultra compare uses the single panel approach to display changes so you get two panels plus a third panel to edit. Other programs use the two panel approach to display changes so you get three panels plus a fourth one for edits.
Again, I believe it's just a matter of taste.

Related

Is there a way to properly dump the navigation history in Visual Studio?

Very frequently, I will be looking for a specific section of code where something happens, and will reach there by starting at a function at a high level of abstraction and go lower by successively opening the code of called methods. Eventually I will find what I'm looking for, and I would like to save the path that I took to get there - which is pretty much what the call stack would be if I had put a breakpoint in that code and stopped here at runtime, except that I'm just inspecting the code.
I'm aware the little arrow next to the "Back" arrow lets me somewhat get that in the UI and I can then take a screenshot of what I'm shown, but that's not a fantastic solution. The names of the functions are trimmed (leading to cases where it could match several functions), the line number is seldom shown (only if there was no code at that line), and I would much rather have the text format to begin with so I can copy the function names into a search tool rather than type them from the screenshot later.
So I was wondering: is there a way to dump the navigation history in Visual Studio ?
Where I could for ex. ask for the last 50 cursor positions, and get the file, file path, line number & possibly the code at that line in text format or some more intelligent thing, should the IDE support that.
Thanks.
PS: I found this very similar question Is there extension for viewing navigation history in Visual studio? that's >5 years old and didn't have a satisfying answer, so I'm trying my luck again, hoping things have changed since if there was no solution back then.

How to move all open Notepad++ files in all views into one single view?

The Issue
When you have Chrome browser open, if you have many different "windows" (as in "open in new window" vs "open in new tab") open, as I often do, it is useful to be able to join them all into one single window, leaving each tab intact. I use an extension called JoinTabs and it works great. A different extension, OneTab, merges all tabs into one tab by converting the individual tabs into hyperlinks -- that is not what I'm trying to do.
What I'm asking is if Notepad++ has configuration settings, a keyboard shortcut, or a plugin that will accomplish the same thing. By "the same thing", I mean not 'merging' all open documents into one document, but rather merging multiple documents dispersed across multiple Notepad++ instances (windows) into one windows.
Example
So, to be ultra clear, lets say I had three Notepad++ instances/windows/views open, and lets refer to them as A, B, and C for ease of discussion. A has 10 files open, B has 3 files open, and C has 5 files open. A working solution must move all open file tabs into window A and remove windows B & C, such that window A now will contain all 18 tabs.
Whenever I search for "join", "merge", or "combine" I keep getting text/document operations instead of view/display operations.
Research
When I search for this all I find are a bunch of false positives including stuff about:
Merging files into one
Merging lines
Merging all files in a directory
Using the 'combine' plugin from Heinz
FYI: Though it can be a little ambiguous, I've tried to take the ambiguity out of it by clarifying -- with a clear example -- what I'm asking. The 'combine' plugin doesn't do anything close to what I'm asking, and it can easily be seen if one take the time to read the description on the author website which says:
3 files (1.txt, 2.txt, 3.txt) can be combined to one file
Those are all entirely different than what I'm asking.
We are not after one file ... but rather all files in one window.
Looking at the Notepad++ Plugin Manager, there is an entry called combine:
...and based on the plugin's description, sounds like what you are seeking?
I have never used the combine plugin, so I have no other details.

Possible to change tab completion behavior in fish shell?

Update: This complaint relates to an old version of fish -- see the below comment from one of the fish developers describing the awesome improvements to the fish pager behavior which nullified this complaint.
The fish shell is pretty cool -- however I hate one of the features of tab-completion.
I frequently -- almost like a nervous tick -- will hit {tab}{tab} while typing a path when changing directories. This lets me use {tab} to examine the contents of some path while simultaneously solving however much of the path disambiguation problem my current keystrokes allow to be solved. This gives a great way to quickly discover the quickest key combination to get to a certain place in the filesystem without a lot of thought or necessarily having to know the contents of the various directories in advance.
Fish on the other hand interprets {tab} {tab} in what I consider to be an incredibly annoying way. The first {tab} lists the possible completions, that's great. The next tab is pressed fish selects the first completion in the list and replaces the last portion of the path currently entered on the line with the full first completion -- regardless of disambiguation status. Subsequent tabs cycle through the next possibilities. Its similar to what the windows command shell does.
This is far worse than the normal bash behavior ...
Consider a deeply nested directory structure foo/bar/baz/a/b/c/
Where some of foo, bar, baz, are empty directories. Bash tab completion lets me type cd foo/{tab}{tab}{tab}{tab}{tab}{tab} -- without having to think about how many times I'm hitting tab, without having to think through the effects in advance of hitting tab on the current state of my command line entry.
The normal case all these directories won't be empty -- but the above still works to very quickly discover the fewest number of characters I need to enter to make it to some deeply nested path.
With bash behavior:
cd some/unknown/dir/{tab}{tab} guarantees that
(1) I see the contents of the directory dir/
(2) as much of what can unambiguously be expressed from my command so far is completed, but no more.
After hitting the two tabs above I might see contents like this:
abc123
bar123
baz123
bcd123
mnop123
the following actions are possible:
a{TAB}{TAB} (gives me abc123 and if this is a directory lists its contents)
m{tab}{tab} (gives me mnop123 and if its a directory lists its contents)
Suppose I want to get to the path bcd123:
b -- shows me that I was too fast in my typing, with only 3 options now shown I easily conclude I need only hit 'c' to disambiguate to my goal
b{tab}{tab}c{tab}{tab} (gets me the path I want, lists bcd123's contents if its a directory)
fish's model is much worse. b{tab}{tab} would've completed to bar123, and I have to hit tab an unknown number of times to get the value I wanted, furthermore I have no way of getting the entry context back to only the letters that I've actually typed up to this point (other than hitting backspace a whole bunch of times). What if there happen to be a whole bunch of things that start with ba in this directory -- I'm totally screwed is what happens ...
In general fish's model is worse:
it does not allow using tab to complete nested paths -- to do this with fish you need to '/' at the correct time within the command sequence -- which requires mental feedback
much more difficult to discover disambiguation sequences when in large directories
in general requires you to 'be careful' before you hit tab which makes you hit it less often and decreases its utility ...
Somone please tell me there's a way to change fish's behavior here to be more like bash ... fish is cool but this behavior is unusable -- I'll have to go back to bash if there's not a way to change this ...
I commend you for writing up this detailed and thoughtful post, and it deserves an equally detailed and thoughtful response!
The tab completion behavior has been rewritten in fish top-of-tree (not yet released), and is referred to as the "new pager." You can see the design goals and discussion here. I put a note at the bottom of this reply for how to get it.
Shells are personal, and like anything personal, rationalizations and justifications aren't worth anything: you either like it, or you don't, and we may not even be conscious of the factors influencing our feelings. So all I can really say is try it, see how you feel, and (please) report back.
I put up a short little screencast of the new pager on YouTube. Things to notice: 1. the menu is dismissed just by typing more, 2. it "unfurls" progressively (requires a few tabs to become fully visible), never modally takes over your screen even when there's a huge number of completions, and is easily searchable and navigable, and 3. escape will always dismiss it and put your command line back to just what you typed.
Let me go through your concerns individually:
"I have to hit tab an unknown number of times to get the value I wanted". With the new pager, the selected item is highlighted in the menu. This sounds minor, but personally I believe this makes a huge difference: the number of additional times to hit tab becomes known, and since your finger is over tab, it's often easier to just hit it a few more times than to type additional letters. You can also use the arrow keys to navigate.
"I have no way of getting the entry context back to only the letters that I've actually typed up to this point". With the new pager, the escape key does exactly that. It's easy to press since escape is right above tab, where your finger is.
"What if there happen to be a whole bunch of things that start with ba in this directory -- I'm totally screwed is what happens". Neither bash nor old-pager-fish handles large numbers of completions well. fish would drop you into this modal paging environment, while bash breaks your flow with the modal "Display all 1002 possibilities? (y or n)" dialog that forces you to stop what you're doing and hit 'n'.
I think you'll love how the new pager handles this. Initially you get a short menu, that fills a maximum of five lines below your prompt (not above, and not replacing). This menu is non-modal, and is dismissed by typing more or hitting escape. If you hit tab again, the menu grows to show more completions, but is still non-modal. There's never a jarring transition.
"it does not allow using tab to complete nested paths" Sorry, I'm not sure what you mean by this. Both bash and fish append a / when tab completing a directory.
"much more difficult to discover disambiguation sequences when in large directories" With the new pager, you can hit escape, type some more, and then tab again. Or you can search the menu: put the focus in the menu and type something, and it's filtered. See the screencast above.
"in general requires you to 'be careful' before you hit tab which makes you hit it less often and decreases its utility" A very valid point, which the new pager addresses in a few ways. First of all, it uses a notion of progressive disclosure, which means that it takes "work" to output a lot of data. Second, it never "takes over your screen" like the old modal pager. And lastly, you can hit escape to get back to just what you typed, and since the pager appears below the prompt, it won't leave little turds in your scrollback like bash does.
If you're using homebrew, you can install from master via brew install fish --HEAD. There's also nightly builds for Linux. And lastly, feel free to open an issue at https://github.com/fish-shell/fish-shell/issues with any ideas for improvements you have.

How do you do a 3-way merge in FileMerge?

I see the option for specifying three files (left, right, and ancestor), but it doesn't seem to be possible to actually display the ancestor.
The bottom pane shows the result of the merge. I'd rather see what the original content was, so I could understand the context for the left and right sides of the conflict. Is this possible? FileMerge has awful help documentation.
Looks like in version 2.5 they have finally added this feature. "Ancestor" now actually means "Ancestor" and there is a separate "merge" option
From the command line you can do something like this:
$ opendiff mine theirs --ancestor base
Where "mine" is my version of the file, "theirs" is the version I'm trying to merge with, and "base" is the common ancestor of "mine" and "theirs.
This command will open File Merge and show the ancestor at the bottom (where the merge is in my example from 2010).
Unfortunately, it's not possible to use the --merge option along with the --ancestor option. So you can't view a three-way merge AND use File Merge to resolve the conflicts at the same time.
I am starting to use File Merge for viewing and understanding the conflict, then editing the conflict markers in a text editor as usual. (sigh...)
To my knowledge, this is not possible with filemerge.
Paid (but very good) app: http://www.deltopia.com/
Open source: http://sourcegear.com/diffmerge/
#mehaase:
That is not exactly correct. Here is the documentation on the new ancestor option from FileMerge Help:
Sometimes, you need to compare two versions of a file that have been modified
independently. For example, say two people branch a file; that is, they make
copies of a file and modify it. In this case, specify an ancestor file, which
is the common ancestor of the modified files.
The ancestor file lets FileMerge choose when to take changes from the left
file or the right file. For example, say the left file and the right file
contain a different version of line 33. If line 33 in the ancestor matches
line 33 in the left file, you know the change happened after the two files
branched off, and FileMerge prefers the newer version of line 33 in the right
file. If line 33 is different among the three files, you know that the files’
editors edited the lines separately. FileMerge displays that difference with
a red border and asks you to choose with edit to use.
So the ancestor is still not displayed, but it helps the merge tool to make a little more informed decisions when it decides to choose the left or right sides by default.
I realise this answer technically doesn't answer the question on how to do it with FileMerge, but I use kdiff3 (available for Windows, Mac and *nix) and it shows the base/ancestor, plus left and right, plus output/result, for a 3-way merge. (http://kdiff3.sourceforge.net/)
It's not a pretty user interface, but (IMHO) it's fairly simple to use and works well. And it's open source. :-)

Fastest way to "jump back" to a file in TextMate?

Often, when I am reading code or debugging, I want the ability to quickly jump around files. I especially want to "go back" to where I was. I know about "Command+T", "Command+Shift+T", and, bookmarks. But, I cannot figure out a way to jump around files quickly.
UPDATE: I do not think I my question was clear enough judging by two answers given. Specifically, I am looking for a way to "jump back" to where I was in a file. I know how to navigate in TextMate (in general). I want to know if TextMate has a "jump back" key binding.
It's subtle.
The command-T thing has the files listed in Most Recently Used order.
So, you can go command-T return to get back to your last file real quick. At first I couldn't find it either.
I don't think there's a go to last edit location as there is in, say, IDEA/RubyMine.
Courtesy of MacroMates.com
2.3 Moving Between Files (With Grace)
When working with projects there are a few ways to move between the open files.
The most straightforward way is by clicking on the file tab you need. This can also be done from the keyboard by pressing ⌘1-9, which will switch to file tab 1-9.
You can also use ⌥⌘← and ⌥⌘→ to select the file tab to the left or right of the current one.
It is possible to re-arrange the file tabs by using the mouse to drag-sort them (click and hold the mouse button on a tab and then drag it to the new location). This should make it possible to arrange them so that keyboard switching is more natural.
One more key is ⌥⌘↑ which cycles through text files with the same base name as the current file. This is mainly useful when working with languages which have an interface file (header) and implementation file (source).
When you want to move to a file which is not open you can use the Go to File… action in the Navigation menu (bound to ⌘T). This opens a window like the one shown below.
Go To File
This window lists all text files in the project sorted by last use, which means pressing return will open (or go to) the last file you worked on. So using it this way makes for easy switching to the most recently used file.
You can enter a filter string to narrow down the number of files shown. This filter string is matched against the filenames as an abbreviation and the files are sorted according to how well they match the given abbreviation. For example in the picture above the filter string is otv and TextMate determines that OakTextView.h is the best match for that (by placing it at the top).
The file I want is OakTextView.mm which ranks as #2. But since I have already corrected it in the past, TextMate has learned that this is the match that should go together with the otv filter string, i.e. it is adaptive and learns from your usage patterns.
If you have a project window open, you can leave frequently-accessed files open (in tabs), and then use ⌘+1-9 to jump to open tabs.

Resources