ross macarthur
estoy usando el óxido git2 crate para clonar repositorios Git como este
use git2::Repository;
fn main() {
let repo = Repository::clone(
"https://github.com/rossmacarthur/dotfiles",
"dotfiles"
).expect("failed to clone repository");
repo.checkout("mybranch"); // need something like this.
}
Quiero poder pagar una rama o una confirmación o una etiqueta.
He mirado la siguiente documentación pero todavía no estoy seguro de qué método usar
- https://docs.rs/git2/0.8.0/git2/struct.Repository.html#method.checkout_head
- https://docs.rs/git2/0.8.0/git2/struct.Repository.html#method.checkout_tree
- https://docs.rs/git2/0.8.0/git2/struct.Repository.html#method.checkout_index
Puedo hacer lo siguiente pero solo cambia los archivos
let object = repo
.revparse_single("mybranch")
.expect("failed to find identifier");
repo.checkout_tree(&object, None)
.expect(&format!("failed to checkout '{:?}'", object));
Y si hago un reset cambia el HEAD pero no la rama actual
repo.reset(&object, git2::ResetType::Soft, None)
.expect(&format!("failed to checkout '{:?}'", object));
szignal
Los siguientes ejemplos son Rust v1.34 y git2 v0.8.
Para pagar una sucursal:
use git2::*;
fn main() {
let repo = Repository::clone(
"https://github.com/rossmacarthur/dotfiles",
"dotfiles"
).expect("failed to clone repository");
let branch_name = "my_branch";
let head = repo.head().unwrap();
let oid = head.target().unwrap();
let commit = repo.find_commit(oid).unwrap();
let branch = repo.branch(
branch_name,
&commit,
false,
);
let obj = repo.revparse_single(&("refs/heads/".to_owned() +
branch_name)).unwrap();
repo.checkout_tree(
&obj,
None
);
repo.set_head(&("refs/heads/".to_owned() + branch_name));
}
Para verificar un compromiso:
use git2::*;
fn main() {
let repo = Repository::clone(
"https://github.com/rossmacarthur/dotfiles",
"dotfiles"
).expect("failed to clone repository");
let my_oid_str = "9411953f92d100f767e6de6325b17afae5231779";
let oid = Oid::from_str(my_oid_str).unwrap();
let commit = repo.find_commit(oid).unwrap();
let branch = repo.branch(
my_oid_str,
&commit,
false,
);
let obj = repo.revparse_single(&("refs/heads/".to_owned() + my_oid_str)).unwrap();
repo.checkout_tree(
&obj,
None,
);
repo.set_head(&("refs/heads/".to_owned() + my_oid_str));
}
Para pagar una etiqueta, intente algo como esto:
use git2::*;
fn main() {
// No relation to the example project below.
// It looks interesting and it has tags!
let repo = Repository::clone(
"https://github.com/narke/colorForth.git",
"colorforth"
).expect("failed to clone repository");
let tag_name = "v2012";
let references = repo.references().unwrap();
for reference in references {
let _reference = reference.unwrap();
if _reference.is_tag() == true {
let tag = _reference.peel_to_tag().unwrap();
if tag.name().unwrap() == tag_name {
let target_oid = tag.target().unwrap().id();
let commit = repo.find_commit(target_oid).unwrap();
let branch = repo.branch(
tag_name,
&commit,
false,
);
let obj = repo.revparse_single(&("refs/heads/".to_owned() + tag_name)).unwrap();
repo.checkout_tree(
&obj,
None,
);
repo.set_head(&("refs/heads/".to_owned() + tag_name));
}
}
}
}
Apuesto a que generalmente hay una mejor manera, pero la pregunta no ha sido respondida durante meses y así es como lo descubrí hace unos momentos.
-
Mi publicación actualizada resuelve completamente la pregunta del OP. Se agradecen los votos a favor. Ni siquiera tengo suficientes puntos para comentar en la publicación de otros, como la del OP, así que puedo dejarles ahora que respondí con éxito la pregunta. Trabajaré para que la respuesta sea más idiomática si se muestra algún interés por esta pregunta.
– szignal
10 de julio de 2019 a las 22:39
-
En el ejemplo para verificar un compromiso, el método adecuado para usar es
set_head_detached()
–set_head()
espera un nombre de referencia comorefs/heads/master
oHEAD
(pero un hash de confirmación no es una referencia). Así que la forma correcta esrepo.set_head_detached(oid);
.– sudormrfbin
23 de abril de 2021 a las 10:27
sudormrfbin
Con una versión más reciente de git2
(v0.13.18
):
use git2::Repository;
fn main() {
let repo = Repository::clone("https://github.com/rossmacarthur/dotfiles", "/tmp/dots")
.expect("Failed to clone repo");
let refname = "master"; // or a tag (v0.1.1) or a commit (8e8128)
let (object, reference) = repo.revparse_ext(refname).expect("Object not found");
repo.checkout_tree(&object, None)
.expect("Failed to checkout");
match reference {
// gref is an actual reference like branches or tags
Some(gref) => repo.set_head(gref.name().unwrap()),
// this is a commit, not a reference
None => repo.set_head_detached(object.id()),
}
.expect("Failed to set HEAD");
}
Tenga en cuenta que checkout_tree
sólo establece el contenido del árbol de trabajo, y set_head
solo establece el HEAD
. Ejecutar solo uno de ellos dejará el directorio en un estado sucio.
-
Gracias, esto es mucho más limpio!
–Ross MacArthur
14 de julio de 2021 a las 14:19
pienso repo.set_head("mybranch")
es lo que buscas Más información está disponible aquí.
-
1.
repo.set_head("refs/heads/mybranch")
2. esto no cambiará los archivos en el directorio de trabajo– Shimón S.
12 de enero a las 13:58