##// END OF EJS Templates
windows: make shellquote() quote any path containing '\' (issue4629)...
Matt Harbison -
r24885:eea3977e stable
parent child Browse files
Show More
@@ -1,375 +1,377 b''
1 # windows.py - Windows utility function implementations for Mercurial
1 # windows.py - Windows utility function implementations for Mercurial
2 #
2 #
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from i18n import _
8 from i18n import _
9 import osutil, encoding
9 import osutil, encoding
10 import errno, msvcrt, os, re, stat, sys, _winreg
10 import errno, msvcrt, os, re, stat, sys, _winreg
11
11
12 import win32
12 import win32
13 executablepath = win32.executablepath
13 executablepath = win32.executablepath
14 getuser = win32.getuser
14 getuser = win32.getuser
15 hidewindow = win32.hidewindow
15 hidewindow = win32.hidewindow
16 makedir = win32.makedir
16 makedir = win32.makedir
17 nlinks = win32.nlinks
17 nlinks = win32.nlinks
18 oslink = win32.oslink
18 oslink = win32.oslink
19 samedevice = win32.samedevice
19 samedevice = win32.samedevice
20 samefile = win32.samefile
20 samefile = win32.samefile
21 setsignalhandler = win32.setsignalhandler
21 setsignalhandler = win32.setsignalhandler
22 spawndetached = win32.spawndetached
22 spawndetached = win32.spawndetached
23 split = os.path.split
23 split = os.path.split
24 termwidth = win32.termwidth
24 termwidth = win32.termwidth
25 testpid = win32.testpid
25 testpid = win32.testpid
26 unlink = win32.unlink
26 unlink = win32.unlink
27
27
28 umask = 0022
28 umask = 0022
29 _SEEK_END = 2 # os.SEEK_END was introduced in Python 2.5
29 _SEEK_END = 2 # os.SEEK_END was introduced in Python 2.5
30
30
31 def posixfile(name, mode='r', buffering=-1):
31 def posixfile(name, mode='r', buffering=-1):
32 '''Open a file with even more POSIX-like semantics'''
32 '''Open a file with even more POSIX-like semantics'''
33 try:
33 try:
34 fp = osutil.posixfile(name, mode, buffering) # may raise WindowsError
34 fp = osutil.posixfile(name, mode, buffering) # may raise WindowsError
35
35
36 # The position when opening in append mode is implementation defined, so
36 # The position when opening in append mode is implementation defined, so
37 # make it consistent with other platforms, which position at EOF.
37 # make it consistent with other platforms, which position at EOF.
38 if 'a' in mode:
38 if 'a' in mode:
39 fp.seek(0, _SEEK_END)
39 fp.seek(0, _SEEK_END)
40
40
41 return fp
41 return fp
42 except WindowsError, err:
42 except WindowsError, err:
43 # convert to a friendlier exception
43 # convert to a friendlier exception
44 raise IOError(err.errno, '%s: %s' % (name, err.strerror))
44 raise IOError(err.errno, '%s: %s' % (name, err.strerror))
45
45
46 class winstdout(object):
46 class winstdout(object):
47 '''stdout on windows misbehaves if sent through a pipe'''
47 '''stdout on windows misbehaves if sent through a pipe'''
48
48
49 def __init__(self, fp):
49 def __init__(self, fp):
50 self.fp = fp
50 self.fp = fp
51
51
52 def __getattr__(self, key):
52 def __getattr__(self, key):
53 return getattr(self.fp, key)
53 return getattr(self.fp, key)
54
54
55 def close(self):
55 def close(self):
56 try:
56 try:
57 self.fp.close()
57 self.fp.close()
58 except IOError:
58 except IOError:
59 pass
59 pass
60
60
61 def write(self, s):
61 def write(self, s):
62 try:
62 try:
63 # This is workaround for "Not enough space" error on
63 # This is workaround for "Not enough space" error on
64 # writing large size of data to console.
64 # writing large size of data to console.
65 limit = 16000
65 limit = 16000
66 l = len(s)
66 l = len(s)
67 start = 0
67 start = 0
68 self.softspace = 0
68 self.softspace = 0
69 while start < l:
69 while start < l:
70 end = start + limit
70 end = start + limit
71 self.fp.write(s[start:end])
71 self.fp.write(s[start:end])
72 start = end
72 start = end
73 except IOError, inst:
73 except IOError, inst:
74 if inst.errno != 0:
74 if inst.errno != 0:
75 raise
75 raise
76 self.close()
76 self.close()
77 raise IOError(errno.EPIPE, 'Broken pipe')
77 raise IOError(errno.EPIPE, 'Broken pipe')
78
78
79 def flush(self):
79 def flush(self):
80 try:
80 try:
81 return self.fp.flush()
81 return self.fp.flush()
82 except IOError, inst:
82 except IOError, inst:
83 if inst.errno != errno.EINVAL:
83 if inst.errno != errno.EINVAL:
84 raise
84 raise
85 self.close()
85 self.close()
86 raise IOError(errno.EPIPE, 'Broken pipe')
86 raise IOError(errno.EPIPE, 'Broken pipe')
87
87
88 sys.__stdout__ = sys.stdout = winstdout(sys.stdout)
88 sys.__stdout__ = sys.stdout = winstdout(sys.stdout)
89
89
90 def _is_win_9x():
90 def _is_win_9x():
91 '''return true if run on windows 95, 98 or me.'''
91 '''return true if run on windows 95, 98 or me.'''
92 try:
92 try:
93 return sys.getwindowsversion()[3] == 1
93 return sys.getwindowsversion()[3] == 1
94 except AttributeError:
94 except AttributeError:
95 return 'command' in os.environ.get('comspec', '')
95 return 'command' in os.environ.get('comspec', '')
96
96
97 def openhardlinks():
97 def openhardlinks():
98 return not _is_win_9x()
98 return not _is_win_9x()
99
99
100 def parsepatchoutput(output_line):
100 def parsepatchoutput(output_line):
101 """parses the output produced by patch and returns the filename"""
101 """parses the output produced by patch and returns the filename"""
102 pf = output_line[14:]
102 pf = output_line[14:]
103 if pf[0] == '`':
103 if pf[0] == '`':
104 pf = pf[1:-1] # Remove the quotes
104 pf = pf[1:-1] # Remove the quotes
105 return pf
105 return pf
106
106
107 def sshargs(sshcmd, host, user, port):
107 def sshargs(sshcmd, host, user, port):
108 '''Build argument list for ssh or Plink'''
108 '''Build argument list for ssh or Plink'''
109 pflag = 'plink' in sshcmd.lower() and '-P' or '-p'
109 pflag = 'plink' in sshcmd.lower() and '-P' or '-p'
110 args = user and ("%s@%s" % (user, host)) or host
110 args = user and ("%s@%s" % (user, host)) or host
111 return port and ("%s %s %s" % (args, pflag, port)) or args
111 return port and ("%s %s %s" % (args, pflag, port)) or args
112
112
113 def setflags(f, l, x):
113 def setflags(f, l, x):
114 pass
114 pass
115
115
116 def copymode(src, dst, mode=None):
116 def copymode(src, dst, mode=None):
117 pass
117 pass
118
118
119 def checkexec(path):
119 def checkexec(path):
120 return False
120 return False
121
121
122 def checklink(path):
122 def checklink(path):
123 return False
123 return False
124
124
125 def setbinary(fd):
125 def setbinary(fd):
126 # When run without console, pipes may expose invalid
126 # When run without console, pipes may expose invalid
127 # fileno(), usually set to -1.
127 # fileno(), usually set to -1.
128 fno = getattr(fd, 'fileno', None)
128 fno = getattr(fd, 'fileno', None)
129 if fno is not None and fno() >= 0:
129 if fno is not None and fno() >= 0:
130 msvcrt.setmode(fno(), os.O_BINARY)
130 msvcrt.setmode(fno(), os.O_BINARY)
131
131
132 def pconvert(path):
132 def pconvert(path):
133 return path.replace(os.sep, '/')
133 return path.replace(os.sep, '/')
134
134
135 def localpath(path):
135 def localpath(path):
136 return path.replace('/', '\\')
136 return path.replace('/', '\\')
137
137
138 def normpath(path):
138 def normpath(path):
139 return pconvert(os.path.normpath(path))
139 return pconvert(os.path.normpath(path))
140
140
141 def normcase(path):
141 def normcase(path):
142 return encoding.upper(path)
142 return encoding.upper(path)
143
143
144 # see posix.py for definitions
144 # see posix.py for definitions
145 normcasespec = encoding.normcasespecs.upper
145 normcasespec = encoding.normcasespecs.upper
146 normcasefallback = encoding.upperfallback
146 normcasefallback = encoding.upperfallback
147
147
148 def samestat(s1, s2):
148 def samestat(s1, s2):
149 return False
149 return False
150
150
151 # A sequence of backslashes is special iff it precedes a double quote:
151 # A sequence of backslashes is special iff it precedes a double quote:
152 # - if there's an even number of backslashes, the double quote is not
152 # - if there's an even number of backslashes, the double quote is not
153 # quoted (i.e. it ends the quoted region)
153 # quoted (i.e. it ends the quoted region)
154 # - if there's an odd number of backslashes, the double quote is quoted
154 # - if there's an odd number of backslashes, the double quote is quoted
155 # - in both cases, every pair of backslashes is unquoted into a single
155 # - in both cases, every pair of backslashes is unquoted into a single
156 # backslash
156 # backslash
157 # (See http://msdn2.microsoft.com/en-us/library/a1y7w461.aspx )
157 # (See http://msdn2.microsoft.com/en-us/library/a1y7w461.aspx )
158 # So, to quote a string, we must surround it in double quotes, double
158 # So, to quote a string, we must surround it in double quotes, double
159 # the number of backslashes that precede double quotes and add another
159 # the number of backslashes that precede double quotes and add another
160 # backslash before every double quote (being careful with the double
160 # backslash before every double quote (being careful with the double
161 # quote we've appended to the end)
161 # quote we've appended to the end)
162 _quotere = None
162 _quotere = None
163 _needsshellquote = None
163 _needsshellquote = None
164 def shellquote(s):
164 def shellquote(s):
165 global _quotere
165 global _quotere
166 if _quotere is None:
166 if _quotere is None:
167 _quotere = re.compile(r'(\\*)("|\\$)')
167 _quotere = re.compile(r'(\\*)("|\\$)')
168 global _needsshellquote
168 global _needsshellquote
169 if _needsshellquote is None:
169 if _needsshellquote is None:
170 # ":" and "\\" are also treated as "safe character", because
170 # ":" is also treated as "safe character", because it is used as a part
171 # they are used as a part of path name (and the latter doesn't
171 # of path name on Windows. "\" is also part of a path name, but isn't
172 # work as "escape character", like one on posix) on Windows
172 # safe because shlex.split() (kind of) treats it as an escape char and
173 _needsshellquote = re.compile(r'[^a-zA-Z0-9._:/\\-]').search
173 # drops it. It will leave the next character, even if it is another
174 # "\".
175 _needsshellquote = re.compile(r'[^a-zA-Z0-9._:/-]').search
174 if s and not _needsshellquote(s) and not _quotere.search(s):
176 if s and not _needsshellquote(s) and not _quotere.search(s):
175 # "s" shouldn't have to be quoted
177 # "s" shouldn't have to be quoted
176 return s
178 return s
177 return '"%s"' % _quotere.sub(r'\1\1\\\2', s)
179 return '"%s"' % _quotere.sub(r'\1\1\\\2', s)
178
180
179 def quotecommand(cmd):
181 def quotecommand(cmd):
180 """Build a command string suitable for os.popen* calls."""
182 """Build a command string suitable for os.popen* calls."""
181 if sys.version_info < (2, 7, 1):
183 if sys.version_info < (2, 7, 1):
182 # Python versions since 2.7.1 do this extra quoting themselves
184 # Python versions since 2.7.1 do this extra quoting themselves
183 return '"' + cmd + '"'
185 return '"' + cmd + '"'
184 return cmd
186 return cmd
185
187
186 def popen(command, mode='r'):
188 def popen(command, mode='r'):
187 # Work around "popen spawned process may not write to stdout
189 # Work around "popen spawned process may not write to stdout
188 # under windows"
190 # under windows"
189 # http://bugs.python.org/issue1366
191 # http://bugs.python.org/issue1366
190 command += " 2> %s" % os.devnull
192 command += " 2> %s" % os.devnull
191 return os.popen(quotecommand(command), mode)
193 return os.popen(quotecommand(command), mode)
192
194
193 def explainexit(code):
195 def explainexit(code):
194 return _("exited with status %d") % code, code
196 return _("exited with status %d") % code, code
195
197
196 # if you change this stub into a real check, please try to implement the
198 # if you change this stub into a real check, please try to implement the
197 # username and groupname functions above, too.
199 # username and groupname functions above, too.
198 def isowner(st):
200 def isowner(st):
199 return True
201 return True
200
202
201 def findexe(command):
203 def findexe(command):
202 '''Find executable for command searching like cmd.exe does.
204 '''Find executable for command searching like cmd.exe does.
203 If command is a basename then PATH is searched for command.
205 If command is a basename then PATH is searched for command.
204 PATH isn't searched if command is an absolute or relative path.
206 PATH isn't searched if command is an absolute or relative path.
205 An extension from PATHEXT is found and added if not present.
207 An extension from PATHEXT is found and added if not present.
206 If command isn't found None is returned.'''
208 If command isn't found None is returned.'''
207 pathext = os.environ.get('PATHEXT', '.COM;.EXE;.BAT;.CMD')
209 pathext = os.environ.get('PATHEXT', '.COM;.EXE;.BAT;.CMD')
208 pathexts = [ext for ext in pathext.lower().split(os.pathsep)]
210 pathexts = [ext for ext in pathext.lower().split(os.pathsep)]
209 if os.path.splitext(command)[1].lower() in pathexts:
211 if os.path.splitext(command)[1].lower() in pathexts:
210 pathexts = ['']
212 pathexts = ['']
211
213
212 def findexisting(pathcommand):
214 def findexisting(pathcommand):
213 'Will append extension (if needed) and return existing file'
215 'Will append extension (if needed) and return existing file'
214 for ext in pathexts:
216 for ext in pathexts:
215 executable = pathcommand + ext
217 executable = pathcommand + ext
216 if os.path.exists(executable):
218 if os.path.exists(executable):
217 return executable
219 return executable
218 return None
220 return None
219
221
220 if os.sep in command:
222 if os.sep in command:
221 return findexisting(command)
223 return findexisting(command)
222
224
223 for path in os.environ.get('PATH', '').split(os.pathsep):
225 for path in os.environ.get('PATH', '').split(os.pathsep):
224 executable = findexisting(os.path.join(path, command))
226 executable = findexisting(os.path.join(path, command))
225 if executable is not None:
227 if executable is not None:
226 return executable
228 return executable
227 return findexisting(os.path.expanduser(os.path.expandvars(command)))
229 return findexisting(os.path.expanduser(os.path.expandvars(command)))
228
230
229 _wantedkinds = set([stat.S_IFREG, stat.S_IFLNK])
231 _wantedkinds = set([stat.S_IFREG, stat.S_IFLNK])
230
232
231 def statfiles(files):
233 def statfiles(files):
232 '''Stat each file in files. Yield each stat, or None if a file
234 '''Stat each file in files. Yield each stat, or None if a file
233 does not exist or has a type we don't care about.
235 does not exist or has a type we don't care about.
234
236
235 Cluster and cache stat per directory to minimize number of OS stat calls.'''
237 Cluster and cache stat per directory to minimize number of OS stat calls.'''
236 dircache = {} # dirname -> filename -> status | None if file does not exist
238 dircache = {} # dirname -> filename -> status | None if file does not exist
237 getkind = stat.S_IFMT
239 getkind = stat.S_IFMT
238 for nf in files:
240 for nf in files:
239 nf = normcase(nf)
241 nf = normcase(nf)
240 dir, base = os.path.split(nf)
242 dir, base = os.path.split(nf)
241 if not dir:
243 if not dir:
242 dir = '.'
244 dir = '.'
243 cache = dircache.get(dir, None)
245 cache = dircache.get(dir, None)
244 if cache is None:
246 if cache is None:
245 try:
247 try:
246 dmap = dict([(normcase(n), s)
248 dmap = dict([(normcase(n), s)
247 for n, k, s in osutil.listdir(dir, True)
249 for n, k, s in osutil.listdir(dir, True)
248 if getkind(s.st_mode) in _wantedkinds])
250 if getkind(s.st_mode) in _wantedkinds])
249 except OSError, err:
251 except OSError, err:
250 # handle directory not found in Python version prior to 2.5
252 # handle directory not found in Python version prior to 2.5
251 # Python <= 2.4 returns native Windows code 3 in errno
253 # Python <= 2.4 returns native Windows code 3 in errno
252 # Python >= 2.5 returns ENOENT and adds winerror field
254 # Python >= 2.5 returns ENOENT and adds winerror field
253 # EINVAL is raised if dir is not a directory.
255 # EINVAL is raised if dir is not a directory.
254 if err.errno not in (3, errno.ENOENT, errno.EINVAL,
256 if err.errno not in (3, errno.ENOENT, errno.EINVAL,
255 errno.ENOTDIR):
257 errno.ENOTDIR):
256 raise
258 raise
257 dmap = {}
259 dmap = {}
258 cache = dircache.setdefault(dir, dmap)
260 cache = dircache.setdefault(dir, dmap)
259 yield cache.get(base, None)
261 yield cache.get(base, None)
260
262
261 def username(uid=None):
263 def username(uid=None):
262 """Return the name of the user with the given uid.
264 """Return the name of the user with the given uid.
263
265
264 If uid is None, return the name of the current user."""
266 If uid is None, return the name of the current user."""
265 return None
267 return None
266
268
267 def groupname(gid=None):
269 def groupname(gid=None):
268 """Return the name of the group with the given gid.
270 """Return the name of the group with the given gid.
269
271
270 If gid is None, return the name of the current group."""
272 If gid is None, return the name of the current group."""
271 return None
273 return None
272
274
273 def removedirs(name):
275 def removedirs(name):
274 """special version of os.removedirs that does not remove symlinked
276 """special version of os.removedirs that does not remove symlinked
275 directories or junction points if they actually contain files"""
277 directories or junction points if they actually contain files"""
276 if osutil.listdir(name):
278 if osutil.listdir(name):
277 return
279 return
278 os.rmdir(name)
280 os.rmdir(name)
279 head, tail = os.path.split(name)
281 head, tail = os.path.split(name)
280 if not tail:
282 if not tail:
281 head, tail = os.path.split(head)
283 head, tail = os.path.split(head)
282 while head and tail:
284 while head and tail:
283 try:
285 try:
284 if osutil.listdir(head):
286 if osutil.listdir(head):
285 return
287 return
286 os.rmdir(head)
288 os.rmdir(head)
287 except (ValueError, OSError):
289 except (ValueError, OSError):
288 break
290 break
289 head, tail = os.path.split(head)
291 head, tail = os.path.split(head)
290
292
291 def unlinkpath(f, ignoremissing=False):
293 def unlinkpath(f, ignoremissing=False):
292 """unlink and remove the directory if it is empty"""
294 """unlink and remove the directory if it is empty"""
293 try:
295 try:
294 unlink(f)
296 unlink(f)
295 except OSError, e:
297 except OSError, e:
296 if not (ignoremissing and e.errno == errno.ENOENT):
298 if not (ignoremissing and e.errno == errno.ENOENT):
297 raise
299 raise
298 # try removing directories that might now be empty
300 # try removing directories that might now be empty
299 try:
301 try:
300 removedirs(os.path.dirname(f))
302 removedirs(os.path.dirname(f))
301 except OSError:
303 except OSError:
302 pass
304 pass
303
305
304 def rename(src, dst):
306 def rename(src, dst):
305 '''atomically rename file src to dst, replacing dst if it exists'''
307 '''atomically rename file src to dst, replacing dst if it exists'''
306 try:
308 try:
307 os.rename(src, dst)
309 os.rename(src, dst)
308 except OSError, e:
310 except OSError, e:
309 if e.errno != errno.EEXIST:
311 if e.errno != errno.EEXIST:
310 raise
312 raise
311 unlink(dst)
313 unlink(dst)
312 os.rename(src, dst)
314 os.rename(src, dst)
313
315
314 def gethgcmd():
316 def gethgcmd():
315 return [sys.executable] + sys.argv[:1]
317 return [sys.executable] + sys.argv[:1]
316
318
317 def groupmembers(name):
319 def groupmembers(name):
318 # Don't support groups on Windows for now
320 # Don't support groups on Windows for now
319 raise KeyError
321 raise KeyError
320
322
321 def isexec(f):
323 def isexec(f):
322 return False
324 return False
323
325
324 class cachestat(object):
326 class cachestat(object):
325 def __init__(self, path):
327 def __init__(self, path):
326 pass
328 pass
327
329
328 def cacheable(self):
330 def cacheable(self):
329 return False
331 return False
330
332
331 def lookupreg(key, valname=None, scope=None):
333 def lookupreg(key, valname=None, scope=None):
332 ''' Look up a key/value name in the Windows registry.
334 ''' Look up a key/value name in the Windows registry.
333
335
334 valname: value name. If unspecified, the default value for the key
336 valname: value name. If unspecified, the default value for the key
335 is used.
337 is used.
336 scope: optionally specify scope for registry lookup, this can be
338 scope: optionally specify scope for registry lookup, this can be
337 a sequence of scopes to look up in order. Default (CURRENT_USER,
339 a sequence of scopes to look up in order. Default (CURRENT_USER,
338 LOCAL_MACHINE).
340 LOCAL_MACHINE).
339 '''
341 '''
340 if scope is None:
342 if scope is None:
341 scope = (_winreg.HKEY_CURRENT_USER, _winreg.HKEY_LOCAL_MACHINE)
343 scope = (_winreg.HKEY_CURRENT_USER, _winreg.HKEY_LOCAL_MACHINE)
342 elif not isinstance(scope, (list, tuple)):
344 elif not isinstance(scope, (list, tuple)):
343 scope = (scope,)
345 scope = (scope,)
344 for s in scope:
346 for s in scope:
345 try:
347 try:
346 val = _winreg.QueryValueEx(_winreg.OpenKey(s, key), valname)[0]
348 val = _winreg.QueryValueEx(_winreg.OpenKey(s, key), valname)[0]
347 # never let a Unicode string escape into the wild
349 # never let a Unicode string escape into the wild
348 return encoding.tolocal(val.encode('UTF-8'))
350 return encoding.tolocal(val.encode('UTF-8'))
349 except EnvironmentError:
351 except EnvironmentError:
350 pass
352 pass
351
353
352 expandglobs = True
354 expandglobs = True
353
355
354 def statislink(st):
356 def statislink(st):
355 '''check whether a stat result is a symlink'''
357 '''check whether a stat result is a symlink'''
356 return False
358 return False
357
359
358 def statisexec(st):
360 def statisexec(st):
359 '''check whether a stat result is an executable file'''
361 '''check whether a stat result is an executable file'''
360 return False
362 return False
361
363
362 def readpipe(pipe):
364 def readpipe(pipe):
363 """Read all available data from a pipe."""
365 """Read all available data from a pipe."""
364 chunks = []
366 chunks = []
365 while True:
367 while True:
366 size = win32.peekpipe(pipe)
368 size = win32.peekpipe(pipe)
367 if not size:
369 if not size:
368 break
370 break
369
371
370 s = pipe.read(size)
372 s = pipe.read(size)
371 if not s:
373 if not s:
372 break
374 break
373 chunks.append(s)
375 chunks.append(s)
374
376
375 return ''.join(chunks)
377 return ''.join(chunks)
@@ -1,340 +1,364 b''
1 $ echo "[extensions]" >> $HGRCPATH
1 $ echo "[extensions]" >> $HGRCPATH
2 $ echo "extdiff=" >> $HGRCPATH
2 $ echo "extdiff=" >> $HGRCPATH
3
3
4 $ hg init a
4 $ hg init a
5 $ cd a
5 $ cd a
6 $ echo a > a
6 $ echo a > a
7 $ echo b > b
7 $ echo b > b
8 $ hg add
8 $ hg add
9 adding a
9 adding a
10 adding b
10 adding b
11
11
12 Should diff cloned directories:
12 Should diff cloned directories:
13
13
14 $ hg extdiff -o -r $opt
14 $ hg extdiff -o -r $opt
15 Only in a: a
15 Only in a: a
16 Only in a: b
16 Only in a: b
17 [1]
17 [1]
18
18
19 $ cat <<EOF >> $HGRCPATH
19 $ cat <<EOF >> $HGRCPATH
20 > [extdiff]
20 > [extdiff]
21 > cmd.falabala = echo
21 > cmd.falabala = echo
22 > opts.falabala = diffing
22 > opts.falabala = diffing
23 > cmd.edspace = echo
23 > cmd.edspace = echo
24 > opts.edspace = "name <user@example.com>"
24 > opts.edspace = "name <user@example.com>"
25 > EOF
25 > EOF
26
26
27 $ hg falabala
27 $ hg falabala
28 diffing a.000000000000 a
28 diffing a.000000000000 a
29 [1]
29 [1]
30
30
31 $ hg help falabala
31 $ hg help falabala
32 hg falabala [OPTION]... [FILE]...
32 hg falabala [OPTION]... [FILE]...
33
33
34 use 'echo' to diff repository (or selected files)
34 use 'echo' to diff repository (or selected files)
35
35
36 Show differences between revisions for the specified files, using the
36 Show differences between revisions for the specified files, using the
37 'echo' program.
37 'echo' program.
38
38
39 When two revision arguments are given, then changes are shown between
39 When two revision arguments are given, then changes are shown between
40 those revisions. If only one revision is specified then that revision is
40 those revisions. If only one revision is specified then that revision is
41 compared to the working directory, and, when no revisions are specified,
41 compared to the working directory, and, when no revisions are specified,
42 the working directory files are compared to its parent.
42 the working directory files are compared to its parent.
43
43
44 options ([+] can be repeated):
44 options ([+] can be repeated):
45
45
46 -o --option OPT [+] pass option to comparison program
46 -o --option OPT [+] pass option to comparison program
47 -r --rev REV [+] revision
47 -r --rev REV [+] revision
48 -c --change REV change made by revision
48 -c --change REV change made by revision
49 -I --include PATTERN [+] include names matching the given patterns
49 -I --include PATTERN [+] include names matching the given patterns
50 -X --exclude PATTERN [+] exclude names matching the given patterns
50 -X --exclude PATTERN [+] exclude names matching the given patterns
51
51
52 (some details hidden, use --verbose to show complete help)
52 (some details hidden, use --verbose to show complete help)
53
53
54 $ hg ci -d '0 0' -mtest1
54 $ hg ci -d '0 0' -mtest1
55
55
56 $ echo b >> a
56 $ echo b >> a
57 $ hg ci -d '1 0' -mtest2
57 $ hg ci -d '1 0' -mtest2
58
58
59 Should diff cloned files directly:
59 Should diff cloned files directly:
60
60
61 #if windows
62 $ hg falabala -r 0:1
63 diffing "*\\extdiff.*\\a.8a5febb7f867\\a" "a.34eed99112ab\\a" (glob)
64 [1]
65 #else
61 $ hg falabala -r 0:1
66 $ hg falabala -r 0:1
62 diffing */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
67 diffing */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
63 [1]
68 [1]
69 #endif
64
70
65 Test diff during merge:
71 Test diff during merge:
66
72
67 $ hg update -C 0
73 $ hg update -C 0
68 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
74 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
69 $ echo c >> c
75 $ echo c >> c
70 $ hg add c
76 $ hg add c
71 $ hg ci -m "new branch" -d '1 0'
77 $ hg ci -m "new branch" -d '1 0'
72 created new head
78 created new head
73 $ hg merge 1
79 $ hg merge 1
74 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
75 (branch merge, don't forget to commit)
81 (branch merge, don't forget to commit)
76
82
77 Should diff cloned file against wc file:
83 Should diff cloned file against wc file:
78
84
85 #if windows
86 $ hg falabala
87 diffing "*\\extdiff.*\\a.2a13a4d2da36\\a" "*\\a\\a" (glob)
88 [1]
89 #else
79 $ hg falabala
90 $ hg falabala
80 diffing */extdiff.*/a.2a13a4d2da36/a */a/a (glob)
91 diffing */extdiff.*/a.2a13a4d2da36/a */a/a (glob)
81 [1]
92 [1]
93 #endif
82
94
83
95
84 Test --change option:
96 Test --change option:
85
97
86 $ hg ci -d '2 0' -mtest3
98 $ hg ci -d '2 0' -mtest3
99 #if windows
100 $ hg falabala -c 1
101 diffing "*\\extdiff.*\\a.8a5febb7f867\\a" "a.34eed99112ab\\a" (glob)
102 [1]
103 #else
87 $ hg falabala -c 1
104 $ hg falabala -c 1
88 diffing */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
105 diffing */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
89 [1]
106 [1]
107 #endif
90
108
91 Check diff are made from the first parent:
109 Check diff are made from the first parent:
92
110
111 #if windows
112 $ hg falabala -c 3 || echo "diff-like tools yield a non-zero exit code"
113 diffing "*\\extdiff.*\\a.2a13a4d2da36\\a" "a.46c0e4daeb72\\a" (glob)
114 diff-like tools yield a non-zero exit code
115 #else
93 $ hg falabala -c 3 || echo "diff-like tools yield a non-zero exit code"
116 $ hg falabala -c 3 || echo "diff-like tools yield a non-zero exit code"
94 diffing */extdiff.*/a.2a13a4d2da36/a a.46c0e4daeb72/a (glob)
117 diffing */extdiff.*/a.2a13a4d2da36/a a.46c0e4daeb72/a (glob)
95 diff-like tools yield a non-zero exit code
118 diff-like tools yield a non-zero exit code
119 #endif
96
120
97 issue4463: usage of command line configuration without additional quoting
121 issue4463: usage of command line configuration without additional quoting
98
122
99 $ cat <<EOF >> $HGRCPATH
123 $ cat <<EOF >> $HGRCPATH
100 > [extdiff]
124 > [extdiff]
101 > cmd.4463a = echo
125 > cmd.4463a = echo
102 > opts.4463a = a-naked 'single quoted' "double quoted"
126 > opts.4463a = a-naked 'single quoted' "double quoted"
103 > 4463b = echo b-naked 'single quoted' "double quoted"
127 > 4463b = echo b-naked 'single quoted' "double quoted"
104 > echo =
128 > echo =
105 > EOF
129 > EOF
106 $ hg update -q -C 0
130 $ hg update -q -C 0
107 $ echo a >> a
131 $ echo a >> a
108 #if windows
132 #if windows
109 $ hg --debug 4463a | grep '^running'
133 $ hg --debug 4463a | grep '^running'
110 running 'echo a-naked \'single quoted\' "double quoted" *\\a *\\a' in */extdiff.* (glob)
134 running 'echo a-naked \'single quoted\' "double quoted" "*\\a" "*\\a"' in */extdiff.* (glob)
111 $ hg --debug 4463b | grep '^running'
135 $ hg --debug 4463b | grep '^running'
112 running 'echo b-naked \'single quoted\' "double quoted" *\\a *\\a' in */extdiff.* (glob)
136 running 'echo b-naked \'single quoted\' "double quoted" "*\\a" "*\\a"' in */extdiff.* (glob)
113 $ hg --debug echo | grep '^running'
137 $ hg --debug echo | grep '^running'
114 running '*echo* *\\a *\\a' in */extdiff.* (glob)
138 running '*echo* "*\\a" "*\\a"' in */extdiff.* (glob)
115 #else
139 #else
116 $ hg --debug 4463a | grep '^running'
140 $ hg --debug 4463a | grep '^running'
117 running 'echo a-naked \'single quoted\' "double quoted" */a $TESTTMP/a/a' in */extdiff.* (glob)
141 running 'echo a-naked \'single quoted\' "double quoted" */a $TESTTMP/a/a' in */extdiff.* (glob)
118 $ hg --debug 4463b | grep '^running'
142 $ hg --debug 4463b | grep '^running'
119 running 'echo b-naked \'single quoted\' "double quoted" */a $TESTTMP/a/a' in */extdiff.* (glob)
143 running 'echo b-naked \'single quoted\' "double quoted" */a $TESTTMP/a/a' in */extdiff.* (glob)
120 $ hg --debug echo | grep '^running'
144 $ hg --debug echo | grep '^running'
121 running '*echo */a $TESTTMP/a/a' in */extdiff.* (glob)
145 running '*echo */a $TESTTMP/a/a' in */extdiff.* (glob)
122 #endif
146 #endif
123
147
124 (getting options from other than extdiff section)
148 (getting options from other than extdiff section)
125
149
126 $ cat <<EOF >> $HGRCPATH
150 $ cat <<EOF >> $HGRCPATH
127 > [extdiff]
151 > [extdiff]
128 > # using diff-tools diffargs
152 > # using diff-tools diffargs
129 > 4463b2 = echo
153 > 4463b2 = echo
130 > # using merge-tools diffargs
154 > # using merge-tools diffargs
131 > 4463b3 = echo
155 > 4463b3 = echo
132 > # no diffargs
156 > # no diffargs
133 > 4463b4 = echo
157 > 4463b4 = echo
134 > [diff-tools]
158 > [diff-tools]
135 > 4463b2.diffargs = b2-naked 'single quoted' "double quoted"
159 > 4463b2.diffargs = b2-naked 'single quoted' "double quoted"
136 > [merge-tools]
160 > [merge-tools]
137 > 4463b3.diffargs = b3-naked 'single quoted' "double quoted"
161 > 4463b3.diffargs = b3-naked 'single quoted' "double quoted"
138 > EOF
162 > EOF
139 #if windows
163 #if windows
140 $ hg --debug 4463b2 | grep '^running'
164 $ hg --debug 4463b2 | grep '^running'
141 running 'echo b2-naked \'single quoted\' "double quoted" *\\a *\\a' in */extdiff.* (glob)
165 running 'echo b2-naked \'single quoted\' "double quoted" "*\\a" "*\\a"' in */extdiff.* (glob)
142 $ hg --debug 4463b3 | grep '^running'
166 $ hg --debug 4463b3 | grep '^running'
143 running 'echo b3-naked \'single quoted\' "double quoted" *\\a *\\a' in */extdiff.* (glob)
167 running 'echo b3-naked \'single quoted\' "double quoted" "*\\a" "*\\a"' in */extdiff.* (glob)
144 $ hg --debug 4463b4 | grep '^running'
168 $ hg --debug 4463b4 | grep '^running'
145 running 'echo *\\a *\\a' in */extdiff.* (glob)
169 running 'echo "*\\a" "*\\a"' in */extdiff.* (glob)
146 $ hg --debug 4463b4 --option b4-naked --option 'being quoted' | grep '^running'
170 $ hg --debug 4463b4 --option b4-naked --option 'being quoted' | grep '^running'
147 running 'echo b4-naked "being quoted" *\\a *\\a' in */extdiff.* (glob)
171 running 'echo b4-naked "being quoted" "*\\a" "*\\a"' in */extdiff.* (glob)
148 $ hg --debug extdiff -p echo --option echo-naked --option 'being quoted' | grep '^running'
172 $ hg --debug extdiff -p echo --option echo-naked --option 'being quoted' | grep '^running'
149 running 'echo echo-naked "being quoted" *\\a *\\a' in */extdiff.* (glob)
173 running 'echo echo-naked "being quoted" "*\\a" "*\\a"' in */extdiff.* (glob)
150 #else
174 #else
151 $ hg --debug 4463b2 | grep '^running'
175 $ hg --debug 4463b2 | grep '^running'
152 running 'echo b2-naked \'single quoted\' "double quoted" */a $TESTTMP/a/a' in */extdiff.* (glob)
176 running 'echo b2-naked \'single quoted\' "double quoted" */a $TESTTMP/a/a' in */extdiff.* (glob)
153 $ hg --debug 4463b3 | grep '^running'
177 $ hg --debug 4463b3 | grep '^running'
154 running 'echo b3-naked \'single quoted\' "double quoted" */a $TESTTMP/a/a' in */extdiff.* (glob)
178 running 'echo b3-naked \'single quoted\' "double quoted" */a $TESTTMP/a/a' in */extdiff.* (glob)
155 $ hg --debug 4463b4 | grep '^running'
179 $ hg --debug 4463b4 | grep '^running'
156 running 'echo */a $TESTTMP/a/a' in */extdiff.* (glob)
180 running 'echo */a $TESTTMP/a/a' in */extdiff.* (glob)
157 $ hg --debug 4463b4 --option b4-naked --option 'being quoted' | grep '^running'
181 $ hg --debug 4463b4 --option b4-naked --option 'being quoted' | grep '^running'
158 running "echo b4-naked 'being quoted' */a $TESTTMP/a/a" in */extdiff.* (glob)
182 running "echo b4-naked 'being quoted' */a $TESTTMP/a/a" in */extdiff.* (glob)
159 $ hg --debug extdiff -p echo --option echo-naked --option 'being quoted' | grep '^running'
183 $ hg --debug extdiff -p echo --option echo-naked --option 'being quoted' | grep '^running'
160 running "echo echo-naked 'being quoted' */a $TESTTMP/a/a" in */extdiff.* (glob)
184 running "echo echo-naked 'being quoted' */a $TESTTMP/a/a" in */extdiff.* (glob)
161 #endif
185 #endif
162
186
163 $ touch 'sp ace'
187 $ touch 'sp ace'
164 $ hg add 'sp ace'
188 $ hg add 'sp ace'
165 $ hg ci -m 'sp ace'
189 $ hg ci -m 'sp ace'
166 created new head
190 created new head
167 $ echo > 'sp ace'
191 $ echo > 'sp ace'
168
192
169 Test pre-72a89cf86fcd backward compatibility with half-baked manual quoting
193 Test pre-72a89cf86fcd backward compatibility with half-baked manual quoting
170
194
171 $ cat <<EOF >> $HGRCPATH
195 $ cat <<EOF >> $HGRCPATH
172 > [extdiff]
196 > [extdiff]
173 > odd =
197 > odd =
174 > [merge-tools]
198 > [merge-tools]
175 > odd.diffargs = --foo='\$clabel' '\$clabel' "--bar=\$clabel" "\$clabel"
199 > odd.diffargs = --foo='\$clabel' '\$clabel' "--bar=\$clabel" "\$clabel"
176 > odd.executable = echo
200 > odd.executable = echo
177 > EOF
201 > EOF
178 #if windows
202 #if windows
179 TODO
203 TODO
180 #else
204 #else
181 $ hg --debug odd | grep '^running'
205 $ hg --debug odd | grep '^running'
182 running "*/echo --foo='sp ace' 'sp ace' --bar='sp ace' 'sp ace'" in * (glob)
206 running "*/echo --foo='sp ace' 'sp ace' --bar='sp ace' 'sp ace'" in * (glob)
183 #endif
207 #endif
184
208
185 Empty argument must be quoted
209 Empty argument must be quoted
186
210
187 $ cat <<EOF >> $HGRCPATH
211 $ cat <<EOF >> $HGRCPATH
188 > [extdiff]
212 > [extdiff]
189 > kdiff3 = echo
213 > kdiff3 = echo
190 > [merge-tools]
214 > [merge-tools]
191 > kdiff3.diffargs=--L1 \$plabel1 --L2 \$clabel \$parent \$child
215 > kdiff3.diffargs=--L1 \$plabel1 --L2 \$clabel \$parent \$child
192 > EOF
216 > EOF
193 #if windows
217 #if windows
194 $ hg --debug kdiff3 -r0 | grep '^running'
218 $ hg --debug kdiff3 -r0 | grep '^running'
195 running 'echo --L1 "@0" --L2 "" a.8a5febb7f867 a' in * (glob)
219 running 'echo --L1 "@0" --L2 "" a.8a5febb7f867 a' in * (glob)
196 #else
220 #else
197 $ hg --debug kdiff3 -r0 | grep '^running'
221 $ hg --debug kdiff3 -r0 | grep '^running'
198 running "echo --L1 '@0' --L2 '' a.8a5febb7f867 a" in * (glob)
222 running "echo --L1 '@0' --L2 '' a.8a5febb7f867 a" in * (glob)
199 #endif
223 #endif
200
224
201 #if execbit
225 #if execbit
202
226
203 Test extdiff of multiple files in tmp dir:
227 Test extdiff of multiple files in tmp dir:
204
228
205 $ hg update -C 0 > /dev/null
229 $ hg update -C 0 > /dev/null
206 $ echo changed > a
230 $ echo changed > a
207 $ echo changed > b
231 $ echo changed > b
208 $ chmod +x b
232 $ chmod +x b
209
233
210 Diff in working directory, before:
234 Diff in working directory, before:
211
235
212 $ hg diff --git
236 $ hg diff --git
213 diff --git a/a b/a
237 diff --git a/a b/a
214 --- a/a
238 --- a/a
215 +++ b/a
239 +++ b/a
216 @@ -1,1 +1,1 @@
240 @@ -1,1 +1,1 @@
217 -a
241 -a
218 +changed
242 +changed
219 diff --git a/b b/b
243 diff --git a/b b/b
220 old mode 100644
244 old mode 100644
221 new mode 100755
245 new mode 100755
222 --- a/b
246 --- a/b
223 +++ b/b
247 +++ b/b
224 @@ -1,1 +1,1 @@
248 @@ -1,1 +1,1 @@
225 -b
249 -b
226 +changed
250 +changed
227
251
228
252
229 Edit with extdiff -p:
253 Edit with extdiff -p:
230
254
231 Prepare custom diff/edit tool:
255 Prepare custom diff/edit tool:
232
256
233 $ cat > 'diff tool.py' << EOT
257 $ cat > 'diff tool.py' << EOT
234 > #!/usr/bin/env python
258 > #!/usr/bin/env python
235 > import time
259 > import time
236 > time.sleep(1) # avoid unchanged-timestamp problems
260 > time.sleep(1) # avoid unchanged-timestamp problems
237 > file('a/a', 'ab').write('edited\n')
261 > file('a/a', 'ab').write('edited\n')
238 > file('a/b', 'ab').write('edited\n')
262 > file('a/b', 'ab').write('edited\n')
239 > EOT
263 > EOT
240
264
241 $ chmod +x 'diff tool.py'
265 $ chmod +x 'diff tool.py'
242
266
243 will change to /tmp/extdiff.TMP and populate directories a.TMP and a
267 will change to /tmp/extdiff.TMP and populate directories a.TMP and a
244 and start tool
268 and start tool
245
269
246 $ hg extdiff -p "`pwd`/diff tool.py"
270 $ hg extdiff -p "`pwd`/diff tool.py"
247 [1]
271 [1]
248
272
249 Diff in working directory, after:
273 Diff in working directory, after:
250
274
251 $ hg diff --git
275 $ hg diff --git
252 diff --git a/a b/a
276 diff --git a/a b/a
253 --- a/a
277 --- a/a
254 +++ b/a
278 +++ b/a
255 @@ -1,1 +1,2 @@
279 @@ -1,1 +1,2 @@
256 -a
280 -a
257 +changed
281 +changed
258 +edited
282 +edited
259 diff --git a/b b/b
283 diff --git a/b b/b
260 old mode 100644
284 old mode 100644
261 new mode 100755
285 new mode 100755
262 --- a/b
286 --- a/b
263 +++ b/b
287 +++ b/b
264 @@ -1,1 +1,2 @@
288 @@ -1,1 +1,2 @@
265 -b
289 -b
266 +changed
290 +changed
267 +edited
291 +edited
268
292
269 Test extdiff with --option:
293 Test extdiff with --option:
270
294
271 $ hg extdiff -p echo -o this -c 1
295 $ hg extdiff -p echo -o this -c 1
272 this */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
296 this */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
273 [1]
297 [1]
274
298
275 $ hg falabala -o this -c 1
299 $ hg falabala -o this -c 1
276 diffing this */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
300 diffing this */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
277 [1]
301 [1]
278
302
279 Test extdiff's handling of options with spaces in them:
303 Test extdiff's handling of options with spaces in them:
280
304
281 $ hg edspace -c 1
305 $ hg edspace -c 1
282 name <user@example.com> */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
306 name <user@example.com> */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
283 [1]
307 [1]
284
308
285 $ hg extdiff -p echo -o "name <user@example.com>" -c 1
309 $ hg extdiff -p echo -o "name <user@example.com>" -c 1
286 name <user@example.com> */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
310 name <user@example.com> */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
287 [1]
311 [1]
288
312
289 Test with revsets:
313 Test with revsets:
290
314
291 $ hg extdif -p echo -c "rev(1)"
315 $ hg extdif -p echo -c "rev(1)"
292 */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
316 */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
293 [1]
317 [1]
294
318
295 $ hg extdif -p echo -r "0::1"
319 $ hg extdif -p echo -r "0::1"
296 */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
320 */extdiff.*/a.8a5febb7f867/a a.34eed99112ab/a (glob)
297 [1]
321 [1]
298
322
299 Fallback to merge-tools.tool.executable|regkey
323 Fallback to merge-tools.tool.executable|regkey
300 $ mkdir dir
324 $ mkdir dir
301 $ cat > 'dir/tool.sh' << EOF
325 $ cat > 'dir/tool.sh' << EOF
302 > #!/bin/sh
326 > #!/bin/sh
303 > echo "** custom diff **"
327 > echo "** custom diff **"
304 > EOF
328 > EOF
305 $ chmod +x dir/tool.sh
329 $ chmod +x dir/tool.sh
306 $ tool=`pwd`/dir/tool.sh
330 $ tool=`pwd`/dir/tool.sh
307 $ hg --debug tl --config extdiff.tl= --config merge-tools.tl.executable=$tool
331 $ hg --debug tl --config extdiff.tl= --config merge-tools.tl.executable=$tool
308 making snapshot of 2 files from rev * (glob)
332 making snapshot of 2 files from rev * (glob)
309 a
333 a
310 b
334 b
311 making snapshot of 2 files from working directory
335 making snapshot of 2 files from working directory
312 a
336 a
313 b
337 b
314 running '$TESTTMP/a/dir/tool.sh a.* a' in */extdiff.* (glob)
338 running '$TESTTMP/a/dir/tool.sh a.* a' in */extdiff.* (glob)
315 ** custom diff **
339 ** custom diff **
316 cleaning up temp directory
340 cleaning up temp directory
317 [1]
341 [1]
318
342
319 $ cd ..
343 $ cd ..
320
344
321 #endif
345 #endif
322
346
323 #if symlink
347 #if symlink
324
348
325 Test symlinks handling (issue1909)
349 Test symlinks handling (issue1909)
326
350
327 $ hg init testsymlinks
351 $ hg init testsymlinks
328 $ cd testsymlinks
352 $ cd testsymlinks
329 $ echo a > a
353 $ echo a > a
330 $ hg ci -Am adda
354 $ hg ci -Am adda
331 adding a
355 adding a
332 $ echo a >> a
356 $ echo a >> a
333 $ ln -s missing linka
357 $ ln -s missing linka
334 $ hg add linka
358 $ hg add linka
335 $ hg falabala -r 0 --traceback
359 $ hg falabala -r 0 --traceback
336 diffing testsymlinks.07f494440405 testsymlinks
360 diffing testsymlinks.07f494440405 testsymlinks
337 [1]
361 [1]
338 $ cd ..
362 $ cd ..
339
363
340 #endif
364 #endif
@@ -1,1024 +1,1024 b''
1
1
2 $ mkdir -p t
2 $ mkdir -p t
3 $ cd t
3 $ cd t
4 $ cat <<EOF > merge
4 $ cat <<EOF > merge
5 > import sys, os
5 > import sys, os
6 > f = open(sys.argv[1], "wb")
6 > f = open(sys.argv[1], "wb")
7 > f.write("merge %s %s %s" % (sys.argv[1], sys.argv[2], sys.argv[3]))
7 > f.write("merge %s %s %s" % (sys.argv[1], sys.argv[2], sys.argv[3]))
8 > f.close()
8 > f.close()
9 > EOF
9 > EOF
10
10
11 perform a test merge with possible renaming
11 perform a test merge with possible renaming
12 args:
12 args:
13 $1 = action in local branch
13 $1 = action in local branch
14 $2 = action in remote branch
14 $2 = action in remote branch
15 $3 = action in working dir
15 $3 = action in working dir
16 $4 = expected result
16 $4 = expected result
17
17
18 $ tm()
18 $ tm()
19 > {
19 > {
20 > hg init t
20 > hg init t
21 > cd t
21 > cd t
22 > echo "[merge]" >> .hg/hgrc
22 > echo "[merge]" >> .hg/hgrc
23 > echo "followcopies = 1" >> .hg/hgrc
23 > echo "followcopies = 1" >> .hg/hgrc
24 >
24 >
25 > # base
25 > # base
26 > echo base > a
26 > echo base > a
27 > echo base > rev # used to force commits
27 > echo base > rev # used to force commits
28 > hg add a rev
28 > hg add a rev
29 > hg ci -m "base"
29 > hg ci -m "base"
30 >
30 >
31 > # remote
31 > # remote
32 > echo remote > rev
32 > echo remote > rev
33 > if [ "$2" != "" ] ; then $2 ; fi
33 > if [ "$2" != "" ] ; then $2 ; fi
34 > hg ci -m "remote"
34 > hg ci -m "remote"
35 >
35 >
36 > # local
36 > # local
37 > hg co -q 0
37 > hg co -q 0
38 > echo local > rev
38 > echo local > rev
39 > if [ "$1" != "" ] ; then $1 ; fi
39 > if [ "$1" != "" ] ; then $1 ; fi
40 > hg ci -m "local"
40 > hg ci -m "local"
41 >
41 >
42 > # working dir
42 > # working dir
43 > echo local > rev
43 > echo local > rev
44 > if [ "$3" != "" ] ; then $3 ; fi
44 > if [ "$3" != "" ] ; then $3 ; fi
45 >
45 >
46 > # merge
46 > # merge
47 > echo "--------------"
47 > echo "--------------"
48 > echo "test L:$1 R:$2 W:$3 - $4"
48 > echo "test L:$1 R:$2 W:$3 - $4"
49 > echo "--------------"
49 > echo "--------------"
50 > hg merge -y --debug --traceback --tool="python ../merge"
50 > hg merge -y --debug --traceback --tool="python ../merge"
51 >
51 >
52 > echo "--------------"
52 > echo "--------------"
53 > hg status -camC -X rev
53 > hg status -camC -X rev
54 >
54 >
55 > hg ci -m "merge"
55 > hg ci -m "merge"
56 >
56 >
57 > echo "--------------"
57 > echo "--------------"
58 > echo
58 > echo
59 >
59 >
60 > cd ..
60 > cd ..
61 > rm -r t
61 > rm -r t
62 > }
62 > }
63 $ up() {
63 $ up() {
64 > cp rev $1
64 > cp rev $1
65 > hg add $1 2> /dev/null
65 > hg add $1 2> /dev/null
66 > if [ "$2" != "" ] ; then
66 > if [ "$2" != "" ] ; then
67 > cp rev $2
67 > cp rev $2
68 > hg add $2 2> /dev/null
68 > hg add $2 2> /dev/null
69 > fi
69 > fi
70 > }
70 > }
71 $ uc() { up $1; hg cp $1 $2; } # update + copy
71 $ uc() { up $1; hg cp $1 $2; } # update + copy
72 $ um() { up $1; hg mv $1 $2; }
72 $ um() { up $1; hg mv $1 $2; }
73 $ nc() { hg cp $1 $2; } # just copy
73 $ nc() { hg cp $1 $2; } # just copy
74 $ nm() { hg mv $1 $2; } # just move
74 $ nm() { hg mv $1 $2; } # just move
75 $ tm "up a " "nc a b" " " "1 get local a to b"
75 $ tm "up a " "nc a b" " " "1 get local a to b"
76 created new head
76 created new head
77 --------------
77 --------------
78 test L:up a R:nc a b W: - 1 get local a to b
78 test L:up a R:nc a b W: - 1 get local a to b
79 --------------
79 --------------
80 searching for copies back to rev 1
80 searching for copies back to rev 1
81 unmatched files in other:
81 unmatched files in other:
82 b
82 b
83 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
83 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
84 src: 'a' -> dst: 'b' *
84 src: 'a' -> dst: 'b' *
85 checking for directory renames
85 checking for directory renames
86 resolving manifests
86 resolving manifests
87 branchmerge: True, force: False, partial: False
87 branchmerge: True, force: False, partial: False
88 ancestor: 924404dff337, local: e300d1c794ec+, remote: 4ce40f5aca24
88 ancestor: 924404dff337, local: e300d1c794ec+, remote: 4ce40f5aca24
89 preserving a for resolve of b
89 preserving a for resolve of b
90 preserving rev for resolve of rev
90 preserving rev for resolve of rev
91 a: remote unchanged -> k
91 a: remote unchanged -> k
92 b: remote copied from a -> m
92 b: remote copied from a -> m
93 updating: b 1/2 files (50.00%)
93 updating: b 1/2 files (50.00%)
94 picked tool 'python ../merge' for b (binary False symlink False)
94 picked tool 'python ../merge' for b (binary False symlink False)
95 merging a and b to b
95 merging a and b to b
96 my b@e300d1c794ec+ other b@4ce40f5aca24 ancestor a@924404dff337
96 my b@e300d1c794ec+ other b@4ce40f5aca24 ancestor a@924404dff337
97 premerge successful
97 premerge successful
98 rev: versions differ -> m
98 rev: versions differ -> m
99 updating: rev 2/2 files (100.00%)
99 updating: rev 2/2 files (100.00%)
100 picked tool 'python ../merge' for rev (binary False symlink False)
100 picked tool 'python ../merge' for rev (binary False symlink False)
101 merging rev
101 merging rev
102 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
102 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
103 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
103 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
104 merge tool returned: 0
104 merge tool returned: 0
105 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
105 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
106 (branch merge, don't forget to commit)
106 (branch merge, don't forget to commit)
107 --------------
107 --------------
108 M b
108 M b
109 a
109 a
110 C a
110 C a
111 --------------
111 --------------
112
112
113 $ tm "nc a b" "up a " " " "2 get rem change to a and b"
113 $ tm "nc a b" "up a " " " "2 get rem change to a and b"
114 created new head
114 created new head
115 --------------
115 --------------
116 test L:nc a b R:up a W: - 2 get rem change to a and b
116 test L:nc a b R:up a W: - 2 get rem change to a and b
117 --------------
117 --------------
118 searching for copies back to rev 1
118 searching for copies back to rev 1
119 unmatched files in local:
119 unmatched files in local:
120 b
120 b
121 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
121 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
122 src: 'a' -> dst: 'b' *
122 src: 'a' -> dst: 'b' *
123 checking for directory renames
123 checking for directory renames
124 resolving manifests
124 resolving manifests
125 branchmerge: True, force: False, partial: False
125 branchmerge: True, force: False, partial: False
126 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: f4db7e329e71
126 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: f4db7e329e71
127 preserving b for resolve of b
127 preserving b for resolve of b
128 preserving rev for resolve of rev
128 preserving rev for resolve of rev
129 a: remote is newer -> g
129 a: remote is newer -> g
130 getting a
130 getting a
131 updating: a 1/3 files (33.33%)
131 updating: a 1/3 files (33.33%)
132 b: local copied/moved from a -> m
132 b: local copied/moved from a -> m
133 updating: b 2/3 files (66.67%)
133 updating: b 2/3 files (66.67%)
134 picked tool 'python ../merge' for b (binary False symlink False)
134 picked tool 'python ../merge' for b (binary False symlink False)
135 merging b and a to b
135 merging b and a to b
136 my b@86a2aa42fc76+ other a@f4db7e329e71 ancestor a@924404dff337
136 my b@86a2aa42fc76+ other a@f4db7e329e71 ancestor a@924404dff337
137 premerge successful
137 premerge successful
138 rev: versions differ -> m
138 rev: versions differ -> m
139 updating: rev 3/3 files (100.00%)
139 updating: rev 3/3 files (100.00%)
140 picked tool 'python ../merge' for rev (binary False symlink False)
140 picked tool 'python ../merge' for rev (binary False symlink False)
141 merging rev
141 merging rev
142 my rev@86a2aa42fc76+ other rev@f4db7e329e71 ancestor rev@924404dff337
142 my rev@86a2aa42fc76+ other rev@f4db7e329e71 ancestor rev@924404dff337
143 launching merge tool: python ../merge $TESTTMP/t/t/rev * (glob)
143 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * (glob)
144 merge tool returned: 0
144 merge tool returned: 0
145 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
145 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
146 (branch merge, don't forget to commit)
146 (branch merge, don't forget to commit)
147 --------------
147 --------------
148 M a
148 M a
149 M b
149 M b
150 a
150 a
151 --------------
151 --------------
152
152
153 $ tm "up a " "nm a b" " " "3 get local a change to b, remove a"
153 $ tm "up a " "nm a b" " " "3 get local a change to b, remove a"
154 created new head
154 created new head
155 --------------
155 --------------
156 test L:up a R:nm a b W: - 3 get local a change to b, remove a
156 test L:up a R:nm a b W: - 3 get local a change to b, remove a
157 --------------
157 --------------
158 searching for copies back to rev 1
158 searching for copies back to rev 1
159 unmatched files in other:
159 unmatched files in other:
160 b
160 b
161 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
161 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
162 src: 'a' -> dst: 'b' *
162 src: 'a' -> dst: 'b' *
163 checking for directory renames
163 checking for directory renames
164 resolving manifests
164 resolving manifests
165 branchmerge: True, force: False, partial: False
165 branchmerge: True, force: False, partial: False
166 ancestor: 924404dff337, local: e300d1c794ec+, remote: bdb19105162a
166 ancestor: 924404dff337, local: e300d1c794ec+, remote: bdb19105162a
167 preserving a for resolve of b
167 preserving a for resolve of b
168 preserving rev for resolve of rev
168 preserving rev for resolve of rev
169 removing a
169 removing a
170 b: remote moved from a -> m
170 b: remote moved from a -> m
171 updating: b 1/2 files (50.00%)
171 updating: b 1/2 files (50.00%)
172 picked tool 'python ../merge' for b (binary False symlink False)
172 picked tool 'python ../merge' for b (binary False symlink False)
173 merging a and b to b
173 merging a and b to b
174 my b@e300d1c794ec+ other b@bdb19105162a ancestor a@924404dff337
174 my b@e300d1c794ec+ other b@bdb19105162a ancestor a@924404dff337
175 premerge successful
175 premerge successful
176 rev: versions differ -> m
176 rev: versions differ -> m
177 updating: rev 2/2 files (100.00%)
177 updating: rev 2/2 files (100.00%)
178 picked tool 'python ../merge' for rev (binary False symlink False)
178 picked tool 'python ../merge' for rev (binary False symlink False)
179 merging rev
179 merging rev
180 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
180 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
181 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
181 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
182 merge tool returned: 0
182 merge tool returned: 0
183 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
183 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
184 (branch merge, don't forget to commit)
184 (branch merge, don't forget to commit)
185 --------------
185 --------------
186 M b
186 M b
187 a
187 a
188 --------------
188 --------------
189
189
190 $ tm "nm a b" "up a " " " "4 get remote change to b"
190 $ tm "nm a b" "up a " " " "4 get remote change to b"
191 created new head
191 created new head
192 --------------
192 --------------
193 test L:nm a b R:up a W: - 4 get remote change to b
193 test L:nm a b R:up a W: - 4 get remote change to b
194 --------------
194 --------------
195 searching for copies back to rev 1
195 searching for copies back to rev 1
196 unmatched files in local:
196 unmatched files in local:
197 b
197 b
198 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
198 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
199 src: 'a' -> dst: 'b' *
199 src: 'a' -> dst: 'b' *
200 checking for directory renames
200 checking for directory renames
201 resolving manifests
201 resolving manifests
202 branchmerge: True, force: False, partial: False
202 branchmerge: True, force: False, partial: False
203 ancestor: 924404dff337, local: 02963e448370+, remote: f4db7e329e71
203 ancestor: 924404dff337, local: 02963e448370+, remote: f4db7e329e71
204 preserving b for resolve of b
204 preserving b for resolve of b
205 preserving rev for resolve of rev
205 preserving rev for resolve of rev
206 b: local copied/moved from a -> m
206 b: local copied/moved from a -> m
207 updating: b 1/2 files (50.00%)
207 updating: b 1/2 files (50.00%)
208 picked tool 'python ../merge' for b (binary False symlink False)
208 picked tool 'python ../merge' for b (binary False symlink False)
209 merging b and a to b
209 merging b and a to b
210 my b@02963e448370+ other a@f4db7e329e71 ancestor a@924404dff337
210 my b@02963e448370+ other a@f4db7e329e71 ancestor a@924404dff337
211 premerge successful
211 premerge successful
212 rev: versions differ -> m
212 rev: versions differ -> m
213 updating: rev 2/2 files (100.00%)
213 updating: rev 2/2 files (100.00%)
214 picked tool 'python ../merge' for rev (binary False symlink False)
214 picked tool 'python ../merge' for rev (binary False symlink False)
215 merging rev
215 merging rev
216 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
216 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
217 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
217 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
218 merge tool returned: 0
218 merge tool returned: 0
219 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
219 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
220 (branch merge, don't forget to commit)
220 (branch merge, don't forget to commit)
221 --------------
221 --------------
222 M b
222 M b
223 a
223 a
224 --------------
224 --------------
225
225
226 $ tm " " "nc a b" " " "5 get b"
226 $ tm " " "nc a b" " " "5 get b"
227 created new head
227 created new head
228 --------------
228 --------------
229 test L: R:nc a b W: - 5 get b
229 test L: R:nc a b W: - 5 get b
230 --------------
230 --------------
231 searching for copies back to rev 1
231 searching for copies back to rev 1
232 unmatched files in other:
232 unmatched files in other:
233 b
233 b
234 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
234 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
235 src: 'a' -> dst: 'b'
235 src: 'a' -> dst: 'b'
236 checking for directory renames
236 checking for directory renames
237 resolving manifests
237 resolving manifests
238 branchmerge: True, force: False, partial: False
238 branchmerge: True, force: False, partial: False
239 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: 4ce40f5aca24
239 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: 4ce40f5aca24
240 preserving rev for resolve of rev
240 preserving rev for resolve of rev
241 b: remote created -> g
241 b: remote created -> g
242 getting b
242 getting b
243 updating: b 1/2 files (50.00%)
243 updating: b 1/2 files (50.00%)
244 rev: versions differ -> m
244 rev: versions differ -> m
245 updating: rev 2/2 files (100.00%)
245 updating: rev 2/2 files (100.00%)
246 picked tool 'python ../merge' for rev (binary False symlink False)
246 picked tool 'python ../merge' for rev (binary False symlink False)
247 merging rev
247 merging rev
248 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
248 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
249 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
249 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
250 merge tool returned: 0
250 merge tool returned: 0
251 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
251 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
252 (branch merge, don't forget to commit)
252 (branch merge, don't forget to commit)
253 --------------
253 --------------
254 M b
254 M b
255 C a
255 C a
256 --------------
256 --------------
257
257
258 $ tm "nc a b" " " " " "6 nothing"
258 $ tm "nc a b" " " " " "6 nothing"
259 created new head
259 created new head
260 --------------
260 --------------
261 test L:nc a b R: W: - 6 nothing
261 test L:nc a b R: W: - 6 nothing
262 --------------
262 --------------
263 searching for copies back to rev 1
263 searching for copies back to rev 1
264 unmatched files in local:
264 unmatched files in local:
265 b
265 b
266 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
266 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
267 src: 'a' -> dst: 'b'
267 src: 'a' -> dst: 'b'
268 checking for directory renames
268 checking for directory renames
269 resolving manifests
269 resolving manifests
270 branchmerge: True, force: False, partial: False
270 branchmerge: True, force: False, partial: False
271 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 97c705ade336
271 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 97c705ade336
272 preserving rev for resolve of rev
272 preserving rev for resolve of rev
273 rev: versions differ -> m
273 rev: versions differ -> m
274 updating: rev 1/1 files (100.00%)
274 updating: rev 1/1 files (100.00%)
275 picked tool 'python ../merge' for rev (binary False symlink False)
275 picked tool 'python ../merge' for rev (binary False symlink False)
276 merging rev
276 merging rev
277 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
277 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
278 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
278 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
279 merge tool returned: 0
279 merge tool returned: 0
280 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
280 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
281 (branch merge, don't forget to commit)
281 (branch merge, don't forget to commit)
282 --------------
282 --------------
283 C a
283 C a
284 C b
284 C b
285 --------------
285 --------------
286
286
287 $ tm " " "nm a b" " " "7 get b"
287 $ tm " " "nm a b" " " "7 get b"
288 created new head
288 created new head
289 --------------
289 --------------
290 test L: R:nm a b W: - 7 get b
290 test L: R:nm a b W: - 7 get b
291 --------------
291 --------------
292 searching for copies back to rev 1
292 searching for copies back to rev 1
293 unmatched files in other:
293 unmatched files in other:
294 b
294 b
295 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
295 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
296 src: 'a' -> dst: 'b'
296 src: 'a' -> dst: 'b'
297 checking for directory renames
297 checking for directory renames
298 resolving manifests
298 resolving manifests
299 branchmerge: True, force: False, partial: False
299 branchmerge: True, force: False, partial: False
300 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: bdb19105162a
300 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: bdb19105162a
301 preserving rev for resolve of rev
301 preserving rev for resolve of rev
302 a: other deleted -> r
302 a: other deleted -> r
303 removing a
303 removing a
304 updating: a 1/3 files (33.33%)
304 updating: a 1/3 files (33.33%)
305 b: remote created -> g
305 b: remote created -> g
306 getting b
306 getting b
307 updating: b 2/3 files (66.67%)
307 updating: b 2/3 files (66.67%)
308 rev: versions differ -> m
308 rev: versions differ -> m
309 updating: rev 3/3 files (100.00%)
309 updating: rev 3/3 files (100.00%)
310 picked tool 'python ../merge' for rev (binary False symlink False)
310 picked tool 'python ../merge' for rev (binary False symlink False)
311 merging rev
311 merging rev
312 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
312 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
313 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
313 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
314 merge tool returned: 0
314 merge tool returned: 0
315 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
315 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
316 (branch merge, don't forget to commit)
316 (branch merge, don't forget to commit)
317 --------------
317 --------------
318 M b
318 M b
319 --------------
319 --------------
320
320
321 $ tm "nm a b" " " " " "8 nothing"
321 $ tm "nm a b" " " " " "8 nothing"
322 created new head
322 created new head
323 --------------
323 --------------
324 test L:nm a b R: W: - 8 nothing
324 test L:nm a b R: W: - 8 nothing
325 --------------
325 --------------
326 searching for copies back to rev 1
326 searching for copies back to rev 1
327 unmatched files in local:
327 unmatched files in local:
328 b
328 b
329 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
329 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
330 src: 'a' -> dst: 'b'
330 src: 'a' -> dst: 'b'
331 checking for directory renames
331 checking for directory renames
332 resolving manifests
332 resolving manifests
333 branchmerge: True, force: False, partial: False
333 branchmerge: True, force: False, partial: False
334 ancestor: 924404dff337, local: 02963e448370+, remote: 97c705ade336
334 ancestor: 924404dff337, local: 02963e448370+, remote: 97c705ade336
335 preserving rev for resolve of rev
335 preserving rev for resolve of rev
336 rev: versions differ -> m
336 rev: versions differ -> m
337 updating: rev 1/1 files (100.00%)
337 updating: rev 1/1 files (100.00%)
338 picked tool 'python ../merge' for rev (binary False symlink False)
338 picked tool 'python ../merge' for rev (binary False symlink False)
339 merging rev
339 merging rev
340 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
340 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
341 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
341 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
342 merge tool returned: 0
342 merge tool returned: 0
343 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
343 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
344 (branch merge, don't forget to commit)
344 (branch merge, don't forget to commit)
345 --------------
345 --------------
346 C b
346 C b
347 --------------
347 --------------
348
348
349 $ tm "um a b" "um a b" " " "9 do merge with ancestor in a"
349 $ tm "um a b" "um a b" " " "9 do merge with ancestor in a"
350 created new head
350 created new head
351 --------------
351 --------------
352 test L:um a b R:um a b W: - 9 do merge with ancestor in a
352 test L:um a b R:um a b W: - 9 do merge with ancestor in a
353 --------------
353 --------------
354 searching for copies back to rev 1
354 searching for copies back to rev 1
355 unmatched files new in both:
355 unmatched files new in both:
356 b
356 b
357 resolving manifests
357 resolving manifests
358 branchmerge: True, force: False, partial: False
358 branchmerge: True, force: False, partial: False
359 ancestor: 924404dff337, local: 62e7bf090eba+, remote: 49b6d8032493
359 ancestor: 924404dff337, local: 62e7bf090eba+, remote: 49b6d8032493
360 preserving b for resolve of b
360 preserving b for resolve of b
361 preserving rev for resolve of rev
361 preserving rev for resolve of rev
362 b: both renamed from a -> m
362 b: both renamed from a -> m
363 updating: b 1/2 files (50.00%)
363 updating: b 1/2 files (50.00%)
364 picked tool 'python ../merge' for b (binary False symlink False)
364 picked tool 'python ../merge' for b (binary False symlink False)
365 merging b
365 merging b
366 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
366 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
367 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
367 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
368 merge tool returned: 0
368 merge tool returned: 0
369 rev: versions differ -> m
369 rev: versions differ -> m
370 updating: rev 2/2 files (100.00%)
370 updating: rev 2/2 files (100.00%)
371 picked tool 'python ../merge' for rev (binary False symlink False)
371 picked tool 'python ../merge' for rev (binary False symlink False)
372 merging rev
372 merging rev
373 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
373 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
374 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
374 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
375 merge tool returned: 0
375 merge tool returned: 0
376 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
376 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
377 (branch merge, don't forget to commit)
377 (branch merge, don't forget to commit)
378 --------------
378 --------------
379 M b
379 M b
380 --------------
380 --------------
381
381
382
382
383 m "um a c" "um x c" " " "10 do merge with no ancestor"
383 m "um a c" "um x c" " " "10 do merge with no ancestor"
384
384
385 $ tm "nm a b" "nm a c" " " "11 get c, keep b"
385 $ tm "nm a b" "nm a c" " " "11 get c, keep b"
386 created new head
386 created new head
387 --------------
387 --------------
388 test L:nm a b R:nm a c W: - 11 get c, keep b
388 test L:nm a b R:nm a c W: - 11 get c, keep b
389 --------------
389 --------------
390 searching for copies back to rev 1
390 searching for copies back to rev 1
391 unmatched files in local:
391 unmatched files in local:
392 b
392 b
393 unmatched files in other:
393 unmatched files in other:
394 c
394 c
395 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
395 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
396 src: 'a' -> dst: 'b' !
396 src: 'a' -> dst: 'b' !
397 src: 'a' -> dst: 'c' !
397 src: 'a' -> dst: 'c' !
398 checking for directory renames
398 checking for directory renames
399 resolving manifests
399 resolving manifests
400 branchmerge: True, force: False, partial: False
400 branchmerge: True, force: False, partial: False
401 ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
401 ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
402 preserving rev for resolve of rev
402 preserving rev for resolve of rev
403 c: remote created -> g
403 c: remote created -> g
404 getting c
404 getting c
405 updating: c 1/2 files (50.00%)
405 updating: c 1/2 files (50.00%)
406 rev: versions differ -> m
406 rev: versions differ -> m
407 updating: rev 2/2 files (100.00%)
407 updating: rev 2/2 files (100.00%)
408 picked tool 'python ../merge' for rev (binary False symlink False)
408 picked tool 'python ../merge' for rev (binary False symlink False)
409 merging rev
409 merging rev
410 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
410 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
411 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
411 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
412 merge tool returned: 0
412 merge tool returned: 0
413 note: possible conflict - a was renamed multiple times to:
413 note: possible conflict - a was renamed multiple times to:
414 b
414 b
415 c
415 c
416 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
416 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
417 (branch merge, don't forget to commit)
417 (branch merge, don't forget to commit)
418 --------------
418 --------------
419 M c
419 M c
420 C b
420 C b
421 --------------
421 --------------
422
422
423 $ tm "nc a b" "up b " " " "12 merge b no ancestor"
423 $ tm "nc a b" "up b " " " "12 merge b no ancestor"
424 created new head
424 created new head
425 --------------
425 --------------
426 test L:nc a b R:up b W: - 12 merge b no ancestor
426 test L:nc a b R:up b W: - 12 merge b no ancestor
427 --------------
427 --------------
428 searching for copies back to rev 1
428 searching for copies back to rev 1
429 unmatched files new in both:
429 unmatched files new in both:
430 b
430 b
431 resolving manifests
431 resolving manifests
432 branchmerge: True, force: False, partial: False
432 branchmerge: True, force: False, partial: False
433 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
433 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
434 preserving b for resolve of b
434 preserving b for resolve of b
435 preserving rev for resolve of rev
435 preserving rev for resolve of rev
436 b: both created -> m
436 b: both created -> m
437 updating: b 1/2 files (50.00%)
437 updating: b 1/2 files (50.00%)
438 picked tool 'python ../merge' for b (binary False symlink False)
438 picked tool 'python ../merge' for b (binary False symlink False)
439 merging b
439 merging b
440 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
440 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
441 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
441 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
442 merge tool returned: 0
442 merge tool returned: 0
443 rev: versions differ -> m
443 rev: versions differ -> m
444 updating: rev 2/2 files (100.00%)
444 updating: rev 2/2 files (100.00%)
445 picked tool 'python ../merge' for rev (binary False symlink False)
445 picked tool 'python ../merge' for rev (binary False symlink False)
446 merging rev
446 merging rev
447 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
447 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
448 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
448 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
449 merge tool returned: 0
449 merge tool returned: 0
450 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
450 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
451 (branch merge, don't forget to commit)
451 (branch merge, don't forget to commit)
452 --------------
452 --------------
453 M b
453 M b
454 C a
454 C a
455 --------------
455 --------------
456
456
457 $ tm "up b " "nm a b" " " "13 merge b no ancestor"
457 $ tm "up b " "nm a b" " " "13 merge b no ancestor"
458 created new head
458 created new head
459 --------------
459 --------------
460 test L:up b R:nm a b W: - 13 merge b no ancestor
460 test L:up b R:nm a b W: - 13 merge b no ancestor
461 --------------
461 --------------
462 searching for copies back to rev 1
462 searching for copies back to rev 1
463 unmatched files new in both:
463 unmatched files new in both:
464 b
464 b
465 resolving manifests
465 resolving manifests
466 branchmerge: True, force: False, partial: False
466 branchmerge: True, force: False, partial: False
467 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
467 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
468 preserving b for resolve of b
468 preserving b for resolve of b
469 preserving rev for resolve of rev
469 preserving rev for resolve of rev
470 a: other deleted -> r
470 a: other deleted -> r
471 removing a
471 removing a
472 updating: a 1/3 files (33.33%)
472 updating: a 1/3 files (33.33%)
473 b: both created -> m
473 b: both created -> m
474 updating: b 2/3 files (66.67%)
474 updating: b 2/3 files (66.67%)
475 picked tool 'python ../merge' for b (binary False symlink False)
475 picked tool 'python ../merge' for b (binary False symlink False)
476 merging b
476 merging b
477 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
477 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
478 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
478 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
479 merge tool returned: 0
479 merge tool returned: 0
480 rev: versions differ -> m
480 rev: versions differ -> m
481 updating: rev 3/3 files (100.00%)
481 updating: rev 3/3 files (100.00%)
482 picked tool 'python ../merge' for rev (binary False symlink False)
482 picked tool 'python ../merge' for rev (binary False symlink False)
483 merging rev
483 merging rev
484 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
484 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
485 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
485 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
486 merge tool returned: 0
486 merge tool returned: 0
487 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
487 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
488 (branch merge, don't forget to commit)
488 (branch merge, don't forget to commit)
489 --------------
489 --------------
490 M b
490 M b
491 --------------
491 --------------
492
492
493 $ tm "nc a b" "up a b" " " "14 merge b no ancestor"
493 $ tm "nc a b" "up a b" " " "14 merge b no ancestor"
494 created new head
494 created new head
495 --------------
495 --------------
496 test L:nc a b R:up a b W: - 14 merge b no ancestor
496 test L:nc a b R:up a b W: - 14 merge b no ancestor
497 --------------
497 --------------
498 searching for copies back to rev 1
498 searching for copies back to rev 1
499 unmatched files new in both:
499 unmatched files new in both:
500 b
500 b
501 resolving manifests
501 resolving manifests
502 branchmerge: True, force: False, partial: False
502 branchmerge: True, force: False, partial: False
503 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
503 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
504 preserving b for resolve of b
504 preserving b for resolve of b
505 preserving rev for resolve of rev
505 preserving rev for resolve of rev
506 a: remote is newer -> g
506 a: remote is newer -> g
507 getting a
507 getting a
508 updating: a 1/3 files (33.33%)
508 updating: a 1/3 files (33.33%)
509 b: both created -> m
509 b: both created -> m
510 updating: b 2/3 files (66.67%)
510 updating: b 2/3 files (66.67%)
511 picked tool 'python ../merge' for b (binary False symlink False)
511 picked tool 'python ../merge' for b (binary False symlink False)
512 merging b
512 merging b
513 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
513 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
514 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
514 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
515 merge tool returned: 0
515 merge tool returned: 0
516 rev: versions differ -> m
516 rev: versions differ -> m
517 updating: rev 3/3 files (100.00%)
517 updating: rev 3/3 files (100.00%)
518 picked tool 'python ../merge' for rev (binary False symlink False)
518 picked tool 'python ../merge' for rev (binary False symlink False)
519 merging rev
519 merging rev
520 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
520 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
521 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
521 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
522 merge tool returned: 0
522 merge tool returned: 0
523 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
523 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
524 (branch merge, don't forget to commit)
524 (branch merge, don't forget to commit)
525 --------------
525 --------------
526 M a
526 M a
527 M b
527 M b
528 --------------
528 --------------
529
529
530 $ tm "up b " "nm a b" " " "15 merge b no ancestor, remove a"
530 $ tm "up b " "nm a b" " " "15 merge b no ancestor, remove a"
531 created new head
531 created new head
532 --------------
532 --------------
533 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
533 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
534 --------------
534 --------------
535 searching for copies back to rev 1
535 searching for copies back to rev 1
536 unmatched files new in both:
536 unmatched files new in both:
537 b
537 b
538 resolving manifests
538 resolving manifests
539 branchmerge: True, force: False, partial: False
539 branchmerge: True, force: False, partial: False
540 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
540 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
541 preserving b for resolve of b
541 preserving b for resolve of b
542 preserving rev for resolve of rev
542 preserving rev for resolve of rev
543 a: other deleted -> r
543 a: other deleted -> r
544 removing a
544 removing a
545 updating: a 1/3 files (33.33%)
545 updating: a 1/3 files (33.33%)
546 b: both created -> m
546 b: both created -> m
547 updating: b 2/3 files (66.67%)
547 updating: b 2/3 files (66.67%)
548 picked tool 'python ../merge' for b (binary False symlink False)
548 picked tool 'python ../merge' for b (binary False symlink False)
549 merging b
549 merging b
550 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
550 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
551 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
551 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
552 merge tool returned: 0
552 merge tool returned: 0
553 rev: versions differ -> m
553 rev: versions differ -> m
554 updating: rev 3/3 files (100.00%)
554 updating: rev 3/3 files (100.00%)
555 picked tool 'python ../merge' for rev (binary False symlink False)
555 picked tool 'python ../merge' for rev (binary False symlink False)
556 merging rev
556 merging rev
557 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
557 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
558 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
558 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
559 merge tool returned: 0
559 merge tool returned: 0
560 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
560 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
561 (branch merge, don't forget to commit)
561 (branch merge, don't forget to commit)
562 --------------
562 --------------
563 M b
563 M b
564 --------------
564 --------------
565
565
566 $ tm "nc a b" "up a b" " " "16 get a, merge b no ancestor"
566 $ tm "nc a b" "up a b" " " "16 get a, merge b no ancestor"
567 created new head
567 created new head
568 --------------
568 --------------
569 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
569 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
570 --------------
570 --------------
571 searching for copies back to rev 1
571 searching for copies back to rev 1
572 unmatched files new in both:
572 unmatched files new in both:
573 b
573 b
574 resolving manifests
574 resolving manifests
575 branchmerge: True, force: False, partial: False
575 branchmerge: True, force: False, partial: False
576 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
576 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
577 preserving b for resolve of b
577 preserving b for resolve of b
578 preserving rev for resolve of rev
578 preserving rev for resolve of rev
579 a: remote is newer -> g
579 a: remote is newer -> g
580 getting a
580 getting a
581 updating: a 1/3 files (33.33%)
581 updating: a 1/3 files (33.33%)
582 b: both created -> m
582 b: both created -> m
583 updating: b 2/3 files (66.67%)
583 updating: b 2/3 files (66.67%)
584 picked tool 'python ../merge' for b (binary False symlink False)
584 picked tool 'python ../merge' for b (binary False symlink False)
585 merging b
585 merging b
586 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
586 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
587 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
587 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
588 merge tool returned: 0
588 merge tool returned: 0
589 rev: versions differ -> m
589 rev: versions differ -> m
590 updating: rev 3/3 files (100.00%)
590 updating: rev 3/3 files (100.00%)
591 picked tool 'python ../merge' for rev (binary False symlink False)
591 picked tool 'python ../merge' for rev (binary False symlink False)
592 merging rev
592 merging rev
593 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
593 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
594 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
594 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
595 merge tool returned: 0
595 merge tool returned: 0
596 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
596 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
597 (branch merge, don't forget to commit)
597 (branch merge, don't forget to commit)
598 --------------
598 --------------
599 M a
599 M a
600 M b
600 M b
601 --------------
601 --------------
602
602
603 $ tm "up a b" "nc a b" " " "17 keep a, merge b no ancestor"
603 $ tm "up a b" "nc a b" " " "17 keep a, merge b no ancestor"
604 created new head
604 created new head
605 --------------
605 --------------
606 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
606 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
607 --------------
607 --------------
608 searching for copies back to rev 1
608 searching for copies back to rev 1
609 unmatched files new in both:
609 unmatched files new in both:
610 b
610 b
611 resolving manifests
611 resolving manifests
612 branchmerge: True, force: False, partial: False
612 branchmerge: True, force: False, partial: False
613 ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
613 ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
614 preserving b for resolve of b
614 preserving b for resolve of b
615 preserving rev for resolve of rev
615 preserving rev for resolve of rev
616 a: remote unchanged -> k
616 a: remote unchanged -> k
617 b: both created -> m
617 b: both created -> m
618 updating: b 1/2 files (50.00%)
618 updating: b 1/2 files (50.00%)
619 picked tool 'python ../merge' for b (binary False symlink False)
619 picked tool 'python ../merge' for b (binary False symlink False)
620 merging b
620 merging b
621 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
621 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
622 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
622 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
623 merge tool returned: 0
623 merge tool returned: 0
624 rev: versions differ -> m
624 rev: versions differ -> m
625 updating: rev 2/2 files (100.00%)
625 updating: rev 2/2 files (100.00%)
626 picked tool 'python ../merge' for rev (binary False symlink False)
626 picked tool 'python ../merge' for rev (binary False symlink False)
627 merging rev
627 merging rev
628 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
628 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
629 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
629 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
630 merge tool returned: 0
630 merge tool returned: 0
631 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
631 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
632 (branch merge, don't forget to commit)
632 (branch merge, don't forget to commit)
633 --------------
633 --------------
634 M b
634 M b
635 C a
635 C a
636 --------------
636 --------------
637
637
638 $ tm "nm a b" "up a b" " " "18 merge b no ancestor"
638 $ tm "nm a b" "up a b" " " "18 merge b no ancestor"
639 created new head
639 created new head
640 --------------
640 --------------
641 test L:nm a b R:up a b W: - 18 merge b no ancestor
641 test L:nm a b R:up a b W: - 18 merge b no ancestor
642 --------------
642 --------------
643 searching for copies back to rev 1
643 searching for copies back to rev 1
644 unmatched files new in both:
644 unmatched files new in both:
645 b
645 b
646 resolving manifests
646 resolving manifests
647 branchmerge: True, force: False, partial: False
647 branchmerge: True, force: False, partial: False
648 ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
648 ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
649 remote changed a which local deleted
649 remote changed a which local deleted
650 use (c)hanged version or leave (d)eleted? c
650 use (c)hanged version or leave (d)eleted? c
651 preserving b for resolve of b
651 preserving b for resolve of b
652 preserving rev for resolve of rev
652 preserving rev for resolve of rev
653 a: prompt recreating -> g
653 a: prompt recreating -> g
654 getting a
654 getting a
655 updating: a 1/3 files (33.33%)
655 updating: a 1/3 files (33.33%)
656 b: both created -> m
656 b: both created -> m
657 updating: b 2/3 files (66.67%)
657 updating: b 2/3 files (66.67%)
658 picked tool 'python ../merge' for b (binary False symlink False)
658 picked tool 'python ../merge' for b (binary False symlink False)
659 merging b
659 merging b
660 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
660 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
661 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
661 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
662 merge tool returned: 0
662 merge tool returned: 0
663 rev: versions differ -> m
663 rev: versions differ -> m
664 updating: rev 3/3 files (100.00%)
664 updating: rev 3/3 files (100.00%)
665 picked tool 'python ../merge' for rev (binary False symlink False)
665 picked tool 'python ../merge' for rev (binary False symlink False)
666 merging rev
666 merging rev
667 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
667 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
668 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
668 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
669 merge tool returned: 0
669 merge tool returned: 0
670 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
670 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
671 (branch merge, don't forget to commit)
671 (branch merge, don't forget to commit)
672 --------------
672 --------------
673 M a
673 M a
674 M b
674 M b
675 --------------
675 --------------
676
676
677 $ tm "up a b" "nm a b" " " "19 merge b no ancestor, prompt remove a"
677 $ tm "up a b" "nm a b" " " "19 merge b no ancestor, prompt remove a"
678 created new head
678 created new head
679 --------------
679 --------------
680 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
680 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
681 --------------
681 --------------
682 searching for copies back to rev 1
682 searching for copies back to rev 1
683 unmatched files new in both:
683 unmatched files new in both:
684 b
684 b
685 resolving manifests
685 resolving manifests
686 branchmerge: True, force: False, partial: False
686 branchmerge: True, force: False, partial: False
687 ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
687 ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
688 local changed a which remote deleted
688 local changed a which remote deleted
689 use (c)hanged version or (d)elete? c
689 use (c)hanged version or (d)elete? c
690 preserving b for resolve of b
690 preserving b for resolve of b
691 preserving rev for resolve of rev
691 preserving rev for resolve of rev
692 a: prompt keep -> a
692 a: prompt keep -> a
693 updating: a 1/3 files (33.33%)
693 updating: a 1/3 files (33.33%)
694 b: both created -> m
694 b: both created -> m
695 updating: b 2/3 files (66.67%)
695 updating: b 2/3 files (66.67%)
696 picked tool 'python ../merge' for b (binary False symlink False)
696 picked tool 'python ../merge' for b (binary False symlink False)
697 merging b
697 merging b
698 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
698 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
699 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
699 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
700 merge tool returned: 0
700 merge tool returned: 0
701 rev: versions differ -> m
701 rev: versions differ -> m
702 updating: rev 3/3 files (100.00%)
702 updating: rev 3/3 files (100.00%)
703 picked tool 'python ../merge' for rev (binary False symlink False)
703 picked tool 'python ../merge' for rev (binary False symlink False)
704 merging rev
704 merging rev
705 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
705 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
706 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
706 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
707 merge tool returned: 0
707 merge tool returned: 0
708 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
708 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
709 (branch merge, don't forget to commit)
709 (branch merge, don't forget to commit)
710 --------------
710 --------------
711 M b
711 M b
712 C a
712 C a
713 --------------
713 --------------
714
714
715 $ tm "up a " "um a b" " " "20 merge a and b to b, remove a"
715 $ tm "up a " "um a b" " " "20 merge a and b to b, remove a"
716 created new head
716 created new head
717 --------------
717 --------------
718 test L:up a R:um a b W: - 20 merge a and b to b, remove a
718 test L:up a R:um a b W: - 20 merge a and b to b, remove a
719 --------------
719 --------------
720 searching for copies back to rev 1
720 searching for copies back to rev 1
721 unmatched files in other:
721 unmatched files in other:
722 b
722 b
723 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
723 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
724 src: 'a' -> dst: 'b' *
724 src: 'a' -> dst: 'b' *
725 checking for directory renames
725 checking for directory renames
726 resolving manifests
726 resolving manifests
727 branchmerge: True, force: False, partial: False
727 branchmerge: True, force: False, partial: False
728 ancestor: 924404dff337, local: e300d1c794ec+, remote: 49b6d8032493
728 ancestor: 924404dff337, local: e300d1c794ec+, remote: 49b6d8032493
729 preserving a for resolve of b
729 preserving a for resolve of b
730 preserving rev for resolve of rev
730 preserving rev for resolve of rev
731 removing a
731 removing a
732 b: remote moved from a -> m
732 b: remote moved from a -> m
733 updating: b 1/2 files (50.00%)
733 updating: b 1/2 files (50.00%)
734 picked tool 'python ../merge' for b (binary False symlink False)
734 picked tool 'python ../merge' for b (binary False symlink False)
735 merging a and b to b
735 merging a and b to b
736 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
736 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
737 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
737 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
738 merge tool returned: 0
738 merge tool returned: 0
739 rev: versions differ -> m
739 rev: versions differ -> m
740 updating: rev 2/2 files (100.00%)
740 updating: rev 2/2 files (100.00%)
741 picked tool 'python ../merge' for rev (binary False symlink False)
741 picked tool 'python ../merge' for rev (binary False symlink False)
742 merging rev
742 merging rev
743 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
743 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
744 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
744 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
745 merge tool returned: 0
745 merge tool returned: 0
746 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
746 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
747 (branch merge, don't forget to commit)
747 (branch merge, don't forget to commit)
748 --------------
748 --------------
749 M b
749 M b
750 a
750 a
751 --------------
751 --------------
752
752
753 $ tm "um a b" "up a " " " "21 merge a and b to b"
753 $ tm "um a b" "up a " " " "21 merge a and b to b"
754 created new head
754 created new head
755 --------------
755 --------------
756 test L:um a b R:up a W: - 21 merge a and b to b
756 test L:um a b R:up a W: - 21 merge a and b to b
757 --------------
757 --------------
758 searching for copies back to rev 1
758 searching for copies back to rev 1
759 unmatched files in local:
759 unmatched files in local:
760 b
760 b
761 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
761 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
762 src: 'a' -> dst: 'b' *
762 src: 'a' -> dst: 'b' *
763 checking for directory renames
763 checking for directory renames
764 resolving manifests
764 resolving manifests
765 branchmerge: True, force: False, partial: False
765 branchmerge: True, force: False, partial: False
766 ancestor: 924404dff337, local: 62e7bf090eba+, remote: f4db7e329e71
766 ancestor: 924404dff337, local: 62e7bf090eba+, remote: f4db7e329e71
767 preserving b for resolve of b
767 preserving b for resolve of b
768 preserving rev for resolve of rev
768 preserving rev for resolve of rev
769 b: local copied/moved from a -> m
769 b: local copied/moved from a -> m
770 updating: b 1/2 files (50.00%)
770 updating: b 1/2 files (50.00%)
771 picked tool 'python ../merge' for b (binary False symlink False)
771 picked tool 'python ../merge' for b (binary False symlink False)
772 merging b and a to b
772 merging b and a to b
773 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
773 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
774 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
774 launching merge tool: python ../merge *$TESTTMP/t/t/b* * * (glob)
775 merge tool returned: 0
775 merge tool returned: 0
776 rev: versions differ -> m
776 rev: versions differ -> m
777 updating: rev 2/2 files (100.00%)
777 updating: rev 2/2 files (100.00%)
778 picked tool 'python ../merge' for rev (binary False symlink False)
778 picked tool 'python ../merge' for rev (binary False symlink False)
779 merging rev
779 merging rev
780 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
780 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
781 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
781 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
782 merge tool returned: 0
782 merge tool returned: 0
783 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
783 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
784 (branch merge, don't forget to commit)
784 (branch merge, don't forget to commit)
785 --------------
785 --------------
786 M b
786 M b
787 a
787 a
788 --------------
788 --------------
789
789
790
790
791 m "nm a b" "um x a" " " "22 get a, keep b"
791 m "nm a b" "um x a" " " "22 get a, keep b"
792
792
793 $ tm "nm a b" "up a c" " " "23 get c, keep b"
793 $ tm "nm a b" "up a c" " " "23 get c, keep b"
794 created new head
794 created new head
795 --------------
795 --------------
796 test L:nm a b R:up a c W: - 23 get c, keep b
796 test L:nm a b R:up a c W: - 23 get c, keep b
797 --------------
797 --------------
798 searching for copies back to rev 1
798 searching for copies back to rev 1
799 unmatched files in local:
799 unmatched files in local:
800 b
800 b
801 unmatched files in other:
801 unmatched files in other:
802 c
802 c
803 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
803 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
804 src: 'a' -> dst: 'b' *
804 src: 'a' -> dst: 'b' *
805 checking for directory renames
805 checking for directory renames
806 resolving manifests
806 resolving manifests
807 branchmerge: True, force: False, partial: False
807 branchmerge: True, force: False, partial: False
808 ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f
808 ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f
809 preserving b for resolve of b
809 preserving b for resolve of b
810 preserving rev for resolve of rev
810 preserving rev for resolve of rev
811 c: remote created -> g
811 c: remote created -> g
812 getting c
812 getting c
813 updating: c 1/3 files (33.33%)
813 updating: c 1/3 files (33.33%)
814 b: local copied/moved from a -> m
814 b: local copied/moved from a -> m
815 updating: b 2/3 files (66.67%)
815 updating: b 2/3 files (66.67%)
816 picked tool 'python ../merge' for b (binary False symlink False)
816 picked tool 'python ../merge' for b (binary False symlink False)
817 merging b and a to b
817 merging b and a to b
818 my b@02963e448370+ other a@2b958612230f ancestor a@924404dff337
818 my b@02963e448370+ other a@2b958612230f ancestor a@924404dff337
819 premerge successful
819 premerge successful
820 rev: versions differ -> m
820 rev: versions differ -> m
821 updating: rev 3/3 files (100.00%)
821 updating: rev 3/3 files (100.00%)
822 picked tool 'python ../merge' for rev (binary False symlink False)
822 picked tool 'python ../merge' for rev (binary False symlink False)
823 merging rev
823 merging rev
824 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
824 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
825 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
825 launching merge tool: python ../merge *$TESTTMP/t/t/rev* * * (glob)
826 merge tool returned: 0
826 merge tool returned: 0
827 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
827 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
828 (branch merge, don't forget to commit)
828 (branch merge, don't forget to commit)
829 --------------
829 --------------
830 M b
830 M b
831 a
831 a
832 M c
832 M c
833 --------------
833 --------------
834
834
835
835
836 $ cd ..
836 $ cd ..
837
837
838
838
839 Systematic and terse testing of merge merges and ancestor calculation:
839 Systematic and terse testing of merge merges and ancestor calculation:
840
840
841 Expected result:
841 Expected result:
842
842
843 \ a m1 m2 dst
843 \ a m1 m2 dst
844 0 - f f f "versions differ"
844 0 - f f f "versions differ"
845 1 f g g g "versions differ"
845 1 f g g g "versions differ"
846 2 f f f f "versions differ"
846 2 f f f f "versions differ"
847 3 f f g f+g "remote copied to " + f
847 3 f f g f+g "remote copied to " + f
848 4 f f g g "remote moved to " + f
848 4 f f g g "remote moved to " + f
849 5 f g f f+g "local copied to " + f2
849 5 f g f f+g "local copied to " + f2
850 6 f g f g "local moved to " + f2
850 6 f g f g "local moved to " + f2
851 7 - (f) f f "remote differs from untracked local"
851 7 - (f) f f "remote differs from untracked local"
852 8 f (f) f f "remote differs from untracked local"
852 8 f (f) f f "remote differs from untracked local"
853
853
854 $ hg init ancestortest
854 $ hg init ancestortest
855 $ cd ancestortest
855 $ cd ancestortest
856 $ for x in 1 2 3 4 5 6 8; do mkdir $x; echo a > $x/f; done
856 $ for x in 1 2 3 4 5 6 8; do mkdir $x; echo a > $x/f; done
857 $ hg ci -Aqm "a"
857 $ hg ci -Aqm "a"
858 $ mkdir 0
858 $ mkdir 0
859 $ touch 0/f
859 $ touch 0/f
860 $ hg mv 1/f 1/g
860 $ hg mv 1/f 1/g
861 $ hg cp 5/f 5/g
861 $ hg cp 5/f 5/g
862 $ hg mv 6/f 6/g
862 $ hg mv 6/f 6/g
863 $ hg rm 8/f
863 $ hg rm 8/f
864 $ for x in */*; do echo m1 > $x; done
864 $ for x in */*; do echo m1 > $x; done
865 $ hg ci -Aqm "m1"
865 $ hg ci -Aqm "m1"
866 $ hg up -qr0
866 $ hg up -qr0
867 $ mkdir 0 7
867 $ mkdir 0 7
868 $ touch 0/f 7/f
868 $ touch 0/f 7/f
869 $ hg mv 1/f 1/g
869 $ hg mv 1/f 1/g
870 $ hg cp 3/f 3/g
870 $ hg cp 3/f 3/g
871 $ hg mv 4/f 4/g
871 $ hg mv 4/f 4/g
872 $ for x in */*; do echo m2 > $x; done
872 $ for x in */*; do echo m2 > $x; done
873 $ hg ci -Aqm "m2"
873 $ hg ci -Aqm "m2"
874 $ hg up -qr1
874 $ hg up -qr1
875 $ mkdir 7 8
875 $ mkdir 7 8
876 $ echo m > 7/f
876 $ echo m > 7/f
877 $ echo m > 8/f
877 $ echo m > 8/f
878 $ hg merge -f --tool internal:dump -v --debug -r2 | sed '/^updating:/,$d' 2> /dev/null
878 $ hg merge -f --tool internal:dump -v --debug -r2 | sed '/^updating:/,$d' 2> /dev/null
879 searching for copies back to rev 1
879 searching for copies back to rev 1
880 unmatched files in local:
880 unmatched files in local:
881 5/g
881 5/g
882 6/g
882 6/g
883 unmatched files in other:
883 unmatched files in other:
884 3/g
884 3/g
885 4/g
885 4/g
886 7/f
886 7/f
887 unmatched files new in both:
887 unmatched files new in both:
888 0/f
888 0/f
889 1/g
889 1/g
890 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
890 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
891 src: '3/f' -> dst: '3/g' *
891 src: '3/f' -> dst: '3/g' *
892 src: '4/f' -> dst: '4/g' *
892 src: '4/f' -> dst: '4/g' *
893 src: '5/f' -> dst: '5/g' *
893 src: '5/f' -> dst: '5/g' *
894 src: '6/f' -> dst: '6/g' *
894 src: '6/f' -> dst: '6/g' *
895 checking for directory renames
895 checking for directory renames
896 resolving manifests
896 resolving manifests
897 branchmerge: True, force: True, partial: False
897 branchmerge: True, force: True, partial: False
898 ancestor: e6cb3cf11019, local: ec44bf929ab5+, remote: c62e34d0b898
898 ancestor: e6cb3cf11019, local: ec44bf929ab5+, remote: c62e34d0b898
899 remote changed 8/f which local deleted
899 remote changed 8/f which local deleted
900 use (c)hanged version or leave (d)eleted? c
900 use (c)hanged version or leave (d)eleted? c
901 preserving 0/f for resolve of 0/f
901 preserving 0/f for resolve of 0/f
902 preserving 1/g for resolve of 1/g
902 preserving 1/g for resolve of 1/g
903 preserving 2/f for resolve of 2/f
903 preserving 2/f for resolve of 2/f
904 preserving 3/f for resolve of 3/f
904 preserving 3/f for resolve of 3/f
905 preserving 3/f for resolve of 3/g
905 preserving 3/f for resolve of 3/g
906 preserving 4/f for resolve of 4/g
906 preserving 4/f for resolve of 4/g
907 preserving 5/f for resolve of 5/f
907 preserving 5/f for resolve of 5/f
908 preserving 5/g for resolve of 5/g
908 preserving 5/g for resolve of 5/g
909 preserving 6/g for resolve of 6/g
909 preserving 6/g for resolve of 6/g
910 preserving 7/f for resolve of 7/f
910 preserving 7/f for resolve of 7/f
911 removing 4/f
911 removing 4/f
912 8/f: prompt recreating -> g
912 8/f: prompt recreating -> g
913 getting 8/f
913 getting 8/f
914 $ hg mani
914 $ hg mani
915 0/f
915 0/f
916 1/g
916 1/g
917 2/f
917 2/f
918 3/f
918 3/f
919 4/f
919 4/f
920 5/f
920 5/f
921 5/g
921 5/g
922 6/g
922 6/g
923 $ for f in */*; do echo $f:; cat $f; done
923 $ for f in */*; do echo $f:; cat $f; done
924 0/f:
924 0/f:
925 m1
925 m1
926 0/f.base:
926 0/f.base:
927 0/f.local:
927 0/f.local:
928 m1
928 m1
929 0/f.orig:
929 0/f.orig:
930 m1
930 m1
931 0/f.other:
931 0/f.other:
932 m2
932 m2
933 1/g:
933 1/g:
934 m1
934 m1
935 1/g.base:
935 1/g.base:
936 a
936 a
937 1/g.local:
937 1/g.local:
938 m1
938 m1
939 1/g.orig:
939 1/g.orig:
940 m1
940 m1
941 1/g.other:
941 1/g.other:
942 m2
942 m2
943 2/f:
943 2/f:
944 m1
944 m1
945 2/f.base:
945 2/f.base:
946 a
946 a
947 2/f.local:
947 2/f.local:
948 m1
948 m1
949 2/f.orig:
949 2/f.orig:
950 m1
950 m1
951 2/f.other:
951 2/f.other:
952 m2
952 m2
953 3/f:
953 3/f:
954 m1
954 m1
955 3/f.base:
955 3/f.base:
956 a
956 a
957 3/f.local:
957 3/f.local:
958 m1
958 m1
959 3/f.orig:
959 3/f.orig:
960 m1
960 m1
961 3/f.other:
961 3/f.other:
962 m2
962 m2
963 3/g:
963 3/g:
964 m1
964 m1
965 3/g.base:
965 3/g.base:
966 a
966 a
967 3/g.local:
967 3/g.local:
968 m1
968 m1
969 3/g.orig:
969 3/g.orig:
970 m1
970 m1
971 3/g.other:
971 3/g.other:
972 m2
972 m2
973 4/g:
973 4/g:
974 m1
974 m1
975 4/g.base:
975 4/g.base:
976 a
976 a
977 4/g.local:
977 4/g.local:
978 m1
978 m1
979 4/g.orig:
979 4/g.orig:
980 m1
980 m1
981 4/g.other:
981 4/g.other:
982 m2
982 m2
983 5/f:
983 5/f:
984 m1
984 m1
985 5/f.base:
985 5/f.base:
986 a
986 a
987 5/f.local:
987 5/f.local:
988 m1
988 m1
989 5/f.orig:
989 5/f.orig:
990 m1
990 m1
991 5/f.other:
991 5/f.other:
992 m2
992 m2
993 5/g:
993 5/g:
994 m1
994 m1
995 5/g.base:
995 5/g.base:
996 a
996 a
997 5/g.local:
997 5/g.local:
998 m1
998 m1
999 5/g.orig:
999 5/g.orig:
1000 m1
1000 m1
1001 5/g.other:
1001 5/g.other:
1002 m2
1002 m2
1003 6/g:
1003 6/g:
1004 m1
1004 m1
1005 6/g.base:
1005 6/g.base:
1006 a
1006 a
1007 6/g.local:
1007 6/g.local:
1008 m1
1008 m1
1009 6/g.orig:
1009 6/g.orig:
1010 m1
1010 m1
1011 6/g.other:
1011 6/g.other:
1012 m2
1012 m2
1013 7/f:
1013 7/f:
1014 m
1014 m
1015 7/f.base:
1015 7/f.base:
1016 7/f.local:
1016 7/f.local:
1017 m
1017 m
1018 7/f.orig:
1018 7/f.orig:
1019 m
1019 m
1020 7/f.other:
1020 7/f.other:
1021 m2
1021 m2
1022 8/f:
1022 8/f:
1023 m2
1023 m2
1024 $ cd ..
1024 $ cd ..
@@ -1,228 +1,228 b''
1 $ HGMERGE=true; export HGMERGE
1 $ HGMERGE=true; export HGMERGE
2
2
3 $ hg init r1
3 $ hg init r1
4 $ cd r1
4 $ cd r1
5 $ echo a > a
5 $ echo a > a
6 $ hg addremove
6 $ hg addremove
7 adding a
7 adding a
8 $ hg commit -m "1"
8 $ hg commit -m "1"
9
9
10 $ hg clone . ../r2
10 $ hg clone . ../r2
11 updating to branch default
11 updating to branch default
12 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
12 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
13 $ cd ../r2
13 $ cd ../r2
14 $ hg up
14 $ hg up
15 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
15 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 $ echo abc > a
16 $ echo abc > a
17 $ hg diff --nodates
17 $ hg diff --nodates
18 diff -r c19d34741b0a a
18 diff -r c19d34741b0a a
19 --- a/a
19 --- a/a
20 +++ b/a
20 +++ b/a
21 @@ -1,1 +1,1 @@
21 @@ -1,1 +1,1 @@
22 -a
22 -a
23 +abc
23 +abc
24
24
25 $ cd ../r1
25 $ cd ../r1
26 $ echo b > b
26 $ echo b > b
27 $ echo a2 > a
27 $ echo a2 > a
28 $ hg addremove
28 $ hg addremove
29 adding b
29 adding b
30 $ hg commit -m "2"
30 $ hg commit -m "2"
31
31
32 $ cd ../r2
32 $ cd ../r2
33 $ hg -q pull ../r1
33 $ hg -q pull ../r1
34 $ hg status
34 $ hg status
35 M a
35 M a
36 $ hg parents
36 $ hg parents
37 changeset: 0:c19d34741b0a
37 changeset: 0:c19d34741b0a
38 user: test
38 user: test
39 date: Thu Jan 01 00:00:00 1970 +0000
39 date: Thu Jan 01 00:00:00 1970 +0000
40 summary: 1
40 summary: 1
41
41
42 $ hg --debug up
42 $ hg --debug up
43 searching for copies back to rev 1
43 searching for copies back to rev 1
44 unmatched files in other:
44 unmatched files in other:
45 b
45 b
46 resolving manifests
46 resolving manifests
47 branchmerge: False, force: False, partial: False
47 branchmerge: False, force: False, partial: False
48 ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
48 ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
49 preserving a for resolve of a
49 preserving a for resolve of a
50 b: remote created -> g
50 b: remote created -> g
51 getting b
51 getting b
52 updating: b 1/2 files (50.00%)
52 updating: b 1/2 files (50.00%)
53 a: versions differ -> m
53 a: versions differ -> m
54 updating: a 2/2 files (100.00%)
54 updating: a 2/2 files (100.00%)
55 picked tool 'true' for a (binary False symlink False)
55 picked tool 'true' for a (binary False symlink False)
56 merging a
56 merging a
57 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
57 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
58 launching merge tool: true $TESTTMP/r2/a * (glob)
58 launching merge tool: true *$TESTTMP/r2/a* * (glob)
59 merge tool returned: 0
59 merge tool returned: 0
60 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
60 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
61 $ hg parents
61 $ hg parents
62 changeset: 1:1e71731e6fbb
62 changeset: 1:1e71731e6fbb
63 tag: tip
63 tag: tip
64 user: test
64 user: test
65 date: Thu Jan 01 00:00:00 1970 +0000
65 date: Thu Jan 01 00:00:00 1970 +0000
66 summary: 2
66 summary: 2
67
67
68 $ hg --debug up 0
68 $ hg --debug up 0
69 resolving manifests
69 resolving manifests
70 branchmerge: False, force: False, partial: False
70 branchmerge: False, force: False, partial: False
71 ancestor: 1e71731e6fbb, local: 1e71731e6fbb+, remote: c19d34741b0a
71 ancestor: 1e71731e6fbb, local: 1e71731e6fbb+, remote: c19d34741b0a
72 preserving a for resolve of a
72 preserving a for resolve of a
73 b: other deleted -> r
73 b: other deleted -> r
74 removing b
74 removing b
75 updating: b 1/2 files (50.00%)
75 updating: b 1/2 files (50.00%)
76 a: versions differ -> m
76 a: versions differ -> m
77 updating: a 2/2 files (100.00%)
77 updating: a 2/2 files (100.00%)
78 picked tool 'true' for a (binary False symlink False)
78 picked tool 'true' for a (binary False symlink False)
79 merging a
79 merging a
80 my a@1e71731e6fbb+ other a@c19d34741b0a ancestor a@1e71731e6fbb
80 my a@1e71731e6fbb+ other a@c19d34741b0a ancestor a@1e71731e6fbb
81 launching merge tool: true $TESTTMP/r2/a * (glob)
81 launching merge tool: true *$TESTTMP/r2/a* * (glob)
82 merge tool returned: 0
82 merge tool returned: 0
83 0 files updated, 1 files merged, 1 files removed, 0 files unresolved
83 0 files updated, 1 files merged, 1 files removed, 0 files unresolved
84 $ hg parents
84 $ hg parents
85 changeset: 0:c19d34741b0a
85 changeset: 0:c19d34741b0a
86 user: test
86 user: test
87 date: Thu Jan 01 00:00:00 1970 +0000
87 date: Thu Jan 01 00:00:00 1970 +0000
88 summary: 1
88 summary: 1
89
89
90 $ hg parents
90 $ hg parents
91 changeset: 0:c19d34741b0a
91 changeset: 0:c19d34741b0a
92 user: test
92 user: test
93 date: Thu Jan 01 00:00:00 1970 +0000
93 date: Thu Jan 01 00:00:00 1970 +0000
94 summary: 1
94 summary: 1
95
95
96 $ hg --debug up
96 $ hg --debug up
97 searching for copies back to rev 1
97 searching for copies back to rev 1
98 unmatched files in other:
98 unmatched files in other:
99 b
99 b
100 resolving manifests
100 resolving manifests
101 branchmerge: False, force: False, partial: False
101 branchmerge: False, force: False, partial: False
102 ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
102 ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
103 preserving a for resolve of a
103 preserving a for resolve of a
104 b: remote created -> g
104 b: remote created -> g
105 getting b
105 getting b
106 updating: b 1/2 files (50.00%)
106 updating: b 1/2 files (50.00%)
107 a: versions differ -> m
107 a: versions differ -> m
108 updating: a 2/2 files (100.00%)
108 updating: a 2/2 files (100.00%)
109 picked tool 'true' for a (binary False symlink False)
109 picked tool 'true' for a (binary False symlink False)
110 merging a
110 merging a
111 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
111 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
112 launching merge tool: true $TESTTMP/r2/a * (glob)
112 launching merge tool: true *$TESTTMP/r2/a* * (glob)
113 merge tool returned: 0
113 merge tool returned: 0
114 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
114 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
115 $ hg parents
115 $ hg parents
116 changeset: 1:1e71731e6fbb
116 changeset: 1:1e71731e6fbb
117 tag: tip
117 tag: tip
118 user: test
118 user: test
119 date: Thu Jan 01 00:00:00 1970 +0000
119 date: Thu Jan 01 00:00:00 1970 +0000
120 summary: 2
120 summary: 2
121
121
122 $ hg -v history
122 $ hg -v history
123 changeset: 1:1e71731e6fbb
123 changeset: 1:1e71731e6fbb
124 tag: tip
124 tag: tip
125 user: test
125 user: test
126 date: Thu Jan 01 00:00:00 1970 +0000
126 date: Thu Jan 01 00:00:00 1970 +0000
127 files: a b
127 files: a b
128 description:
128 description:
129 2
129 2
130
130
131
131
132 changeset: 0:c19d34741b0a
132 changeset: 0:c19d34741b0a
133 user: test
133 user: test
134 date: Thu Jan 01 00:00:00 1970 +0000
134 date: Thu Jan 01 00:00:00 1970 +0000
135 files: a
135 files: a
136 description:
136 description:
137 1
137 1
138
138
139
139
140 $ hg diff --nodates
140 $ hg diff --nodates
141 diff -r 1e71731e6fbb a
141 diff -r 1e71731e6fbb a
142 --- a/a
142 --- a/a
143 +++ b/a
143 +++ b/a
144 @@ -1,1 +1,1 @@
144 @@ -1,1 +1,1 @@
145 -a2
145 -a2
146 +abc
146 +abc
147
147
148
148
149 create a second head
149 create a second head
150
150
151 $ cd ../r1
151 $ cd ../r1
152 $ hg up 0
152 $ hg up 0
153 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
153 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
154 $ echo b2 > b
154 $ echo b2 > b
155 $ echo a3 > a
155 $ echo a3 > a
156 $ hg addremove
156 $ hg addremove
157 adding b
157 adding b
158 $ hg commit -m "3"
158 $ hg commit -m "3"
159 created new head
159 created new head
160
160
161 $ cd ../r2
161 $ cd ../r2
162 $ hg -q pull ../r1
162 $ hg -q pull ../r1
163 $ hg status
163 $ hg status
164 M a
164 M a
165 $ hg parents
165 $ hg parents
166 changeset: 1:1e71731e6fbb
166 changeset: 1:1e71731e6fbb
167 user: test
167 user: test
168 date: Thu Jan 01 00:00:00 1970 +0000
168 date: Thu Jan 01 00:00:00 1970 +0000
169 summary: 2
169 summary: 2
170
170
171 $ hg --debug up
171 $ hg --debug up
172 abort: uncommitted changes
172 abort: uncommitted changes
173 (commit and merge, or update --clean to discard changes)
173 (commit and merge, or update --clean to discard changes)
174 [255]
174 [255]
175
175
176 test conflicting untracked files
176 test conflicting untracked files
177
177
178 $ hg up -qC 0
178 $ hg up -qC 0
179 $ echo untracked > b
179 $ echo untracked > b
180 $ hg st
180 $ hg st
181 ? b
181 ? b
182 $ hg up 1
182 $ hg up 1
183 b: untracked file differs
183 b: untracked file differs
184 abort: untracked files in working directory differ from files in requested revision
184 abort: untracked files in working directory differ from files in requested revision
185 [255]
185 [255]
186 $ rm b
186 $ rm b
187
187
188 test conflicting untracked ignored file
188 test conflicting untracked ignored file
189
189
190 $ hg up -qC 0
190 $ hg up -qC 0
191 $ echo ignored > .hgignore
191 $ echo ignored > .hgignore
192 $ hg add .hgignore
192 $ hg add .hgignore
193 $ hg ci -m 'add .hgignore'
193 $ hg ci -m 'add .hgignore'
194 created new head
194 created new head
195 $ echo ignored > ignored
195 $ echo ignored > ignored
196 $ hg add ignored
196 $ hg add ignored
197 $ hg ci -m 'add ignored file'
197 $ hg ci -m 'add ignored file'
198
198
199 $ hg up -q 'desc("add .hgignore")'
199 $ hg up -q 'desc("add .hgignore")'
200 $ echo untracked > ignored
200 $ echo untracked > ignored
201 $ hg st
201 $ hg st
202 $ hg up 'desc("add ignored file")'
202 $ hg up 'desc("add ignored file")'
203 ignored: untracked file differs
203 ignored: untracked file differs
204 abort: untracked files in working directory differ from files in requested revision
204 abort: untracked files in working directory differ from files in requested revision
205 [255]
205 [255]
206
206
207 test a local add
207 test a local add
208
208
209 $ cd ..
209 $ cd ..
210 $ hg init a
210 $ hg init a
211 $ hg init b
211 $ hg init b
212 $ echo a > a/a
212 $ echo a > a/a
213 $ echo a > b/a
213 $ echo a > b/a
214 $ hg --cwd a commit -A -m a
214 $ hg --cwd a commit -A -m a
215 adding a
215 adding a
216 $ cd b
216 $ cd b
217 $ hg add a
217 $ hg add a
218 $ hg pull -u ../a
218 $ hg pull -u ../a
219 pulling from ../a
219 pulling from ../a
220 requesting all changes
220 requesting all changes
221 adding changesets
221 adding changesets
222 adding manifests
222 adding manifests
223 adding file changes
223 adding file changes
224 added 1 changesets with 1 changes to 1 files
224 added 1 changesets with 1 changes to 1 files
225 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
225 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
226 $ hg st
226 $ hg st
227
227
228 $ cd ..
228 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now