克隆git回购(深入) [英] Clone a git repo (in depth)

查看:140
本文介绍了克隆git回购(深入)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何克隆回购(使用 libgit2



我想要做的只是 git clone ,但是使用 libgit2 。我可能会问的是 git clone 确实深入。



这就是我所做的远:


  1. 初始化回购

  2. 调整配置文件以添加远程

  3. 创建 git_remote

  4. 下载packfile packfile并写入索引(给我们一个.idx文件)
  5. (编辑)将所有不同的分支写入磁盘。

  6. git checkout 以某种方式。

现在我没有想法该怎么做。我唯一的猜测就是将 .idx 加载到 git_index 并使用 git_repository_set_index ,但没有显示任何文件。



编辑



我在半克隆​​的回购库上测试了运行 git checkout master ,并且完成了这项工作。现在我只需要找出如何使用libgit2来做到这一点,似乎问题跟踪器中有一些有用的信息。



编辑2

strong>



现在我将添加我当前的代码,希望有人某天会发现它有用,希望能成为我从未找到的快速启动代码。注意:我在这里使用 Obj-C Objective-Git ,但主要是纯c。

  +(GTRepository *)cloneFromRemoteURL:(NSURL *)remoteURL toLocalURL:(NSURL *)localURL 
{
/ /让我们假设这个URL如下所示:https://github.com/libgit2/libgit2.git
//然后我们需要得到一个这样的URL:git://github.com/libgit2/libgit2。 git
//这可能有点狡猾,但它现在会做。
const char * gitURL = [remoteURL.absoluteString stringByReplacingOccurrencesOfString:@https://github.com/withString:@git://github.com/] .UTF8String;

//安装
int错误;
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);

//配置
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,remote,gitURL,origin);

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



git_repository_config(& cfg,repo);

//连接到repo
error = git_remote_load(& remote,repo,origin);

error = git_remote_connect(remote,GIT_DIR_FETCH);
//获取包文件

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 includesPropertiesForKeys:nil options:0 error:nil];
NSLog(@Dictionary:%@,array);
NSString *结果;
for(NSURL * url in array){
if([url.path rangeOfString:@。pack]。location!= NSNotFound){
result = url.path;
}
}
const char * packname = [result UTF8String];


//解包文件
if(packname!= NULL)
{
git_indexer * indexer;
git_indexer_stats stats2;
int错误;
char hash [GIT_OID_HEXSZ + 1] = {0};

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

//获取packfile的散列(应该变成文件名)
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); //不知道它做了什么,但它看起来很重要......它确实使分支出现在.git / refs / remotes / origin

}

//以某种方式在这里执行git checkout master

 返回[GTRepository repositoryWithURL:localURL error:nil]; 



解决方案

由于libgit2不会在其 https://github.com/libgit2/libgit2/issuesrel =nofollow>问题列表,其中一个关键是在原始git项目的源代码中:



最后一个脚本将指导您完成 git clone 的所有阶段。


How to clone a repo (with libgit2)

I want to do exactly what git clone does but with libgit2. What I may be asking is what git clone really does in depth.

This is what I'm doing so far:

  1. Initialize a repo
  2. Adjust the config file to add the remote
  3. Create a git_remote
  4. Download a packfile
  5. Index the packfile and write the index (gives us a .idx file)
  6. (edit) Write all the different branches to disk.
  7. (edit) Do git checkout in some way.

And now I have no idea what to do. My only guess would be to load the .idx to a git_index and use git_repository_set_index, but that didn't show any files either.

Edit

I tested running git checkout master on the half-cloned repo, and that did the job. Now I just need to find out how to do it with libgit2, and it seems like there is some useful information in the issue tracker.

Edit 2

I will now add my current code, in hope that someone someday will find it useful, in hope to be that quick-start code I never found. Note: I'm using Obj-C and Objective-Git here, but it's mainly plain 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

}

//Somehow do git checkout master here

return [GTRepository repositoryWithURL:localURL error:nil];

}

解决方案

Since the libgit2 doesn't explicitly mention git clone in its issue list, one lead to follow is in the sources of the original git project with:

That last script will guide you through all the stages of a git clone.

这篇关于克隆git回购(深入)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆