-
-
Save creationix/7443198 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// repo is assumed to be in closure | |
var repo; | |
// commit - the hash of the current commit | |
// path - the path to the hash in the current commit | |
// callback -> the previous blob value | |
function findPrevious(commit, path, callback) { | |
var log; // The log stream | |
var currentBlob; // The current value of the blob | |
var oldBlob; // The last value of the blob | |
var changeCommit; // The commit that made the last change to the blob | |
var oldCommit; // The previous commit | |
// First get the log stream | |
repo.logWalk(commit, onLog); | |
function onLog(err, result) { | |
if (err) return callback(err); | |
log = result; | |
// Read the current commit | |
log.read(onCurrentCommit); | |
} | |
function onCurrentCommit(err, result) { | |
if (err) return callback(err); | |
changeCommit = result; | |
// Find the file by path in the current commit | |
walkPath(changeCommit.tree, path, onCurrentBlob); | |
} | |
function onCurrentBlob(err, result) { | |
if (err) return callback(err); | |
currentBlob = result; | |
// Start our search loop looking for a change in the next commit | |
log.read(onCommit); | |
} | |
function onCommit(err, result) { | |
if (err) return callback(err); | |
oldCommit = result | |
if (oldCommit === undefined) { | |
// We've reached the beginning of history, this was created in the initial commit | |
return callback(null, { | |
oldBlob: undefined, | |
currentBlob: currentBlob, | |
changeCommit: changeCommit | |
}); | |
} | |
walkPath(oldCommit.tree, path, onBlob); | |
} | |
function onBlob(err, result) { | |
if (err) return callback(err); | |
oldBlob = result; | |
if ((oldBlob && oldBlob.hash) !== currentBlob.hash) { | |
return callback(null, { | |
oldBlob: oldBlob, | |
currentBlob: currentBlob, | |
changeCommit: changeCommit | |
}); | |
} | |
changeCommit = oldCommit; | |
log.read(onCommit); | |
} | |
} | |
function walkPath(tree, path, callback) { | |
// Remove leading and trailing slashes, '.' entries, and split artifacts. | |
var names = path.split("/").filter(cleanPath); | |
repo.loadAs("tree", tree, onTree); | |
function onTree(err, tree) { | |
if (err) return callback(err); | |
var name = names.shift(); | |
var entry = findByName(tree, name); | |
// return undefined for not-found errors | |
if (!entry) return callback(); | |
// If there are still segments left, keep reading tree paths | |
if (names.length) return repo.loadAs("tree", entry.hash, onTree); | |
// Otherwise, load and return the blob | |
repo.loadAs("blob", entry.hash, callback); | |
} | |
} | |
function findByName(tree, name) { | |
for (var i = 0, l = tree.length; i < l; i++) { | |
var entry = tree[i]; | |
if (entry.name === name) return entry; | |
} | |
} | |
function cleanPath(name) { | |
return name && name !== "."; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment