diff --git a/org.eclipse.jgit.iplog/README b/org.eclipse.jgit.iplog/README index 4015c7da9..6f945346e 100644 --- a/org.eclipse.jgit.iplog/README +++ b/org.eclipse.jgit.iplog/README @@ -11,19 +11,19 @@ # $JGIT_BASE/.eclipse_iplog # ----------------------------------------------------------- # Prepare: -# jgit work tree base dir -export JGIT_BASE="c:/data/ide/helios/jgit" +# jgit executable (assuming jgit mvn build is up to date) +export jgit="~/src/git/jgit/org.eclipse.jgit.pgm/target/jgit" # repository work dir root path -export WORK_DIR="c:/data/ide/helios/jgit" +export WORK_DIR="~/src/git/jgit/" -# cd to repository work dir root path (for jgit this is identical to $JGIT_BASE) +# cd to repository work dir root path cd $WORK_DIR # ----------------------------------------------------------- # Update the CQ list: # - this command updates file .eclipse_iplog -java -jar $JGIT_BASE/org.eclipse.jgit.pgm/target/jgit-cli.jar eclipse-ipzilla +jgit eclipse-ipzilla # - if there are any updates 'git commit' them git add .eclipse_iplog @@ -49,6 +49,6 @@ ssh -p 29418 username@egit.eclipse.org gerrit gsql --format PRETTY # options: # -- version : the project version the iplog is to be generated for # - o : the output file -java -jar $JGIT_BASE/org.eclipse.jgit.pgm/target/jgit-cli.jar eclipse-iplog --version=0.8.0 -o jgit-0.8.0.xml +jgit eclipse-iplog --version=1.3.0 -o $WORK_DIR/jgit-1.3.0.xml diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java index 37fbc67ca..b9f5882d5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java @@ -44,15 +44,25 @@ package org.eclipse.jgit.api; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.io.File; +import java.util.List; +import org.eclipse.jgit.diff.DiffEntry; import org.eclipse.jgit.lib.ConfigConstants; +import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.RefUpdate; +import org.eclipse.jgit.lib.RefUpdate.Result; +import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryTestCase; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.submodule.SubmoduleWalk; import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.eclipse.jgit.util.FS; import org.junit.Test; @@ -152,4 +162,100 @@ public class CommitCommandTest extends RepositoryTestCase { assertNotNull(walk); assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0)); } + + @Test + public void commitNewSubmodule() throws Exception { + Git git = new Git(db); + writeTrashFile("file.txt", "content"); + git.add().addFilepattern("file.txt").call(); + RevCommit commit = git.commit().setMessage("create file").call(); + + SubmoduleAddCommand command = new SubmoduleAddCommand(db); + String path = "sub"; + command.setPath(path); + String uri = db.getDirectory().toURI().toString(); + command.setURI(uri); + Repository repo = command.call(); + assertNotNull(repo); + + SubmoduleWalk generator = SubmoduleWalk.forIndex(db); + assertTrue(generator.next()); + assertEquals(path, generator.getPath()); + assertEquals(commit, generator.getObjectId()); + assertEquals(uri, generator.getModulesUrl()); + assertEquals(path, generator.getModulesPath()); + assertEquals(uri, generator.getConfigUrl()); + assertNotNull(generator.getRepository()); + assertEquals(commit, repo.resolve(Constants.HEAD)); + + RevCommit submoduleCommit = git.commit().setMessage("submodule add") + .setOnly(path).call(); + assertNotNull(submoduleCommit); + TreeWalk walk = new TreeWalk(db); + walk.addTree(commit.getTree()); + walk.addTree(submoduleCommit.getTree()); + walk.setFilter(TreeFilter.ANY_DIFF); + List diffs = DiffEntry.scan(walk); + assertEquals(1, diffs.size()); + DiffEntry subDiff = diffs.get(0); + assertEquals(FileMode.MISSING, subDiff.getOldMode()); + assertEquals(FileMode.GITLINK, subDiff.getNewMode()); + assertEquals(ObjectId.zeroId(), subDiff.getOldId().toObjectId()); + assertEquals(commit, subDiff.getNewId().toObjectId()); + assertEquals(path, subDiff.getNewPath()); + } + + @Test + public void commitSubmoduleUpdate() throws Exception { + Git git = new Git(db); + writeTrashFile("file.txt", "content"); + git.add().addFilepattern("file.txt").call(); + RevCommit commit = git.commit().setMessage("create file").call(); + writeTrashFile("file.txt", "content2"); + git.add().addFilepattern("file.txt").call(); + RevCommit commit2 = git.commit().setMessage("edit file").call(); + + SubmoduleAddCommand command = new SubmoduleAddCommand(db); + String path = "sub"; + command.setPath(path); + String uri = db.getDirectory().toURI().toString(); + command.setURI(uri); + Repository repo = command.call(); + assertNotNull(repo); + + SubmoduleWalk generator = SubmoduleWalk.forIndex(db); + assertTrue(generator.next()); + assertEquals(path, generator.getPath()); + assertEquals(commit2, generator.getObjectId()); + assertEquals(uri, generator.getModulesUrl()); + assertEquals(path, generator.getModulesPath()); + assertEquals(uri, generator.getConfigUrl()); + assertNotNull(generator.getRepository()); + assertEquals(commit2, repo.resolve(Constants.HEAD)); + + RevCommit submoduleAddCommit = git.commit().setMessage("submodule add") + .setOnly(path).call(); + assertNotNull(submoduleAddCommit); + + RefUpdate update = repo.updateRef(Constants.HEAD); + update.setNewObjectId(commit); + assertEquals(Result.FORCED, update.forceUpdate()); + + RevCommit submoduleEditCommit = git.commit() + .setMessage("submodule add").setOnly(path).call(); + assertNotNull(submoduleEditCommit); + TreeWalk walk = new TreeWalk(db); + walk.addTree(submoduleAddCommit.getTree()); + walk.addTree(submoduleEditCommit.getTree()); + walk.setFilter(TreeFilter.ANY_DIFF); + List diffs = DiffEntry.scan(walk); + assertEquals(1, diffs.size()); + DiffEntry subDiff = diffs.get(0); + assertEquals(FileMode.GITLINK, subDiff.getOldMode()); + assertEquals(FileMode.GITLINK, subDiff.getNewMode()); + assertEquals(commit2, subDiff.getOldId().toObjectId()); + assertEquals(commit, subDiff.getNewId().toObjectId()); + assertEquals(path, subDiff.getNewPath()); + assertEquals(path, subDiff.getOldPath()); + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleWalkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleWalkTest.java index c4bf33b8b..89843fc24 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleWalkTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleWalkTest.java @@ -44,10 +44,12 @@ package org.eclipse.jgit.submodule; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.File; +import java.io.FileWriter; import java.io.IOException; import org.eclipse.jgit.dircache.DirCache; @@ -58,7 +60,9 @@ import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryTestCase; +import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.treewalk.filter.PathFilter; import org.junit.Test; @@ -97,8 +101,6 @@ public class SubmoduleWalkTest extends RepositoryTestCase { assertEquals(path, gen.getPath()); assertEquals(id, gen.getObjectId()); assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); - assertEquals(new File(db.getWorkTree(), path + File.separatorChar - + Constants.DOT_GIT), gen.getGitDirectory()); assertNull(gen.getConfigUpdate()); assertNull(gen.getConfigUrl()); assertNull(gen.getModulesPath()); @@ -108,6 +110,101 @@ public class SubmoduleWalkTest extends RepositoryTestCase { assertFalse(gen.next()); } + @Test + public void repositoryWithRootLevelSubmoduleAbsoluteRef() + throws IOException, ConfigInvalidException { + final ObjectId id = ObjectId + .fromString("abcd1234abcd1234abcd1234abcd1234abcd1234"); + final String path = "sub"; + File dotGit = new File(db.getWorkTree(), path + File.separatorChar + + Constants.DOT_GIT); + if (!dotGit.getParentFile().exists()) + dotGit.getParentFile().mkdirs(); + + File modulesGitDir = new File(db.getDirectory(), "modules" + + File.separatorChar + path); + new FileWriter(dotGit).append( + "gitdir: " + modulesGitDir.getAbsolutePath()).close(); + FileRepositoryBuilder builder = new FileRepositoryBuilder(); + builder.setWorkTree(new File(db.getWorkTree(), path)); + builder.build().create(); + + 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(); + + SubmoduleWalk gen = SubmoduleWalk.forIndex(db); + assertTrue(gen.next()); + assertEquals(path, gen.getPath()); + assertEquals(id, gen.getObjectId()); + assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); + assertNull(gen.getConfigUpdate()); + assertNull(gen.getConfigUrl()); + assertNull(gen.getModulesPath()); + assertNull(gen.getModulesUpdate()); + assertNull(gen.getModulesUrl()); + Repository subRepo = gen.getRepository(); + assertNotNull(subRepo); + assertEquals(modulesGitDir, subRepo.getDirectory()); + assertEquals(new File(db.getWorkTree(), path), subRepo.getWorkTree()); + assertFalse(gen.next()); + } + + @Test + public void repositoryWithRootLevelSubmoduleRelativeRef() + throws IOException, ConfigInvalidException { + final ObjectId id = ObjectId + .fromString("abcd1234abcd1234abcd1234abcd1234abcd1234"); + final String path = "sub"; + File dotGit = new File(db.getWorkTree(), path + File.separatorChar + + Constants.DOT_GIT); + if (!dotGit.getParentFile().exists()) + dotGit.getParentFile().mkdirs(); + + File modulesGitDir = new File(db.getDirectory(), "modules" + + File.separatorChar + path); + new FileWriter(dotGit).append( + "gitdir: " + "../" + Constants.DOT_GIT + "/modules/" + path) + .close(); + FileRepositoryBuilder builder = new FileRepositoryBuilder(); + builder.setWorkTree(new File(db.getWorkTree(), path)); + builder.build().create(); + + 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(); + + SubmoduleWalk gen = SubmoduleWalk.forIndex(db); + assertTrue(gen.next()); + assertEquals(path, gen.getPath()); + assertEquals(id, gen.getObjectId()); + assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); + assertNull(gen.getConfigUpdate()); + assertNull(gen.getConfigUrl()); + assertNull(gen.getModulesPath()); + assertNull(gen.getModulesUpdate()); + assertNull(gen.getModulesUrl()); + Repository subRepo = gen.getRepository(); + assertNotNull(subRepo); + assertEquals(modulesGitDir, subRepo.getDirectory()); + assertEquals(new File(db.getWorkTree(), path), subRepo.getWorkTree()); + assertFalse(gen.next()); + } + @Test public void repositoryWithNestedSubmodule() throws IOException, ConfigInvalidException { @@ -130,8 +227,6 @@ public class SubmoduleWalkTest extends RepositoryTestCase { assertEquals(path, gen.getPath()); assertEquals(id, gen.getObjectId()); assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); - assertEquals(new File(db.getWorkTree(), path + File.separatorChar - + Constants.DOT_GIT), gen.getGitDirectory()); assertNull(gen.getConfigUpdate()); assertNull(gen.getConfigUrl()); assertNull(gen.getModulesPath()); diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties index 5b2280134..8a5e02310 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties @@ -234,6 +234,7 @@ invalidChannel=Invalid channel {0} invalidCharacterInBase64Data=Invalid character in Base64 data. invalidCommitParentNumber=Invalid commit parent number invalidEncryption=Invalid encryption +invalidGitdirRef = Invalid .git reference in file ''{0}'' invalidGitType=invalid git type: {0} invalidId=Invalid id {0} invalidIdLength=Invalid id length {0}; should be {1} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java index dbc3bcae6..bcd14c6a4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java @@ -294,6 +294,7 @@ public class JGitText extends TranslationBundle { /***/ public String invalidCharacterInBase64Data; /***/ public String invalidCommitParentNumber; /***/ public String invalidEncryption; + /***/ public String invalidGitdirRef; /***/ public String invalidGitType; /***/ public String invalidId; /***/ public String invalidIdLength; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java index d2386f1e8..882ce2176 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java @@ -351,12 +351,9 @@ public class CommitCommand extends GitCommand { if (objectExists) { dcEntry.setObjectId(fTree.getEntryObjectId()); } else { - if (FileMode.GITLINK.equals(dcEntry.getFileMode())) { - // Do not check the content of submodule entries - // Use the old entry information instead. - dcEntry.copyMetaData(index.getEntry(dcEntry - .getPathString())); - } else { + if (FileMode.GITLINK.equals(dcEntry.getFileMode())) + dcEntry.setObjectId(fTree.getEntryObjectId()); + else { // insert object if (inserter == null) inserter = repo.newObjectInserter(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java index 22a2ae505..7db0b9f87 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java @@ -69,6 +69,8 @@ import org.eclipse.jgit.storage.file.FileBasedConfig; import org.eclipse.jgit.storage.file.FileRepository; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.util.FS; +import org.eclipse.jgit.util.IO; +import org.eclipse.jgit.util.RawParseUtils; import org.eclipse.jgit.util.SystemReader; /** @@ -85,6 +87,19 @@ import org.eclipse.jgit.util.SystemReader; * @see FileRepositoryBuilder */ public class BaseRepositoryBuilder { + private static boolean isSymRef(byte[] ref) { + if (ref.length < 9) + return false; + return /**/ref[0] == 'g' // + && ref[1] == 'i' // + && ref[2] == 't' // + && ref[3] == 'd' // + && ref[4] == 'i' // + && ref[5] == 'r' // + && ref[6] == ':' // + && ref[7] == ' '; + } + private FS fs; private File gitDir; @@ -546,10 +561,37 @@ public class BaseRepositoryBuilder