Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions R/blob.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## git2r, R bindings to the libgit2 library.
## Copyright (C) 2013-2019 The git2r contributors
## Copyright (C) 2013-2023 The git2r contributors
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License, version 2,
Expand Down Expand Up @@ -64,7 +64,10 @@ blob_create <- function(repo = ".", path = NULL, relative = TRUE) {
##'
##' @param blob The blob object.
##' @param split Split blob content to text lines. Default TRUE.
##' @return The content of the blob. NA_character_ if the blob is binary.
##' @param raw When \code{TRUE}, get the content of the blob as a raw
##' vector, else as a character vector. Default is \code{FALSE}.
##' @return The content of the blob. NA_character_ if the blob is
##' binary and \code{raw} is \code{FALSE}.
##' @export
##' @examples
##' \dontrun{
Expand All @@ -82,14 +85,13 @@ blob_create <- function(repo = ".", path = NULL, relative = TRUE) {
##' ## Display content of blob.
##' content(tree(commits(repo)[[1]])["example.txt"])
##' }
content <- function(blob = NULL, split = TRUE) {
if (is_binary(blob))
return(NA_character_)

ret <- .Call(git2r_blob_content, blob)
content <- function(blob = NULL, split = TRUE, raw = FALSE) {
result <- .Call(git2r_blob_content, blob, raw)
if (isTRUE(raw))
return(result)
if (isTRUE(split))
ret <- strsplit(ret, "\n")[[1]]
ret
result <- strsplit(result, "\n")[[1]]
result
}

##' Determine the sha from a blob string
Expand Down
8 changes: 6 additions & 2 deletions man/content.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/git2r.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
static const R_CallMethodDef callMethods[] =
{
CALLDEF(git2r_blame_file, 2),
CALLDEF(git2r_blob_content, 1),
CALLDEF(git2r_blob_content, 2),
CALLDEF(git2r_blob_create_fromdisk, 2),
CALLDEF(git2r_blob_create_fromworkdir, 2),
CALLDEF(git2r_blob_is_binary, 1),
Expand Down
28 changes: 23 additions & 5 deletions src/git2r_blob.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* git2r, R bindings to the libgit2 library.
* Copyright (C) 2013-2020 The git2r contributors
* Copyright (C) 2013-2023 The git2r contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2,
Expand Down Expand Up @@ -28,11 +28,14 @@
* Get content of a blob
*
* @param blob S3 class git_blob
* @param raw If true, return content as a RAWSXP vector, else as a
* STRSXP vector.
* @return content
*/
SEXP attribute_hidden
git2r_blob_content(
SEXP blob)
SEXP blob,
SEXP raw)
{
int error, nprotect = 0;
SEXP result = R_NilValue;
Expand All @@ -43,6 +46,8 @@ git2r_blob_content(

if (git2r_arg_check_blob(blob))
git2r_error(__func__, NULL, "'blob'", git2r_err_blob_arg);
if (git2r_arg_check_logical(raw))
git2r_error(__func__, NULL, "'raw'", git2r_err_logical_arg);

repository = git2r_repository_open(git2r_get_list_element(blob, "repo"));
if (!repository)
Expand All @@ -55,9 +60,22 @@ git2r_blob_content(
if (error)
goto cleanup;

PROTECT(result = Rf_allocVector(STRSXP, 1));
nprotect++;
SET_STRING_ELT(result, 0, Rf_mkChar(git_blob_rawcontent(blob_obj)));
if (LOGICAL(raw)[0]) {
PROTECT(result = Rf_allocVector(RAWSXP, git_blob_rawsize(blob_obj)));
nprotect++;
memcpy(
RAW(result),
git_blob_rawcontent(blob_obj),
git_blob_rawsize(blob_obj));
} else {
PROTECT(result = Rf_allocVector(STRSXP, 1));
nprotect++;
if (git_blob_is_binary(blob_obj)) {
SET_STRING_ELT(result, 0, NA_STRING);
} else {
SET_STRING_ELT(result, 0, Rf_mkChar(git_blob_rawcontent(blob_obj)));
}
}

cleanup:
git_blob_free(blob_obj);
Expand Down
4 changes: 2 additions & 2 deletions src/git2r_blob.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* git2r, R bindings to the libgit2 library.
* Copyright (C) 2013-2015 The git2r contributors
* Copyright (C) 2013-2023 The git2r contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2,
Expand All @@ -23,7 +23,7 @@
#include <Rinternals.h>
#include <git2.h>

SEXP git2r_blob_content(SEXP blob);
SEXP git2r_blob_content(SEXP blob, SEXP raw);
SEXP git2r_blob_create_fromdisk(SEXP repo, SEXP path);
SEXP git2r_blob_create_fromworkdir(SEXP repo, SEXP relative_path);
void git2r_blob_init(const git_blob *source, SEXP repo, SEXP dest);
Expand Down
17 changes: 10 additions & 7 deletions tests/blob.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## git2r, R bindings to the libgit2 library.
## Copyright (C) 2013-2019 The git2r contributors
## Copyright (C) 2013-2023 The git2r contributors
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License, version 2,
Expand Down Expand Up @@ -56,15 +56,18 @@ add(repo, "test.txt")
blob <- lookup(repo, tree(commit(repo, "New commit message"))$id[1])
stopifnot(identical(content(blob),
c("Hello world!", "HELLO WORLD!", "HeLlO wOrLd!")))
stopifnot(identical(rawToChar(content(blob, raw = TRUE)),
content(blob, split = FALSE)))

## Check content of binary file
set.seed(42)
writeBin(as.raw((sample(0:255, 1000, replace = TRUE))),
con = file.path(path, "test.bin"))
x <- as.raw((sample(0:255, 1000, replace = TRUE)))
writeBin(x, con = file.path(path, "test.bin"))
add(repo, "test.bin")
commit(repo, "Add binary file")
blob <- tree(last_commit(repo))["test.bin"]
stopifnot(identical(content(blob), NA_character_))
stopifnot(identical(x, content(blob, raw = TRUE)))

## Hash
stopifnot(identical(hash("Hello, world!\n"),
Expand Down Expand Up @@ -135,16 +138,16 @@ stopifnot(identical(sapply(blob_list_2, "[[", "sha"),
"d670460b4b4aece5915caf5c68d12f560a9fe3e4")))

## Test arguments
check_error(assertError(.Call(git2r:::git2r_blob_content, NULL)),
check_error(assertError(.Call(git2r:::git2r_blob_content, NULL, FALSE)),
"'blob' must be an S3 class git_blob")
check_error(assertError(.Call(git2r:::git2r_blob_content, 3)),
check_error(assertError(.Call(git2r:::git2r_blob_content, 3, FALSE)),
"'blob' must be an S3 class git_blob")
check_error(assertError(.Call(git2r:::git2r_blob_content, repo)),
check_error(assertError(.Call(git2r:::git2r_blob_content, repo, FALSE)),
"'blob' must be an S3 class git_blob")

b <- blob_list_1[[1]]
b$sha <- NA_character_
check_error(assertError(.Call(git2r:::git2r_blob_content, b)),
check_error(assertError(.Call(git2r:::git2r_blob_content, b, FALSE)),
"'blob' must be an S3 class git_blob")

check_error(assertError(hashfile(NA)), "invalid 'path' argument")
Expand Down