Clona un git repo (en profundidad)

Cómo clonar un repository (con libgit2 )

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

Esto es lo que estoy haciendo hasta ahora:

  1. Inicializar un repository
  2. Ajuste el file de configuration para agregar el control remoto
  3. Crea un git_remote
  4. Descargar un file de package
  5. Indexe el file packy y escriba el índice (nos da un file .idx)
  6. (editar) Escribe todas las diferentes twigs en el disco.
  7. (editar) Hacer el git checkout de alguna manera.

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

Editar

Probé ejecutando el git checkout master en el repository medio clonado, y eso hizo el trabajo. 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 agregaré mi código actual, con la esperanza de que alguien algún día lo encuentre útil, con la esperanza de ser 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 forma, el maestro de pago de git aquí

 return [GTRepository repositoryWithURL:localURL error:nil]; } 

Dado que libgit2 no menciona explícitamente a git clone en su list de problemas , uno de los pasos a seguir está en las fonts del proyecto original de git con:

  • builtin/clone.c
  • contrib/examples/git-clone.sh

Ese último script lo guiará a través de todas las etapas de un git clone .