diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java new file mode 100644 index 000000000..e72b7e215 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2009, Christian Halstrick + * Copyright (C) 2009, Christian Halstrick, Matthias Sohn, SAP AG + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.lib; + +import java.io.IOException; + +public class ReflogConfigTest extends RepositoryTestCase { + public void testlogAllRefUpdates() throws Exception { + long commitTime = 1154236443000L; + int tz = -4 * 60; + + // check that there are no entries in the reflog and turn off writing + // reflogs + assertTrue("there should be no entries in reflog", db.getReflogReader( + Constants.HEAD).getReverseEntries().size() == 0); + db.getConfig().setBoolean("core", null, "logallrefupdates", false); + + // do one commit and check that reflog size is 0: no reflogs should be + // written + final Tree t = new Tree(db); + addFileToTree(t, "i-am-a-file", "and this is the data in me\n"); + commit(t, "A Commit\n", new PersonIdent(jauthor, commitTime, tz), + new PersonIdent(jcommitter, commitTime, tz)); + commitTime += 100; + assertTrue( + "Reflog for HEAD still contain no entry", + db.getReflogReader(Constants.HEAD).getReverseEntries().size() == 0); + + // set the logAllRefUpdates parameter to true and check it + db.getConfig().setBoolean("core", null, "logallrefupdates", true); + assertTrue(db.getConfig().getCore().isLogAllRefUpdates()); + + // do one commit and check that reflog size is increased to 1 + addFileToTree(t, "i-am-another-file", "and this is other data in me\n"); + commit(t, "A Commit\n", new PersonIdent(jauthor, commitTime, tz), + new PersonIdent(jcommitter, commitTime, tz)); + commitTime += 100; + assertTrue( + "Reflog for HEAD should contain one entry", + db.getReflogReader(Constants.HEAD).getReverseEntries().size() == 1); + + // set the logAllRefUpdates parameter to false and check it + db.getConfig().setBoolean("core", null, "logallrefupdates", false); + assertFalse(db.getConfig().getCore().isLogAllRefUpdates()); + + // do one commit and check that reflog size is 2 + addFileToTree(t, "i-am-anotheranother-file", + "and this is other other data in me\n"); + commit(t, "A Commit\n", new PersonIdent(jauthor, commitTime, tz), + new PersonIdent(jcommitter, commitTime, tz)); + assertTrue( + "Reflog for HEAD should contain two entries", + db.getReflogReader(Constants.HEAD).getReverseEntries().size() == 2); + } + + private void addFileToTree(final Tree t, String filename, String content) + throws IOException { + FileTreeEntry f = t.addFile(filename); + writeTrashFile(f.getName(), content); + t.accept(new WriteTree(trash, db), TreeEntry.MODIFIED_ONLY); + } + + private void commit(final Tree t, String commitMsg, PersonIdent author, + PersonIdent committer) throws IOException { + final Commit commit = new Commit(db); + commit.setAuthor(author); + commit.setCommitter(committer); + commit.setMessage(commitMsg); + commit.setTree(t); + ObjectWriter writer = new ObjectWriter(db); + commit.setCommitId(writer.writeCommit(commit)); + + int nl = commitMsg.indexOf('\n'); + final RefUpdate ru = db.updateRef(Constants.HEAD); + ru.setNewObjectId(commit.getCommitId()); + ru.setRefLogMessage("commit : " + + ((nl == -1) ? commitMsg : commitMsg.substring(0, nl)), false); + ru.forceUpdate(); + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java index 4d4c3a731..9080ec139 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java @@ -1,4 +1,5 @@ /* + * Copyright (C) 2009, Christian Halstrick * Copyright (C) 2009, Google Inc. * Copyright (C) 2007, Robin Rosenberg * Copyright (C) 2006-2008, Shawn O. Pearce @@ -64,9 +65,12 @@ public class CoreConfig { private final int packIndexVersion; + private final boolean logAllRefUpdates; + private CoreConfig(final Config rc) { compression = rc.getInt("core", "compression", DEFAULT_COMPRESSION); packIndexVersion = rc.getInt("pack", "indexversion", 2); + logAllRefUpdates = rc.getBoolean("core", "logallrefupdates", true); } /** @@ -84,4 +88,11 @@ public class CoreConfig { public int getPackIndexVersion() { return packIndexVersion; } + + /** + * @return whether to log all refUpdates + */ + public boolean isLogAllRefUpdates() { + return logAllRefUpdates; + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefLogWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefLogWriter.java index d41bbb644..63307a3bc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefLogWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefLogWriter.java @@ -1,4 +1,5 @@ /* + * Copyright (C) 2009, Christian Halstrick * Copyright (C) 2007, Dave Watson * Copyright (C) 2009, Google Inc. * Copyright (C) 2007-2009, Robin Rosenberg @@ -119,16 +120,18 @@ public class RefLogWriter { final byte[] rec = Constants.encode(r.toString()); final File logdir = new File(db.getDirectory(), Constants.LOGS); final File reflog = new File(logdir, refName); - final File refdir = reflog.getParentFile(); + if (reflog.exists() || db.getConfig().getCore().isLogAllRefUpdates()) { + final File refdir = reflog.getParentFile(); - if (!refdir.exists() && !refdir.mkdirs()) - throw new IOException("Cannot create directory " + refdir); + if (!refdir.exists() && !refdir.mkdirs()) + throw new IOException("Cannot create directory " + refdir); - final FileOutputStream out = new FileOutputStream(reflog, true); - try { - out.write(rec); - } finally { - out.close(); + final FileOutputStream out = new FileOutputStream(reflog, true); + try { + out.write(rec); + } finally { + out.close(); + } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java index 181ca580f..52f9ff393 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java @@ -193,6 +193,7 @@ public class Repository { cfg.setBoolean("core", null, "filemode", true); if (bare) cfg.setBoolean("core", null, "bare", true); + cfg.setBoolean("core", null, "logallrefupdates", !bare); cfg.save(); }