summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Straub <bstraub@github.com>2012-07-13 16:44:13 -0700
committerBen Straub <bstraub@github.com>2012-07-13 16:44:13 -0700
commitdc1b0909d6ec96def686de11ac987892abf7538f (patch)
tree46172ec7ea853a77a508a7733f11e8f5c51a2518 /src
parent280c7bbf13080c00fb563f8ecc08d9e606e3bd12 (diff)
downloadlibgit2-dc1b0909d6ec96def686de11ac987892abf7538f.tar.gz
Create filtered_blob_contents out of parts on hand.
Diffstat (limited to 'src')
-rw-r--r--src/checkout.c134
1 files changed, 77 insertions, 57 deletions
diff --git a/src/checkout.c b/src/checkout.c
index 907253fec..1e02935ab 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -27,63 +27,70 @@ typedef struct tree_walk_data
{
git_indexer_stats *stats;
git_repository *repo;
+ git_odb *odb;
} tree_walk_data;
-static int apply_filters(git_buf *out,
- git_vector *filters,
- const void *data,
- size_t len)
+static int unfiltered_blob_contents(git_buf *out, git_repository *repo, const git_oid *blob_id)
{
int retcode = GIT_ERROR;
- git_buf origblob = GIT_BUF_INIT;
- git_buf_clear(out);
-
- if (!filters->length) {
- /* No filters to apply; just copy the result */
- git_buf_put(out, (const char *)data, len);
- return 0;
+ git_blob *blob;
+ if (!git_blob_lookup(&blob, repo, blob_id)) {
+ const void *contents = git_blob_rawcontent(blob);
+ size_t len = git_blob_rawsize(blob);
+ git_buf_clear(out);
+ git_buf_set(out, (const char*)contents, len);
+ git_blob_free(blob);
+ retcode = 0;
}
-
- git_buf_attach(&origblob, (char*)data, len);
- retcode = git_filters_apply(out, &origblob, filters);
- git_buf_detach(&origblob);
-
return retcode;
}
-static int blob_contents_to_file(git_repository *repo, git_buf *fnbuf, const git_oid *id, int mode)
+static int filtered_blob_contents(git_buf *out, git_repository *repo, const git_oid *oid, const char *path)
{
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);
+ git_buf unfiltered = GIT_BUF_INIT;
+ if (!unfiltered_blob_contents(&unfiltered, repo, oid)) {
git_vector filters = GIT_VECTOR_INIT;
- int filter_count;
-
- /* TODO: line-ending smudging */
- filter_count = git_filters_load(&filters, repo,
- git_buf_cstr(fnbuf),
- GIT_FILTER_TO_WORKTREE);
+ int filter_count = git_filters_load(&filters, repo,
+ path, GIT_FILTER_TO_WORKTREE);
if (filter_count >= 0) {
- git_buf filteredblob = GIT_BUF_INIT;
- if (!apply_filters(&filteredblob, &filters, contents, len)) {
- 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_buf_clear(out);
+ if (!filter_count) {
+ git_buf_put(out, git_buf_cstr(&unfiltered), git_buf_len(&unfiltered));
+ retcode = 0;
+ } else {
+ retcode = git_filters_apply(out, &unfiltered, &filters);
}
- git_buf_free(&filteredblob);
- git_filters_free(&filters);
}
- git_blob_free(blob);
+ git_filters_free(&filters);
+ }
+
+ git_buf_free(&unfiltered);
+ return retcode;
+}
+
+static int blob_contents_to_file(git_repository *repo, git_buf *fnbuf, const git_oid *id, int mode)
+{
+ int retcode = GIT_ERROR;
+
+ git_buf filteredcontents = GIT_BUF_INIT;
+ if (!filtered_blob_contents(&filteredcontents, repo, id, git_buf_cstr(fnbuf))) {
+ int fd = git_futils_creat_withpath(git_buf_cstr(fnbuf),
+ GIT_DIR_MODE, mode);
+ if (fd >= 0) {
+ if (!p_write(fd, git_buf_cstr(&filteredcontents),
+ git_buf_len(&filteredcontents)))
+ retcode = 0;
+ else
+ retcode = GIT_ERROR;
+ p_close(fd);
+ }
}
+ git_buf_free(&filteredcontents);
return retcode;
}
@@ -94,26 +101,32 @@ static int checkout_walker(const char *path, git_tree_entry *entry, void *payloa
tree_walk_data *data = (tree_walk_data*)payload;
int attr = git_tree_entry_attributes(entry);
- switch(git_tree_entry_type(entry)) {
- case GIT_OBJ_TREE:
- /* TODO: mkdir? */
- break;
-
- case GIT_OBJ_BLOB:
- {
- 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;
+ /* TODO: handle submodules */
+
+ if (S_ISLNK(attr)) {
+ printf("It's a link!\n'");
+ } else {
+ switch(git_tree_entry_type(entry)) {
+ case GIT_OBJ_TREE:
+ /* Nothing to do; the blob handling creates necessary directories. */
+ break;
+
+ case GIT_OBJ_BLOB:
+ {
+ 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;
- default:
- retcode = -1;
- break;
+ default:
+ retcode = -1;
+ break;
+ }
}
data->stats->processed++;
@@ -131,9 +144,15 @@ int git_checkout_force(git_repository *repo, git_indexer_stats *stats)
assert(repo);
if (!stats) stats = &dummy_stats;
+ if (git_repository_is_bare(repo)) {
+ giterr_set(GITERR_INVALID, "Checkout is not allowed for bare repositories");
+ return GIT_ERROR;
+ }
+
stats->total = stats->processed = 0;
payload.stats = stats;
payload.repo = repo;
+ if (git_repository_odb(&payload.odb, repo) < 0) return GIT_ERROR;
/* TODO: stats->total is never calculated. */
@@ -145,6 +164,7 @@ int git_checkout_force(git_repository *repo, git_indexer_stats *stats)
git_tree_free(tree);
}
+ git_odb_free(payload.odb);
return retcode;
}