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 agit 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 agit checkout-index
o 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 agit 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.
Che cosa sto facendo di sbagliato? Mi aspettavo che questo codice facesse qualcosa di simile git checkout master
risposte:
4 per risposta № 1Il 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();