Programmatically `git checkout .` con dulwich

Tener este código

from dulwich.objects import Blob, Tree, Commit, parse_timezone from dulwich.repo import Repo from time import time repo = Repo.init("myrepo", mkdir=True) blob = Blob.from_string("my file content\n") tree = Tree() tree.add("spam", 0100644, blob.id) commit = Commit() commit.tree = tree.id author = "Flav <foo@bar.com>" commit.author = commit.committer = author commit.commit_time = commit.author_time = int(time()) tz = parse_timezone('+0200')[0] commit.commit_timezone = commit.author_timezone = tz commit.encoding = "UTF-8" commit.message = "initial commit" o_sto = repo.object_store o_sto.add_object(blob) o_sto.add_object(tree) o_sto.add_object(commit) repo.refs["HEAD"] = commit.id 

Termino con la confirmación en el historial, PERO el file creado está pendiente de eliminación (el git status lo dice).

Un git checkout . lo arregla

Mi pregunta es: cómo hacer git checkout . programáticamente con dulwich?

Ahora es posible desde la versión 0.8.4 , con el método dulwich.index.build_index_from_tree() .

Escribe un tree para el file de índice y el sistema de files (copy de trabajo), que es una forma muy básica de pago.

Ver la nota

el índice existente se borra y los contenidos no se fusionan en un directory de trabajo. Suite solo para clones frescos

Podría hacer que funcione con el siguiente código

 from dulwich import index, repo #get repository object of current directory repo = repo.Repo('.') indexfile = repo.index_path() #we want to checkout HEAD tree = repo["HEAD"].tree index.build_index_from_tree(repo.path, indexfile, repo.object_store, tree) 

El estado de Git dice que se borró porque el file no existe en la copy de trabajo, por eso revisarlo corrige el estado.

Parece que todavía no hay soporte para classs y funciones de copy de trabajo de alto nivel en dulwich. Tendría que lidiar con treees y blobs y desempacar objects.

OK, tomé el desafío: podría hacer una comprobación básica con Dulwich:

 #get repository object of current directory repo = Repo('.') #get tree corresponding to the head commit tree_id = repo["HEAD"].tree #iterate over tree content, giving path and blob sha. for entry in repo.object_store.iter_tree_contents(tree_id): path = entry.in_path(repo.path).path dulwich.file.ensure_dir_exists(os.path.split(path)[0]) with open(path, 'wb') as file: #write blob's content to file file.write(repo[entry.sha].as_raw_string()) 

No eliminará los files que se deben eliminar, no le importará su índice, etc.
Ver también el proyecto github de Mark Mikofski para get un código más completo basado en esto.

 from dulwich.repo import Repo repo = Repo.init('myrepo', mkdir=True) f = open('myrepo/spam', 'w+') f.write('my file content\n') f.close() repo.stage(['spam']) repo.do_commit('initial commit', 'Flav <foo@bar.com>') 

Encontrado mirando dulwich/tests/test_repository.py:371 . dulwich es poderoso, pero los documentos son un poco insuficientes, desafortunadamente.

También puede considerar usar GitFile en su lugar.