##// END OF EJS Templates
Merge with crew-stable
Alexis S. L. Carvalho -
r4059:431f3c1d merge default
parent child Browse files
Show More
@@ -0,0 +1,77 b''
1 #!/bin/sh
2 # check that renames are correctly saved by a commit after a merge
3
4 HGMERGE=merge
5 export HGMERGE
6
7 # test with the merge on 3 having the rename on the local parent
8 hg init a
9 cd a
10
11 echo line1 > foo
12 hg add foo
13 hg ci -m '0: add foo' -d '0 0'
14
15 echo line2 >> foo
16 hg ci -m '1: change foo' -d '0 0'
17
18 hg up -C 0
19 hg mv foo bar
20 rm bar
21 echo line0 > bar
22 echo line1 >> bar
23 hg ci -m '2: mv foo bar; change bar' -d '0 0'
24
25 hg merge 1
26 echo '% contents of bar should be line0 line1 line2'
27 cat bar
28 hg ci -m '3: merge with local rename' -d '0 0'
29 hg debugindex .hg/store/data/bar.i
30 hg debugrename bar
31 hg debugindex .hg/store/data/foo.i
32
33 # revert the content change from rev 2
34 hg up -C 2
35 rm bar
36 echo line1 > bar
37 hg ci -m '4: revert content change from rev 2' -d '0 0'
38
39 hg log --template '#rev#:#node|short# #parents#\n'
40 echo '% this should use bar@rev2 as the ancestor'
41 hg --debug merge 3
42 echo '% contents of bar should be line1 line2'
43 cat bar
44 hg ci -m '5: merge' -d '0 0'
45 hg debugindex .hg/store/data/bar.i
46
47
48 # same thing, but with the merge on 3 having the rename on the remote parent
49 echo
50 echo
51 cd ..
52 hg clone -U -r 1 -r 2 a b
53 cd b
54
55 hg up -C 1
56 hg merge 2
57 echo '% contents of bar should be line0 line1 line2'
58 cat bar
59 hg ci -m '3: merge with remote rename' -d '0 0'
60 hg debugindex .hg/store/data/bar.i
61 hg debugrename bar
62 hg debugindex .hg/store/data/foo.i
63
64 # revert the content change from rev 2
65 hg up -C 2
66 rm bar
67 echo line1 > bar
68 hg ci -m '4: revert content change from rev 2' -d '0 0'
69
70 hg log --template '#rev#:#node|short# #parents#\n'
71 echo '% this should use bar@rev2 as the ancestor'
72 hg --debug merge 3
73 echo '% contents of bar should be line1 line2'
74 cat bar
75 hg ci -m '5: merge' -d '0 0'
76 hg debugindex .hg/store/data/bar.i
77
@@ -0,0 +1,83 b''
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 merging bar and foo
3 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
4 (branch merge, don't forget to commit)
5 % contents of bar should be line0 line1 line2
6 line0
7 line1
8 line2
9 rev offset length base linkrev nodeid p1 p2
10 0 0 77 0 2 da78c0659611 000000000000 000000000000
11 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
12 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
13 rev offset length base linkrev nodeid p1 p2
14 0 0 7 0 0 690b295714ae 000000000000 000000000000
15 1 7 13 1 1 9e25c27b8757 690b295714ae 000000000000
16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
17 4:2d2f9a22c82b 2:0a3ab4856510
18 3:7d3b554bfdf1 2:0a3ab4856510 1:5cd961e4045d
19 2:0a3ab4856510 0:2665aaee66e9
20 1:5cd961e4045d
21 0:2665aaee66e9
22 % this should use bar@rev2 as the ancestor
23 resolving manifests
24 overwrite None partial False
25 ancestor 0a3ab4856510 local 2d2f9a22c82b+ remote 7d3b554bfdf1
26 bar: versions differ -> m
27 merging bar
28 my bar@2d2f9a22c82b+ other bar@7d3b554bfdf1 ancestor bar@0a3ab4856510
29 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
30 (branch merge, don't forget to commit)
31 % contents of bar should be line1 line2
32 line1
33 line2
34 rev offset length base linkrev nodeid p1 p2
35 0 0 77 0 2 da78c0659611 000000000000 000000000000
36 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
37 2 153 7 2 4 4defe5eec418 da78c0659611 000000000000
38 3 160 13 3 5 4663501da27b 4defe5eec418 4b358025380b
39
40
41 requesting all changes
42 adding changesets
43 adding manifests
44 adding file changes
45 added 3 changesets with 3 changes to 2 files (+1 heads)
46 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
47 merging foo and bar
48 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
49 (branch merge, don't forget to commit)
50 % contents of bar should be line0 line1 line2
51 line0
52 line1
53 line2
54 rev offset length base linkrev nodeid p1 p2
55 0 0 77 0 2 da78c0659611 000000000000 000000000000
56 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
57 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
58 rev offset length base linkrev nodeid p1 p2
59 0 0 7 0 0 690b295714ae 000000000000 000000000000
60 1 7 13 1 1 9e25c27b8757 690b295714ae 000000000000
61 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 4:2d2f9a22c82b 2:0a3ab4856510
63 3:96ab80c60897 1:5cd961e4045d 2:0a3ab4856510
64 2:0a3ab4856510 0:2665aaee66e9
65 1:5cd961e4045d
66 0:2665aaee66e9
67 % this should use bar@rev2 as the ancestor
68 resolving manifests
69 overwrite None partial False
70 ancestor 0a3ab4856510 local 2d2f9a22c82b+ remote 96ab80c60897
71 bar: versions differ -> m
72 merging bar
73 my bar@2d2f9a22c82b+ other bar@96ab80c60897 ancestor bar@0a3ab4856510
74 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
75 (branch merge, don't forget to commit)
76 % contents of bar should be line1 line2
77 line1
78 line2
79 rev offset length base linkrev nodeid p1 p2
80 0 0 77 0 2 da78c0659611 000000000000 000000000000
81 1 77 76 0 3 4b358025380b 000000000000 da78c0659611
82 2 153 7 2 4 4defe5eec418 da78c0659611 000000000000
83 3 160 13 3 5 4663501da27b 4defe5eec418 4b358025380b
@@ -439,6 +439,9 b' ui::'
439 The committer of a changeset created when running "commit".
439 The committer of a changeset created when running "commit".
440 Typically a person's name and email address, e.g. "Fred Widget
440 Typically a person's name and email address, e.g. "Fred Widget
441 <fred@example.com>". Default is $EMAIL or username@hostname.
441 <fred@example.com>". Default is $EMAIL or username@hostname.
442 If the username in hgrc is empty, it has to be specified manually or
443 in a different hgrc file (e.g. $HOME/.hgrc, if the admin set "username ="
444 in the system hgrc).
442 verbose;;
445 verbose;;
443 Increase the amount of output printed. True or False. Default is False.
446 Increase the amount of output printed. True or False. Default is False.
444
447
@@ -125,7 +125,7 b' def make_file(repo, pat, node=None,'
125 pathname),
125 pathname),
126 mode)
126 mode)
127
127
128 def matchpats(repo, pats=[], opts={}, head=''):
128 def matchpats(repo, pats=[], opts={}, head='', globbed=False):
129 cwd = repo.getcwd()
129 cwd = repo.getcwd()
130 if not pats and cwd:
130 if not pats and cwd:
131 opts['include'] = [os.path.join(cwd, i)
131 opts['include'] = [os.path.join(cwd, i)
@@ -134,10 +134,12 b' def matchpats(repo, pats=[], opts={}, he'
134 for x in opts.get('exclude', [])]
134 for x in opts.get('exclude', [])]
135 cwd = ''
135 cwd = ''
136 return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'),
136 return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'),
137 opts.get('exclude'), head)
137 opts.get('exclude'), head, globbed=globbed)
138
138
139 def walk(repo, pats=[], opts={}, node=None, head='', badmatch=None):
139 def walk(repo, pats=[], opts={}, node=None, head='', badmatch=None,
140 files, matchfn, anypats = matchpats(repo, pats, opts, head)
140 globbed=False):
141 files, matchfn, anypats = matchpats(repo, pats, opts, head,
142 globbed=globbed)
141 exact = dict.fromkeys(files)
143 exact = dict.fromkeys(files)
142 for src, fn in repo.walk(node=node, files=files, match=matchfn,
144 for src, fn in repo.walk(node=node, files=files, match=matchfn,
143 badmatch=badmatch):
145 badmatch=badmatch):
@@ -604,7 +604,7 b' def docopy(ui, repo, pats, opts, wlock):'
604 return res
604 return res
605
605
606
606
607 pats = list(pats)
607 pats = util.expand_glob(pats)
608 if not pats:
608 if not pats:
609 raise util.Abort(_('no source or destination specified'))
609 raise util.Abort(_('no source or destination specified'))
610 if len(pats) == 1:
610 if len(pats) == 1:
@@ -621,7 +621,8 b' def docopy(ui, repo, pats, opts, wlock):'
621 copylist = []
621 copylist = []
622 for pat in pats:
622 for pat in pats:
623 srcs = []
623 srcs = []
624 for tag, abssrc, relsrc, exact in cmdutil.walk(repo, [pat], opts):
624 for tag, abssrc, relsrc, exact in cmdutil.walk(repo, [pat], opts,
625 globbed=True):
625 origsrc = okaytocopy(abssrc, relsrc, exact)
626 origsrc = okaytocopy(abssrc, relsrc, exact)
626 if origsrc:
627 if origsrc:
627 srcs.append((origsrc, abssrc, relsrc, exact))
628 srcs.append((origsrc, abssrc, relsrc, exact))
@@ -769,10 +770,16 b' def debugstate(ui, repo):'
769 keys = dc.keys()
770 keys = dc.keys()
770 keys.sort()
771 keys.sort()
771 for file_ in keys:
772 for file_ in keys:
773 if dc[file_][3] == -1:
774 # Pad or slice to locale representation
775 locale_len = len(time.strftime("%x %X", time.localtime(0)))
776 timestr = 'unset'
777 timestr = timestr[:locale_len] + ' '*(locale_len - len(timestr))
778 else:
779 timestr = time.strftime("%x %X", time.localtime(dc[file_][3]))
772 ui.write("%c %3o %10d %s %s\n"
780 ui.write("%c %3o %10d %s %s\n"
773 % (dc[file_][0], dc[file_][1] & 0777, dc[file_][2],
781 % (dc[file_][0], dc[file_][1] & 0777, dc[file_][2],
774 time.strftime("%x %X",
782 timestr, file_))
775 time.localtime(dc[file_][3])), file_))
776 for f in repo.dirstate.copies():
783 for f in repo.dirstate.copies():
777 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
784 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
778
785
@@ -2478,7 +2485,11 b' def unbundle(ui, repo, fname, **opts):'
2478 Apply a compressed changegroup file generated by the bundle
2485 Apply a compressed changegroup file generated by the bundle
2479 command.
2486 command.
2480 """
2487 """
2481 gen = changegroup.readbundle(urllib.urlopen(fname), fname)
2488 if os.path.exists(fname):
2489 f = open(fname)
2490 else:
2491 f = urllib.urlopen(fname)
2492 gen = changegroup.readbundle(f, fname)
2482 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2493 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
2483 return postincoming(ui, repo, modheads, opts['update'])
2494 return postincoming(ui, repo, modheads, opts['update'])
2484
2495
@@ -616,6 +616,24 b' class localrepository(repo.repository):'
616 meta = {}
616 meta = {}
617 cp = self.dirstate.copied(fn)
617 cp = self.dirstate.copied(fn)
618 if cp:
618 if cp:
619 # Mark the new revision of this file as a copy of another
620 # file. This copy data will effectively act as a parent
621 # of this new revision. If this is a merge, the first
622 # parent will be the nullid (meaning "look up the copy data")
623 # and the second one will be the other parent. For example:
624 #
625 # 0 --- 1 --- 3 rev1 changes file foo
626 # \ / rev2 renames foo to bar and changes it
627 # \- 2 -/ rev3 should have bar with all changes and
628 # should record that bar descends from
629 # bar in rev2 and foo in rev1
630 #
631 # this allows this merge to succeed:
632 #
633 # 0 --- 1 --- 3 rev4 reverts the content change from rev2
634 # \ / merging rev3 and rev4 should use bar@rev2
635 # \- 2 --- 4 as the merge base
636 #
619 meta["copy"] = cp
637 meta["copy"] = cp
620 if not manifest2: # not a branch merge
638 if not manifest2: # not a branch merge
621 meta["copyrev"] = hex(manifest1.get(cp, nullid))
639 meta["copyrev"] = hex(manifest1.get(cp, nullid))
@@ -624,7 +642,7 b' class localrepository(repo.repository):'
624 meta["copyrev"] = hex(manifest1.get(cp, nullid))
642 meta["copyrev"] = hex(manifest1.get(cp, nullid))
625 elif fp1 != nullid: # copied on local side, reversed
643 elif fp1 != nullid: # copied on local side, reversed
626 meta["copyrev"] = hex(manifest2.get(cp))
644 meta["copyrev"] = hex(manifest2.get(cp))
627 fp2 = nullid
645 fp2 = fp1
628 else: # directory rename
646 else: # directory rename
629 meta["copyrev"] = hex(manifest1.get(cp, nullid))
647 meta["copyrev"] = hex(manifest1.get(cp, nullid))
630 self.ui.debug(_(" %s: copy %s:%s\n") %
648 self.ui.debug(_(" %s: copy %s:%s\n") %
@@ -14,10 +14,13 b' platform-specific details from the core.'
14
14
15 from i18n import _
15 from i18n import _
16 import cStringIO, errno, getpass, popen2, re, shutil, sys, tempfile
16 import cStringIO, errno, getpass, popen2, re, shutil, sys, tempfile
17 import os, threading, time, calendar, ConfigParser, locale
17 import os, threading, time, calendar, ConfigParser, locale, glob
18
18
19 _encoding = os.environ.get("HGENCODING") or locale.getpreferredencoding() \
19 try:
20 or "ascii"
20 _encoding = os.environ.get("HGENCODING") or locale.getpreferredencoding() \
21 or "ascii"
22 except locale.Error:
23 _encoding = 'ascii'
21 _encodingmode = os.environ.get("HGENCODINGMODE", "strict")
24 _encodingmode = os.environ.get("HGENCODINGMODE", "strict")
22 _fallbackencoding = 'ISO-8859-1'
25 _fallbackencoding = 'ISO-8859-1'
23
26
@@ -233,6 +236,22 b' class UnexpectedOutput(Abort):'
233 def always(fn): return True
236 def always(fn): return True
234 def never(fn): return False
237 def never(fn): return False
235
238
239 def expand_glob(pats):
240 '''On Windows, expand the implicit globs in a list of patterns'''
241 if os.name != 'nt':
242 return list(pats)
243 ret = []
244 for p in pats:
245 kind, name = patkind(p, None)
246 if kind is None:
247 globbed = glob.glob(name)
248 if globbed:
249 ret.extend(globbed)
250 continue
251 # if we couldn't expand the glob, just keep it around
252 ret.append(p)
253 return ret
254
236 def patkind(name, dflt_pat='glob'):
255 def patkind(name, dflt_pat='glob'):
237 """Split a string into an optional pattern kind prefix and the
256 """Split a string into an optional pattern kind prefix and the
238 actual pattern."""
257 actual pattern."""
@@ -358,12 +377,11 b' def canonpath(root, cwd, myname):'
358 def matcher(canonroot, cwd='', names=['.'], inc=[], exc=[], head='', src=None):
377 def matcher(canonroot, cwd='', names=['.'], inc=[], exc=[], head='', src=None):
359 return _matcher(canonroot, cwd, names, inc, exc, head, 'glob', src)
378 return _matcher(canonroot, cwd, names, inc, exc, head, 'glob', src)
360
379
361 def cmdmatcher(canonroot, cwd='', names=['.'], inc=[], exc=[], head='', src=None):
380 def cmdmatcher(canonroot, cwd='', names=['.'], inc=[], exc=[], head='',
362 if os.name == 'nt':
381 src=None, globbed=False):
363 dflt_pat = 'glob'
382 if not globbed:
364 else:
383 names = expand_glob(names)
365 dflt_pat = 'relpath'
384 return _matcher(canonroot, cwd, names, inc, exc, head, 'relpath', src)
366 return _matcher(canonroot, cwd, names, inc, exc, head, dflt_pat, src)
367
385
368 def _matcher(canonroot, cwd, names, inc, exc, head, dflt_pat, src):
386 def _matcher(canonroot, cwd, names, inc, exc, head, dflt_pat, src):
369 """build a function to match a set of file patterns
387 """build a function to match a set of file patterns
General Comments 0
You need to be logged in to leave comments. Login now