##// END OF EJS Templates
localrepo: sort hg bookmark output...
David Soria Parra -
r13388:a184dbd9 merge default
parent child Browse files
Show More
@@ -0,0 +1,9 b''
1 @echo off
2 rem Double-click this file to (re)build Mercurial for Windows in place.
3 rem Useful for testing and development.
4 cd ..\..
5 del /Q mercurial\*.pyd
6 del /Q mercurial\*.pyc
7 rmdir /Q /S mercurial\locale
8 python setup.py build_py -c -d . build_ext -i build_mo
9 pause
@@ -482,7 +482,7 b' proc makewindow {} {'
482 .bar.file add command -label "Quit" -command doquit
482 .bar.file add command -label "Quit" -command doquit
483 menu .bar.help
483 menu .bar.help
484 .bar add cascade -label "Help" -menu .bar.help
484 .bar add cascade -label "Help" -menu .bar.help
485 .bar.help add command -label "About gitk" -command about
485 .bar.help add command -label "About hgk" -command about
486 . configure -menu .bar
486 . configure -menu .bar
487
487
488 if {![info exists geometry(canv1)]} {
488 if {![info exists geometry(canv1)]} {
@@ -867,9 +867,9 b' proc about {} {'
867 return
867 return
868 }
868 }
869 toplevel $w
869 toplevel $w
870 wm title $w "About gitk"
870 wm title $w "About hgk"
871 message $w.m -text {
871 message $w.m -text {
872 Gitk version 1.2
872 Hgk version 1.2
873
873
874 Copyright � 2005 Paul Mackerras
874 Copyright � 2005 Paul Mackerras
875
875
@@ -16,23 +16,14 b''
16 <File Name="mercurial.parsers.pyd" />
16 <File Name="mercurial.parsers.pyd" />
17 <File Name="pyexpat.pyd" />
17 <File Name="pyexpat.pyd" />
18 <File Name="python26.dll" />
18 <File Name="python26.dll" />
19 <File Name="pythoncom26.dll" />
20 <File Name="pywintypes26.dll" />
21 <File Name="bz2.pyd" />
19 <File Name="bz2.pyd" />
22 <File Name="select.pyd" />
20 <File Name="select.pyd" />
23 <File Name="unicodedata.pyd" />
21 <File Name="unicodedata.pyd" />
24 <File Name="win32api.pyd" />
22 <File Name="_ctypes.pyd" />
25 <File Name="win32com.shell.shell.pyd" />
26 <File Name="win32console.pyd" />
27 <File Name="win32file.pyd" />
28 <File Name="win32gui.pyd" />
29 <File Name="win32pipe.pyd" />
30 <File Name="win32process.pyd" />
31 <File Name="_elementtree.pyd" />
23 <File Name="_elementtree.pyd" />
32 <File Name="_hashlib.pyd" />
24 <File Name="_hashlib.pyd" />
33 <File Name="_socket.pyd" />
25 <File Name="_socket.pyd" />
34 <File Name="_ssl.pyd" />
26 <File Name="_ssl.pyd" />
35 <File Name="_win32sysloader.pyd" />
36 </Component>
27 </Component>
37 </DirectoryRef>
28 </DirectoryRef>
38 </Fragment>
29 </Fragment>
@@ -9,7 +9,7 b''
9 <?define contrib.vim.guid = {BB04903A-652D-4C4F-9590-2BD07A2304F2} ?>
9 <?define contrib.vim.guid = {BB04903A-652D-4C4F-9590-2BD07A2304F2} ?>
10
10
11 <!-- dist.wxs -->
11 <!-- dist.wxs -->
12 <?define dist.guid = {0F63D160-0740-4BAF-BF25-0C6930310F51} ?>
12 <?define dist.guid = {C3B634A4-1B05-4A40-94A9-38EE853CF693} ?>
13
13
14 <!-- doc.wxs -->
14 <!-- doc.wxs -->
15 <?define doc.hg.1.html.guid = {AAAA3FDA-EDC5-4220-B59D-D342722358A2} ?>
15 <?define doc.hg.1.html.guid = {AAAA3FDA-EDC5-4220-B59D-D342722358A2} ?>
@@ -38,7 +38,7 b' def readcurrent(repo):'
38 if os.path.exists(repo.join('bookmarks.current')):
38 if os.path.exists(repo.join('bookmarks.current')):
39 file = repo.opener('bookmarks.current')
39 file = repo.opener('bookmarks.current')
40 # No readline() in posixfile_nt, reading everything is cheap
40 # No readline() in posixfile_nt, reading everything is cheap
41 mark = (file.readlines() or [''])[0]
41 mark = encoding.tolocal((file.readlines() or [''])[0])
42 if mark == '':
42 if mark == '':
43 mark = None
43 mark = None
44 file.close()
44 file.close()
@@ -251,11 +251,6 b' class bundlerepository(localrepo.localre'
251 self.bundle.close()
251 self.bundle.close()
252 if self.tempfile is not None:
252 if self.tempfile is not None:
253 os.unlink(self.tempfile)
253 os.unlink(self.tempfile)
254
255 def __del__(self):
256 del self.bundle
257 if self.tempfile is not None:
258 os.unlink(self.tempfile)
259 if self._tempparent:
254 if self._tempparent:
260 shutil.rmtree(self._tempparent, True)
255 shutil.rmtree(self._tempparent, True)
261
256
@@ -806,6 +806,9 b' class changeset_printer(object):'
806 if branch != 'default':
806 if branch != 'default':
807 self.ui.write(_("branch: %s\n") % branch,
807 self.ui.write(_("branch: %s\n") % branch,
808 label='log.branch')
808 label='log.branch')
809 for bookmark in self.repo.nodebookmarks(changenode):
810 self.ui.write(_("bookmark: %s\n") % bookmark,
811 label='log.bookmark')
809 for tag in self.repo.nodetags(changenode):
812 for tag in self.repo.nodetags(changenode):
810 self.ui.write(_("tag: %s\n") % tag,
813 self.ui.write(_("tag: %s\n") % tag,
811 label='log.tag')
814 label='log.tag')
@@ -530,7 +530,7 b' def bookmark(ui, repo, mark=None, rev=No'
530 if len(marks) == 0:
530 if len(marks) == 0:
531 ui.status(_("no bookmarks set\n"))
531 ui.status(_("no bookmarks set\n"))
532 else:
532 else:
533 for bmark, n in marks.iteritems():
533 for bmark, n in sorted(marks.iteritems()):
534 if ui.configbool('bookmarks', 'track.current'):
534 if ui.configbool('bookmarks', 'track.current'):
535 current = repo._bookmarkcurrent
535 current = repo._bookmarkcurrent
536 if bmark == current and n == cur:
536 if bmark == current and n == cur:
@@ -114,6 +114,8 b' class changectx(object):'
114 return self._changeset[5]
114 return self._changeset[5]
115 def tags(self):
115 def tags(self):
116 return self._repo.nodetags(self._node)
116 return self._repo.nodetags(self._node)
117 def bookmarks(self):
118 return self._repo.nodebookmarks(self._node)
117
119
118 def parents(self):
120 def parents(self):
119 """return contexts for each parent changeset"""
121 """return contexts for each parent changeset"""
@@ -589,8 +589,12 b' def _dispatch(ui, args):'
589 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
589 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
590 ui.log("command", msg + "\n")
590 ui.log("command", msg + "\n")
591 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
591 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
592 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
592 try:
593 cmdpats, cmdoptions)
593 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
594 cmdpats, cmdoptions)
595 finally:
596 if repo:
597 repo.close()
594
598
595 def _runcommand(ui, options, cmd, cmdfunc):
599 def _runcommand(ui, options, cmd, cmdfunc):
596 def checkargs():
600 def checkargs():
@@ -360,7 +360,6 b' class localrepository(repo.repository):'
360 if node != nullid:
360 if node != nullid:
361 tags[encoding.tolocal(name)] = node
361 tags[encoding.tolocal(name)] = node
362 tags['tip'] = self.changelog.tip()
362 tags['tip'] = self.changelog.tip()
363 tags.update(self._bookmarks)
364 tagtypes = dict([(encoding.tolocal(name), value)
363 tagtypes = dict([(encoding.tolocal(name), value)
365 for (name, value) in tagtypes.iteritems()])
364 for (name, value) in tagtypes.iteritems()])
366 return (tags, tagtypes)
365 return (tags, tagtypes)
@@ -399,6 +398,13 b' class localrepository(repo.repository):'
399 tags.sort()
398 tags.sort()
400 return self.nodetagscache.get(node, [])
399 return self.nodetagscache.get(node, [])
401
400
401 def nodebookmarks(self, node):
402 marks = []
403 for bookmark, n in self._bookmarks.iteritems():
404 if n == node:
405 marks.append(bookmark)
406 return sorted(marks)
407
402 def _branchtags(self, partial, lrev):
408 def _branchtags(self, partial, lrev):
403 # TODO: rename this function?
409 # TODO: rename this function?
404 tiprev = len(self) - 1
410 tiprev = len(self) - 1
@@ -13,6 +13,7 b' posixfile = open'
13 nulldev = '/dev/null'
13 nulldev = '/dev/null'
14 normpath = os.path.normpath
14 normpath = os.path.normpath
15 samestat = os.path.samestat
15 samestat = os.path.samestat
16 os_link = os.link
16 unlink = os.unlink
17 unlink = os.unlink
17 rename = os.rename
18 rename = os.rename
18 expandglobs = False
19 expandglobs = False
@@ -24,6 +25,10 b' def openhardlinks():'
24 '''return true if it is safe to hold open file handles to hardlinks'''
25 '''return true if it is safe to hold open file handles to hardlinks'''
25 return True
26 return True
26
27
28 def nlinks(name):
29 '''return number of hardlinks for the given file'''
30 return os.lstat(name).st_nlink
31
27 def rcfiles(path):
32 def rcfiles(path):
28 rcs = [os.path.join(path, 'hgrc')]
33 rcs = [os.path.join(path, 'hgrc')]
29 rcdir = os.path.join(path, 'hgrc.d')
34 rcdir = os.path.join(path, 'hgrc.d')
@@ -35,3 +35,6 b' class repository(object):'
35
35
36 def cancopy(self):
36 def cancopy(self):
37 return self.local()
37 return self.local()
38
39 def close(self):
40 pass
@@ -153,6 +153,10 b' def showbranches(**args):'
153 if branch != 'default':
153 if branch != 'default':
154 return showlist('branch', [branch], plural='branches', **args)
154 return showlist('branch', [branch], plural='branches', **args)
155
155
156 def showbookmarks(**args):
157 bookmarks = args['ctx'].bookmarks()
158 return showlist('bookmark', bookmarks, **args)
159
156 def showchildren(**args):
160 def showchildren(**args):
157 ctx = args['ctx']
161 ctx = args['ctx']
158 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()]
162 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()]
@@ -252,6 +256,7 b' keywords = {'
252 'author': showauthor,
256 'author': showauthor,
253 'branch': showbranch,
257 'branch': showbranch,
254 'branches': showbranches,
258 'branches': showbranches,
259 'bookmarks': showbookmarks,
255 'children': showchildren,
260 'children': showchildren,
256 'date': showdate,
261 'date': showdate,
257 'desc': showdescription,
262 'desc': showdescription,
@@ -1,7 +1,7 b''
1 changeset = 'changeset: {rev}:{node|short}\n{branches}{tags}{parents}user: {author}\ndate: {date|date}\nsummary: {desc|firstline}\n\n'
1 changeset = 'changeset: {rev}:{node|short}\n{branches}{bookmarks}{tags}{parents}user: {author}\ndate: {date|date}\nsummary: {desc|firstline}\n\n'
2 changeset_quiet = '{rev}:{node|short}\n'
2 changeset_quiet = '{rev}:{node|short}\n'
3 changeset_verbose = 'changeset: {rev}:{node|short}\n{branches}{tags}{parents}user: {author}\ndate: {date|date}\n{files}{file_copies_switch}description:\n{desc|strip}\n\n\n'
3 changeset_verbose = 'changeset: {rev}:{node|short}\n{branches}{bookmarks}{tags}{parents}user: {author}\ndate: {date|date}\n{files}{file_copies_switch}description:\n{desc|strip}\n\n\n'
4 changeset_debug = 'changeset: {rev}:{node}\n{branches}{tags}{parents}{manifest}user: {author}\ndate: {date|date}\n{file_mods}{file_adds}{file_dels}{file_copies_switch}{extras}description:\n{desc|strip}\n\n\n'
4 changeset_debug = 'changeset: {rev}:{node}\n{branches}{bookmarks}{tags}{parents}{manifest}user: {author}\ndate: {date|date}\n{file_mods}{file_adds}{file_dels}{file_copies_switch}{extras}description:\n{desc|strip}\n\n\n'
5 start_files = 'files: '
5 start_files = 'files: '
6 file = ' {file}'
6 file = ' {file}'
7 end_files = '\n'
7 end_files = '\n'
@@ -21,4 +21,5 b" parent = 'parent: {rev}:{node|forma"
21 manifest = 'manifest: {rev}:{node}\n'
21 manifest = 'manifest: {rev}:{node}\n'
22 branch = 'branch: {branch}\n'
22 branch = 'branch: {branch}\n'
23 tag = 'tag: {tag}\n'
23 tag = 'tag: {tag}\n'
24 bookmark = 'bookmark: {bookmark}\n'
24 extra = 'extra: {key}={value|stringescape}\n'
25 extra = 'extra: {key}={value|stringescape}\n'
@@ -1,9 +1,9 b''
1 header = '<?xml version="1.0"?>\n<log>\n'
1 header = '<?xml version="1.0"?>\n<log>\n'
2 footer = '</log>\n'
2 footer = '</log>\n'
3
3
4 changeset = '<logentry revision="{rev}" node="{node}">\n{branches}{tags}{parents}<author email="{author|email|xmlescape}">{author|person|xmlescape}</author>\n<date>{date|rfc3339date}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n</logentry>\n'
4 changeset = '<logentry revision="{rev}" node="{node}">\n{branches}{bookmarks}{tags}{parents}<author email="{author|email|xmlescape}">{author|person|xmlescape}</author>\n<date>{date|rfc3339date}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n</logentry>\n'
5 changeset_verbose = '<logentry revision="{rev}" node="{node}">\n{branches}{tags}{parents}<author email="{author|email|xmlescape}">{author|person|xmlescape}</author>\n<date>{date|rfc3339date}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n<paths>\n{file_adds}{file_dels}{file_mods}</paths>\n{file_copies}</logentry>\n'
5 changeset_verbose = '<logentry revision="{rev}" node="{node}">\n{branches}{bookmarks}{tags}{parents}<author email="{author|email|xmlescape}">{author|person|xmlescape}</author>\n<date>{date|rfc3339date}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n<paths>\n{file_adds}{file_dels}{file_mods}</paths>\n{file_copies}</logentry>\n'
6 changeset_debug = '<logentry revision="{rev}" node="{node}">\n{branches}{tags}{parents}<author email="{author|email|xmlescape}">{author|person|xmlescape}</author>\n<date>{date|rfc3339date}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n<paths>\n{file_adds}{file_dels}{file_mods}</paths>\n{file_copies}{extras}</logentry>\n'
6 changeset_debug = '<logentry revision="{rev}" node="{node}">\n{branches}{bookmarks}{tags}{parents}<author email="{author|email|xmlescape}">{author|person|xmlescape}</author>\n<date>{date|rfc3339date}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n<paths>\n{file_adds}{file_dels}{file_mods}</paths>\n{file_copies}{extras}</logentry>\n'
7
7
8 file_add = '<path action="A">{file_add|xmlescape}</path>\n'
8 file_add = '<path action="A">{file_add|xmlescape}</path>\n'
9 file_mod = '<path action="M">{file_mod|xmlescape}</path>\n'
9 file_mod = '<path action="M">{file_mod|xmlescape}</path>\n'
@@ -16,4 +16,5 b" end_file_copies = '</copies>\\n'"
16 parent = '<parent revision="{rev}" node="{node}" />\n'
16 parent = '<parent revision="{rev}" node="{node}" />\n'
17 branch = '<branch>{branch|xmlescape}</branch>\n'
17 branch = '<branch>{branch|xmlescape}</branch>\n'
18 tag = '<tag>{tag|xmlescape}</tag>\n'
18 tag = '<tag>{tag|xmlescape}</tag>\n'
19 bookmark = '<bookmark>{bookmark|xmlescape}</bookmark>\n'
19 extra = '<extra key="{key|xmlescape}">{value|xmlescape}</extra>\n'
20 extra = '<extra key="{key|xmlescape}">{value|xmlescape}</extra>\n'
@@ -554,16 +554,6 b' class path_auditor(object):'
554 # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
554 # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
555 self.auditeddir.update(prefixes)
555 self.auditeddir.update(prefixes)
556
556
557 def nlinks(pathname):
558 """Return number of hardlinks for the given file."""
559 return os.lstat(pathname).st_nlink
560
561 if hasattr(os, 'link'):
562 os_link = os.link
563 else:
564 def os_link(src, dst):
565 raise OSError(0, _("Hardlinks not supported"))
566
567 def lookup_reg(key, name=None, scope=None):
557 def lookup_reg(key, name=None, scope=None):
568 return None
558 return None
569
559
@@ -5,73 +5,173 b''
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 """Utility functions that use win32 API.
8 import encoding
9 import ctypes, errno, os, struct, subprocess
10
11 _kernel32 = ctypes.windll.kernel32
12
13 _BOOL = ctypes.c_long
14 _WORD = ctypes.c_ushort
15 _DWORD = ctypes.c_ulong
16 _LPCSTR = _LPSTR = ctypes.c_char_p
17 _HANDLE = ctypes.c_void_p
18 _HWND = _HANDLE
19
20 _INVALID_HANDLE_VALUE = -1
21
22 # GetLastError
23 _ERROR_SUCCESS = 0
24 _ERROR_INVALID_PARAMETER = 87
25 _ERROR_INSUFFICIENT_BUFFER = 122
26
27 # WPARAM is defined as UINT_PTR (unsigned type)
28 # LPARAM is defined as LONG_PTR (signed type)
29 if ctypes.sizeof(ctypes.c_long) == ctypes.sizeof(ctypes.c_void_p):
30 _WPARAM = ctypes.c_ulong
31 _LPARAM = ctypes.c_long
32 elif ctypes.sizeof(ctypes.c_longlong) == ctypes.sizeof(ctypes.c_void_p):
33 _WPARAM = ctypes.c_ulonglong
34 _LPARAM = ctypes.c_longlong
35
36 class _FILETIME(ctypes.Structure):
37 _fields_ = [('dwLowDateTime', _DWORD),
38 ('dwHighDateTime', _DWORD)]
39
40 class _BY_HANDLE_FILE_INFORMATION(ctypes.Structure):
41 _fields_ = [('dwFileAttributes', _DWORD),
42 ('ftCreationTime', _FILETIME),
43 ('ftLastAccessTime', _FILETIME),
44 ('ftLastWriteTime', _FILETIME),
45 ('dwVolumeSerialNumber', _DWORD),
46 ('nFileSizeHigh', _DWORD),
47 ('nFileSizeLow', _DWORD),
48 ('nNumberOfLinks', _DWORD),
49 ('nFileIndexHigh', _DWORD),
50 ('nFileIndexLow', _DWORD)]
51
52 # CreateFile
53 _FILE_SHARE_READ = 0x00000001
54 _FILE_SHARE_WRITE = 0x00000002
55 _FILE_SHARE_DELETE = 0x00000004
56
57 _OPEN_EXISTING = 3
58
59 # Process Security and Access Rights
60 _PROCESS_QUERY_INFORMATION = 0x0400
61
62 # GetExitCodeProcess
63 _STILL_ACTIVE = 259
64
65 # registry
66 _HKEY_CURRENT_USER = 0x80000001L
67 _HKEY_LOCAL_MACHINE = 0x80000002L
68 _KEY_READ = 0x20019
69 _REG_SZ = 1
70 _REG_DWORD = 4
9
71
10 Mark Hammond's win32all package allows better functionality on
72 class _STARTUPINFO(ctypes.Structure):
11 Windows. This module overrides definitions in util.py. If not
73 _fields_ = [('cb', _DWORD),
12 available, import of this module will fail, and generic code will be
74 ('lpReserved', _LPSTR),
13 used.
75 ('lpDesktop', _LPSTR),
14 """
76 ('lpTitle', _LPSTR),
77 ('dwX', _DWORD),
78 ('dwY', _DWORD),
79 ('dwXSize', _DWORD),
80 ('dwYSize', _DWORD),
81 ('dwXCountChars', _DWORD),
82 ('dwYCountChars', _DWORD),
83 ('dwFillAttribute', _DWORD),
84 ('dwFlags', _DWORD),
85 ('wShowWindow', _WORD),
86 ('cbReserved2', _WORD),
87 ('lpReserved2', ctypes.c_char_p),
88 ('hStdInput', _HANDLE),
89 ('hStdOutput', _HANDLE),
90 ('hStdError', _HANDLE)]
91
92 class _PROCESS_INFORMATION(ctypes.Structure):
93 _fields_ = [('hProcess', _HANDLE),
94 ('hThread', _HANDLE),
95 ('dwProcessId', _DWORD),
96 ('dwThreadId', _DWORD)]
97
98 _DETACHED_PROCESS = 0x00000008
99 _STARTF_USESHOWWINDOW = 0x00000001
100 _SW_HIDE = 0
15
101
16 import win32api
102 class _COORD(ctypes.Structure):
103 _fields_ = [('X', ctypes.c_short),
104 ('Y', ctypes.c_short)]
105
106 class _SMALL_RECT(ctypes.Structure):
107 _fields_ = [('Left', ctypes.c_short),
108 ('Top', ctypes.c_short),
109 ('Right', ctypes.c_short),
110 ('Bottom', ctypes.c_short)]
111
112 class _CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
113 _fields_ = [('dwSize', _COORD),
114 ('dwCursorPosition', _COORD),
115 ('wAttributes', _WORD),
116 ('srWindow', _SMALL_RECT),
117 ('dwMaximumWindowSize', _COORD)]
17
118
18 import errno, os, sys, pywintypes, win32con, win32file, win32process
119 _STD_ERROR_HANDLE = 0xfffffff4L # (DWORD)-12
19 import winerror, win32gui, win32console
120
20 import osutil, encoding
121 def _raiseoserror(name):
21 from win32com.shell import shell, shellcon
122 err = ctypes.WinError()
123 raise OSError(err.errno, '%s: %s' % (name, err.strerror))
124
125 def _getfileinfo(name):
126 fh = _kernel32.CreateFileA(name, 0,
127 _FILE_SHARE_READ | _FILE_SHARE_WRITE | _FILE_SHARE_DELETE,
128 None, _OPEN_EXISTING, 0, None)
129 if fh == _INVALID_HANDLE_VALUE:
130 _raiseoserror(name)
131 try:
132 fi = _BY_HANDLE_FILE_INFORMATION()
133 if not _kernel32.GetFileInformationByHandle(fh, ctypes.byref(fi)):
134 _raiseoserror(name)
135 return fi
136 finally:
137 _kernel32.CloseHandle(fh)
22
138
23 def os_link(src, dst):
139 def os_link(src, dst):
24 try:
140 if not _kernel32.CreateHardLinkA(dst, src, None):
25 win32file.CreateHardLink(dst, src)
141 _raiseoserror(src)
26 except pywintypes.error:
27 raise OSError(errno.EINVAL, 'target implements hardlinks improperly')
28 except NotImplementedError: # Another fake error win Win98
29 raise OSError(errno.EINVAL, 'Hardlinking not supported')
30
142
31 def _getfileinfo(pathname):
143 def nlinks(name):
32 """Return number of hardlinks for the given file."""
144 '''return number of hardlinks for the given file'''
33 try:
145 return _getfileinfo(name).nNumberOfLinks
34 fh = win32file.CreateFile(pathname,
35 win32file.GENERIC_READ, win32file.FILE_SHARE_READ,
36 None, win32file.OPEN_EXISTING, 0, None)
37 except pywintypes.error:
38 raise OSError(errno.ENOENT, 'The system cannot find the file specified')
39 try:
40 return win32file.GetFileInformationByHandle(fh)
41 finally:
42 fh.Close()
43
44 def nlinks(pathname):
45 """Return number of hardlinks for the given file."""
46 return _getfileinfo(pathname)[7]
47
146
48 def samefile(fpath1, fpath2):
147 def samefile(fpath1, fpath2):
49 """Returns whether fpath1 and fpath2 refer to the same file. This is only
148 '''Returns whether fpath1 and fpath2 refer to the same file. This is only
50 guaranteed to work for files, not directories."""
149 guaranteed to work for files, not directories.'''
51 res1 = _getfileinfo(fpath1)
150 res1 = _getfileinfo(fpath1)
52 res2 = _getfileinfo(fpath2)
151 res2 = _getfileinfo(fpath2)
53 # Index 4 is the volume serial number, and 8 and 9 contain the file ID
152 return (res1.dwVolumeSerialNumber == res2.dwVolumeSerialNumber
54 return res1[4] == res2[4] and res1[8] == res2[8] and res1[9] == res2[9]
153 and res1.nFileIndexHigh == res2.nFileIndexHigh
154 and res1.nFileIndexLow == res2.nFileIndexLow)
55
155
56 def samedevice(fpath1, fpath2):
156 def samedevice(fpath1, fpath2):
57 """Returns whether fpath1 and fpath2 are on the same device. This is only
157 '''Returns whether fpath1 and fpath2 are on the same device. This is only
58 guaranteed to work for files, not directories."""
158 guaranteed to work for files, not directories.'''
59 res1 = _getfileinfo(fpath1)
159 res1 = _getfileinfo(fpath1)
60 res2 = _getfileinfo(fpath2)
160 res2 = _getfileinfo(fpath2)
61 return res1[4] == res2[4]
161 return res1.dwVolumeSerialNumber == res2.dwVolumeSerialNumber
62
162
63 def testpid(pid):
163 def testpid(pid):
64 '''return True if pid is still running or unable to
164 '''return True if pid is still running or unable to
65 determine, False otherwise'''
165 determine, False otherwise'''
66 try:
166 h = _kernel32.OpenProcess(_PROCESS_QUERY_INFORMATION, False, pid)
67 handle = win32api.OpenProcess(
167 if h:
68 win32con.PROCESS_QUERY_INFORMATION, False, pid)
168 try:
69 if handle:
169 status = _DWORD()
70 status = win32process.GetExitCodeProcess(handle)
170 if _kernel32.GetExitCodeProcess(h, ctypes.byref(status)):
71 return status == win32con.STILL_ACTIVE
171 return status.value == _STILL_ACTIVE
72 except pywintypes.error, details:
172 finally:
73 return details[0] != winerror.ERROR_INVALID_PARAMETER
173 _kernel32.CloseHandle(h)
74 return True
174 return _kernel32.GetLastError() != _ERROR_INVALID_PARAMETER
75
175
76 def lookup_reg(key, valname=None, scope=None):
176 def lookup_reg(key, valname=None, scope=None):
77 ''' Look up a key/value name in the Windows registry.
177 ''' Look up a key/value name in the Windows registry.
@@ -82,101 +182,137 b' def lookup_reg(key, valname=None, scope='
82 a sequence of scopes to look up in order. Default (CURRENT_USER,
182 a sequence of scopes to look up in order. Default (CURRENT_USER,
83 LOCAL_MACHINE).
183 LOCAL_MACHINE).
84 '''
184 '''
85 try:
185 adv = ctypes.windll.advapi32
86 from _winreg import HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, \
186 byref = ctypes.byref
87 QueryValueEx, OpenKey
88 except ImportError:
89 return None
90
91 if scope is None:
187 if scope is None:
92 scope = (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE)
188 scope = (_HKEY_CURRENT_USER, _HKEY_LOCAL_MACHINE)
93 elif not isinstance(scope, (list, tuple)):
189 elif not isinstance(scope, (list, tuple)):
94 scope = (scope,)
190 scope = (scope,)
95 for s in scope:
191 for s in scope:
192 kh = _HANDLE()
193 res = adv.RegOpenKeyExA(s, key, 0, _KEY_READ, ctypes.byref(kh))
194 if res != _ERROR_SUCCESS:
195 continue
96 try:
196 try:
97 val = QueryValueEx(OpenKey(s, key), valname)[0]
197 size = _DWORD(600)
98 # never let a Unicode string escape into the wild
198 type = _DWORD()
99 return encoding.tolocal(val.encode('UTF-8'))
199 buf = ctypes.create_string_buffer(size.value + 1)
100 except EnvironmentError:
200 res = adv.RegQueryValueExA(kh.value, valname, None,
101 pass
201 byref(type), buf, byref(size))
202 if res != _ERROR_SUCCESS:
203 continue
204 if type.value == _REG_SZ:
205 # never let a Unicode string escape into the wild
206 return encoding.tolocal(buf.value.encode('UTF-8'))
207 elif type.value == _REG_DWORD:
208 fmt = '<L'
209 s = ctypes.string_at(byref(buf), struct.calcsize(fmt))
210 return struct.unpack(fmt, s)[0]
211 finally:
212 adv.RegCloseKey(kh.value)
102
213
103 def system_rcpath_win32():
214 def executable_path():
104 '''return default os-specific hgrc search path'''
215 '''return full path of hg.exe'''
105 filename = win32api.GetModuleFileName(0)
216 size = 600
106 # Use mercurial.ini found in directory with hg.exe
217 buf = ctypes.create_string_buffer(size + 1)
107 progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
218 len = _kernel32.GetModuleFileNameA(None, ctypes.byref(buf), size)
108 if os.path.isfile(progrc):
219 if len == 0:
109 return [progrc]
220 raise ctypes.WinError()
110 # Use hgrc.d found in directory with hg.exe
221 elif len == size:
111 progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d')
222 raise ctypes.WinError(_ERROR_INSUFFICIENT_BUFFER)
112 if os.path.isdir(progrcd):
223 return buf.value
113 rcpath = []
114 for f, kind in osutil.listdir(progrcd):
115 if f.endswith('.rc'):
116 rcpath.append(os.path.join(progrcd, f))
117 return rcpath
118 # else look for a system rcpath in the registry
119 try:
120 value = win32api.RegQueryValue(
121 win32con.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Mercurial')
122 rcpath = []
123 for p in value.split(os.pathsep):
124 if p.lower().endswith('mercurial.ini'):
125 rcpath.append(p)
126 elif os.path.isdir(p):
127 for f, kind in osutil.listdir(p):
128 if f.endswith('.rc'):
129 rcpath.append(os.path.join(p, f))
130 return rcpath
131 except pywintypes.error:
132 return []
133
134 def user_rcpath_win32():
135 '''return os-specific hgrc search path to the user dir'''
136 userdir = os.path.expanduser('~')
137 if sys.getwindowsversion()[3] != 2 and userdir == '~':
138 # We are on win < nt: fetch the APPDATA directory location and use
139 # the parent directory as the user home dir.
140 appdir = shell.SHGetPathFromIDList(
141 shell.SHGetSpecialFolderLocation(0, shellcon.CSIDL_APPDATA))
142 userdir = os.path.dirname(appdir)
143 return [os.path.join(userdir, 'mercurial.ini'),
144 os.path.join(userdir, '.hgrc')]
145
224
146 def getuser():
225 def getuser():
147 '''return name of current user'''
226 '''return name of current user'''
148 return win32api.GetUserName()
227 adv = ctypes.windll.advapi32
228 size = _DWORD(300)
229 buf = ctypes.create_string_buffer(size.value + 1)
230 if not adv.GetUserNameA(ctypes.byref(buf), ctypes.byref(size)):
231 raise ctypes.WinError()
232 return buf.value
149
233
150 def set_signal_handler_win32():
234 _SIGNAL_HANDLER = ctypes.WINFUNCTYPE(_BOOL, _DWORD)
151 """Register a termination handler for console events including
235 _signal_handler = []
236
237 def set_signal_handler():
238 '''Register a termination handler for console events including
152 CTRL+C. python signal handlers do not work well with socket
239 CTRL+C. python signal handlers do not work well with socket
153 operations.
240 operations.
154 """
241 '''
155 def handler(event):
242 def handler(event):
156 win32process.ExitProcess(1)
243 _kernel32.ExitProcess(1)
157 win32api.SetConsoleCtrlHandler(handler)
244
245 if _signal_handler:
246 return # already registered
247 h = _SIGNAL_HANDLER(handler)
248 _signal_handler.append(h) # needed to prevent garbage collection
249 if not _kernel32.SetConsoleCtrlHandler(h, True):
250 raise ctypes.WinError()
251
252 _WNDENUMPROC = ctypes.WINFUNCTYPE(_BOOL, _HWND, _LPARAM)
158
253
159 def hidewindow():
254 def hidewindow():
160 def callback(*args, **kwargs):
255 user32 = ctypes.windll.user32
161 hwnd, pid = args
162 wpid = win32process.GetWindowThreadProcessId(hwnd)[1]
163 if pid == wpid:
164 win32gui.ShowWindow(hwnd, win32con.SW_HIDE)
165
256
166 pid = win32process.GetCurrentProcessId()
257 def callback(hwnd, pid):
167 win32gui.EnumWindows(callback, pid)
258 wpid = _DWORD()
259 user32.GetWindowThreadProcessId(hwnd, ctypes.byref(wpid))
260 if pid == wpid.value:
261 user32.ShowWindow(hwnd, _SW_HIDE)
262 return False # stop enumerating windows
263 return True
264
265 pid = _kernel32.GetCurrentProcessId()
266 user32.EnumWindows(_WNDENUMPROC(callback), pid)
168
267
169 def termwidth():
268 def termwidth():
170 try:
269 # cmd.exe does not handle CR like a unix console, the CR is
171 # Query stderr to avoid problems with redirections
270 # counted in the line length. On 80 columns consoles, if 80
172 screenbuf = win32console.GetStdHandle(win32console.STD_ERROR_HANDLE)
271 # characters are written, the following CR won't apply on the
173 if screenbuf is None:
272 # current line but on the new one. Keep room for it.
174 return 79
273 width = 79
175 try:
274 # Query stderr to avoid problems with redirections
176 window = screenbuf.GetConsoleScreenBufferInfo()['Window']
275 screenbuf = _kernel32.GetStdHandle(
177 width = window.Right - window.Left
276 _STD_ERROR_HANDLE) # don't close the handle returned
178 return width
277 if screenbuf is None or screenbuf == _INVALID_HANDLE_VALUE:
179 finally:
278 return width
180 screenbuf.Detach()
279 csbi = _CONSOLE_SCREEN_BUFFER_INFO()
181 except pywintypes.error:
280 if not _kernel32.GetConsoleScreenBufferInfo(
182 return 79
281 screenbuf, ctypes.byref(csbi)):
282 return width
283 width = csbi.srWindow.Right - csbi.srWindow.Left
284 return width
285
286 def spawndetached(args):
287 # No standard library function really spawns a fully detached
288 # process under win32 because they allocate pipes or other objects
289 # to handle standard streams communications. Passing these objects
290 # to the child process requires handle inheritance to be enabled
291 # which makes really detached processes impossible.
292 si = _STARTUPINFO()
293 si.cb = ctypes.sizeof(_STARTUPINFO)
294 si.dwFlags = _STARTF_USESHOWWINDOW
295 si.wShowWindow = _SW_HIDE
296
297 pi = _PROCESS_INFORMATION()
298
299 env = ''
300 for k in os.environ:
301 env += "%s=%s\0" % (k, os.environ[k])
302 if not env:
303 env = '\0'
304 env += '\0'
305
306 args = subprocess.list2cmdline(args)
307 # Not running the command in shell mode makes python26 hang when
308 # writing to hgweb output socket.
309 comspec = os.environ.get("COMSPEC", "cmd.exe")
310 args = comspec + " /c " + args
311
312 res = _kernel32.CreateProcessA(
313 None, args, None, None, False, _DETACHED_PROCESS,
314 env, os.getcwd(), ctypes.byref(si), ctypes.byref(pi))
315 if not res:
316 raise ctypes.WinError()
317
318 return pi.dwProcessId
@@ -71,22 +71,45 b' def _is_win_9x():'
71 return 'command' in os.environ.get('comspec', '')
71 return 'command' in os.environ.get('comspec', '')
72
72
73 def openhardlinks():
73 def openhardlinks():
74 return not _is_win_9x() and "win32api" in globals()
74 return not _is_win_9x()
75
76 _HKEY_LOCAL_MACHINE = 0x80000002L
75
77
76 def system_rcpath():
78 def system_rcpath():
77 try:
79 '''return default os-specific hgrc search path'''
78 return system_rcpath_win32()
80 rcpath = []
79 except:
81 filename = executable_path()
80 return [r'c:\mercurial\mercurial.ini']
82 # Use mercurial.ini found in directory with hg.exe
83 progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
84 if os.path.isfile(progrc):
85 rcpath.append(progrc)
86 return rcpath
87 # Use hgrc.d found in directory with hg.exe
88 progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d')
89 if os.path.isdir(progrcd):
90 for f, kind in osutil.listdir(progrcd):
91 if f.endswith('.rc'):
92 rcpath.append(os.path.join(progrcd, f))
93 return rcpath
94 # else look for a system rcpath in the registry
95 value = lookup_reg('SOFTWARE\\Mercurial', None, _HKEY_LOCAL_MACHINE)
96 if not isinstance(value, str) or not value:
97 return rcpath
98 value = value.replace('/', os.sep)
99 for p in value.split(os.pathsep):
100 if p.lower().endswith('mercurial.ini'):
101 rcpath.append(p)
102 elif os.path.isdir(p):
103 for f, kind in osutil.listdir(p):
104 if f.endswith('.rc'):
105 rcpath.append(os.path.join(p, f))
106 return rcpath
81
107
82 def user_rcpath():
108 def user_rcpath():
83 '''return os-specific hgrc search path to the user dir'''
109 '''return os-specific hgrc search path to the user dir'''
84 try:
110 home = os.path.expanduser('~')
85 path = user_rcpath_win32()
111 path = [os.path.join(home, 'mercurial.ini'),
86 except:
112 os.path.join(home, '.hgrc')]
87 home = os.path.expanduser('~')
88 path = [os.path.join(home, 'mercurial.ini'),
89 os.path.join(home, '.hgrc')]
90 userprofile = os.environ.get('USERPROFILE')
113 userprofile = os.environ.get('USERPROFILE')
91 if userprofile:
114 if userprofile:
92 path.append(os.path.join(userprofile, 'mercurial.ini'))
115 path.append(os.path.join(userprofile, 'mercurial.ini'))
@@ -106,10 +129,6 b' def sshargs(sshcmd, host, user, port):'
106 args = user and ("%s@%s" % (user, host)) or host
129 args = user and ("%s@%s" % (user, host)) or host
107 return port and ("%s %s %s" % (args, pflag, port)) or args
130 return port and ("%s %s %s" % (args, pflag, port)) or args
108
131
109 def testpid(pid):
110 '''return False if pid dead, True if running or not known'''
111 return True
112
113 def set_flags(f, l, x):
132 def set_flags(f, l, x):
114 pass
133 pass
115
134
@@ -208,12 +227,6 b' def find_exe(command):'
208 return executable
227 return executable
209 return findexisting(os.path.expanduser(os.path.expandvars(command)))
228 return findexisting(os.path.expanduser(os.path.expandvars(command)))
210
229
211 def set_signal_handler():
212 try:
213 set_signal_handler_win32()
214 except NameError:
215 pass
216
217 def statfiles(files):
230 def statfiles(files):
218 '''Stat each file in files and yield stat or None if file does not exist.
231 '''Stat each file in files and yield stat or None if file does not exist.
219 Cluster and cache stat per directory to minimize number of OS stat calls.'''
232 Cluster and cache stat per directory to minimize number of OS stat calls.'''
@@ -241,11 +254,6 b' def statfiles(files):'
241 cache = dircache.setdefault(dir, dmap)
254 cache = dircache.setdefault(dir, dmap)
242 yield cache.get(base, None)
255 yield cache.get(base, None)
243
256
244 def getuser():
245 '''return name of current user'''
246 raise error.Abort(_('user name not available - set USERNAME '
247 'environment variable'))
248
249 def username(uid=None):
257 def username(uid=None):
250 """Return the name of the user with the given uid.
258 """Return the name of the user with the given uid.
251
259
@@ -335,37 +343,6 b' def rename(src, dst):'
335 unlink(dst)
343 unlink(dst)
336 os.rename(src, dst)
344 os.rename(src, dst)
337
345
338 def spawndetached(args):
339 # No standard library function really spawns a fully detached
340 # process under win32 because they allocate pipes or other objects
341 # to handle standard streams communications. Passing these objects
342 # to the child process requires handle inheritance to be enabled
343 # which makes really detached processes impossible.
344 class STARTUPINFO:
345 dwFlags = subprocess.STARTF_USESHOWWINDOW
346 hStdInput = None
347 hStdOutput = None
348 hStdError = None
349 wShowWindow = subprocess.SW_HIDE
350
351 args = subprocess.list2cmdline(args)
352 # Not running the command in shell mode makes python26 hang when
353 # writing to hgweb output socket.
354 comspec = os.environ.get("COMSPEC", "cmd.exe")
355 args = comspec + " /c " + args
356 hp, ht, pid, tid = subprocess.CreateProcess(
357 None, args,
358 # no special security
359 None, None,
360 # Do not inherit handles
361 0,
362 # DETACHED_PROCESS
363 0x00000008,
364 os.environ,
365 os.getcwd(),
366 STARTUPINFO())
367 return pid
368
369 def gethgcmd():
346 def gethgcmd():
370 return [sys.executable] + sys.argv[:1]
347 return [sys.executable] + sys.argv[:1]
371
348
@@ -380,10 +357,6 b' def groupmembers(name):'
380 # Don't support groups on Windows for now
357 # Don't support groups on Windows for now
381 raise KeyError()
358 raise KeyError()
382
359
383 try:
360 from win32 import *
384 # override functions with win32 versions if possible
385 from win32 import *
386 except ImportError:
387 pass
388
361
389 expandglobs = True
362 expandglobs = True
@@ -48,8 +48,8 b' import bookmark by name'
48 no changes found
48 no changes found
49 importing bookmark X
49 importing bookmark X
50 $ hg bookmark
50 $ hg bookmark
51 X 0:4e3505fd9583
51 Y 0:4e3505fd9583
52 Y 0:4e3505fd9583
52 X 0:4e3505fd9583
53
53
54 export bookmark by name
54 export bookmark by name
55
55
@@ -62,10 +62,10 b' export bookmark by name'
62 no changes found
62 no changes found
63 exporting bookmark W
63 exporting bookmark W
64 $ hg -R ../a bookmarks
64 $ hg -R ../a bookmarks
65 Y 0:4e3505fd9583
65 W -1:000000000000
66 X 0:4e3505fd9583
66 X 0:4e3505fd9583
67 Y 0:4e3505fd9583
67 * Z 0:4e3505fd9583
68 * Z 0:4e3505fd9583
68 W -1:000000000000
69
69
70 delete a remote bookmark
70 delete a remote bookmark
71
71
@@ -97,8 +97,8 b' divergent bookmarks'
97 adding f1
97 adding f1
98 $ hg book -f X
98 $ hg book -f X
99 $ hg book
99 $ hg book
100 * X 1:0d2164f0ce0d
100 Y 0:4e3505fd9583
101 Y 0:4e3505fd9583
101 * X 1:0d2164f0ce0d
102 Z 1:0d2164f0ce0d
102 Z 1:0d2164f0ce0d
103
103
104 $ cd ../b
104 $ cd ../b
@@ -109,8 +109,8 b' divergent bookmarks'
109 adding f2
109 adding f2
110 $ hg book -f X
110 $ hg book -f X
111 $ hg book
111 $ hg book
112 * X 1:9b140be10808
112 Y 0:4e3505fd9583
113 Y 0:4e3505fd9583
113 * X 1:9b140be10808
114 foo -1:000000000000
114 foo -1:000000000000
115 foobar -1:000000000000
115 foobar -1:000000000000
116
116
@@ -124,8 +124,8 b' divergent bookmarks'
124 not updating divergent bookmark X
124 not updating divergent bookmark X
125 (run 'hg heads' to see heads, 'hg merge' to merge)
125 (run 'hg heads' to see heads, 'hg merge' to merge)
126 $ hg book
126 $ hg book
127 * X 1:9b140be10808
127 Y 0:4e3505fd9583
128 Y 0:4e3505fd9583
128 * X 1:9b140be10808
129 foo -1:000000000000
129 foo -1:000000000000
130 foobar -1:000000000000
130 foobar -1:000000000000
131 $ hg push -f ../a
131 $ hg push -f ../a
@@ -136,8 +136,8 b' divergent bookmarks'
136 adding file changes
136 adding file changes
137 added 1 changesets with 1 changes to 1 files (+1 heads)
137 added 1 changesets with 1 changes to 1 files (+1 heads)
138 $ hg -R ../a book
138 $ hg -R ../a book
139 * X 1:0d2164f0ce0d
139 Y 0:4e3505fd9583
140 Y 0:4e3505fd9583
140 * X 1:0d2164f0ce0d
141 Z 1:0d2164f0ce0d
141 Z 1:0d2164f0ce0d
142
142
143 hgweb
143 hgweb
@@ -31,8 +31,8 b' initialize repository'
31 bookmark list
31 bookmark list
32
32
33 $ hg bookmark
33 $ hg bookmark
34 one 1:925d80f479bb
34 * two 3:2ae46b1d99a7
35 * two 3:2ae46b1d99a7
35 one 1:925d80f479bb
36
36
37 rebase
37 rebase
38
38
@@ -41,9 +41,9 b' rebase'
41
41
42 $ hg log
42 $ hg log
43 changeset: 3:9163974d1cb5
43 changeset: 3:9163974d1cb5
44 tag: one
44 bookmark: one
45 bookmark: two
45 tag: tip
46 tag: tip
46 tag: two
47 parent: 1:925d80f479bb
47 parent: 1:925d80f479bb
48 parent: 2:db815d6d32e6
48 parent: 2:db815d6d32e6
49 user: test
49 user: test
@@ -36,7 +36,7 b' look up bookmark'
36
36
37 $ hg log -r X
37 $ hg log -r X
38 changeset: 0:f7b1eb17ad24
38 changeset: 0:f7b1eb17ad24
39 tag: X
39 bookmark: X
40 tag: tip
40 tag: tip
41 user: test
41 user: test
42 date: Thu Jan 01 00:00:00 1970 +0000
42 date: Thu Jan 01 00:00:00 1970 +0000
@@ -54,8 +54,8 b' bookmark rev -1 again'
54 list bookmarks
54 list bookmarks
55
55
56 $ hg bookmarks
56 $ hg bookmarks
57 * X 0:f7b1eb17ad24
57 * X2 0:f7b1eb17ad24
58 * X2 0:f7b1eb17ad24
58 * X 0:f7b1eb17ad24
59 Y -1:000000000000
59 Y -1:000000000000
60
60
61 $ echo b > b
61 $ echo b > b
@@ -66,8 +66,8 b' bookmarks revset'
66
66
67 $ hg log -r 'bookmark()'
67 $ hg log -r 'bookmark()'
68 changeset: 1:925d80f479bb
68 changeset: 1:925d80f479bb
69 tag: X
69 bookmark: X
70 tag: X2
70 bookmark: X2
71 tag: tip
71 tag: tip
72 user: test
72 user: test
73 date: Thu Jan 01 00:00:00 1970 +0000
73 date: Thu Jan 01 00:00:00 1970 +0000
@@ -76,8 +76,8 b' bookmarks revset'
76 $ hg log -r 'bookmark(Y)'
76 $ hg log -r 'bookmark(Y)'
77 $ hg log -r 'bookmark(X2)'
77 $ hg log -r 'bookmark(X2)'
78 changeset: 1:925d80f479bb
78 changeset: 1:925d80f479bb
79 tag: X
79 bookmark: X
80 tag: X2
80 bookmark: X2
81 tag: tip
81 tag: tip
82 user: test
82 user: test
83 date: Thu Jan 01 00:00:00 1970 +0000
83 date: Thu Jan 01 00:00:00 1970 +0000
@@ -89,8 +89,8 b' bookmarks revset'
89 bookmarks X and X2 moved to rev 1, Y at rev -1
89 bookmarks X and X2 moved to rev 1, Y at rev -1
90
90
91 $ hg bookmarks
91 $ hg bookmarks
92 * X 1:925d80f479bb
92 * X2 1:925d80f479bb
93 * X2 1:925d80f479bb
93 * X 1:925d80f479bb
94 Y -1:000000000000
94 Y -1:000000000000
95
95
96 bookmark rev 0 again
96 bookmark rev 0 again
@@ -104,10 +104,10 b' bookmark rev 0 again'
104 bookmarks X and X2 moved to rev 2, Y at rev -1, Z at rev 0
104 bookmarks X and X2 moved to rev 2, Y at rev -1, Z at rev 0
105
105
106 $ hg bookmarks
106 $ hg bookmarks
107 * X 2:0316ce92851d
107 * X2 2:0316ce92851d
108 * X2 2:0316ce92851d
108 * X 2:0316ce92851d
109 Y -1:000000000000
109 Z 0:f7b1eb17ad24
110 Z 0:f7b1eb17ad24
110 Y -1:000000000000
111
111
112 rename nonexistent bookmark
112 rename nonexistent bookmark
113
113
@@ -166,10 +166,10 b' look up stripped bookmark name'
166
166
167 $ hg log -r '"x y"'
167 $ hg log -r '"x y"'
168 changeset: 2:0316ce92851d
168 changeset: 2:0316ce92851d
169 tag: X2
169 bookmark: X2
170 tag: Y
170 bookmark: Y
171 bookmark: x y
171 tag: tip
172 tag: tip
172 tag: x y
173 user: test
173 user: test
174 date: Thu Jan 01 00:00:00 1970 +0000
174 date: Thu Jan 01 00:00:00 1970 +0000
175 summary: 2
175 summary: 2
@@ -188,6 +188,13 b' Log -R full.hg in fresh empty'
188 date: Thu Jan 01 00:00:00 1970 +0000
188 date: Thu Jan 01 00:00:00 1970 +0000
189 summary: 0.0
189 summary: 0.0
190
190
191 Make sure bundlerepo doesn't leak tempfiles (issue2491)
192
193 $ ls .hg
194 00changelog.i
195 cache
196 requires
197 store
191
198
192 Pull ../full.hg into empty (with hook)
199 Pull ../full.hg into empty (with hook)
193
200
General Comments 0
You need to be logged in to leave comments. Login now