Permalink
Browse files

get sha packing and unpacking working

  • Loading branch information...
1 parent 5718e04 commit 85eed4ede0bacf46d6438ea6e2ebf1deeb90add1 @schacon committed Aug 29, 2008
Showing with 151 additions and 53 deletions.
  1. +90 −21 src/git.c
  2. +25 −17 src/git.h
  3. +12 −6 src/test_git.c
  4. +24 −9 test/test_basic.c
View
@@ -2,7 +2,8 @@
* libGit
*/
-/* NOTE : I use rawsha for the 20 char version, and sha1 for the 40 char version */
+/* NOTE : I use rawsha for the 20 char version,
+ and sha1 for the 40 char version */
#include <stdlib.h>
#include <string.h>
@@ -17,36 +18,104 @@ static char *git_repo_dir;
*/
void git_setup(char *git_directory)
{
- git_repo_dir = git_directory;
+ git_repo_dir = git_directory;
}
/*
* return git_object struct of object pointed to by sha
-git_object git_get_object(char *sha)
+ */
+git_object git_object_from_sha(char *sha1)
{
- git_object object;
- //strcpy(object.sha, sha);
- return object;
+ git_object object;
+ char *git_object_path;
+
+ // check for loose, then packfile
+ if(git_object_is_loose(sha1)) {
+ git_object_path = git_loose_path_from_sha(sha1);
+ //strcpy(object.sha1, sha1);
+ } else {
+ // !! TODO - PACKFILE !!
+ }
+
+ return object;
}
-*/
-char *git_get_contents(git_object obj)
-{
- return "contents";
+/*
+ * returns 1 if the object for this sha is loose, 0 if it is in a packfile
+ */
+int git_object_is_loose(char *sha1) {
+ return 1;
}
+
char *git_loose_path_from_sha(char *sha1)
{
- int len = strlen(git_repo_dir);
- char *file_path;
- file_path = (char *) malloc(len + 51); // sha + 'objects' + three '/'s + null byte
- memcpy(file_path, git_repo_dir, len);
- memcpy(file_path + len, "/objects/", 9);
- memcpy(file_path + len + 9, sha1, 2);
- memcpy(file_path + len + 12, sha1 + 2, 38);
- file_path[len + 11] = '/';
- file_path[len + 50] = 0;
- return file_path;
+ int len = strlen(git_repo_dir);
+ char *file_path;
+ file_path = (char *) malloc(len + 51); // sha + 'objects' + three '/'s + null byte
+ memcpy(file_path, git_repo_dir, len);
+ memcpy(file_path + len, "/objects/", 9);
+ memcpy(file_path + len + 9, sha1, 2);
+ memcpy(file_path + len + 12, sha1 + 2, 38);
+ file_path[len + 11] = '/';
+ file_path[len + 50] = 0;
+ return file_path;
+}
+
+/*
+ * returns readable hex version of 20-char sha binary
+ */
+int git_unpack_hex(const unsigned char *rawsha, char *sha1)
+{
+ static const char hex[] = "0123456789abcdef";
+ int i;
+
+ for (i = 0; i < 20; i++) {
+ unsigned char n = rawsha[i];
+ sha1[i * 2] = hex[((n >> 4) & 15)];
+ n <<= 4;
+ sha1[(i * 2) + 1] = hex[((n >> 4) & 15)];
+ }
+ sha1[40] = 0;
+
+ return 1;
+}
+
+/*
+ * fills 20-char sha from 40-char hex version
+ */
+int git_pack_hex(const char *sha1, unsigned char *rawsha)
+{
+ unsigned char byte = 0;
+ int i, j = 0;
+
+
+ for (i = 1; i <= 40; i++) {
+ unsigned char n = sha1[i - 1];
+
+ if(is_alpha(n)) {
+ byte |= ((n & 15) + 9) & 15;
+ } else {
+ byte |= (n & 15);
+ }
+ if(i & 1) {
+ byte <<= 4;
+ } else {
+ rawsha[j] = (byte & 0xff);
+ j++;
+ byte = 0;
+ }
+ }
+ return 1;
+}
+
+
+int is_alpha(unsigned char n)
+{
+ if(n <= 102 && n >= 97) {
+ return 1;
+ }
+ return 0;
}
@@ -64,4 +133,4 @@ char *libgit_version()
char *get_git_repo_dir()
{
return git_repo_dir;
-}
+}
View
@@ -12,41 +12,49 @@
typedef struct {
- char type;
- int size;
- unsigned char rawsha[20];
+ char type;
+ int size;
+ unsigned char rawsha[20];
} git_object;
typedef struct {
- char mode[7];
- struct git_object *object;
- char name[255];
+ char mode[7];
+ struct git_object *object;
+ char name[255];
} git_tree_node;
typedef struct {
- char *author_name;
- int author_date;
- char *committer_name;
- int committer_date;
- struct git_object *tree;
- struct git_parent *parent;
- char *message;
+ char *author_name;
+ int author_date;
+ char *committer_name;
+ int committer_date;
+ struct git_object *tree;
+ struct git_parent *parent;
+ char *message;
} git_commit_data;
typedef struct {
- struct git_object *object;
- struct git_parent *parent;
+ struct git_object *object;
+ struct git_parent *parent;
} git_parent;
void git_setup(char *git_directory);
-//git_object git_get_object(char *sha);
+git_object git_object_from_sha(char *sha1);
+
+int git_object_is_loose(char *sha);
char *git_loose_path_from_sha(char *sha1);
char *git_get_contents(git_object obj);
char *libgit_version();
-char *get_git_repo_dir();
+char *get_git_repo_dir();
+
+int git_unpack_hex(const unsigned char *rawsha, char *sha1);
+
+int git_pack_hex(const char *sha1, unsigned char *rawsha);
+
+int is_alpha(unsigned char n);
View
@@ -8,9 +8,15 @@
*/
int main(int argc, char *argv[])
{
- git_setup("/tmp/gittest/test.git");
- char *tester;
- tester = git_loose_path_from_sha("34197fb6abac000a2af7482f4876de45ba33d1f0");
- printf("test: %s\n", tester);
- return 0;
-}
+ unsigned char rawsha[20];
+ char sha[41];
+ char tester[] = "a600f1d158be31b96cb4502b8768b202c358ad20";
+
+ git_setup("/tmp/gittest/.git");
+
+ git_pack_hex(tester, rawsha);
+ printf("raw: (%s)\n", rawsha);
+ git_unpack_hex(rawsha, sha);
+ printf("sha: (%s)\n", sha);
+ return 0;
+}
View
@@ -9,29 +9,44 @@ int tests_run = 0;
/* TESTS */
static char * test_git_version() {
- mu_assert("libGit version not returned", libgit_version() == "0.1");
- return 0;
+ mu_assert("libGit version not returned", libgit_version() == "0.1");
+ return 0;
}
static char * test_git_setup() {
- git_setup("/tmp/git.git");
- mu_assert("git setup failed", get_git_repo_dir() == "/tmp/git.git");
- return 0;
+ git_setup("/tmp/git.git");
+ mu_assert("git setup failed", get_git_repo_dir() == "/tmp/git.git");
+ return 0;
}
static char * test_loose_path_from_sha() {
- git_setup("/tmp/git.git");
- mu_assert("git loose sha failed", \
- git_loose_path_from_sha("34197fb6abac000a2af7482f4876de45ba33d1f0") == "/tmp/git.git/objects/34/197fb6abac000a2af7482f4876de45ba33d1f0");
- return 0;
+ git_setup("/tmp/git.git");
+ mu_assert("git loose sha failed", \
+ strcmp(git_loose_path_from_sha("34197fb6abac000a2af7482f4876de45ba33d1f0"), "/tmp/git.git/objects/34/197fb6abac000a2af7482f4876de45ba33d1f0") == 0);
+ return 0;
}
+static char * test_pack_unpack_sha() {
+ unsigned char rawsha[20];
+ char sha[41];
+ char tester[] = "a600f1d158be31b96cb4502b8768b202c358ad20";
+
+ git_pack_hex(tester, rawsha);
+ git_unpack_hex(rawsha, sha);
+
+ //printf("1: [%s]\n", tester);
+ //printf("2: [%s]\n", sha);
+
+ mu_assert("git pack/unpack sha failed", strcmp(sha, tester) == 0);
+ return 0;
+}
/* TEST RUNNING STUFF */
static char * all_tests() {
mu_run_test(test_git_version);
mu_run_test(test_git_setup);
+ mu_run_test(test_pack_unpack_sha);
mu_run_test(test_loose_path_from_sha);
return 0;
}

0 comments on commit 85eed4e

Please sign in to comment.