summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-pack-objects.txt7
-rw-r--r--builtin-pack-objects.c4
-rw-r--r--cache.h2
-rw-r--r--commit.c6
-rw-r--r--environment.c1
-rwxr-xr-xgit-repack.sh2
-rwxr-xr-xt/t7700-repack.sh12
7 files changed, 31 insertions, 3 deletions
diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt
index 7d4c1a7556..2e4992970e 100644
--- a/Documentation/git-pack-objects.txt
+++ b/Documentation/git-pack-objects.txt
@@ -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
@@ -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
------
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index a27c2f6277..ef4bf6bc14 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -2255,6 +2255,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);
}
diff --git a/cache.h b/cache.h
index c72f125bd4..e6c7f3307d 100644
--- a/cache.h
+++ b/cache.h
@@ -560,6 +560,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);
diff --git a/commit.c b/commit.c
index a47fb4da27..e2bcbe8149 100644
--- a/commit.c
+++ b/commit.c
@@ -262,7 +262,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)
diff --git a/environment.c b/environment.c
index 720f26b67d..8f5eaa7dd8 100644
--- a/environment.c
+++ b/environment.c
@@ -47,6 +47,7 @@ enum push_default_type push_default = PUSH_DEFAULT_MATCHING;
#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;
diff --git a/git-repack.sh b/git-repack.sh
index 1bf239499c..1eb3bca352 100755
--- a/git-repack.sh
+++ b/git-repack.sh
@@ -81,7 +81,7 @@ case ",$all_into_one," in
esac
args="$args $local ${GIT_QUIET:+-q} $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
say Nothing new to pack.
diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh
index 87c9b0e121..f4aa054750 100755
--- a/t/t7700-repack.sh
+++ b/t/t7700-repack.sh
@@ -149,5 +149,17 @@ test_expect_success 'local packed unreachable obs that exist in alternate ODB ar
test_must_fail git show $csha1
'
+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) &&
+ H1=$(git rev-parse HEAD^) &&
+ H2=$(git rev-parse HEAD^^) &&
+ echo "$H0 $H2" > .git/info/grafts &&
+ git reflog expire --expire=now --expire-unreachable=now --all &&
+ git repack -a -d &&
+ git cat-file -t $H1
+ '
+
test_done