Search in sources :

Example 1 with DeletedResourceConflict

use of de.catma.project.conflict.DeletedResourceConflict in project catma by forTEXT.

the class JGitRepoManager method resolveRootConflicts.

@Override
public Collection<DeletedResourceConflict> resolveRootConflicts(String projectId, CredentialsProvider credentialsProvider) throws IOException {
    if (!isAttached()) {
        throw new IllegalStateException("Can't call `resolveRootConflicts` on a detached instance");
    }
    List<DeletedResourceConflict> deletedResourceConflicts = new ArrayList<>();
    DirCache dirCache = gitApi.getRepository().lockDirCache();
    try {
        if (dirCache.hasUnmergedPaths()) {
            Status status = gitApi.status().call();
            for (String conflictingSubmodule : status.getConflicting()) {
                StageState conflictState = status.getConflictingStageState().get(conflictingSubmodule);
                switch(conflictState) {
                    case BOTH_MODIFIED:
                        {
                            // get the base entry from where the branches diverge, the common ancestor version
                            int baseIdx = dirCache.findEntry(conflictingSubmodule);
                            DirCacheEntry baseEntry = dirCache.getEntry(baseIdx);
                            // get their version, the being-merged in version
                            DirCacheEntry theirEntry = dirCache.getEntry(baseIdx + 2);
                            if (theirEntry.getPathString().equals(conflictingSubmodule) && theirEntry.getStage() == 3) {
                                // we try to make sure that their version is included (merged) in the latest version
                                // of this submodule
                                ensureLatestSubmoduleRevision(baseEntry, theirEntry, conflictingSubmodule, credentialsProvider);
                                try (Repository subModuleRepo = SubmoduleWalk.getSubmoduleRepository(this.gitApi.getRepository(), conflictingSubmodule)) {
                                    // now get the current submodule revision (which includes the merge)
                                    ObjectId subModuleHeadRevision = subModuleRepo.resolve(Constants.HEAD);
                                    baseEntry.setObjectId(subModuleHeadRevision);
                                }
                                break;
                            } else {
                                Logger.getLogger(this.getClass().getName()).severe(String.format("Cannot resolve root conflict for submodule %1$s expected a 'theirs'-stage-3 commit entry but found none!", conflictingSubmodule));
                                throw new CommitMissingException("Failed to synchronize the Project because of an unexpected merge conflict, " + "please contact the system administrator!");
                            }
                        }
                    case DELETED_BY_THEM:
                        {
                            String ourTreeName = "refs/heads/master";
                            RevCommit ourCommit = gitApi.log().add(gitApi.getRepository().resolve(ourTreeName)).addPath(conflictingSubmodule).call().iterator().next();
                            String ourLastCommitMsg = ourCommit.getFullMessage();
                            String theirTreeName = "refs/remotes/origin/master";
                            RevCommit theirCommit = gitApi.log().add(gitApi.getRepository().resolve(theirTreeName)).addPath(conflictingSubmodule).call().iterator().next();
                            if (theirCommit == null) {
                                // couldn't find their commit based on the conflicting submodule path
                                // we try to find it based on the DOT_GIT_MODULES file and the resourceId in the commit message
                                Iterator<RevCommit> remoteCommitIterator = gitApi.log().add(gitApi.getRepository().resolve(theirTreeName)).addPath(Constants.DOT_GIT_MODULES).call().iterator();
                                String resourceId = conflictingSubmodule.substring(conflictingSubmodule.indexOf('/') + 1);
                                while (remoteCommitIterator.hasNext()) {
                                    RevCommit revCommit = remoteCommitIterator.next();
                                    if (revCommit.getFullMessage().contains(resourceId)) {
                                        theirCommit = revCommit;
                                        break;
                                    }
                                }
                            }
                            String theirLastCommitMsg = "no commit found";
                            if (theirCommit != null) {
                                theirLastCommitMsg = theirCommit.getFullMessage();
                            }
                            deletedResourceConflicts.add(new DeletedResourceConflict(projectId, conflictingSubmodule, ourCommit.getName(), ourLastCommitMsg, theirCommit != null ? theirCommit.getName() : "", theirLastCommitMsg, theirCommit != null ? theirCommit.getCommitterIdent().getName() : "", true));
                            break;
                        }
                    case DELETED_BY_US:
                        {
                            String ourTreeName = "refs/heads/master";
                            RevCommit ourCommit = gitApi.log().add(gitApi.getRepository().resolve(ourTreeName)).addPath(conflictingSubmodule).call().iterator().next();
                            String ourLastCommitMsg = ourCommit.getFullMessage();
                            String theirTreeName = "refs/remotes/origin/master";
                            RevCommit theirCommit = gitApi.log().add(gitApi.getRepository().resolve(theirTreeName)).addPath(conflictingSubmodule).call().iterator().next();
                            String theirLastCommitMsg = theirCommit.getFullMessage();
                            deletedResourceConflicts.add(new DeletedResourceConflict(projectId, conflictingSubmodule, ourCommit.getName(), ourLastCommitMsg, theirCommit.getName(), theirLastCommitMsg, theirCommit.getCommitterIdent().getName(), false));
                            break;
                        }
                    default:
                        {
                            Logger.getLogger(this.getClass().getName()).severe(String.format("Cannot resolve root conflict for submodule %1$s %2$s not supported yet!", conflictingSubmodule, conflictState.name()));
                            throw new CommitMissingException("Failed to synchronize the Project because of an unexpected merge conflict, " + "please contact the system administrator!");
                        }
                }
            }
            dirCache.write();
            dirCache.commit();
        } else {
            dirCache.unlock();
        }
    } catch (Exception e) {
        try {
            dirCache.unlock();
        } catch (Exception e2) {
            e2.printStackTrace();
        }
        throw new IOException("Failed to resolve root conflicts", e);
    }
    return deletedResourceConflicts;
}
Also used : Status(org.eclipse.jgit.api.Status) SubmoduleStatus(org.eclipse.jgit.submodule.SubmoduleStatus) CommitMissingException(de.catma.repository.git.CommitMissingException) DirCacheEntry(org.eclipse.jgit.dircache.DirCacheEntry) ObjectId(org.eclipse.jgit.lib.ObjectId) DeletedResourceConflict(de.catma.project.conflict.DeletedResourceConflict) ArrayList(java.util.ArrayList) IOException(java.io.IOException) CommitMissingException(de.catma.repository.git.CommitMissingException) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) IOException(java.io.IOException) NoFilepatternException(org.eclipse.jgit.api.errors.NoFilepatternException) JGitInternalException(org.eclipse.jgit.api.errors.JGitInternalException) DirCache(org.eclipse.jgit.dircache.DirCache) Repository(org.eclipse.jgit.lib.Repository) StageState(org.eclipse.jgit.lib.IndexDiff.StageState) Iterator(java.util.Iterator) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Aggregations

DeletedResourceConflict (de.catma.project.conflict.DeletedResourceConflict)1 CommitMissingException (de.catma.repository.git.CommitMissingException)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 Iterator (java.util.Iterator)1 Status (org.eclipse.jgit.api.Status)1 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)1 JGitInternalException (org.eclipse.jgit.api.errors.JGitInternalException)1 NoFilepatternException (org.eclipse.jgit.api.errors.NoFilepatternException)1 DirCache (org.eclipse.jgit.dircache.DirCache)1 DirCacheEntry (org.eclipse.jgit.dircache.DirCacheEntry)1 ConfigInvalidException (org.eclipse.jgit.errors.ConfigInvalidException)1 StageState (org.eclipse.jgit.lib.IndexDiff.StageState)1 ObjectId (org.eclipse.jgit.lib.ObjectId)1 Repository (org.eclipse.jgit.lib.Repository)1 RevCommit (org.eclipse.jgit.revwalk.RevCommit)1 SubmoduleStatus (org.eclipse.jgit.submodule.SubmoduleStatus)1