Skip to content

Instantly share code, notes, and snippets.

@porcelli
Created October 13, 2012 00:19
Show Gist options
  • Save porcelli/3882505 to your computer and use it in GitHub Desktop.
Save porcelli/3882505 to your computer and use it in GitHub Desktop.
jgit on bare repo
public static void delete(final Git git, final String branchName, final String path,
final String name, final String email, final String message, final TimeZone timeZone, final Date when) {
commit(git, branchName, path, null, name, email, message, timeZone, when);
}
public static void commit(final Git git, final String branchName, final String path, final File file,
final String name, final String email, final String message, final TimeZone timeZone, final Date when) {
final String gitPath = fixPath(path);
final PersonIdent author = buildPersonIdent(git, name, email, timeZone, when);
try {
final ObjectInserter odi = git.getRepository().newObjectInserter();
try {
// Create the in-memory index of the new/updated issue.
final ObjectId headId = git.getRepository().resolve(branchName + "^{commit}");
final DirCache index = createTemporaryIndex(git, headId, gitPath, file);
final ObjectId indexTreeId = index.writeTree(odi);
// Create a commit object
final CommitBuilder commit = new CommitBuilder();
commit.setAuthor(author);
commit.setCommitter(author);
commit.setEncoding(Constants.CHARACTER_ENCODING);
commit.setMessage(message);
//headId can be null if the repository has no commit yet
if (headId != null) {
commit.setParentId(headId);
}
commit.setTreeId(indexTreeId);
// Insert the commit into the repository
final ObjectId commitId = odi.insert(commit);
odi.flush();
final RevWalk revWalk = new RevWalk(git.getRepository());
try {
final RevCommit revCommit = revWalk.parseCommit(commitId);
final RefUpdate ru = git.getRepository().updateRef("refs/heads/" + branchName);
if (headId == null) {
ru.setExpectedOldObjectId(ObjectId.zeroId());
} else {
ru.setExpectedOldObjectId(headId);
}
ru.setNewObjectId(commitId);
ru.setRefLogMessage("commit: " + revCommit.getShortMessage(), false);
final RefUpdate.Result rc = ru.forceUpdate();
switch (rc) {
case NEW:
case FORCED:
case FAST_FORWARD:
break;
case REJECTED:
case LOCK_FAILURE:
throw new ConcurrentRefUpdateException(JGitText.get().couldNotLockHEAD, ru.getRef(), rc);
default:
throw new JGitInternalException(MessageFormat.format(JGitText.get().updatingRefFailed, Constants.HEAD, commitId.toString(), rc));
}
} finally {
revWalk.release();
}
} finally {
odi.release();
}
} catch (final Throwable t) {
throw new RuntimeException(t);
}
}
private static PersonIdent buildPersonIdent(final Git git, final String name, final String email,
final TimeZone timeZone, final Date when) {
final TimeZone tz = timeZone == null ? TimeZone.getDefault() : timeZone;
if (name != null) {
if (when != null) {
return new PersonIdent(name, email, when, tz);
} else {
return new PersonIdent(name, email);
}
}
return new PersonIdent(git.getRepository());
}
/**
* Creates an in-memory index of the issue change.
*/
private static DirCache createTemporaryIndex(final Git git, final ObjectId headId, final String path, final File file) {
final DirCache inCoreIndex = DirCache.newInCore();
final DirCacheBuilder dcBuilder = inCoreIndex.builder();
final ObjectInserter inserter = git.getRepository().newObjectInserter();
try {
if (file != null) {
final DirCacheEntry dcEntry = new DirCacheEntry(path);
dcEntry.setLength(file.length());
dcEntry.setLastModified(file.lastModified());
dcEntry.setFileMode(FileMode.REGULAR_FILE);
final InputStream inputStream = new FileInputStream(file);
try {
dcEntry.setObjectId(inserter.insert(Constants.OBJ_BLOB, file.length(), inputStream));
} finally {
inputStream.close();
}
dcBuilder.add(dcEntry);
}
if (headId != null) {
final TreeWalk treeWalk = new TreeWalk(git.getRepository());
final int hIdx = treeWalk.addTree(new RevWalk(git.getRepository()).parseTree(headId));
treeWalk.setRecursive(true);
while (treeWalk.next()) {
final String walkPath = treeWalk.getPathString();
final CanonicalTreeParser hTree = treeWalk.getTree(hIdx, CanonicalTreeParser.class);
if (!walkPath.equals(path)) {
// add entries from HEAD for all other paths
// create a new DirCacheEntry with data retrieved from HEAD
final DirCacheEntry dcEntry = new DirCacheEntry(walkPath);
dcEntry.setObjectId(hTree.getEntryObjectId());
dcEntry.setFileMode(hTree.getEntryFileMode());
// add to temporary in-core index
dcBuilder.add(dcEntry);
}
}
treeWalk.release();
}
dcBuilder.finish();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
inserter.release();
}
if (file == null) {
final DirCacheEditor editor = inCoreIndex.editor();
editor.add(new DirCacheEditor.DeleteTree(path));
editor.finish();
}
return inCoreIndex;
}
@Lesmiscore
Copy link

Lesmiscore commented Oct 16, 2020

@porcelli - I know this is quite old, but any chance you remember what fixPath(path) on line 9 was supposed to have done?

I think it's doing simple path canonicaliz
ation. (for UNIX paths that use forward slash for its path separator)

@porcelli
Copy link
Author

and maybe this is also of your interest coming directly into jgit: https://git.eclipse.org/r/c/jgit/jgit/+/156039

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment