In server applications we may want to ensure the remote user identity is used within the reflog, rather than whatever the local repository might come up with. This change introduces an optional RefLogIdent property of the RefUpdate, settable by the caller to override any default guessing performed within the ref log writer. Signed-off-by: Shawn O. Pearce <spearce@xxxxxxxxxxx> --- .../src/org/spearce/jgit/lib/RefLogWriter.java | 71 ++++++++++++------- .../src/org/spearce/jgit/lib/RefUpdate.java | 32 ++++++++- 2 files changed, 75 insertions(+), 28 deletions(-) diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefLogWriter.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefLogWriter.java index 6de8c0f..a077051 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefLogWriter.java +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefLogWriter.java @@ -42,7 +42,6 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.io.PrintWriter; /** * Utility class to add reflog entries @@ -50,6 +49,49 @@ * @author Dave Watson */ public class RefLogWriter { + static void append(final RefUpdate u, final String msg) throws IOException { + final ObjectId oldId = u.getOldObjectId(); + final ObjectId newId = u.getNewObjectId(); + final Repository db = u.getRepository(); + final PersonIdent ident = u.getRefLogIdent(); + + appendOneRecord(oldId, newId, ident, msg, db, u.getName()); + } + + private static void appendOneRecord(final ObjectId oldId, + final ObjectId newId, PersonIdent ident, final String msg, + final Repository db, final String refName) throws IOException { + if (ident == null) + ident = new PersonIdent(db); + else + ident = new PersonIdent(ident); + + final StringBuilder r = new StringBuilder(); + r.append(ObjectId.toString(oldId)); + r.append(' '); + r.append(ObjectId.toString(newId)); + r.append(' '); + r.append(ident.toExternalString()); + r.append('\t'); + r.append(msg); + r.append('\n'); + + 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 (!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(); + } + } + /** * Writes reflog entry for ref specified by refName * @@ -64,33 +106,10 @@ * @param refName * full ref name * @throws IOException + * @deprecated rely upon {@link RefUpdate}'s automatic logging instead. */ public static void writeReflog(Repository repo, ObjectId oldCommit, ObjectId commit, String message, String refName) throws IOException { - String entry = buildReflogString(repo, oldCommit, commit, message); - - File directory = repo.getDirectory(); - File reflogfile = new File(directory, Constants.LOGS + "/" + refName); - File reflogdir = reflogfile.getParentFile(); - if (!reflogdir.exists()) - if (!reflogdir.mkdirs()) - throw new IOException("Cannot create directory "+reflogdir); - PrintWriter writer = new PrintWriter(new FileOutputStream(reflogfile, true)); - writer.println(entry); - writer.close(); + appendOneRecord(oldCommit, commit, null, message, repo, refName); } - - private static String buildReflogString(Repository repo, - ObjectId oldCommit, ObjectId commit, String message) { - PersonIdent me = new PersonIdent(repo); - String initial = ""; - if (oldCommit == null) { - oldCommit = ObjectId.zeroId(); - initial = " (initial)"; - } - String s = oldCommit.name() + " " + commit.name() + " " - + me.toExternalString() + "\t" + message + initial; - return s; - } - } diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java index 1417f2c..1ce1e71 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java @@ -140,6 +140,9 @@ /** Does this specification ask for forced updated (rewind/reset)? */ private boolean force; + /** Identity to record action as within the reflog. */ + private PersonIdent refLogIdent; + /** Message the caller wants included in the reflog. */ private String refLogMessage; @@ -164,6 +167,11 @@ RefUpdate(final RefDatabase r, final Ref ref, final File f) { looseFile = f; } + /** @return the repository the updated ref resides in */ + public Repository getRepository() { + return db.getRepository(); + } + /** * Get the name of the ref this update will operate on. * @@ -232,6 +240,27 @@ public void setForceUpdate(final boolean b) { force = b; } + /** @return identity of the user making the change in the reflog. */ + public PersonIdent getRefLogIdent() { + return refLogIdent; + } + + /** + * Set the identity of the user appearing in the reflog. + * <p> + * The timestamp portion of the identity is ignored. A new identity with the + * current timestamp will be created automatically when the update occurs + * and the log record is written. + * + * @param pi + * identity of the user. If null the identity will be + * automatically determined based on the repository + * configuration. + */ + public void setRefLogIdent(final PersonIdent pi) { + refLogIdent = pi; + } + /** * Get the message to include in the reflog. * @@ -450,8 +479,7 @@ else if (status == Result.FAST_FORWARD) else if (status == Result.NEW) msg += ": created"; } - RefLogWriter.writeReflog(db.getRepository(), oldValue, newValue, msg, - getName()); + RefLogWriter.append(this, msg); if (!lock.commit()) return Result.LOCK_FAILURE; db.stored(this.ref.getOrigName(), ref.getName(), newValue, lock.getCommitLastModified()); -- 1.6.1.2.492.g8554a -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html