diff --git a/ide/app/lib/git/commands/checkout.dart b/ide/app/lib/git/commands/checkout.dart index 0a511d4d2..a81960f62 100644 --- a/ide/app/lib/git/commands/checkout.dart +++ b/ide/app/lib/git/commands/checkout.dart @@ -58,7 +58,7 @@ class Checkout { return Conditions.checkForUncommittedChanges(root, store).then( (GitConfig config) { return _cleanWorkingDir(root).then((_) { - return store.retrieveObject(branchSha, ObjectTypes.COMMIT).then( + return store.retrieveObject(branchSha, ObjectTypes.COMMIT_STR).then( (CommitObject commit) { return ObjectUtils.expandTree(root, store, commit.treeSha) .then((_) { diff --git a/ide/app/lib/git/commands/clone.dart b/ide/app/lib/git/commands/clone.dart index 059dc88f2..653229cf0 100644 --- a/ide/app/lib/git/commands/clone.dart +++ b/ide/app/lib/git/commands/clone.dart @@ -78,7 +78,7 @@ class Clone { Future _createCurrentTreeFromPack(chrome.DirectoryEntry dir, ObjectStore store, String headSha) { - return store.retrieveObject(headSha, ObjectTypes.COMMIT).then((commit) { + return store.retrieveObject(headSha, ObjectTypes.COMMIT_STR).then((commit) { return ObjectUtils.expandTree(dir, store, commit.treeSha); }); } diff --git a/ide/app/lib/git/commands/commit.dart b/ide/app/lib/git/commands/commit.dart index b3aeec15b..b66aad501 100644 --- a/ide/app/lib/git/commands/commit.dart +++ b/ide/app/lib/git/commands/commit.dart @@ -86,7 +86,7 @@ class Commit { if (parent.isEmpty) { return null; } else { - return store.retrieveObject(parent, ObjectTypes.COMMIT).then( + return store.retrieveObject(parent, ObjectTypes.COMMIT_STR).then( (CommitObject parentCommit) { String oldTree = parentCommit.treeSha; if (oldTree == sha) { @@ -123,21 +123,10 @@ class Commit { String refName) { chrome.DirectoryEntry dir = options.root; ObjectStore store = options.store; - String name = options.name; - String email = options.email; - String commitMsg = options.commitMessage; - - if (name == null) { - name = ""; - } - - if (email == null) { - email = ""; - } - - if (commitMsg == null) { - commitMsg = ""; - } + String name = options.name == null ? "" : options.name; + String email = options.email == null ? "" : options.email; + String commitMsg = options.commitMessage == null ? "" + : options.commitMessage; return walkFiles(dir, store).then((String sha) { return checkTreeChanged(store, parent, sha).then((_) { @@ -158,17 +147,12 @@ class Commit { } } - commitContent.write('author ${name}'); - commitContent.write(' <${email}> '); - commitContent.write(dateString); - commitContent.write('\n'); - commitContent.write('committer ${name}'); - commitContent.write(' <${email}> '); - commitContent.write(dateString); + commitContent.write('author ${name} <${email}> ${dateString}\n'); + commitContent.write('committer ${name} <${email}> ${dateString}'); commitContent.write('\n\n${commitMsg}\n'); return store.writeRawObject( - ObjectTypes.COMMIT, commitContent.toString()).then( + ObjectTypes.COMMIT_STR, commitContent.toString()).then( (String commitSha) { return FileOps.createFileWithContent(dir, '.git/${refName}', commitSha + '\n', 'Text').then((_) { diff --git a/ide/app/lib/git/commands/merge.dart b/ide/app/lib/git/commands/merge.dart index ee3acb475..d1720bae3 100644 --- a/ide/app/lib/git/commands/merge.dart +++ b/ide/app/lib/git/commands/merge.dart @@ -210,7 +210,7 @@ class Merge { } }); } else { - return store.retrieveObjectList(shas, ObjectTypes.TREE).then( + return store.retrieveObjectList(shas, ObjectTypes.TREE_STR).then( (List trees) { return mergeTrees(store, trees[0], trees[1], trees[2]).then( (String mergedSha) { diff --git a/ide/app/lib/git/commands/pull.dart b/ide/app/lib/git/commands/pull.dart index 1d49ba557..3e15545ab 100644 --- a/ide/app/lib/git/commands/pull.dart +++ b/ide/app/lib/git/commands/pull.dart @@ -123,7 +123,7 @@ class Pull { shaBytesToString(mergeEntry['new'].sha)); } else { return store.retrieveObjectList([mergeEntry['old'].sha, - mergeEntry['new'].sha], ObjectTypes.TREE).then( + mergeEntry['new'].sha], ObjectTypes.TREE_STR).then( (List trees) { TreeDiffResult treeDiff2 = Merge.diffTree(trees[0], trees[1]); return dir.createDirectory(mergeEntry['new'].name).then( diff --git a/ide/app/lib/git/object.dart b/ide/app/lib/git/object.dart index fb5c8921f..001a7f9fb 100644 --- a/ide/app/lib/git/object.dart +++ b/ide/app/lib/git/object.dart @@ -26,14 +26,14 @@ abstract class GitObject { static GitObject make(String sha, String type, content, [LooseObject rawObj]) { switch (type) { - case ObjectTypes.BLOB: + case ObjectTypes.BLOB_STR: return new BlobObject(sha, content); - case ObjectTypes.TREE: + case ObjectTypes.TREE_STR: case "Tree": return new TreeObject(sha, content, rawObj); - case ObjectTypes.COMMIT: + case ObjectTypes.COMMIT_STR: return new CommitObject(sha, content, rawObj); - case ObjectTypes.TAG: + case ObjectTypes.TAG_STR: return new TagObject(sha, content); default: throw new ArgumentError("Unsupported git object type: ${type}"); @@ -43,7 +43,7 @@ abstract class GitObject { GitObject([this._sha, this.data]); // The type of git object. - String _type; + String type; dynamic data; String _sha; @@ -62,8 +62,6 @@ class TreeEntry { TreeEntry(this.name, this.sha, this.isBlob); } - - /** * Error thrown for a parse failure. */ @@ -91,7 +89,7 @@ class TreeObject extends GitObject { TreeObject( [String sha, Uint8List data, LooseObject rawObj]) : super(sha, data) { - this._type = ObjectTypes.TREE; + this.type = ObjectTypes.TREE_STR; this.rawObj = rawObj; _parse(); } @@ -134,7 +132,7 @@ class TreeObject extends GitObject { class BlobObject extends GitObject { BlobObject(String sha, String data) : super(sha, data) { - this._type = ObjectTypes.BLOB; + this.type = ObjectTypes.BLOB_STR; } } @@ -165,7 +163,7 @@ class CommitObject extends GitObject { LooseObject rawObj; CommitObject(String sha, var data, [rawObj]) { - this._type = ObjectTypes.COMMIT; + this.type = ObjectTypes.COMMIT_STR; this._sha = sha; this.rawObj = rawObj; @@ -177,7 +175,6 @@ class CommitObject extends GitObject { // TODO: Clarify this exception. throw "Data is in incompatible format."; } - _parseData(); } @@ -251,26 +248,15 @@ class CommitObject extends GitObject { */ class TagObject extends GitObject { TagObject(String sha, String data) : super(sha, data) { - this._type = ObjectTypes.TAG; + this.type = ObjectTypes.TAG_STR; } } /** * A loose git object. */ -class LooseObject { +class LooseObject extends GitObject { int size; - int type; - - static Map _typeMap = { - ObjectTypes.COMMIT : 1, - ObjectTypes.TREE : 2, - ObjectTypes.BLOB : 3 - }; - - // Represents either an ArrayBuffer or a string representation of byte - //stream. - dynamic data; LooseObject(buf) { _parse(buf); @@ -299,7 +285,18 @@ class LooseObject { this.data = buf.substring(i + 1, buf.length); } List parts = header.split(' '); - this.type = _typeMap[parts[0]]; + this.type = parts[0]; this.size = int.parse(parts[1]); } } + +/** + * Encapsulates a git pack object. + */ +class PackedObject extends GitObject { + List sha; + String baseSha; + int crc; + int offset; + int desiredOffset; +} \ No newline at end of file diff --git a/ide/app/lib/git/object_utils.dart b/ide/app/lib/git/object_utils.dart index 7021b5220..bcde0ad96 100644 --- a/ide/app/lib/git/object_utils.dart +++ b/ide/app/lib/git/object_utils.dart @@ -18,10 +18,58 @@ import 'utils.dart'; * */ abstract class ObjectTypes { - static const String BLOB = "blob"; - static const String TREE = "tree"; - static const String COMMIT = "commit"; - static const String TAG = "tag"; + + static const String BLOB_STR = "blob"; + static const String TREE_STR = "tree"; + static const String COMMIT_STR = "commit"; + static const String TAG_STR = "tag"; + static const String OFS_DELTA_STR = "ofs_delta"; + static const String REF_DELTA_STR = "ref_delta"; + + static const int COMMIT = 1; + static const int TREE = 2; + static const int BLOB = 3; + static const int TAG = 4; + static const int OFS_DELTA = 6; + static const int REF_DELTA = 7; + + static String getTypeString(int type) { + switch(type) { + case COMMIT: + return COMMIT_STR; + case TREE: + return TREE_STR; + case BLOB: + return BLOB_STR; + case TAG: + return TAG_STR; + case OFS_DELTA: + return OFS_DELTA_STR; + case REF_DELTA: + return REF_DELTA_STR; + default: + throw "unsupported pack type ${type}."; + } + } + + static int getType(String type) { + switch(type) { + case COMMIT_STR: + return COMMIT; + case TREE_STR: + return TREE; + case BLOB_STR: + return BLOB; + case TAG_STR: + return TAG; + case OFS_DELTA_STR: + return OFS_DELTA; + case REF_DELTA_STR: + return REF_DELTA; + default: + throw "unsupported pack type ${type}."; + } + } } /** @@ -32,10 +80,12 @@ abstract class ObjectUtils { /** * Expands a git blob object into a file and writes on disc. */ - static Future expandBlob(chrome.DirectoryEntry dir, ObjectStore store, - String fileName, String blobSha) { - return store.retrieveObject(blobSha, ObjectTypes.BLOB).then((BlobObject blob) { - return FileOps.createFileWithContent(dir, fileName, blob.data, ObjectTypes.BLOB); + static Future expandBlob(chrome.DirectoryEntry dir, + ObjectStore store, String fileName, String blobSha) { + return store.retrieveObject(blobSha, ObjectTypes.BLOB_STR).then( + (BlobObject blob) { + return FileOps.createFileWithContent(dir, fileName, blob.data, + ObjectTypes.BLOB_STR); }); } diff --git a/ide/app/lib/git/objectstore.dart b/ide/app/lib/git/objectstore.dart index 9bcc303b9..7b0448148 100644 --- a/ide/app/lib/git/objectstore.dart +++ b/ide/app/lib/git/objectstore.dart @@ -39,9 +39,9 @@ class GitRef { GitRef(this.sha, this.name, [this.type, this.remote]); - getPktLine() => '${sha} ${head} ${name}'; + String getPktLine() => '${sha} ${head} ${name}'; - toString() => getPktLine(); + String toString() => getPktLine(); } class GitConfig { @@ -161,7 +161,8 @@ class ObjectStore { } Future getHeadRef() { - return _rootDir.getFile(gitPath + HEAD_PATH).then((chrome.ChromeFileEntry entry) { + return _rootDir.getFile(gitPath + HEAD_PATH).then( + (chrome.ChromeFileEntry entry) { return entry.readBytes().then((chrome.ArrayBuffer buffer) { String content = UTF8.decode(buffer.getBytes()); // get rid of the initial 'ref: ' plus newline at end. @@ -220,7 +221,7 @@ class ObjectStore { Future _findLooseObject(String sha) => objectDir.getFile( sha.substring(0, 2) + '/' + sha.substring(2)); - FindPackedObjectResult findPackedObject(Uint8List shaBytes) { + FindPackedObjectResult findPackedObject(List shaBytes) { for (var i = 0; i < packs.length; ++i) { int offset = packs[i].packIdx.getObjectOffset(shaBytes); @@ -232,8 +233,9 @@ class ObjectStore { return throw("Not found."); } - Future retrieveObject(String sha, String objType) { - String dataType = (objType == ObjectTypes.COMMIT ? "Text" : "ArrayBuffer"); + Future retrieveObject(String sha, String objType) { + String dataType = (objType == ObjectTypes.COMMIT_STR ? "Text" + : "ArrayBuffer"); return retrieveRawObject(sha, dataType).then((object) { if (objType == 'Raw') { return object; @@ -245,7 +247,7 @@ class ObjectStore { }); } - Future retrieveRawObject(dynamic sha, String dataType) { + Future retrieveRawObject(dynamic sha, String dataType) { Uint8List shaBytes; if (sha is Uint8List) { shaBytes = sha; @@ -294,7 +296,8 @@ class ObjectStore { seen[sha] = true; - return retrieveObject(sha, ObjectTypes.COMMIT).then((CommitObject commitObj) { + return retrieveObject(sha, ObjectTypes.COMMIT_STR).then( + (CommitObject commitObj) { nextLevel.addAll(commitObj.parents); int i = commits.length - 1; for (; i >= 0; i--) { @@ -329,11 +332,12 @@ class ObjectStore { Future _checkRemoteHead(GitRef remoteRef) { // Check if the remote head exists in the local repo. if (remoteRef.sha != HEAD_MASTER_SHA) { - return retrieveObject(remoteRef.sha, ObjectTypes.COMMIT).then((obj) => obj, - onError: (e) { - //TODO support non-fast forward. - _nonFastForward(); - throw(e); + return retrieveObject(remoteRef.sha, ObjectTypes.COMMIT_STR).then( + (obj) => obj, + onError: (e) { + //TODO support non-fast forward. + _nonFastForward(); + throw(e); }); } return new Future.value(); @@ -389,7 +393,7 @@ class ObjectStore { var commits = []; Future getNextCommit(String sha) { - return retrieveObject(sha, ObjectTypes.COMMIT).then(( + return retrieveObject(sha, ObjectTypes.COMMIT_STR).then(( CommitObject commitObj) { Completer completer = new Completer(); @@ -461,8 +465,9 @@ class ObjectStore { } Future _getTreeFromCommitSha(String sha) { - return retrieveObject(sha, ObjectTypes.COMMIT).then((CommitObject commit) { - return retrieveObject(commit.treeSha, ObjectTypes.TREE).then( + return retrieveObject(sha, ObjectTypes.COMMIT_STR).then( + (CommitObject commit) { + return retrieveObject(commit.treeSha, ObjectTypes.TREE_STR).then( (rawObject) => rawObject); }); } @@ -579,7 +584,7 @@ class ObjectStore { blobParts.add(tree.sha); }); - return writeRawObject(ObjectTypes.TREE, new Blob(blobParts)); + return writeRawObject(ObjectTypes.TREE_STR, new Blob(blobParts)); } Future getConfig() { diff --git a/ide/app/lib/git/pack.dart b/ide/app/lib/git/pack.dart index 30adc8d7c..ff1b50bf8 100644 --- a/ide/app/lib/git/pack.dart +++ b/ide/app/lib/git/pack.dart @@ -18,51 +18,11 @@ import 'package:utf/utf.dart'; import 'file_operations.dart'; import 'object.dart'; +import 'object_utils.dart'; import 'objectstore.dart'; import 'utils.dart'; import 'zlib.dart'; -/** - * Encapsulates a git pack object. - */ -class PackObject { - List sha; - String baseSha; - int crc; - int offset; - int type; - int desiredOffset; - Uint8List data; -} - -class PackedTypes { - static const COMMIT = 1; - static const TREE = 2; - static const BLOB = 3; - static const TAG = 4; - static const OFS_DELTA = 6; - static const REF_DELTA = 7; - - static String getTypeString(int type) { - switch(type) { - case COMMIT: - return "commit"; - case TREE: - return "tree"; - case BLOB: - return "blob"; - case TAG: - return "tag"; - case OFS_DELTA: - return "ofs_delta"; - case REF_DELTA: - return "ref_delta"; - default: - throw "unsupported pack type."; - } - } -} - /** * Encapsulates a pack object header. */ @@ -87,7 +47,7 @@ class Pack { Uint8List data; int _offset = 0; ObjectStore _store; - List objects = []; + List objects = []; Pack(Uint8List data, store) { this.data = data; @@ -145,9 +105,8 @@ class Pack { /** * Returns a SHA1 hash of given data. */ - List getObjectHash(int type, Uint8List contentData) { - List header = encodeUtf8(PackedTypes.getTypeString(type) - + " ${contentData.length}\u0000"); + List getObjectHash(String type, Uint8List contentData) { + List header = encodeUtf8(type + " ${contentData.length}\u0000"); Uint8List fullContent = new Uint8List(header.length + contentData.length); @@ -204,23 +163,23 @@ class Pack { return header.offset - offsetDelta; } - Future expandDeltifiedObject(PackObject object) { + Future expandDeltifiedObject(PackedObject object) { Completer completer = new Completer(); - PackObject doExpand(PackObject baseObj, PackObject deltaObj) { + PackedObject doExpand(PackedObject baseObj, PackedObject deltaObj) { deltaObj.type = baseObj.type; deltaObj.data = applyDelta(baseObj.data, deltaObj.data); deltaObj.sha = getObjectHash(deltaObj.type, deltaObj.data); return deltaObj; } - if (object.type == PackedTypes.OFS_DELTA) { - PackObject baseObj = _matchObjectAtOffset(object.desiredOffset); + if (object.type == ObjectTypes.OFS_DELTA_STR) { + PackedObject baseObj = _matchObjectAtOffset(object.desiredOffset); switch (baseObj.type) { - case PackedTypes.OFS_DELTA: - case PackedTypes.REF_DELTA: + case ObjectTypes.OFS_DELTA_STR: + case ObjectTypes.REF_DELTA_STR: return expandDeltifiedObject(baseObj).then(( - PackObject expandedObject) => doExpand(expandedObject, object)); + PackedObject expandedObject) => doExpand(expandedObject, object)); default: completer.complete(doExpand(baseObj, object)); } @@ -243,18 +202,18 @@ class Pack { } - PackObject _matchObjectData(PackObjectHeader header) { + PackedObject _matchObjectData(PackObjectHeader header) { - PackObject object = new PackObject(); + PackedObject object = new PackedObject(); object.offset = header.offset; - object.type = header.type; + object.type = ObjectTypes.getTypeString(header.type); switch (header.type) { - case PackedTypes.OFS_DELTA: + case ObjectTypes.OFS_DELTA: object.desiredOffset = findDeltaBaseOffset(header); break; - case PackedTypes.REF_DELTA: + case ObjectTypes.REF_DELTA: Uint8List shaBytes = _peek(20); _advance(20); object.baseSha = shaBytes.map((int byte) { @@ -272,20 +231,20 @@ class Pack { return object; } - Future matchAndExpandObjectAtOffset(int startOffset, + Future matchAndExpandObjectAtOffset(int startOffset, String dataType) { - PackObject object = _matchObjectAtOffset(startOffset); + PackedObject object = _matchObjectAtOffset(startOffset); switch (object.type) { - case PackedTypes.OFS_DELTA: - case PackedTypes.REF_DELTA: + case ObjectTypes.OFS_DELTA_STR: + case ObjectTypes.REF_DELTA_STR: return expandDeltifiedObject(object); default: return new Future.value(object); } } - PackObject _matchObjectAtOffset(int startOffset) { + PackedObject _matchObjectAtOffset(int startOffset) { _offset = startOffset; return _matchObjectData(_getObjectHeader()); } @@ -296,20 +255,20 @@ class Pack { try { int numObjects; - List deferredObjects = []; + List deferredObjects = []; _matchPrefix(); _matchVersion(2); numObjects = _matchNumberOfObjects(); for (int i = 0; i < numObjects; ++i) { - PackObject object = _matchObjectAtOffset(_offset); + PackedObject object = _matchObjectAtOffset(_offset); object.crc = getCrc32(data.sublist(object.offset, _offset)); // hold on to the data for delta style objects. switch (object.type) { - case PackedTypes.OFS_DELTA: - case PackedTypes.REF_DELTA: + case ObjectTypes.OFS_DELTA_STR: + case ObjectTypes.REF_DELTA_STR: deferredObjects.add(object); break; default: @@ -320,8 +279,8 @@ class Pack { } objects.add(object); } - return Future.forEach(deferredObjects, (PackObject obj) { - return expandDeltifiedObject(obj).then((PackObject deltifiedObj) { + return Future.forEach(deferredObjects, (PackedObject obj) { + return expandDeltifiedObject(obj).then((PackedObject deltifiedObj) { deltifiedObj.data = null; // TODO(grv) : add progress. }); @@ -410,7 +369,8 @@ class Pack { // TODO(grv) : check if this is a version 2 packfile and apply // copyFromResult if so. copyFromResult = (opcode & 0x01); - Uint8List sublist = baseData.sublist(copyOffset, copyOffset + copyLength); + Uint8List sublist = baseData.sublist(copyOffset, + copyOffset + copyLength); resultData.setAll(resultOffset, sublist); resultOffset += sublist.length; } else if ((opcode & 0x80) == 0) { @@ -448,7 +408,7 @@ class PackBuilder { }); } - Uint8List _packTypeSizeBits(int type, int size) { + List _packTypeSizeBits(int type, int size) { int typeBits = type; int shifter = size; List bytes = []; @@ -463,7 +423,7 @@ class PackBuilder { idx++; shifter >>= 7; } - return new Uint8List.fromList(bytes); + return bytes; } void _packIt(LooseObject object) { @@ -481,7 +441,8 @@ class PackBuilder { ByteBuffer compressed; compressed = new Uint8List.fromList(Zlib.deflate(data).buffer .getBytes()).buffer; - _packed.add(_packTypeSizeBits(object.type, data.length)); + _packed.add(_packTypeSizeBits(ObjectTypes.getType(object.type), + data.length)); _packed.add(compressed); } diff --git a/ide/app/lib/git/pack_index.dart b/ide/app/lib/git/pack_index.dart index 6b73fb5c8..817b56b2d 100644 --- a/ide/app/lib/git/pack_index.dart +++ b/ide/app/lib/git/pack_index.dart @@ -10,7 +10,7 @@ import 'dart:typed_data'; import 'package:crypto/crypto.dart' as crypto; -import 'pack.dart'; +import 'object.dart'; /** * This class partially parses the data contained in a pack-*.idx file, and @@ -148,7 +148,7 @@ class PackIndex { /** * Creates a pack file index and returns the bytestream. */ - static Uint8List writePackIndex(List objects, List packSha) { + static Uint8List writePackIndex(List objects, List packSha) { int size = 4 + 4 + (256 * 4) + (objects.length * 20) + (objects.length * 4) + (objects.length * 4) + (20 * 2); @@ -189,21 +189,21 @@ class PackIndex { byteOffset += (256 * 4); // Write list of shas. - objects.forEach((PackObject obj) { + objects.forEach((PackedObject obj) { for (int j = 0; j < 20; ++j) { data.setUint8(byteOffset++, obj.sha[j]); } }); // Write list of crcs. - objects.forEach((PackObject obj) { + objects.forEach((PackedObject obj) { data.setUint32(byteOffset, obj.crc); byteOffset +=4; }); // Write list of offsets. Only upto 32 bit long offsets are supported. // TODO(grv) : add support for longer offsets(maybe). - objects.forEach((PackObject obj) { + objects.forEach((PackedObject obj) { data.setUint32(byteOffset, obj.offset); byteOffset += 4; }); diff --git a/ide/app/lib/git/upload_pack_parser.dart b/ide/app/lib/git/upload_pack_parser.dart index 3331f5a10..d015627fa 100644 --- a/ide/app/lib/git/upload_pack_parser.dart +++ b/ide/app/lib/git/upload_pack_parser.dart @@ -11,6 +11,7 @@ import 'dart:html'; import 'dart:typed_data'; import 'file_operations.dart'; +import 'object.dart'; import 'objectstore.dart'; import 'pack.dart'; @@ -23,7 +24,7 @@ class PktLine { } class PackParseResult { - List objects; + List objects; String shallow; List common; Uint8List data;