Show More
@@ -0,0 +1,4 b'' | |||
|
1 | #!/bin/sh | |
|
2 | ||
|
3 | hg clone --quiet $TESTDIR/test-path-normalization.hg t | |
|
4 | exec hg st -R t |
|
1 | NO CONTENT: new file 100644, binary diff hidden |
@@ -249,12 +249,12 b' def reposetup(ui, repo):' | |||
|
249 | 249 | key = self._bookmarks[key] |
|
250 | 250 | return super(bookmark_repo, self).lookup(key) |
|
251 | 251 | |
|
252 |
def commit(self, |
|
|
252 | def commitctx(self, ctx, error=False): | |
|
253 | 253 | """Add a revision to the repository and |
|
254 | 254 | move the bookmark""" |
|
255 | 255 | wlock = self.wlock() # do both commit and bookmark with lock held |
|
256 | 256 | try: |
|
257 |
node = super(bookmark_repo, self).commit( |
|
|
257 | node = super(bookmark_repo, self).commitctx(ctx, error) | |
|
258 | 258 | if node is None: |
|
259 | 259 | return None |
|
260 | 260 | parents = self.changelog.parents(node) |
@@ -262,12 +262,13 b' def reposetup(ui, repo):' | |||
|
262 | 262 | parents = (parents[0],) |
|
263 | 263 | marks = parse(self) |
|
264 | 264 | update = False |
|
265 | for mark, n in marks.items(): | |
|
266 | 265 |
|
|
267 |
|
|
|
266 | mark = current(self) | |
|
267 | if mark and marks[mark] in parents: | |
|
268 | 268 |
|
|
269 | 269 |
|
|
270 | 270 |
|
|
271 | for mark, n in marks.items(): | |
|
271 | 272 | if n in parents: |
|
272 | 273 | marks[mark] = node |
|
273 | 274 | update = True |
@@ -288,6 +289,12 b' def reposetup(ui, repo):' | |||
|
288 | 289 | node = self.changelog.tip() |
|
289 | 290 | marks = parse(self) |
|
290 | 291 | update = False |
|
292 | if ui.configbool('bookmarks', 'track.current'): | |
|
293 | mark = current(self) | |
|
294 | if mark and marks[mark] in parents: | |
|
295 | marks[mark] = node | |
|
296 | update = True | |
|
297 | else: | |
|
291 | 298 | for mark, n in marks.items(): |
|
292 | 299 | if n in parents: |
|
293 | 300 | marks[mark] = node |
@@ -59,7 +59,7 b' class dirstate(object):' | |||
|
59 | 59 | def _foldmap(self): |
|
60 | 60 | f = {} |
|
61 | 61 | for name in self._map: |
|
62 |
f[ |
|
|
62 | f[util.realpath(self._join(name))] = name | |
|
63 | 63 | return f |
|
64 | 64 | |
|
65 | 65 | @propertycache |
@@ -340,7 +340,7 b' class dirstate(object):' | |||
|
340 | 340 | self._ui.warn(_("not in dirstate: %s\n") % f) |
|
341 | 341 | |
|
342 | 342 | def _normalize(self, path, knownpath): |
|
343 |
norm_path = |
|
|
343 | norm_path = util.realpath(self._join(path)) | |
|
344 | 344 | fold_path = self._foldmap.get(norm_path, None) |
|
345 | 345 | if fold_path is None: |
|
346 | 346 | if knownpath or not os.path.exists(os.path.join(self._root, path)): |
@@ -138,7 +138,7 b' def share(ui, source, dest=None, update=' | |||
|
138 | 138 | try: |
|
139 | 139 | uprev = r.lookup(test) |
|
140 | 140 | break |
|
141 | except: | |
|
141 | except LookupError: | |
|
142 | 142 | continue |
|
143 | 143 | _update(r, uprev) |
|
144 | 144 |
@@ -36,7 +36,10 b' def _smtp(ui):' | |||
|
36 | 36 | if username and password: |
|
37 | 37 | ui.note(_('(authenticating to mail server as %s)\n') % |
|
38 | 38 | (username)) |
|
39 | try: | |
|
39 | 40 | s.login(username, password) |
|
41 | except smtplib.SMTPException, inst: | |
|
42 | raise util.Abort(inst) | |
|
40 | 43 | |
|
41 | 44 | def send(sender, recipients, msg): |
|
42 | 45 | try: |
@@ -182,6 +182,7 b' def readgitpatch(lr):' | |||
|
182 | 182 | lineno = 0 |
|
183 | 183 | for line in lr: |
|
184 | 184 | lineno += 1 |
|
185 | line = line.rstrip(' \r\n') | |
|
185 | 186 | if line.startswith('diff --git'): |
|
186 | 187 | m = gitre.match(line) |
|
187 | 188 | if m: |
@@ -200,23 +201,23 b' def readgitpatch(lr):' | |||
|
200 | 201 | continue |
|
201 | 202 | if line.startswith('rename from '): |
|
202 | 203 | gp.op = 'RENAME' |
|
203 |
gp.oldpath = line[12:] |
|
|
204 | gp.oldpath = line[12:] | |
|
204 | 205 | elif line.startswith('rename to '): |
|
205 |
gp.path = line[10:] |
|
|
206 | gp.path = line[10:] | |
|
206 | 207 | elif line.startswith('copy from '): |
|
207 | 208 | gp.op = 'COPY' |
|
208 |
gp.oldpath = line[10:] |
|
|
209 | gp.oldpath = line[10:] | |
|
209 | 210 | elif line.startswith('copy to '): |
|
210 |
gp.path = line[8:] |
|
|
211 | gp.path = line[8:] | |
|
211 | 212 | elif line.startswith('deleted file'): |
|
212 | 213 | gp.op = 'DELETE' |
|
213 | 214 | # is the deleted file a symlink? |
|
214 |
gp.setmode(int(line |
|
|
215 | gp.setmode(int(line[-6:], 8)) | |
|
215 | 216 | elif line.startswith('new file mode '): |
|
216 | 217 | gp.op = 'ADD' |
|
217 |
gp.setmode(int(line |
|
|
218 | gp.setmode(int(line[-6:], 8)) | |
|
218 | 219 | elif line.startswith('new mode '): |
|
219 |
gp.setmode(int(line |
|
|
220 | gp.setmode(int(line[-6:], 8)) | |
|
220 | 221 | elif line.startswith('GIT binary patch'): |
|
221 | 222 | dopatch |= GP_BINARY |
|
222 | 223 | gp.binary = True |
@@ -7,7 +7,7 b'' | |||
|
7 | 7 | |
|
8 | 8 | from i18n import _ |
|
9 | 9 | import osutil |
|
10 | import os, sys, errno, stat, getpass, pwd, grp | |
|
10 | import os, sys, errno, stat, getpass, pwd, grp, fcntl | |
|
11 | 11 | |
|
12 | 12 | posixfile = open |
|
13 | 13 | nulldev = '/dev/null' |
@@ -104,6 +104,44 b' def pconvert(path):' | |||
|
104 | 104 | def localpath(path): |
|
105 | 105 | return path |
|
106 | 106 | |
|
107 | if sys.platform == 'darwin': | |
|
108 | def realpath(path): | |
|
109 | ''' | |
|
110 | Returns the true, canonical file system path equivalent to the given | |
|
111 | path. | |
|
112 | ||
|
113 | Equivalent means, in this case, resulting in the same, unique | |
|
114 | file system link to the path. Every file system entry, whether a file, | |
|
115 | directory, hard link or symbolic link or special, will have a single | |
|
116 | path preferred by the system, but may allow multiple, differing path | |
|
117 | lookups to point to it. | |
|
118 | ||
|
119 | Most regular UNIX file systems only allow a file system entry to be | |
|
120 | looked up by its distinct path. Obviously, this does not apply to case | |
|
121 | insensitive file systems, whether case preserving or not. The most | |
|
122 | complex issue to deal with is file systems transparently reencoding the | |
|
123 | path, such as the non-standard Unicode normalisation required for HFS+ | |
|
124 | and HFSX. | |
|
125 | ''' | |
|
126 | # Constants copied from /usr/include/sys/fcntl.h | |
|
127 | F_GETPATH = 50 | |
|
128 | O_SYMLINK = 0x200000 | |
|
129 | ||
|
130 | try: | |
|
131 | fd = os.open(path, O_SYMLINK) | |
|
132 | except OSError, err: | |
|
133 | if err.errno is errno.ENOENT: | |
|
134 | return path | |
|
135 | raise | |
|
136 | ||
|
137 | try: | |
|
138 | return fcntl.fcntl(fd, F_GETPATH, '\0' * 1024).rstrip('\0') | |
|
139 | finally: | |
|
140 | os.close(fd) | |
|
141 | else: | |
|
142 | # Fallback to the likely inadequate Python builtin function. | |
|
143 | realpath = os.path.realpath | |
|
144 | ||
|
107 | 145 | def shellquote(s): |
|
108 | 146 | if os.sys.platform == 'OpenVMS': |
|
109 | 147 | return '"%s"' % s |
@@ -126,6 +126,15 b' def localpath(path):' | |||
|
126 | 126 | def normpath(path): |
|
127 | 127 | return pconvert(os.path.normpath(path)) |
|
128 | 128 | |
|
129 | def realpath(path): | |
|
130 | ''' | |
|
131 | Returns the true, canonical file system path equivalent to the given | |
|
132 | path. | |
|
133 | ''' | |
|
134 | # TODO: There may be a more clever way to do this that also handles other, | |
|
135 | # less common file systems. | |
|
136 | return os.path.normpath(os.path.normcase(os.path.realpath(path))) | |
|
137 | ||
|
129 | 138 | def samestat(s1, s2): |
|
130 | 139 | return False |
|
131 | 140 |
General Comments 0
You need to be logged in to leave comments.
Login now