Merge "Provide an id for submodule entries."
This commit is contained in:
commit
ede88c60a5
|
@ -45,19 +45,26 @@
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
|
|
||||||
import org.eclipse.jgit.api.Git;
|
import org.eclipse.jgit.api.Git;
|
||||||
|
import org.eclipse.jgit.dircache.DirCache;
|
||||||
import org.eclipse.jgit.dircache.DirCacheCheckout;
|
import org.eclipse.jgit.dircache.DirCacheCheckout;
|
||||||
|
import org.eclipse.jgit.dircache.DirCacheEditor;
|
||||||
import org.eclipse.jgit.dircache.DirCacheEntry;
|
import org.eclipse.jgit.dircache.DirCacheEntry;
|
||||||
|
import org.eclipse.jgit.dircache.DirCacheIterator;
|
||||||
|
import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
|
||||||
import org.eclipse.jgit.lib.Constants;
|
import org.eclipse.jgit.lib.Constants;
|
||||||
import org.eclipse.jgit.lib.FileMode;
|
import org.eclipse.jgit.lib.FileMode;
|
||||||
import org.eclipse.jgit.lib.ObjectId;
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
import org.eclipse.jgit.lib.ObjectReader;
|
import org.eclipse.jgit.lib.ObjectReader;
|
||||||
import org.eclipse.jgit.lib.RepositoryTestCase;
|
import org.eclipse.jgit.lib.RepositoryTestCase;
|
||||||
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
|
import org.eclipse.jgit.treewalk.filter.PathFilter;
|
||||||
import org.eclipse.jgit.util.FileUtils;
|
import org.eclipse.jgit.util.FileUtils;
|
||||||
import org.eclipse.jgit.util.RawParseUtils;
|
import org.eclipse.jgit.util.RawParseUtils;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -208,6 +215,170 @@ public void testIsModifiedSymlink() throws Exception {
|
||||||
assertFalse(fti.isModified(dce, false));
|
assertFalse(fti.isModified(dce, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void submoduleHeadMatchesIndex() throws Exception {
|
||||||
|
Git git = new Git(db);
|
||||||
|
writeTrashFile("file.txt", "content");
|
||||||
|
git.add().addFilepattern("file.txt").call();
|
||||||
|
final RevCommit id = git.commit().setMessage("create file").call();
|
||||||
|
final String path = "sub";
|
||||||
|
DirCache cache = db.lockDirCache();
|
||||||
|
DirCacheEditor editor = cache.editor();
|
||||||
|
editor.add(new PathEdit(path) {
|
||||||
|
|
||||||
|
public void apply(DirCacheEntry ent) {
|
||||||
|
ent.setFileMode(FileMode.GITLINK);
|
||||||
|
ent.setObjectId(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
editor.commit();
|
||||||
|
|
||||||
|
Git.cloneRepository().setURI(db.getDirectory().toURI().toString())
|
||||||
|
.setDirectory(new File(db.getWorkTree(), path)).call();
|
||||||
|
|
||||||
|
TreeWalk walk = new TreeWalk(db);
|
||||||
|
DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
|
||||||
|
FileTreeIterator workTreeIter = new FileTreeIterator(db);
|
||||||
|
walk.addTree(indexIter);
|
||||||
|
walk.addTree(workTreeIter);
|
||||||
|
walk.setFilter(PathFilter.create(path));
|
||||||
|
|
||||||
|
assertTrue(walk.next());
|
||||||
|
assertTrue(indexIter.idEqual(workTreeIter));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void submoduleWithNoGitDirectory() throws Exception {
|
||||||
|
Git git = new Git(db);
|
||||||
|
writeTrashFile("file.txt", "content");
|
||||||
|
git.add().addFilepattern("file.txt").call();
|
||||||
|
final RevCommit id = git.commit().setMessage("create file").call();
|
||||||
|
final String path = "sub";
|
||||||
|
DirCache cache = db.lockDirCache();
|
||||||
|
DirCacheEditor editor = cache.editor();
|
||||||
|
editor.add(new PathEdit(path) {
|
||||||
|
|
||||||
|
public void apply(DirCacheEntry ent) {
|
||||||
|
ent.setFileMode(FileMode.GITLINK);
|
||||||
|
ent.setObjectId(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
editor.commit();
|
||||||
|
|
||||||
|
File submoduleRoot = new File(db.getWorkTree(), path);
|
||||||
|
assertTrue(submoduleRoot.mkdir());
|
||||||
|
assertTrue(new File(submoduleRoot, Constants.DOT_GIT).mkdir());
|
||||||
|
|
||||||
|
TreeWalk walk = new TreeWalk(db);
|
||||||
|
DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
|
||||||
|
FileTreeIterator workTreeIter = new FileTreeIterator(db);
|
||||||
|
walk.addTree(indexIter);
|
||||||
|
walk.addTree(workTreeIter);
|
||||||
|
walk.setFilter(PathFilter.create(path));
|
||||||
|
|
||||||
|
assertTrue(walk.next());
|
||||||
|
assertFalse(indexIter.idEqual(workTreeIter));
|
||||||
|
assertEquals(ObjectId.zeroId(), workTreeIter.getEntryObjectId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void submoduleWithNoHead() throws Exception {
|
||||||
|
Git git = new Git(db);
|
||||||
|
writeTrashFile("file.txt", "content");
|
||||||
|
git.add().addFilepattern("file.txt").call();
|
||||||
|
final RevCommit id = git.commit().setMessage("create file").call();
|
||||||
|
final String path = "sub";
|
||||||
|
DirCache cache = db.lockDirCache();
|
||||||
|
DirCacheEditor editor = cache.editor();
|
||||||
|
editor.add(new PathEdit(path) {
|
||||||
|
|
||||||
|
public void apply(DirCacheEntry ent) {
|
||||||
|
ent.setFileMode(FileMode.GITLINK);
|
||||||
|
ent.setObjectId(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
editor.commit();
|
||||||
|
|
||||||
|
assertNotNull(Git.init().setDirectory(new File(db.getWorkTree(), path))
|
||||||
|
.call().getRepository());
|
||||||
|
|
||||||
|
TreeWalk walk = new TreeWalk(db);
|
||||||
|
DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
|
||||||
|
FileTreeIterator workTreeIter = new FileTreeIterator(db);
|
||||||
|
walk.addTree(indexIter);
|
||||||
|
walk.addTree(workTreeIter);
|
||||||
|
walk.setFilter(PathFilter.create(path));
|
||||||
|
|
||||||
|
assertTrue(walk.next());
|
||||||
|
assertFalse(indexIter.idEqual(workTreeIter));
|
||||||
|
assertEquals(ObjectId.zeroId(), workTreeIter.getEntryObjectId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void submoduleDirectoryIterator() throws Exception {
|
||||||
|
Git git = new Git(db);
|
||||||
|
writeTrashFile("file.txt", "content");
|
||||||
|
git.add().addFilepattern("file.txt").call();
|
||||||
|
final RevCommit id = git.commit().setMessage("create file").call();
|
||||||
|
final String path = "sub";
|
||||||
|
DirCache cache = db.lockDirCache();
|
||||||
|
DirCacheEditor editor = cache.editor();
|
||||||
|
editor.add(new PathEdit(path) {
|
||||||
|
|
||||||
|
public void apply(DirCacheEntry ent) {
|
||||||
|
ent.setFileMode(FileMode.GITLINK);
|
||||||
|
ent.setObjectId(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
editor.commit();
|
||||||
|
|
||||||
|
Git.cloneRepository().setURI(db.getDirectory().toURI().toString())
|
||||||
|
.setDirectory(new File(db.getWorkTree(), path)).call();
|
||||||
|
|
||||||
|
TreeWalk walk = new TreeWalk(db);
|
||||||
|
DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
|
||||||
|
FileTreeIterator workTreeIter = new FileTreeIterator(db.getWorkTree(),
|
||||||
|
db.getFS(), db.getConfig().get(WorkingTreeOptions.KEY));
|
||||||
|
walk.addTree(indexIter);
|
||||||
|
walk.addTree(workTreeIter);
|
||||||
|
walk.setFilter(PathFilter.create(path));
|
||||||
|
|
||||||
|
assertTrue(walk.next());
|
||||||
|
assertTrue(indexIter.idEqual(workTreeIter));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void submoduleNestedWithHeadMatchingIndex() throws Exception {
|
||||||
|
Git git = new Git(db);
|
||||||
|
writeTrashFile("file.txt", "content");
|
||||||
|
git.add().addFilepattern("file.txt").call();
|
||||||
|
final RevCommit id = git.commit().setMessage("create file").call();
|
||||||
|
final String path = "sub/dir1/dir2";
|
||||||
|
DirCache cache = db.lockDirCache();
|
||||||
|
DirCacheEditor editor = cache.editor();
|
||||||
|
editor.add(new PathEdit(path) {
|
||||||
|
|
||||||
|
public void apply(DirCacheEntry ent) {
|
||||||
|
ent.setFileMode(FileMode.GITLINK);
|
||||||
|
ent.setObjectId(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
editor.commit();
|
||||||
|
|
||||||
|
Git.cloneRepository().setURI(db.getDirectory().toURI().toString())
|
||||||
|
.setDirectory(new File(db.getWorkTree(), path)).call();
|
||||||
|
|
||||||
|
TreeWalk walk = new TreeWalk(db);
|
||||||
|
DirCacheIterator indexIter = new DirCacheIterator(db.readDirCache());
|
||||||
|
FileTreeIterator workTreeIter = new FileTreeIterator(db);
|
||||||
|
walk.addTree(indexIter);
|
||||||
|
walk.addTree(workTreeIter);
|
||||||
|
walk.setFilter(PathFilter.create(path));
|
||||||
|
|
||||||
|
assertTrue(walk.next());
|
||||||
|
assertTrue(indexIter.idEqual(workTreeIter));
|
||||||
|
}
|
||||||
|
|
||||||
private static String nameOf(final AbstractTreeIterator i) {
|
private static String nameOf(final AbstractTreeIterator i) {
|
||||||
return RawParseUtils.decode(Constants.CHARSET, i.path, 0, i.pathLen);
|
return RawParseUtils.decode(Constants.CHARSET, i.path, 0, i.pathLen);
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,4 +223,11 @@ public File getDirectory() {
|
||||||
public File getEntryFile() {
|
public File getEntryFile() {
|
||||||
return ((FileEntry) current()).getFile();
|
return ((FileEntry) current()).getFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected byte[] idSubmodule(final Entry e) {
|
||||||
|
if (repository == null)
|
||||||
|
return idSubmodule(getDirectory(), e);
|
||||||
|
return super.idSubmodule(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,12 +67,15 @@
|
||||||
import org.eclipse.jgit.dircache.DirCacheEntry;
|
import org.eclipse.jgit.dircache.DirCacheEntry;
|
||||||
import org.eclipse.jgit.dircache.DirCacheIterator;
|
import org.eclipse.jgit.dircache.DirCacheIterator;
|
||||||
import org.eclipse.jgit.errors.CorruptObjectException;
|
import org.eclipse.jgit.errors.CorruptObjectException;
|
||||||
|
import org.eclipse.jgit.errors.NoWorkTreeException;
|
||||||
import org.eclipse.jgit.ignore.IgnoreNode;
|
import org.eclipse.jgit.ignore.IgnoreNode;
|
||||||
import org.eclipse.jgit.ignore.IgnoreRule;
|
import org.eclipse.jgit.ignore.IgnoreRule;
|
||||||
import org.eclipse.jgit.lib.Constants;
|
import org.eclipse.jgit.lib.Constants;
|
||||||
import org.eclipse.jgit.lib.CoreConfig;
|
import org.eclipse.jgit.lib.CoreConfig;
|
||||||
import org.eclipse.jgit.lib.FileMode;
|
import org.eclipse.jgit.lib.FileMode;
|
||||||
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
|
import org.eclipse.jgit.lib.RepositoryBuilder;
|
||||||
import org.eclipse.jgit.util.FS;
|
import org.eclipse.jgit.util.FS;
|
||||||
import org.eclipse.jgit.util.IO;
|
import org.eclipse.jgit.util.IO;
|
||||||
import org.eclipse.jgit.util.io.EolCanonicalizingInputStream;
|
import org.eclipse.jgit.util.io.EolCanonicalizingInputStream;
|
||||||
|
@ -122,6 +125,9 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
|
||||||
/** If there is a .gitignore file present, the parsed rules from it. */
|
/** If there is a .gitignore file present, the parsed rules from it. */
|
||||||
private IgnoreNode ignoreNode;
|
private IgnoreNode ignoreNode;
|
||||||
|
|
||||||
|
/** Repository that is the root level being iterated over */
|
||||||
|
protected Repository repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new iterator with no parent.
|
* Create a new iterator with no parent.
|
||||||
*
|
*
|
||||||
|
@ -177,6 +183,7 @@ protected WorkingTreeIterator(final WorkingTreeIterator p) {
|
||||||
* the repository.
|
* the repository.
|
||||||
*/
|
*/
|
||||||
protected void initRootIterator(Repository repo) {
|
protected void initRootIterator(Repository repo) {
|
||||||
|
repository = repo;
|
||||||
Entry entry;
|
Entry entry;
|
||||||
if (ignoreNode instanceof PerDirectoryIgnoreNode)
|
if (ignoreNode instanceof PerDirectoryIgnoreNode)
|
||||||
entry = ((PerDirectoryIgnoreNode) ignoreNode).entry;
|
entry = ((PerDirectoryIgnoreNode) ignoreNode).entry;
|
||||||
|
@ -239,13 +246,66 @@ public byte[] idBuffer() {
|
||||||
//
|
//
|
||||||
return zeroid;
|
return zeroid;
|
||||||
case FileMode.TYPE_GITLINK:
|
case FileMode.TYPE_GITLINK:
|
||||||
// TODO: Support obtaining current HEAD SHA-1 from nested repository
|
contentIdFromPtr = ptr;
|
||||||
//
|
return contentId = idSubmodule(entries[ptr]);
|
||||||
return zeroid;
|
|
||||||
}
|
}
|
||||||
return zeroid;
|
return zeroid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get submodule id for given entry.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* @return non-null submodule id
|
||||||
|
*/
|
||||||
|
protected byte[] idSubmodule(Entry e) {
|
||||||
|
if (repository == null)
|
||||||
|
return zeroid;
|
||||||
|
File directory;
|
||||||
|
try {
|
||||||
|
directory = repository.getWorkTree();
|
||||||
|
} catch (NoWorkTreeException nwte) {
|
||||||
|
return zeroid;
|
||||||
|
}
|
||||||
|
return idSubmodule(directory, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get submodule id using the repository at the location of the entry
|
||||||
|
* relative to the directory.
|
||||||
|
*
|
||||||
|
* @param directory
|
||||||
|
* @param e
|
||||||
|
* @return non-null submodule id
|
||||||
|
*/
|
||||||
|
protected byte[] idSubmodule(File directory, Entry e) {
|
||||||
|
final String gitDirPath = e.getName() + "/" + Constants.DOT_GIT;
|
||||||
|
final File submoduleGitDir = new File(directory, gitDirPath);
|
||||||
|
if (!submoduleGitDir.isDirectory())
|
||||||
|
return zeroid;
|
||||||
|
final Repository submoduleRepo;
|
||||||
|
try {
|
||||||
|
FS fs = repository != null ? repository.getFS() : FS.DETECTED;
|
||||||
|
submoduleRepo = new RepositoryBuilder().setGitDir(submoduleGitDir)
|
||||||
|
.setMustExist(true).setFS(fs).build();
|
||||||
|
} catch (IOException exception) {
|
||||||
|
return zeroid;
|
||||||
|
}
|
||||||
|
final ObjectId head;
|
||||||
|
try {
|
||||||
|
head = submoduleRepo.resolve(Constants.HEAD);
|
||||||
|
} catch (IOException exception) {
|
||||||
|
return zeroid;
|
||||||
|
} finally {
|
||||||
|
submoduleRepo.close();
|
||||||
|
}
|
||||||
|
if (head == null)
|
||||||
|
return zeroid;
|
||||||
|
final byte[] id = new byte[Constants.OBJECT_ID_LENGTH];
|
||||||
|
head.copyRawTo(id, 0);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
private static final byte[] digits = { '0', '1', '2', '3', '4', '5', '6',
|
private static final byte[] digits = { '0', '1', '2', '3', '4', '5', '6',
|
||||||
'7', '8', '9' };
|
'7', '8', '9' };
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue