2017-10-15 4 views
1

Ich versuche, einen einfachen Checkout-Vorgang zwischen zwei Filialen zu implementieren. Der Code wird ohne Fehler ausgeführt.Checkout-Zweig mit libgit2

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(); 

Allerdings ist der Zweig nicht ändern, wenn ich es überprüfen git status verwenden. Ich habe überprüft die 101 examples of libgit2 und es sagt:

git_checkout_options nicht eigentlich sehr optional. Die Standardeinstellungen sind außerhalb einer kleinen Anzahl von Fällen nicht nützlich. Das beste Beispiel für diese ist checkout_strategy; Der Standardwert wirkt sich nicht auf den Arbeitsbaum aus. Wenn Sie also möchten, dass Ihre Kasse Dateien auscheckt, wählen Sie eine geeignete Strategie.

NONE ist das Äquivalent eines Trockenlaufs; Keine Dateien werden ausgecheckt.

SAFE ist ähnlich zu git checkout; Unmodifizierte Dateien werden aktualisiert, und geänderte Dateien bleiben in Ruhe. Wenn eine Datei im alten HEAD vorhanden war, aber fehlt, gilt sie als gelöscht und wird nicht erstellt.

RECREATE_MISSING ist ähnlich wie git checkout-index, oder was passiert nach einem Klon. Unmodifizierte Dateien werden aktualisiert und fehlende Dateien werden erstellt, aber Dateien mit Änderungen bleiben allein.

FORCE ist vergleichbar mit ; Alle Änderungen werden überschrieben und alle fehlenden Dateien werden erstellt.

In meinem Fall teste ich es mit einem sehr kleinen Repo ohne unbeaufsichtigte Änderungen und ohne Konflikte zwischen diesen beiden Zweigen.

git log

Was mache ich falsch? Ich habe erwartet, dass dieser Code etwas wie git checkout master tut

Antwort

2

Der Befehl git checkout ist außergewöhnlich überlastet. Es befasst sich sowohl mit dem Setzen von Dateien auf die Festplatte (Auschecken) und Umschalten von Zweigen. Insbesondere git checkout <branch> wird das Arbeitsverzeichnis aktualisieren, um den Inhalt des angegebenen Zweigs zu entsprechen und zu diesem wechseln.

Die libgit2-APIs führen diese beiden Vorgänge nicht zusammen. git_checkout_* Funktionen prüfen nur Dateien auf der Festplatte.

Die Dokumentation soll dies verdeutlichen:

In libgit2 wird die Kasse verwendet das Arbeitsverzeichnis und Index zu aktualisieren, um einen Zielbaum zu entsprechen. Im Gegensatz zu git checkout, verschiebt es nicht den HEAD Commit für Sie - verwenden Sie dazu git_repository_set_head oder dergleichen.

Also, was Sie geschrieben haben (oben) wird das Arbeitsverzeichnis auf den Inhalt der Branche zu aktualisieren. Danach müssen Sie Ihren Zweig zu dem Zweig aktualisieren, zu dem Sie wechseln möchten.

Sie können dies mit git_repository_set_head zu aktualisieren HEAD auf den angegebenen Zweig zeigen, sobald die Dateien ausgecheckt wurden. Stellen Sie sicher, dass Sie den vollständig qualifizierten Zweignamen angeben (z. B. refs/heads/master).

git_object *treeish = NULL; 
git_checkout_options opts; 
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(); 
+0

Vielen Dank! Es funktioniert jetzt wie erwartet! Ich würde auch Ihre Antwort auf diese Frage hinzufügen (https://Stackoverflow.com/a/30469509/4942153), um den Fehler "ungültige Version 0 auf git_checkout_options" zu vermeiden –

Verwandte Themen