2012-05-17 34 views
8

Làm thế nào để sao chép một repo (với libgit2)Clone một repo git (sâu)

tôi muốn làm chính xác những gì git clone không nhưng với libgit2. Những gì tôi có thể hỏi là những gì git clone thực sự chuyên sâu.

Đây là những gì tôi đang làm cho đến nay:

  1. Khởi tạo một repo
  2. Điều chỉnh tập tin cấu hình để thêm điều khiển từ xa
  3. Tạo một git_remote
  4. Tải về một packfile
  5. Index gói và ghi chỉ mục (cung cấp cho chúng tôi tệp .idx)
  6. (chỉnh sửa) Viết tất cả các nhánh khác nhau vào đĩa.
  7. (chỉnh sửa) Làm git checkout theo một cách nào đó.

Và bây giờ tôi không biết phải làm gì. Dự đoán duy nhất của tôi là tải .idx đến git_index và sử dụng git_repository_set_index, nhưng điều đó cũng không hiển thị bất kỳ tệp nào.

Sửa

Tôi đã thử nghiệm chạy git checkout master trên repo nửa nhân bản, và điều đó đã làm các công việc. Bây giờ tôi chỉ cần tìm hiểu làm thế nào để làm điều đó với libgit2, và nó có vẻ như có một số thông tin hữu ích trong bộ theo dõi vấn đề.

Chỉnh sửa 2

bây giờ tôi sẽ thêm mã hiện tại của tôi, trong hy vọng rằng ai đó một ngày nào đó sẽ tìm thấy nó hữu ích, trong hy vọng được rằng mã nhanh chóng bắt đầu tôi không bao giờ được tìm thấy. Lưu ý: Tôi đang sử dụng Obj-CObjective-Git tại đây, nhưng chủ yếu là đồng bằng c.

+ (GTRepository *)cloneFromRemoteURL:(NSURL *)remoteURL toLocalURL:(NSURL *)localURL 
{ 
// Let's suppose the URL looks like: https://github.com/libgit2/libgit2.git 
// Then we need to get a URL like this too: git://github.com/libgit2/libgit2.git 
// This may be a bit dodgy, but it will do for now. 
const char *gitURL = [remoteURL.absoluteString stringByReplacingOccurrencesOfString:@"https://github.com/" withString:@"git://github.com/"].UTF8String; 

//Setup 
int error; 
git_repository *repo 
git_config *cfg; 
git_remote *remote; 

NSURL *gitDirURL = [localURL URLByAppendingPathComponent:@".git"]; 

error = git_repository_open(&repo, gitDirURL.path.UTF8String); 
    if (error != GIT_SUCCESS) { 

    git_repository_init(&repo, gitDirURL.path.UTF8String, 1); 

    //Config 
    git_repository_config(&cfg, repo); 
    git_config_set_int32 (cfg, "core.repositoryformatversion", 0); 
    git_config_set_bool (cfg, "core.filemode", 1); 
    git_config_set_bool (cfg, "core.bare", 0); 
    git_config_set_bool (cfg, "core.logallrefupdates", 1); 
    git_config_set_bool (cfg, "core.ignorecase", 1); 
    git_config_set_string (cfg, "remote.origin.url", gitURL); 
    git_config_set_string (cfg, "remote.origin.fetch", "+refs/heads/*:refs/remotes/origin/*"); 
    git_config_set_string (cfg, "branch.master.remote", "origin"); 
    git_config_set_string (cfg, "branch.master.merge", "refs/heads/master"); 

    git_repository_set_workdir(repo, localURL.path.UTF8String); 

    error = git_remote_new(&remote, repo, "A remote", gitURL, "origin"); 

    git_repository_free(repo); 
    git_repository_open (&repo, localURL.path.UTF8String); 
} 



git_repository_config(&cfg, repo); 

// connect to repo 
error = git_remote_load(&remote, repo, "origin"); 

error = git_remote_connect(remote, GIT_DIR_FETCH); 
// get pack file 

git_off_t bytes; 
git_indexer_stats stats; 
error = git_remote_download(remote, &bytes, &stats); 

NSURL *packFolderURL = [localURL URLByAppendingPathComponent:@".git/objects/pack"]; 
NSFileManager *fileManager = [NSFileManager defaultManager]; 
NSArray *array = [fileManager contentsOfDirectoryAtURL:packFolderURL includingPropertiesForKeys:nil options:0 error:nil]; 
NSLog(@"Dictionary:%@",array); 
NSString *result; 
for (NSURL *url in array) { 
    if ([url.path rangeOfString:@".pack"].location != NSNotFound) { 
     result = url.path; 
    } 
} 
const char *packname = [result UTF8String]; 


// unpack pack file 
if (packname != NULL) 
{ 
    git_indexer *indexer; 
    git_indexer_stats stats2; 
    int error; 
    char hash[GIT_OID_HEXSZ + 1] = {0}; 

    error = git_indexer_new(&indexer, packname); 
    error = git_indexer_run(indexer, &stats2); 
    error = git_indexer_write(indexer); 

    // Get the packfile's hash (which should become it's filename) 
    git_oid_fmt(hash, git_indexer_hash(indexer)); 

    NSString *hashStr = [NSString stringWithCString:hash encoding:NSUTF8StringEncoding]; 
    hashStr = [NSString stringWithFormat:@"pack-%@.idx",hashStr]; 
    const char *indexPath = [hashStr UTF8String]; 

    puts(hash); 
    git_index *index; 
    git_index_open(&index, indexPath); 
    git_index_read(index); 
    git_repository_set_index(repo, index); 


    git_indexer_free(indexer); 
    git_remote_update_tips(remote, update_cb2); //No idea what it does, but it seems like it's important… It does make the branches appear in .git/refs/remotes/origin 

} 

// Bằng cách nào đó làm git checkout chính vào đây

return [GTRepository repositoryWithURL:localURL error:nil]; 

} 
+0

Phản hồi thú vị. Điều đó nên được tích hợp bằng cách nào đó trong 'gitlib2' lib. – VonC

Trả lời