简体   繁体   中英

Understanding why Patch created with git diff -w --patience does not apply

I'm trying to clean up a pull request that we received at a project that I admin for.

The contributor added a lot of unnecessary white-space changes in along with the functional contribution. He re-indented most of several files. It needs to be done, but it should be a separate commit. I'm not accepting changes that read as an almost total re-write of a file for ~80 lines of added feature.

I've generated a patch by redirecting git diff -w --patience to a file, and it seems to be what I want: A relatively few specific lines added or deleted, and when reading the context, the changes make sense. I'm okay with the few changed lines being indented inconsistently from the rest of the file for the time being.

git apply claims that the patch does not apply. patch -p1 -v basically lists all of the hunks, and states that each one does not apply. It creates a .rej file that is simply a restatement of the patch. patch -p1 --merge manages to get part of the first hunk, and leaves the file filled with merge markers that are... odd.

The really frustrating part for me is that the revision that I am trying to apply the patch too is the exact same parent that I used to generate the diff!

Patch: (Sorry, its long)

diff --git a/ArtOfIllusion/src/artofillusion/ScrollViewTool.java b/ArtOfIllusion/src/artofillusion/ScrollViewTool.java
index e0f9af35..91fcb863 100644
--- a/ArtOfIllusion/src/artofillusion/ScrollViewTool.java
+++ b/ArtOfIllusion/src/artofillusion/ScrollViewTool.java
@@ -20,15 +20,17 @@ import java.awt.*;
 import java.awt.event.*;
 import javax.swing.Timer;

+/** ScrollViewTool is a tool to handle mouse scroll wheel events in scene and object views. 
+    It moves the viewpoint in view z-directi and/or in some cases changes view orientation. */
+
 public class ScrollViewTool
 {
     private EditingWindow window;
-   private MouseScrolledEvent event;
     private ViewerCanvas view;
     private Camera camera;
     private double distToPlane;
     private double scrollRadius, scrollBlend, scrollBlendX, scrollBlendY; // for graphics
-   private int navigationMode;
+    private int navigationMode, scrollSteps;
     private Rectangle bounds;
     private Point mousePoint;
     private CoordinateSystem startCoords;
@@ -42,7 +44,9 @@ public class ScrollViewTool

     protected void mouseScrolled(MouseScrolledEvent e, ViewerCanvas v)
     {
-       event = e;
+       scrollSteps = v.scrollBuffer;
+        v.scrollBuffer = 0;
+        v.mouseMoving = false;
         view = v;
         view.scrolling = true;
         distToPlane = view.getDistToPlane();
@@ -50,13 +54,13 @@ public class ScrollViewTool
         bounds = view.getBounds();
         camera = view.getCamera();
         boundCamera = view.getBoundCamera();
-       if (boundCamera != null)
-           startCoords = boundCamera.getCoords().duplicate();
+        if (!scrollTimer.isRunning())
+            startCoords = camera.getCameraCoordinates().duplicate();

         // Make sure that the rotation Center is on Camera Z-axis.
         // After a SceneCamera is read from a file, that may not be the case.
-       // A SceneCamera should have a 'distToPlane' that should be saved with the camera.
-       // Makin it saveable will cause version incompatibility.
+        // Any bound should have a 'distToPlane' that should be saved with the object.
+
         CoordinateSystem coords = camera.getCameraCoordinates();
         view.setRotationCenter(coords.getOrigin().plus(coords.getZDirection().times(view.getDistToPlane())));

@@ -77,15 +81,9 @@ public class ScrollViewTool
                 break;
         }

-       if (boundCamera != null && window != null) // wonder why the window is here...
-       {
-           boundCamera.setCoords(camera.getCameraCoordinates().duplicate());
-           ((SceneCamera)boundCamera.getObject()).setDistToPlane(distToPlane);
-           moveCameraChildren(boundCamera, boundCamera.getCoords().fromLocal().times(startCoords.toLocal()));
-
-       }
         setAuxGraphs(view);
         repaintAllViews(view);
+       //view.repaint
         view.viewChanged(false);
     }

@@ -100,7 +98,7 @@ public class ScrollViewTool
         {
             CoordinateSystem coords = camera.getCameraCoordinates();
             double oldDist = distToPlane;
-           //double newDist = oldDist*Math.pow(1.0/1.01, amount); // This woud reverse the action
+            //double newDist = oldDist*Math.pow(1.0/1.01, amount); // This would reverse the action
             double newDist = oldDist*Math.pow(1.01, amount);
             Vec3 oldPos = new Vec3(coords.getOrigin());
             Vec3 newPos = view.getRotationCenter().plus(coords.getZDirection().times(-newDist));
@@ -224,8 +222,17 @@ public class ScrollViewTool

     public void mouseStoppedScrolling()
     {
-       // This should set an undorecord if a camera moved
+       if (window != null && boundCamera != null)
+        {
+            boundCamera.getCoords().copyCoords(camera.getCameraCoordinates());
+            if (boundCamera.getObject() instanceof SceneCamera) ((SceneCamera)boundCamera.getObject()).setDistToPlane(distToPlane);
+
+            UndoRecord undo = new UndoRecord(window, false, UndoRecord.COPY_COORDS, new Object [] {boundCamera.getCoords(), startCoords});
+            moveCameraChildren(boundCamera, boundCamera.getCoords().fromLocal().times(startCoords.toLocal()), undo);
+            window.setUndoRecord(undo);
+        }
         wipeAuxGraphs();
+        window.updateImage();
     }

     private Timer scrollTimer = new Timer(500, new ActionListener() 
@@ -250,15 +257,16 @@ public class ScrollViewTool

     /** 
         This is called recursively to move any children of a bound camera. 
-       This does not set an undo record.
     */
-   private void moveCameraChildren(ObjectInfo parent, Mat4 transform)
+    private void moveCameraChildren(ObjectInfo parent, Mat4 transform, UndoRecord undo)
     {    
         for (int i = 0; i < parent.getChildren().length; i++)
         {
             CoordinateSystem coords = parent.getChildren()[i].getCoords();
+            CoordinateSystem previousCoords = coords.duplicate();
             coords.transformCoordinates(transform);
-           moveCameraChildren(parent.getChildren()[i], transform);
+            undo.addCommand(UndoRecord.COPY_COORDS, new Object [] {coords, previousCoords});
+            moveCameraChildren(parent.getChildren()[i], transform, undo);
         }  
     }

@@ -273,7 +281,6 @@ public class ScrollViewTool

     private void setAuxGraphs(ViewerCanvas view)
     {
-
         if (window != null)
             for (ViewerCanvas v : window.getAllViews())
                 if (v != view)
@@ -287,7 +294,8 @@ public class ScrollViewTool
                v.auxGraphs.wipe();
     }       

-   /** Maybe some day? */
     public void drawOverlay()
-   {}
+    {
+        // This could draw a "ghost" of the bound camera and it's children during scroll
+    }
 }

I have truncated this patch to an extent: I've removed a diff for a second file, which is applying correctly.

The file to which I'm trying to apply the patch on github - permalink

The (messy) commit that I started from Note: there are other commits in this PR. Right now, I'm trying to work with the first one. Note that its direct parent is the same revision that I linked above.

Any Ideas on why this patch is being so grouchy, or how to troubleshoot it, would be appreciated.

As @torek nudged me towards, the patch is not quite what I had expected:

The context lines generated by -w and -b options for git diff do not match the parent file, instead, the whitespace involved matches the 'messy' commit. Both git apply and patch do not like this.

When they look at the expected context from the patch, they think that the context does not match, and that the patch therefore cannot be applied. Varous 'ignore whitespace', &tc. options do not seem to affect this.


The Workaround:

Get rid of the context lines. Generate the patches with git diff -w -U0 (U for unified diff format, 0 for number of context lines), which leaves only the line numbers and replacement line data. Since this is a clean patch (Applied to the revision that was the parent of the original commit) The line numbers are the only thing that patch needs. NOTE: git apply still did not like these patches for some reason, though patch seems to think they are just mahvelous .

If you try it:

This only works if the file that you are applying to is the line for line equivalent of the one used as a base for the diff. In practice, if you have a series of messy commits {1, 2, 3} on top of a clean base, 0 , you need to:

  • Create a new branch, starting at 0 .
  • Generate your patch for 1 against 0
  • Apply the patch to your new branch as 1a
  • Generate your patch for 2 against the new, clean commit 1a
  • &tc, as needed

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM