2012-05-17 15 views
8

Cómo clonar un acuerdo de recompra (con libgit2)clonar un repositorio git (en profundidad)

que quiero hacer exactamente lo que hace git clone pero con libgit2. Lo que puedo estar preguntando es qué realmente hace en profundidad el git clone.

Esto es lo que estoy haciendo hasta ahora:

  1. inicializar un repo
  2. Ajuste el archivo de configuración para agregar el control remoto
  3. Crear una git_remote
  4. Descargar una PACKFILE
  5. Índice el archivo de paquete y escriba el índice (nos da un archivo .idx)
  6. (editar) Escriba todas las ramas diferentes en el disco.
  7. (editar) Hacer git checkout de alguna manera.

Y ahora no tengo ni idea de qué hacer. Mi única conjetura sería cargar el .idx en un git_index y usar git_repository_set_index, pero eso tampoco mostró ningún archivo.

Editar

He probado correr git checkout master en el repositorio mitad clonado, y que cumplió con su cometido. Ahora solo necesito averiguar cómo hacerlo con libgit2, y parece que hay alguna información útil en el rastreador de problemas.

Editar 2

Ahora voy a añadir mi código actual, con la esperanza de que alguien, algún día será de gran utilidad, con la esperanza de ser que el código de inicio rápido que nunca encontré. Nota: Estoy usando Obj-C y Objective-Git aquí, pero es principalmente simple 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 

} 

// De alguna manera hacer git checkout master aquí

return [GTRepository repositoryWithURL:localURL error:nil]; 

} 
+0

Comentarios interesantes. Eso debería integrarse de alguna manera en la librería 'gitlib2'. – VonC

Respuesta

Cuestiones relacionadas