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 |
|
NO CONTENT: new file 100644, binary diff hidden |
@@ -249,12 +249,12 b' def reposetup(ui, repo):' | |||||
249 | key = self._bookmarks[key] |
|
249 | key = self._bookmarks[key] | |
250 | return super(bookmark_repo, self).lookup(key) |
|
250 | return super(bookmark_repo, self).lookup(key) | |
251 |
|
251 | |||
252 |
def commit(self, |
|
252 | def commitctx(self, ctx, error=False): | |
253 | """Add a revision to the repository and |
|
253 | """Add a revision to the repository and | |
254 | move the bookmark""" |
|
254 | move the bookmark""" | |
255 | wlock = self.wlock() # do both commit and bookmark with lock held |
|
255 | wlock = self.wlock() # do both commit and bookmark with lock held | |
256 | try: |
|
256 | try: | |
257 |
node = super(bookmark_repo, self).commit( |
|
257 | node = super(bookmark_repo, self).commitctx(ctx, error) | |
258 | if node is None: |
|
258 | if node is None: | |
259 | return None |
|
259 | return None | |
260 | parents = self.changelog.parents(node) |
|
260 | parents = self.changelog.parents(node) | |
@@ -262,12 +262,13 b' def reposetup(ui, repo):' | |||||
262 | parents = (parents[0],) |
|
262 | parents = (parents[0],) | |
263 | marks = parse(self) |
|
263 | marks = parse(self) | |
264 | update = False |
|
264 | update = False | |
265 | for mark, n in marks.items(): |
|
265 | if ui.configbool('bookmarks', 'track.current'): | |
266 |
|
|
266 | mark = current(self) | |
267 |
|
|
267 | if mark and marks[mark] in parents: | |
268 |
|
|
268 | marks[mark] = node | |
269 |
|
|
269 | update = True | |
270 |
|
|
270 | else: | |
|
271 | for mark, n in marks.items(): | |||
271 | if n in parents: |
|
272 | if n in parents: | |
272 | marks[mark] = node |
|
273 | marks[mark] = node | |
273 | update = True |
|
274 | update = True | |
@@ -288,10 +289,16 b' def reposetup(ui, repo):' | |||||
288 | node = self.changelog.tip() |
|
289 | node = self.changelog.tip() | |
289 | marks = parse(self) |
|
290 | marks = parse(self) | |
290 | update = False |
|
291 | update = False | |
291 | for mark, n in marks.items(): |
|
292 | if ui.configbool('bookmarks', 'track.current'): | |
292 |
|
|
293 | mark = current(self) | |
|
294 | if mark and marks[mark] in parents: | |||
293 | marks[mark] = node |
|
295 | marks[mark] = node | |
294 | update = True |
|
296 | update = True | |
|
297 | else: | |||
|
298 | for mark, n in marks.items(): | |||
|
299 | if n in parents: | |||
|
300 | marks[mark] = node | |||
|
301 | update = True | |||
295 | if update: |
|
302 | if update: | |
296 | write(self, marks) |
|
303 | write(self, marks) | |
297 | return result |
|
304 | return result |
@@ -59,7 +59,7 b' class dirstate(object):' | |||||
59 | def _foldmap(self): |
|
59 | def _foldmap(self): | |
60 | f = {} |
|
60 | f = {} | |
61 | for name in self._map: |
|
61 | for name in self._map: | |
62 |
f[ |
|
62 | f[util.realpath(self._join(name))] = name | |
63 | return f |
|
63 | return f | |
64 |
|
64 | |||
65 | @propertycache |
|
65 | @propertycache | |
@@ -340,7 +340,7 b' class dirstate(object):' | |||||
340 | self._ui.warn(_("not in dirstate: %s\n") % f) |
|
340 | self._ui.warn(_("not in dirstate: %s\n") % f) | |
341 |
|
341 | |||
342 | def _normalize(self, path, knownpath): |
|
342 | def _normalize(self, path, knownpath): | |
343 |
norm_path = |
|
343 | norm_path = util.realpath(self._join(path)) | |
344 | fold_path = self._foldmap.get(norm_path, None) |
|
344 | fold_path = self._foldmap.get(norm_path, None) | |
345 | if fold_path is None: |
|
345 | if fold_path is None: | |
346 | if knownpath or not os.path.exists(os.path.join(self._root, path)): |
|
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 | try: |
|
138 | try: | |
139 | uprev = r.lookup(test) |
|
139 | uprev = r.lookup(test) | |
140 | break |
|
140 | break | |
141 | except: |
|
141 | except LookupError: | |
142 | continue |
|
142 | continue | |
143 | _update(r, uprev) |
|
143 | _update(r, uprev) | |
144 |
|
144 |
@@ -36,7 +36,10 b' def _smtp(ui):' | |||||
36 | if username and password: |
|
36 | if username and password: | |
37 | ui.note(_('(authenticating to mail server as %s)\n') % |
|
37 | ui.note(_('(authenticating to mail server as %s)\n') % | |
38 | (username)) |
|
38 | (username)) | |
39 | s.login(username, password) |
|
39 | try: | |
|
40 | s.login(username, password) | |||
|
41 | except smtplib.SMTPException, inst: | |||
|
42 | raise util.Abort(inst) | |||
40 |
|
43 | |||
41 | def send(sender, recipients, msg): |
|
44 | def send(sender, recipients, msg): | |
42 | try: |
|
45 | try: |
@@ -182,6 +182,7 b' def readgitpatch(lr):' | |||||
182 | lineno = 0 |
|
182 | lineno = 0 | |
183 | for line in lr: |
|
183 | for line in lr: | |
184 | lineno += 1 |
|
184 | lineno += 1 | |
|
185 | line = line.rstrip(' \r\n') | |||
185 | if line.startswith('diff --git'): |
|
186 | if line.startswith('diff --git'): | |
186 | m = gitre.match(line) |
|
187 | m = gitre.match(line) | |
187 | if m: |
|
188 | if m: | |
@@ -200,23 +201,23 b' def readgitpatch(lr):' | |||||
200 | continue |
|
201 | continue | |
201 | if line.startswith('rename from '): |
|
202 | if line.startswith('rename from '): | |
202 | gp.op = 'RENAME' |
|
203 | gp.op = 'RENAME' | |
203 |
gp.oldpath = line[12:] |
|
204 | gp.oldpath = line[12:] | |
204 | elif line.startswith('rename to '): |
|
205 | elif line.startswith('rename to '): | |
205 |
gp.path = line[10:] |
|
206 | gp.path = line[10:] | |
206 | elif line.startswith('copy from '): |
|
207 | elif line.startswith('copy from '): | |
207 | gp.op = 'COPY' |
|
208 | gp.op = 'COPY' | |
208 |
gp.oldpath = line[10:] |
|
209 | gp.oldpath = line[10:] | |
209 | elif line.startswith('copy to '): |
|
210 | elif line.startswith('copy to '): | |
210 |
gp.path = line[8:] |
|
211 | gp.path = line[8:] | |
211 | elif line.startswith('deleted file'): |
|
212 | elif line.startswith('deleted file'): | |
212 | gp.op = 'DELETE' |
|
213 | gp.op = 'DELETE' | |
213 | # is the deleted file a symlink? |
|
214 | # is the deleted file a symlink? | |
214 |
gp.setmode(int(line |
|
215 | gp.setmode(int(line[-6:], 8)) | |
215 | elif line.startswith('new file mode '): |
|
216 | elif line.startswith('new file mode '): | |
216 | gp.op = 'ADD' |
|
217 | gp.op = 'ADD' | |
217 |
gp.setmode(int(line |
|
218 | gp.setmode(int(line[-6:], 8)) | |
218 | elif line.startswith('new mode '): |
|
219 | elif line.startswith('new mode '): | |
219 |
gp.setmode(int(line |
|
220 | gp.setmode(int(line[-6:], 8)) | |
220 | elif line.startswith('GIT binary patch'): |
|
221 | elif line.startswith('GIT binary patch'): | |
221 | dopatch |= GP_BINARY |
|
222 | dopatch |= GP_BINARY | |
222 | gp.binary = True |
|
223 | gp.binary = True |
@@ -7,7 +7,7 b'' | |||||
7 |
|
7 | |||
8 | from i18n import _ |
|
8 | from i18n import _ | |
9 | import osutil |
|
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 | posixfile = open |
|
12 | posixfile = open | |
13 | nulldev = '/dev/null' |
|
13 | nulldev = '/dev/null' | |
@@ -104,6 +104,44 b' def pconvert(path):' | |||||
104 | def localpath(path): |
|
104 | def localpath(path): | |
105 | return path |
|
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 | def shellquote(s): |
|
145 | def shellquote(s): | |
108 | if os.sys.platform == 'OpenVMS': |
|
146 | if os.sys.platform == 'OpenVMS': | |
109 | return '"%s"' % s |
|
147 | return '"%s"' % s |
@@ -126,6 +126,15 b' def localpath(path):' | |||||
126 | def normpath(path): |
|
126 | def normpath(path): | |
127 | return pconvert(os.path.normpath(path)) |
|
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 | def samestat(s1, s2): |
|
138 | def samestat(s1, s2): | |
130 | return False |
|
139 | return False | |
131 |
|
140 |
@@ -39,7 +39,7 b' def has_bzr114():' | |||||
39 | try: |
|
39 | try: | |
40 | import bzrlib |
|
40 | import bzrlib | |
41 | return (bzrlib.__doc__ != None |
|
41 | return (bzrlib.__doc__ != None | |
42 |
and bzrlib.version_info[:2] |
|
42 | and bzrlib.version_info[:2] >= (1, 14)) | |
43 | except ImportError: |
|
43 | except ImportError: | |
44 | return False |
|
44 | return False | |
45 |
|
45 |
General Comments 0
You need to be logged in to leave comments.
Login now