Show More
@@ -0,0 +1,8 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | hg init a | |||
|
4 | ln -s a link | |||
|
5 | cd a | |||
|
6 | echo foo > foo | |||
|
7 | hg status | |||
|
8 | hg status ../link |
@@ -57,7 +57,10 b' def dodiff(ui, repo, diffcmd, diffopts, ' | |||||
57 | def snapshot_node(files, node): |
|
57 | def snapshot_node(files, node): | |
58 | '''snapshot files as of some revision''' |
|
58 | '''snapshot files as of some revision''' | |
59 | mf = repo.changectx(node).manifest() |
|
59 | mf = repo.changectx(node).manifest() | |
60 |
dirname = |
|
60 | dirname = os.path.basename(repo.root) | |
|
61 | if dirname == "": | |||
|
62 | dirname = "root" | |||
|
63 | dirname = '%s.%s' % (dirname, short(node)) | |||
61 | base = os.path.join(tmproot, dirname) |
|
64 | base = os.path.join(tmproot, dirname) | |
62 | os.mkdir(base) |
|
65 | os.mkdir(base) | |
63 | if not ui.quiet: |
|
66 | if not ui.quiet: | |
@@ -74,7 +77,7 b' def dodiff(ui, repo, diffcmd, diffopts, ' | |||||
74 | if not os.path.isdir(destdir): |
|
77 | if not os.path.isdir(destdir): | |
75 | os.makedirs(destdir) |
|
78 | os.makedirs(destdir) | |
76 | data = repo.wwritedata(wfn, repo.file(wfn).read(mf[wfn])) |
|
79 | data = repo.wwritedata(wfn, repo.file(wfn).read(mf[wfn])) | |
77 | open(dest, 'w').write(data) |
|
80 | open(dest, 'wb').write(data) | |
78 | return dirname |
|
81 | return dirname | |
79 |
|
82 | |||
80 | def snapshot_wdir(files): |
|
83 | def snapshot_wdir(files): | |
@@ -82,6 +85,8 b' def dodiff(ui, repo, diffcmd, diffopts, ' | |||||
82 | if not using snapshot, -I/-X does not work and recursive diff |
|
85 | if not using snapshot, -I/-X does not work and recursive diff | |
83 | in tools like kdiff3 and meld displays too many files.''' |
|
86 | in tools like kdiff3 and meld displays too many files.''' | |
84 | dirname = os.path.basename(repo.root) |
|
87 | dirname = os.path.basename(repo.root) | |
|
88 | if dirname == "": | |||
|
89 | dirname = "root" | |||
85 | base = os.path.join(tmproot, dirname) |
|
90 | base = os.path.join(tmproot, dirname) | |
86 | os.mkdir(base) |
|
91 | os.mkdir(base) | |
87 | if not ui.quiet: |
|
92 | if not ui.quiet: | |
@@ -94,7 +99,7 b' def dodiff(ui, repo, diffcmd, diffopts, ' | |||||
94 | destdir = os.path.dirname(dest) |
|
99 | destdir = os.path.dirname(dest) | |
95 | if not os.path.isdir(destdir): |
|
100 | if not os.path.isdir(destdir): | |
96 | os.makedirs(destdir) |
|
101 | os.makedirs(destdir) | |
97 | fp = open(dest, 'w') |
|
102 | fp = open(dest, 'wb') | |
98 | for chunk in util.filechunkiter(repo.wopener(wfn)): |
|
103 | for chunk in util.filechunkiter(repo.wopener(wfn)): | |
99 | fp.write(chunk) |
|
104 | fp.write(chunk) | |
100 | return dirname |
|
105 | return dirname |
@@ -1501,7 +1501,6 b' def clone(ui, source, dest=None, **opts)' | |||||
1501 | sr = hg.repository(ui, ui.expandpath(source)) |
|
1501 | sr = hg.repository(ui, ui.expandpath(source)) | |
1502 | qbase, destrev = None, None |
|
1502 | qbase, destrev = None, None | |
1503 | if sr.local(): |
|
1503 | if sr.local(): | |
1504 | reposetup(ui, sr) |
|
|||
1505 | if sr.mq.applied: |
|
1504 | if sr.mq.applied: | |
1506 | qbase = revlog.bin(sr.mq.applied[0].rev) |
|
1505 | qbase = revlog.bin(sr.mq.applied[0].rev) | |
1507 | if not hg.islocal(dest): |
|
1506 | if not hg.islocal(dest): | |
@@ -1521,7 +1520,6 b' def clone(ui, source, dest=None, **opts)' | |||||
1521 | if dr.local(): |
|
1520 | if dr.local(): | |
1522 | if qbase: |
|
1521 | if qbase: | |
1523 | ui.note(_('stripping applied patches from destination repo\n')) |
|
1522 | ui.note(_('stripping applied patches from destination repo\n')) | |
1524 | reposetup(ui, dr) |
|
|||
1525 | dr.mq.strip(dr, qbase, update=False, backup=None) |
|
1523 | dr.mq.strip(dr, qbase, update=False, backup=None) | |
1526 | if not opts['noupdate']: |
|
1524 | if not opts['noupdate']: | |
1527 | ui.note(_('updating destination repo\n')) |
|
1525 | ui.note(_('updating destination repo\n')) |
@@ -136,11 +136,12 b' class notifier(object):' | |||||
136 | '''try to clean up email addresses.''' |
|
136 | '''try to clean up email addresses.''' | |
137 |
|
137 | |||
138 | addr = templater.email(addr.strip()) |
|
138 | addr = templater.email(addr.strip()) | |
139 | a = addr.find('@localhost') |
|
139 | if self.domain: | |
140 | if a != -1: |
|
140 | a = addr.find('@localhost') | |
141 |
|
|
141 | if a != -1: | |
142 | if '@' not in addr: |
|
142 | addr = addr[:a] | |
143 | return addr + '@' + self.domain |
|
143 | if '@' not in addr: | |
|
144 | return addr + '@' + self.domain | |||
144 | return addr |
|
145 | return addr | |
145 |
|
146 | |||
146 | def subscribers(self): |
|
147 | def subscribers(self): |
@@ -1134,8 +1134,12 b' class hgweb(object):' | |||||
1134 | try: |
|
1134 | try: | |
1135 | url = 'remote:%s:%s' % (proto, |
|
1135 | url = 'remote:%s:%s' % (proto, | |
1136 | req.env.get('REMOTE_HOST', '')) |
|
1136 | req.env.get('REMOTE_HOST', '')) | |
1137 | ret = self.repo.addchangegroup(util.chunkbuffer(gen), |
|
1137 | try: | |
1138 | 'serve', url) |
|
1138 | ret = self.repo.addchangegroup(util.chunkbuffer(gen), | |
|
1139 | 'serve', url) | |||
|
1140 | except util.Abort, inst: | |||
|
1141 | sys.stdout.write("abort: %s\n" % inst) | |||
|
1142 | ret = 0 | |||
1139 | finally: |
|
1143 | finally: | |
1140 | val = sys.stdout.getvalue() |
|
1144 | val = sys.stdout.getvalue() | |
1141 | sys.stdout = old_stdout |
|
1145 | sys.stdout = old_stdout |
@@ -222,8 +222,8 b' def create_server(ui, repo):' | |||||
222 | if self.webdir_conf: |
|
222 | if self.webdir_conf: | |
223 | hgwebobj = self.webdirmaker(self.webdir_conf, ui) |
|
223 | hgwebobj = self.webdirmaker(self.webdir_conf, ui) | |
224 | elif self.repo is not None: |
|
224 | elif self.repo is not None: | |
225 |
hgwebobj = self.repoviewmaker( |
|
225 | hgwebobj = self.repoviewmaker(hg.repository(repo.ui, | |
226 |
|
|
226 | repo.root)) | |
227 | else: |
|
227 | else: | |
228 | raise hg.RepoError(_("There is no Mercurial repository here" |
|
228 | raise hg.RepoError(_("There is no Mercurial repository here" | |
229 | " (.hg not found)")) |
|
229 | " (.hg not found)")) |
@@ -6,7 +6,7 b'' | |||||
6 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. | |
7 |
|
7 | |||
8 | from i18n import _ |
|
8 | from i18n import _ | |
9 | import os, smtplib, templater, util |
|
9 | import os, smtplib, templater, util, socket | |
10 |
|
10 | |||
11 | def _smtp(ui): |
|
11 | def _smtp(ui): | |
12 | '''send mail using smtp.''' |
|
12 | '''send mail using smtp.''' | |
@@ -21,6 +21,9 b' def _smtp(ui):' | |||||
21 | (mailhost, mailport)) |
|
21 | (mailhost, mailport)) | |
22 | s.connect(host=mailhost, port=mailport) |
|
22 | s.connect(host=mailhost, port=mailport) | |
23 | if ui.configbool('smtp', 'tls'): |
|
23 | if ui.configbool('smtp', 'tls'): | |
|
24 | if not hasattr(socket, 'ssl'): | |||
|
25 | raise util.Abort(_("can't use TLS: Python SSL support " | |||
|
26 | "not installed")) | |||
24 | ui.note(_('(using tls)\n')) |
|
27 | ui.note(_('(using tls)\n')) | |
25 | s.ehlo() |
|
28 | s.ehlo() | |
26 | s.starttls() |
|
29 | s.starttls() |
@@ -412,6 +412,8 b' def b85diff(fp, to, tn):' | |||||
412 | yield text[i:i+csize] |
|
412 | yield text[i:i+csize] | |
413 | i += csize |
|
413 | i += csize | |
414 |
|
414 | |||
|
415 | if to == tn: | |||
|
416 | return | |||
415 | # TODO: deltas |
|
417 | # TODO: deltas | |
416 | l = len(tn) |
|
418 | l = len(tn) | |
417 | fp.write('index %s..%s\nGIT binary patch\nliteral %s\n' % |
|
419 | fp.write('index %s..%s\nGIT binary patch\nliteral %s\n' % | |
@@ -560,8 +562,8 b' def diff(repo, node1=None, node2=None, f' | |||||
560 | to = getfilectx(a, ctx1).data() |
|
562 | to = getfilectx(a, ctx1).data() | |
561 | else: |
|
563 | else: | |
562 | header.append('new file mode %s\n' % mode) |
|
564 | header.append('new file mode %s\n' % mode) | |
563 |
|
|
565 | if util.binary(tn): | |
564 |
|
|
566 | dodiff = 'binary' | |
565 | elif f in removed: |
|
567 | elif f in removed: | |
566 | if f in srcs: |
|
568 | if f in srcs: | |
567 | dodiff = False |
|
569 | dodiff = False |
@@ -374,6 +374,9 b' def canonpath(root, cwd, myname):' | |||||
374 | except OSError: |
|
374 | except OSError: | |
375 | break |
|
375 | break | |
376 | if samestat(name_st, root_st): |
|
376 | if samestat(name_st, root_st): | |
|
377 | if not rel: | |||
|
378 | # name was actually the same as root (maybe a symlink) | |||
|
379 | return '' | |||
377 | rel.reverse() |
|
380 | rel.reverse() | |
378 | name = os.path.join(*rel) |
|
381 | name = os.path.join(*rel) | |
379 | audit_path(name) |
|
382 | audit_path(name) | |
@@ -846,8 +849,23 b" if os.name == 'nt':" | |||||
846 | def samestat(s1, s2): |
|
849 | def samestat(s1, s2): | |
847 | return False |
|
850 | return False | |
848 |
|
851 | |||
|
852 | # A sequence of backslashes is special iff it precedes a double quote: | |||
|
853 | # - if there's an even number of backslashes, the double quote is not | |||
|
854 | # quoted (i.e. it ends the quoted region) | |||
|
855 | # - if there's an odd number of backslashes, the double quote is quoted | |||
|
856 | # - in both cases, every pair of backslashes is unquoted into a single | |||
|
857 | # backslash | |||
|
858 | # (See http://msdn2.microsoft.com/en-us/library/a1y7w461.aspx ) | |||
|
859 | # So, to quote a string, we must surround it in double quotes, double | |||
|
860 | # the number of backslashes that preceed double quotes and add another | |||
|
861 | # backslash before every double quote (being careful with the double | |||
|
862 | # quote we've appended to the end) | |||
|
863 | _quotere = None | |||
849 | def shellquote(s): |
|
864 | def shellquote(s): | |
850 | return '"%s"' % s.replace('"', '\\"') |
|
865 | global _quotere | |
|
866 | if _quotere is None: | |||
|
867 | _quotere = re.compile(r'(\\*)("|\\$)') | |||
|
868 | return '"%s"' % _quotere.sub(r'\1\1\\\2', s) | |||
851 |
|
869 | |||
852 | def explain_exit(code): |
|
870 | def explain_exit(code): | |
853 | return _("exited with status %d") % code, code |
|
871 | return _("exited with status %d") % code, code |
@@ -61,6 +61,11 b' hg import -mfoo b.diff' | |||||
61 | cmp binfile.bin $TESTDIR/binfile.bin |
|
61 | cmp binfile.bin $TESTDIR/binfile.bin | |
62 |
|
62 | |||
63 | echo |
|
63 | echo | |
|
64 | echo '% rename binary file' | |||
|
65 | hg mv binfile.bin renamed.bin | |||
|
66 | hg diff --git | |||
|
67 | ||||
|
68 | echo | |||
64 | echo '% diff across many revisions' |
|
69 | echo '% diff across many revisions' | |
65 | hg mv dst dst2 |
|
70 | hg mv dst dst2 | |
66 | hg ci -m 'mv dst dst2' -d '0 0' |
|
71 | hg ci -m 'mv dst dst2' -d '0 0' |
@@ -66,6 +66,11 b' fQItJW-{SoTm)8|5##k|m00000NkvXXu0mjf{mKw' | |||||
66 | % import binary diff |
|
66 | % import binary diff | |
67 | applying b.diff |
|
67 | applying b.diff | |
68 |
|
68 | |||
|
69 | % rename binary file | |||
|
70 | diff --git a/binfile.bin b/renamed.bin | |||
|
71 | rename from binfile.bin | |||
|
72 | rename to renamed.bin | |||
|
73 | ||||
69 | % diff across many revisions |
|
74 | % diff across many revisions | |
70 | diff --git a/dst2 b/dst3 |
|
75 | diff --git a/dst2 b/dst3 | |
71 | rename from dst2 |
|
76 | rename from dst2 |
@@ -298,4 +298,42 b" hg ci -m merge -d '0 0'" | |||||
298 | hg log |
|
298 | hg log | |
299 | hg strip 1 2>&1 | sed 's/\(saving bundle to \).*/\1/' |
|
299 | hg strip 1 2>&1 | sed 's/\(saving bundle to \).*/\1/' | |
300 | hg log |
|
300 | hg log | |
|
301 | cd .. | |||
301 |
|
302 | |||
|
303 | echo '% qclone' | |||
|
304 | qlog() | |||
|
305 | { | |||
|
306 | echo 'main repo:' | |||
|
307 | hg log --template ' rev {rev}: {desc}\n' | |||
|
308 | echo 'patch repo:' | |||
|
309 | hg -R .hg/patches log --template ' rev {rev}: {desc}\n' | |||
|
310 | } | |||
|
311 | hg init qclonesource | |||
|
312 | cd qclonesource | |||
|
313 | echo foo > foo | |||
|
314 | hg add foo | |||
|
315 | hg ci -m 'add foo' | |||
|
316 | hg qinit -c | |||
|
317 | hg qnew patch1 | |||
|
318 | echo bar >> foo | |||
|
319 | hg qrefresh -m 'change foo' | |||
|
320 | hg qci -m checkpoint | |||
|
321 | qlog | |||
|
322 | cd .. | |||
|
323 | ||||
|
324 | # repo with patches applied | |||
|
325 | hg qclone qclonesource qclonedest | |||
|
326 | cd qclonedest | |||
|
327 | qlog | |||
|
328 | cd .. | |||
|
329 | ||||
|
330 | # repo with patches unapplied | |||
|
331 | cd qclonesource | |||
|
332 | hg qpop -a | |||
|
333 | qlog | |||
|
334 | cd .. | |||
|
335 | hg qclone qclonesource qclonedest2 | |||
|
336 | cd qclonedest2 | |||
|
337 | qlog | |||
|
338 | cd .. | |||
|
339 |
@@ -333,3 +333,26 b' user: test' | |||||
333 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
333 | date: Thu Jan 01 00:00:00 1970 +0000 | |
334 | summary: add foo |
|
334 | summary: add foo | |
335 |
|
335 | |||
|
336 | % qclone | |||
|
337 | main repo: | |||
|
338 | rev 1: change foo | |||
|
339 | rev 0: add foo | |||
|
340 | patch repo: | |||
|
341 | rev 0: checkpoint | |||
|
342 | 3 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
343 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
344 | main repo: | |||
|
345 | rev 0: add foo | |||
|
346 | patch repo: | |||
|
347 | rev 0: checkpoint | |||
|
348 | Patch queue now empty | |||
|
349 | main repo: | |||
|
350 | rev 0: add foo | |||
|
351 | patch repo: | |||
|
352 | rev 0: checkpoint | |||
|
353 | 3 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
354 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
355 | main repo: | |||
|
356 | rev 0: add foo | |||
|
357 | patch repo: | |||
|
358 | rev 0: checkpoint |
@@ -8,18 +8,14 b' notify=' | |||||
8 | incoming.notify = python:hgext.notify.hook |
|
8 | incoming.notify = python:hgext.notify.hook | |
9 |
|
9 | |||
10 | [notify] |
|
10 | [notify] | |
11 | config = $HGTMP/.notify.conf |
|
|||
12 | sources = pull |
|
11 | sources = pull | |
13 | domain = test.com |
|
|||
14 | strip = 3 |
|
|||
15 | template = Subject: {desc|firstline|strip}\nFrom: {author}\n\nchangeset {node|short} in {webroot}\ndescription:\n\t{desc|tabindent|strip} |
|
|||
16 | diffstat = False |
|
12 | diffstat = False | |
17 |
|
13 | |||
18 | [web] |
|
|||
19 | baseurl = http://test/ |
|
|||
20 |
|
||||
21 | [usersubs] |
|
14 | [usersubs] | |
22 | foo@bar = * |
|
15 | foo@bar = * | |
|
16 | ||||
|
17 | [reposubs] | |||
|
18 | * = baz | |||
23 | EOF |
|
19 | EOF | |
24 |
|
20 | |||
25 | hg help notify |
|
21 | hg help notify | |
@@ -35,6 +31,24 b' echo a >> a/a' | |||||
35 | echo % commit |
|
31 | echo % commit | |
36 | hg --traceback --cwd a commit -Amb -d '1 0' |
|
32 | hg --traceback --cwd a commit -Amb -d '1 0' | |
37 |
|
33 | |||
|
34 | echo '% pull (minimal config)' | |||
|
35 | hg --traceback --cwd b pull ../a 2>&1 | sed -e 's/\(Message-Id:\).*/\1/' \ | |||
|
36 | -e 's/changeset \([0-9a-f]* \)\?in .*test-notif/changeset \1in test-notif/' \ | |||
|
37 | -e 's/^details: .*test-notify/details: test-notify/' | |||
|
38 | ||||
|
39 | cat <<EOF >> $HGRCPATH | |||
|
40 | [notify] | |||
|
41 | config = $HGTMP/.notify.conf | |||
|
42 | domain = test.com | |||
|
43 | strip = 3 | |||
|
44 | template = Subject: {desc|firstline|strip}\nFrom: {author}\n\nchangeset {node|short} in {webroot}\ndescription:\n\t{desc|tabindent|strip} | |||
|
45 | ||||
|
46 | [web] | |||
|
47 | baseurl = http://test/ | |||
|
48 | EOF | |||
|
49 | ||||
38 | echo % pull |
|
50 | echo % pull | |
|
51 | hg --cwd b rollback | |||
39 | hg --traceback --cwd b pull ../a 2>&1 | sed -e 's/\(Message-Id:\).*/\1/' \ |
|
52 | hg --traceback --cwd b pull ../a 2>&1 | sed -e 's/\(Message-Id:\).*/\1/' \ | |
40 | -e 's/changeset \([0-9a-f]*\) in .*/changeset \1/' |
|
53 | -e 's/changeset \([0-9a-f]*\) in .*/changeset \1/' | |
|
54 |
@@ -6,7 +6,35 b' adding a' | |||||
6 | % clone |
|
6 | % clone | |
7 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
7 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
8 | % commit |
|
8 | % commit | |
|
9 | % pull (minimal config) | |||
|
10 | pulling from ../a | |||
|
11 | searching for changes | |||
|
12 | adding changesets | |||
|
13 | adding manifests | |||
|
14 | adding file changes | |||
|
15 | added 1 changesets with 1 changes to 1 files | |||
|
16 | Subject: changeset in test-notify/b: b | |||
|
17 | From: test | |||
|
18 | X-Hg-Notification: changeset 0647d048b600 | |||
|
19 | Message-Id: | |||
|
20 | To: baz, foo@bar | |||
|
21 | ||||
|
22 | changeset 0647d048b600 in test-notify/b | |||
|
23 | details: test-notify/b?cmd=changeset;node=0647d048b600 | |||
|
24 | description: | |||
|
25 | b | |||
|
26 | ||||
|
27 | diffs (6 lines): | |||
|
28 | ||||
|
29 | diff -r cb9a9f314b8b -r 0647d048b600 a | |||
|
30 | --- a/a Thu Jan 01 00:00:00 1970 +0000 | |||
|
31 | +++ b/a Thu Jan 01 00:00:01 1970 +0000 | |||
|
32 | @@ -1,1 +1,2 @@ a | |||
|
33 | a | |||
|
34 | +a | |||
|
35 | (run 'hg update' to get a working copy) | |||
9 | % pull |
|
36 | % pull | |
|
37 | rolling back last transaction | |||
10 | pulling from ../a |
|
38 | pulling from ../a | |
11 | searching for changes |
|
39 | searching for changes | |
12 | adding changesets |
|
40 | adding changesets | |
@@ -17,7 +45,7 b' Subject: b' | |||||
17 | From: test@test.com |
|
45 | From: test@test.com | |
18 | X-Hg-Notification: changeset 0647d048b600 |
|
46 | X-Hg-Notification: changeset 0647d048b600 | |
19 | Message-Id: |
|
47 | Message-Id: | |
20 | To: foo@bar |
|
48 | To: baz@test.com, foo@bar | |
21 |
|
49 | |||
22 | changeset 0647d048b600 |
|
50 | changeset 0647d048b600 | |
23 | description: |
|
51 | description: |
General Comments 0
You need to be logged in to leave comments.
Login now