Skip to content

Commit 86fdd94

Browse files
derrickstoleegitster
authored andcommitted
clone: fail gracefully when cloning filtered bundle
Users can create a new repository using 'git clone <bundle-file>'. The new "@filter" capability for bundles means that we can generate a bundle that does not contain all reachable objects, even if the header has no negative commit OIDs. It is feasible to think that we could make a filtered bundle work with the command git clone --filter=$filter --bare <bundle-file> or possibly replacing --bare with --no-checkout. However, this requires having some repository-global config that specifies the specified object filter and notifies Git about the existence of promisor pack-files. Without a remote, that is currently impossible. As a stop-gap, parse the bundle header during 'git clone' and die() with a helpful error message instead of the current behavior of failing due to "missing objects". Most of the existing logic for handling bundle clones actually happens in fetch-pack.c, but that logic is the same as if the user specified 'git fetch <bundle>', so we want to avoid failing to fetch a filtered bundle when in an existing repository that has the proper config set up for at least one remote. Carefully comment around the test that this is not the desired long-term behavior of 'git clone' in this case, but instead that we need to do more work before that is possible. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4f39eb0 commit 86fdd94

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

builtin/clone.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "packfile.h"
3434
#include "list-objects-filter-options.h"
3535
#include "hook.h"
36+
#include "bundle.h"
3637

3738
/*
3839
* Overall FIXMEs:
@@ -1138,6 +1139,18 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
11381139
warning(_("--local is ignored"));
11391140
transport->cloning = 1;
11401141

1142+
if (is_bundle) {
1143+
struct bundle_header header = BUNDLE_HEADER_INIT;
1144+
int fd = read_bundle_header(path, &header);
1145+
int has_filter = header.filter.choice != LOFC_DISABLED;
1146+
1147+
if (fd > 0)
1148+
close(fd);
1149+
bundle_header_release(&header);
1150+
if (has_filter)
1151+
die(_("cannot clone from filtered bundle"));
1152+
}
1153+
11411154
transport_set_option(transport, TRANS_OPT_KEEP, "yes");
11421155

11431156
if (reject_shallow)

t/t6020-bundle-misc.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,4 +537,16 @@ do
537537
'
538538
done
539539

540+
# NEEDSWORK: 'git clone --bare' should be able to clone from a filtered
541+
# bundle, but that requires a change to promisor/filter config options.
542+
# For now, we fail gracefully with a helpful error. This behavior can be
543+
# changed in the future to succeed as much as possible.
544+
test_expect_success 'cloning from filtered bundle has useful error' '
545+
git bundle create partial.bdl \
546+
--all \
547+
--filter=blob:none &&
548+
test_must_fail git clone --bare partial.bdl partial 2>err &&
549+
grep "cannot clone from filtered bundle" err
550+
'
551+
540552
test_done

0 commit comments

Comments
 (0)