Search code examples
gitversion-controlgit-addgit-patch

Manually editing using git add --patch <filename>


So, I've got a file I've been working on in branch A, and I'm just about ready to commit it. However, looking at the diff, I think it's better to put it into two separate commits (Well, in this case, two separate branches, maybe). I've used git add --patch before to stage separate hunks, so I thought I could use this. The problem is, I need to split one of my hunks. Running git add --patch SdA.py and using e to edit the problem hunk...

# Manual hunk edit mode -- see bottom for a quick guide
@@ -50,13 +50,74 @@ import PIL.Image as im

 import constant

+
+def exp_range(min=None, max=None, step=None):
+    """
+    Generate an exponentially increasing value scaled and offset such
+    that it covers the range (min, max].  Behaviour is similar to
+    exp(x), scaled such that the final value generated is equal to
+    'max'.  'step' defines the granularity of the exponential
+    function.  The default value is 5, corresponding to a step-size
+    of tau.
+
+    :type min: float
+    :param min: minimum value of range (offset)
+
+    :type max: float
+    :param max: Maximum (final) value of range
+
+    :type step: int
+    :param step: Number of incremental steps within the range
+                 (min, max]
+    
+    """
+    if min is None:
+        raise StopIteration
+
+    # One input argument (same as range(10))
+    if min is not None and max is None and step is None:
+        step = min
+        min = 0.
+        max = 1.
+    elif step is None:
+        step = 5
+
+    for i in xrange(step):
+        exp_rate = np.exp(i - (step-1))
+        yield min + (max - min) * exp_rate
+    raise StopIteration
+
+
 def norm(input):
+    """
+    Return the norm of a vector or row-wise norm of a matrix
+
+    :type input: theano.tensor.TensorType
+    :param input: Theano array or matrix to take the norm of.
+    
+    """
     return T.sqrt((input * input).sum(axis=0))


 def normalize(vector, scale=1.0, offset=0.5):
+    """
+    Normalize (Zero and scale) a vector such that it's peak to peak
+    value is equal to 'scale', and it is centered about 'offset'.
+
+    :type vector: numpy.ndarray
+    :param vector: Vector to normalize to the given parameters.
+
+    :type scale: float
+    :param scale: Peak-to-peak range to stretch or shrink the vector's
+                  current peak-to-peak range to.
+
+    :type offset: float
+    :param offset: Value at which to center the peak-to-peak range at.
+    
+    """
     return (vector - vector.min()) * scale / vector.ptp()

+

That's okay. There's a mini-guide on the bottom. I get that. So, we want to put the new function in this commit, and the documentation for the other functions into another commit. According to the mini-doc: # To remove '+' lines, delete them.

# Manual hunk edit mode -- see bottom for a quick guide
@@ -50,13 +50,74 @@ import PIL.Image as im

 import constant

+
+def exp_range(min=None, max=None, step=None):
+    """
+    Generate an exponentially increasing value scaled and offset such
+    that it covers the range (min, max].  Behaviour is similar to
+    exp(x), scaled such that the final value generated is equal to
+    'max'.  'step' defines the granularity of the exponential
+    function.  The default value is 5, corresponding to a step-size
+    of tau.
+
+    :type min: float
+    :param min: minimum value of range (offset)
+
+    :type max: float
+    :param max: Maximum (final) value of range
+
+    :type step: int
+    :param step: Number of incremental steps within the range
+                 (min, max]
+    
+    """
+    if min is None:
+        raise StopIteration
+
+    # One input argument (same as range(10))
+    if min is not None and max is None and step is None:
+        step = min
+        min = 0.
+        max = 1.
+    elif step is None:
+        step = 5
+
+    for i in xrange(step):
+        exp_rate = np.exp(i - (step-1))
+        yield min + (max - min) * exp_rate
+    raise StopIteration
+
+
 def norm(input):
     return T.sqrt((input * input).sum(axis=0))


 def normalize(vector, scale=1.0, offset=0.5):
     return (vector - vector.min()) * scale / vector.ptp()

That looks good. Let's add that puppy...

error: patch failed: SdA.py:50
error: SdA.py: patch does not apply
Your edited hunk does not apply. Edit again (saying "no" discards!) [y/n]?

Mmkay... git add --interactive "Your edited hunk does not apply" and How to read the output from git diff? explain that I have to update the affected line numbers. To do this, now, I can manually count and say "Hmm, I've removed 1, 2, 3... 23 lines. I was editing 74 lines previously, now I'm editing... hmm... wish I had a calculator... .... 51 lines" ('whew, I'm sweaty')

This seems like an overcomplicated method. I still think patch is the right approach, but I must be doing something wrong if I need to manually update the number of affected lines in the to-file. Anyone have any advice on how to do this more easily and efficiently?


Solution

  • Commenting out the lines to remove, with #, rather than deleting them, solves this issue. I'm not certain if the behaviour is part of emacs, but commenting a line actually decrements the counter at the top of the patch message. Another feature I found useful was to use s to first split the hunk, then add each one independently. In this particular example, that would have been the better solution.