mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 07:17:55 +03:00
only call resetParentCommits() on dirstate write
Summary: This updates the Eden mercurial extension to no longer invoke the Eden `resetParentCommits()` thrift call when `setparents()` is called on the dirstate map. Instead we now defer the call to `resetParentCommits()` until `write()` is called to write the dirstate data to disk. Informing edenfs of the parent change as soon as `setparents()` was called was problematic, as this made edenfs reflect the change before the transaction was committed. Some mercurial commands, notably `hg status` also call `setparents()` on the dirstate but never write this back to disk at all. This is problematic since `hg status` calls `setparents()` without holding any mercurial locks. As a result it may call `setparents()` with the "wrong" parent if another mercurial process is running and is in the middle of a transaction. Reviewed By: bolinfest, chadaustin Differential Revision: D7980375 fbshipit-source-id: 4f5e4391fd291d4ea5fc93bb9d49ed0380fc1721
This commit is contained in:
parent
abe68df349
commit
c8e69b61fb
@ -8,6 +8,7 @@
|
||||
# of patent rights can be found in the PATENTS file in the same directory.
|
||||
|
||||
import os
|
||||
import threading
|
||||
|
||||
from eden.integration.lib import eden_server_inspector, hgrepo
|
||||
|
||||
@ -248,3 +249,50 @@ class RebaseTest(EdenHgTestCase):
|
||||
+ str(num_slow_path)
|
||||
),
|
||||
)
|
||||
|
||||
def test_rebase_with_concurrent_status(self):
|
||||
"""
|
||||
Test using `hg rebase` to rebase a stack while simultaneously running
|
||||
`hg status`
|
||||
"""
|
||||
stop = threading.Event()
|
||||
|
||||
def status_thread():
|
||||
while not stop.is_set():
|
||||
self.hg("status", stdout=None, stderr=None)
|
||||
|
||||
# Spawn several threads to run "hg status" in parallel with the rebase
|
||||
num_threads = 6
|
||||
threads = []
|
||||
for _ in range(num_threads):
|
||||
t = threading.Thread(target=status_thread)
|
||||
threads.append(t)
|
||||
t.start()
|
||||
|
||||
# Run the rebase. Explicitly disable inmemory rebase so that eden
|
||||
# will need to update the working directory state as tehe rebase progresses
|
||||
self.hg(
|
||||
"--debug",
|
||||
"--config",
|
||||
"rebase.experimental.inmemory=False",
|
||||
"rebase",
|
||||
"-s",
|
||||
self._c11,
|
||||
"-d",
|
||||
self._c25,
|
||||
stdout=None,
|
||||
stderr=None,
|
||||
)
|
||||
new_commit = self.hg("log", "-rtip", "-T{node}")
|
||||
|
||||
stop.set()
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
self.assert_status_empty()
|
||||
|
||||
# Verify that the new commit looks correct
|
||||
self.repo.update(new_commit)
|
||||
self.assert_status_empty()
|
||||
self.assert_file_regex("numbers/1/15", "15\n")
|
||||
self.assert_file_regex("numbers/2/25", "25\n")
|
||||
|
Loading…
Reference in New Issue
Block a user