From c890e1f7d3f5cd83025b1d993cedf4990de63897 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Tue, 09 Oct 2012 08:01:47 -0400
Subject: [PATCH] Fixed missing translations in Gitblit Manager builds (issue 145)
---
src/com/gitblit/GitBlit.java | 267 +++++++++++++++++++++++++++++++++++++----------------
1 files changed, 185 insertions(+), 82 deletions(-)
diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java
index 699bbac..7fbd3ef 100644
--- a/src/com/gitblit/GitBlit.java
+++ b/src/com/gitblit/GitBlit.java
@@ -32,6 +32,7 @@
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@@ -56,18 +57,13 @@
import javax.servlet.http.Cookie;
import org.apache.wicket.protocol.http.WebResponse;
-import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.RepositoryCache;
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.storage.file.WindowCache;
import org.eclipse.jgit.storage.file.WindowCacheConfig;
-import org.eclipse.jgit.transport.ServiceMayNotContinueException;
-import org.eclipse.jgit.transport.resolver.FileResolver;
-import org.eclipse.jgit.transport.resolver.RepositoryResolver;
-import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
-import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
import org.slf4j.Logger;
@@ -81,6 +77,7 @@
import com.gitblit.models.FederationModel;
import com.gitblit.models.FederationProposal;
import com.gitblit.models.FederationSet;
+import com.gitblit.models.ForkModel;
import com.gitblit.models.Metric;
import com.gitblit.models.ProjectModel;
import com.gitblit.models.RepositoryModel;
@@ -139,8 +136,6 @@
private final Map<String, ProjectModel> projectCache = new ConcurrentHashMap<String, ProjectModel>();
private final AtomicReference<String> repositoryListSettingsChecksum = new AtomicReference<String>("");
-
- private RepositoryResolver<Void> repositoryResolver;
private ServletContext servletContext;
@@ -744,17 +739,17 @@
* Adds the repository to the list of cached repositories if Gitblit is
* configured to cache the repository list.
*
- * @param name
+ * @param model
*/
- private void addToCachedRepositoryList(String name, RepositoryModel model) {
+ private void addToCachedRepositoryList(RepositoryModel model) {
if (settings.getBoolean(Keys.git.cacheRepositoryList, true)) {
- repositoryListCache.put(name, model);
+ repositoryListCache.put(model.name, model);
// update the fork origin repository with this repository clone
if (!StringUtils.isEmpty(model.originRepository)) {
if (repositoryListCache.containsKey(model.originRepository)) {
RepositoryModel origin = repositoryListCache.get(model.originRepository);
- origin.addFork(name);
+ origin.addFork(model.name);
}
}
}
@@ -893,32 +888,18 @@
* @return repository or null
*/
public Repository getRepository(String repositoryName, boolean logError) {
+ File dir = FileKey.resolve(new File(repositoriesFolder, repositoryName), FS.DETECTED);
+ if (dir == null)
+ return null;
+
Repository r = null;
try {
- r = repositoryResolver.open(null, repositoryName);
- } catch (RepositoryNotFoundException e) {
- r = null;
+ FileKey key = FileKey.exact(dir, FS.DETECTED);
+ r = RepositoryCache.open(key, true);
+ } catch (IOException e) {
if (logError) {
logger.error("GitBlit.getRepository(String) failed to find "
+ new File(repositoriesFolder, repositoryName).getAbsolutePath());
- }
- } catch (ServiceNotAuthorizedException e) {
- r = null;
- if (logError) {
- logger.error("GitBlit.getRepository(String) failed to find "
- + new File(repositoriesFolder, repositoryName).getAbsolutePath(), e);
- }
- } catch (ServiceNotEnabledException e) {
- r = null;
- if (logError) {
- logger.error("GitBlit.getRepository(String) failed to find "
- + new File(repositoriesFolder, repositoryName).getAbsolutePath(), e);
- }
- } catch (ServiceMayNotContinueException e) {
- r = null;
- if (logError) {
- logger.error("GitBlit.getRepository(String) failed to find "
- + new File(repositoriesFolder, repositoryName).getAbsolutePath(), e);
}
}
return r;
@@ -999,7 +980,7 @@
if (model == null) {
return null;
}
- addToCachedRepositoryList(repositoryName, model);
+ addToCachedRepositoryList(model);
return model;
}
@@ -1021,7 +1002,7 @@
logger.info(MessageFormat.format("Config for \"{0}\" has changed. Reloading model and updating cache.", repositoryName));
model = loadRepositoryModel(repositoryName);
removeFromCachedRepositoryList(repositoryName);
- addToCachedRepositoryList(repositoryName, model);
+ addToCachedRepositoryList(model);
} else {
// update a few repository parameters
if (!model.hasCommits) {
@@ -1234,10 +1215,15 @@
return null;
}
RepositoryModel model = new RepositoryModel();
- model.name = repositoryName;
+ model.isBare = r.isBare();
+ File basePath = getFileOrFolder(Keys.git.repositoriesFolder, "git");
+ if (model.isBare) {
+ model.name = com.gitblit.utils.FileUtils.getRelativePath(basePath, r.getDirectory());
+ } else {
+ model.name = com.gitblit.utils.FileUtils.getRelativePath(basePath, r.getDirectory().getParentFile());
+ }
model.hasCommits = JGitUtils.hasCommits(r);
model.lastChange = JGitUtils.getLastChange(r);
- model.isBare = r.isBare();
if (repositoryName.indexOf('/') == -1) {
model.projectPath = "";
} else {
@@ -1268,6 +1254,9 @@
Constants.CONFIG_GITBLIT, null, "federationSets")));
model.isFederated = getConfig(config, "isFederated", false);
model.origin = config.getString("remote", "origin", "url");
+ if (model.origin != null) {
+ model.origin = model.origin.replace('\\', '/');
+ }
model.preReceiveScripts = new ArrayList<String>(Arrays.asList(config.getStringList(
Constants.CONFIG_GITBLIT, null, "preReceiveScript")));
model.postReceiveScripts = new ArrayList<String>(Arrays.asList(config.getStringList(
@@ -1325,6 +1314,113 @@
r.close();
return true;
}
+
+ /**
+ * Determines if the specified user has a fork of the specified origin
+ * repository.
+ *
+ * @param username
+ * @param origin
+ * @return true the if the user has a fork
+ */
+ public boolean hasFork(String username, String origin) {
+ return getFork(username, origin) != null;
+ }
+
+ /**
+ * Gets the name of a user's fork of the specified origin
+ * repository.
+ *
+ * @param username
+ * @param origin
+ * @return the name of the user's fork, null otherwise
+ */
+ public String getFork(String username, String origin) {
+ String userProject = "~" + username.toLowerCase();
+ if (settings.getBoolean(Keys.git.cacheRepositoryList, true)) {
+ String userPath = userProject + "/";
+
+ // collect all origin nodes in fork network
+ Set<String> roots = new HashSet<String>();
+ roots.add(origin);
+ RepositoryModel originModel = repositoryListCache.get(origin);
+ while (originModel != null) {
+ if (!ArrayUtils.isEmpty(originModel.forks)) {
+ for (String fork : originModel.forks) {
+ if (!fork.startsWith(userPath)) {
+ roots.add(fork);
+ }
+ }
+ }
+
+ if (originModel.originRepository != null) {
+ roots.add(originModel.originRepository);
+ originModel = repositoryListCache.get(originModel.originRepository);
+ } else {
+ // break
+ originModel = null;
+ }
+ }
+
+ for (String repository : repositoryListCache.keySet()) {
+ if (repository.toLowerCase().startsWith(userPath)) {
+ RepositoryModel model = repositoryListCache.get(repository);
+ if (!StringUtils.isEmpty(model.originRepository)) {
+ if (roots.contains(model.originRepository)) {
+ // user has a fork in this graph
+ return model.name;
+ }
+ }
+ }
+ }
+ } else {
+ // not caching
+ ProjectModel project = getProjectModel(userProject);
+ for (String repository : project.repositories) {
+ if (repository.toLowerCase().startsWith(userProject)) {
+ RepositoryModel model = repositoryListCache.get(repository);
+ if (model.originRepository.equalsIgnoreCase(origin)) {
+ // user has a fork
+ return model.name;
+ }
+ }
+ }
+ }
+ // user does not have a fork
+ return null;
+ }
+
+ /**
+ * Returns the fork network for a repository by traversing up the fork graph
+ * to discover the root and then down through all children of the root node.
+ *
+ * @param repository
+ * @return a ForkModel
+ */
+ public ForkModel getForkNetwork(String repository) {
+ if (settings.getBoolean(Keys.git.cacheRepositoryList, true)) {
+ // find the root
+ RepositoryModel model = repositoryListCache.get(repository);
+ while (model.originRepository != null) {
+ model = repositoryListCache.get(model.originRepository);
+ }
+ ForkModel root = getForkModel(model.name);
+ return root;
+ }
+ return null;
+ }
+
+ private ForkModel getForkModel(String repository) {
+ RepositoryModel model = repositoryListCache.get(repository);
+ ForkModel fork = new ForkModel(model);
+ if (!ArrayUtils.isEmpty(model.forks)) {
+ for (String aFork : model.forks) {
+ ForkModel fm = getForkModel(aFork);
+ fork.forks.add(fm);
+ }
+ }
+ return fork;
+ }
/**
* Returns the size in bytes of the repository. Gitblit caches the
@@ -1353,6 +1449,8 @@
*/
private void closeRepository(String repositoryName) {
Repository repository = getRepository(repositoryName);
+ RepositoryCache.close(repository);
+
// assume 2 uses in case reflection fails
int uses = 2;
try {
@@ -1449,6 +1547,13 @@
public void updateRepositoryModel(String repositoryName, RepositoryModel repository,
boolean isCreate) throws GitBlitException {
Repository r = null;
+ String projectPath = StringUtils.getFirstPathElement(repository.name);
+ if (!StringUtils.isEmpty(projectPath)) {
+ if (projectPath.equalsIgnoreCase(getString(Keys.web.repositoryRootGroupName, "main"))) {
+ // strip leading group name
+ repository.name = repository.name.substring(projectPath.length() + 1);
+ }
+ }
if (isCreate) {
// ensure created repository name ends with .git
if (!repository.name.toLowerCase().endsWith(org.eclipse.jgit.lib.Constants.DOT_GIT_EXT)) {
@@ -1516,6 +1621,14 @@
rf.close();
}
}
+
+ // remove this repository from any origin model's fork list
+ if (!StringUtils.isEmpty(repository.originRepository)) {
+ RepositoryModel origin = repositoryListCache.get(repository.originRepository);
+ if (origin != null && !ArrayUtils.isEmpty(origin.forks)) {
+ origin.forks.remove(repositoryName);
+ }
+ }
// clear the cache
clearRepositoryMetadataCache(repositoryName);
@@ -1524,17 +1637,7 @@
// load repository
logger.info("edit repository " + repository.name);
- try {
- r = repositoryResolver.open(null, repository.name);
- } catch (RepositoryNotFoundException e) {
- logger.error("Repository not found", e);
- } catch (ServiceNotAuthorizedException e) {
- logger.error("Service not authorized", e);
- } catch (ServiceNotEnabledException e) {
- logger.error("Service not enabled", e);
- } catch (ServiceMayNotContinueException e) {
- logger.error("Service may not continue", e);
- }
+ r = getRepository(repository.name);
}
// update settings
@@ -1558,7 +1661,7 @@
// update repository cache
removeFromCachedRepositoryList(repositoryName);
// model will actually be replaced on next load because config is stale
- addToCachedRepositoryList(repository.name, repository);
+ addToCachedRepositoryList(repository);
}
/**
@@ -2382,7 +2485,6 @@
this.settings = settings;
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());
@@ -2528,44 +2630,45 @@
*
* @param repository
* @param user
- * @return true, if successful
+ * @return the repository model of the fork, if successful
+ * @throws GitBlitException
*/
- public boolean fork(RepositoryModel repository, UserModel user) {
+ public RepositoryModel fork(RepositoryModel repository, UserModel user) throws GitBlitException {
String cloneName = MessageFormat.format("~{0}/{1}.git", user.username, StringUtils.stripDotGit(StringUtils.getLastPathElement(repository.name)));
String fromUrl = MessageFormat.format("file://{0}/{1}", repositoriesFolder.getAbsolutePath(), repository.name);
+
+ // clone the repository
try {
- // clone the repository
JGitUtils.cloneRepository(repositoriesFolder, cloneName, fromUrl, true, null);
-
- // create a Gitblit repository model for the clone
- RepositoryModel cloneModel = repository.cloneAs(cloneName);
- cloneModel.owner = user.username;
- updateRepositoryModel(cloneName, cloneModel, false);
-
- if (AuthorizationControl.NAMED.equals(cloneModel.authorizationControl)) {
- // add the owner of the source repository to the clone's access list
- if (!StringUtils.isEmpty(repository.owner)) {
- UserModel owner = getUserModel(repository.owner);
- if (owner != null) {
- owner.repositories.add(cloneName);
- updateUserModel(owner.username, owner, false);
- }
- }
-
- // inherit origin's access lists
- List<String> users = getRepositoryUsers(repository);
- setRepositoryUsers(cloneModel, users);
-
- List<String> teams = getRepositoryTeams(repository);
- setRepositoryTeams(cloneModel, teams);
- }
-
- // add this clone to the cached model
- addToCachedRepositoryList(cloneModel.name, cloneModel);
- return true;
} catch (Exception e) {
- logger.error("failed to fork", e);
+ throw new GitBlitException(e);
}
- return false;
+
+ // create a Gitblit repository model for the clone
+ RepositoryModel cloneModel = repository.cloneAs(cloneName);
+ cloneModel.owner = user.username;
+ updateRepositoryModel(cloneName, cloneModel, false);
+
+ if (AuthorizationControl.NAMED.equals(cloneModel.authorizationControl)) {
+ // add the owner of the source repository to the clone's access list
+ if (!StringUtils.isEmpty(repository.owner)) {
+ UserModel owner = getUserModel(repository.owner);
+ if (owner != null) {
+ owner.repositories.add(cloneName);
+ updateUserModel(owner.username, owner, false);
+ }
+ }
+
+ // inherit origin's access lists
+ List<String> users = getRepositoryUsers(repository);
+ setRepositoryUsers(cloneModel, users);
+
+ List<String> teams = getRepositoryTeams(repository);
+ setRepositoryTeams(cloneModel, teams);
+ }
+
+ // add this clone to the cached model
+ addToCachedRepositoryList(cloneModel);
+ return cloneModel;
}
}
--
Gitblit v1.9.1