Search in sources :

Example 1 with RepositoryLifeCycleListener

use of com.gitblit.extensions.RepositoryLifeCycleListener in project gitblit by gitblit.

the class RepositoryManager method updateRepositoryModel.

/**
	 * Creates/updates the repository model keyed by repositoryName. Saves all
	 * repository settings in .git/config. This method allows for renaming
	 * repositories and will update user access permissions accordingly.
	 *
	 * All repositories created by this method are bare and automatically have
	 * .git appended to their names, which is the standard convention for bare
	 * repositories.
	 *
	 * @param repositoryName
	 * @param repository
	 * @param isCreate
	 * @throws GitBlitException
	 */
@Override
public void updateRepositoryModel(String repositoryName, RepositoryModel repository, boolean isCreate) throws GitBlitException {
    if (isCollectingGarbage(repositoryName)) {
        throw new GitBlitException(MessageFormat.format("sorry, Gitblit is busy collecting garbage in {0}", repositoryName));
    }
    Repository r = null;
    String projectPath = StringUtils.getFirstPathElement(repository.name);
    if (!StringUtils.isEmpty(projectPath)) {
        if (projectPath.equalsIgnoreCase(settings.getString(Keys.web.repositoryRootGroupName, "main"))) {
            // strip leading group name
            repository.name = repository.name.substring(projectPath.length() + 1);
        }
    }
    boolean isRename = false;
    if (isCreate) {
        // ensure created repository name ends with .git
        if (!repository.name.toLowerCase().endsWith(org.eclipse.jgit.lib.Constants.DOT_GIT_EXT)) {
            repository.name += org.eclipse.jgit.lib.Constants.DOT_GIT_EXT;
        }
        if (hasRepository(repository.name)) {
            throw new GitBlitException(MessageFormat.format("Can not create repository ''{0}'' because it already exists.", repository.name));
        }
        // create repository
        logger.info("create repository " + repository.name);
        String shared = settings.getString(Keys.git.createRepositoriesShared, "FALSE");
        r = JGitUtils.createRepository(repositoriesFolder, repository.name, shared);
    } else {
        // rename repository
        isRename = !repositoryName.equalsIgnoreCase(repository.name);
        if (isRename) {
            if (!repository.name.toLowerCase().endsWith(org.eclipse.jgit.lib.Constants.DOT_GIT_EXT)) {
                repository.name += org.eclipse.jgit.lib.Constants.DOT_GIT_EXT;
            }
            if (new File(repositoriesFolder, repository.name).exists()) {
                throw new GitBlitException(MessageFormat.format("Failed to rename ''{0}'' because ''{1}'' already exists.", repositoryName, repository.name));
            }
            close(repositoryName);
            File folder = new File(repositoriesFolder, repositoryName);
            File destFolder = new File(repositoriesFolder, repository.name);
            if (destFolder.exists()) {
                throw new GitBlitException(MessageFormat.format("Can not rename repository ''{0}'' to ''{1}'' because ''{1}'' already exists.", repositoryName, repository.name));
            }
            File parentFile = destFolder.getParentFile();
            if (!parentFile.exists() && !parentFile.mkdirs()) {
                throw new GitBlitException(MessageFormat.format("Failed to create folder ''{0}''", parentFile.getAbsolutePath()));
            }
            if (!folder.renameTo(destFolder)) {
                throw new GitBlitException(MessageFormat.format("Failed to rename repository ''{0}'' to ''{1}''.", repositoryName, repository.name));
            }
            // rename the roles
            if (!userManager.renameRepositoryRole(repositoryName, repository.name)) {
                throw new GitBlitException(MessageFormat.format("Failed to rename repository permissions ''{0}'' to ''{1}''.", repositoryName, repository.name));
            }
            // rename fork origins in their configs
            if (!ArrayUtils.isEmpty(repository.forks)) {
                for (String fork : repository.forks) {
                    Repository rf = getRepository(fork);
                    try {
                        StoredConfig config = rf.getConfig();
                        String origin = config.getString("remote", "origin", "url");
                        origin = origin.replace(repositoryName, repository.name);
                        config.setString("remote", "origin", "url", origin);
                        config.setString(Constants.CONFIG_GITBLIT, null, "originRepository", repository.name);
                        config.save();
                    } catch (Exception e) {
                        logger.error("Failed to update repository fork config for " + fork, e);
                    }
                    rf.close();
                }
            }
            // update this repository's origin's fork list
            if (!StringUtils.isEmpty(repository.originRepository)) {
                String originKey = getRepositoryKey(repository.originRepository);
                RepositoryModel origin = repositoryListCache.get(originKey);
                if (origin != null && !ArrayUtils.isEmpty(origin.forks)) {
                    origin.forks.remove(repositoryName);
                    origin.forks.add(repository.name);
                }
            }
            // clear the cache
            clearRepositoryMetadataCache(repositoryName);
            repository.resetDisplayName();
        }
        // load repository
        logger.info("edit repository " + repository.name);
        r = getRepository(repository.name);
    }
    // update settings
    if (r != null) {
        updateConfiguration(r, repository);
        // Update the description file
        File descFile = new File(r.getDirectory(), "description");
        if (repository.description != null) {
            com.gitblit.utils.FileUtils.writeContent(descFile, repository.description);
        } else if (descFile.exists() && !descFile.isDirectory()) {
            descFile.delete();
        }
        // only update symbolic head if it changes
        String currentRef = JGitUtils.getHEADRef(r);
        if (!StringUtils.isEmpty(repository.HEAD) && !repository.HEAD.equals(currentRef)) {
            logger.info(MessageFormat.format("Relinking {0} HEAD from {1} to {2}", repository.name, currentRef, repository.HEAD));
            if (JGitUtils.setHEADtoRef(r, repository.HEAD)) {
                // clear the cache
                clearRepositoryMetadataCache(repository.name);
            }
        }
        // Adjust permissions in case we updated the config files
        JGitUtils.adjustSharedPerm(new File(r.getDirectory().getAbsolutePath(), "config"), settings.getString(Keys.git.createRepositoriesShared, "FALSE"));
        JGitUtils.adjustSharedPerm(new File(r.getDirectory().getAbsolutePath(), "HEAD"), settings.getString(Keys.git.createRepositoriesShared, "FALSE"));
        // close the repository object
        r.close();
    }
    // update repository cache
    removeFromCachedRepositoryList(repositoryName);
    // model will actually be replaced on next load because config is stale
    addToCachedRepositoryList(repository);
    if (isCreate && pluginManager != null) {
        for (RepositoryLifeCycleListener listener : pluginManager.getExtensions(RepositoryLifeCycleListener.class)) {
            try {
                listener.onCreation(repository);
            } catch (Throwable t) {
                logger.error(String.format("failed to call plugin onCreation %s", repositoryName), t);
            }
        }
    } else if (isRename && pluginManager != null) {
        for (RepositoryLifeCycleListener listener : pluginManager.getExtensions(RepositoryLifeCycleListener.class)) {
            try {
                listener.onRename(repositoryName, repository);
            } catch (Throwable t) {
                logger.error(String.format("failed to call plugin onRename %s", repositoryName), t);
            }
        }
    }
}
Also used : StoredConfig(org.eclipse.jgit.lib.StoredConfig) Repository(org.eclipse.jgit.lib.Repository) GitBlitException(com.gitblit.GitBlitException) RepositoryModel(com.gitblit.models.RepositoryModel) RepositoryLifeCycleListener(com.gitblit.extensions.RepositoryLifeCycleListener) File(java.io.File) URISyntaxException(java.net.URISyntaxException) GitBlitException(com.gitblit.GitBlitException) IOException(java.io.IOException)

Example 2 with RepositoryLifeCycleListener

use of com.gitblit.extensions.RepositoryLifeCycleListener in project gitblit by gitblit.

the class RepositoryManager method deleteRepository.

/**
	 * Deletes the repository from the file system and removes the repository
	 * permission from all repository users.
	 *
	 * @param repositoryName
	 * @return true if successful
	 */
@Override
public boolean deleteRepository(String repositoryName) {
    RepositoryModel repository = getRepositoryModel(repositoryName);
    if (!canDelete(repository)) {
        logger.warn("Attempt to delete {} rejected!", repositoryName);
        return false;
    }
    try {
        close(repositoryName);
        // clear the repository cache
        clearRepositoryMetadataCache(repositoryName);
        RepositoryModel model = removeFromCachedRepositoryList(repositoryName);
        if (model != null && !ArrayUtils.isEmpty(model.forks)) {
            resetRepositoryListCache();
        }
        File folder = new File(repositoriesFolder, repositoryName);
        if (folder.exists() && folder.isDirectory()) {
            FileUtils.delete(folder, FileUtils.RECURSIVE | FileUtils.RETRY);
            if (userManager.deleteRepositoryRole(repositoryName)) {
                logger.info(MessageFormat.format("Repository \"{0}\" deleted", repositoryName));
                if (pluginManager != null) {
                    for (RepositoryLifeCycleListener listener : pluginManager.getExtensions(RepositoryLifeCycleListener.class)) {
                        try {
                            listener.onDeletion(repository);
                        } catch (Throwable t) {
                            logger.error(String.format("failed to call plugin onDeletion %s", repositoryName), t);
                        }
                    }
                }
                return true;
            }
        }
    } catch (Throwable t) {
        logger.error(MessageFormat.format("Failed to delete repository {0}", repositoryName), t);
    }
    return false;
}
Also used : RepositoryModel(com.gitblit.models.RepositoryModel) RepositoryLifeCycleListener(com.gitblit.extensions.RepositoryLifeCycleListener) File(java.io.File)

Example 3 with RepositoryLifeCycleListener

use of com.gitblit.extensions.RepositoryLifeCycleListener in project gitblit by gitblit.

the class GitblitManager method fork.

/*
	 * IGITBLIT
	 */
/**
	 * Creates a personal fork of the specified repository. The clone is view
	 * restricted by default and the owner of the source repository is given
	 * access to the clone.
	 *
	 * @param repository
	 * @param user
	 * @return the repository model of the fork, if successful
	 * @throws GitBlitException
	 */
@Override
public RepositoryModel fork(RepositoryModel repository, UserModel user) throws GitBlitException {
    String cloneName = MessageFormat.format("{0}/{1}.git", user.getPersonalPath(), StringUtils.stripDotGit(StringUtils.getLastPathElement(repository.name)));
    String fromUrl = MessageFormat.format("file://{0}/{1}", repositoryManager.getRepositoriesFolder().getAbsolutePath(), repository.name);
    // clone the repository
    try {
        Repository canonical = getRepository(repository.name);
        File folder = new File(repositoryManager.getRepositoriesFolder(), cloneName);
        CloneCommand clone = new CloneCommand();
        clone.setBare(true);
        // fetch branches with exclusions
        Collection<Ref> branches = canonical.getRefDatabase().getRefs(Constants.R_HEADS).values();
        List<String> branchesToClone = new ArrayList<String>();
        for (Ref branch : branches) {
            String name = branch.getName();
            if (name.startsWith(Constants.R_TICKET)) {
                // exclude ticket branches
                continue;
            }
            branchesToClone.add(name);
        }
        clone.setBranchesToClone(branchesToClone);
        clone.setURI(fromUrl);
        clone.setDirectory(folder);
        Git git = clone.call();
        // fetch tags
        FetchCommand fetch = git.fetch();
        fetch.setRefSpecs(new RefSpec("+refs/tags/*:refs/tags/*"));
        fetch.call();
        git.getRepository().close();
    } catch (Exception e) {
        throw new GitBlitException(e);
    }
    // create a Gitblit repository model for the clone
    RepositoryModel cloneModel = repository.cloneAs(cloneName);
    // owner has REWIND/RW+ permissions
    cloneModel.addOwner(user.username);
    // is not lower than the source repository  (issue-495/ticket-167)
    if (repository.accessRestriction.exceeds(cloneModel.accessRestriction)) {
        cloneModel.accessRestriction = repository.accessRestriction;
    }
    repositoryManager.updateRepositoryModel(cloneName, cloneModel, false);
    // add the owner of the source repository to the clone's access list
    if (!ArrayUtils.isEmpty(repository.owners)) {
        for (String owner : repository.owners) {
            UserModel originOwner = userManager.getUserModel(owner);
            if (originOwner != null && !originOwner.canClone(cloneModel)) {
                // origin owner can't yet clone fork, grant explicit clone access
                originOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE);
                reviseUser(originOwner.username, originOwner);
            }
        }
    }
    // grant origin's user list clone permission to fork
    List<String> users = repositoryManager.getRepositoryUsers(repository);
    List<UserModel> cloneUsers = new ArrayList<UserModel>();
    for (String name : users) {
        if (!name.equalsIgnoreCase(user.username)) {
            UserModel cloneUser = userManager.getUserModel(name);
            if (cloneUser.canClone(repository) && !cloneUser.canClone(cloneModel)) {
                // origin user can't yet clone fork, grant explicit clone access
                cloneUser.setRepositoryPermission(cloneName, AccessPermission.CLONE);
            }
            cloneUsers.add(cloneUser);
        }
    }
    userManager.updateUserModels(cloneUsers);
    // grant origin's team list clone permission to fork
    List<String> teams = repositoryManager.getRepositoryTeams(repository);
    List<TeamModel> cloneTeams = new ArrayList<TeamModel>();
    for (String name : teams) {
        TeamModel cloneTeam = userManager.getTeamModel(name);
        if (cloneTeam.canClone(repository) && !cloneTeam.canClone(cloneModel)) {
            // origin team can't yet clone fork, grant explicit clone access
            cloneTeam.setRepositoryPermission(cloneName, AccessPermission.CLONE);
        }
        cloneTeams.add(cloneTeam);
    }
    userManager.updateTeamModels(cloneTeams);
    // add this clone to the cached model
    repositoryManager.addToCachedRepositoryList(cloneModel);
    if (pluginManager != null) {
        for (RepositoryLifeCycleListener listener : pluginManager.getExtensions(RepositoryLifeCycleListener.class)) {
            try {
                listener.onFork(repository, cloneModel);
            } catch (Throwable t) {
                logger.error(String.format("failed to call plugin onFork %s", repository.name), t);
            }
        }
    }
    return cloneModel;
}
Also used : CloneCommand(org.eclipse.jgit.api.CloneCommand) ArrayList(java.util.ArrayList) GitBlitException(com.gitblit.GitBlitException) RepositoryModel(com.gitblit.models.RepositoryModel) JsonIOException(com.google.gson.JsonIOException) GitBlitException(com.gitblit.GitBlitException) JsonSyntaxException(com.google.gson.JsonSyntaxException) IOException(java.io.IOException) UserModel(com.gitblit.models.UserModel) Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) Git(org.eclipse.jgit.api.Git) RefSpec(org.eclipse.jgit.transport.RefSpec) TeamModel(com.gitblit.models.TeamModel) FetchCommand(org.eclipse.jgit.api.FetchCommand) RepositoryLifeCycleListener(com.gitblit.extensions.RepositoryLifeCycleListener) File(java.io.File)

Aggregations

RepositoryLifeCycleListener (com.gitblit.extensions.RepositoryLifeCycleListener)3 RepositoryModel (com.gitblit.models.RepositoryModel)3 File (java.io.File)3 GitBlitException (com.gitblit.GitBlitException)2 IOException (java.io.IOException)2 Repository (org.eclipse.jgit.lib.Repository)2 TeamModel (com.gitblit.models.TeamModel)1 UserModel (com.gitblit.models.UserModel)1 JsonIOException (com.google.gson.JsonIOException)1 JsonSyntaxException (com.google.gson.JsonSyntaxException)1 URISyntaxException (java.net.URISyntaxException)1 ArrayList (java.util.ArrayList)1 CloneCommand (org.eclipse.jgit.api.CloneCommand)1 FetchCommand (org.eclipse.jgit.api.FetchCommand)1 Git (org.eclipse.jgit.api.Git)1 Ref (org.eclipse.jgit.lib.Ref)1 StoredConfig (org.eclipse.jgit.lib.StoredConfig)1 RefSpec (org.eclipse.jgit.transport.RefSpec)1