Merge branch 'js/shallow-and-fetch-prune' into maint
"git repack" in a shallow clone did not correctly update the shallow points in the repository, leading to a repository that does not pass fsck. * js/shallow-and-fetch-prune: repack -ad: prune the list of shallow commits shallow: offer to prune only non-existing entries repack: point out a bug handling stale shallow info
This commit is contained in:
commit
d0975a0724
@ -161,7 +161,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
|
||||
free(s);
|
||||
|
||||
if (is_repository_shallow(the_repository))
|
||||
prune_shallow(show_only);
|
||||
prune_shallow(show_only ? PRUNE_SHOW_ONLY : 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -531,6 +531,12 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
|
||||
if (!po_args.quiet && isatty(2))
|
||||
opts |= PRUNE_PACKED_VERBOSE;
|
||||
prune_packed_objects(opts);
|
||||
|
||||
if (!keep_unreachable &&
|
||||
(!(pack_everything & LOOSEN_UNREACHABLE) ||
|
||||
unpack_unreachable) &&
|
||||
is_repository_shallow(the_repository))
|
||||
prune_shallow(PRUNE_QUICK);
|
||||
}
|
||||
|
||||
if (!no_update_server_info)
|
||||
|
4
commit.h
4
commit.h
@ -256,7 +256,9 @@ extern void assign_shallow_commits_to_refs(struct shallow_info *info,
|
||||
uint32_t **used,
|
||||
int *ref_status);
|
||||
extern int delayed_reachability_test(struct shallow_info *si, int c);
|
||||
extern void prune_shallow(int show_only);
|
||||
#define PRUNE_SHOW_ONLY 1
|
||||
#define PRUNE_QUICK 2
|
||||
extern void prune_shallow(unsigned options);
|
||||
extern struct trace_key trace_shallow;
|
||||
|
||||
int is_descendant_of(struct commit *, struct commit_list *);
|
||||
|
23
shallow.c
23
shallow.c
@ -246,6 +246,7 @@ static void check_shallow_file_for_update(struct repository *r)
|
||||
|
||||
#define SEEN_ONLY 1
|
||||
#define VERBOSE 2
|
||||
#define QUICK 4
|
||||
|
||||
struct write_shallow_data {
|
||||
struct strbuf *out;
|
||||
@ -260,7 +261,10 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
|
||||
const char *hex = oid_to_hex(&graft->oid);
|
||||
if (graft->nr_parent != -1)
|
||||
return 0;
|
||||
if (data->flags & SEEN_ONLY) {
|
||||
if (data->flags & QUICK) {
|
||||
if (!has_object_file(&graft->oid))
|
||||
return 0;
|
||||
} else if (data->flags & SEEN_ONLY) {
|
||||
struct commit *c = lookup_commit(the_repository, &graft->oid);
|
||||
if (!c || !(c->object.flags & SEEN)) {
|
||||
if (data->flags & VERBOSE)
|
||||
@ -370,16 +374,23 @@ void advertise_shallow_grafts(int fd)
|
||||
|
||||
/*
|
||||
* mark_reachable_objects() should have been run prior to this and all
|
||||
* reachable commits marked as "SEEN".
|
||||
* reachable commits marked as "SEEN", except when quick_prune is non-zero,
|
||||
* in which case lines are excised from the shallow file if they refer to
|
||||
* commits that do not exist (any longer).
|
||||
*/
|
||||
void prune_shallow(int show_only)
|
||||
void prune_shallow(unsigned options)
|
||||
{
|
||||
struct lock_file shallow_lock = LOCK_INIT;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
unsigned flags = SEEN_ONLY;
|
||||
int fd;
|
||||
|
||||
if (show_only) {
|
||||
write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY | VERBOSE);
|
||||
if (options & PRUNE_QUICK)
|
||||
flags |= QUICK;
|
||||
|
||||
if (options & PRUNE_SHOW_ONLY) {
|
||||
flags |= VERBOSE;
|
||||
write_shallow_commits_1(&sb, 0, NULL, flags);
|
||||
strbuf_release(&sb);
|
||||
return;
|
||||
}
|
||||
@ -387,7 +398,7 @@ void prune_shallow(int show_only)
|
||||
git_path_shallow(the_repository),
|
||||
LOCK_DIE_ON_ERROR);
|
||||
check_shallow_file_for_update(the_repository);
|
||||
if (write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY)) {
|
||||
if (write_shallow_commits_1(&sb, 0, NULL, flags)) {
|
||||
if (write_in_full(fd, sb.buf, sb.len) < 0)
|
||||
die_errno("failed to write to %s",
|
||||
get_lock_file_path(&shallow_lock));
|
||||
|
@ -186,6 +186,33 @@ EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success '.git/shallow is edited by repack' '
|
||||
git init shallow-server &&
|
||||
test_commit -C shallow-server A &&
|
||||
test_commit -C shallow-server B &&
|
||||
git -C shallow-server checkout -b branch &&
|
||||
test_commit -C shallow-server C &&
|
||||
test_commit -C shallow-server E &&
|
||||
test_commit -C shallow-server D &&
|
||||
d="$(git -C shallow-server rev-parse --verify D^0)" &&
|
||||
git -C shallow-server checkout master &&
|
||||
|
||||
git clone --depth=1 --no-tags --no-single-branch \
|
||||
"file://$PWD/shallow-server" shallow-client &&
|
||||
|
||||
: now remove the branch and fetch with prune &&
|
||||
git -C shallow-server branch -D branch &&
|
||||
git -C shallow-client fetch --prune --depth=1 \
|
||||
origin "+refs/heads/*:refs/remotes/origin/*" &&
|
||||
git -C shallow-client repack -adfl &&
|
||||
test_must_fail git -C shallow-client rev-parse --verify $d^0 &&
|
||||
! grep $d shallow-client/.git/shallow &&
|
||||
|
||||
git -C shallow-server branch branch-orig $d &&
|
||||
git -C shallow-client fetch --prune --depth=2 \
|
||||
origin "+refs/heads/*:refs/remotes/origin/*"
|
||||
'
|
||||
|
||||
. "$TEST_DIRECTORY"/lib-httpd.sh
|
||||
start_httpd
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user