List of usage examples for org.eclipse.jgit.dircache DirCacheEntry STAGE_2
int STAGE_2
To view the source code for org.eclipse.jgit.dircache DirCacheEntry STAGE_2.
Click Source Link
From source file:com.itemis.maven.plugins.unleash.scm.providers.merge.UnleashGitMerger.java
License:Eclipse Distribution License
/** * Processes one path and tries to merge. This method will do all do all * trivial (not content) merges and will also detect if a merge will fail. * The merge will fail when one of the following is true * <ul>//w w w .jav a 2 s . c o m * <li>the index entry does not match the entry in ours. When merging one * branch into the current HEAD, ours will point to HEAD and theirs will * point to the other branch. It is assumed that the index matches the HEAD * because it will only not match HEAD if it was populated before the merge * operation. But the merge commit should not accidentally contain * modifications done before the merge. Check the <a href= * "http://www.kernel.org/pub/software/scm/git/docs/git-read-tree.html#_3_way_merge" * >git read-tree</a> documentation for further explanations.</li> * <li>A conflict was detected and the working-tree file is dirty. When a * conflict is detected the content-merge algorithm will try to write a * merged version into the working-tree. If the file is dirty we would * override unsaved data.</li> * </ul> * * @param base * the common base for ours and theirs * @param ours * the ours side of the merge. When merging a branch into the * HEAD ours will point to HEAD * @param theirs * the theirs side of the merge. When merging a branch into the * current HEAD theirs will point to the branch which is merged * into HEAD. * @param index * the index entry * @param work * the file in the working tree * @param ignoreConflicts * see * {@link UnleashGitMerger#mergeTrees(AbstractTreeIterator, RevTree, RevTree, boolean)} * @return <code>false</code> if the merge will fail because the index entry * didn't match ours or the working-dir file was dirty and a * conflict occurred * @throws MissingObjectException * @throws IncorrectObjectTypeException * @throws CorruptObjectException * @throws IOException * @since 3.5 */ @Override protected boolean processEntry(CanonicalTreeParser base, CanonicalTreeParser ours, CanonicalTreeParser theirs, DirCacheBuildIterator index, WorkingTreeIterator work, boolean ignoreConflicts) throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException, IOException { this.enterSubtree = true; final int modeO = this.tw.getRawMode(T_OURS); final int modeT = this.tw.getRawMode(T_THEIRS); final int modeB = this.tw.getRawMode(T_BASE); if (modeO == 0 && modeT == 0 && modeB == 0) { // File is either untracked or new, staged but uncommitted return true; } if (isIndexDirty()) { return false; } DirCacheEntry ourDce = null; if (index == null || index.getDirCacheEntry() == null) { // create a fake DCE, but only if ours is valid. ours is kept only // in case it is valid, so a null ourDce is ok in all other cases. if (nonTree(modeO)) { ourDce = new DirCacheEntry(this.tw.getRawPath()); ourDce.setObjectId(this.tw.getObjectId(T_OURS)); ourDce.setFileMode(this.tw.getFileMode(T_OURS)); } } else { ourDce = index.getDirCacheEntry(); } if (nonTree(modeO) && nonTree(modeT) && this.tw.idEqual(T_OURS, T_THEIRS)) { // OURS and THEIRS have equal content. Check the file mode if (modeO == modeT) { // content and mode of OURS and THEIRS are equal: it doesn't // matter which one we choose. OURS is chosen. Since the index // is clean (the index matches already OURS) we can keep the existing one keep(ourDce); // no checkout needed! return true; } else { // same content but different mode on OURS and THEIRS. // Try to merge the mode and report an error if this is // not possible. int newMode = mergeFileModes(modeB, modeO, modeT); if (newMode != FileMode.MISSING.getBits()) { if (newMode == modeO) { // ours version is preferred keep(ourDce); } else { // the preferred version THEIRS has a different mode // than ours. Check it out! if (isWorktreeDirty(work, ourDce)) { return false; } // we know about length and lastMod only after we have written the new content. // This will happen later. Set these values to 0 for know. DirCacheEntry e = add(this.tw.getRawPath(), theirs, DirCacheEntry.STAGE_0, 0, 0); this.toBeCheckedOut.put(this.tw.getPathString(), e); } return true; } else { // FileModes are not mergeable. We found a conflict on modes. // For conflicting entries we don't know lastModified and length. add(this.tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0); add(this.tw.getRawPath(), ours, DirCacheEntry.STAGE_2, 0, 0); add(this.tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, 0, 0); this.unmergedPaths.add(this.tw.getPathString()); this.mergeResults.put(this.tw.getPathString(), new MergeResult<RawText>(Collections.<RawText>emptyList())); } return true; } } if (modeB == modeT && this.tw.idEqual(T_BASE, T_THEIRS)) { // THEIRS was not changed compared to BASE. All changes must be in // OURS. OURS is chosen. We can keep the existing entry. if (ourDce != null) { keep(ourDce); } // no checkout needed! return true; } if (modeB == modeO && this.tw.idEqual(T_BASE, T_OURS)) { // OURS was not changed compared to BASE. All changes must be in // THEIRS. THEIRS is chosen. // Check worktree before checking out THEIRS if (isWorktreeDirty(work, ourDce)) { return false; } if (nonTree(modeT)) { // we know about length and lastMod only after we have written // the new content. // This will happen later. Set these values to 0 for know. DirCacheEntry e = add(this.tw.getRawPath(), theirs, DirCacheEntry.STAGE_0, 0, 0); if (e != null) { this.toBeCheckedOut.put(this.tw.getPathString(), e); } return true; } else { // we want THEIRS ... but THEIRS contains a folder or the // deletion of the path. Delete what's in the workingtree (the // workingtree is clean) but do not complain if the file is // already deleted locally. This complements the test in // isWorktreeDirty() for the same case. if (this.tw.getTreeCount() > T_FILE && this.tw.getRawMode(T_FILE) == 0) { return true; } this.toBeDeleted.add(this.tw.getPathString()); return true; } } if (this.tw.isSubtree()) { // file/folder conflicts: here I want to detect only file/folder // conflict between ours and theirs. file/folder conflicts between // base/index/workingTree and something else are not relevant or // detected later if (nonTree(modeO) && !nonTree(modeT)) { if (nonTree(modeB)) { add(this.tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0); } add(this.tw.getRawPath(), ours, DirCacheEntry.STAGE_2, 0, 0); this.unmergedPaths.add(this.tw.getPathString()); this.enterSubtree = false; return true; } if (nonTree(modeT) && !nonTree(modeO)) { if (nonTree(modeB)) { add(this.tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0); } add(this.tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, 0, 0); this.unmergedPaths.add(this.tw.getPathString()); this.enterSubtree = false; return true; } // ours and theirs are both folders or both files (and treewalk // tells us we are in a subtree because of index or working-dir). // If they are both folders no content-merge is required - we can // return here. if (!nonTree(modeO)) { return true; } // ours and theirs are both files, just fall out of the if block // and do the content merge } if (nonTree(modeO) && nonTree(modeT)) { // Check worktree before modifying files if (isWorktreeDirty(work, ourDce)) { return false; } // Don't attempt to resolve submodule link conflicts if (isGitLink(modeO) || isGitLink(modeT)) { add(this.tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0); add(this.tw.getRawPath(), ours, DirCacheEntry.STAGE_2, 0, 0); add(this.tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, 0, 0); this.unmergedPaths.add(this.tw.getPathString()); return true; } MergeResult<RawText> result = contentMerge(base, ours, theirs); // if (ignoreConflicts) { // result.setContainsConflicts(false); // } updateIndex(base, ours, theirs, result); if (result.containsConflicts() && !ignoreConflicts) { this.unmergedPaths.add(this.tw.getPathString()); } this.modifiedFiles.add(this.tw.getPathString()); } else if (modeO != modeT) { // OURS or THEIRS has been deleted if (modeO != 0 && !this.tw.idEqual(T_BASE, T_OURS) || modeT != 0 && !this.tw.idEqual(T_BASE, T_THEIRS)) { add(this.tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0); add(this.tw.getRawPath(), ours, DirCacheEntry.STAGE_2, 0, 0); DirCacheEntry e = add(this.tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, 0, 0); // OURS was deleted checkout THEIRS if (modeO == 0) { // Check worktree before checking out THEIRS if (isWorktreeDirty(work, ourDce)) { return false; } if (nonTree(modeT)) { if (e != null) { this.toBeCheckedOut.put(this.tw.getPathString(), e); } } } this.unmergedPaths.add(this.tw.getPathString()); // generate a MergeResult for the deleted file this.mergeResults.put(this.tw.getPathString(), contentMerge(base, ours, theirs)); } } return true; }
From source file:com.itemis.maven.plugins.unleash.scm.providers.merge.UnleashGitMerger.java
License:Eclipse Distribution License
/** * Updates the index after a content merge has happened. If no conflict has * occurred this includes persisting the merged content to the object * database. In case of conflicts this method takes care to write the * correct stages to the index.//from w w w. j a va2s . c o m * * @param base * @param ours * @param theirs * @param result * @throws FileNotFoundException * @throws IOException */ private void updateIndex(CanonicalTreeParser base, CanonicalTreeParser ours, CanonicalTreeParser theirs, MergeResult<RawText> result) throws FileNotFoundException, IOException { File mergedFile = !this.inCore ? writeMergedFile(result) : null; if (result.containsConflicts()) { // A conflict occurred, the file will contain conflict markers // the index will be populated with the three stages and the // workdir (if used) contains the halfway merged content. add(this.tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0); add(this.tw.getRawPath(), ours, DirCacheEntry.STAGE_2, 0, 0); add(this.tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, 0, 0); this.mergeResults.put(this.tw.getPathString(), result); return; } // No conflict occurred, the file will contain fully merged content. // The index will be populated with the new merged version. DirCacheEntry dce = new DirCacheEntry(this.tw.getPathString()); // Set the mode for the new content. Fall back to REGULAR_FILE if // we can't merge modes of OURS and THEIRS. int newMode = mergeFileModes(this.tw.getRawMode(0), this.tw.getRawMode(1), this.tw.getRawMode(2)); dce.setFileMode(newMode == FileMode.MISSING.getBits() ? FileMode.REGULAR_FILE : FileMode.fromBits(newMode)); if (mergedFile != null) { long len = mergedFile.length(); dce.setLastModified(mergedFile.lastModified()); dce.setLength((int) len); InputStream is = new FileInputStream(mergedFile); try { dce.setObjectId(getObjectInserter().insert(OBJ_BLOB, len, is)); } finally { is.close(); } } else { dce.setObjectId(insertMergeResult(result)); } this.builder.add(dce); }
From source file:org.eclipse.egit.core.GitMoveDeleteHookTest.java
License:Open Source License
private static void addUnmergedEntry(String filePath, DirCacheBuilder builder) { DirCacheEntry stage1 = new DirCacheEntry(filePath, DirCacheEntry.STAGE_1); DirCacheEntry stage2 = new DirCacheEntry(filePath, DirCacheEntry.STAGE_2); DirCacheEntry stage3 = new DirCacheEntry(filePath, DirCacheEntry.STAGE_3); stage1.setFileMode(FileMode.REGULAR_FILE); stage2.setFileMode(FileMode.REGULAR_FILE); stage3.setFileMode(FileMode.REGULAR_FILE); builder.add(stage1);/* w w w . ja v a 2s . co m*/ builder.add(stage2); builder.add(stage3); }
From source file:org.eclipse.egit.core.internal.merge.DirCacheResourceVariantTreeProvider.java
License:Open Source License
/** * Constructs the resource variant trees by iterating over the given * repository's DirCache entries./* w w w .j ava 2 s . c om*/ * * @param repository * The repository which DirCache info we need to cache as * IResourceVariantTrees. * @throws IOException * if we somehow cannot read the DirCache. */ public DirCacheResourceVariantTreeProvider(Repository repository) throws IOException { final DirCache cache = repository.readDirCache(); final GitResourceVariantCache baseCache = new GitResourceVariantCache(); final GitResourceVariantCache sourceCache = new GitResourceVariantCache(); final GitResourceVariantCache remoteCache = new GitResourceVariantCache(); for (int i = 0; i < cache.getEntryCount(); i++) { final DirCacheEntry entry = cache.getEntry(i); final IPath path = new Path(entry.getPathString()); final IResource resource = ResourceUtil.getResourceHandleForLocation(path); // Resource variants only make sense for IResources. Do not consider // files outside of the workspace or otherwise non accessible. if (resource == null || resource.getProject() == null || !resource.getProject().isAccessible()) { continue; } switch (entry.getStage()) { case DirCacheEntry.STAGE_0: // Skipped on purpose (no conflict) break; case DirCacheEntry.STAGE_1: baseCache.setVariant(resource, IndexResourceVariant.create(repository, entry)); break; case DirCacheEntry.STAGE_2: sourceCache.setVariant(resource, IndexResourceVariant.create(repository, entry)); break; case DirCacheEntry.STAGE_3: remoteCache.setVariant(resource, IndexResourceVariant.create(repository, entry)); break; default: throw new IllegalStateException("Invalid stage: " + entry.getStage()); //$NON-NLS-1$ } } baseTree = new GitCachedResourceVariantTree(baseCache); sourceTree = new GitCachedResourceVariantTree(sourceCache); remoteTree = new GitCachedResourceVariantTree(remoteCache); roots = new LinkedHashSet<IResource>(); roots.addAll(baseCache.getRoots()); roots.addAll(sourceCache.getRoots()); roots.addAll(remoteCache.getRoots()); knownResources = new LinkedHashSet<IResource>(); knownResources.addAll(baseCache.getKnownResources()); knownResources.addAll(sourceCache.getKnownResources()); knownResources.addAll(remoteCache.getKnownResources()); }
From source file:org.eclipse.egit.core.internal.merge.ResourceVariantTest.java
License:Open Source License
@Test public void testIndexVariantsConflict() throws Exception { File file1 = testRepo.createFile(iProject, "file1"); IFile iFile1 = testRepo.getIFile(iProject, file1); setupConflictingBranches();/* w ww .j a va 2 s .c o m*/ // end setup // create a conflict to force multiple stages new MergeOperation(repo, BRANCH).execute(null); DirCache cache = repo.readDirCache(); // 3 stages for file 1, 2 stages for file 2 assertEquals(5, cache.getEntryCount()); for (int i = 0; i < cache.getEntryCount(); i++) { final DirCacheEntry entry = cache.getEntry(i); AbstractGitResourceVariant variant = IndexResourceVariant.create(repo, entry); assertEquals(entry.getObjectId().getName(), variant.getContentIdentifier()); assertEquals(entry.getObjectId(), variant.getObjectId()); assertEquals(entry.getRawMode(), variant.getRawMode()); if (iFile1.getName().equals(variant.getName())) { switch (entry.getStage()) { case DirCacheEntry.STAGE_1: assertContentEquals(variant, INITIAL_CONTENT_1); break; case DirCacheEntry.STAGE_2: assertContentEquals(variant, INITIAL_CONTENT_1 + MASTER_CHANGE); break; case DirCacheEntry.STAGE_3: assertContentEquals(variant, BRANCH_CHANGE + INITIAL_CONTENT_1); break; case DirCacheEntry.STAGE_0: default: fail("Unexpected entry stage " + entry.getStage() + " in the index for file " + entry.getPathString()); break; } } else { switch (entry.getStage()) { case DirCacheEntry.STAGE_2: assertContentEquals(variant, INITIAL_CONTENT_2 + MASTER_CHANGE); break; case DirCacheEntry.STAGE_3: assertContentEquals(variant, BRANCH_CHANGE + INITIAL_CONTENT_2); break; case DirCacheEntry.STAGE_0: case DirCacheEntry.STAGE_1: default: fail("Unexpected entry stage " + entry.getStage() + " in the index for file " + entry.getPathString()); break; } } } }
From source file:org.eclipse.emf.compare.egit.internal.merge.DirCacheResourceVariantTreeProvider.java
License:Open Source License
/** * Constructs the resource variant trees by iterating over the given repository's DirCache entries. * * @param repository//from w w w . ja v a 2 s. co m * The repository which DirCache info we need to cache as IResourceVariantTrees. * @param useWorkspace * Whether we should use local data instead of what's in the index for our side. * @throws IOException * if we somehow cannot read the DirCache. */ public DirCacheResourceVariantTreeProvider(Repository repository, boolean useWorkspace) throws IOException { final DirCache cache = repository.readDirCache(); final GitResourceVariantCache baseCache = new GitResourceVariantCache(); final GitResourceVariantCache sourceCache = new GitResourceVariantCache(); final GitResourceVariantCache remoteCache = new GitResourceVariantCache(); for (int i = 0; i < cache.getEntryCount(); i++) { final DirCacheEntry entry = cache.getEntry(i); final IResource resource = ModelEGitResourceUtil.getResourceHandleForLocation(repository, entry.getPathString(), FileMode.fromBits(entry.getRawMode()) == FileMode.TREE); // Resource variants only make sense for IResources. Do not consider // files outside of the workspace or otherwise non accessible. if (resource == null || resource.getProject() == null || !resource.getProject().isAccessible()) { continue; } switch (entry.getStage()) { case DirCacheEntry.STAGE_0: if (useWorkspace) { sourceCache.setVariant(resource, new GitLocalResourceVariant(resource)); } else { sourceCache.setVariant(resource, IndexResourceVariant.create(repository, entry)); } baseCache.setVariant(resource, IndexResourceVariant.create(repository, entry)); remoteCache.setVariant(resource, IndexResourceVariant.create(repository, entry)); break; case DirCacheEntry.STAGE_1: baseCache.setVariant(resource, IndexResourceVariant.create(repository, entry)); break; case DirCacheEntry.STAGE_2: if (useWorkspace) { sourceCache.setVariant(resource, new GitLocalResourceVariant(resource)); } else { sourceCache.setVariant(resource, IndexResourceVariant.create(repository, entry)); } break; case DirCacheEntry.STAGE_3: remoteCache.setVariant(resource, IndexResourceVariant.create(repository, entry)); break; default: throw new IllegalStateException("Invalid stage: " + entry.getStage()); //$NON-NLS-1$ } } baseTree = new GitCachedResourceVariantTree(baseCache); sourceTree = new GitCachedResourceVariantTree(sourceCache); remoteTree = new GitCachedResourceVariantTree(remoteCache); roots = new LinkedHashSet<IResource>(); roots.addAll(baseCache.getRoots()); roots.addAll(sourceCache.getRoots()); roots.addAll(remoteCache.getRoots()); knownResources = new LinkedHashSet<IResource>(); knownResources.addAll(baseCache.getKnownResources()); knownResources.addAll(sourceCache.getKnownResources()); knownResources.addAll(remoteCache.getKnownResources()); }
From source file:org.eclipse.emf.compare.egit.internal.merge.RecursiveModelMerger.java
License:Open Source License
private void markConflict(String filePath, DirCacheBuilder cacheBuilder, TreeParserResourceVariant baseVariant, TreeParserResourceVariant ourVariant, TreeParserResourceVariant theirVariant) { add(filePath, cacheBuilder, baseVariant, DirCacheEntry.STAGE_1); add(filePath, cacheBuilder, ourVariant, DirCacheEntry.STAGE_2); add(filePath, cacheBuilder, theirVariant, DirCacheEntry.STAGE_3); }
From source file:org.eclipse.emf.compare.egit.ui.internal.merge.ModelGitMergeEditorInput.java
License:Open Source License
private IDiffContainer buildDiffContainer(Repository repository, RevCommit headCommit, RevCommit ancestorCommit, List<String> filterPaths, RevWalk rw, IProgressMonitor monitor) throws IOException, InterruptedException { monitor.setTaskName(UIText.GitMergeEditorInput_CalculatingDiffTaskName); IDiffContainer result = new DiffNode(Differencer.CONFLICTING); TreeWalk tw = new TreeWalk(repository); try {/*from w w w.j a v a 2s . c om*/ int dirCacheIndex = tw.addTree(new DirCacheIterator(repository.readDirCache())); int fileTreeIndex = tw.addTree(new FileTreeIterator(repository)); int repositoryTreeIndex = tw.addTree(rw.parseTree(repository.resolve(Constants.HEAD))); // skip ignored resources NotIgnoredFilter notIgnoredFilter = new NotIgnoredFilter(fileTreeIndex); // filter by selected resources if (filterPaths.size() > 1) { List<TreeFilter> suffixFilters = new ArrayList<TreeFilter>(); for (String filterPath : filterPaths) { suffixFilters.add(PathFilter.create(filterPath)); } TreeFilter otf = OrTreeFilter.create(suffixFilters); tw.setFilter(AndTreeFilter.create(otf, notIgnoredFilter)); } else if (filterPaths.size() > 0) { String path = filterPaths.get(0); if (path.length() == 0) { tw.setFilter(notIgnoredFilter); } else { tw.setFilter(AndTreeFilter.create(PathFilter.create(path), notIgnoredFilter)); } } else { tw.setFilter(notIgnoredFilter); } tw.setRecursive(true); while (tw.next()) { if (monitor.isCanceled()) { throw new InterruptedException(); } String gitPath = tw.getPathString(); monitor.setTaskName(gitPath); FileTreeIterator fit = tw.getTree(fileTreeIndex, FileTreeIterator.class); if (fit == null) { continue; } DirCacheIterator dit = tw.getTree(dirCacheIndex, DirCacheIterator.class); final DirCacheEntry dirCacheEntry = dit == null ? null : dit.getDirCacheEntry(); boolean conflicting = dirCacheEntry != null && dirCacheEntry.getStage() > 0; AbstractTreeIterator rt = tw.getTree(repositoryTreeIndex, AbstractTreeIterator.class); // compare local file against HEAD to see if it was modified boolean modified = rt != null && !fit.getEntryObjectId().equals(rt.getEntryObjectId()); // if this is neither conflicting nor changed, we skip it if (!conflicting && !modified) { continue; } ITypedElement right; if (conflicting) { GitFileRevision revision = GitFileRevision.inIndex(repository, gitPath, DirCacheEntry.STAGE_3); String encoding = CompareCoreUtils.getResourceEncoding(repository, gitPath); right = new FileRevisionTypedElement(revision, encoding); } else { right = CompareUtils.getFileRevisionTypedElement(gitPath, headCommit, repository); } // can this really happen? if (right instanceof EmptyTypedElement) { continue; } IFileRevision rev; // if the file is not conflicting (as it was auto-merged) // we will show the auto-merged (local) version Path repositoryPath = new Path(repository.getWorkTree().getAbsolutePath()); IPath location = repositoryPath.append(fit.getEntryPathString()); IFile file = ResourceUtil.getFileForLocation(location, false); if (!conflicting || useWorkspace) { if (file != null) { rev = new LocalFileRevision(file); } else { rev = new WorkingTreeFileRevision(location.toFile()); } } else { rev = GitFileRevision.inIndex(repository, gitPath, DirCacheEntry.STAGE_2); } IRunnableContext runnableContext = getContainer(); if (runnableContext == null) { runnableContext = PlatformUI.getWorkbench().getProgressService(); } EditableRevision leftEditable; if (file != null) { leftEditable = new ResourceEditableRevision(rev, file, runnableContext); } else { leftEditable = new LocationEditableRevision(rev, location, runnableContext); } // make sure we don't need a round trip later try { leftEditable.cacheContents(monitor); } catch (CoreException e) { throw new IOException(e.getMessage()); } int kind = Differencer.NO_CHANGE; if (conflicting) { kind = Differencer.CONFLICTING; } else if (modified) { kind = Differencer.PSEUDO_CONFLICT; } IDiffContainer fileParent = getFileParent(result, repositoryPath, file, location); ITypedElement anc; if (ancestorCommit != null) { anc = CompareUtils.getFileRevisionTypedElement(gitPath, ancestorCommit, repository); } else { anc = null; } // we get an ugly black icon if we have an EmptyTypedElement // instead of null if (anc instanceof EmptyTypedElement) { anc = null; } // create the node as child new DiffNode(fileParent, kind, anc, leftEditable, right); } return result; } finally { tw.close(); } }
From source file:org.eclipse.emf.compare.ide.ui.tests.merge.ResourceVariantTest.java
License:Open Source License
@Test public void testIndexVariantsConflict() throws Exception { File file1 = repository.createFile(iProject, "file1"); IFile iFile1 = repository.getIFile(iProject, file1); setupConflictingBranches();/*from w w w . j ava 2 s. c om*/ // end setup // create a conflict to force multiple stages new MergeOperation(repo, BRANCH).execute(null); DirCache cache = repo.readDirCache(); // 3 stages for file 1, 2 stages for file 2 assertEquals(5, cache.getEntryCount()); for (int i = 0; i < cache.getEntryCount(); i++) { final DirCacheEntry entry = cache.getEntry(i); AbstractGitResourceVariant variant = IndexResourceVariant.create(repo, entry); assertEquals(entry.getObjectId().getName(), variant.getContentIdentifier()); assertEquals(entry.getObjectId(), variant.getObjectId()); assertEquals(entry.getRawMode(), variant.getRawMode()); if (iFile1.getName().equals(variant.getName())) { switch (entry.getStage()) { case DirCacheEntry.STAGE_1: assertContentEquals(variant, INITIAL_CONTENT_1); break; case DirCacheEntry.STAGE_2: assertContentEquals(variant, INITIAL_CONTENT_1 + MASTER_CHANGE); break; case DirCacheEntry.STAGE_3: assertContentEquals(variant, BRANCH_CHANGE + INITIAL_CONTENT_1); break; case DirCacheEntry.STAGE_0: default: fail("Unexpected entry stage " + entry.getStage() + " in the index for file " + entry.getPathString()); break; } } else { switch (entry.getStage()) { case DirCacheEntry.STAGE_2: assertContentEquals(variant, INITIAL_CONTENT_2 + MASTER_CHANGE); break; case DirCacheEntry.STAGE_3: assertContentEquals(variant, BRANCH_CHANGE + INITIAL_CONTENT_2); break; case DirCacheEntry.STAGE_0: case DirCacheEntry.STAGE_1: default: fail("Unexpected entry stage " + entry.getStage() + " in the index for file " + entry.getPathString()); break; } } } }
From source file:org.openflexo.hannah.IterativeFileGenerator.java
License:Open Source License
/** * <p>Ends the generation. It asks to resolve conflicts (if any). By * default conflict are resolved using user modifications.</p> * @param callback callback to handle conflicts * @throws IOException//w w w. j av a 2 s . c om */ public void end(ConflictHandler callback) throws IOException, GitAPIException { final Status status = git.status().call(); // checks if needs commit. if (status.isClean() == false) { // checks for files to add boolean execute = false; final AddCommand add = git.add(); for (String filename : status.getModified()) { execute = true; add.addFilepattern(filename); } for (String filename : status.getUntracked()) { execute = true; add.addFilepattern(filename); } if (execute) add.call(); // checks for files to remove execute = false; final RmCommand rm = git.rm(); for (String filename : status.getMissing()) { execute = true; rm.addFilepattern(filename); } if (execute) rm.call(); git.commit().setMessage("Generation").call(); } // checks out master branch git.checkout().setName(MASTER).call(); // merges generation branch with master (resolving conflict with USER). final Repository repo = git.getRepository(); final Ref generationHead = repo.getRef(GENERATION); final MergeStatus mergeStatus = git.merge().include(generationHead).call().getMergeStatus(); // in case of conflicts, uses the resolution mode to choose the outcome if (mergeStatus == MergeStatus.CONFLICTING) { // maps to stores confliting files final Map<String, DirCacheEntry> baseEntry = new LinkedHashMap<String, DirCacheEntry>(); final Map<String, DirCacheEntry> userEntry = new LinkedHashMap<String, DirCacheEntry>(); final Map<String, DirCacheEntry> generationEntry = new LinkedHashMap<String, DirCacheEntry>(); // for all conflicting entry collects base, user and generation entries. final DirCache cache = repo.lockDirCache(); for (int i = 0; i < cache.getEntryCount(); i++) { final DirCacheEntry entry = cache.getEntry(i); switch (entry.getStage()) { case DirCacheEntry.STAGE_1: baseEntry.put(entry.getPathString(), entry); break; case DirCacheEntry.STAGE_2: userEntry.put(entry.getPathString(), entry); break; case DirCacheEntry.STAGE_3: generationEntry.put(entry.getPathString(), entry); break; } } // creates list of conflicting files final List<ConflictingFile> conflictingFiles = new ArrayList<ConflictingFile>(); final MergeAlgorithm mergeAlgorithm = new MergeAlgorithm(); for (final String path : baseEntry.keySet()) { final RawText baseText = getRawText(baseEntry.get(path)); final RawText userText = getRawText(userEntry.get(path)); final RawText generationText = getRawText(generationEntry.get(path)); final MergeResult<RawText> result = mergeAlgorithm.merge(RawTextComparator.DEFAULT, baseText, userText, generationText); conflictingFiles.add(new ConflictingFile(path, result)); } // unlocks cache. cache.unlock(); // calls the callback callback.conflicts(conflictingFiles); // prepares the reset command final ResetCommand reset = git.reset(); // applies callback selections for (final ConflictingFile conflictingFile : conflictingFiles) { final File file = new File(repo.getWorkTree(), conflictingFile.getPath()); FileUtil.writeFile(file, conflictingFile.getContents(), "UTF-8"); reset.addPath(conflictingFile.getPath()); } // resets repository state to allows commit. reset.call(); // commit resolutions git.commit().setMessage("User/Generation merge conflicts resolutions.").call(); } // renames git repository to hannah gitFolder.renameTo(hannahFolder); }