Skip to content

Commit

Permalink
Improve git-peek-remote
Browse files Browse the repository at this point in the history
This makes git-peek-remote able to basically do everything that
git-ls-remote does (but obviously just for the native protocol, so no
http[s]: or rsync: support).

The default behaviour is the same, but you can now give a mixture of
"--refs", "--tags" and "--heads" flags, where "--refs" forces
git-peek-remote to only show real refs (ie none of the fakey tag lookups,
but also not the special pseudo-refs like HEAD and MERGE_HEAD).

The "--tags" and "--heads" flags respectively limit the output to just
regular tags and heads, of course.

You can still also ask to limit them by name too.

You can combine the flags, so

	git peek-remote --refs --tags .

will show all local _true_ tags, without the generated tag lookups
(compare the output without the "--refs" flag).

And "--tags --heads" will show both tags and heads, but will avoid (for
example) any special refs outside of the standard locations.

I'm also planning on adding a "--ignore-local" flag that allows us to ask
it to ignore any refs that we already have in the local tree, but that's
an independent thing.

All this is obviously gearing up to making "git fetch" cheaper.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
  • Loading branch information
Linus Torvalds authored and Junio C Hamano committed Jul 4, 2006
1 parent 4d62eaa commit 2718ff0
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 13 deletions.
6 changes: 5 additions & 1 deletion cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,13 +322,17 @@ struct ref {
char name[FLEX_ARRAY]; /* more */
};

#define REF_NORMAL (1u << 0)
#define REF_HEADS (1u << 1)
#define REF_TAGS (1u << 2)

extern int git_connect(int fd[2], char *url, const char *prog);
extern int finish_connect(pid_t pid);
extern int path_match(const char *path, int nr, char **match);
extern int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
int nr_refspec, char **refspec, int all);
extern int get_ack(int fd, unsigned char *result_sha1);
extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, int ignore_funny);
extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags);
extern int server_supports(const char *feature);

extern struct packed_git *parse_pack_index(unsigned char *sha1);
Expand Down
35 changes: 31 additions & 4 deletions connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,40 @@

static char *server_capabilities = NULL;

static int check_ref(const char *name, int len, unsigned int flags)
{
if (!flags)
return 1;

if (len > 45 || memcmp(name, "refs/", 5))
return 0;

/* Skip the "refs/" part */
name += 5;
len -= 5;

/* REF_NORMAL means that we don't want the magic fake tag refs */
if ((flags & REF_NORMAL) && check_ref_format(name) < 0)
return 0;

/* REF_HEADS means that we want regular branch heads */
if ((flags & REF_HEADS) && !memcmp(name, "heads/", 6))
return 1;

/* REF_TAGS means that we want tags */
if ((flags & REF_TAGS) && !memcmp(name, "tags/", 5))
return 1;

/* All type bits clear means that we are ok with anything */
return !(flags & ~REF_NORMAL);
}

/*
* Read all the refs from the other end
*/
struct ref **get_remote_heads(int in, struct ref **list,
int nr_match, char **match, int ignore_funny)
int nr_match, char **match,
unsigned int flags)
{
*list = NULL;
for (;;) {
Expand All @@ -43,10 +72,8 @@ struct ref **get_remote_heads(int in, struct ref **list,
server_capabilities = strdup(name + name_len + 1);
}

if (ignore_funny && 45 < len && !memcmp(name, "refs/", 5) &&
check_ref_format(name + 5))
if (!check_ref(name, name_len, flags))
continue;

if (nr_match && !path_match(name, nr_match, match))
continue;
ref = xcalloc(1, sizeof(*ref) + len - 40);
Expand Down
28 changes: 21 additions & 7 deletions peek-remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ static const char peek_remote_usage[] =
"git-peek-remote [--exec=upload-pack] [host:]directory";
static const char *exec = "git-upload-pack";

static int peek_remote(int fd[2])
static int peek_remote(int fd[2], unsigned flags)
{
struct ref *ref;

get_remote_heads(fd[0], &ref, 0, NULL, 0);
get_remote_heads(fd[0], &ref, 0, NULL, flags);
packet_flush(fd[1]);

while (ref) {
Expand All @@ -28,29 +28,43 @@ int main(int argc, char **argv)
int fd[2];
pid_t pid;
int nongit = 0;
unsigned flags = 0;

setup_git_directory_gently(&nongit);

for (i = 1; i < argc; i++) {
char *arg = argv[i];

if (*arg == '-') {
if (!strncmp("--exec=", arg, 7))
if (!strncmp("--exec=", arg, 7)) {
exec = arg + 7;
else
usage(peek_remote_usage);
continue;
continue;
}
if (!strcmp("--tags", arg)) {
flags |= REF_TAGS;
continue;
}
if (!strcmp("--heads", arg)) {
flags |= REF_HEADS;
continue;
}
if (!strcmp("--refs", arg)) {
flags |= REF_NORMAL;
continue;
}
usage(peek_remote_usage);
}
dest = arg;
break;
}

if (!dest || i != argc - 1)
usage(peek_remote_usage);

pid = git_connect(fd, dest, exec);
if (pid < 0)
return 1;
ret = peek_remote(fd);
ret = peek_remote(fd, flags);
close(fd[0]);
close(fd[1]);
finish_connect(pid);
Expand Down
2 changes: 1 addition & 1 deletion send-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
int expect_status_report = 0;

/* No funny business with the matcher */
remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, 1);
remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL);
get_local_heads();

/* Does the other end support the reporting? */
Expand Down

0 comments on commit 2718ff0

Please sign in to comment.