Patching in Eclipse Galileo

Learn to apply and share changes

Eclipse Galileo includes new features for applying patches, including the ability to copy a patch to the clipboard and paste it directly into the Project Explorer. This article introduces this and provides an overview of the method for creating and applying patches, and includes an overview of the patch format used by Eclipse.

Nathan A. Good, Senior Information Engineer, Freelance Developer

Nathan GoodNathan A. Good lives in the Twin Cities area of Minnesota. Professionally, he does software development, software architecture, and systems administration. When he's not writing software, he enjoys building PCs and servers, reading about and working with new technologies, and trying to get his friends to make the move to open source software. He's written and co-written many books and articles, including Professional Red Hat Enterprise Linux 3, Regular Expression Recipes: A Problem-Solution Approach, and Foundations of PEAR: Rapid PHP Development.



03 November 2009

Also available in Japanese Portuguese

This article discusses patching in Eclipse, including a feature introduced in Eclipse Galileo. To take advantage of the examples in this article, you need to have Eclipse installed and a source-code repository, such as Subversion (SVN) or Concurrent Versions System (CVS), available.

Problem

The Eclipse integrated development environment (IDE) facilitates work in a team environment by providing features that allow you to integrate with a source-control management system directly from the IDE. These features not only enable you to get source, view changes, and commit them but also provide the ability to work with changes by applying patches to code.

Patches can be exchanges in the form of files that contain the changes among versions of your code in a standard diff format. When created correctly, the patch files contain only the differences between the modified files and the files in your workspace. Not only does this make the patches smaller but it also makes it easier to apply the patches more selectively.

Sometimes in team development environments, it's necessary to share changes to the code base directly from developer to developer. Different scenarios for using patch files include:

  • The change comes from outside the team — for example, in open source code when the change could come from someone in the community.
  • The change cannot be committed into the current source tree for some reason, such as a breaking change, that would affect the build.
  • The change is complex and needs to be integrated with another change before being committed into the source-code management system.

An advantage of a patch file is that it can be submitted as an attachment to an e-mail message or bug report. The patch file can then be applied to the source to integrate the modified code.


Patch format overview

When you create patches in Eclipse, the patch is written in unified diff format. This means that you can create diffs from CVS or SVN and apply them to your Eclipse project. It also means that you can rely on a standard format for the patch files so they're easily shared. diff files come in several formats (see Resources to learn more about them).

Understanding the patch file format is not critical to understanding how to apply them in Eclipse, but having a basic understanding of the diff file format used by Eclipse can help you troubleshoot problems and understand what to expect when applying a patch.

For example, see the simple Motorcycle class in Listing 1. In this article, it serves as a baseline example from which you'll make changes and see how the patch file appears in later examples.

Listing 1. The example Motorcycle class
package com.nathangood.examples;

public class Motorcycle {

    private int cc;
    private String model;
    private String make;
    private String year;

    public String getModel() {
        return model;
    }

    public int getCc() {
        return cc;
    }

    public void setCc(int cc) {
        this.cc = cc;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public String getMake() {
        return make;
    }

    public void setMake(String make) {
        this.make = make;
    }

    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }
}

Add a simple constructor to the class, such as the constructor in Listing 2.

Listing 2. A simple constructor using make
    public Motorcycle(String make) {
        super();
        this.make = make;
    }

Now when you generate a unified diff between the modified class and the original version of the class, your diff will look like the one in Listing 3.

Listing 3. The patch for adding the constructor
Index: src/com/nathangood/examples/Motorcycle.java
===================================================================
--- src/com/nathangood/examples/Motorcycle.java    (revision 3)
+++ src/com/nathangood/examples/Motorcycle.java    (working copy)
@@ -7,6 +7,11 @@
     private String make;
     private String year;
 
+    public Motorcycle(String make) {
+        super();
+        this.make = make;
+    }
+
     public String getModel() {
         return model;
     }

The patch file contains only the new lines that have been added, plus a few lines before and after that provide some context for the change.

Note the following line in the patch file: @@ -7,6 +7,11 @@. This line provides the line numbers and ranges of the changes immediately following it. The minus sign (-) or plus sign (+) before each change corresponds with the file names directly above the line. In this example, - refers to revision 3, and + refers to the working copy.

The changes in the working copy, which is the new version of the file, start at line 7 and go for 11 lines, including the lines shown for context. The original version of the file, called revision 3 in this example, included only six lines. The difference between the two are the five new lines with a + in front of them.

Consider another example by removing the accessors for the make variable, getMake() and setMake()— discarding the changes to the constructor for the moment. The patch showing the differences would look like Listing 4.

Listing 4. An example of removing elements with a patch
Index: src/com/nathangood/examples/Motorcycle.java
===================================================================
--- src/com/nathangood/examples/Motorcycle.java    (revision 3)
+++ src/com/nathangood/examples/Motorcycle.java    (working copy)
@@ -23,14 +23,6 @@
         this.model = model;
     }
 
-    public String getMake() {
-        return make;
-    }
-
-    public void setMake(String make) {
-        this.make = make;
-    }
-
     public String getYear() {
         return year;
     }

The patch shows that the context of the changes started on line 23 of the version of the file in the repository (revision 3) and went for 14 lines. Because lines from the file have been deleted, the context of the new change also starts on line 23 and spans only six lines. The lines to be deleted start with a -.

Finally, consider a modification to the original file (again discarding the last changes). The changes are shown in bold in Listing 5, demonstrating a renaming of cc to cubicCentimeters.

Listing 5. An example of modifying elements with a patch
Index: src/com/nathangood/examples/Motorcycle.java
===================================================================
--- src/com/nathangood/examples/Motorcycle.java    (revision 3)
+++ src/com/nathangood/examples/Motorcycle.java    (working copy)
@@ -2,7 +2,7 @@
 
 public class Motorcycle {
 
-    private int cc;
+    private int cubicCentimeters;
     private String model;
     private String make;
     private String year;
@@ -11,12 +11,12 @@
         return model;
     }
 
-    public int getCc() {
-        return cc;
+    public int getCubicCentimeters() {
+        return cubicCentimeters;
     }
 
-    public void setCc(int cc) {
-        this.cc = cc;
+    public void setCubicCentimeters(int cubicCentimeters) {
+        this.cubicCentimeters = cubicCentimeters;
     }
 
     public void setModel(String model) {

The patch showing the changes is a little more sophisticated than simple additions or deletions because it shows the change by combining the two.

The context of the first change starts at line 2 and goes for seven lines. The context of the changed file contains the same range because one line has been removed and one line has been added to make the change. The original line containing cc was replaced with the new line containing cubicCentimeters. The second modification in the file is done in the context that starts on line 11 and goes for 12 lines in the same manner.


Creating a simple patch

Now that you understand the basic structure of the patch file, you can create one in Eclipse to apply it to the same project in another workspace. If you'd rather run through these examples in the same workspace, simply make changes to a file in source control in Eclipse. Create the patch and revert to the original version of the file. You can then reapply the patch to see the changes you made come back again.

With the original version of the Motorcycle class, use the Source menu to generate a few constructors, like those shown in Listing 6.

Listing 6. Example new constructors
    public Motorcycle() {
        super();
    }
    
    public Motorcycle(int cc, String model, String make, String year) {
        super();
        this.cc = cc;
        this.model = model;
        this.make = make;
        this.year = year;
    }

In Eclipse, open the context menu (usually the right mouse button) on the project and choose Team > Create Patch.

In the Create Patch window, select Save in File System (see Figure 1) and click Browse to find a suitable location for your new patch file. Click Next when finished.

Figure 1. Create Patch
Image showing Create Patch

On the next step, choose Project (see Figure 2) and click Finish. You can create a patch for more than one project in your workspace at the same time. When you choose Project, Eclipse builds the patch using the current project as the root directory for the patch and ignores the changes in the other projects. Limiting the patch scope to your project can be simpler because it reduces the number of changes you need to review later.

Figure 2. Selecting the patch root
Image showing how to select the patch root

Viewing the patch

After Eclipse creates the patch file, you can view it in Eclipse by clicking File > Open File to open the file. The patch will look similar to the one in Listing 7.

Listing 7. The patch that adds the new constructors
Index: src/com/nathangood/examples/Motorcycle.java
===================================================================
--- src/com/nathangood/examples/Motorcycle.java    (revision 3)
+++ src/com/nathangood/examples/Motorcycle.java    (working copy)
@@ -6,7 +6,19 @@
     private String model;
     private String make;
     private String year;
-
+    
+    public Motorcycle() {
+        super();
+    }
+    
+    public Motorcycle(int cc, String model, String make, String year) {
+        super();
+        this.cc = cc;
+        this.model = model;
+        this.make = make;
+        this.year = year;
+    }
+    
     public String getModel() {
         return model;
     }

Applying a patch in Package Explorer

If you only have a single workspace available, revert the changes that you made to Motorcycle.java. Alternatively, you can switch to a workspace with original versions of the project files in it.

On an original version of the project, use the Team > Apply Patch context menu item to open the Apply Patch wizard shown in Figure 3. Select File, then click Browse to find the location of the patch file you created in "Creating a simple patch."

Figure 3. Choosing the input for the patch
Graphic depicting how to choose input for the patch

Because you created the patch based on a project and not a workspace root, select Apply the patch to the selected file and select the project folder from the list (see Figure 4). Click Next.

Figure 4. Choosing the target for the patch
Image showing how to choose the target for the patch

The next screen, shown in Figure 5, shows a comparison between the original version (Local Copy) and the version including the modifications (After Patch). Because this is a Java™ file, the Java Structure Compare section shows the differences in the file in an outline form, which makes it somewhat easier to understand.

Figure 5. Reviewing the changes before applying them
Graphic depicting reviewing the changes before applying them

If you are confident of the changes shown, click Finish.

Now when you open the file, it includes the changes you made before.

An alternative method of applying patches with Eclipse Galileo is to simply paste the contents into the Package Explorer view. If you have Eclipse Galileo installed, you can apply the patch that you created by:

  1. Opening the patch file you created in a text editor.
  2. Copying the contents of the file to your clipboard.
  3. In the Package Explorer, right-clicking on the project and selecting Paste from the context menu.
  4. Following the wizard as shown when applying the patch from a file.

Patching options

In the Review Patch step shown in Figure 5, there are several options for applying a patch. The simple patch in the previous example did not require any changes to the default options on the Review Patch step. However, there are some cases when you might need to modify the settings while you are reviewing the patch to get the results you want.

When applying a patch, sometimes you get errors in the Patch Contents list during the Review Patch step (see Figure 6). This is a good indication that you need to modify some of the patch options.

Figure 6. Dealing with errors while applying a patch
Dealing with errors while applying a patch

The Ignore leading path name segments option is useful if your original directory structure in the patch is different from the version to which you're applying the patch. You can simulate this behavior by creating the patch for the project and selecting the src folder in the Target Resource step (Figure 4) of the Apply Patch wizard. You will get errors (as in Figure 6), but if you change the Ignore leading path name segments value to 1 Eclipse can apply the patch correctly.

The Show matched hunks option displays the line numbers and context in the Patch Contents list.

The Fuzz factor option allows you to tell Eclipse to ignore some of the context lines when applying the patch. In the example in this article, the need for a Fuzz factor can be simulated by using the Source > Sort Members menu option to sort the original file before attempting to apply that patch. Because some of the context lines will now be out of order, you need the Fuzz factor to correctly apply the patch. You can click Guess to have Eclipse to make its best attempt at finding the Fuzz factor for you, or you can modify the setting until you're confident of the changes.

The Show Excluded option shows excluded patch operations, if any.

The Generate a .rej file for unmerged hunks stores the entries from the patch file that were not applied during the operation. To see this behavior in action, use the patch containing the new constructor, but before applying it, type your own, slightly different, constructor — like the one in Listing 8.

Listing 8. Adding a local constructor to create a conflict
    public Motorcycle() {
        // TODO:  Create some conflict with this constructor
    }

When you attempt to apply the patch, there will now be a conflict between the code in the patch file and the code in the Motorcycle class. The conflict will not be applied to the modified file. Instead, it will be written to a file called Motorcycle.java.rej, as shown in Listing 9.

Listing 9. The rejected patch code
@@ -5,6 +5,10 @@
     private String model;
     private String make;
     private String year;
+    
+    public Motorcycle() {
+        super();
+    }
 
     public String getModel() {
         return model;

The file shown in Listing 9 is not a complete, valid patch file. But you could use it to create a patch for the class if the conflicts were resolved first.


Creating a patch in the Synchronize View

Another method of creating a patch is in the Synchronize View, after synchronizing your changes with your code repository. To create a patch in the Synchronize View, open the Team Synchronizing perspective and click the synchronize button shown in Figure 7.

Figure 7. The synchronize button
Image depicting the synchronize button

Open the context menu for the project in the Synchronize View and click Create Patch. From there, follow the patch creation process described in "Creating a Simple Patch."


Reverse patches

A reverse patch does just that: It reverses the action of the patch being applied. Instead of lines being added, they are removed. Lines that would be removed in the patch are instead added. You can use a reverse patch to revert certain changes from a previous version of a file or to back out changes from a patch that caused problems.

Summary

Eclipse's team tools allow you to easily share changes to code using patches in standard unified diff format. Team members can now apply patches submitted as attachments in files using the new method of pasting the patch contents in the Package Explorer in Eclipse Galileo.

Resources

Learn

Get products and technologies

Discuss

  • The Eclipse Platform newsgroups should be your first stop to discuss questions regarding Eclipse. (Selecting this will launch your default Usenet news reader application and open eclipse.platform.)
  • The Eclipse newsgroups has many resources for people interested in using and extending Eclipse.
  • Participate in developerWorks blogs and get involved in the developerWorks community.

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Open source on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source, Java technology
ArticleID=441721
ArticleTitle=Patching in Eclipse Galileo
publish-date=11032009