changeset 7739:edcb56991afe

merge with mpm
author Dirkjan Ochtman <dirkjan@ochtman.nl>
date Sat, 07 Feb 2009 23:29:12 +0100
parents db366ec8d0a4 (current diff) 9f73bddb9d0b (diff)
children 176d3d681702
files mercurial/commands.py mercurial/patch.py
diffstat 11 files changed, 644 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/mq.py	Sat Feb 07 18:46:13 2009 +0100
+++ b/hgext/mq.py	Sat Feb 07 23:29:12 2009 +0100
@@ -1737,7 +1737,10 @@
     if dest is None:
         dest = hg.defaultdest(source)
     sr = hg.repository(ui, ui.expandpath(source))
-    patchespath = opts['patches'] or patchdir(sr)
+    if opts['patches']:
+        patchespath = ui.expandpath(opts['patches'])
+    else:
+        patchespath = patchdir(sr)
     try:
         pr = hg.repository(ui, patchespath)
     except error.RepoError:
--- a/mercurial/commands.py	Sat Feb 07 18:46:13 2009 +0100
+++ b/mercurial/commands.py	Sat Feb 07 23:29:12 2009 +0100
@@ -645,6 +645,9 @@
     elif ui.verbose:
         ui.write(_('committed changeset %d:%s\n') % (rev,short(node)))
 
+    ms = merge_.mergestate(repo)
+    ms.reset(node)
+
 def copy(ui, repo, *pats, **opts):
     """mark files as copied for the next commit
 
--- a/mercurial/dispatch.py	Sat Feb 07 18:46:13 2009 +0100
+++ b/mercurial/dispatch.py	Sat Feb 07 23:29:12 2009 +0100
@@ -354,6 +354,8 @@
                                       " here (.hg not found)"))
                 raise
         args.insert(0, repo)
+    elif rpath:
+        ui.warn("warning: --repository ignored\n")
 
     d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
 
--- a/mercurial/localrepo.py	Sat Feb 07 18:46:13 2009 +0100
+++ b/mercurial/localrepo.py	Sat Feb 07 23:29:12 2009 +0100
@@ -852,8 +852,6 @@
             user = wctx.user()
             text = wctx.description()
 
-            if branchname == 'default' and extra.get('close'):
-                raise util.Abort(_('closing the default branch is invalid'))
             p1, p2 = [p.node() for p in wctx.parents()]
             c1 = self.changelog.read(p1)
             c2 = self.changelog.read(p2)
--- a/mercurial/patch.py	Sat Feb 07 18:46:13 2009 +0100
+++ b/mercurial/patch.py	Sat Feb 07 23:29:12 2009 +0100
@@ -1137,7 +1137,7 @@
             try:
                 return internalpatch(patchname, ui, strip, cwd, files)
             except NoHunks:
-                patcher = util.find_exe('gpatch') or util.find_exe('patch')
+                patcher = util.find_exe('gpatch') or util.find_exe('patch') or 'patch'
                 ui.debug(_('no valid hunks found; trying with %r instead\n') %
                          patcher)
                 if util.needbinarypatch():
--- a/mercurial/util.py	Sat Feb 07 18:46:13 2009 +0100
+++ b/mercurial/util.py	Sat Feb 07 23:29:12 2009 +0100
@@ -653,7 +653,7 @@
         elif main_is_frozen():
             set_hgexecutable(sys.executable)
         else:
-            set_hgexecutable(find_exe('hg', 'hg'))
+            set_hgexecutable(find_exe('hg') or 'hg')
     return _hgexecutable
 
 def set_hgexecutable(path):
@@ -1270,29 +1270,33 @@
     def isowner(fp, st=None):
         return True
 
-    def find_in_path(name, path, default=None):
-        '''find name in search path. path can be string (will be split
-        with os.pathsep), or iterable thing that returns strings.  if name
-        found, return path to name. else return default. name is looked up
-        using cmd.exe rules, using PATHEXT.'''
-        if isinstance(path, str):
-            path = path.split(os.pathsep)
-
+    def find_exe(command):
+        '''Find executable for command searching like cmd.exe does.
+        If command is a basename then PATH is searched for command.
+        PATH isn't searched if command is an absolute or relative path.  
+        An extension from PATHEXT is found and added if not present.
+        If command isn't found None is returned.'''
         pathext = os.environ.get('PATHEXT', '.COM;.EXE;.BAT;.CMD')
-        pathext = pathext.lower().split(os.pathsep)
-        isexec = os.path.splitext(name)[1].lower() in pathext
+        pathexts = [ext for ext in pathext.lower().split(os.pathsep)]
+        if os.path.splitext(command)[1].lower() in pathexts:
+            pathexts = ['']
+        
+        def findexisting(pathcommand):
+            'Will append extension (if needed) and return existing file'
+            for ext in pathexts:
+                executable = pathcommand + ext
+                if os.path.exists(executable):
+                    return executable
+            return None
 
-        for p in path:
-            p_name = os.path.join(p, name)
-
-            if isexec and os.path.exists(p_name):
-                return p_name
-
-            for ext in pathext:
-                p_name_ext = p_name + ext
-                if os.path.exists(p_name_ext):
-                    return p_name_ext
-        return default
+        if os.sep in command:
+            return findexisting(command)
+            
+        for path in os.environ.get('PATH', '').split(os.pathsep):
+            executable = findexisting(os.path.join(path, command))
+            if executable is not None:
+                return executable
+        return None
 
     def set_signal_handler():
         try:
@@ -1458,33 +1462,32 @@
             st = fstat(fp)
         return st.st_uid == os.getuid()
 
-    def find_in_path(name, path, default=None):
-        '''find name in search path. path can be string (will be split
-        with os.pathsep), or iterable thing that returns strings.  if name
-        found, return path to name. else return default.'''
-        if isinstance(path, str):
-            path = path.split(os.pathsep)
-        for p in path:
-            p_name = os.path.join(p, name)
-            if os.path.exists(p_name):
-                return p_name
-        return default
+    def find_exe(command):
+        '''Find executable for command searching like which does.
+        If command is a basename then PATH is searched for command.
+        PATH isn't searched if command is an absolute or relative path.  
+        If command isn't found None is returned.'''
+        if sys.platform == 'OpenVMS':
+            return command
+        
+        def findexisting(executable):
+            'Will return executable if existing file'
+            if os.path.exists(executable):
+                return executable
+            return None
+
+        if os.sep in command:
+            return findexisting(command)
+            
+        for path in os.environ.get('PATH', '').split(os.pathsep):
+            executable = findexisting(os.path.join(path, command))
+            if executable is not None:
+                return executable
+        return None
 
     def set_signal_handler():
         pass
 
-def find_exe(name, default=None):
-    '''find path of an executable.
-    if name contains a path component, return it as is.  otherwise,
-    use normal executable search path.'''
-
-    if os.sep in name or sys.platform == 'OpenVMS':
-        # don't check the executable bit.  if the file isn't
-        # executable, whoever tries to actually run it will give a
-        # much more useful error message.
-        return name
-    return find_in_path(name, os.environ.get('PATH', ''), default=default)
-
 def mktempcopy(name, emptyok=False, createmode=None):
     """Create a temporary file with the same contents from name
 
--- a/tests/run-tests.py	Sat Feb 07 18:46:13 2009 +0100
+++ b/tests/run-tests.py	Sat Feb 07 23:29:12 2009 +0100
@@ -465,7 +465,8 @@
 os.environ['CDPATH'] = ''
 
 TESTDIR = os.environ["TESTDIR"] = os.getcwd()
-HGTMP = os.environ['HGTMP'] = tempfile.mkdtemp('', 'hgtests.', options.tmpdir)
+HGTMP = os.environ['HGTMP'] = os.path.realpath(tempfile.mkdtemp('', 'hgtests.',
+                                               options.tmpdir))
 DAEMON_PIDS = None
 HGRCPATH = None
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-merge-tools	Sat Feb 07 23:29:12 2009 +0100
@@ -0,0 +1,150 @@
+#!/bin/sh
+
+# test merge-tools configuration - mostly exercising filemerge.py
+
+unset HGMERGE # make sure HGMERGE doesn't interfere with the test
+
+hg init
+
+echo "# revision 0"
+echo "revision 0" > f
+echo "space" >> f
+hg commit -Am "revision 0" -d "1000000 0"
+
+echo "# revision 1"
+echo "revision 1" > f
+echo "space" >> f
+hg commit -Am "revision 1" -d "1000000 0"
+
+hg update 0 > /dev/null
+echo "# revision 2"
+echo "revision 2" > f
+echo "space" >> f
+hg commit -Am "revision 2" -d "1000000 0"
+
+hg update 0 > /dev/null
+echo "# revision 3 - simple to merge"
+echo "revision 3" >> f
+hg commit -Am "revision 3" -d "1000000 0"
+
+
+echo "[merge-tools]" > .hg/hgrc
+echo
+
+beforemerge() {
+  cat .hg/hgrc
+  echo "# hg update -C 1"
+  hg update -C 1 > /dev/null
+}
+
+aftermerge() {
+  echo "# cat f"
+  cat f
+  echo "# hg stat"
+  hg stat
+  rm -f f.orig
+  echo
+}
+
+domerge() {
+  beforemerge
+  echo "# hg merge $*"
+  hg merge $*
+  aftermerge
+}
+
+echo
+echo Tool selection
+echo
+
+echo "# default is internal merge:"
+domerge -r 2
+
+echo "# simplest hgrc using false for merge:"
+echo "false.whatever=" >> .hg/hgrc
+domerge -r 2
+
+echo "# true with higher .priority gets precedence:"
+echo "true.priority=1" >> .hg/hgrc
+domerge -r 2
+
+echo "# unless lowered on command line:"
+domerge -r 2 --config merge-tools.true.priority=-7
+
+echo "# or false set higher on command line:"
+domerge -r 2 --config merge-tools.false.priority=117
+
+echo "# or true.executable not found in PATH:"
+domerge -r 2 --config merge-tools.true.executable=nonexistingmergetool
+
+echo "# or true.executable with bogus path:"
+domerge -r 2 --config merge-tools.true.executable=/bin/nonexistingmergetool
+
+echo "# but true.executable set to cat found in PATH works:"
+echo "true.executable=cat" >> .hg/hgrc
+domerge -r 2
+
+echo "# and true.executable set to cat with path works:"
+domerge -r 2 --config merge-tools.true.executable=/bin/cat
+
+
+echo
+echo Tool selection and merge-patterns
+echo
+
+echo "# merge-patterns specifies new tool tac:"
+domerge -r 2 --config merge-patterns.f=tac
+
+echo "# merge-patterns specifies executable not found in PATH and gets warning:"
+domerge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=nonexistingmergetool
+
+echo "# merge-patterns specifies executable with bogus path and gets warning:"
+domerge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=/bin/nonexistingmergetool
+
+
+echo
+echo Premerge
+echo
+
+echo "# Default is silent simplemerge:"
+domerge -r 3
+
+echo "# .premerge=True is same:"
+domerge -r 3 --config merge-tools.true.premerge=True
+
+echo "# .premerge=False executes merge-tool:"
+domerge -r 3 --config merge-tools.true.premerge=False
+
+
+echo
+echo Tool execution
+echo
+
+echo '# set tools.args explicit to include $base $local $other $output:' # default '$local $base $other'
+beforemerge
+hg merge -r 2 --config merge-tools.true.executable=head --config merge-tools.true.args='$base $local $other $output' \
+  | sed 's,==> .* <==,==> ... <==,g'
+aftermerge
+
+echo '# Merge with "echo mergeresult > $local":'
+beforemerge
+hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > $local'
+aftermerge
+
+echo '# - and $local is the file f:'
+beforemerge
+hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > f'
+aftermerge
+
+echo '# Merge with "echo mergeresult > $output" - the variable is a bit magic:'
+beforemerge
+hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > $output'
+aftermerge
+
+
+echo
+echo Merge post-processing
+echo
+
+echo "# cat is a bad merge-tool and doesn't change:"
+domerge -r 2 --config merge-tools.true.checkchanged=1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-merge-tools.out	Sat Feb 07 23:29:12 2009 +0100
@@ -0,0 +1,399 @@
+# revision 0
+adding f
+# revision 1
+# revision 2
+created new head
+# revision 3 - simple to merge
+created new head
+
+
+Tool selection
+
+# default is internal merge:
+[merge-tools]
+# hg update -C 1
+# hg merge -r 2
+merging f
+warning: conflicts during merge.
+merging f failed!
+0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+use 'hg resolve' to retry unresolved file merges
+# cat f
+<<<<<<< local
+revision 1
+=======
+revision 2
+>>>>>>> other
+space
+# hg stat
+M f
+? f.orig
+
+# simplest hgrc using false for merge:
+[merge-tools]
+false.whatever=
+# hg update -C 1
+# hg merge -r 2
+merging f
+merging f failed!
+0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+use 'hg resolve' to retry unresolved file merges
+# cat f
+revision 1
+space
+# hg stat
+M f
+? f.orig
+
+# true with higher .priority gets precedence:
+[merge-tools]
+false.whatever=
+true.priority=1
+# hg update -C 1
+# hg merge -r 2
+merging f
+0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+# cat f
+revision 1
+space
+# hg stat
+M f
+
+# unless lowered on command line:
+[merge-tools]
+false.whatever=
+true.priority=1
+# hg update -C 1
+# hg merge -r 2 --config merge-tools.true.priority=-7
+merging f
+merging f failed!
+0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+use 'hg resolve' to retry unresolved file merges
+# cat f
+revision 1
+space
+# hg stat
+M f
+? f.orig
+
+# or false set higher on command line:
+[merge-tools]
+false.whatever=
+true.priority=1
+# hg update -C 1
+# hg merge -r 2 --config merge-tools.false.priority=117
+merging f
+merging f failed!
+0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+use 'hg resolve' to retry unresolved file merges
+# cat f
+revision 1
+space
+# hg stat
+M f
+? f.orig
+
+# or true.executable not found in PATH:
+[merge-tools]
+false.whatever=
+true.priority=1
+# hg update -C 1
+# hg merge -r 2 --config merge-tools.true.executable=nonexistingmergetool
+merging f
+merging f failed!
+0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+use 'hg resolve' to retry unresolved file merges
+# cat f
+revision 1
+space
+# hg stat
+M f
+? f.orig
+
+# or true.executable with bogus path:
+[merge-tools]
+false.whatever=
+true.priority=1
+# hg update -C 1
+# hg merge -r 2 --config merge-tools.true.executable=/bin/nonexistingmergetool
+merging f
+merging f failed!
+0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+use 'hg resolve' to retry unresolved file merges
+# cat f
+revision 1
+space
+# hg stat
+M f
+? f.orig
+
+# but true.executable set to cat found in PATH works:
+[merge-tools]
+false.whatever=
+true.priority=1
+true.executable=cat
+# hg update -C 1
+# hg merge -r 2
+revision 1
+space
+revision 0
+space
+revision 2
+space
+merging f
+0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+# cat f
+revision 1
+space
+# hg stat
+M f
+
+# and true.executable set to cat with path works:
+[merge-tools]
+false.whatever=
+true.priority=1
+true.executable=cat
+# hg update -C 1
+# hg merge -r 2 --config merge-tools.true.executable=/bin/cat
+revision 1
+space
+revision 0
+space
+revision 2
+space
+merging f
+0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+# cat f
+revision 1
+space
+# hg stat
+M f
+
+
+Tool selection and merge-patterns
+
+# merge-patterns specifies new tool tac:
+[merge-tools]
+false.whatever=
+true.priority=1
+true.executable=cat
+# hg update -C 1
+# hg merge -r 2 --config merge-patterns.f=tac
+space
+revision 1
+space
+revision 0
+space
+revision 2
+merging f
+0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+# cat f
+revision 1
+space
+# hg stat
+M f
+
+# merge-patterns specifies executable not found in PATH and gets warning:
+[merge-tools]
+false.whatever=
+true.priority=1
+true.executable=cat
+# hg update -C 1
+# hg merge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=nonexistingmergetool
+couldn't find merge tool true specified for f
+merging f
+merging f failed!
+0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+use 'hg resolve' to retry unresolved file merges
+# cat f
+revision 1
+space
+# hg stat
+M f
+? f.orig
+
+# merge-patterns specifies executable with bogus path and gets warning:
+[merge-tools]
+false.whatever=
+true.priority=1
+true.executable=cat
+# hg update -C 1
+# hg merge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=/bin/nonexistingmergetool
+couldn't find merge tool true specified for f
+merging f
+merging f failed!
+0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+use 'hg resolve' to retry unresolved file merges
+# cat f
+revision 1
+space
+# hg stat
+M f
+? f.orig
+
+
+Premerge
+
+# Default is silent simplemerge:
+[merge-tools]
+false.whatever=
+true.priority=1
+true.executable=cat
+# hg update -C 1
+# hg merge -r 3
+merging f
+0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+# cat f
+revision 1
+space
+revision 3
+# hg stat
+M f
+
+# .premerge=True is same:
+[merge-tools]
+false.whatever=
+true.priority=1
+true.executable=cat
+# hg update -C 1
+# hg merge -r 3 --config merge-tools.true.premerge=True
+merging f
+0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+# cat f
+revision 1
+space
+revision 3
+# hg stat
+M f
+
+# .premerge=False executes merge-tool:
+[merge-tools]
+false.whatever=
+true.priority=1
+true.executable=cat
+# hg update -C 1
+# hg merge -r 3 --config merge-tools.true.premerge=False
+revision 1
+space
+revision 0
+space
+revision 0
+space
+revision 3
+merging f
+0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+# cat f
+revision 1
+space
+# hg stat
+M f
+
+
+Tool execution
+
+# set tools.args explicit to include $base $local $other $output:
+[merge-tools]
+false.whatever=
+true.priority=1
+true.executable=cat
+# hg update -C 1
+==> ... <==
+revision 0
+space
+
+==> ... <==
+revision 1
+space
+
+==> ... <==
+revision 2
+space
+
+==> ... <==
+revision 1
+space
+merging f
+0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+# cat f
+revision 1
+space
+# hg stat
+M f
+
+# Merge with "echo mergeresult > $local":
+[merge-tools]
+false.whatever=
+true.priority=1
+true.executable=cat
+# hg update -C 1
+merging f
+0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+# cat f
+mergeresult
+# hg stat
+M f
+
+# - and $local is the file f:
+[merge-tools]
+false.whatever=
+true.priority=1
+true.executable=cat
+# hg update -C 1
+merging f
+0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+# cat f
+mergeresult
+# hg stat
+M f
+
+# Merge with "echo mergeresult > $output" - the variable is a bit magic:
+[merge-tools]
+false.whatever=
+true.priority=1
+true.executable=cat
+# hg update -C 1
+merging f
+0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+# cat f
+mergeresult
+# hg stat
+M f
+
+
+Merge post-processing
+
+# cat is a bad merge-tool and doesn't change:
+[merge-tools]
+false.whatever=
+true.priority=1
+true.executable=cat
+# hg update -C 1
+# hg merge -r 2 --config merge-tools.true.checkchanged=1
+revision 1
+space
+revision 0
+space
+revision 2
+space
+merging f
+merging f failed!
+0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+use 'hg resolve' to retry unresolved file merges
+# cat f
+revision 1
+space
+# hg stat
+M f
+? f.orig
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-resolve	Sat Feb 07 23:29:12 2009 +0100
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# test that a commit clears the merge state.
+
+hg init repo
+cd repo
+
+echo foo > file
+hg commit -Am 'add file' -d '0 0'
+
+echo bar >> file
+hg commit -Am 'append bar' -d '0 0'
+
+echo % create a second head
+hg up -C 0
+echo baz >> file
+hg commit -Am 'append baz' -d '0 0'
+
+echo % failing merge
+HGMERGE=internal:fail hg merge
+
+echo resolved > file
+hg resolve -m file
+hg commit -m 'resolved' -d '0 0'
+
+echo % resolve -l, should be empty
+hg resolve -l
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-resolve.out	Sat Feb 07 23:29:12 2009 +0100
@@ -0,0 +1,8 @@
+adding file
+% create a second head
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+created new head
+% failing merge
+0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+use 'hg resolve' to retry unresolved file merges
+% resolve -l, should be empty