Visualization and Selective Undo of Fine-Grained Code Changes
1. Visualization of
Fine-Grained Code Change History
YoungSeok Yoon
Institute for Software Research (ISR)
Brad A. Myers
Human-Computer Interaction Institute (HCII)
Sebon Koo
Human-Computer Interaction Institute (HCII)
School of Computer Science
Carnegie Mellon University
Presented at VL/HCC 2013
September 18th, 2013
4. Initial Code
private JPanel createButtons() {
JPanel buttonPanel = new JPanel();
JButton button1 = new JButton("Button 1");
JButton button2 = new JButton("Button 2");
JButton button3 = new JButton("Button 3");
buttonPanel.add(button1);
buttonPanel.add(button2);
buttonPanel.add(button3);
return buttonPanel;
}
VL/HCC 2013 4
5. First Attempt: GridBagLayout
private JPanel createButtons() {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
// c.fill will make all buttons the same width
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
JButton button1 = new JButton("Button 1");
JButton button2 = new JButton("Button 2");
JButton button3 = new JButton("Button 3");
buttonPanel.add(button1);
buttonPanel.add(button2);
buttonPanel.add(button3);
return buttonPanel;
}
VL/HCC 2013 5
The code already looks
too complicated
for the simple vertical layout!
Remove this code
with “Undo”
6. Second Attempt: BoxLayout
private JPanel createButtons() {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(
buttonPanel, BoxLayout.Y_AXIS));
JButton button1 = new JButton("Button 1");
JButton button2 = new JButton("Button 2");
JButton button3 = new JButton("Button 3");
buttonPanel.add(button1);
buttonPanel.add(button2);
buttonPanel.add(button3);
return buttonPanel;
}
VL/HCC 2013 6
Looks promising
+ much simpler code!
8. However…
• BoxLayout does not support spacing
between GUI elements
• He wants to restore the
GridBagLayout code, but it’s gone!
VL/HCC 2013 8
9. Undo command can’t bring this code back
private JPanel createButtons() {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
// c.fill will make all buttons the same width
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
JButton button1 = new JButton("Button 1");
JButton button2 = new JButton("Button 2");
JButton button3 = new JButton("Button 3");
buttonPanel.add(button1);
buttonPanel.add(button2);
buttonPanel.add(button3);
return buttonPanel;
}
VL/HCC 2013 9
Removed this code
with “Undo”
10. Undo command can’t bring this code back
private JPanel createButtons() {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(
buttonPanel, BoxLayout.Y_AXIS));
JButton buttonOrange = new JButton(“Orange");
buttonOrange.setBackground(Color.orange);
JButton button2 = new JButton("Button 2");
JButton button3 = new JButton("Button 3");
buttonPanel.add(buttonOrange);
buttonPanel.add(button2);
buttonPanel.add(button3);
return buttonPanel;
}
VL/HCC 2013 10
11. Our Tool: AZURITE
• AZURITE
– Allows selectively undoing
fine-grained code changes
– Developed as an Eclipse plug-in
• “AZURITE”
– Adding Zest to
Undoing and Restoring
Improves Textual Exploration
VL/HCC 2013 11
<Azurite, Velvet Beauty1>1 Attribution: cobalt, flickr.com – CC BY-SA 2.0
13. How can we support this?
• Automatically record the
fine-grained code change history
– e.g., FLUORITE [Yoon+11], CODINGTRACKER [Negara+12]
• Provide usable interfaces and commands
for interacting with the code change history
– focus of this talk!
VL/HCC 2013 13
14. This talk is about…
Our new visualizations of
fine-grained code change history,
new editor commands for developers
including selective undo commands
executed on the fine-grained history
VL/HCC 2013 14
18. Basic Features: Time
• New information is always added to the right
VL/HCC 2013 18
And the indicator moves accordingly
19. Compact Mode
• Problem: Horizontal gaps between the rectangles
(only 20% of their time editing code [Ko+05])
• Compact mode: removes all the horizontal gaps
VL/HCC 2013 19
What if we removed these gaps?
20. Multiple Sessions
• By default, only the history of the
current editing session is shown
• An old history can be brought back
VL/HCC 2013 20
21. Multiple Sessions
• By default, only the history of the
current editing session is shown
• An old history can be brought back
VL/HCC 2013 21
22. Multiple Sessions
• By default, only the history of the
current editing session is shown
• An old history can be brought back
VL/HCC 2013 22
A session divider (gray vertical line)
23. Rectangles = Edit Operations
• Each rectangle represents a code edit operation
(one of Insert, Delete, or Replace)
VL/HCC 2013 23
24. Coalescing Operations
• Multiple operations are merged into a single edit
– Edit operations can have different durations
VL/HCC 2013 24
25. Size / Location
• Width: Duration of the edit
• Vertical location/height: Relative location and size of the
edit within the file
• Minimum width and height for small edits
VL/HCC 2013 25
26. Tooltip
• Hovering mouse on a rectangle shows a tooltip with
more detailed information
VL/HCC 2013 26
This change replaced a
constant “800” with a
variable named “width”
27. Multiple Files
• Each row contains the history of a single file
• The most recently edited file is always brought to top
VL/HCC 2013 27
Each row contains the
edit history of one file
31. Selective Undo
• Undoes only the selected edits without
affecting the other edits
VL/HCC 2013 31
32. Undo Everything After Selection
• Undoes all changes made after the current
selection
• A shortcut for undoing multiple operations from
the back of the history
VL/HCC 2013 32
33. Jump to the Affected Code
• Enabled when a single rectangle is selected
• Opens the relevant file in the code editor and
moves the cursor to the location where the
operation was performed
VL/HCC 2013 33
34. Jump to the Affected Code
VL/HCC 2013 34
Can be considered as
automatic bookmarks of
the edited locations
35. Show All Files Edited Together
VL/HCC 2013 35
What other files
were edited
between these two
operations?
The files edited
within the same
timeframe are
brought to top
36. HISTORY SEARCH
Well, but isn’t that too difficult to select
the “correct” rectangles?
VL/HCC 2013 36
38. Selective Undo
• Selectively undoing A requires selecting all the
edits performed in region A
VL/HCC 2013 38
(3) Later, it turns out A was a mistake, so the
user wants to undo A.
At the same time, the user does not want to
lose the changes made in B.
Selective Undo!
39. Finding All Changes in Region
• AZURITE provides
“Select corresponding rectangles” command
VL/HCC 2013 39
40. Finding Code through History
• AZURITE allows searching for
a certain code (or text)
through the edit history
VL/HCC 2013 40
When did I have that
GridBagLayout
code?
41. Finding Code through History
• Highlights all the rectangles
within the time interval(s)
when the search text existed
in the code
VL/HCC 2013 41
When did I have that
GridBagLayout
code?
42. CODE HISTORY DIFF VIEW
It is still difficult to predict
the result of selective undo
VL/HCC 2013 42
43. Code History Diff View
• Users can select an arbitrary region of code and
launch code history diff view
VL/HCC 2013 43
44. Code History Diff View
VL/HCC 2013 44
Right panel:
Shows the current code
Left panel:
Shows a previous version at which
the red marker is pointing
45. Code History Diff View
VL/HCC 2013 45
The file name / location of the
selected region
50. Other Possible Benefits
• Answering history-related questions
[Fritz+10][LaToza+10]
– When, how was this code changed or inserted?
– How has it changed over time?
– Has this code always been this way?
• Code history diff view can answer these
questions at a fine-grain level
VL/HCC 2013 50
52. Preliminary Study Results
• Interviewed 2 users who were actively using AZURITE
– There were situations where AZURITE was useful
– The timeline is useful for keeping track of which files are being
edited
– Code history diff view “previews” the undo result, which is better
than regular undo command
• Suggestions for improvement (already implemented)
– Live preview of selective undo
– Having a way of marking the current point in time,
as a lightweight way of versioning
VL/HCC 2013 52
55. Conclusion
• Visualizing fine-grained code change history and
providing editor commands interacting with the history
can be useful for developers
• AZURITE is a publicly available Eclipse plug-in,
and we invite your feedback!
http://www.cs.cmu.edu/~azurite/
VL/HCC 2013 55
57. Performance
• Size of the logs
– Data collected from 19 developers for 17 months
– 291MB of data / 1059 hours of coding
– About 281.5 KB/hour
• Performance of the timeline visualization
VL/HCC 2013 57
58. Selective Undo
• Keeps track of all fine-grained code changes
• Maintains the correct locations of the previous
edits in the current state
• Deals with regional conflicts
VL/HCC 2013 58
Example
:myFontSize myRectangleSize myRegionArea
R1 R2
What should be the result of selectively undoing only R1?
myFontgionArea? myFontSize?
Or do nothing and keep it myRegionArea?
Probably don’t have to read the title, mention the co-authors.
To start with, let’s think about an example scenario a developer might face.Here’s a graphical user interface developer, who wants to implement a panel with three vertically located buttons with some amount of spacing between buttons.
First of all, it’s very unlikely that the GridBagLayout code is commited to the version control repository, because it was just an intermediate version which wasn’t even finished.In addition, undo command cannot bring this code back. Because…
Even if he did not use the undo command to remove the desired code,Undo command is still inappropriate to bring this code back.Now there are some parts of this code, the button decoration code, that he wants to retain,but using undo command will undo these code first, because they are the most recent edits.Therefore, what we need here is “selective undo”.
So we’re building a tool called Azurite, which allows selectively undoing “fine-grained” code changes.Selective undo only undoes some of the previous edits while not affecting the other changes.Azurite is developed as an Eclipse plug-in.Azurite is a blue mineral looking like this,and also an acronym for “adding zest to undoing and restoring improves textual exploration”
So let me quickly demo how Azurite can help resolving this problem.
So, what are the things the tool should do, in order to support these features?First of all, the tool should automatically record all the fine-grained code change history.Another important thing is providing usable interfaces and commands for interacting with the code change history.The second part here is the focus of today’s talk.
Throughout this talk, I will introduce our new visualizations of fine-grained code change history,And the new editor commands for developers including selective undo commands executed on the fine-grained history.
First, I would like to start with the very basic UI for seeing and interacting with the fine-grained code change history,which we call a timeline visualization.
Timeline visualization is the view shown at the bottom of the IDE,And it displays the fine-grained history information in a 2-dimensional space.Each colored box represents a previous edit, but I’ll explain the meaning of the boxes in detail shortly.For now, I want to focus on the time aspect of this visualization.As you could imagine, the horizontal axis represents time.
The yellow vertical line indicates “now”
Any new information is added to the right, and the yellow bar moves accordingly.
Because developers don’t edit source code all the time, there will be big horizontal gaps between the rectangles if we just display the history proportional to the actual time.So Azurite provides a compact mode, which removes all the horizontal gaps.Because of this, the timeline can be non-linear.
By default, only the current session’s history is shown, but the old history can be brought back into the history if the user wants.If the user closes Eclipse and re-launches it again later,
The timeline shows an empty history initially, and the user can make any changes from here.If the user clicks the “read previous log” button, the previous history is brought back to the timeline
And the gray vertical line is the border line between two consecutive editing sessions.
Each rectangle in the timeline represents a code edit operation, which can be one of Insert, Delete, and Replace.Timeline only adds new rectangles, and never removes them from the history, even for undo commandsWhen the user invokes undo, it will add a new rectangle which represents an inverse of the original operation.
Just like conventional text and code editors do, if the user types a lot, they are coalesced into a single edit.Because of this, edit operationscan have different durations depending on how they were coalesced.
So the width of a rectangle indicates the duration of the edit, and the vertical location and height indicate the relative location and size of the edit with respect to the entire file.In addition, there is a notion of minimum width and height, so the user can see the small edits in the timeline.
Use a fade animation to show the tooltip
So, the filenames shown on the left end becomes a list of the most recently edited files.
Say while the video is goingNow I’m zooming horizontally… and vertically… and scrolling.
Users can select one or more rectangles using mouse, and the selected rectangles are highlighted with the yellow outlines.Can span across multiple files, and be disconnected. put this on the slide, and take out the details on how to.
So far, I went through the features of the timeline visualization, and showed that users can see the change history and select one or more previous edits from the timeline.Then, what can we actually do with these selected operations?
Select the rectangles, invoke selective undo from the context menu.The results of this selective undo are added as inverse operations of the original edit.Multiple rectangles can be selected together and undone at once, even across multiple files.In fact, implementing selective undo is quite a challenging task, because the meaning of selective undo may not be well-defined when there are conflicts among the edit operations. I won’t go into the details of it in this talk, but Azurite can handle those edge cases.
Can be used as automatic bookmarks of recently edited locations
Recall that whenever a new change is made to a file, the corresponding row is always put to top.So, the order of these rows keep changes as new edits are made.When trying to investigate some previous history, it could be difficult to see what actually happened within some timeframe, when there are a lot of rows. If the user wants to see what other files were being edited in this timeframe, she can invoke “show All Files Edited Together” command to bring those files to top.
So far, I’ve talked about how the users can see the code change history, and how to select some of the previous edits and invoke some interesting commands.However, it could be difficult for users to select the desired edit operations, just by looking at the timeline.
Selectively undoing A requires selecting all the edits performed in region A.
Azurite also allows to search for a certain code (or text) through the edit history.For instance, in the GridBagLayout example that I presented earlier, suppose that the GUI developer couldn’t quite remember when exactly he had the GridBagLayout code.He can use this history search dialog, type in “GridBagLayout”, to find the time in the past when the text GridBagLayout existed in the code. This is tricky, because the provided code does not even exist in the current code.
The results will be highlighted in the timeline.
The right panel shows the “current” code, and the left panel shows one of the previous versions of the code snippet, where the red marker is pointing at.This is a side-by-side diff view, and the differences between the version on the left and the current version are highlighted.
This screenshot is showing code from the file DrawingEditor.java, lines 37-50
and for that code, there are 70 different versions, and we are currently viewing the 64th which dates back from Feb 28 at 10:29am.
The user can move back and forth through the history by dragging this red marker,Or using one of the navigation buttons.The user can revert this code snippet to the version currently shown on the left panel, using the “revert” button.
There can be multiple instances of these code history diff views, in which case the red vertical marker shown in the timeline is shared across all the views so that the user can easily see what was going on in multiple locations of code.
The Azurite features can be used in different ways.For example, imagine that the GUI developer we talked about before couldn’t exactly remember where in the source code the GridBagLayout code existed. But he is certain that the code was somewhere in this method. Let’s see how he can restore the desired code in this case.First, he selects the entire method and launches the code history diff view,Uses history search to find the time in past when “GridBagLayout” existed in this code,Moves the marker to the point where the desired code fully existed with the help of the history search results.At this point, if he uses the “revert” button, he would lose the code related to the orangeButton that he wants to retain.To avoid this problem, he just decides to copy the GridBagLayout Code from the left panel, and pastes the code in the code editor.As a result, he could achieve the same task of restoring the GridBagLayout code, taking a different path.The point I want to make here is that Azurite provides a rich set of features, and users can choose whatever method they feel the most comfortable.
Having these user interfaces can also be beneficial for answering some of the code change history related questions identified by previous research to be difficult and important to answer.Example questions include “when and how was this code changed or inserted?”Although existing version control systems can answer these questions to some extent,but Azurite’s code history diff view can answer these at a finer-grained level.
I have introduced many features, and user interfaces.Then this question follows naturally: “Are these really useful for the actual users?Although this part was not included in the paper, I would like to present some of the preliminary study results we got so far.
We started a field study over the summer, and getting some feedback from the users.[the first slide bullets]…To add to these results, personally, I’ve been using Azurite for the last six months while developing Azurite, and it was found to be useful for me as well. For instance, when performing an “extract method” refactoring manually, I could easily abort it by backtracking to the point where the code didn’t contain the extracted method name. There were a number of cases where I successfully restored some of the deleted code that I deleted but turned out to be needed later on.[the second slide bullets]…We already implemented these two features.Again, these were just added over the summer and not in the paper, but here’s how they look.
This is an interactive selective undo dialog we implemented, which provides a live preview of selective undo results, as the user selects or deselects some rectangles from the timeline.
Now users can mark the “current” point in time, so that it can be referred back later on, more easily.These can be named or left anonymous.
[first bullet point]And our preliminary field study results and my personal experience confirmed that it’s useful for real situations.Azurite is a publicly available Eclipse plug-in,and we would be delighted if you used it, too!