提交 7f3140cd 编写于 作者: J Johannes Schindelin 提交者: Junio C Hamano

git repack: keep commits hidden by a graft

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: NJohannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: NJunio C Hamano <gitster@pobox.com>
上级 1ec64827
...@@ -11,7 +11,8 @@ SYNOPSIS ...@@ -11,7 +11,8 @@ SYNOPSIS
[verse] [verse]
'git pack-objects' [-q] [--no-reuse-delta] [--delta-base-offset] [--non-empty] 'git pack-objects' [-q] [--no-reuse-delta] [--delta-base-offset] [--non-empty]
[--local] [--incremental] [--window=N] [--depth=N] [--all-progress] [--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 DESCRIPTION
...@@ -197,6 +198,10 @@ base-name:: ...@@ -197,6 +198,10 @@ base-name::
to force the version for the generated pack index, and to force to force the version for the generated pack index, and to force
64-bit index entries on objects located above the given offset. 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 Author
------ ------
......
...@@ -2259,6 +2259,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) ...@@ -2259,6 +2259,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
die("bad %s", arg); die("bad %s", arg);
continue; continue;
} }
if (!strcmp(arg, "--keep-true-parents")) {
grafts_replace_parents = 0;
continue;
}
usage(pack_usage); usage(pack_usage);
} }
......
...@@ -561,6 +561,8 @@ enum object_creation_mode { ...@@ -561,6 +561,8 @@ enum object_creation_mode {
extern enum object_creation_mode object_creation_mode; extern enum object_creation_mode object_creation_mode;
extern int grafts_replace_parents;
#define GIT_REPO_VERSION 0 #define GIT_REPO_VERSION 0
extern int repository_format_version; extern int repository_format_version;
extern int check_repository_format(void); extern int check_repository_format(void);
......
...@@ -266,7 +266,11 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size) ...@@ -266,7 +266,11 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
bufptr[47] != '\n') bufptr[47] != '\n')
return error("bad parents in commit %s", sha1_to_hex(item->object.sha1)); return error("bad parents in commit %s", sha1_to_hex(item->object.sha1));
bufptr += 48; 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; continue;
new_parent = lookup_commit(parent); new_parent = lookup_commit(parent);
if (new_parent) if (new_parent)
......
...@@ -47,6 +47,7 @@ enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED; ...@@ -47,6 +47,7 @@ enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
#define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS #define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS
#endif #endif
enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE; enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
int grafts_replace_parents = 1;
/* Parallel index stat data preload? */ /* Parallel index stat data preload? */
int core_preload_index = 0; int core_preload_index = 0;
......
...@@ -81,7 +81,7 @@ case ",$all_into_one," in ...@@ -81,7 +81,7 @@ case ",$all_into_one," in
esac esac
args="$args $local $quiet $no_reuse$extra" 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 exit 1
if [ -z "$names" ]; then if [ -z "$names" ]; then
if test -z "$quiet"; then if test -z "$quiet"; then
......
...@@ -149,7 +149,7 @@ test_expect_success 'local packed unreachable obs that exist in alternate ODB ar ...@@ -149,7 +149,7 @@ test_expect_success 'local packed unreachable obs that exist in alternate ODB ar
test_must_fail git show $csha1 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 && test_tick &&
git commit --allow-empty -m "commit 4" && git commit --allow-empty -m "commit 4" &&
H0=$(git rev-parse HEAD) && H0=$(git rev-parse HEAD) &&
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册