View Javadoc
1   /*
2    * Copyright (C) 2014, Christian Halstrick <christian.halstrick@sap.com>
3    * and other copyright owners as documented in the project's IP log.
4    *
5    * This program and the accompanying materials are made available
6    * under the terms of the Eclipse Distribution License v1.0 which
7    * accompanies this distribution, is reproduced below, and is
8    * available at http://www.eclipse.org/org/documents/edl-v10.php
9    *
10   * All rights reserved.
11   *
12   * Redistribution and use in source and binary forms, with or
13   * without modification, are permitted provided that the following
14   * conditions are met:
15   *
16   * - Redistributions of source code must retain the above copyright
17   *   notice, this list of conditions and the following disclaimer.
18   *
19   * - Redistributions in binary form must reproduce the above
20   *   copyright notice, this list of conditions and the following
21   *   disclaimer in the documentation and/or other materials provided
22   *   with the distribution.
23   *
24   * - Neither the name of the Eclipse Foundation, Inc. nor the
25   *   names of its contributors may be used to endorse or promote
26   *   products derived from this software without specific prior
27   *   written permission.
28   *
29   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42   */
43  
44  package org.eclipse.jgit.lib;
45  
46  import static org.junit.Assert.assertEquals;
47  import static org.junit.Assert.assertFalse;
48  import static org.junit.Assert.assertTrue;
49  
50  import java.io.File;
51  import java.io.IOException;
52  import java.util.Set;
53  
54  import org.eclipse.jgit.api.Git;
55  import org.eclipse.jgit.api.errors.GitAPIException;
56  import org.eclipse.jgit.errors.NoWorkTreeException;
57  import org.eclipse.jgit.internal.storage.file.FileRepository;
58  import org.eclipse.jgit.junit.JGitTestUtil;
59  import org.eclipse.jgit.junit.RepositoryTestCase;
60  import org.eclipse.jgit.submodule.SubmoduleWalk.IgnoreSubmoduleMode;
61  import org.eclipse.jgit.treewalk.FileTreeIterator;
62  import org.junit.Before;
63  import org.junit.experimental.theories.DataPoints;
64  import org.junit.experimental.theories.Theories;
65  import org.junit.experimental.theories.Theory;
66  import org.junit.runner.RunWith;
67  
68  @RunWith(Theories.class)
69  public class IndexDiffSubmoduleTest extends RepositoryTestCase {
70  	/** a submodule repository inside a root repository */
71  	protected FileRepository submodule_db;
72  
73  	/** Working directory of the submodule repository */
74  	protected File submodule_trash;
75  
76  	@DataPoints
77  	public static IgnoreSubmoduleMode allModes[] = IgnoreSubmoduleMode.values();
78  
79  	@Override
80  	@Before
81  	public void setUp() throws Exception {
82  		super.setUp();
83  		FileRepository submoduleStandalone = createWorkRepository();
84  		JGitTestUtil.writeTrashFile(submoduleStandalone, "fileInSubmodule",
85  				"submodule");
86  		Git submoduleStandaloneGit = Git.wrap(submoduleStandalone);
87  		submoduleStandaloneGit.add().addFilepattern("fileInSubmodule").call();
88  		submoduleStandaloneGit.commit().setMessage("add file to submodule")
89  				.call();
90  
91  		submodule_db = (FileRepository) Git.wrap(db).submoduleAdd()
92  				.setPath("modules/submodule")
93  				.setURI(submoduleStandalone.getDirectory().toURI().toString())
94  				.call();
95  		submodule_trash = submodule_db.getWorkTree();
96  		addRepoToClose(submodule_db);
97  		writeTrashFile("fileInRoot", "root");
98  		Git rootGit = Git.wrap(db);
99  		rootGit.add().addFilepattern("fileInRoot").call();
100 		rootGit.commit().setMessage("add submodule and root file").call();
101 	}
102 
103 	@Theory
104 	public void testInitiallyClean(IgnoreSubmoduleMode mode)
105 			throws IOException {
106 		IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
107 				new FileTreeIterator(db));
108 		indexDiff.setIgnoreSubmoduleMode(mode);
109 		assertFalse(indexDiff.diff());
110 	}
111 
112 	@Theory
113 	public void testDirtyRootWorktree(IgnoreSubmoduleMode mode)
114 			throws IOException {
115 		writeTrashFile("fileInRoot", "2");
116 
117 		IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
118 				new FileTreeIterator(db));
119 		indexDiff.setIgnoreSubmoduleMode(mode);
120 		assertTrue(indexDiff.diff());
121 	}
122 
123 	private void assertDiff(IndexDiff indexDiff, IgnoreSubmoduleMode mode,
124 			IgnoreSubmoduleMode... expectedEmptyModes) throws IOException {
125 		boolean diffResult = indexDiff.diff();
126 		Set<String> submodulePaths = indexDiff
127 				.getPathsWithIndexMode(FileMode.GITLINK);
128 		boolean emptyExpected = false;
129 		for (IgnoreSubmoduleMode empty : expectedEmptyModes) {
130 			if (mode.equals(empty)) {
131 				emptyExpected = true;
132 				break;
133 			}
134 		}
135 		if (emptyExpected) {
136 			assertFalse("diff should be false with mode=" + mode,
137 					diffResult);
138 			assertEquals("should have no paths with FileMode.GITLINK", 0,
139 					submodulePaths.size());
140 		} else {
141 			assertTrue("diff should be true with mode=" + mode,
142 					diffResult);
143 			assertTrue("submodule path should have FileMode.GITLINK",
144 					submodulePaths.contains("modules/submodule"));
145 		}
146 	}
147 
148 	@Theory
149 	public void testDirtySubmoduleWorktree(IgnoreSubmoduleMode mode)
150 			throws IOException {
151 		JGitTestUtil.writeTrashFile(submodule_db, "fileInSubmodule", "2");
152 		IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
153 				new FileTreeIterator(db));
154 		indexDiff.setIgnoreSubmoduleMode(mode);
155 		assertDiff(indexDiff, mode, IgnoreSubmoduleMode.ALL,
156 				IgnoreSubmoduleMode.DIRTY);
157 	}
158 
159 	@Theory
160 	public void testDirtySubmoduleHEAD(IgnoreSubmoduleMode mode)
161 			throws IOException, GitAPIException {
162 		JGitTestUtil.writeTrashFile(submodule_db, "fileInSubmodule", "2");
163 		Git submoduleGit = Git.wrap(submodule_db);
164 		submoduleGit.add().addFilepattern("fileInSubmodule").call();
165 		submoduleGit.commit().setMessage("Modified fileInSubmodule").call();
166 
167 		IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
168 				new FileTreeIterator(db));
169 		indexDiff.setIgnoreSubmoduleMode(mode);
170 		assertDiff(indexDiff, mode, IgnoreSubmoduleMode.ALL);
171 	}
172 
173 	@Theory
174 	public void testDirtySubmoduleIndex(IgnoreSubmoduleMode mode)
175 			throws IOException, GitAPIException {
176 		JGitTestUtil.writeTrashFile(submodule_db, "fileInSubmodule", "2");
177 		Git submoduleGit = Git.wrap(submodule_db);
178 		submoduleGit.add().addFilepattern("fileInSubmodule").call();
179 
180 		IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
181 				new FileTreeIterator(db));
182 		indexDiff.setIgnoreSubmoduleMode(mode);
183 		assertDiff(indexDiff, mode, IgnoreSubmoduleMode.ALL,
184 				IgnoreSubmoduleMode.DIRTY);
185 	}
186 
187 	@Theory
188 	public void testDirtySubmoduleIndexAndWorktree(IgnoreSubmoduleMode mode)
189 			throws IOException, GitAPIException, NoWorkTreeException {
190 		JGitTestUtil.writeTrashFile(submodule_db, "fileInSubmodule", "2");
191 		Git submoduleGit = Git.wrap(submodule_db);
192 		submoduleGit.add().addFilepattern("fileInSubmodule").call();
193 		JGitTestUtil.writeTrashFile(submodule_db, "fileInSubmodule", "3");
194 
195 		IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
196 				new FileTreeIterator(db));
197 		indexDiff.setIgnoreSubmoduleMode(mode);
198 		assertDiff(indexDiff, mode, IgnoreSubmoduleMode.ALL,
199 				IgnoreSubmoduleMode.DIRTY);
200 	}
201 
202 	@Theory
203 	public void testDirtySubmoduleWorktreeUntracked(IgnoreSubmoduleMode mode)
204 			throws IOException {
205 		JGitTestUtil.writeTrashFile(submodule_db, "additionalFileInSubmodule",
206 				"2");
207 		IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
208 				new FileTreeIterator(db));
209 		indexDiff.setIgnoreSubmoduleMode(mode);
210 		assertDiff(indexDiff, mode, IgnoreSubmoduleMode.ALL,
211 				IgnoreSubmoduleMode.DIRTY, IgnoreSubmoduleMode.UNTRACKED);
212 	}
213 }