Git and Hg repository structure fixed

*Common methods moved to AbstractRepositoryManager
*update config method called from HgRepo using separate event queue in HgRepositoryUpdater is case hgrc file changed
*HgConfig doesn't implement HgUpdater interface
*Do not reuse old HgConfig, just create new instance in HgRepository
This commit is contained in:
Nadya Zabrodina
2013-07-05 18:53:01 +04:00
parent 16a5cbaf6a
commit cadce3c07f
10 changed files with 53 additions and 58 deletions
@@ -4,6 +4,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
@@ -25,14 +26,25 @@ public abstract class AbstractRepositoryManager<T extends Repository> extends Ab
private static final Logger LOG = Logger.getInstance(RepositoryManager.class);
@NotNull private final ProjectLevelVcsManager myVcsManager;
@NotNull protected AbstractVcs myVcs;
@NotNull private final AbstractVcs myVcs;
@NotNull private final String myRootDirName;
@NotNull protected final Map<VirtualFile, T> myRepositories = new HashMap<VirtualFile, T>();
@NotNull protected final ReentrantReadWriteLock REPO_LOCK = new ReentrantReadWriteLock();
protected AbstractRepositoryManager(@NotNull Project project, @NotNull ProjectLevelVcsManager vcsManager) {
protected AbstractRepositoryManager(@NotNull Project project,
@NotNull ProjectLevelVcsManager vcsManager, @NotNull AbstractVcs vcs, @NotNull String rootDirName) {
super(project);
myVcsManager = vcsManager;
myVcs = vcs;
myRootDirName = rootDirName;
}
@Override
public void initComponent() {
Disposer.register(myProject, this);
myProject.getMessageBus().connect().subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, this);
}
@Override
@@ -87,7 +99,7 @@ public abstract class AbstractRepositoryManager<T extends Repository> extends Ab
final AbstractVcs vcs = vcsRoot.getVcs();
if (!myVcs.equals(vcs)) {
if (vcs != null) {
LOG.debug(String.format("getRepositoryForFile returned non-(%s) root for file %s", vcs.getDisplayName(), filePath));
LOG.debug(String.format("getRepositoryForFile returned non-(%s) root for file %s", myVcs.getDisplayName(), filePath));
}
return null;
}
@@ -181,7 +193,10 @@ public abstract class AbstractRepositoryManager<T extends Repository> extends Ab
}
}
protected abstract boolean isRootValid(@NotNull VirtualFile root);
private boolean isRootValid(@NotNull VirtualFile root) {
VirtualFile gitDir = root.findChild(myRootDirName);
return gitDir != null && gitDir.exists();
}
@NotNull
protected abstract T createRepository(@NotNull VirtualFile root);
@@ -19,7 +19,6 @@ import com.intellij.dvcs.repo.AbstractRepositoryManager;
import com.intellij.dvcs.repo.RepositoryManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vfs.VirtualFile;
import git4idea.GitPlatformFacade;
@@ -36,26 +35,18 @@ public class GitRepositoryManager extends AbstractRepositoryManager<GitRepositor
public GitRepositoryManager(@NotNull Project project, @NotNull GitPlatformFacade platformFacade,
@NotNull ProjectLevelVcsManager vcsManager) {
super(project, vcsManager);
super(project, vcsManager, platformFacade.getVcs(project), GitUtil.DOT_GIT);
myPlatformFacade = platformFacade;
}
@Override
public void initComponent() {
myVcs = myPlatformFacade.getVcs(myProject);
Disposer.register(myProject, this);
myProject.getMessageBus().connect().subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, this);
super.initComponent();
if (!ApplicationManager.getApplication().isUnitTestMode()) {
GitRootScanner.start(myProject);
}
}
@Override
protected boolean isRootValid(@NotNull VirtualFile root) {
VirtualFile gitDir = root.findChild(GitUtil.DOT_GIT);
return gitDir != null && gitDir.exists();
}
@NotNull
@Override
protected GitRepository createRepository(@NotNull VirtualFile root) {
@@ -65,7 +65,6 @@ public class HgVcs extends AbstractVcs<CommittedChangeList> {
public static final Topic<HgUpdater> BRANCH_TOPIC = new Topic<HgUpdater>("hg4idea.branch", HgUpdater.class);
public static final Topic<HgUpdater> REMOTE_TOPIC = new Topic<HgUpdater>("hg4idea.remote", HgUpdater.class);
public static final Topic<HgUpdater> STATUS_TOPIC = new Topic<HgUpdater>("hg4idea.status", HgUpdater.class);
public static final Topic<HgUpdater> UPDATE_CONFIG_TOPIC = new Topic<HgUpdater>("hg4idea.config", HgUpdater.class);
public static final Topic<HgHideableWidget> INCOMING_OUTGOING_CHECK_TOPIC =
new Topic<HgHideableWidget>("hg4idea.incomingcheck", HgHideableWidget.class);
private static final Logger LOG = Logger.getInstance(HgVcs.class);
@@ -5,8 +5,6 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgUpdater;
import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.command.HgShowConfigCommand;
import java.util.Collections;
@@ -15,24 +13,24 @@ import java.util.Map;
/**
* @author Nadya Zabrodina
*/
public class HgConfig implements HgUpdater {
public class HgConfig {
@NotNull private VirtualFile myRepo;
@NotNull private Project myProject;
@NotNull private Map<String, Map<String, String>> myConfigMap = Collections.emptyMap();
@Nullable private String myDefaultPath; // cache most recent config
public HgConfig(@NotNull Project project, @NotNull VirtualFile repo) {
myProject = project;
myRepo = repo;
update(myProject, myRepo);
myProject.getMessageBus().connect().subscribe(HgVcs.UPDATE_CONFIG_TOPIC, this);
public static HgConfig getInstance(Project project, VirtualFile root) {
return new HgConfig(project, root);
}
private HgConfig(@NotNull Project project, @NotNull VirtualFile repo) {
myProject = project;
myRepo = repo;
update();
}
@Override
public void update(@NotNull Project project, @Nullable VirtualFile root) {
private void update() {
// todo: may be should change showconfigCommand to parse hgrc file
// but default values for extension and repository root are not included in hgrc, so perform showconfig is better
// in windows configuration Mercurial.ini file may be used instead of hgrc
@@ -48,4 +48,6 @@ public interface HgRepository extends Repository {
@NotNull
HgConfig getRepositoryConfig();
void updateConfig();
}
@@ -49,7 +49,7 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
@SuppressWarnings("ConstantConditions")
protected HgRepositoryImpl(@NotNull VirtualFile rootDir, @NotNull Project project,
private HgRepositoryImpl(@NotNull VirtualFile rootDir, @NotNull Project project,
@NotNull Disposable parentDisposable) {
super(project, rootDir, parentDisposable);
myHgDir = rootDir.findChild(HgUtil.DOT_HG);
@@ -57,7 +57,7 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
myState = State.NORMAL;
myCurrentRevision = null;
myReader = new HgRepositoryReader(VfsUtilCore.virtualToIoFile(myHgDir));
myConfig = new HgConfig(project, rootDir);
myConfig = HgConfig.getInstance(project, rootDir);
update();
}
@@ -142,4 +142,8 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
myCurrentBookmark = myReader.readCurrentBookmark();
}
}
public void updateConfig(){
myConfig = HgConfig.getInstance(getProject(),getRoot());
}
}
@@ -3,7 +3,6 @@ package org.zmlx.hg4idea.repo;
import com.intellij.dvcs.repo.AbstractRepositoryManager;
import com.intellij.dvcs.repo.RepositoryManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
@@ -17,21 +16,7 @@ public class HgRepositoryManager extends AbstractRepositoryManager<HgRepository>
public HgRepositoryManager(@NotNull Project project,
@NotNull ProjectLevelVcsManager vcsManager) {
super(project, vcsManager);
}
@Override
public void initComponent() {
myVcs = HgVcs.getInstance(myProject);
Disposer.register(myProject, this);
myProject.getMessageBus().connect().subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, this);
}
@Override
protected boolean isRootValid(@NotNull VirtualFile root) {
VirtualFile hgDir = root.findChild(HgUtil.DOT_HG);
return hgDir != null && hgDir.exists();
super(project, vcsManager, HgVcs.getInstance(project), HgUtil.DOT_HG);
}
@NotNull
@@ -28,7 +28,6 @@ import com.intellij.util.messages.MessageBusConnection;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgVcs;
import java.util.List;
@@ -38,27 +37,32 @@ import java.util.List;
* @author Nadya Zabrodina
*/
final class HgRepositoryUpdater implements Disposable, BulkFileListener {
@NotNull private Project myProject;
@NotNull private final HgRepositoryFiles myRepositoryFiles;
@Nullable private final MessageBusConnection myMessageBusConnection;
@NotNull private final QueueProcessor<Object> myUpdateQueue;
@NotNull private final Object DUMMY_UPDATE_OBJECT = new Object();
@Nullable private final VirtualFile myBranchHeadsDir;
@Nullable private final LocalFileSystem.WatchRequest myWatchRequest;
@NotNull private final QueueProcessor<Object> myUpdateConfigQueue;
HgRepositoryUpdater(@NotNull HgRepository repository) {
HgRepositoryUpdater(@NotNull final HgRepository repository) {
VirtualFile hgDir = repository.getHgDir();
myWatchRequest = LocalFileSystem.getInstance().addRootToWatch(hgDir.getPath(), true);
myRepositoryFiles = HgRepositoryFiles.getInstance(hgDir);
RepositoryUtil.visitVcsDirVfs(hgDir, HgRepositoryFiles.getSubDirRelativePaths());
myBranchHeadsDir = VcsUtil.getVirtualFile(myRepositoryFiles.getBranchHeadsDirPath());
myProject = repository.getProject();
myUpdateQueue = new QueueProcessor<Object>(new RepositoryUtil.Updater(repository), myProject.getDisposed());
if (!myProject.isDisposed()) {
myMessageBusConnection = myProject.getMessageBus().connect();
Project project = repository.getProject();
myUpdateQueue = new QueueProcessor<Object>(new RepositoryUtil.Updater(repository), project.getDisposed());
myUpdateConfigQueue = new QueueProcessor<Object>(new RepositoryUtil.Updater(repository){
@Override
public void consume(Object dummy) {
repository.updateConfig();
}
}, project.getDisposed());
if (!project.isDisposed()) {
myMessageBusConnection = project.getMessageBus().connect();
myMessageBusConnection.subscribe(VirtualFileManager.VFS_CHANGES, this);
}
else {
@@ -66,7 +70,6 @@ final class HgRepositoryUpdater implements Disposable, BulkFileListener {
}
}
@Override
public void dispose() {
if (myWatchRequest != null) {
@@ -122,7 +125,7 @@ final class HgRepositoryUpdater implements Disposable, BulkFileListener {
myUpdateQueue.add(DUMMY_UPDATE_OBJECT);
}
if (configHgrcChanged) {
myProject.getMessageBus().syncPublisher(HgVcs.UPDATE_CONFIG_TOPIC).update(myProject, null);
myUpdateConfigQueue.add(Void.TYPE);
}
}
}
@@ -125,7 +125,7 @@ public abstract class HgPlatformTest extends UsefulTestCase {
protected static void updateRepoConfig(@NotNull Project project, @Nullable VirtualFile repo) {
HgRepository hgRepository = HgUtil.getRepositoryManager(project).getRepositoryForRoot(repo);
assertNotNull(hgRepository);
hgRepository.getRepositoryConfig().update(project, null);
hgRepository.updateConfig();
}
protected void createRepository(VirtualFile root) {
@@ -67,8 +67,6 @@ public class HgDiffProviderTest extends HgSingleUserTest {
refreshVfs();
//ChangeListManager.getInstance(myProject).ensureUpToDate(false);
HgDiffProvider diffProvider = new HgDiffProvider(myProject);
HgRevisionNumber currentRevision = (HgRevisionNumber)diffProvider.getCurrentRevision(myWorkingCopyDir.findChild(AFILE));