Search in sources :

Example 26 with RefModel

use of com.gitblit.models.RefModel in project gitblit by gitblit.

the class BranchTicketService method deleteTicketImpl.

/**
	 * Deletes a ticket from the repository.
	 *
	 * @param ticket
	 * @return true if successful
	 */
@Override
protected synchronized boolean deleteTicketImpl(RepositoryModel repository, TicketModel ticket, String deletedBy) {
    if (ticket == null) {
        throw new RuntimeException("must specify a ticket!");
    }
    boolean success = false;
    Repository db = repositoryManager.getRepository(ticket.repository);
    try {
        RefModel ticketsBranch = getTicketsBranch(db);
        if (ticketsBranch == null) {
            throw new RuntimeException(BRANCH + " does not exist!");
        }
        String ticketPath = toTicketPath(ticket.number);
        TreeWalk treeWalk = null;
        try {
            ObjectId treeId = db.resolve(BRANCH + "^{tree}");
            // Create the in-memory index of the new/updated ticket
            DirCache index = DirCache.newInCore();
            DirCacheBuilder builder = index.builder();
            // Traverse HEAD to add all other paths
            treeWalk = new TreeWalk(db);
            int hIdx = -1;
            if (treeId != null) {
                hIdx = treeWalk.addTree(treeId);
            }
            treeWalk.setRecursive(true);
            while (treeWalk.next()) {
                String path = treeWalk.getPathString();
                CanonicalTreeParser hTree = null;
                if (hIdx != -1) {
                    hTree = treeWalk.getTree(hIdx, CanonicalTreeParser.class);
                }
                if (!path.startsWith(ticketPath)) {
                    // add entries from HEAD for all other paths
                    if (hTree != null) {
                        final DirCacheEntry entry = new DirCacheEntry(path);
                        entry.setObjectId(hTree.getEntryObjectId());
                        entry.setFileMode(hTree.getEntryFileMode());
                        // add to temporary in-core index
                        builder.add(entry);
                    }
                }
            }
            // finish temporary in-core index used for this commit
            builder.finish();
            success = commitIndex(db, index, deletedBy, "- " + ticket.number);
        } catch (Throwable t) {
            log.error(MessageFormat.format("Failed to delete ticket {0,number,0} from {1}", ticket.number, db.getDirectory()), t);
        } finally {
            // release the treewalk
            if (treeWalk != null) {
                treeWalk.close();
            }
        }
    } finally {
        db.close();
    }
    return success;
}
Also used : RefModel(com.gitblit.models.RefModel) DirCacheBuilder(org.eclipse.jgit.dircache.DirCacheBuilder) DirCacheEntry(org.eclipse.jgit.dircache.DirCacheEntry) ObjectId(org.eclipse.jgit.lib.ObjectId) CanonicalTreeParser(org.eclipse.jgit.treewalk.CanonicalTreeParser) DirCache(org.eclipse.jgit.dircache.DirCache) Repository(org.eclipse.jgit.lib.Repository) TreeWalk(org.eclipse.jgit.treewalk.TreeWalk)

Example 27 with RefModel

use of com.gitblit.models.RefModel in project gitblit by gitblit.

the class BranchTicketService method getTicketsBranch.

/**
	 * Returns a RefModel for the refs/meta/gitblit/tickets branch in the repository.
	 * If the branch can not be found, null is returned.
	 *
	 * @return a refmodel for the gitblit tickets branch or null
	 */
private RefModel getTicketsBranch(Repository db) {
    List<RefModel> refs = JGitUtils.getRefs(db, "refs/");
    Ref oldRef = null;
    for (RefModel ref : refs) {
        if (ref.reference.getName().equals(BRANCH)) {
            return ref;
        } else if (ref.reference.getName().equals("refs/gitblit/tickets")) {
            oldRef = ref.reference;
        }
    }
    if (oldRef != null) {
        // rename old ref to refs/meta/gitblit/tickets
        RefRename cmd;
        try {
            cmd = db.renameRef(oldRef.getName(), BRANCH);
            cmd.setRefLogIdent(new PersonIdent("Gitblit", "gitblit@localhost"));
            cmd.setRefLogMessage("renamed " + oldRef.getName() + " => " + BRANCH);
            Result res = cmd.rename();
            switch(res) {
                case RENAMED:
                    log.info(db.getDirectory() + " " + cmd.getRefLogMessage());
                    return getTicketsBranch(db);
                default:
                    log.error("failed to rename " + oldRef.getName() + " => " + BRANCH + " (" + res.name() + ")");
            }
        } catch (IOException e) {
            log.error("failed to rename tickets branch", e);
        }
    }
    return null;
}
Also used : Ref(org.eclipse.jgit.lib.Ref) RefModel(com.gitblit.models.RefModel) PersonIdent(org.eclipse.jgit.lib.PersonIdent) IOException(java.io.IOException) RefRename(org.eclipse.jgit.lib.RefRename) Result(org.eclipse.jgit.lib.RefUpdate.Result)

Example 28 with RefModel

use of com.gitblit.models.RefModel in project gitblit by gitblit.

the class BranchTicketService method hasTicket.

/**
	 * Ensures that we have a ticket for this ticket id.
	 *
	 * @param repository
	 * @param ticketId
	 * @return true if the ticket exists
	 */
@Override
public boolean hasTicket(RepositoryModel repository, long ticketId) {
    boolean hasTicket = false;
    Repository db = repositoryManager.getRepository(repository.name);
    try {
        RefModel ticketsBranch = getTicketsBranch(db);
        if (ticketsBranch == null) {
            return false;
        }
        String ticketPath = toTicketPath(ticketId);
        RevCommit tip = JGitUtils.getCommit(db, BRANCH);
        hasTicket = !JGitUtils.getFilesInPath(db, ticketPath, tip).isEmpty();
    } finally {
        db.close();
    }
    return hasTicket;
}
Also used : Repository(org.eclipse.jgit.lib.Repository) RefModel(com.gitblit.models.RefModel) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 29 with RefModel

use of com.gitblit.models.RefModel in project gitblit by gitblit.

the class FederationPullService method pull.

/**
	 * Mirrors a repository and, optionally, the server's users, and/or
	 * configuration settings from a origin Gitblit instance.
	 *
	 * @param registration
	 * @throws Exception
	 */
private void pull(FederationModel registration) throws Exception {
    Map<String, RepositoryModel> repositories = FederationUtils.getRepositories(registration, true);
    String registrationFolder = registration.folder.toLowerCase().trim();
    // confirm valid characters in server alias
    Character c = StringUtils.findInvalidCharacter(registrationFolder);
    if (c != null) {
        logger.error(MessageFormat.format("Illegal character ''{0}'' in folder name ''{1}'' of federation registration {2}!", c, registrationFolder, registration.name));
        return;
    }
    File repositoriesFolder = gitblit.getRepositoriesFolder();
    File registrationFolderFile = new File(repositoriesFolder, registrationFolder);
    registrationFolderFile.mkdirs();
    // Clone/Pull the repository
    for (Map.Entry<String, RepositoryModel> entry : repositories.entrySet()) {
        String cloneUrl = entry.getKey();
        RepositoryModel repository = entry.getValue();
        if (!repository.hasCommits) {
            logger.warn(MessageFormat.format("Skipping federated repository {0} from {1} @ {2}. Repository is EMPTY.", repository.name, registration.name, registration.url));
            registration.updateStatus(repository, FederationPullStatus.SKIPPED);
            continue;
        }
        // Determine local repository name
        String repositoryName;
        if (StringUtils.isEmpty(registrationFolder)) {
            repositoryName = repository.name;
        } else {
            repositoryName = registrationFolder + "/" + repository.name;
        }
        if (registration.bare) {
            // bare repository, ensure .git suffix
            if (!repositoryName.toLowerCase().endsWith(DOT_GIT_EXT)) {
                repositoryName += DOT_GIT_EXT;
            }
        } else {
            // normal repository, strip .git suffix
            if (repositoryName.toLowerCase().endsWith(DOT_GIT_EXT)) {
                repositoryName = repositoryName.substring(0, repositoryName.indexOf(DOT_GIT_EXT));
            }
        }
        // confirm that the origin of any pre-existing repository matches
        // the clone url
        String fetchHead = null;
        Repository existingRepository = gitblit.getRepository(repositoryName);
        if (existingRepository == null && gitblit.isCollectingGarbage(repositoryName)) {
            logger.warn(MessageFormat.format("Skipping local repository {0}, busy collecting garbage", repositoryName));
            continue;
        }
        if (existingRepository != null) {
            StoredConfig config = existingRepository.getConfig();
            config.load();
            String origin = config.getString("remote", "origin", "url");
            RevCommit commit = JGitUtils.getCommit(existingRepository, org.eclipse.jgit.lib.Constants.FETCH_HEAD);
            if (commit != null) {
                fetchHead = commit.getName();
            }
            existingRepository.close();
            if (!origin.startsWith(registration.url)) {
                logger.warn(MessageFormat.format("Skipping federated repository {0} from {1} @ {2}. Origin does not match, consider EXCLUDING.", repository.name, registration.name, registration.url));
                registration.updateStatus(repository, FederationPullStatus.SKIPPED);
                continue;
            }
        }
        // clone/pull this repository
        CredentialsProvider credentials = new UsernamePasswordCredentialsProvider(Constants.FEDERATION_USER, registration.token);
        logger.info(MessageFormat.format("Pulling federated repository {0} from {1} @ {2}", repository.name, registration.name, registration.url));
        CloneResult result = JGitUtils.cloneRepository(registrationFolderFile, repository.name, cloneUrl, registration.bare, credentials);
        Repository r = gitblit.getRepository(repositoryName);
        RepositoryModel rm = gitblit.getRepositoryModel(repositoryName);
        repository.isFrozen = registration.mirror;
        if (result.createdRepository) {
            // default local settings
            repository.federationStrategy = FederationStrategy.EXCLUDE;
            repository.isFrozen = registration.mirror;
            repository.showRemoteBranches = !registration.mirror;
            logger.info(MessageFormat.format("     cloning {0}", repository.name));
            registration.updateStatus(repository, FederationPullStatus.MIRRORED);
        } else {
            // fetch and update
            boolean fetched = false;
            RevCommit commit = JGitUtils.getCommit(r, org.eclipse.jgit.lib.Constants.FETCH_HEAD);
            String newFetchHead = commit.getName();
            fetched = fetchHead == null || !fetchHead.equals(newFetchHead);
            if (registration.mirror) {
                // mirror
                if (fetched) {
                    // update local branches to match the remote tracking branches
                    for (RefModel ref : JGitUtils.getRemoteBranches(r, false, -1)) {
                        if (ref.displayName.startsWith("origin/")) {
                            String branch = org.eclipse.jgit.lib.Constants.R_HEADS + ref.displayName.substring(ref.displayName.indexOf('/') + 1);
                            String hash = ref.getReferencedObjectId().getName();
                            JGitUtils.setBranchRef(r, branch, hash);
                            logger.info(MessageFormat.format("     resetting {0} of {1} to {2}", branch, repository.name, hash));
                        }
                    }
                    String newHead;
                    if (StringUtils.isEmpty(repository.HEAD)) {
                        newHead = newFetchHead;
                    } else {
                        newHead = repository.HEAD;
                    }
                    JGitUtils.setHEADtoRef(r, newHead);
                    logger.info(MessageFormat.format("     resetting HEAD of {0} to {1}", repository.name, newHead));
                    registration.updateStatus(repository, FederationPullStatus.MIRRORED);
                } else {
                    // indicate no commits pulled
                    registration.updateStatus(repository, FederationPullStatus.NOCHANGE);
                }
            } else {
                // non-mirror
                if (fetched) {
                    // indicate commits pulled to origin/master
                    registration.updateStatus(repository, FederationPullStatus.PULLED);
                } else {
                    // indicate no commits pulled
                    registration.updateStatus(repository, FederationPullStatus.NOCHANGE);
                }
            }
            // preserve local settings
            repository.isFrozen = rm.isFrozen;
            repository.federationStrategy = rm.federationStrategy;
            // merge federation sets
            Set<String> federationSets = new HashSet<String>();
            if (rm.federationSets != null) {
                federationSets.addAll(rm.federationSets);
            }
            if (repository.federationSets != null) {
                federationSets.addAll(repository.federationSets);
            }
            repository.federationSets = new ArrayList<String>(federationSets);
            // merge indexed branches
            Set<String> indexedBranches = new HashSet<String>();
            if (rm.indexedBranches != null) {
                indexedBranches.addAll(rm.indexedBranches);
            }
            if (repository.indexedBranches != null) {
                indexedBranches.addAll(repository.indexedBranches);
            }
            repository.indexedBranches = new ArrayList<String>(indexedBranches);
        }
        // only repositories that are actually _cloned_ from the origin
        // Gitblit repository are marked as federated. If the origin
        // is from somewhere else, these repositories are not considered
        // "federated" repositories.
        repository.isFederated = cloneUrl.startsWith(registration.url);
        gitblit.updateConfiguration(r, repository);
        r.close();
    }
    IUserService userService = null;
    try {
        // Pull USERS
        // TeamModels are automatically pulled because they are contained
        // within the UserModel. The UserService creates unknown teams
        // and updates existing teams.
        Collection<UserModel> users = FederationUtils.getUsers(registration);
        if (users != null && users.size() > 0) {
            File realmFile = new File(registrationFolderFile, registration.name + "_users.conf");
            realmFile.delete();
            userService = new ConfigUserService(realmFile);
            for (UserModel user : users) {
                userService.updateUserModel(user.username, user);
                // the user accounts of this Gitblit instance
                if (registration.mergeAccounts) {
                    // repositories are stored within subfolders
                    if (!StringUtils.isEmpty(registrationFolder)) {
                        if (user.permissions != null) {
                            // pulling from >= 1.2 version
                            Map<String, AccessPermission> copy = new HashMap<String, AccessPermission>(user.permissions);
                            user.permissions.clear();
                            for (Map.Entry<String, AccessPermission> entry : copy.entrySet()) {
                                user.setRepositoryPermission(registrationFolder + "/" + entry.getKey(), entry.getValue());
                            }
                        } else {
                            // pulling from <= 1.1 version
                            List<String> permissions = new ArrayList<String>(user.repositories);
                            user.repositories.clear();
                            for (String permission : permissions) {
                                user.addRepositoryPermission(registrationFolder + "/" + permission);
                            }
                        }
                    }
                    // insert new user or update local user
                    UserModel localUser = gitblit.getUserModel(user.username);
                    if (localUser == null) {
                        // create new local user
                        gitblit.addUser(user);
                    } else {
                        // update repository permissions of local user
                        if (user.permissions != null) {
                            // pulling from >= 1.2 version
                            Map<String, AccessPermission> copy = new HashMap<String, AccessPermission>(user.permissions);
                            for (Map.Entry<String, AccessPermission> entry : copy.entrySet()) {
                                localUser.setRepositoryPermission(entry.getKey(), entry.getValue());
                            }
                        } else {
                            // pulling from <= 1.1 version
                            for (String repository : user.repositories) {
                                localUser.addRepositoryPermission(repository);
                            }
                        }
                        localUser.password = user.password;
                        localUser.canAdmin = user.canAdmin;
                        gitblit.reviseUser(localUser.username, localUser);
                    }
                    for (String teamname : gitblit.getAllTeamNames()) {
                        TeamModel team = gitblit.getTeamModel(teamname);
                        if (user.isTeamMember(teamname) && !team.hasUser(user.username)) {
                            // new team member
                            team.addUser(user.username);
                            gitblit.updateTeamModel(teamname, team);
                        } else if (!user.isTeamMember(teamname) && team.hasUser(user.username)) {
                            // remove team member
                            team.removeUser(user.username);
                            gitblit.updateTeamModel(teamname, team);
                        }
                        // update team repositories
                        TeamModel remoteTeam = user.getTeam(teamname);
                        if (remoteTeam != null) {
                            if (remoteTeam.permissions != null) {
                                // pulling from >= 1.2
                                for (Map.Entry<String, AccessPermission> entry : remoteTeam.permissions.entrySet()) {
                                    team.setRepositoryPermission(entry.getKey(), entry.getValue());
                                }
                                gitblit.updateTeamModel(teamname, team);
                            } else if (!ArrayUtils.isEmpty(remoteTeam.repositories)) {
                                // pulling from <= 1.1
                                team.addRepositoryPermissions(remoteTeam.repositories);
                                gitblit.updateTeamModel(teamname, team);
                            }
                        }
                    }
                }
            }
        }
    } catch (ForbiddenException e) {
    // ignore forbidden exceptions
    } catch (IOException e) {
        logger.warn(MessageFormat.format("Failed to retrieve USERS from federated gitblit ({0} @ {1})", registration.name, registration.url), e);
    }
    try {
        // mailing lists or push scripts without specifying users.
        if (userService != null) {
            Collection<TeamModel> teams = FederationUtils.getTeams(registration);
            if (teams != null && teams.size() > 0) {
                for (TeamModel team : teams) {
                    userService.updateTeamModel(team);
                }
            }
        }
    } catch (ForbiddenException e) {
    // ignore forbidden exceptions
    } catch (IOException e) {
        logger.warn(MessageFormat.format("Failed to retrieve TEAMS from federated gitblit ({0} @ {1})", registration.name, registration.url), e);
    }
    try {
        // Pull SETTINGS
        Map<String, String> settings = FederationUtils.getSettings(registration);
        if (settings != null && settings.size() > 0) {
            Properties properties = new Properties();
            properties.putAll(settings);
            FileOutputStream os = new FileOutputStream(new File(registrationFolderFile, registration.name + "_" + Constants.PROPERTIES_FILE));
            properties.store(os, null);
            os.close();
        }
    } catch (ForbiddenException e) {
    // ignore forbidden exceptions
    } catch (IOException e) {
        logger.warn(MessageFormat.format("Failed to retrieve SETTINGS from federated gitblit ({0} @ {1})", registration.name, registration.url), e);
    }
    try {
        // Pull SCRIPTS
        Map<String, String> scripts = FederationUtils.getScripts(registration);
        if (scripts != null && scripts.size() > 0) {
            for (Map.Entry<String, String> script : scripts.entrySet()) {
                String scriptName = script.getKey();
                if (scriptName.endsWith(".groovy")) {
                    scriptName = scriptName.substring(0, scriptName.indexOf(".groovy"));
                }
                File file = new File(registrationFolderFile, registration.name + "_" + scriptName + ".groovy");
                FileUtils.writeContent(file, script.getValue());
            }
        }
    } catch (ForbiddenException e) {
    // ignore forbidden exceptions
    } catch (IOException e) {
        logger.warn(MessageFormat.format("Failed to retrieve SCRIPTS from federated gitblit ({0} @ {1})", registration.name, registration.url), e);
    }
}
Also used : RefModel(com.gitblit.models.RefModel) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) RepositoryModel(com.gitblit.models.RepositoryModel) Properties(java.util.Properties) StoredConfig(org.eclipse.jgit.lib.StoredConfig) UserModel(com.gitblit.models.UserModel) TeamModel(com.gitblit.models.TeamModel) RevCommit(org.eclipse.jgit.revwalk.RevCommit) HashSet(java.util.HashSet) UsernamePasswordCredentialsProvider(org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider) ForbiddenException(com.gitblit.GitBlitException.ForbiddenException) ConfigUserService(com.gitblit.ConfigUserService) AccessPermission(com.gitblit.Constants.AccessPermission) UsernamePasswordCredentialsProvider(org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider) CredentialsProvider(org.eclipse.jgit.transport.CredentialsProvider) IOException(java.io.IOException) CloneResult(com.gitblit.utils.JGitUtils.CloneResult) Repository(org.eclipse.jgit.lib.Repository) IUserService(com.gitblit.IUserService) FileOutputStream(java.io.FileOutputStream) File(java.io.File) HashMap(java.util.HashMap) Map(java.util.Map)

Example 30 with RefModel

use of com.gitblit.models.RefModel in project gitblit by gitblit.

the class RepositoryManager method configureCommitCache.

protected void configureCommitCache() {
    final int daysToCache = settings.getInteger(Keys.web.activityCacheDays, 14);
    if (daysToCache <= 0) {
        logger.info("Commit cache is disabled");
        return;
    }
    logger.info(MessageFormat.format("Preparing {0} day commit cache...", daysToCache));
    CommitCache.instance().setCacheDays(daysToCache);
    Thread loader = new Thread() {

        @Override
        public void run() {
            long start = System.nanoTime();
            long repoCount = 0;
            long commitCount = 0;
            Date cutoff = CommitCache.instance().getCutoffDate();
            for (String repositoryName : getRepositoryList()) {
                RepositoryModel model = getRepositoryModel(repositoryName);
                if (model != null && model.hasCommits && model.lastChange.after(cutoff)) {
                    repoCount++;
                    Repository repository = getRepository(repositoryName);
                    for (RefModel ref : JGitUtils.getLocalBranches(repository, true, -1)) {
                        if (!ref.getDate().after(cutoff)) {
                            // branch not recently updated
                            continue;
                        }
                        List<?> commits = CommitCache.instance().getCommits(repositoryName, repository, ref.getName());
                        if (commits.size() > 0) {
                            logger.info(MessageFormat.format("  cached {0} commits for {1}:{2}", commits.size(), repositoryName, ref.getName()));
                            commitCount += commits.size();
                        }
                    }
                    repository.close();
                }
            }
            logger.info(MessageFormat.format("built {0} day commit cache of {1} commits across {2} repositories in {3} msecs", daysToCache, commitCount, repoCount, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)));
        }
    };
    loader.setName("CommitCacheLoader");
    loader.setDaemon(true);
    loader.start();
}
Also used : Repository(org.eclipse.jgit.lib.Repository) RefModel(com.gitblit.models.RefModel) RepositoryModel(com.gitblit.models.RepositoryModel) Date(java.util.Date)

Aggregations

RefModel (com.gitblit.models.RefModel)32 ArrayList (java.util.ArrayList)18 ObjectId (org.eclipse.jgit.lib.ObjectId)13 Repository (org.eclipse.jgit.lib.Repository)12 RevCommit (org.eclipse.jgit.revwalk.RevCommit)12 List (java.util.List)10 IOException (java.io.IOException)8 HashMap (java.util.HashMap)8 RepositoryModel (com.gitblit.models.RepositoryModel)6 RepositoryCommit (com.gitblit.models.RepositoryCommit)5 UserModel (com.gitblit.models.UserModel)5 Date (java.util.Date)5 TreeSet (java.util.TreeSet)4 RevWalk (org.eclipse.jgit.revwalk.RevWalk)4 DateFormat (java.text.DateFormat)3 SimpleDateFormat (java.text.SimpleDateFormat)3 IndexWriter (org.apache.lucene.index.IndexWriter)3 Ref (org.eclipse.jgit.lib.Ref)3 GitBlitException (com.gitblit.GitBlitException)2 PathChangeModel (com.gitblit.models.PathModel.PathChangeModel)2