Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

repack -ad: fix after fetch --prune in a shallow repository #9

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion builtin/prune.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
6 changes: 6 additions & 0 deletions builtin/repack.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,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)
Expand Down
4 changes: 3 additions & 1 deletion commit.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,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;

extern int interactive_add(int argc, const char **argv, const char *prefix, int patch);
Expand Down
23 changes: 17 additions & 6 deletions shallow.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,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;
Expand All @@ -261,7 +262,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)
Expand Down Expand Up @@ -371,24 +375,31 @@ 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;
}
fd = hold_lock_file_for_update(&shallow_lock,
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));
Expand Down
27 changes: 27 additions & 0 deletions t/t5537-fetch-shallow.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down