Skip to content

Commit

Permalink
git-pack-objects: Automatically pack annotated tags if object was packed
Browse files Browse the repository at this point in the history
The new option "--include-tag" allows the caller to request that
any annotated tag be included into the packfile if the object the tag
references was also included as part of the packfile.

This option can be useful on the server side of a native git transport,
where the server knows what commits it is including into a packfile to
update the client.  If new annotated tags have been introduced then we
can also include them in the packfile, saving the client from needing
to request them through a second connection.

This change only introduces the backend option and provides a test.
Protocol extensions to make this useful in fetch-pack/upload-pack
are still necessary to activate the logic during transport.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Shawn O. Pearce authored and Junio C Hamano committed Mar 5, 2008
1 parent cf7f929 commit f0a24aa
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 2 deletions.
5 changes: 5 additions & 0 deletions Documentation/git-pack-objects.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ base-name::
as if all refs under `$GIT_DIR/refs` are specified to be
included.

--include-tag::
Include unasked-for annotated tags if the object they
reference was included in the resulting packfile. This
can be useful to send new tags to native git clients.

--window=[N], --depth=[N]::
These two options affect how the objects contained in
the pack are stored using delta compression. The
Expand Down
24 changes: 22 additions & 2 deletions builtin-pack-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "revision.h"
#include "list-objects.h"
#include "progress.h"
#include "refs.h"

#ifdef THREADED_DELTA_SEARCH
#include "thread-utils.h"
Expand All @@ -27,7 +28,8 @@ git-pack-objects [{ -q | --progress | --all-progress }] \n\
[--window=N] [--window-memory=N] [--depth=N] \n\
[--no-reuse-delta] [--no-reuse-object] [--delta-base-offset] \n\
[--threads=N] [--non-empty] [--revs [--unpacked | --all]*] [--reflog] \n\
[--stdout | base-name] [--keep-unreachable] [<ref-list | <object-list]";
[--stdout | base-name] [--include-tag] [--keep-unreachable] \n\
[<ref-list | <object-list]";

struct object_entry {
struct pack_idx_entry idx;
Expand Down Expand Up @@ -63,7 +65,7 @@ static struct pack_idx_entry **written_list;
static uint32_t nr_objects, nr_alloc, nr_result, nr_written;

static int non_empty;
static int no_reuse_delta, no_reuse_object, keep_unreachable;
static int no_reuse_delta, no_reuse_object, keep_unreachable, include_tag;
static int local;
static int incremental;
static int allow_ofs_delta;
Expand Down Expand Up @@ -1630,6 +1632,18 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
#define ll_find_deltas(l, s, w, d, p) find_deltas(l, &s, w, d, p)
#endif

static int add_ref_tag(const char *path, const unsigned char *sha1, int flag, void *cb_data)
{
unsigned char peeled[20];

if (!prefixcmp(path, "refs/tags/") && /* is a tag? */
!peel_ref(path, peeled) && /* peelable? */
!is_null_sha1(peeled) && /* annotated tag? */
locate_object_entry(peeled)) /* object packed? */
add_object_entry(sha1, OBJ_TAG, NULL, 0);
return 0;
}

static void prepare_pack(int window, int depth)
{
struct object_entry **delta_list;
Expand Down Expand Up @@ -2033,6 +2047,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
keep_unreachable = 1;
continue;
}
if (!strcmp("--include-tag", arg)) {
include_tag = 1;
continue;
}
if (!strcmp("--unpacked", arg) ||
!prefixcmp(arg, "--unpacked=") ||
!strcmp("--reflog", arg) ||
Expand Down Expand Up @@ -2109,6 +2127,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
rp_av[rp_ac] = NULL;
get_object_list(rp_ac, rp_av);
}
if (include_tag && nr_result)
for_each_ref(add_ref_tag, NULL);
stop_progress(&progress_state);

if (non_empty && !nr_result)
Expand Down
84 changes: 84 additions & 0 deletions t/t5305-include-tag.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/bin/sh

test_description='git-pack-object --include-tag'
. ./test-lib.sh

TRASH=`pwd`

test_expect_success setup '
echo c >d &&
git update-index --add d &&
tree=`git write-tree` &&
commit=`git commit-tree $tree </dev/null` &&
echo "object $commit" >sig &&
echo "type commit" >>sig &&
echo "tag mytag" >>sig &&
echo "tagger $(git var GIT_COMMITTER_IDENT)" >>sig &&
echo >>sig &&
echo "our test tag" >>sig &&
tag=`git mktag <sig` &&
rm d sig &&
git update-ref refs/tags/mytag $tag && {
echo $tree &&
echo $commit &&
git ls-tree $tree | sed -e "s/.* \\([0-9a-f]*\\) .*/\\1/"
} >obj-list
'

rm -rf clone.git
test_expect_success 'pack without --include-tag' '
packname_1=$(git pack-objects \
--window=0 \
test-1 <obj-list)
'

test_expect_success 'unpack objects' '
(
GIT_DIR=clone.git &&
export GIT_DIR &&
git init &&
git unpack-objects -n <test-1-${packname_1}.pack &&
git unpack-objects <test-1-${packname_1}.pack
)
'

test_expect_success 'check unpacked result (have commit, no tag)' '
git rev-list --objects $commit >list.expect &&
(
GIT_DIR=clone.git &&
export GIT_DIR &&
test_must_fail git cat-file -e $tag &&
git rev-list --objects $commit
) >list.actual &&
git diff list.expect list.actual
'

rm -rf clone.git
test_expect_success 'pack with --include-tag' '
packname_1=$(git pack-objects \
--window=0 \
--include-tag \
test-2 <obj-list)
'

test_expect_success 'unpack objects' '
(
GIT_DIR=clone.git &&
export GIT_DIR &&
git init &&
git unpack-objects -n <test-2-${packname_1}.pack &&
git unpack-objects <test-2-${packname_1}.pack
)
'

test_expect_success 'check unpacked result (have commit, have tag)' '
git rev-list --objects mytag >list.expect &&
(
GIT_DIR=clone.git &&
export GIT_DIR &&
git rev-list --objects $tag
) >list.actual &&
git diff list.expect list.actual
'

test_done

0 comments on commit f0a24aa

Please sign in to comment.