Skip to content

Commit 4e4baee

Browse files
committed
Merge branch 'bc/filter-process'
Provide more information (e.g. the object of the tree-ish in which the blob being converted appears, in addition to its path, which has already been given) to smudge/clean conversion filters. * bc/filter-process: t0021: test filter metadata for additional cases builtin/reset: compute checkout metadata for reset builtin/rebase: compute checkout metadata for rebases builtin/clone: compute checkout metadata for clones builtin/checkout: compute checkout metadata for checkouts convert: provide additional metadata to filters convert: permit passing additional metadata to filter processes builtin/checkout: pass branch info down to checkout_worktree
2 parents fa82be9 + 0c0f8a7 commit 4e4baee

20 files changed

+350
-75
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: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ void *object_file_to_archive(const struct archiver_args *args,
7777
{
7878
void *buffer;
7979
const struct commit *commit = args->convert ? args->commit : NULL;
80+
struct checkout_metadata meta;
81+
82+
init_checkout_metadata(&meta, args->refname,
83+
args->commit_oid ? args->commit_oid :
84+
(args->tree ? &args->tree->object.oid : NULL), oid);
8085

8186
path += args->baselen;
8287
buffer = read_object_file(oid, type, sizep);
@@ -85,7 +90,7 @@ void *object_file_to_archive(const struct archiver_args *args,
8590
size_t size = 0;
8691

8792
strbuf_attach(&buf, buffer, *sizep, *sizep + 1);
88-
convert_to_working_tree(args->repo->index, path, buf.buf, buf.len, &buf);
93+
convert_to_working_tree(args->repo->index, path, buf.buf, buf.len, &buf, &meta);
8994
if (commit)
9095
format_subst(commit, buf.buf, buf.len, &buf);
9196
buffer = strbuf_detach(&buf, &size);
@@ -385,16 +390,17 @@ static void parse_treeish_arg(const char **argv,
385390
struct tree *tree;
386391
const struct commit *commit;
387392
struct object_id oid;
393+
char *ref = NULL;
388394

389395
/* Remotes are only allowed to fetch actual refs */
390396
if (remote && !remote_allow_unreachable) {
391-
char *ref = NULL;
392397
const char *colon = strchrnul(name, ':');
393398
int refnamelen = colon - name;
394399

395400
if (!dwim_ref(name, refnamelen, &oid, &ref))
396401
die(_("no such ref: %.*s"), refnamelen, name);
397-
free(ref);
402+
} else {
403+
dwim_ref(name, strlen(name), &oid, &ref);
398404
}
399405

400406
if (get_oid(name, &oid))
@@ -427,6 +433,7 @@ static void parse_treeish_arg(const char **argv,
427433

428434
tree = parse_tree_indirect(&tree_oid);
429435
}
436+
ar_args->refname = ref;
430437
ar_args->tree = tree;
431438
ar_args->commit_oid = commit_oid;
432439
ar_args->commit = commit;

archive.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ struct repository;
88

99
struct archiver_args {
1010
struct repository *repo;
11+
const char *refname;
1112
const char *base;
1213
size_t baselen;
1314
struct tree *tree;

builtin/cat-file.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ 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+
struct checkout_metadata meta;
46+
47+
init_checkout_metadata(&meta, NULL, NULL, oid);
48+
if (convert_to_working_tree(&the_index, path, *buf, *size, &strbuf, &meta)) {
4649
free(*buf);
4750
*size = strbuf.len;
4851
*buf = strbuf_detach(&strbuf, NULL);

builtin/checkout.c

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,19 @@ struct checkout_opts {
8888
struct tree *source_tree;
8989
};
9090

91+
struct branch_info {
92+
const char *name; /* The short name used */
93+
const char *path; /* The full name of a real branch */
94+
struct commit *commit; /* The named commit */
95+
char *refname; /* The full name of the ref being checked out. */
96+
struct object_id oid; /* The object ID of the commit being checked out. */
97+
/*
98+
* if not null the branch is detached because it's already
99+
* checked out in this checkout
100+
*/
101+
char *checkout;
102+
};
103+
91104
static int post_checkout_hook(struct commit *old_commit, struct commit *new_commit,
92105
int changed)
93106
{
@@ -337,7 +350,8 @@ static void mark_ce_for_checkout_no_overlay(struct cache_entry *ce,
337350
}
338351
}
339352

340-
static int checkout_worktree(const struct checkout_opts *opts)
353+
static int checkout_worktree(const struct checkout_opts *opts,
354+
const struct branch_info *info)
341355
{
342356
struct checkout state = CHECKOUT_INIT;
343357
int nr_checkouts = 0, nr_unmerged = 0;
@@ -348,6 +362,10 @@ static int checkout_worktree(const struct checkout_opts *opts)
348362
state.refresh_cache = 1;
349363
state.istate = &the_index;
350364

365+
init_checkout_metadata(&state.meta, info->refname,
366+
info->commit ? &info->commit->object.oid : &info->oid,
367+
NULL);
368+
351369
enable_delayed_checkout(&state);
352370
for (pos = 0; pos < active_nr; pos++) {
353371
struct cache_entry *ce = active_cache[pos];
@@ -396,7 +414,7 @@ static int checkout_worktree(const struct checkout_opts *opts)
396414
}
397415

398416
static int checkout_paths(const struct checkout_opts *opts,
399-
const char *revision)
417+
const struct branch_info *new_branch_info)
400418
{
401419
int pos;
402420
static char *ps_matched;
@@ -462,7 +480,7 @@ static int checkout_paths(const struct checkout_opts *opts,
462480
else
463481
BUG("either flag must have been set, worktree=%d, index=%d",
464482
opts->checkout_worktree, opts->checkout_index);
465-
return run_add_interactive(revision, patch_mode, &opts->pathspec);
483+
return run_add_interactive(new_branch_info->name, patch_mode, &opts->pathspec);
466484
}
467485

468486
repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);
@@ -523,7 +541,7 @@ static int checkout_paths(const struct checkout_opts *opts,
523541

524542
/* Now we are committed to check them out */
525543
if (opts->checkout_worktree)
526-
errs |= checkout_worktree(opts);
544+
errs |= checkout_worktree(opts, new_branch_info);
527545
else
528546
remove_marked_cache_entries(&the_index, 1);
529547

@@ -586,7 +604,8 @@ static void describe_detached_head(const char *msg, struct commit *commit)
586604
}
587605

588606
static int reset_tree(struct tree *tree, const struct checkout_opts *o,
589-
int worktree, int *writeout_error)
607+
int worktree, int *writeout_error,
608+
struct branch_info *info)
590609
{
591610
struct unpack_trees_options opts;
592611
struct tree_desc tree_desc;
@@ -601,6 +620,11 @@ static int reset_tree(struct tree *tree, const struct checkout_opts *o,
601620
opts.verbose_update = o->show_progress;
602621
opts.src_index = &the_index;
603622
opts.dst_index = &the_index;
623+
init_checkout_metadata(&opts.meta, info->refname,
624+
info->commit ? &info->commit->object.oid :
625+
is_null_oid(&info->oid) ? &tree->object.oid :
626+
&info->oid,
627+
NULL);
604628
parse_tree(tree);
605629
init_tree_desc(&tree_desc, tree->buffer, tree->size);
606630
switch (unpack_trees(1, &tree_desc, &opts)) {
@@ -620,21 +644,17 @@ static int reset_tree(struct tree *tree, const struct checkout_opts *o,
620644
}
621645
}
622646

623-
struct branch_info {
624-
const char *name; /* The short name used */
625-
const char *path; /* The full name of a real branch */
626-
struct commit *commit; /* The named commit */
627-
/*
628-
* if not null the branch is detached because it's already
629-
* checked out in this checkout
630-
*/
631-
char *checkout;
632-
};
633-
634647
static void setup_branch_path(struct branch_info *branch)
635648
{
636649
struct strbuf buf = STRBUF_INIT;
637650

651+
/*
652+
* If this is a ref, resolve it; otherwise, look up the OID for our
653+
* expression. Failure here is okay.
654+
*/
655+
if (!dwim_ref(branch->name, strlen(branch->name), &branch->oid, &branch->refname))
656+
repo_get_oid_committish(the_repository, branch->name, &branch->oid);
657+
638658
strbuf_branchname(&buf, branch->name, INTERPRET_BRANCH_LOCAL);
639659
if (strcmp(buf.buf, branch->name))
640660
branch->name = xstrdup(buf.buf);
@@ -663,7 +683,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
663683
} else
664684
new_tree = get_commit_tree(new_branch_info->commit);
665685
if (opts->discard_changes) {
666-
ret = reset_tree(new_tree, opts, 1, writeout_error);
686+
ret = reset_tree(new_tree, opts, 1, writeout_error, new_branch_info);
667687
if (ret)
668688
return ret;
669689
} else {
@@ -692,6 +712,10 @@ static int merge_working_tree(const struct checkout_opts *opts,
692712
topts.quiet = opts->merge && old_branch_info->commit;
693713
topts.verbose_update = opts->show_progress;
694714
topts.fn = twoway_merge;
715+
init_checkout_metadata(&topts.meta, new_branch_info->refname,
716+
new_branch_info->commit ?
717+
&new_branch_info->commit->object.oid :
718+
&new_branch_info->oid, NULL);
695719
if (opts->overwrite_ignore) {
696720
topts.dir = xcalloc(1, sizeof(*topts.dir));
697721
topts.dir->flags |= DIR_SHOW_IGNORED;
@@ -762,7 +786,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
762786

763787
ret = reset_tree(new_tree,
764788
opts, 1,
765-
writeout_error);
789+
writeout_error, new_branch_info);
766790
if (ret)
767791
return ret;
768792
o.ancestor = old_branch_info->name;
@@ -782,7 +806,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
782806
exit(128);
783807
ret = reset_tree(new_tree,
784808
opts, 0,
785-
writeout_error);
809+
writeout_error, new_branch_info);
786810
strbuf_release(&o.obuf);
787811
strbuf_release(&old_commit_shortname);
788812
if (ret)
@@ -1710,7 +1734,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
17101734

17111735
UNLEAK(opts);
17121736
if (opts->patch_mode || opts->pathspec.nr)
1713-
return checkout_paths(opts, new_branch_info.name);
1737+
return checkout_paths(opts, &new_branch_info);
17141738
else
17151739
return checkout_branch(opts, &new_branch_info);
17161740
}

builtin/clone.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -784,11 +784,11 @@ static int checkout(int submodule_progress)
784784
if (!strcmp(head, "HEAD")) {
785785
if (advice_detached_head)
786786
detach_advice(oid_to_hex(&oid));
787+
FREE_AND_NULL(head);
787788
} else {
788789
if (!starts_with(head, "refs/heads/"))
789790
die(_("HEAD not found below refs/heads!"));
790791
}
791-
free(head);
792792

793793
/* We need to be in the new work tree for the checkout */
794794
setup_work_tree();
@@ -803,13 +803,16 @@ static int checkout(int submodule_progress)
803803
opts.verbose_update = (option_verbosity >= 0);
804804
opts.src_index = &the_index;
805805
opts.dst_index = &the_index;
806+
init_checkout_metadata(&opts.meta, head, &oid, NULL);
806807

807808
tree = parse_tree_indirect(&oid);
808809
parse_tree(tree);
809810
init_tree_desc(&t, tree->buffer, tree->size);
810811
if (unpack_trees(1, &t, &opts) < 0)
811812
die(_("unable to checkout working tree"));
812813

814+
free(head);
815+
813816
if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
814817
die(_("unable to write new index file"));
815818

builtin/rebase.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,7 @@ static int reset_head(struct object_id *oid, const char *action,
868868
unpack_tree_opts.fn = reset_hard ? oneway_merge : twoway_merge;
869869
unpack_tree_opts.update = 1;
870870
unpack_tree_opts.merge = 1;
871+
init_checkout_metadata(&unpack_tree_opts.meta, switch_to_branch, oid, NULL);
871872
if (!detach_head)
872873
unpack_tree_opts.reset = 1;
873874

builtin/reset.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static inline int is_merge(void)
4646
return !access(git_path_merge_head(the_repository), F_OK);
4747
}
4848

49-
static int reset_index(const struct object_id *oid, int reset_type, int quiet)
49+
static int reset_index(const char *ref, const struct object_id *oid, int reset_type, int quiet)
5050
{
5151
int i, nr = 0;
5252
struct tree_desc desc[2];
@@ -60,6 +60,7 @@ static int reset_index(const struct object_id *oid, int reset_type, int quiet)
6060
opts.dst_index = &the_index;
6161
opts.fn = oneway_merge;
6262
opts.merge = 1;
63+
init_checkout_metadata(&opts.meta, ref, oid, NULL);
6364
if (!quiet)
6465
opts.verbose_update = 1;
6566
switch (reset_type) {
@@ -418,11 +419,20 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
418419
}
419420
}
420421
} else {
421-
int err = reset_index(&oid, reset_type, quiet);
422+
struct object_id dummy;
423+
char *ref = NULL;
424+
int err;
425+
426+
dwim_ref(rev, strlen(rev), &dummy, &ref);
427+
if (ref && !starts_with(ref, "refs/"))
428+
ref = NULL;
429+
430+
err = reset_index(ref, &oid, reset_type, quiet);
422431
if (reset_type == KEEP && !err)
423-
err = reset_index(&oid, MIXED, quiet);
432+
err = reset_index(ref, &oid, MIXED, quiet);
424433
if (err)
425434
die(_("Could not reset index file to revision '%s'."), rev);
435+
free(ref);
426436
}
427437

428438
if (write_locked_index(&the_index, &lock, COMMIT_LOCK))

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1698,6 +1698,7 @@ struct checkout {
16981698
const char *base_dir;
16991699
int base_dir_len;
17001700
struct delayed_checkout *delayed_checkout;
1701+
struct checkout_metadata meta;
17011702
unsigned force:1,
17021703
quiet:1,
17031704
not_new:1,

0 commit comments

Comments
 (0)