From: Axel Bonnet <axel.bonnet@ensimag.imag.fr>
To: git@vger.kernel.org
Cc: "Axel Bonnet" <axel.bonnet@ensimag.imag.fr>,
"Diane Gasselin" <diane.gasselin@ensimag.imag.fr>,
"Clément Poulain" <clement.poulain@ensimag.imag.fr>
Subject: [RFC/PATCH 3/4] textconv: support for blame
Date: Thu, 3 Jun 2010 12:47:17 +0200 [thread overview]
Message-ID: <1275562038-7468-4-git-send-email-axel.bonnet@ensimag.imag.fr> (raw)
In-Reply-To: <1275562038-7468-3-git-send-email-axel.bonnet@ensimag.imag.fr>
This patches enables to perform textconv with blame if a textconv driver
is available for the file.
The main task is performed by the textconv_object function which
prepares diff_filespec and if possible converts the file using diff
textconv API.
Textconv conversion is enabled by default (equivalent to the option
--textconv), since blaming binary files is useless in most cases.
The option --no-textconv is used to disable textconv conversion.
The declaration of fill_blob_sha1 declaration is modified to get back
the mode the function was getting.
Signed-off-by: Diane Gasselin <diane.gasselin@ensimag.imag.fr>
Signed-off-by: Clément Poulain <clement.poulain@ensimag.imag.fr>
Signed-off-by: Axel Bonnet <axel.bonnet@ensimag.imag.fr>
---
builtin/blame.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 63 insertions(+), 11 deletions(-)
diff --git a/builtin/blame.c b/builtin/blame.c
index 63b497c..4679fd9 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -20,6 +20,7 @@
#include "mailmap.h"
#include "parse-options.h"
#include "utf8.h"
+#include "userdiff.h"
static char blame_usage[] = "git blame [options] [rev-opts] [rev] [--] file";
@@ -86,17 +87,57 @@ struct origin {
};
/*
+ * Prepare diff_filespec and convert it using diff textconv API
+ * if the textconv driver exists.
+ * Return 1 if the conversion succeeds, 0 otherwise.
+ */
+static int textconv_object(const char *path,
+ const unsigned char *sha1,
+ unsigned short mode,
+ struct strbuf *buf)
+{
+ struct diff_filespec *df;
+
+ df = alloc_filespec(path);
+ fill_filespec(df, sha1, mode);
+ get_textconv(df);
+
+ if (!df->driver|| !df->driver->textconv) {
+ free_filespec(df);
+ return 0;
+ }
+
+ buf->len = fill_textconv(df->driver, df, &buf->buf);
+ buf->alloc = 1;
+ free_filespec(df);
+ return 1;
+}
+
+/*
* Given an origin, prepare mmfile_t structure to be used by the
* diff machinery
*/
static void fill_origin_blob(struct diff_options opt,
struct origin *o, mmfile_t *file)
{
+ unsigned mode;
+
if (!o->file.ptr) {
+ struct strbuf buf = STRBUF_INIT;
enum object_type type;
num_read_blob++;
- file->ptr = read_sha1_file(o->blob_sha1, &type,
- (unsigned long *)(&(file->size)));
+
+ get_tree_entry(o->commit->object.sha1,
+ o->path,
+ o->blob_sha1, &mode);
+ if (DIFF_OPT_TST(&opt, ALLOW_TEXTCONV) &&
+ textconv_object(o->path, o->blob_sha1, mode, &buf))
+ file->ptr = strbuf_detach(&buf, (size_t *) &file->size);
+ else
+ file->ptr = read_sha1_file(o->blob_sha1, &type,
+ (unsigned long *)(&(file->size)));
+ strbuf_release(&buf);
+
if (!file->ptr)
die("Cannot read blob %s for path %s",
sha1_to_hex(o->blob_sha1),
@@ -280,15 +321,13 @@ static struct origin *get_origin(struct scoreboard *sb,
* the parent to detect the case where a child's blob is identical to
* that of its parent's.
*/
-static int fill_blob_sha1(struct origin *origin)
+static int fill_blob_sha1(struct origin *origin, unsigned *mode)
{
- unsigned mode;
-
if (!is_null_sha1(origin->blob_sha1))
return 0;
if (get_tree_entry(origin->commit->object.sha1,
origin->path,
- origin->blob_sha1, &mode))
+ origin->blob_sha1, mode))
goto error_out;
if (sha1_object_info(origin->blob_sha1, NULL) != OBJ_BLOB)
goto error_out;
@@ -2033,10 +2072,13 @@ static struct commit *fake_working_tree_commit(struct diff_options opt,
read_from = path;
}
mode = canon_mode(st.st_mode);
+
switch (st.st_mode & S_IFMT) {
case S_IFREG:
- if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)
- die_errno("cannot open or read '%s'", read_from);
+ if (!DIFF_OPT_TST(&opt, ALLOW_TEXTCONV) ||
+ !textconv_object(read_from, null_sha1, mode, &buf))
+ if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)
+ die_errno("cannot open or read '%s'", read_from);
break;
case S_IFLNK:
if (strbuf_readlink(&buf, read_from, st.st_size) < 0)
@@ -2249,8 +2291,10 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
int cmd_is_annotate = !strcmp(argv[0], "annotate");
git_config(git_blame_config, NULL);
+ git_config(git_diff_ui_config, NULL);
init_revisions(&revs, NULL);
revs.date_mode = blame_date_mode;
+ DIFF_OPT_SET(&revs.diffopt, ALLOW_TEXTCONV);
save_commit_buffer = 0;
dashdash_pos = 0;
@@ -2411,12 +2455,20 @@ parse_done:
sb.final_buf_size = o->file.size;
}
else {
+ struct strbuf buf = STRBUF_INIT;
+ unsigned mode;
o = get_origin(&sb, sb.final, path);
- if (fill_blob_sha1(o))
+ if (fill_blob_sha1(o, &mode))
die("no such path %s in %s", path, final_commit_name);
- sb.final_buf = read_sha1_file(o->blob_sha1, &type,
- &sb.final_buf_size);
+ if (DIFF_OPT_TST(&sb.revs->diffopt, ALLOW_TEXTCONV) &&
+ textconv_object(path, o->blob_sha1, mode, &buf))
+ sb.final_buf= strbuf_detach(&buf, (size_t *) &sb.final_buf_size);
+ else
+ sb.final_buf = read_sha1_file(o->blob_sha1, &type,
+ &sb.final_buf_size);
+
+ strbuf_release(&buf);
if (!sb.final_buf)
die("Cannot read blob %s for path %s",
sha1_to_hex(o->blob_sha1),
--
1.6.6.7.ga5fe3
next prev parent reply other threads:[~2010-06-03 10:55 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-03 10:47 [RFC/PATCH 0/4] textconv support for blame Axel Bonnet
2010-06-03 10:47 ` [RFC/PATCH 1/4] textconv: make the API public Axel Bonnet
2010-06-03 10:47 ` [RFC/PATCH 2/4] textconv: make diff_options accessible from blame Axel Bonnet
2010-06-03 10:47 ` Axel Bonnet [this message]
2010-06-03 10:47 ` [RFC/PATCH 4/4] t/t8006: test textconv support for blame Axel Bonnet
2010-06-03 15:44 ` Johannes Sixt
2010-06-04 8:55 ` Diane Gasselin
2010-06-04 9:45 ` Matthieu Moy
2010-06-04 8:49 ` Matthieu Moy
2010-06-04 6:00 ` [RFC/PATCH 3/4] textconv: " Junio C Hamano
2010-06-04 10:34 ` Diane Gasselin
2010-06-06 21:51 ` Jeff King
2010-06-04 5:48 ` [RFC/PATCH 2/4] textconv: make diff_options accessible from blame Junio C Hamano
2010-06-04 7:59 ` Matthieu Moy
2010-06-04 10:21 ` bonneta
2010-06-04 17:23 ` Matthieu Moy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1275562038-7468-4-git-send-email-axel.bonnet@ensimag.imag.fr \
--to=axel.bonnet@ensimag.imag.fr \
--cc=clement.poulain@ensimag.imag.fr \
--cc=diane.gasselin@ensimag.imag.fr \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).