2170 |
2170 |
2171 assert len(getfiledata) == ( |
2171 assert len(getfiledata) == ( |
2172 mresult.len((mergestatemod.ACTION_GET,)) if wantfiledata else 0 |
2172 mresult.len((mergestatemod.ACTION_GET,)) if wantfiledata else 0 |
2173 ) |
2173 ) |
2174 with repo.dirstate.parentchange(): |
2174 with repo.dirstate.parentchange(): |
|
2175 ### Filter Filedata |
|
2176 # |
|
2177 # We gathered "cache" information for the clean file while |
|
2178 # updating them: mtime, size and mode. |
|
2179 # |
|
2180 # At the time this comment is written, they are various issues |
|
2181 # with how we gather the `mode` and `mtime` information (see |
|
2182 # the comment in `batchget`). |
|
2183 # |
|
2184 # We are going to smooth one of this issue here : mtime ambiguity. |
|
2185 # |
|
2186 # i.e. even if the mtime gathered during `batchget` was |
|
2187 # correct[1] a change happening right after it could change the |
|
2188 # content while keeping the same mtime[2]. |
|
2189 # |
|
2190 # When we reach the current code, the "on disk" part of the |
|
2191 # update operation is finished. We still assume that no other |
|
2192 # process raced that "on disk" part, but we want to at least |
|
2193 # prevent later file change to alter the content of the file |
|
2194 # right after the update operation. So quickly that the same |
|
2195 # mtime is record for the operation. |
|
2196 # To prevent such ambiguity to happens, we will only keep the |
|
2197 # "file data" for files with mtime that are stricly in the past, |
|
2198 # i.e. whose mtime is strictly lower than the current time. |
|
2199 # |
|
2200 # This protect us from race conditions from operation that could |
|
2201 # run right after this one, especially other Mercurial |
|
2202 # operation that could be waiting for the wlock to touch files |
|
2203 # content and the dirstate. |
|
2204 # |
|
2205 # In an ideal world, we could only get reliable information in |
|
2206 # `getfiledata` (from `getbatch`), however the current approach |
|
2207 # have been a successful compromise since many years. |
|
2208 # |
|
2209 # At the time this comment is written, not using any "cache" |
|
2210 # file data at all here would not be viable. As it would result is |
|
2211 # a very large amount of work (equivalent to the previous `hg |
|
2212 # update` during the next status after an update). |
|
2213 # |
|
2214 # [1] the current code cannot grantee that the `mtime` and |
|
2215 # `mode` are correct, but the result is "okay in practice". |
|
2216 # (see the comment in `batchget`). # |
|
2217 # |
|
2218 # [2] using nano-second precision can greatly help here because |
|
2219 # it makes the "different write with same mtime" issue |
|
2220 # virtually vanish. However, dirstate v1 cannot store such |
|
2221 # precision and a bunch of python-runtime, operating-system and |
|
2222 # filesystem does not provide use with such precision, so we |
|
2223 # have to operate as if it wasn't available. |
|
2224 if getfiledata: |
|
2225 ambiguous_mtime = {} |
|
2226 now = timestamp.get_fs_now(repo.vfs) |
|
2227 if now is None: |
|
2228 # we can't write to the FS, so we won't actually update |
|
2229 # the dirstate content anyway, no need to put cache |
|
2230 # information. |
|
2231 getfiledata = None |
|
2232 else: |
|
2233 now_sec = now[0] |
|
2234 for f, m in pycompat.iteritems(getfiledata): |
|
2235 if m is not None and m[2][0] >= now_sec: |
|
2236 ambiguous_mtime[f] = (m[0], m[1], None) |
|
2237 for f, m in pycompat.iteritems(ambiguous_mtime): |
|
2238 getfiledata[f] = m |
|
2239 |
2175 repo.setparents(fp1, fp2) |
2240 repo.setparents(fp1, fp2) |
2176 mergestatemod.recordupdates( |
2241 mergestatemod.recordupdates( |
2177 repo, mresult.actionsdict, branchmerge, getfiledata |
2242 repo, mresult.actionsdict, branchmerge, getfiledata |
2178 ) |
2243 ) |
2179 # update completed, clear state |
2244 # update completed, clear state |