| A description of GIT's unidiff-compatible patch extensions, which we might |
| use for "svn patch" format. Copied from Augie Fackler's email |
| <http://subversion.tigris.org/ds/viewMessage.do?dsForumId=462&dsMessageId=2388540>. |
| |
| Documentation for the format is pretty sparse. Here's an overview (now |
| that I've written this out, it might be more like "everything you need |
| to know to support this format other than specifics of how base85 |
| works"): |
| |
| Copies and renames are both handled like this: |
| diff --git a/{oldname} b/{newname} |
| copy from {oldname} |
| copy to {newname} |
| {normal unidiff data here if there was a difference, only for how new |
| is different from old} |
| |
| (naturally, with copy instead of rename if that was the case} |
| |
| New files: |
| diff --git a/alpha b/alpha |
| new file mode 100644 |
| --- /dev/null |
| +++ b/alpha |
| @@ -0,0 +1,1 @@ |
| +alpha |
| |
| (the longer file mode is used for representing symlinks, they come in |
| with mode 120000, and the contents are listed as *just* the path of |
| the symlink, that is, svn's symlink format without the leading 'link ') |
| |
| Removals: |
| diff --git a/README b/README |
| deleted file mode 100644 |
| --- a/README |
| +++ /dev/null |
| @@ -1,77 +0,0 @@ |
| {pile of unidiff data} |
| |
| File mode changes: |
| diff --git a/README b/README |
| old mode 100644 |
| new mode 100755 |
| (I think it's normal for patch implementations to not care about the |
| old mode, and just apply the new one blindly - the old mode I believe |
| is more for human consumption or reverse-patching than anything else. |
| Also, you don't really ever see any modes other than these two - the |
| first is just "not executable", the second is executable. I've never |
| *seen* any other modes for regular files). |
| |
| Binaries (this is for literals, which I believe is the new binary in |
| its entirety. I think there's a delta format which Mercurial does not |
| support, per a "TODO: deltas" in the code): |
| index {old hash}..{new hash} |
| GIT binary patch |
| literal {file length} |
| {base85-encoded zlib-compressed data} |
| |
| The hashes are either the nullid (40 0's) if there was (or is) no |
| text, and are |
| sha1('blob %d\0%s' % (len(text), text, )) (using python syntax). |
| The base85 encoding seems to use a leading z to indicate this isn't |
| the last line of data, and a leading e to indicate this is the last |
| line of data. There's more to base85 than that, and I'd gladly take |
| some time to write down how it works for those interested in |
| reimplementing it. It appears at first glance to be the part that |
| requries the most detailed documentation. |
| |
| Supporting binary deltas is something that can obviously come later, |
| since Mercurial doesn't appear to implement it at all right now. Note |
| that with binary literals it does not appear that patch -R is |
| possible. That's really a minor limitation, since you're never using |
| this on non-version-controlled files anyway. |
| |
| It should be possible to add your own hunk types to this format (once |
| the base format is supported) that would allow you to transmit |
| property modifications inline as well (other than symlink and |
| executable, which are already handled sanely). |
| |
| For those interested in some source code (GPLv2): |
| http://mercurial.selenic.com/hg/hg/file/ac02b43bc08a/mercurial/patch.py#l195 |
| http://mercurial.selenic.com/hg/hg/file/ac02b43bc08a/mercurial/patch.py#l710 |
| http://mercurial.selenic.com/hg/hg/file/ac02b43bc08a/mercurial/pure/base85.py |
| |