mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-08 01:20:53 +00:00
Checkout: read blob objects to file.
Properly handling file modes. Still needs line- ending transformations.
This commit is contained in:
parent
830388a728
commit
24b0d3d56e
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user