8000 GitHub - mannewalis/python-patch at wiki
[go: up one dir, main page]

Skip to content

mannewalis/python-patch

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

History

The project started because Windows platform lacks native tool to apply patches, and there was no cross-platform solution that could be safely run by web server process.

Usually patches are applied with a UNIX patch utility from GNU tools. It is ported to windows, but still feels buggy and insecure for web server process. It is also not customizable without a C compiler, which is a problem for Windows. So it was good to have a good utility written in Python that can be potential *diff.py* counterpart.

patch.py is meant to be a command line tool with intuitive defaults, taking care of the most problems (e.g. line end differences) automatically.

Status

API status: API is unstable, so use strict dependencies on major version number when using this tool as a library.

It understands only unified diffs. Currently it doesn't support file renames, creation and removals.

Note that patch.py was not designed to reproduce original files. Parsing is a lossy process where data is normalized to be cross-platform. Absolute paths are stripped as well as references to parent directories, backslashes are converted to forward slashes and so on.

patch.py is designed to transparently handle line end differences. Line endings from patch are converted into best suitable format for patched file. patch.py scans line endings in source file, and if they are consistent - lines from patch are applied with the same ending. If source linefeeds are inconsistend - lines from patch are applied "as is".

Parsing of diff is done in a in very straightforward manner as an exercise to approach the problem of parsing on my own before learning the 'proper ways'. Thanks creators, the format of unified diff is rather simple (an illustration of Subversion style unified diff is included in source doc/ directory).

Features

  • Automatic correction of
    • Linefeeds according to patched file
    • Diffs broken by stripping trailing whitespace
    • a/ and b/ prefixes
  • Single file, which is a command line tool and library
  • Python 2.5+ compatible, 2.7 tested, 3 not supported
  • No dependencies outside Python stdlib
  • Patch format detection (SVN, HG, GIT)
  • Test coverage for easy modification
  • Nice diffstat histogram

Things that don't work:

  • Python 3
  • File renaming, creation and removal
  • Directory tree operations
  • Version control specific properties
  • Non-unified diff formats

Library usage

See APIUseCases.

Changes


1.xx.x

   - --revert option to apply patches in reverse order (unpatch)
   - support for broken patches generated by online Google Code editor
   - API changes:
     + PatchSet and Patch objects are now iterable
     + new PatchSet.findfile() contains logic detecting filename to patch
     + PatchSet.revert()
   - make directory based tests easier to create and run manually
   - fix xnormpath with Windows paths on Linux
     (issue #24, found by Philippe Ombredanne)

1.13

   - diffstat output now also shows size delta in bytes
   - added --directory (-d) option to specify root when applying patches
   - hunk headers produced by `diff -p` option are now parsed and accessible
     (issue #22, found by Philippe Ombredanne)
   - API changes:
     + Hunk.desc field to access hunk headers content
     + PatchSet.apply() gets `root` keyword argument for the working dir
       when applying patches (issue #7)
   - improve error message for missing files
   - improve docs (fix issue #5)

1.12.11  Major API Break

   - patch.py can read patches from stdin
   - patch.py can show nice histogram with --diffstat option
   - added detection of SVN, GIT and HG patch types, unrecognized
     patches marked as PLAIN
   - added error reporting for parsing functions and helpers (now they
     return False if parsing failed) - make sure you handle this correctly
   - added normalization to filenames to protect against patching files
     using absolute paths or files in parent directories
   - test run patch.py on all patches submitted to Python bug tracker, which
     resulted in improved parsing and error handling for some corner cases
   - improved logging
   - API changes
     * fromfile(), fromstring() and fromurl() now return False on errors
     * previous Patch is renamed to PatchSet, new Patch is single file entry
     * Patch.header is now a list of strings
     * PatchSet.parse() now returns True if parsing completed without errors
     + PatchSet.__len__()
     + PatchSet.diffstat()
     + PatchSet.type and Patch.type
     + PatchSet.errors and 
     + xisabs() cross-platform version of `os.path.isabs()`
     + xnormpath() forward slashed version of `os.path.normpath()`
     + xstrip() to strip absolute path prefixes

11.01
   - patch.py can read patches from web
   - patch.py returns -1 if there were errors during patching
   - store patch headers (necessary for future DIFF/SVN/HG/GIT detection)
   - report about extra bytes at the end after patch is parsed
   - API changes
     + fromurl()
     * Patch.apply() now returns True on success
10.11
   - fixed fromstring() failure due to invalid StringIO import (issue #9)
     (thanks john.stumpo for reporting)
   - added --verbose and --quiet options
   - improved message logging
   - change "successfully patched..." message to INFO instead of WARN
     (thanks Alex Stewart for reporting and patch)
   - skip __main__ imports when used as a library (patch by Alex Stewart)
   - API changes
      * renamed class HunkInfo to Hunk
      + Patch.type placeholder (no detection yet - parser is not ready)
      + constants for patch types DIFF/PLAIN, HG/MERCURIAL, SVN/SUBVERSION
      + Patch.header for saving headers which can be used later to extract
        additional meta information such as commit message
   - internal: improving parser speed by allowing blocks fetch lines on
               demand
   - test suite improvements
10.04
    - renamed debug option to --debug
    - API changes
      * method names are now underscored for consistency with difflib
      + addded Patch.can_patch(filename) to test if source file is in list
        of source filenames and can be patched
      * use designated logger "python_patch" instead of default
9.08-2
    - compatibility fix for Python 2.4
9.08-1
    - fixed issue #2 - remove trailing whitespaces from filename
      (thanks James from Twisted Fish)
    - API changes
      + added Patch and HunkInfo classes
      * moved utility methods into Patch
      + build Patch object by specifying stream to constructor
        or use top level functions fromfile() and fromstring()
    - added test suite
8.06-2
    - compatibility fix for Python 2.4
8.06-1
    - initial release

Future

Patch utility in Python makes it possible to implement online "submit, review and apply" module. Similar to Review Board for code, but suitable for all kind of textual content that uses unified diffs as an interchange format between users, website, and version control system. With this system patches can be applied after on site review, automatically storing the names of patch contributors in SVN history logs without requiring write access for these contributors. This system is not the scope of this project though.

Additional unified diff parsers may be added in future to compare different parsing techniques (with pyparsing, SPARK or others as example).

See also https://code.google.com/p/rainforce/wiki/ModerationQueue

It would be nice to further simplify parser, make it more modular to allow easy customization and extension, but the primary focus for now is to figure out an API that will make it usable as a library. There is separate TODO item to check behavior of "\ No newline at end of file" cases. Other goals is to expand test coverage, and try to make script more interactive.

About

Patches are welcome

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • HTML 73.0%
  • Python 14.3%
  • C++ 9.1%
  • JavaScript 2.4%
  • CSS 0.8%
  • C 0.3%
  • Other 0.1%
0