Skip to content

Commit

Permalink
git repack: keep commits hidden by a graft
Browse files Browse the repository at this point in the history
When you have grafts that pretend that a given commit has different
parents than the ones recorded in the commit object, it is dangerous
to let 'git repack' remove those hidden parents, as you can easily
remove the graft and end up with a broken repository.

So let's play it safe and keep those parent objects and everything
that is reachable by them, in addition to the grafted parents.

As this behavior can only be triggered by git pack-objects, and as that
command handles duplicate parents gracefully, we do not bother to cull
duplicated parents that may result by using both true and grafted
parents.

Signed-off-by: Johannes Schindelin <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
dscho authored and gitster committed Jul 24, 2009
1 parent 1ec6482 commit 7f3140c
Show file tree
Hide file tree
Showing 7 changed files with 20 additions and 4 deletions.
7 changes: 6 additions & 1 deletion Documentation/git-pack-objects.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ SYNOPSIS
[verse]
'git pack-objects' [-q] [--no-reuse-delta] [--delta-base-offset] [--non-empty]
[--local] [--incremental] [--window=N] [--depth=N] [--all-progress]
[--revs [--unpacked | --all]*] [--stdout | base-name] < object-list
[--revs [--unpacked | --all]*] [--stdout | base-name]
[--keep-true-parents] < object-list


DESCRIPTION
Expand Down Expand Up @@ -197,6 +198,10 @@ base-name::
to force the version for the generated pack index, and to force
64-bit index entries on objects located above the given offset.

--keep-true-parents::
With this option, parents that are hidden by grafts are packed
nevertheless.


Author
------
Expand Down
4 changes: 4 additions & 0 deletions builtin-pack-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -2259,6 +2259,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
die("bad %s", arg);
continue;
}
if (!strcmp(arg, "--keep-true-parents")) {
grafts_replace_parents = 0;
continue;
}
usage(pack_usage);
}

Expand Down
2 changes: 2 additions & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,8 @@ enum object_creation_mode {

extern enum object_creation_mode object_creation_mode;

extern int grafts_replace_parents;

#define GIT_REPO_VERSION 0
extern int repository_format_version;
extern int check_repository_format(void);
Expand Down
6 changes: 5 additions & 1 deletion commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,11 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
bufptr[47] != '\n')
return error("bad parents in commit %s", sha1_to_hex(item->object.sha1));
bufptr += 48;
if (graft)
/*
* The clone is shallow if nr_parent < 0, and we must
* not traverse its real parents even when we unhide them.
*/
if (graft && (graft->nr_parent < 0 || grafts_replace_parents))
continue;
new_parent = lookup_commit(parent);
if (new_parent)
Expand Down
1 change: 1 addition & 0 deletions environment.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
#define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS
#endif
enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
int grafts_replace_parents = 1;

/* Parallel index stat data preload? */
int core_preload_index = 0;
Expand Down
2 changes: 1 addition & 1 deletion git-repack.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ case ",$all_into_one," in
esac

args="$args $local $quiet $no_reuse$extra"
names=$(git pack-objects --honor-pack-keep --non-empty --all --reflog $args </dev/null "$PACKTMP") ||
names=$(git pack-objects --keep-true-parents --honor-pack-keep --non-empty --all --reflog $args </dev/null "$PACKTMP") ||
exit 1
if [ -z "$names" ]; then
if test -z "$quiet"; then
Expand Down
2 changes: 1 addition & 1 deletion t/t7700-repack.sh
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ test_expect_success 'local packed unreachable obs that exist in alternate ODB ar
test_must_fail git show $csha1
'

test_expect_failure 'objects made unreachable by grafts only are kept' '
test_expect_success 'objects made unreachable by grafts only are kept' '
test_tick &&
git commit --allow-empty -m "commit 4" &&
H0=$(git rev-parse HEAD) &&
Expand Down

0 comments on commit 7f3140c

Please sign in to comment.