Commit 24b0d3d5 by Ben Straub

Checkout: read blob objects to file.

Properly handling file modes. Still needs line-
ending transformations.
parent 830388a7
...@@ -12,10 +12,12 @@ ...@@ -12,10 +12,12 @@
#include "git2/refs.h" #include "git2/refs.h"
#include "git2/tree.h" #include "git2/tree.h"
#include "git2/commit.h" #include "git2/commit.h"
#include "git2/blob.h"
#include "common.h" #include "common.h"
#include "refs.h" #include "refs.h"
#include "buffer.h" #include "buffer.h"
#include "repository.h"
GIT_BEGIN_DECL GIT_BEGIN_DECL
...@@ -46,6 +48,7 @@ static int get_head_tree(git_tree **out, git_repository *repo) ...@@ -46,6 +48,7 @@ static int get_head_tree(git_tree **out, git_repository *repo)
typedef struct tree_walk_data typedef struct tree_walk_data
{ {
git_indexer_stats *stats; git_indexer_stats *stats;
git_repository *repo;
} tree_walk_data; } tree_walk_data;
...@@ -57,18 +60,51 @@ static int count_walker(const char *path, git_tree_entry *entry, void *payload) ...@@ -57,18 +60,51 @@ static int count_walker(const char *path, git_tree_entry *entry, void *payload)
return 0; return 0;
} }
static int blob_contents_to_file(git_repository *repo, git_buf *fnbuf, const git_oid *id, int mode)
{
int retcode = GIT_ERROR;
git_blob *blob;
if (!git_blob_lookup(&blob, repo, id)) {
const void *contents = git_blob_rawcontent(blob);
size_t len = git_blob_rawsize(blob);
/* TODO: line-ending smudging */
int fd = git_futils_creat_withpath(git_buf_cstr(fnbuf),
GIT_DIR_MODE, mode);
if (fd >= 0) {
retcode = (!p_write(fd, contents, len)) ? 0 : GIT_ERROR;
p_close(fd);
}
git_blob_free(blob);
}
return retcode;
}
static int checkout_walker(const char *path, git_tree_entry *entry, void *payload) static int checkout_walker(const char *path, git_tree_entry *entry, void *payload)
{ {
int retcode = 0; int retcode = 0;
tree_walk_data *data = (tree_walk_data*)payload; tree_walk_data *data = (tree_walk_data*)payload;
int attr = git_tree_entry_attributes(entry);
switch(git_tree_entry_type(entry)) { switch(git_tree_entry_type(entry)) {
case GIT_OBJ_TREE: case GIT_OBJ_TREE:
/* TODO: mkdir */ /* TODO: mkdir? */
break; break;
case GIT_OBJ_BLOB: case GIT_OBJ_BLOB:
/* TODO: create/populate file */ {
git_buf fnbuf = GIT_BUF_INIT;
git_buf_join_n(&fnbuf, '/', 3,
git_repository_workdir(data->repo),
path,
git_tree_entry_name(entry));
retcode = blob_contents_to_file(data->repo, &fnbuf, git_tree_entry_id(entry), attr);
git_buf_free(&fnbuf);
}
break; break;
default: default:
...@@ -95,6 +131,7 @@ int git_checkout_force(git_repository *repo, git_indexer_stats *stats) ...@@ -95,6 +131,7 @@ int git_checkout_force(git_repository *repo, git_indexer_stats *stats)
stats->total = stats->processed = 0; stats->total = stats->processed = 0;
payload.stats = stats; payload.stats = stats;
payload.repo = repo;
if (!get_head_tree(&tree, repo)) { if (!get_head_tree(&tree, repo)) {
/* Count all the tree nodes for progress information */ /* Count all the tree nodes for progress information */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment