Reduce calls to Repository.getConfig
Each time getConfig() is called on FileRepository, it checks the last modified time of both ~/.gitconfig and $GIT_DIR?config. If $GIT_DIR/config appears to have been modified, it is read back in from disk and the current config is wiped out. When mutating a configuration file, this may cause in-memory edits to disappear. To avoid that callers need to avoid calling getConfig until after the configuration has been saved to disk. Unfortunately the API is still horribly broken. Configuration should be modified only while a lock is held on the configuration file, very similar to the way a ref is updated via its locking protocol. But our existing API is really broken for that so we'll have to defer cleaning up the edit path for a future change. Change-Id: I5888dd97bac20ddf60456c81ffc1eb8df04ef410 Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
parent
86847ee322
commit
013cb8de38
|
@ -500,9 +500,10 @@ public void testPush_ChunkedEncoding() throws Exception {
|
|||
|
||||
enableReceivePack();
|
||||
|
||||
db.getConfig().setInt("core", null, "compression", 0);
|
||||
db.getConfig().setInt("http", null, "postbuffer", 8 * 1024);
|
||||
db.getConfig().save();
|
||||
final FileBasedConfig cfg = db.getConfig();
|
||||
cfg.setInt("core", null, "compression", 0);
|
||||
cfg.setInt("http", null, "postbuffer", 8 * 1024);
|
||||
cfg.save();
|
||||
|
||||
t = Transport.open(db, remoteURI);
|
||||
try {
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
import org.eclipse.jgit.lib.WorkDirCheckout;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
import org.eclipse.jgit.storage.file.FileBasedConfig;
|
||||
import org.eclipse.jgit.storage.file.FileRepository;
|
||||
import org.eclipse.jgit.transport.FetchResult;
|
||||
import org.eclipse.jgit.transport.RefSpec;
|
||||
|
@ -110,8 +111,9 @@ protected void run() throws Exception {
|
|||
|
||||
dst = new FileRepository(gitdir);
|
||||
dst.create();
|
||||
dst.getConfig().setBoolean("core", null, "bare", false);
|
||||
dst.getConfig().save();
|
||||
final FileBasedConfig dstcfg = dst.getConfig();
|
||||
dstcfg.setBoolean("core", null, "bare", false);
|
||||
dstcfg.save();
|
||||
db = dst;
|
||||
|
||||
out.print(MessageFormat.format(
|
||||
|
@ -128,13 +130,14 @@ protected void run() throws Exception {
|
|||
|
||||
private void saveRemote(final URIish uri) throws URISyntaxException,
|
||||
IOException {
|
||||
final RemoteConfig rc = new RemoteConfig(dst.getConfig(), remoteName);
|
||||
final FileBasedConfig dstcfg = dst.getConfig();
|
||||
final RemoteConfig rc = new RemoteConfig(dstcfg, remoteName);
|
||||
rc.addURI(uri);
|
||||
rc.addFetchRefSpec(new RefSpec().setForceUpdate(true)
|
||||
.setSourceDestination(Constants.R_HEADS + "*",
|
||||
Constants.R_REMOTES + remoteName + "/*"));
|
||||
rc.update(dst.getConfig());
|
||||
dst.getConfig().save();
|
||||
rc.update(dstcfg);
|
||||
dstcfg.save();
|
||||
}
|
||||
|
||||
private FetchResult runFetch() throws NotSupportedException,
|
||||
|
|
|
@ -182,9 +182,9 @@ public void test000_openrepo_default_absolute_workdirconfig()
|
|||
workdir.mkdir();
|
||||
FileRepository repo1initial = new FileRepository(new File(repo1Parent, Constants.DOT_GIT));
|
||||
repo1initial.create();
|
||||
repo1initial.getConfig().setString("core", null, "worktree",
|
||||
workdir.getAbsolutePath());
|
||||
repo1initial.getConfig().save();
|
||||
final FileBasedConfig cfg = repo1initial.getConfig();
|
||||
cfg.setString("core", null, "worktree", workdir.getAbsolutePath());
|
||||
cfg.save();
|
||||
repo1initial.close();
|
||||
|
||||
File theDir = new File(repo1Parent, Constants.DOT_GIT);
|
||||
|
@ -207,9 +207,9 @@ public void test000_openrepo_default_relative_workdirconfig()
|
|||
workdir.mkdir();
|
||||
FileRepository repo1initial = new FileRepository(new File(repo1Parent, Constants.DOT_GIT));
|
||||
repo1initial.create();
|
||||
repo1initial.getConfig()
|
||||
.setString("core", null, "worktree", "../../rw");
|
||||
repo1initial.getConfig().save();
|
||||
final FileBasedConfig cfg = repo1initial.getConfig();
|
||||
cfg.setString("core", null, "worktree", "../../rw");
|
||||
cfg.save();
|
||||
repo1initial.close();
|
||||
|
||||
File theDir = new File(repo1Parent, Constants.DOT_GIT);
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.lib.RefUpdate;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.StoredConfig;
|
||||
import org.eclipse.jgit.lib.RefUpdate.Result;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
|
@ -156,10 +157,11 @@ public List<String> call() throws JGitInternalException,
|
|||
String shortenedName = fullName
|
||||
.substring(Constants.R_HEADS.length());
|
||||
// remove upstream configuration if any
|
||||
repo.getConfig().unsetSection(
|
||||
final StoredConfig cfg = repo.getConfig();
|
||||
cfg.unsetSection(
|
||||
ConfigConstants.CONFIG_BRANCH_SECTION,
|
||||
shortenedName);
|
||||
repo.getConfig().save();
|
||||
cfg.save();
|
||||
}
|
||||
} else
|
||||
throw new JGitInternalException(MessageFormat.format(
|
||||
|
|
|
@ -186,7 +186,7 @@ public PullResult call() throws WrongRepositoryStateException,
|
|||
String remoteUri;
|
||||
FetchResult fetchRes;
|
||||
if (isRemote) {
|
||||
remoteUri = repo.getConfig().getString("remote", remote,
|
||||
remoteUri = repoConfig.getString("remote", remote,
|
||||
ConfigConstants.CONFIG_KEY_URL);
|
||||
if (remoteUri == null) {
|
||||
String missingKey = ConfigConstants.CONFIG_REMOTE_SECTION + DOT
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.lib.RefRename;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.StoredConfig;
|
||||
import org.eclipse.jgit.lib.RefUpdate.Result;
|
||||
|
||||
/**
|
||||
|
@ -144,27 +145,28 @@ public Ref call() throws RefNotFoundException, InvalidRefNameException,
|
|||
// move the upstream configuration over to the new branch
|
||||
String shortOldName = fullOldName
|
||||
.substring(Constants.R_HEADS.length());
|
||||
String oldRemote = repo.getConfig().getString(
|
||||
final StoredConfig repoConfig = repo.getConfig();
|
||||
String oldRemote = repoConfig.getString(
|
||||
ConfigConstants.CONFIG_BRANCH_SECTION,
|
||||
shortOldName, ConfigConstants.CONFIG_KEY_REMOTE);
|
||||
if (oldRemote != null) {
|
||||
repo.getConfig().setString(
|
||||
repoConfig.setString(
|
||||
ConfigConstants.CONFIG_BRANCH_SECTION, newName,
|
||||
ConfigConstants.CONFIG_KEY_REMOTE, oldRemote);
|
||||
}
|
||||
String oldMerge = repo.getConfig().getString(
|
||||
String oldMerge = repoConfig.getString(
|
||||
ConfigConstants.CONFIG_BRANCH_SECTION,
|
||||
shortOldName, ConfigConstants.CONFIG_KEY_MERGE);
|
||||
if (oldMerge != null) {
|
||||
repo.getConfig().setString(
|
||||
repoConfig.setString(
|
||||
ConfigConstants.CONFIG_BRANCH_SECTION, newName,
|
||||
ConfigConstants.CONFIG_KEY_MERGE, oldMerge);
|
||||
}
|
||||
repo.getConfig()
|
||||
repoConfig
|
||||
.unsetSection(
|
||||
ConfigConstants.CONFIG_BRANCH_SECTION,
|
||||
shortOldName);
|
||||
repo.getConfig().save();
|
||||
repoConfig.save();
|
||||
}
|
||||
|
||||
} else
|
||||
|
|
|
@ -160,7 +160,7 @@ public FileRepository(final BaseRepositoryBuilder options) throws IOException {
|
|||
loadUserConfig();
|
||||
loadRepoConfig();
|
||||
|
||||
getConfig().addChangeListener(new ConfigChangedListener() {
|
||||
repoConfig.addChangeListener(new ConfigChangedListener() {
|
||||
public void onConfigChanged(ConfigChangedEvent event) {
|
||||
fireEvent(event);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue