提交 c7740a94 编写于 作者: J Junio C Hamano

send-pack --keep: do not explode into loose objects on the receiving end.

This adds "keep-pack" extension to send-pack vs receive pack protocol,
and makes the receiver invoke "index-pack --stdin --fix-thin".

With this, you can ask send-pack not to explode the result into
loose objects on the receiving end.

I've patched has_sha1_file() to re-check for added packs just
like is done in read_sha1_file() for now, but I think the static
"re-prepare" interface for packs was a mistake.  Creation of a
new pack inside a process that needs to read objects in them
back ought to be a rare event, so we are better off making the
callers (such as receive-pack that calls "index-pack --stdin
--fix-thin") explicitly call re-prepare.  That way we do not
have to penalize ordinary users of read_sha1_file() and
has_sha1_file().

We would need to fix this someday.
Signed-off-by: NJunio C Hamano <junkio@cox.net>
上级 b89c4e93
......@@ -8,10 +8,14 @@
static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
static const char *unpacker[] = { "unpack-objects", NULL };
static const char *keep_packer[] = {
"index-pack", "--stdin", "--fix-thin", NULL
};
static int report_status;
static int keep_pack;
static char capabilities[] = "report-status";
static char capabilities[] = "report-status keep-pack";
static int capabilities_sent;
static int show_ref(const char *path, const unsigned char *sha1)
......@@ -261,6 +265,8 @@ static void read_head_info(void)
if (reflen + 82 < len) {
if (strstr(refname + reflen + 1, "report-status"))
report_status = 1;
if (strstr(refname + reflen + 1, "keep-pack"))
keep_pack = 1;
}
cmd = xmalloc(sizeof(struct command) + len - 80);
hashcpy(cmd->old_sha1, old_sha1);
......@@ -275,7 +281,14 @@ static void read_head_info(void)
static const char *unpack(int *error_code)
{
int code = run_command_v_opt(1, unpacker, RUN_GIT_CMD);
int code;
if (keep_pack)
code = run_command_v_opt(ARRAY_SIZE(keep_packer) - 1,
keep_packer, RUN_GIT_CMD);
else
code = run_command_v_opt(ARRAY_SIZE(unpacker) - 1,
unpacker, RUN_GIT_CMD);
*error_code = 0;
switch (code) {
......@@ -335,7 +348,7 @@ int main(int argc, char **argv)
if (!dir)
usage(receive_pack_usage);
if(!enter_repo(dir, 0))
if (!enter_repo(dir, 0))
die("'%s': unable to chdir or not a git archive", dir);
write_head_info();
......
......@@ -6,13 +6,14 @@
#include "exec_cmd.h"
static const char send_pack_usage[] =
"git-send-pack [--all] [--exec=git-receive-pack] <remote> [<head>...]\n"
"git-send-pack [--all] [--keep] [--exec=git-receive-pack] <remote> [<head>...]\n"
" --all and explicit <head> specification are mutually exclusive.";
static const char *exec = "git-receive-pack";
static int verbose;
static int send_all;
static int force_update;
static int use_thin_pack;
static int keep_pack;
static int is_zero_sha1(const unsigned char *sha1)
{
......@@ -270,6 +271,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
int new_refs;
int ret = 0;
int ask_for_status_report = 0;
int ask_to_keep_pack = 0;
int expect_status_report = 0;
/* No funny business with the matcher */
......@@ -279,6 +281,8 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
/* Does the other end support the reporting? */
if (server_supports("report-status"))
ask_for_status_report = 1;
if (server_supports("keep-pack") && keep_pack)
ask_to_keep_pack = 1;
/* match them up */
if (!remote_tail)
......@@ -355,12 +359,17 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
strcpy(old_hex, sha1_to_hex(ref->old_sha1));
new_hex = sha1_to_hex(ref->new_sha1);
if (ask_for_status_report) {
packet_write(out, "%s %s %s%c%s",
if (ask_for_status_report || ask_to_keep_pack) {
packet_write(out, "%s %s %s%c%s%s",
old_hex, new_hex, ref->name, 0,
"report-status");
ask_for_status_report
? " report-status" : "",
ask_to_keep_pack
? " keep-pack" : "");
if (ask_for_status_report)
expect_status_report = 1;
ask_for_status_report = 0;
expect_status_report = 1;
ask_to_keep_pack = 0;
}
else
packet_write(out, "%s %s %s",
......@@ -419,6 +428,10 @@ int main(int argc, char **argv)
verbose = 1;
continue;
}
if (!strcmp(arg, "--keep")) {
keep_pack = 1;
continue;
}
if (!strcmp(arg, "--thin")) {
use_thin_pack = 1;
continue;
......
......@@ -1292,7 +1292,7 @@ static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned lo
return unpack_entry(&e, type, size);
}
void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size)
void *read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size)
{
unsigned long mapsize;
void *map, *buf;
......@@ -1757,7 +1757,10 @@ int has_sha1_file(const unsigned char *sha1)
if (find_pack_entry(sha1, &e, NULL))
return 1;
return find_sha1_file(sha1, &st) ? 1 : 0;
if (find_sha1_file(sha1, &st))
return 1;
reprepare_packed_git();
return find_pack_entry(sha1, &e, NULL);
}
/*
......
......@@ -78,4 +78,13 @@ test_expect_success \
! diff -u .git/refs/heads/master victim/.git/refs/heads/master
'
test_expect_success 'push with --keep' '
t=`cd victim && git-rev-parse --verify refs/heads/master` &&
git-update-ref refs/heads/master $t &&
: > foo &&
git add foo &&
git commit -m "one more" &&
git-send-pack --keep ./victim/.git/ master
'
test_done
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册