/ / Checkout branch con libgit2 - c, git, git-checkout, libgit2

Filiale di checkout con libgit2 - c, git, git-checkout, libgit2

Sto cercando di implementare una semplice operazione di checkout tra 2 rami, il codice viene eseguito senza errori.

git_libgit2_init();
git_object *treeish = NULL;
git_checkout_options opts;
opts.checkout_strategy = GIT_CHECKOUT_SAFE;

/* branchName in this case is "master" */
handleError(git_revparse_single(&treeish, repo, branchName));
handleError(git_checkout_tree(repo, treeish, &opts));

git_object_free(treeish);
git_libgit2_shutdown();

Tuttavia, il ramo non cambia quando lo controllo usando git status. Ho controllato il 101 esempi di libgit2 e dice:

git_checkout_options in realtà non è molto facoltativo. Le impostazioni predefinite no essere utile al di fuori di un piccolo numero di casi. Il miglior esempio di questo è checkout_strategy; il valore predefinito non fa nulla per l'albero di lavoro. Quindi, se vuoi che il checkout controlli i file, scegli un appropriato strategia.

NONE è l'equivalente di una corsa a secco; nessun file verrà estratto.

SAFE è simile a git checkout; i file non modificati vengono aggiornati e i file modificati vengono lasciati da soli. Se un file era presente nel vecchio HEAD ma manca, è considerato cancellato e non verrà creato.

RECREATE_MISSING è simile a git checkout-indexo cosa succede dopo un clone. I file non modificati vengono aggiornati e i file mancanti sono creato, ma i file con modifiche sono lasciati da soli.

FORCE è simile a git checkout --force; tutte le modifiche vengono sovrascritte e vengono creati tutti i file mancanti.

Nel mio caso lo sto testando con un repository molto piccolo senza modifiche non modificate e senza conflitti tra questi 2 rami.

log git

Che cosa sto facendo di sbagliato? Mi aspettavo che questo codice facesse qualcosa di simile git checkout master

risposte:

4 per risposta № 1

Il git checkout il comando è eccezionalmente sovraccarico. Si occupa sia di mettere i file su disco (check-out) e cambiare ramo. In particolare, git checkout <branch> aggiornerà la directory di lavoro in modo che corrisponda al contenuto del ramo specificato e passare ad esso.

Le API libgit2 non confondono queste due operazioni. git_checkout_* le funzioni controllano solo i file sul disco.

La documentazione dovrebbe chiarire questo:

In libgit2, il checkout viene utilizzato per aggiornare la directory di lavoro e l'indice per abbinare un albero bersaglio. A differenza del checkout di git, non sposta il HEAD commetti per te - usa git_repository_set_head o simili a farlo.

Quindi ciò che hai scritto (sopra) aggiornerà la directory di lavoro in modo che corrisponda al contenuto del ramo. Dopodiché, dovrai aggiornare il tuo ramo al ramo a cui vuoi passare.

Puoi farlo con git_repository_set_head aggiornare HEAD per puntare al ramo dato, una volta che i file sono stati estratti. Assicurati di specificare il nome del ramo completo (es. refs/heads/master).

git_object *treeish = NULL;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE;

git_libgit2_init();

handleError(git_revparse_single(&treeish, repo, "master"));
handleError(git_checkout_tree(repo, treeish, &opts));

handleError(git_repository_set_head(g_repo, "refs/heads/master"));

git_object_free(treeish);
git_libgit2_shutdown();