--- a/mercurial/commands.py Mon Aug 14 15:51:35 2006 -0700
+++ b/mercurial/commands.py Mon Aug 14 22:48:03 2006 -0700
@@ -2877,6 +2877,7 @@
('a', 'text', None, _('treat all files as text')),
('p', 'show-function', None,
_('show which function each change is in')),
+ ('g', 'git', None, _('use git extended diff format')),
('w', 'ignore-all-space', None,
_('ignore white space when comparing lines')),
('b', 'ignore-space-change', None,
--- a/mercurial/mdiff.py Mon Aug 14 15:51:35 2006 -0700
+++ b/mercurial/mdiff.py Mon Aug 14 22:48:03 2006 -0700
@@ -23,6 +23,7 @@
'''context is the number of context lines
text treats all files as text
showfunc enables diff -p output
+ git enables the git extended patch format
ignorews ignores all whitespace changes in the diff
ignorewsamount ignores changes in the amount of whitespace
ignoreblanklines ignores changes whose lines are all blank'''
@@ -31,6 +32,7 @@
'context': 3,
'text': False,
'showfunc': True,
+ 'git': False,
'ignorews': False,
'ignorewsamount': False,
'ignoreblanklines': False,
--- a/mercurial/patch.py Mon Aug 14 15:51:35 2006 -0700
+++ b/mercurial/patch.py Mon Aug 14 22:48:03 2006 -0700
@@ -298,6 +298,9 @@
return _date2
def read(f):
return repo.file(f).read(mmap2[f])
+ def renamed(f):
+ src = repo.file(f).renamed(mmap2[f])
+ return src and src[0] or None
else:
tz = util.makedate()[1]
_date2 = util.datestr()
@@ -309,6 +312,8 @@
return _date2
def read(f):
return repo.wread(f)
+ def renamed(f):
+ return repo.dirstate.copies.get(f)
if repo.ui.quiet:
r = None
@@ -316,16 +321,65 @@
hexfunc = repo.ui.verbose and hex or short
r = [hexfunc(node) for node in [node1, node2] if node]
+ if opts.git:
+ copied = {}
+ for f in added:
+ src = renamed(f)
+ if src:
+ copied[f] = src
+ srcs = [x[1] for x in copied.items()]
+
all = modified + added + removed
all.sort()
for f in all:
to = None
tn = None
+ dodiff = True
if f in mmap:
to = repo.file(f).read(mmap[f])
if f not in removed:
tn = read(f)
- fp.write(mdiff.unidiff(to, date1, tn, date2(f), f, r, opts=opts))
+ if opts.git:
+ def gitmode(x):
+ return x and '100755' or '100644'
+ def addmodehdr(header, omode, nmode):
+ if omode != nmode:
+ header.append('old mode %s\n' % omode)
+ header.append('new mode %s\n' % nmode)
+
+ a, b = f, f
+ header = []
+ if f in added:
+ if node2:
+ mode = gitmode(mmap2.execf(f))
+ else:
+ mode = gitmode(util.is_exec(repo.wjoin(f), None))
+ if f in copied:
+ a = copied[f]
+ omode = gitmode(mmap.execf(a))
+ addmodehdr(header, omode, mode)
+ op = a in removed and 'rename' or 'copy'
+ header.append('%s from %s\n' % (op, a))
+ header.append('%s to %s\n' % (op, f))
+ to = repo.file(a).read(mmap[a])
+ else:
+ header.append('new file mode %s\n' % mode)
+ elif f in removed:
+ if f in srcs:
+ dodiff = False
+ else:
+ mode = gitmode(mmap.execf(f))
+ header.append('deleted file mode %s\n' % mode)
+ else:
+ omode = gitmode(mmap.execf(f))
+ nmode = gitmode(util.is_exec(repo.wjoin(f), mmap.execf(f)))
+ addmodehdr(header, omode, nmode)
+ r = None
+ if dodiff:
+ header.insert(0, 'diff --git a/%s b/%s\n' % (a, b))
+ fp.write(''.join(header))
+ if dodiff:
+ fp.write(mdiff.unidiff(to, date1, tn, date2(f), f, r, opts=opts))
def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False,
opts=None):
--- a/mercurial/ui.py Mon Aug 14 15:51:35 2006 -0700
+++ b/mercurial/ui.py Mon Aug 14 22:48:03 2006 -0700
@@ -174,6 +174,8 @@
text=opts.get('text'),
showfunc=(opts.get('show_function') or
self.configbool('diff', 'showfunc', None)),
+ git=(opts.get('git') or
+ self.configbool('diff', 'git', None)),
ignorews=(opts.get('ignore_all_space') or
self.configbool('diff', 'ignorews', None)),
ignorewsamount=(opts.get('ignore_space_change') or
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-git-export Mon Aug 14 22:48:03 2006 -0700
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+hg init a
+cd a
+
+echo start > start
+hg ci -Amstart -d '0 0'
+echo new > new
+hg ci -Amnew -d '0 0'
+echo '% new file'
+hg diff --git -r 0 | sed "s/\(\(---\|+++\) [a-zA-Z0-9_/.-]*\).*/\1/"
+
+hg cp new copy
+hg ci -mcopy -d '0 0'
+echo '% copy'
+hg diff --git -r 1:tip | sed "s/\(\(---\|+++\) [a-zA-Z0-9_/.-]*\).*/\1/"
+
+hg mv copy rename
+hg ci -mrename -d '0 0'
+echo '% rename'
+hg diff --git -r 2:tip | sed "s/\(\(---\|+++\) [a-zA-Z0-9_/.-]*\).*/\1/"
+
+hg rm rename
+hg ci -mdelete -d '0 0'
+echo '% delete'
+hg diff --git -r 3:tip | sed "s/\(\(---\|+++\) [a-zA-Z0-9_/.-]*\).*/\1/"
+
+cat > src <<EOF
+1
+2
+3
+4
+5
+EOF
+hg ci -Amsrc -d '0 0'
+chmod +x src
+hg ci -munexec -d '0 0'
+echo '% chmod 644'
+hg diff --git -r 5:tip | sed "s/\(\(---\|+++\) [a-zA-Z0-9_/.-]*\).*/\1/"
+
+hg mv src dst
+chmod -x dst
+echo a >> dst
+hg ci -mrenamemod -d '0 0'
+echo '% rename+mod+chmod'
+hg diff --git -r 6:tip | sed "s/\(\(---\|+++\) [a-zA-Z0-9_/.-]*\).*/\1/"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-git-export.out Mon Aug 14 22:48:03 2006 -0700
@@ -0,0 +1,42 @@
+adding start
+adding new
+% new file
+diff --git a/new b/new
+new file mode 100644
+--- /dev/null
++++ b/new
+@@ -0,0 +1,1 @@
++new
+% copy
+diff --git a/new b/copy
+copy from new
+copy to copy
+% rename
+diff --git a/copy b/rename
+rename from copy
+rename to rename
+% delete
+diff --git a/rename b/rename
+deleted file mode 100644
+--- a/rename
++++ /dev/null
+@@ -1,1 +0,0 @@
+-new
+adding src
+% chmod 644
+diff --git a/src b/src
+old mode 100644
+new mode 100755
+% rename+mod+chmod
+diff --git a/src b/dst
+old mode 100755
+new mode 100644
+rename from src
+rename to dst
+--- a/dst
++++ b/dst
+@@ -3,3 +3,4 @@ 3
+ 3
+ 4
+ 5
++a
--- a/tests/test-help.out Mon Aug 14 15:51:35 2006 -0700
+++ b/tests/test-help.out Mon Aug 14 22:48:03 2006 -0700
@@ -176,6 +176,7 @@
-r --rev revision
-a --text treat all files as text
-p --show-function show which function each change is in
+ -g --git use git extended diff format
-w --ignore-all-space ignore white space when comparing lines
-b --ignore-space-change ignore changes in the amount of white space
-B --ignore-blank-lines ignore changes whose lines are all blank