summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2006-12-19 01:25:28 (GMT)
committerJunio C Hamano <junkio@cox.net>2006-12-21 01:22:10 (GMT)
commit63049292e083faf80e033eba4fa43efdbac3acad (patch)
treedf1f63518f6593934c8961545c90b44d6fe01943
parent55dd55263b6d27aa8daa77bd69f5ea990b66c7a1 (diff)
downloadgit-63049292e083faf80e033eba4fa43efdbac3acad.zip
git-63049292e083faf80e033eba4fa43efdbac3acad.tar.gz
git-63049292e083faf80e033eba4fa43efdbac3acad.tar.bz2
Teach git-repack to preserve objects referred to by reflog entries.
This adds a new option --reflog to pack-objects and revision machinery; do not bother documenting it for now, since this is only useful for local repacking. When the option is passed, objects reachable from reflog entries are marked as interesting while computing the set of objects to pack. Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r--builtin-pack-objects.c3
-rwxr-xr-xgit-repack.sh2
-rw-r--r--revision.c56
3 files changed, 52 insertions, 9 deletions
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 807be8c..9e15beb 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -17,7 +17,7 @@ static const char pack_usage[] = "\
git-pack-objects [{ -q | --progress | --all-progress }] \n\
[--local] [--incremental] [--window=N] [--depth=N] \n\
[--no-reuse-delta] [--delta-base-offset] [--non-empty] \n\
- [--revs [--unpacked | --all]*] [--stdout | base-name] \n\
+ [--revs [--unpacked | --all]*] [--reflog] [--stdout | base-name] \n\
[<ref-list | <object-list]";
struct object_entry {
@@ -1575,6 +1575,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
}
if (!strcmp("--unpacked", arg) ||
!strncmp("--unpacked=", arg, 11) ||
+ !strcmp("--reflog", arg) ||
!strcmp("--all", arg)) {
use_internal_rev_list = 1;
if (ARRAY_SIZE(rp_av) - 1 <= rp_ac)
diff --git a/git-repack.sh b/git-repack.sh
index 067898f..375434b 100755
--- a/git-repack.sh
+++ b/git-repack.sh
@@ -62,7 +62,7 @@ case ",$all_into_one," in
esac
args="$args $local $quiet $no_reuse_delta$extra"
-name=$(git-pack-objects --non-empty --all $args </dev/null "$PACKTMP") ||
+name=$(git-pack-objects --non-empty --all --reflog $args </dev/null "$PACKTMP") ||
exit 1
if [ -z "$name" ]; then
echo Nothing new to pack.
diff --git a/revision.c b/revision.c
index 4dae534..bda9d4d 100644
--- a/revision.c
+++ b/revision.c
@@ -464,21 +464,59 @@ static void limit_list(struct rev_info *revs)
revs->commits = newlist;
}
-static int all_flags;
-static struct rev_info *all_revs;
+struct all_refs_cb {
+ int all_flags;
+ struct rev_info *all_revs;
+ const char *name_for_errormsg;
+};
static int handle_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
{
- struct object *object = get_reference(all_revs, path, sha1, all_flags);
- add_pending_object(all_revs, object, "");
+ struct all_refs_cb *cb = cb_data;
+ struct object *object = get_reference(cb->all_revs, path, sha1,
+ cb->all_flags);
+ add_pending_object(cb->all_revs, object, "");
return 0;
}
static void handle_all(struct rev_info *revs, unsigned flags)
{
- all_revs = revs;
- all_flags = flags;
- for_each_ref(handle_one_ref, NULL);
+ struct all_refs_cb cb;
+ cb.all_revs = revs;
+ cb.all_flags = flags;
+ for_each_ref(handle_one_ref, &cb);
+}
+
+static int handle_one_reflog_ent(unsigned char *osha1, unsigned char *nsha1, char *detail, void *cb_data)
+{
+ struct all_refs_cb *cb = cb_data;
+ struct object *object;
+
+ if (!is_null_sha1(osha1)) {
+ object = get_reference(cb->all_revs, cb->name_for_errormsg,
+ osha1, cb->all_flags);
+ add_pending_object(cb->all_revs, object, "");
+ }
+ object = get_reference(cb->all_revs, cb->name_for_errormsg,
+ nsha1, cb->all_flags);
+ add_pending_object(cb->all_revs, object, "");
+ return 0;
+}
+
+static int handle_one_reflog(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+{
+ struct all_refs_cb *cb = cb_data;
+ cb->name_for_errormsg = path;
+ for_each_reflog_ent(path, handle_one_reflog_ent, cb_data);
+ return 0;
+}
+
+static void handle_reflog(struct rev_info *revs, unsigned flags)
+{
+ struct all_refs_cb cb;
+ cb.all_revs = revs;
+ cb.all_flags = flags;
+ for_each_ref(handle_one_reflog, &cb);
}
static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
@@ -805,6 +843,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
handle_all(revs, flags);
continue;
}
+ if (!strcmp(arg, "--reflog")) {
+ handle_reflog(revs, flags);
+ continue;
+ }
if (!strcmp(arg, "--not")) {
flags ^= UNINTERESTING;
continue;