summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--distrib/gitblit.properties19
-rw-r--r--docs/02_rpc.mkd4
-rw-r--r--docs/04_releases.mkd2
-rw-r--r--src/com/gitblit/Constants.java4
-rw-r--r--src/com/gitblit/GitBlit.java152
-rw-r--r--src/com/gitblit/RpcServlet.java9
-rw-r--r--src/com/gitblit/client/GitblitClient.java4
-rw-r--r--src/com/gitblit/client/RepositoriesPanel.java31
-rw-r--r--src/com/gitblit/utils/JGitUtils.java20
-rw-r--r--src/com/gitblit/utils/ObjectCache.java4
-rw-r--r--src/com/gitblit/utils/RpcUtils.java15
-rw-r--r--src/com/gitblit/wicket/GitBlitWebApp.properties3
-rw-r--r--src/com/gitblit/wicket/panels/RepositoriesPanel.html8
-rw-r--r--src/com/gitblit/wicket/panels/RepositoriesPanel.java11
-rw-r--r--src/com/gitblit/wicket/panels/TeamsPanel.html4
-rw-r--r--src/com/gitblit/wicket/panels/UsersPanel.html4
-rw-r--r--tests/com/gitblit/tests/RepositoryModelTest.java5
17 files changed, 246 insertions, 53 deletions
diff --git a/distrib/gitblit.properties b/distrib/gitblit.properties
index 836ac05c..80cbb7e1 100644
--- a/distrib/gitblit.properties
+++ b/distrib/gitblit.properties
@@ -12,6 +12,17 @@
# RESTART REQUIRED
git.repositoriesFolder = git
+# Build the available repository list at startup and cache this list for reuse.
+# This reduces disk io when presenting the repositories page, responding to rpcs,
+# etc, but it means that Gitblit will not automatically identify repositories
+# added or deleted by external tools.
+#
+# For this case you can use curl, wget, etc to issue an rpc request to clear the
+# cache (e.g. https://localhost/rpc?req=CLEAR_REPOSITORY_CACHE)
+#
+# SINCE 1.1.0
+git.cacheRepositoryList = true
+
# Search the repositories folder subfolders for other repositories.
# Repositories MAY NOT be nested (i.e. one repository within another)
# but they may be grouped together in subfolders.
@@ -24,7 +35,7 @@ git.searchRepositoriesSubfolders = true
# Maximum number of folders to recurse into when searching for repositories.
# The default value, -1, disables depth limits.
#
-# SINCE 1.0.1
+# SINCE 1.1.0
git.searchRecursionDepth = -1
# List of regex exclusion patterns to match against folders found in
@@ -34,7 +45,7 @@ git.searchRecursionDepth = -1
#
# SPACE-DELIMITED
# CASE-SENSITIVE
-# SINCE 1.0.1
+# SINCE 1.1.0
git.searchExclusions =
# List of regex url patterns for extracting a repository name when locating
@@ -46,7 +57,7 @@ git.searchExclusions =
#
# SPACE-DELIMITED
# CASE-SENSITIVE
-# SINCE 1.0.1
+# SINCE 1.1.0
git.submoduleUrlPatterns = .*?://github.com/(.*)
# Allow push/pull over http/https with JGit servlet.
@@ -80,7 +91,7 @@ git.defaultAccessRestriction = NONE
# AUTHENTICATED = any authenticated user is granted restricted access
# NAMED = only named users/teams are granted restricted access
#
-# SINCE 1.0.1
+# SINCE 1.1.0
git.defaultAuthorizationControl = NAMED
# Number of bytes of a pack file to load into memory in a single read operation.
diff --git a/docs/02_rpc.mkd b/docs/02_rpc.mkd
index 8aa84f5b..6089ac9b 100644
--- a/docs/02_rpc.mkd
+++ b/docs/02_rpc.mkd
@@ -63,7 +63,8 @@ The Gitblit API includes methods for retrieving and interpreting RSS feeds. The
<tr><th>Release</th><th>Protocol Version</th></tr>
<tr><td>Gitblit v0.7.0</td><td>1 (inferred version)</td></tr>
<tr><td>Gitblit v0.8.0</td><td>2</td></tr>
-<tr><td>Gitblit v0.9.0+</td><td>3</td></tr>
+<tr><td>Gitblit v0.9.0 - v1.0.0</td><td>3</td></tr>
+<tr><td>Gitblit v1.1.0+</td><td>4</td></tr>
</tbody>
</table>
@@ -101,6 +102,7 @@ The Gitblit API includes methods for retrieving and interpreting RSS feeds. The
<tr><td>LIST_SETTINGS</td><td>-</td><td><em>admin</em></td><td>1</td><td>-</td><td>ServerSettings (all keys)</td></tr>
<tr><td>EDIT_SETTINGS</td><td>-</td><td><em>admin</em></td><td>1</td><td>Map&lt;String, String&gt;</td><td>-</td></tr>
<tr><td>LIST_STATUS</td><td>-</td><td><em>admin</em></td><td>1</td><td>-</td><td>ServerStatus (see example below)</td></tr>
+<tr><td>CLEAR_REPOSITORY_CACHE</td><td>-</td><td><em>admin</em></td><td>4</td><td>-</td><td>-</td></tr>
</table>
### RPC/HTTP Response Codes
diff --git a/docs/04_releases.mkd b/docs/04_releases.mkd
index 624cb53f..5c89d9a4 100644
--- a/docs/04_releases.mkd
+++ b/docs/04_releases.mkd
@@ -25,6 +25,8 @@ If you are updating from an earlier release AND you have indexed branches with t
#### additions
+- Identified repository list is now cached by default to reduce disk io and to improve performance (issue 103)
+ **New:** *git.cacheRepositoryList=true*
- Preliminary bare repository submodule support
**New:** *git.submoduleUrlPatterns=*
- *git.submoduleUrlPatterns* is a space-delimited list of regular expressions for extracting a repository name from a submodule url.
diff --git a/src/com/gitblit/Constants.java b/src/com/gitblit/Constants.java
index 181fb8f0..5f3bea9f 100644
--- a/src/com/gitblit/Constants.java
+++ b/src/com/gitblit/Constants.java
@@ -30,7 +30,7 @@ public class Constants {
// The build script extracts this exact line so be careful editing it
// and only use A-Z a-z 0-9 .-_ in the string.
- public static final String VERSION = "1.0.1-SNAPSHOT";
+ public static final String VERSION = "1.1.0-SNAPSHOT";
// The build script extracts this exact line so be careful editing it
// and only use A-Z a-z 0-9 .-_ in the string.
@@ -248,7 +248,7 @@ public class Constants {
LIST_TEAMS, CREATE_TEAM, EDIT_TEAM, DELETE_TEAM,
LIST_REPOSITORY_MEMBERS, SET_REPOSITORY_MEMBERS, LIST_REPOSITORY_TEAMS, SET_REPOSITORY_TEAMS,
LIST_FEDERATION_REGISTRATIONS, LIST_FEDERATION_RESULTS, LIST_FEDERATION_PROPOSALS, LIST_FEDERATION_SETS,
- EDIT_SETTINGS, LIST_STATUS;
+ EDIT_SETTINGS, LIST_STATUS, CLEAR_REPOSITORY_CACHE;
public static RpcRequest fromName(String name) {
for (RpcRequest type : values()) {
diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java
index f52f229f..97fb5a95 100644
--- a/src/com/gitblit/GitBlit.java
+++ b/src/com/gitblit/GitBlit.java
@@ -39,10 +39,12 @@ import java.util.Set;
import java.util.TimeZone;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
import javax.mail.Message;
import javax.mail.MessagingException;
@@ -125,6 +127,10 @@ public class GitBlit implements ServletContextListener {
private final ObjectCache<Long> repositorySizeCache = new ObjectCache<Long>();
private final ObjectCache<List<Metric>> repositoryMetricsCache = new ObjectCache<List<Metric>>();
+
+ private final List<String> repositoryListCache = new CopyOnWriteArrayList<String>();
+
+ private final AtomicReference<String> repositoryListSettingsChecksum = new AtomicReference<String>("");
private RepositoryResolver<Void> repositoryResolver;
@@ -723,15 +729,73 @@ public class GitBlit implements ServletContextListener {
public boolean deleteTeam(String teamname) {
return userService.deleteTeam(teamname);
}
+
+ /**
+ * Adds the repository to the list of cached repositories if Gitblit is
+ * configured to cache the repository list.
+ *
+ * @param name
+ */
+ private void addToCachedRepositoryList(String name) {
+ if (settings.getBoolean(Keys.git.cacheRepositoryList, true)) {
+ repositoryListCache.add(name);
+ }
+ }
/**
* Clears all the cached data for the specified repository.
*
* @param repositoryName
+ * @param isDeleted
*/
- public void clearRepositoryCache(String repositoryName) {
+ private void clearRepositoryCache(String repositoryName, boolean isDeleted) {
repositorySizeCache.remove(repositoryName);
repositoryMetricsCache.remove(repositoryName);
+
+ if (isDeleted) {
+ repositoryListCache.remove(repositoryName);
+ }
+ }
+
+ /**
+ * Resets the repository list cache.
+ *
+ */
+ public void resetRepositoryListCache() {
+ logger.info("Repository cache manually reset");
+ repositoryListCache.clear();
+ }
+
+ /**
+ * Calculate the checksum of settings that affect the repository list cache.
+ * @return a checksum
+ */
+ private String getRepositoryListSettingsChecksum() {
+ StringBuilder ns = new StringBuilder();
+ ns.append(settings.getString(Keys.git.cacheRepositoryList, "")).append('\n');
+ ns.append(settings.getString(Keys.git.onlyAccessBareRepositories, "")).append('\n');
+ ns.append(settings.getString(Keys.git.searchRepositoriesSubfolders, "")).append('\n');
+ ns.append(settings.getString(Keys.git.searchRecursionDepth, "")).append('\n');
+ ns.append(settings.getString(Keys.git.searchExclusions, "")).append('\n');
+ String checksum = StringUtils.getSHA1(ns.toString());
+ return checksum;
+ }
+
+ /**
+ * Compare the last repository list setting checksum to the current checksum.
+ * If different then clear the cache so that it may be rebuilt.
+ *
+ * @return true if the cached repository list is valid since the last check
+ */
+ private boolean isValidRepositoryList() {
+ String newChecksum = getRepositoryListSettingsChecksum();
+ boolean valid = newChecksum.equals(repositoryListSettingsChecksum.get());
+ repositoryListSettingsChecksum.set(newChecksum);
+ if (!valid && settings.getBoolean(Keys.git.cacheRepositoryList, true)) {
+ logger.info("Repository list settings have changed. Clearing repository list cache.");
+ repositoryListCache.clear();
+ }
+ return valid;
}
/**
@@ -741,11 +805,46 @@ public class GitBlit implements ServletContextListener {
* @return list of all repositories
*/
public List<String> getRepositoryList() {
- return JGitUtils.getRepositoryList(repositoriesFolder,
- settings.getBoolean(Keys.git.onlyAccessBareRepositories, false),
- settings.getBoolean(Keys.git.searchRepositoriesSubfolders, true),
- settings.getInteger(Keys.git.searchRecursionDepth, -1),
- settings.getStrings(Keys.git.searchExclusions));
+ if (repositoryListCache.size() == 0 || !isValidRepositoryList()) {
+ // we are not caching OR we have not yet cached OR the cached list is invalid
+ long startTime = System.currentTimeMillis();
+ List<String> repositories = JGitUtils.getRepositoryList(repositoriesFolder,
+ settings.getBoolean(Keys.git.onlyAccessBareRepositories, false),
+ settings.getBoolean(Keys.git.searchRepositoriesSubfolders, true),
+ settings.getInteger(Keys.git.searchRecursionDepth, -1),
+ settings.getStrings(Keys.git.searchExclusions));
+
+ if (!settings.getBoolean(Keys.git.cacheRepositoryList, true)) {
+ // we are not caching
+ StringUtils.sortRepositorynames(repositories);
+ return repositories;
+ } else {
+ // we are caching this list
+ String msg = "{0} repositories identified in {1} msecs";
+
+ // optionally (re)calculate repository sizes
+ if (getBoolean(Keys.web.showRepositorySizes, true)) {
+ msg = "{0} repositories identified with calculated folder sizes in {1} msecs";
+ for (String repository : repositories) {
+ RepositoryModel model = getRepositoryModel(repository);
+ if (!model.skipSizeCalculation) {
+ calculateSize(model);
+ }
+ }
+ }
+
+ // update cache
+ repositoryListCache.addAll(repositories);
+
+ long duration = System.currentTimeMillis() - startTime;
+ logger.info(MessageFormat.format(msg, repositoryListCache.size(), duration));
+ }
+ }
+
+ // return sorted copy of cached list
+ List<String> list = new ArrayList<String>(repositoryListCache);
+ StringUtils.sortRepositorynames(list);
+ return list;
}
/**
@@ -804,6 +903,7 @@ public class GitBlit implements ServletContextListener {
* @return list of repository models accessible to user
*/
public List<RepositoryModel> getRepositoryModels(UserModel user) {
+ long methodStart = System.currentTimeMillis();
List<String> list = getRepositoryList();
List<RepositoryModel> repositories = new ArrayList<RepositoryModel>();
for (String repo : list) {
@@ -823,9 +923,15 @@ public class GitBlit implements ServletContextListener {
}
}
long duration = System.currentTimeMillis() - startTime;
- logger.info(MessageFormat.format("{0} repository sizes calculated in {1} msecs",
+ if (duration > 250) {
+ // only log calcualtion time if > 250 msecs
+ logger.info(MessageFormat.format("{0} repository sizes calculated in {1} msecs",
repoCount, duration));
+ }
}
+ long duration = System.currentTimeMillis() - methodStart;
+ logger.info(MessageFormat.format("{0} repository models loaded for {1} in {2} msecs",
+ repositories.size(), user.username, duration));
return repositories;
}
@@ -869,7 +975,8 @@ public class GitBlit implements ServletContextListener {
model.hasCommits = JGitUtils.hasCommits(r);
model.lastChange = JGitUtils.getLastChange(r);
model.isBare = r.isBare();
- StoredConfig config = JGitUtils.readConfig(r);
+
+ StoredConfig config = r.getConfig();
if (config != null) {
model.description = getConfig(config, "description", "");
model.owner = getConfig(config, "owner", "");
@@ -1062,6 +1169,9 @@ public class GitBlit implements ServletContextListener {
// create repository
logger.info("create repository " + repository.name);
r = JGitUtils.createRepository(repositoriesFolder, repository.name);
+
+ // add name to cache
+ addToCachedRepositoryList(repository.name);
} else {
// rename repository
if (!repositoryName.equalsIgnoreCase(repository.name)) {
@@ -1101,7 +1211,10 @@ public class GitBlit implements ServletContextListener {
}
// clear the cache
- clearRepositoryCache(repositoryName);
+ clearRepositoryCache(repositoryName, true);
+
+ // add new name to repository list cache
+ addToCachedRepositoryList(repository.name);
}
// load repository
@@ -1129,7 +1242,7 @@ public class GitBlit implements ServletContextListener {
repository.name, currentRef, repository.HEAD));
if (JGitUtils.setHEADtoRef(r, repository.HEAD)) {
// clear the cache
- clearRepositoryCache(repository.name);
+ clearRepositoryCache(repository.name, false);
}
}
@@ -1137,7 +1250,7 @@ public class GitBlit implements ServletContextListener {
r.close();
}
}
-
+
/**
* Updates the Gitblit configuration for the specified repository.
*
@@ -1147,7 +1260,7 @@ public class GitBlit implements ServletContextListener {
* the Gitblit repository model
*/
public void updateConfiguration(Repository r, RepositoryModel repository) {
- StoredConfig config = JGitUtils.readConfig(r);
+ StoredConfig config = r.getConfig();
config.setString(Constants.CONFIG_GITBLIT, null, "description", repository.description);
config.setString(Constants.CONFIG_GITBLIT, null, "owner", repository.owner);
config.setBoolean(Constants.CONFIG_GITBLIT, null, "useTickets", repository.useTickets);
@@ -1225,6 +1338,9 @@ public class GitBlit implements ServletContextListener {
public boolean deleteRepository(String repositoryName) {
try {
closeRepository(repositoryName);
+ // clear the repository cache
+ clearRepositoryCache(repositoryName, true);
+
File folder = new File(repositoriesFolder, repositoryName);
if (folder.exists() && folder.isDirectory()) {
FileUtils.delete(folder, FileUtils.RECURSIVE | FileUtils.RETRY);
@@ -1232,9 +1348,6 @@ public class GitBlit implements ServletContextListener {
return true;
}
}
-
- // clear the repository cache
- clearRepositoryCache(repositoryName);
} catch (Throwable t) {
logger.error(MessageFormat.format("Failed to delete repository {0}", repositoryName), t);
}
@@ -1953,6 +2066,15 @@ public class GitBlit implements ServletContextListener {
repositoriesFolder = getRepositoriesFolder();
logger.info("Git repositories folder " + repositoriesFolder.getAbsolutePath());
repositoryResolver = new FileResolver<Void>(repositoriesFolder, true);
+
+ // calculate repository list settings checksum for future config changes
+ repositoryListSettingsChecksum.set(getRepositoryListSettingsChecksum());
+
+ // build initial repository list
+ if (settings.getBoolean(Keys.git.cacheRepositoryList, true)) {
+ logger.info("Identifying available repositories...");
+ getRepositoryList();
+ }
logTimezone("JVM", TimeZone.getDefault());
logTimezone(Constants.NAME, getTimezone());
diff --git a/src/com/gitblit/RpcServlet.java b/src/com/gitblit/RpcServlet.java
index 31ee5ad0..929e9cc6 100644
--- a/src/com/gitblit/RpcServlet.java
+++ b/src/com/gitblit/RpcServlet.java
@@ -49,7 +49,7 @@ public class RpcServlet extends JsonServlet {
private static final long serialVersionUID = 1L;
- public static final int PROTOCOL_VERSION = 3;
+ public static final int PROTOCOL_VERSION = 4;
public RpcServlet() {
super();
@@ -319,6 +319,13 @@ public class RpcServlet extends JsonServlet {
} else {
response.sendError(notAllowedCode);
}
+ } else if (RpcRequest.CLEAR_REPOSITORY_CACHE.equals(reqType)) {
+ // clear the repository list cache
+ if (allowAdmin) {
+ GitBlit.self().resetRepositoryListCache();
+ } else {
+ response.sendError(notAllowedCode);
+ }
}
// send the result of the request
diff --git a/src/com/gitblit/client/GitblitClient.java b/src/com/gitblit/client/GitblitClient.java
index 5e05fa49..52d4e06d 100644
--- a/src/com/gitblit/client/GitblitClient.java
+++ b/src/com/gitblit/client/GitblitClient.java
@@ -578,6 +578,10 @@ public class GitblitClient implements Serializable {
public boolean deleteRepository(RepositoryModel repository) throws IOException {
return RpcUtils.deleteRepository(repository, url, account, password);
}
+
+ public boolean clearRepositoryCache() throws IOException {
+ return RpcUtils.clearRepositoryCache(url, account, password);
+ }
public boolean createUser(UserModel user) throws IOException {
return RpcUtils.createUser(user, url, account, password);
diff --git a/src/com/gitblit/client/RepositoriesPanel.java b/src/com/gitblit/client/RepositoriesPanel.java
index cbe18743..54158e8e 100644
--- a/src/com/gitblit/client/RepositoriesPanel.java
+++ b/src/com/gitblit/client/RepositoriesPanel.java
@@ -82,6 +82,8 @@ public abstract class RepositoriesPanel extends JPanel {
private JTextField filterTextfield;
+ private JButton clearCache;
+
public RepositoriesPanel(GitblitClient gitblit) {
super();
this.gitblit = gitblit;
@@ -105,6 +107,13 @@ public abstract class RepositoriesPanel extends JPanel {
refreshRepositories();
}
});
+
+ clearCache = new JButton(Translation.get("gb.clearCache"));
+ clearCache.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ clearCache();
+ }
+ });
createRepository = new JButton(Translation.get("gb.create"));
createRepository.addActionListener(new ActionListener() {
@@ -242,6 +251,7 @@ public abstract class RepositoriesPanel extends JPanel {
repositoryTablePanel.add(new JScrollPane(table), BorderLayout.CENTER);
JPanel repositoryControls = new JPanel(new FlowLayout(FlowLayout.CENTER, Utils.MARGIN, 0));
+ repositoryControls.add(clearCache);
repositoryControls.add(refreshRepositories);
repositoryControls.add(browseRepository);
repositoryControls.add(createRepository);
@@ -285,6 +295,7 @@ public abstract class RepositoriesPanel extends JPanel {
protected abstract void updateTeamsTable();
protected void disableManagement() {
+ clearCache.setVisible(false);
createRepository.setVisible(false);
editRepository.setVisible(false);
delRepository.setVisible(false);
@@ -348,6 +359,26 @@ public abstract class RepositoriesPanel extends JPanel {
};
worker.execute();
}
+
+ protected void clearCache() {
+ GitblitWorker worker = new GitblitWorker(RepositoriesPanel.this,
+ RpcRequest.CLEAR_REPOSITORY_CACHE) {
+ @Override
+ protected Boolean doRequest() throws IOException {
+ if (gitblit.clearRepositoryCache()) {
+ gitblit.refreshRepositories();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected void onSuccess() {
+ updateTable(false);
+ }
+ };
+ worker.execute();
+ }
/**
* Displays the create repository dialog and fires a SwingWorker to update
diff --git a/src/com/gitblit/utils/JGitUtils.java b/src/com/gitblit/utils/JGitUtils.java
index 5eb83edb..a78a7716 100644
--- a/src/com/gitblit/utils/JGitUtils.java
+++ b/src/com/gitblit/utils/JGitUtils.java
@@ -47,7 +47,6 @@ import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.StopWalkException;
import org.eclipse.jgit.lib.BlobBasedConfig;
import org.eclipse.jgit.lib.CommitBuilder;
-import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
@@ -59,7 +58,6 @@ import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
-import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.lib.TreeFormatter;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
@@ -1709,24 +1707,6 @@ public class JGitUtils {
}
/**
- * Returns a StoredConfig object for the repository.
- *
- * @param repository
- * @return the StoredConfig of the repository
- */
- public static StoredConfig readConfig(Repository repository) {
- StoredConfig c = repository.getConfig();
- try {
- c.load();
- } catch (ConfigInvalidException cex) {
- error(cex, repository, "{0} configuration is invalid!");
- } catch (IOException cex) {
- error(cex, repository, "Could not open configuration for {0}!");
- }
- return c;
- }
-
- /**
* Zips the contents of the tree at the (optionally) specified revision and
* the (optionally) specified basepath to the supplied outputstream.
*
diff --git a/src/com/gitblit/utils/ObjectCache.java b/src/com/gitblit/utils/ObjectCache.java
index 3bbf4d19..38f2e59a 100644
--- a/src/com/gitblit/utils/ObjectCache.java
+++ b/src/com/gitblit/utils/ObjectCache.java
@@ -91,4 +91,8 @@ public class ObjectCache<X> implements Serializable {
}
return null;
}
+
+ public int size() {
+ return cache.size();
+ }
}
diff --git a/src/com/gitblit/utils/RpcUtils.java b/src/com/gitblit/utils/RpcUtils.java
index 02a63a48..2b80e2af 100644
--- a/src/com/gitblit/utils/RpcUtils.java
+++ b/src/com/gitblit/utils/RpcUtils.java
@@ -231,6 +231,21 @@ public class RpcUtils {
password);
}
+
+ /**
+ * Clears the repository cache on the Gitblit server.
+ *
+ * @param serverUrl
+ * @param account
+ * @param password
+ * @return true if the action succeeded
+ * @throws IOException
+ */
+ public static boolean clearRepositoryCache(String serverUrl, String account,
+ char[] password) throws IOException {
+ return doAction(RpcRequest.CLEAR_REPOSITORY_CACHE, null, null, serverUrl, account,
+ password);
+ }
/**
* Create a user on the Gitblit server.
diff --git a/src/com/gitblit/wicket/GitBlitWebApp.properties b/src/com/gitblit/wicket/GitBlitWebApp.properties
index f9480a8f..2a31f8be 100644
--- a/src/com/gitblit/wicket/GitBlitWebApp.properties
+++ b/src/com/gitblit/wicket/GitBlitWebApp.properties
@@ -313,4 +313,5 @@ gb.duration.years = {0} years
gb.authorizationControl = authorization control
gb.allowAuthenticatedDescription = grant restricted access to all authenticated users
gb.allowNamedDescription = grant restricted access to named users or teams
-gb.markdownFailure = Failed to parse Markdown content! \ No newline at end of file
+gb.markdownFailure = Failed to parse Markdown content!
+gb.clearCache = clear cache \ No newline at end of file
diff --git a/src/com/gitblit/wicket/panels/RepositoriesPanel.html b/src/com/gitblit/wicket/panels/RepositoriesPanel.html
index 5b53d772..99bedc63 100644
--- a/src/com/gitblit/wicket/panels/RepositoriesPanel.html
+++ b/src/com/gitblit/wicket/panels/RepositoriesPanel.html
@@ -21,8 +21,12 @@
<wicket:fragment wicket:id="adminLinks">
<!-- page nav links -->
<div class="admin_nav">
- <img style="vertical-align: middle;" src="add_16x16.png"/>
- <a wicket:id="newRepository">
+ <a class="btn-small" wicket:id="clearCache">
+ <i class="icon icon-remove"></i>
+ <wicket:message key="gb.clearCache"></wicket:message>
+ </a>
+ <a class="btn-small" wicket:id="newRepository" style="padding-right:0px;">
+ <i class="icon icon-plus-sign"></i>
<wicket:message key="gb.newRepository"></wicket:message>
</a>
</div>
diff --git a/src/com/gitblit/wicket/panels/RepositoriesPanel.java b/src/com/gitblit/wicket/panels/RepositoriesPanel.java
index 9664e05b..8c8e1e5e 100644
--- a/src/com/gitblit/wicket/panels/RepositoriesPanel.java
+++ b/src/com/gitblit/wicket/panels/RepositoriesPanel.java
@@ -54,6 +54,7 @@ import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.pages.BasePage;
import com.gitblit.wicket.pages.EditRepositoryPage;
import com.gitblit.wicket.pages.EmptyRepositoryPage;
+import com.gitblit.wicket.pages.RepositoriesPage;
import com.gitblit.wicket.pages.SummaryPage;
public class RepositoriesPanel extends BasePanel {
@@ -73,6 +74,16 @@ public class RepositoriesPanel extends BasePanel {
final IDataProvider<RepositoryModel> dp;
Fragment adminLinks = new Fragment("adminPanel", "adminLinks", this);
+ adminLinks.add(new Link<Void>("clearCache") {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void onClick() {
+ GitBlit.self().resetRepositoryListCache();
+ setResponsePage(RepositoriesPage.class);
+ }
+ }.setVisible(GitBlit.getBoolean(Keys.git.cacheRepositoryList, true)));
adminLinks.add(new BookmarkablePageLink<Void>("newRepository", EditRepositoryPage.class));
add(adminLinks.setVisible(showAdmin));
diff --git a/src/com/gitblit/wicket/panels/TeamsPanel.html b/src/com/gitblit/wicket/panels/TeamsPanel.html
index c6a73cd7..ff689292 100644
--- a/src/com/gitblit/wicket/panels/TeamsPanel.html
+++ b/src/com/gitblit/wicket/panels/TeamsPanel.html
@@ -32,8 +32,8 @@
<wicket:fragment wicket:id="adminLinks">
<!-- page nav links -->
<div class="admin_nav">
- <img style="vertical-align: middle;" src="add_16x16.png"/>
- <a wicket:id="newTeam">
+ <a class="btn-small" wicket:id="newTeam" style="padding-right:0px;">
+ <i class="icon icon-plus-sign"></i>
<wicket:message key="gb.newTeam"></wicket:message>
</a>
</div>
diff --git a/src/com/gitblit/wicket/panels/UsersPanel.html b/src/com/gitblit/wicket/panels/UsersPanel.html
index 8e0ed1f1..aed985c1 100644
--- a/src/com/gitblit/wicket/panels/UsersPanel.html
+++ b/src/com/gitblit/wicket/panels/UsersPanel.html
@@ -38,8 +38,8 @@
<wicket:fragment wicket:id="adminLinks">
<!-- page nav links -->
<div class="admin_nav">
- <img style="vertical-align: middle;" src="add_16x16.png"/>
- <a wicket:id="newUser">
+ <a class="btn-small" wicket:id="newUser" style="padding-right:0px;">
+ <i class="icon icon-plus-sign"></i>
<wicket:message key="gb.newUser"></wicket:message>
</a>
</div>
diff --git a/tests/com/gitblit/tests/RepositoryModelTest.java b/tests/com/gitblit/tests/RepositoryModelTest.java
index d49cb434..1fe3fbd0 100644
--- a/tests/com/gitblit/tests/RepositoryModelTest.java
+++ b/tests/com/gitblit/tests/RepositoryModelTest.java
@@ -29,7 +29,6 @@ import org.junit.Test;
import com.gitblit.Constants;
import com.gitblit.GitBlit;
import com.gitblit.models.RepositoryModel;
-import com.gitblit.utils.JGitUtils;
public class RepositoryModelTest {
@@ -49,7 +48,7 @@ public class RepositoryModelTest {
@Before
public void initializeConfiguration() throws Exception{
Repository r = GitBlitSuite.getHelloworldRepository();
- StoredConfig config = JGitUtils.readConfig(r);
+ StoredConfig config = r.getConfig();
config.unsetSection(Constants.CONFIG_GITBLIT, Constants.CONFIG_CUSTOM_FIELDS);
config.setString(Constants.CONFIG_GITBLIT, Constants.CONFIG_CUSTOM_FIELDS, "commitMessageRegEx", "\\d");
@@ -61,7 +60,7 @@ public class RepositoryModelTest {
@After
public void teardownConfiguration() throws Exception {
Repository r = GitBlitSuite.getHelloworldRepository();
- StoredConfig config = JGitUtils.readConfig(r);
+ StoredConfig config = r.getConfig();
config.unsetSection(Constants.CONFIG_GITBLIT, Constants.CONFIG_CUSTOM_FIELDS);
config.save();