# HG changeset patch # User Matt Mackall # Date 2007-05-03 22:27:21 # Node ID 47371e1c1db4d8e2622346c3faba72ec0383cf52 # Parent 15289406f89c3866e5a1e1ce7d666a7555a23631 # Parent 249e2603324cd53e9bf2910a9ce61af108b77834 Merge with stable diff --git a/contrib/win32/win32-build.txt b/contrib/win32/win32-build.txt --- a/contrib/win32/win32-build.txt +++ b/contrib/win32/win32-build.txt @@ -4,7 +4,7 @@ jury-rigged fashion. It has the following prerequisites, at least as I build it: Python for Windows - http://www.python.org/ftp/python/2.4.1/python-2.4.1.msi + http://www.python.org/ftp/python/2.4.3/python-2.4.3.msi MinGW http://www.mingw.org/ @@ -21,7 +21,7 @@ It has the following prerequisites, at l Inno Setup http://www.jrsoftware.org/isinfo.php - ISTool + ISTool - optional http://www.istool.org/default.aspx/ add_path (you need only add_path.exe in the zip file) @@ -35,13 +35,37 @@ C:\hg\hg-release. In a shell, build a standalone copy of the hg.exe program: - python setup.py build -c mingw32 py2exe -b 1 + python setup.py build -c mingw32 + python setup.py py2exe -b 1 + +Note: the previously suggested combined command of "python setup.py build -c +mingw32 py2exe -b 1" doesn't work correctly anymore as it doesn't include the +extensions in the mercurial subdirectory. -Copy mfc71.dll and add_path.exe into the dist directory that just -got created. +If you want to create a file named setup.cfg with the contents: + +[build] +compiler=mingw32 + +you can skip the first build step. + +Copy mfc71.dll and add_path.exe into the dist directory that just got created. -Run ISTool, and open the C:\hg\hg-release\contrib\win32\mercurial.iss -file. +If you use ISTool, you open the C:\hg\hg-release\contrib\win32\mercurial.iss +file and type Ctrl-F9 to compile the installer file. + +Otherwise you run the Inno Setup compiler. Assuming it's on the path you run: + + iscc contrib\win32\mercurial.iss + +The actual installer will be in the C:\hg\hg-release\Output directory. -In ISTool, type Ctrl-F9 to compile the installer file. The actual -installer will be in the C:\hg\hg-release\Output directory. +To automate the steps above you may want to create a batchfile based on the +following: + + echo [build] > setup.cfg + echo compiler=mingw32 >> setup.cfg + python setup.py py2exe -b 1 + iscc contrib\win32\mercurial.iss + +and run it from the root of the hg repository (c:\hg\hg-release). diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -102,6 +102,27 @@ def findcopies(repo, m1, m2, ma, limit): Find moves and copies between m1 and m2 back to limit linkrev """ + def nonoverlap(d1, d2, d3): + "Return list of elements in d1 not in d2 or d3" + l = [d for d in d1 if d not in d3 and d not in d2] + l.sort() + return l + + def dirname(f): + s = f.rfind("/") + if s == -1: + return "" + return f[:s] + + def dirs(files): + d = {} + for f in files: + f = dirname(f) + while f not in d: + d[f] = True + f = dirname(f) + return d + def findold(fctx): "find files that path was copied from, back to linkrev limit" old = {} @@ -124,33 +145,25 @@ def findcopies(repo, m1, m2, ma, limit): old.sort() return old - def nonoverlap(d1, d2, d3): - "Return list of elements in d1 not in d2 or d3" - l = [d for d in d1 if d not in d3 and d not in d2] - l.sort() - return l + copy = {} + fullcopy = {} def checkcopies(c, man): '''check possible copies for filectx c''' for of in findold(c): - if of not in man: + if of not in man: # original file not in other manifest? continue c2 = ctx(of, man[of]) ca = c.ancestor(c2) - if not ca: # unrelated + if not ca: # unrelated? continue + # named changed on only one side? if ca.path() == c.path() or ca.path() == c2.path(): - fullcopy[c.path()] = of - if c == ca and c2 == ca: # no merge needed, ignore copy + fullcopy[c.path()] = of # remember for dir rename detection + if c == c2: # no merge needed, ignore copy continue copy[c.path()] = of - def dirs(files): - d = {} - for f in files: - d[os.path.dirname(f)] = True - return d - if not repo.ui.configbool("merge", "followcopies", True): return {} @@ -159,8 +172,6 @@ def findcopies(repo, m1, m2, ma, limit): return {} dcopies = repo.dirstate.copies() - copy = {} - fullcopy = {} u1 = nonoverlap(m1, m2, ma) u2 = nonoverlap(m2, m1, ma) ctx = util.cachefunc(lambda f, n: repo.filectx(f, fileid=n[:20])) @@ -179,28 +190,41 @@ def findcopies(repo, m1, m2, ma, limit): invalid = {} dirmove = {} + # examine each file copy for a potential directory move, which is + # when all the files in a directory are moved to a new directory for dst, src in fullcopy.items(): - dsrc, ddst = os.path.dirname(src), os.path.dirname(dst) + dsrc, ddst = dirname(src), dirname(dst) if dsrc in invalid: + # already seen to be uninteresting continue - elif (dsrc in d1 and ddst in d1) or (dsrc in d2 and ddst in d2): + elif dsrc in d1 and ddst in d1: + # directory wasn't entirely moved locally + invalid[dsrc] = True + elif dsrc in d2 and ddst in d2: + # directory wasn't entirely moved remotely invalid[dsrc] = True elif dsrc in dirmove and dirmove[dsrc] != ddst: + # files from the same directory moved to two different places invalid[dsrc] = True - del dirmove[dsrc] else: + # looks good so far dirmove[dsrc + "/"] = ddst + "/" + for i in invalid: + if i in dirmove: + del dirmove[i] + del d1, d2, invalid if not dirmove: return copy - # check unaccounted nonoverlapping files + # check unaccounted nonoverlapping files against directory moves for f in u1 + u2: if f not in fullcopy: for d in dirmove: if f.startswith(d): + # new file added in a directory that was moved, move it copy[f] = dirmove[d] + f[len(d):] break