зеркало из https://github.com/microsoft/git.git
Merge branch 'jc/maint-fetch-alt'
* jc/maint-fetch-alt: fetch-pack: objects in our alternates are available to us refs_from_alternate: helper to use refs from alternates Conflicts: builtin/receive-pack.c
This commit is contained in:
Коммит
91b3c7ce8e
|
@ -9,6 +9,7 @@
|
|||
#include "fetch-pack.h"
|
||||
#include "remote.h"
|
||||
#include "run-command.h"
|
||||
#include "transport.h"
|
||||
|
||||
static int transfer_unpack_limit = -1;
|
||||
static int fetch_unpack_limit = -1;
|
||||
|
@ -217,6 +218,16 @@ static void send_request(int fd, struct strbuf *buf)
|
|||
safe_write(fd, buf->buf, buf->len);
|
||||
}
|
||||
|
||||
static void insert_one_alternate_ref(const struct ref *ref, void *unused)
|
||||
{
|
||||
rev_list_insert_ref(NULL, ref->old_sha1, 0, NULL);
|
||||
}
|
||||
|
||||
static void insert_alternate_refs(void)
|
||||
{
|
||||
foreach_alt_odb(refs_from_alternate_cb, insert_one_alternate_ref);
|
||||
}
|
||||
|
||||
static int find_common(int fd[2], unsigned char *result_sha1,
|
||||
struct ref *refs)
|
||||
{
|
||||
|
@ -235,6 +246,7 @@ static int find_common(int fd[2], unsigned char *result_sha1,
|
|||
marked = 1;
|
||||
|
||||
for_each_ref(rev_list_insert_ref, NULL);
|
||||
insert_alternate_refs();
|
||||
|
||||
fetching = 0;
|
||||
for ( ; refs ; refs = refs->next) {
|
||||
|
|
|
@ -731,43 +731,14 @@ static int delete_only(struct command *commands)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
|
||||
static void add_one_alternate_ref(const struct ref *ref, void *unused)
|
||||
{
|
||||
char *other;
|
||||
size_t len;
|
||||
struct remote *remote;
|
||||
struct transport *transport;
|
||||
const struct ref *extra;
|
||||
|
||||
e->name[-1] = '\0';
|
||||
other = xstrdup(real_path(e->base));
|
||||
e->name[-1] = '/';
|
||||
len = strlen(other);
|
||||
|
||||
while (other[len-1] == '/')
|
||||
other[--len] = '\0';
|
||||
if (len < 8 || memcmp(other + len - 8, "/objects", 8))
|
||||
return 0;
|
||||
/* Is this a git repository with refs? */
|
||||
memcpy(other + len - 8, "/refs", 6);
|
||||
if (!is_directory(other))
|
||||
return 0;
|
||||
other[len - 8] = '\0';
|
||||
remote = remote_get(other);
|
||||
transport = transport_get(remote, other);
|
||||
for (extra = transport_get_remote_refs(transport);
|
||||
extra;
|
||||
extra = extra->next) {
|
||||
add_extra_ref(".have", extra->old_sha1, 0);
|
||||
}
|
||||
transport_disconnect(transport);
|
||||
free(other);
|
||||
return 0;
|
||||
add_extra_ref(".have", ref->old_sha1, 0);
|
||||
}
|
||||
|
||||
static void add_alternate_refs(void)
|
||||
{
|
||||
foreach_alt_odb(add_refs_from_alternate, NULL);
|
||||
foreach_alt_odb(refs_from_alternate_cb, add_one_alternate_ref);
|
||||
}
|
||||
|
||||
int cmd_receive_pack(int argc, const char **argv, const char *prefix)
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
#!/bin/sh
|
||||
|
||||
test_description='fetch/push involving alternates'
|
||||
. ./test-lib.sh
|
||||
|
||||
count_objects () {
|
||||
loose=0 inpack=0
|
||||
eval "$(
|
||||
git count-objects -v |
|
||||
sed -n -e 's/^count: \(.*\)/loose=\1/p' \
|
||||
-e 's/^in-pack: \(.*\)/inpack=\1/p'
|
||||
)" &&
|
||||
echo $(( $loose + $inpack ))
|
||||
}
|
||||
|
||||
|
||||
test_expect_success setup '
|
||||
(
|
||||
git init original &&
|
||||
cd original &&
|
||||
i=0 &&
|
||||
while test $i -le 100
|
||||
do
|
||||
echo "$i" >count &&
|
||||
git add count &&
|
||||
git commit -m "$i" || exit
|
||||
i=$(($i + 1))
|
||||
done
|
||||
) &&
|
||||
(
|
||||
git clone --reference=original "file:///$(pwd)/original" one &&
|
||||
cd one &&
|
||||
echo Z >count &&
|
||||
git add count &&
|
||||
git commit -m Z &&
|
||||
count_objects >../one.count
|
||||
) &&
|
||||
A=$(pwd)/original/.git/objects &&
|
||||
git init receiver &&
|
||||
echo "$A" >receiver/.git/objects/info/alternates &&
|
||||
git init fetcher &&
|
||||
echo "$A" >fetcher/.git/objects/info/alternates
|
||||
'
|
||||
|
||||
test_expect_success 'pushing into a repository with the same alternate' '
|
||||
(
|
||||
cd one &&
|
||||
git push ../receiver master:refs/heads/it
|
||||
) &&
|
||||
(
|
||||
cd receiver &&
|
||||
count_objects >../receiver.count
|
||||
) &&
|
||||
test_cmp one.count receiver.count
|
||||
'
|
||||
|
||||
test_expect_success 'fetching from a repository with the same alternate' '
|
||||
(
|
||||
cd fetcher &&
|
||||
git fetch ../one master:refs/heads/it &&
|
||||
count_objects >../fetcher.count
|
||||
) &&
|
||||
test_cmp one.count fetcher.count
|
||||
'
|
||||
|
||||
test_done
|
34
transport.c
34
transport.c
|
@ -1189,3 +1189,37 @@ char *transport_anonymize_url(const char *url)
|
|||
literal_copy:
|
||||
return xstrdup(url);
|
||||
}
|
||||
|
||||
int refs_from_alternate_cb(struct alternate_object_database *e, void *cb)
|
||||
{
|
||||
char *other;
|
||||
size_t len;
|
||||
struct remote *remote;
|
||||
struct transport *transport;
|
||||
const struct ref *extra;
|
||||
alternate_ref_fn *ref_fn = cb;
|
||||
|
||||
e->name[-1] = '\0';
|
||||
other = xstrdup(real_path(e->base));
|
||||
e->name[-1] = '/';
|
||||
len = strlen(other);
|
||||
|
||||
while (other[len-1] == '/')
|
||||
other[--len] = '\0';
|
||||
if (len < 8 || memcmp(other + len - 8, "/objects", 8))
|
||||
return 0;
|
||||
/* Is this a git repository with refs? */
|
||||
memcpy(other + len - 8, "/refs", 6);
|
||||
if (!is_directory(other))
|
||||
return 0;
|
||||
other[len - 8] = '\0';
|
||||
remote = remote_get(other);
|
||||
transport = transport_get(remote, other);
|
||||
for (extra = transport_get_remote_refs(transport);
|
||||
extra;
|
||||
extra = extra->next)
|
||||
ref_fn(extra, NULL);
|
||||
transport_disconnect(transport);
|
||||
free(other);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -166,4 +166,7 @@ int transport_refs_pushed(struct ref *ref);
|
|||
void transport_print_push_status(const char *dest, struct ref *refs,
|
||||
int verbose, int porcelain, int *nonfastforward);
|
||||
|
||||
typedef void alternate_ref_fn(const struct ref *, void *);
|
||||
extern int refs_from_alternate_cb(struct alternate_object_database *e, void *cb);
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче