by
Changes to 3 files · Browse files at 9675010b468e Showing diff from parent 54f3cf74d3ec b0916a4160dd Diff from another changeset...
@@ -356,7 +356,7 @@ store = basestore._open_store(repo)
return store.verify(revs, contents=contents)
-def revert_bfiles(ui, repo):
+def revert_bfiles(ui, repo, file_list=None):
wlock = repo.wlock()
try:
bfdirstate = bfutil.open_bfdirstate(ui, repo)
@@ -368,21 +368,31 @@ at = 0
updated = 0
for bfile in bfiles:
- if not os.path.exists(repo.wjoin(bfutil.standin(bfile))):
- bfdirstate.remove(bfile)
- continue
- if os.path.exists(repo.wjoin(bfutil.standin(os.path.join(bfile + '.orig')))):
- shutil.copyfile(repo.wjoin(bfile), repo.wjoin(bfile + '.orig'))
- at += 1
- expectedhash = repo[None][bfutil.standin(bfile)].data().strip()
- mode = os.stat(repo.wjoin(bfutil.standin(bfile))).st_mode
- if not os.path.exists(repo.wjoin(bfile)) or expectedhash != bfutil.hashfile(repo.wjoin(bfile)):
- path = bfutil.find_file(repo, expectedhash)
- if path is None:
- toget.append((bfile, expectedhash))
- else:
- util.makedirs(os.path.dirname(repo.wjoin(bfile)))
- shutil.copy(path, repo.wjoin(bfile))
+ if file_list == None or bfile in file_list:
+ if not os.path.exists(repo.wjoin(bfutil.standin(bfile))):
+ bfdirstate.remove(bfile)
+ continue
+ if os.path.exists(repo.wjoin(bfutil.standin(os.path.join(bfile + '.orig')))):
+ shutil.copyfile(repo.wjoin(bfile), repo.wjoin(bfile + '.orig'))
+ at += 1
+ expectedhash = repo[None][bfutil.standin(bfile)].data().strip()
+ mode = os.stat(repo.wjoin(bfutil.standin(bfile))).st_mode
+ if not os.path.exists(repo.wjoin(bfile)) or expectedhash != bfutil.hashfile(repo.wjoin(bfile)):
+ path = bfutil.find_file(repo, expectedhash)
+ if path is None:
+ toget.append((bfile, expectedhash))
+ else:
+ util.makedirs(os.path.dirname(repo.wjoin(bfile)))
+ shutil.copy(path, repo.wjoin(bfile))
+ os.chmod(repo.wjoin(bfile), mode)
+ updated += 1
+ if bfutil.standin(bfile) not in repo['.']:
+ bfdirstate.add(bfutil.unixpath(bfile))
+ elif expectedhash == repo['.'][bfutil.standin(bfile)].data().strip():
+ bfdirstate.normal(bfutil.unixpath(bfile))
+ else:
+ bfutil.dirstate_normaldirty(bfdirstate, bfutil.unixpath(bfile))
+ elif os.path.exists(repo.wjoin(bfile)) and mode != os.stat(repo.wjoin(bfile)).st_mode:
os.chmod(repo.wjoin(bfile), mode)
updated += 1
if bfutil.standin(bfile) not in repo['.']:
@@ -391,15 +401,6 @@ bfdirstate.normal(bfutil.unixpath(bfile))
else:
bfutil.dirstate_normaldirty(bfdirstate, bfutil.unixpath(bfile))
- elif os.path.exists(repo.wjoin(bfile)) and mode != os.stat(repo.wjoin(bfile)).st_mode:
- os.chmod(repo.wjoin(bfile), mode)
- updated += 1
- if bfutil.standin(bfile) not in repo['.']:
- bfdirstate.add(bfutil.unixpath(bfile))
- elif expectedhash == repo['.'][bfutil.standin(bfile)].data().strip():
- bfdirstate.normal(bfutil.unixpath(bfile))
- else:
- bfutil.dirstate_normaldirty(bfdirstate, bfutil.unixpath(bfile))
if toget:
store = basestore._open_store(repo)
@@ -420,23 +421,24 @@
removed = 0
for bfile in bfdirstate:
- if not os.path.exists(repo.wjoin(bfutil.standin(bfile))):
- if os.path.exists(repo.wjoin(bfile)):
- os.unlink(repo.wjoin(bfile))
- removed += 1
- if bfutil.standin(bfile) in repo['.']:
- bfdirstate.remove(bfutil.unixpath(bfile))
- else:
- bfdirstate.forget(bfutil.unixpath(bfile))
- else:
- state = repo.dirstate[bfutil.standin(bfile)]
- if state == 'n':
- bfdirstate.normal(bfile)
- elif state == 'r':
- bfdirstate.remove(bfile)
- elif state == 'a':
- bfdirstate.add(bfile)
- elif state == '?':
+ if file_list == None or bfile in file_list:
+ if not os.path.exists(repo.wjoin(bfutil.standin(bfile))):
+ if os.path.exists(repo.wjoin(bfile)):
+ os.unlink(repo.wjoin(bfile))
+ removed += 1
+ if bfutil.standin(bfile) in repo['.']:
+ bfdirstate.remove(bfutil.unixpath(bfile))
+ else:
+ bfdirstate.forget(bfutil.unixpath(bfile))
+ else:
+ state = repo.dirstate[bfutil.standin(bfile)]
+ if state == 'n':
+ bfdirstate.normal(bfile)
+ elif state == 'r':
+ bfdirstate.remove(bfile)
+ elif state == 'a':
+ bfdirstate.add(bfile)
+ elif state == '?':
try:
# Mercurial >= 1.9
bfdirstate.drop(bfile)
|
@@ -782,6 +782,10 @@
return result
+# When the user calls revert, we have to be careful to not revert any changes to other
+# bfiles accidentally. This means we have to keep track of the bfiles that are
+# being reverted so we only pull down the necessary bfiles.
+#
# Standins are only updated (to match the hash of bfiles) before commits.
# Update the standins then run the original revert (changing the matcher to hit standins
# instead of bfiles). Based on the resulting standins update the bfiles. Then return the
@@ -821,7 +825,17 @@ orig_matchfn = m.matchfn
def matchfn(f):
if bfutil.is_standin(f):
- return orig_matchfn(bfutil.split_standin(f)) and (f in ctx0 or f in ctx)
+ # We need to keep track of what bfiles are being matched so we know which
+ # ones to update later (otherwise we revert changes to other bfiles
+ # accidentally). This is repo specific, so duckpunch the repo object to
+ # keep the list of bfiles for us later.
+ if(orig_matchfn(bfutil.split_standin(f)) and (f in repo[None] or f in ctx)):
+ bfiles_list = getattr(repo, "_bfiles_to_update", [])
+ bfiles_list.append(bfutil.split_standin(f))
+ repo._bfiles_to_update = bfiles_list;
+ return True
+ else:
+ return False
return orig_matchfn(f)
m.matchfn = matchfn
return m
@@ -839,10 +853,14 @@ except ImportError:
# Mercurial <= 1.8
cmdutil.match = oldmatch
- bfcommands.revert_bfiles(ui, repo)
+ bfiles_list = getattr(repo, "_bfiles_to_update", [])
+ bfcommands.revert_bfiles(ui, repo, bfiles_list)
+ # Empty out the bfiles list so we start fresh next time
+ repo._bfiles_to_update = []
for bfile in modified:
- if os.path.exists(repo.wjoin(bfutil.standin(bfile))) and bfile in repo['.']:
- bfutil.write_standin(repo, bfutil.standin(bfile), repo['.'][bfile].data().strip(), 'x' in repo['.'][bfile].flags())
+ if bfile in bfiles_list:
+ if os.path.exists(repo.wjoin(bfutil.standin(bfile))) and bfile in repo['.']:
+ bfutil.write_standin(repo, bfutil.standin(bfile), repo['.'][bfile].data().strip(), 'x' in repo['.'][bfile].flags())
finally:
wlock.release()
|
@@ -211,3 +211,34 @@ ? b2.txt.orig
? n2.txt.orig
''')
+# Test that modifying a normal file and a bfile, then reverting the normal file,
+# does not alter the bfile
+os.chdir('..')
+os.mkdir('repo2')
+os.chdir('repo2')
+hgt.hg(['init', '-q'])
+hgt.writefile('n1', 'n1')
+hgt.hg(['add', 'n1'])
+hgt.hg(['commit', '-m', 'added normal file'])
+hgt.writefile('b1', 'b1')
+hgt.hg(['add', '--bf', 'b1'])
+hgt.hg(['commit', '-m', 'added bfile'])
+hgt.writefile('n1', 'n11')
+hgt.writefile('b1', 'b11')
+hgt.hg(['revert', 'n1'])
+hgt.asserttrue(hgt.readfile('b1') == 'b11', 'file chnaged')
+# Test that modifying 2 bfiles and reverting one of the bfiles, does not alter the
+# second bfile
+os.chdir('..')
+os.mkdir('repo3')
+hgt.hg(['init', '-q'])
+hgt.writefile('b1', 'b1')
+hgt.hg(['add', '--bf', 'b1'])
+hgt.hg(['commit', '-m', 'added first bfile'])
+hgt.writefile('b2', 'b2')
+hgt.hg(['add', '--bf', 'b2'])
+hgt.hg(['commit', '-m', 'added second bfile'])
+hgt.writefile('b1', 'b11')
+hgt.writefile('b2', 'b22')
+hgt.hg(['revert', 'b1'])
+hgt.asserttrue(hgt.readfile('b2') == 'b22', 'file chnaged')
|
Loading...