Skip to content

Commit ab90eca

Browse files
bk2204gitster
authored andcommitted
convert: permit passing additional metadata to filter processes
There are a variety of situations where a filter process can make use of some additional metadata. For example, some people find the ident filter too limiting and would like to include the commit or the branch in their smudged files. This information isn't available during checkout as HEAD hasn't been updated at that point, and it wouldn't be available in archives either. Let's add a way to pass this metadata down to the filter. We pass the blob we're operating on, the treeish (preferring the commit over the tree if one exists), and the ref we're operating on. Note that we won't pass this information in all cases, such as when renormalizing or when we're performing diffs, since it doesn't make sense in those cases. The data we currently get from the filter process looks like the following: command=smudge pathname=git.c 0000 With this change, we'll get data more like this: command=smudge pathname=git.c refname=refs/tags/v2.25.1 treeish=c522f061d551c9bb8684a7c3859b2ece4499b56b blob=7be7ad34bd053884ec48923706e70c81719a8660 0000 There are a couple things to note about this approach. For operations like checkout, treeish will always be a commit, since we cannot check out individual trees, but for other operations, like archive, we can end up operating on only a particular tree, so we'll provide only a tree as the treeish. Similar comments apply for refname, since there are a variety of cases in which we won't have a ref. This commit wires up the code to print this information, but doesn't pass any of it at this point. In a future commit, we'll have various code paths pass the actual useful data down. Signed-off-by: brian m. carlson <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a860476 commit ab90eca

File tree

8 files changed

+51
-19
lines changed

8 files changed

+51
-19
lines changed

apply.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4349,7 +4349,7 @@ static int try_create_file(struct apply_state *state, const char *path,
43494349
if (fd < 0)
43504350
return 1;
43514351

4352-
if (convert_to_working_tree(state->repo->index, path, buf, size, &nbuf)) {
4352+
if (convert_to_working_tree(state->repo->index, path, buf, size, &nbuf, NULL)) {
43534353
size = nbuf.len;
43544354
buf = nbuf.buf;
43554355
}

archive.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ void *object_file_to_archive(const struct archiver_args *args,
8585
size_t size = 0;
8686

8787
strbuf_attach(&buf, buffer, *sizep, *sizep + 1);
88-
convert_to_working_tree(args->repo->index, path, buf.buf, buf.len, &buf);
88+
convert_to_working_tree(args->repo->index, path, buf.buf, buf.len, &buf, NULL);
8989
if (commit)
9090
format_subst(commit, buf.buf, buf.len, &buf);
9191
buffer = strbuf_detach(&buf, &size);

builtin/cat-file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ static int filter_object(const char *path, unsigned mode,
4242
oid_to_hex(oid), path);
4343
if ((type == OBJ_BLOB) && S_ISREG(mode)) {
4444
struct strbuf strbuf = STRBUF_INIT;
45-
if (convert_to_working_tree(&the_index, path, *buf, *size, &strbuf)) {
45+
if (convert_to_working_tree(&the_index, path, *buf, *size, &strbuf, NULL)) {
4646
free(*buf);
4747
*size = strbuf.len;
4848
*buf = strbuf_detach(&strbuf, NULL);

convert.c

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,7 @@ static void handle_filter_error(const struct strbuf *filter_status,
797797
static int apply_multi_file_filter(const char *path, const char *src, size_t len,
798798
int fd, struct strbuf *dst, const char *cmd,
799799
const unsigned int wanted_capability,
800+
const struct checkout_metadata *meta,
800801
struct delayed_checkout *dco)
801802
{
802803
int err;
@@ -855,6 +856,24 @@ static int apply_multi_file_filter(const char *path, const char *src, size_t len
855856
if (err)
856857
goto done;
857858

859+
if (meta && meta->refname) {
860+
err = packet_write_fmt_gently(process->in, "ref=%s\n", meta->refname);
861+
if (err)
862+
goto done;
863+
}
864+
865+
if (meta && !is_null_oid(&meta->treeish)) {
866+
err = packet_write_fmt_gently(process->in, "treeish=%s\n", oid_to_hex(&meta->treeish));
867+
if (err)
868+
goto done;
869+
}
870+
871+
if (meta && !is_null_oid(&meta->blob)) {
872+
err = packet_write_fmt_gently(process->in, "blob=%s\n", oid_to_hex(&meta->blob));
873+
if (err)
874+
goto done;
875+
}
876+
858877
if ((entry->supported_capabilities & CAP_DELAY) &&
859878
dco && dco->state == CE_CAN_DELAY) {
860879
can_delay = 1;
@@ -971,6 +990,7 @@ static struct convert_driver {
971990
static int apply_filter(const char *path, const char *src, size_t len,
972991
int fd, struct strbuf *dst, struct convert_driver *drv,
973992
const unsigned int wanted_capability,
993+
const struct checkout_metadata *meta,
974994
struct delayed_checkout *dco)
975995
{
976996
const char *cmd = NULL;
@@ -990,7 +1010,7 @@ static int apply_filter(const char *path, const char *src, size_t len,
9901010
return apply_single_file_filter(path, src, len, fd, dst, cmd);
9911011
else if (drv->process && *drv->process)
9921012
return apply_multi_file_filter(path, src, len, fd, dst,
993-
drv->process, wanted_capability, dco);
1013+
drv->process, wanted_capability, meta, dco);
9941014

9951015
return 0;
9961016
}
@@ -1368,7 +1388,7 @@ int would_convert_to_git_filter_fd(const struct index_state *istate, const char
13681388
if (!ca.drv->required)
13691389
return 0;
13701390

1371-
return apply_filter(path, NULL, 0, -1, NULL, ca.drv, CAP_CLEAN, NULL);
1391+
return apply_filter(path, NULL, 0, -1, NULL, ca.drv, CAP_CLEAN, NULL, NULL);
13721392
}
13731393

13741394
const char *get_convert_attr_ascii(const struct index_state *istate, const char *path)
@@ -1406,7 +1426,7 @@ int convert_to_git(const struct index_state *istate,
14061426

14071427
convert_attrs(istate, &ca, path);
14081428

1409-
ret |= apply_filter(path, src, len, -1, dst, ca.drv, CAP_CLEAN, NULL);
1429+
ret |= apply_filter(path, src, len, -1, dst, ca.drv, CAP_CLEAN, NULL, NULL);
14101430
if (!ret && ca.drv && ca.drv->required)
14111431
die(_("%s: clean filter '%s' failed"), path, ca.drv->name);
14121432

@@ -1441,7 +1461,7 @@ void convert_to_git_filter_fd(const struct index_state *istate,
14411461
assert(ca.drv);
14421462
assert(ca.drv->clean || ca.drv->process);
14431463

1444-
if (!apply_filter(path, NULL, 0, fd, dst, ca.drv, CAP_CLEAN, NULL))
1464+
if (!apply_filter(path, NULL, 0, fd, dst, ca.drv, CAP_CLEAN, NULL, NULL))
14451465
die(_("%s: clean filter '%s' failed"), path, ca.drv->name);
14461466

14471467
encode_to_git(path, dst->buf, dst->len, dst, ca.working_tree_encoding, conv_flags);
@@ -1452,7 +1472,9 @@ void convert_to_git_filter_fd(const struct index_state *istate,
14521472
static int convert_to_working_tree_internal(const struct index_state *istate,
14531473
const char *path, const char *src,
14541474
size_t len, struct strbuf *dst,
1455-
int normalizing, struct delayed_checkout *dco)
1475+
int normalizing,
1476+
const struct checkout_metadata *meta,
1477+
struct delayed_checkout *dco)
14561478
{
14571479
int ret = 0, ret_filter = 0;
14581480
struct conv_attrs ca;
@@ -1484,7 +1506,7 @@ static int convert_to_working_tree_internal(const struct index_state *istate,
14841506
}
14851507

14861508
ret_filter = apply_filter(
1487-
path, src, len, -1, dst, ca.drv, CAP_SMUDGE, dco);
1509+
path, src, len, -1, dst, ca.drv, CAP_SMUDGE, meta, dco);
14881510
if (!ret_filter && ca.drv && ca.drv->required)
14891511
die(_("%s: smudge filter %s failed"), path, ca.drv->name);
14901512

@@ -1494,22 +1516,24 @@ static int convert_to_working_tree_internal(const struct index_state *istate,
14941516
int async_convert_to_working_tree(const struct index_state *istate,
14951517
const char *path, const char *src,
14961518
size_t len, struct strbuf *dst,
1519+
const struct checkout_metadata *meta,
14971520
void *dco)
14981521
{
1499-
return convert_to_working_tree_internal(istate, path, src, len, dst, 0, dco);
1522+
return convert_to_working_tree_internal(istate, path, src, len, dst, 0, meta, dco);
15001523
}
15011524

15021525
int convert_to_working_tree(const struct index_state *istate,
15031526
const char *path, const char *src,
1504-
size_t len, struct strbuf *dst)
1527+
size_t len, struct strbuf *dst,
1528+
const struct checkout_metadata *meta)
15051529
{
1506-
return convert_to_working_tree_internal(istate, path, src, len, dst, 0, NULL);
1530+
return convert_to_working_tree_internal(istate, path, src, len, dst, 0, meta, NULL);
15071531
}
15081532

15091533
int renormalize_buffer(const struct index_state *istate, const char *path,
15101534
const char *src, size_t len, struct strbuf *dst)
15111535
{
1512-
int ret = convert_to_working_tree_internal(istate, path, src, len, dst, 1, NULL);
1536+
int ret = convert_to_working_tree_internal(istate, path, src, len, dst, 1, NULL, NULL);
15131537
if (ret) {
15141538
src = dst->buf;
15151539
len = dst->len;

convert.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
#ifndef CONVERT_H
55
#define CONVERT_H
66

7+
#include "hash.h"
78
#include "string-list.h"
89

910
struct index_state;
10-
struct object_id;
1111
struct strbuf;
1212

1313
#define CONV_EOL_RNDTRP_DIE (1<<0) /* Die if CRLF to LF to CRLF is different */
@@ -57,6 +57,12 @@ struct delayed_checkout {
5757
struct string_list paths;
5858
};
5959

60+
struct checkout_metadata {
61+
const char *refname;
62+
struct object_id treeish;
63+
struct object_id blob;
64+
};
65+
6066
extern enum eol core_eol;
6167
extern char *check_roundtrip_encoding;
6268
const char *get_cached_convert_stats_ascii(const struct index_state *istate,
@@ -71,10 +77,12 @@ int convert_to_git(const struct index_state *istate,
7177
struct strbuf *dst, int conv_flags);
7278
int convert_to_working_tree(const struct index_state *istate,
7379
const char *path, const char *src,
74-
size_t len, struct strbuf *dst);
80+
size_t len, struct strbuf *dst,
81+
const struct checkout_metadata *meta);
7582
int async_convert_to_working_tree(const struct index_state *istate,
7683
const char *path, const char *src,
7784
size_t len, struct strbuf *dst,
85+
const struct checkout_metadata *meta,
7886
void *dco);
7987
int async_query_available_blobs(const char *cmd,
8088
struct string_list *available_paths);

diff.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4071,7 +4071,7 @@ static void prep_temp_blob(struct index_state *istate,
40714071
if (!temp->tempfile)
40724072
die_errno("unable to create temp-file");
40734073
if (convert_to_working_tree(istate, path,
4074-
(const char *)blob, (size_t)size, &buf)) {
4074+
(const char *)blob, (size_t)size, &buf, NULL)) {
40754075
blob = buf.buf;
40764076
size = buf.len;
40774077
}

entry.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,13 +315,13 @@ static int write_entry(struct cache_entry *ce,
315315
*/
316316
if (dco && dco->state != CE_NO_DELAY) {
317317
ret = async_convert_to_working_tree(state->istate, ce->name, new_blob,
318-
size, &buf, dco);
318+
size, &buf, NULL, dco);
319319
if (ret && string_list_has_string(&dco->paths, ce->name)) {
320320
free(new_blob);
321321
goto delayed;
322322
}
323323
} else
324-
ret = convert_to_working_tree(state->istate, ce->name, new_blob, size, &buf);
324+
ret = convert_to_working_tree(state->istate, ce->name, new_blob, size, &buf, NULL);
325325

326326
if (ret) {
327327
free(new_blob);

merge-recursive.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,7 @@ static int update_file_flags(struct merge_options *opt,
958958
if (S_ISREG(contents->mode)) {
959959
struct strbuf strbuf = STRBUF_INIT;
960960
if (convert_to_working_tree(opt->repo->index,
961-
path, buf, size, &strbuf)) {
961+
path, buf, size, &strbuf, NULL)) {
962962
free(buf);
963963
size = strbuf.len;
964964
buf = strbuf_detach(&strbuf, NULL);

0 commit comments

Comments
 (0)