1 /*******************************************************************************
2 * Copyright (C) 2015 Obeo and others.
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9 package org
.eclipse
.egit
.core
.internal
.merge
;
11 import static org
.junit
.Assert
.assertEquals
;
12 import static org
.junit
.Assert
.assertTrue
;
13 import static org
.junit
.Assert
.fail
;
16 import java
.util
.Arrays
;
17 import java
.util
.List
;
19 import org
.eclipse
.core
.resources
.IFile
;
20 import org
.eclipse
.core
.resources
.IResource
;
21 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
22 import org
.eclipse
.egit
.core
.internal
.storage
.AbstractGitResourceVariant
;
23 import org
.eclipse
.egit
.core
.internal
.storage
.IndexResourceVariant
;
24 import org
.eclipse
.egit
.core
.internal
.storage
.TreeParserResourceVariant
;
25 import org
.eclipse
.egit
.core
.op
.MergeOperation
;
26 import org
.eclipse
.jgit
.dircache
.DirCache
;
27 import org
.eclipse
.jgit
.dircache
.DirCacheEntry
;
28 import org
.eclipse
.jgit
.lib
.ObjectId
;
29 import org
.eclipse
.jgit
.revwalk
.RevWalk
;
30 import org
.eclipse
.jgit
.treewalk
.CanonicalTreeParser
;
31 import org
.eclipse
.jgit
.treewalk
.TreeWalk
;
32 import org
.junit
.Test
;
34 public class ResourceVariantTest
extends VariantsTestCase
{
35 private final static String BASE_BRANCH
= "base";
37 private final static String BRANCH_CHANGE
= "branch changes\n";
39 private final static String MASTER_CHANGE
= "master changes\n";
42 public void testIndexVariants() throws Exception
{
43 File file1
= testRepo
.createFile(iProject
, "file1");
44 File file2
= testRepo
.createFile(iProject
, "file2");
45 IFile iFile1
= testRepo
.getIFile(iProject
, file1
);
46 IFile iFile2
= testRepo
.getIFile(iProject
, file2
);
48 setupUnconflictingBranches();
50 List
<String
> possibleNames
= Arrays
.asList(iFile1
.getName(),
52 DirCache cache
= repo
.readDirCache();
53 for (int i
= 0; i
< cache
.getEntryCount(); i
++) {
54 final DirCacheEntry entry
= cache
.getEntry(i
);
56 AbstractGitResourceVariant variant
= IndexResourceVariant
.create(
59 assertEquals(entry
.getObjectId().getName(),
60 variant
.getContentIdentifier());
61 assertTrue(possibleNames
.contains(variant
.getName()));
62 assertEquals(entry
.getObjectId(), variant
.getObjectId());
63 assertEquals(entry
.getRawMode(), variant
.getRawMode());
64 if (iFile1
.getName().equals(variant
.getName())) {
65 assertContentEquals(variant
, INITIAL_CONTENT_1
+ MASTER_CHANGE
);
67 assertContentEquals(variant
, INITIAL_CONTENT_2
+ MASTER_CHANGE
);
71 testRepo
.checkoutBranch(BRANCH
);
73 cache
= repo
.readDirCache();
74 for (int i
= 0; i
< cache
.getEntryCount(); i
++) {
75 final DirCacheEntry entry
= cache
.getEntry(i
);
77 AbstractGitResourceVariant variant
= IndexResourceVariant
.create(
79 assertEquals(entry
.getObjectId().getName(),
80 variant
.getContentIdentifier());
81 assertTrue(possibleNames
.contains(variant
.getName()));
82 assertEquals(entry
.getObjectId(), variant
.getObjectId());
83 assertEquals(entry
.getRawMode(), variant
.getRawMode());
84 if (iFile1
.getName().equals(variant
.getName())) {
85 assertContentEquals(variant
, BRANCH_CHANGE
+ INITIAL_CONTENT_1
);
87 assertContentEquals(variant
, BRANCH_CHANGE
+ INITIAL_CONTENT_2
);
93 public void testIndexVariantsConflict() throws Exception
{
94 File file1
= testRepo
.createFile(iProject
, "file1");
95 IFile iFile1
= testRepo
.getIFile(iProject
, file1
);
97 setupConflictingBranches();
100 // create a conflict to force multiple stages
101 new MergeOperation(repo
, BRANCH
).execute(null);
103 DirCache cache
= repo
.readDirCache();
104 // 3 stages for file 1, 2 stages for file 2
105 assertEquals(5, cache
.getEntryCount());
106 for (int i
= 0; i
< cache
.getEntryCount(); i
++) {
107 final DirCacheEntry entry
= cache
.getEntry(i
);
109 AbstractGitResourceVariant variant
= IndexResourceVariant
.create(
111 assertEquals(entry
.getObjectId().getName(),
112 variant
.getContentIdentifier());
113 assertEquals(entry
.getObjectId(), variant
.getObjectId());
114 assertEquals(entry
.getRawMode(), variant
.getRawMode());
115 if (iFile1
.getName().equals(variant
.getName())) {
116 switch (entry
.getStage()) {
117 case DirCacheEntry
.STAGE_1
:
118 assertContentEquals(variant
, INITIAL_CONTENT_1
);
120 case DirCacheEntry
.STAGE_2
:
121 assertContentEquals(variant
, INITIAL_CONTENT_1
124 case DirCacheEntry
.STAGE_3
:
125 assertContentEquals(variant
, BRANCH_CHANGE
126 + INITIAL_CONTENT_1
);
128 case DirCacheEntry
.STAGE_0
:
130 fail("Unexpected entry stage " + entry
.getStage()
131 + " in the index for file " + entry
.getPathString());
135 switch (entry
.getStage()) {
136 case DirCacheEntry
.STAGE_2
:
137 assertContentEquals(variant
, INITIAL_CONTENT_2
140 case DirCacheEntry
.STAGE_3
:
141 assertContentEquals(variant
, BRANCH_CHANGE
142 + INITIAL_CONTENT_2
);
144 case DirCacheEntry
.STAGE_0
:
145 case DirCacheEntry
.STAGE_1
:
147 fail("Unexpected entry stage " + entry
.getStage()
148 + " in the index for file " + entry
.getPathString());
156 public void testTreeWalkBranchVariants() throws Exception
{
157 File file1
= testRepo
.createFile(iProject
, "file1");
158 IFile iFile1
= testRepo
.getIFile(iProject
, file1
);
160 setupUnconflictingBranches();
162 ObjectId baseId
= repo
.resolve(BRANCH
);
163 try (RevWalk walk
= new RevWalk(repo
);
164 TreeWalk tw
= new TreeWalk(repo
)) {
165 tw
.addTree(walk
.parseTree(baseId
));
168 AbstractGitResourceVariant variant
= TreeParserResourceVariant
169 .create(repo
, tw
.getTree(0, CanonicalTreeParser
.class));
171 assertEquals(tw
.getObjectId(0).getName(),
172 variant
.getContentIdentifier());
173 assertEquals(tw
.getObjectId(0), variant
.getObjectId());
174 assertEquals(tw
.getRawMode(0), variant
.getRawMode());
175 if (iFile1
.getName().equals(variant
.getName())) {
176 assertContentEquals(variant
,
177 BRANCH_CHANGE
+ INITIAL_CONTENT_1
);
178 } else if (!tw
.isSubtree()) {
179 assertContentEquals(variant
,
180 BRANCH_CHANGE
+ INITIAL_CONTENT_2
);
183 if (tw
.isSubtree()) {
191 public void testTreeWalkMasterVariants() throws Exception
{
192 File file1
= testRepo
.createFile(iProject
, "file1");
193 IFile iFile1
= testRepo
.getIFile(iProject
, file1
);
195 setupUnconflictingBranches();
197 ObjectId baseId
= repo
.resolve(MASTER
);
198 try (RevWalk walk
= new RevWalk(repo
);
199 TreeWalk tw
= new TreeWalk(repo
)) {
200 tw
.addTree(walk
.parseTree(baseId
));
203 AbstractGitResourceVariant variant
= TreeParserResourceVariant
204 .create(repo
, tw
.getTree(0, CanonicalTreeParser
.class));
206 assertEquals(tw
.getObjectId(0).getName(),
207 variant
.getContentIdentifier());
208 assertEquals(tw
.getObjectId(0), variant
.getObjectId());
209 assertEquals(tw
.getRawMode(0), variant
.getRawMode());
210 if (iFile1
.getName().equals(variant
.getName())) {
211 assertContentEquals(variant
,
212 INITIAL_CONTENT_1
+ MASTER_CHANGE
);
213 } else if (!tw
.isSubtree()) {
214 assertContentEquals(variant
,
215 INITIAL_CONTENT_2
+ MASTER_CHANGE
);
218 if (tw
.isSubtree()) {
226 public void testTreeWalkBaseVariants() throws Exception
{
227 File file1
= testRepo
.createFile(iProject
, "file1");
228 IFile iFile1
= testRepo
.getIFile(iProject
, file1
);
230 setupUnconflictingBranches();
232 ObjectId baseId
= repo
.resolve(BASE_BRANCH
);
233 try (RevWalk walk
= new RevWalk(repo
);
234 TreeWalk tw
= new TreeWalk(repo
)) {
235 tw
.addTree(walk
.parseTree(baseId
));
238 AbstractGitResourceVariant variant
= TreeParserResourceVariant
239 .create(repo
, tw
.getTree(0, CanonicalTreeParser
.class));
241 assertEquals(tw
.getObjectId(0).getName(),
242 variant
.getContentIdentifier());
243 assertEquals(tw
.getObjectId(0), variant
.getObjectId());
244 assertEquals(tw
.getRawMode(0), variant
.getRawMode());
245 if (iFile1
.getName().equals(variant
.getName())) {
246 assertContentEquals(variant
, INITIAL_CONTENT_1
);
247 } else if (!tw
.isSubtree()) {
248 fail("file2 shouldn't exist in our base.");
251 if (tw
.isSubtree()) {
258 private void setupUnconflictingBranches() throws Exception
{
259 File file1
= testRepo
.createFile(iProject
, "file1");
260 File file2
= testRepo
.createFile(iProject
, "file2");
261 IFile iFile1
= testRepo
.getIFile(iProject
, file1
);
263 testRepo
.appendContentAndCommit(iProject
, file1
, INITIAL_CONTENT_1
,
264 "first file - initial commit");
266 testRepo
.createBranch(MASTER
, BASE_BRANCH
);
267 testRepo
.createAndCheckoutBranch(MASTER
, BRANCH
);
269 setContentsAndCommit(testRepo
, iFile1
, BRANCH_CHANGE
270 + INITIAL_CONTENT_1
, "branch commit");
271 testRepo
.appendContentAndCommit(iProject
, file2
, BRANCH_CHANGE
272 + INITIAL_CONTENT_2
, "second file - initial commit - branch");
274 testRepo
.checkoutBranch(MASTER
);
276 setContentsAndCommit(testRepo
, iFile1
, INITIAL_CONTENT_1
277 + MASTER_CHANGE
, "master commit - file1");
278 testRepo
.appendContentAndCommit(iProject
, file2
, INITIAL_CONTENT_2
279 + MASTER_CHANGE
, "second file - initial commit - master");
280 iProject
.refreshLocal(IResource
.DEPTH_INFINITE
,
281 new NullProgressMonitor());
284 private void setupConflictingBranches() throws Exception
{
285 File file1
= testRepo
.createFile(iProject
, "file1");
286 File file2
= testRepo
.createFile(iProject
, "file2");
287 IFile iFile1
= testRepo
.getIFile(iProject
, file1
);
289 testRepo
.appendContentAndCommit(iProject
, file1
, INITIAL_CONTENT_1
,
290 "first file - initial commit");
292 testRepo
.createAndCheckoutBranch(MASTER
, BRANCH
);
294 setContentsAndCommit(testRepo
, iFile1
, BRANCH_CHANGE
295 + INITIAL_CONTENT_1
, "branch commit");
296 testRepo
.appendContentAndCommit(iProject
, file2
, BRANCH_CHANGE
297 + INITIAL_CONTENT_2
, "second file - initial commit - branch");
299 testRepo
.checkoutBranch(MASTER
);
301 setContentsAndCommit(testRepo
, iFile1
, INITIAL_CONTENT_1
302 + MASTER_CHANGE
, "master commit - file1");
303 testRepo
.appendContentAndCommit(iProject
, file2
, INITIAL_CONTENT_2
304 + MASTER_CHANGE
, "second file - initial commit - master");
305 iProject
.refreshLocal(IResource
.DEPTH_INFINITE
,
306 new NullProgressMonitor());