Merge branch 'tr/maint-bundle-long-subject'
* tr/maint-bundle-long-subject: t5704: match tests to modern style strbuf: improve strbuf_get*line documentation bundle: use a strbuf to scan the log for boundary commits bundle: put strbuf_readline_fd in strbuf.c with adjustments
This commit is contained in:
commit
ac1373f1c2
@ -255,8 +255,24 @@ same behaviour as well.
|
|||||||
|
|
||||||
`strbuf_getline`::
|
`strbuf_getline`::
|
||||||
|
|
||||||
Read a line from a FILE* pointer. The second argument specifies the line
|
Read a line from a FILE *, overwriting the existing contents
|
||||||
|
of the strbuf. The second argument specifies the line
|
||||||
terminator character, typically `'\n'`.
|
terminator character, typically `'\n'`.
|
||||||
|
Reading stops after the terminator or at EOF. The terminator
|
||||||
|
is removed from the buffer before returning. Returns 0 unless
|
||||||
|
there was nothing left before EOF, in which case it returns `EOF`.
|
||||||
|
|
||||||
|
`strbuf_getwholeline`::
|
||||||
|
|
||||||
|
Like `strbuf_getline`, but keeps the trailing terminator (if
|
||||||
|
any) in the buffer.
|
||||||
|
|
||||||
|
`strbuf_getwholeline_fd`::
|
||||||
|
|
||||||
|
Like `strbuf_getwholeline`, but operates on a file descriptor.
|
||||||
|
It reads one character at a time, so it is very slow. Do not
|
||||||
|
use it unless you need the correct position in the file
|
||||||
|
descriptor.
|
||||||
|
|
||||||
`stripspace`::
|
`stripspace`::
|
||||||
|
|
||||||
|
36
bundle.c
36
bundle.c
@ -23,23 +23,6 @@ static void add_to_ref_list(const unsigned char *sha1, const char *name,
|
|||||||
list->nr++;
|
list->nr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Eventually this should go to strbuf.[ch] */
|
|
||||||
static int strbuf_readline_fd(struct strbuf *sb, int fd)
|
|
||||||
{
|
|
||||||
strbuf_reset(sb);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
char ch;
|
|
||||||
ssize_t len = xread(fd, &ch, 1);
|
|
||||||
if (len <= 0)
|
|
||||||
return len;
|
|
||||||
strbuf_addch(sb, ch);
|
|
||||||
if (ch == '\n')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_bundle_header(int fd, struct bundle_header *header,
|
static int parse_bundle_header(int fd, struct bundle_header *header,
|
||||||
const char *report_path)
|
const char *report_path)
|
||||||
{
|
{
|
||||||
@ -47,7 +30,7 @@ static int parse_bundle_header(int fd, struct bundle_header *header,
|
|||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
/* The bundle header begins with the signature */
|
/* The bundle header begins with the signature */
|
||||||
if (strbuf_readline_fd(&buf, fd) ||
|
if (strbuf_getwholeline_fd(&buf, fd, '\n') ||
|
||||||
strcmp(buf.buf, bundle_signature)) {
|
strcmp(buf.buf, bundle_signature)) {
|
||||||
if (report_path)
|
if (report_path)
|
||||||
error("'%s' does not look like a v2 bundle file",
|
error("'%s' does not look like a v2 bundle file",
|
||||||
@ -57,7 +40,7 @@ static int parse_bundle_header(int fd, struct bundle_header *header,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* The bundle header ends with an empty line */
|
/* The bundle header ends with an empty line */
|
||||||
while (!strbuf_readline_fd(&buf, fd) &&
|
while (!strbuf_getwholeline_fd(&buf, fd, '\n') &&
|
||||||
buf.len && buf.buf[0] != '\n') {
|
buf.len && buf.buf[0] != '\n') {
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
int is_prereq = 0;
|
int is_prereq = 0;
|
||||||
@ -251,7 +234,7 @@ int create_bundle(struct bundle_header *header, const char *path,
|
|||||||
const char **argv_boundary = xmalloc((argc + 4) * sizeof(const char *));
|
const char **argv_boundary = xmalloc((argc + 4) * sizeof(const char *));
|
||||||
const char **argv_pack = xmalloc(6 * sizeof(const char *));
|
const char **argv_pack = xmalloc(6 * sizeof(const char *));
|
||||||
int i, ref_count = 0;
|
int i, ref_count = 0;
|
||||||
char buffer[1024];
|
struct strbuf buf = STRBUF_INIT;
|
||||||
struct rev_info revs;
|
struct rev_info revs;
|
||||||
struct child_process rls;
|
struct child_process rls;
|
||||||
FILE *rls_fout;
|
FILE *rls_fout;
|
||||||
@ -283,20 +266,21 @@ int create_bundle(struct bundle_header *header, const char *path,
|
|||||||
if (start_command(&rls))
|
if (start_command(&rls))
|
||||||
return -1;
|
return -1;
|
||||||
rls_fout = xfdopen(rls.out, "r");
|
rls_fout = xfdopen(rls.out, "r");
|
||||||
while (fgets(buffer, sizeof(buffer), rls_fout)) {
|
while (strbuf_getwholeline(&buf, rls_fout, '\n') != EOF) {
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
if (buffer[0] == '-') {
|
if (buf.len > 0 && buf.buf[0] == '-') {
|
||||||
write_or_die(bundle_fd, buffer, strlen(buffer));
|
write_or_die(bundle_fd, buf.buf, buf.len);
|
||||||
if (!get_sha1_hex(buffer + 1, sha1)) {
|
if (!get_sha1_hex(buf.buf + 1, sha1)) {
|
||||||
struct object *object = parse_object(sha1);
|
struct object *object = parse_object(sha1);
|
||||||
object->flags |= UNINTERESTING;
|
object->flags |= UNINTERESTING;
|
||||||
add_pending_object(&revs, object, buffer);
|
add_pending_object(&revs, object, buf.buf);
|
||||||
}
|
}
|
||||||
} else if (!get_sha1_hex(buffer, sha1)) {
|
} else if (!get_sha1_hex(buf.buf, sha1)) {
|
||||||
struct object *object = parse_object(sha1);
|
struct object *object = parse_object(sha1);
|
||||||
object->flags |= SHOWN;
|
object->flags |= SHOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
strbuf_release(&buf);
|
||||||
fclose(rls_fout);
|
fclose(rls_fout);
|
||||||
if (finish_command(&rls))
|
if (finish_command(&rls))
|
||||||
return error("rev-list died");
|
return error("rev-list died");
|
||||||
|
16
strbuf.c
16
strbuf.c
@ -383,6 +383,22 @@ int strbuf_getline(struct strbuf *sb, FILE *fp, int term)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int strbuf_getwholeline_fd(struct strbuf *sb, int fd, int term)
|
||||||
|
{
|
||||||
|
strbuf_reset(sb);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
char ch;
|
||||||
|
ssize_t len = xread(fd, &ch, 1);
|
||||||
|
if (len <= 0)
|
||||||
|
return EOF;
|
||||||
|
strbuf_addch(sb, ch);
|
||||||
|
if (ch == term)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
|
int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
|
||||||
{
|
{
|
||||||
int fd, len;
|
int fd, len;
|
||||||
|
1
strbuf.h
1
strbuf.h
@ -116,6 +116,7 @@ extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);
|
|||||||
|
|
||||||
extern int strbuf_getwholeline(struct strbuf *, FILE *, int);
|
extern int strbuf_getwholeline(struct strbuf *, FILE *, int);
|
||||||
extern int strbuf_getline(struct strbuf *, FILE *, int);
|
extern int strbuf_getline(struct strbuf *, FILE *, int);
|
||||||
|
extern int strbuf_getwholeline_fd(struct strbuf *, int, int);
|
||||||
|
|
||||||
extern void stripspace(struct strbuf *buf, int skip_comments);
|
extern void stripspace(struct strbuf *buf, int skip_comments);
|
||||||
extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
|
extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
|
||||||
|
@ -4,59 +4,58 @@ test_description='some bundle related tests'
|
|||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
test_expect_success 'setup' '
|
test_expect_success 'setup' '
|
||||||
|
test_commit initial &&
|
||||||
: > file &&
|
|
||||||
git add file &&
|
|
||||||
test_tick &&
|
|
||||||
git commit -m initial &&
|
|
||||||
test_tick &&
|
test_tick &&
|
||||||
git tag -m tag tag &&
|
git tag -m tag tag &&
|
||||||
: > file2 &&
|
test_commit second &&
|
||||||
git add file2 &&
|
test_commit third &&
|
||||||
: > file3 &&
|
git tag -d initial &&
|
||||||
test_tick &&
|
git tag -d second &&
|
||||||
git commit -m second &&
|
git tag -d third
|
||||||
git add file3 &&
|
|
||||||
test_tick &&
|
|
||||||
git commit -m third
|
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'tags can be excluded by rev-list options' '
|
test_expect_success 'tags can be excluded by rev-list options' '
|
||||||
|
|
||||||
git bundle create bundle --all --since=7.Apr.2005.15:16:00.-0700 &&
|
git bundle create bundle --all --since=7.Apr.2005.15:16:00.-0700 &&
|
||||||
git ls-remote bundle > output &&
|
git ls-remote bundle > output &&
|
||||||
! grep tag output
|
! grep tag output
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'die if bundle file cannot be created' '
|
test_expect_success 'die if bundle file cannot be created' '
|
||||||
|
|
||||||
mkdir adir &&
|
mkdir adir &&
|
||||||
test_must_fail git bundle create adir --all
|
test_must_fail git bundle create adir --all
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_failure 'bundle --stdin' '
|
test_expect_failure 'bundle --stdin' '
|
||||||
|
|
||||||
echo master | git bundle create stdin-bundle.bdl --stdin &&
|
echo master | git bundle create stdin-bundle.bdl --stdin &&
|
||||||
git ls-remote stdin-bundle.bdl >output &&
|
git ls-remote stdin-bundle.bdl >output &&
|
||||||
grep master output
|
grep master output
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_failure 'bundle --stdin <rev-list options>' '
|
test_expect_failure 'bundle --stdin <rev-list options>' '
|
||||||
|
|
||||||
echo master | git bundle create hybrid-bundle.bdl --stdin tag &&
|
echo master | git bundle create hybrid-bundle.bdl --stdin tag &&
|
||||||
git ls-remote hybrid-bundle.bdl >output &&
|
git ls-remote hybrid-bundle.bdl >output &&
|
||||||
grep master output
|
grep master output
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'empty bundle file is rejected' '
|
test_expect_success 'empty bundle file is rejected' '
|
||||||
|
: >empty-bundle &&
|
||||||
|
test_must_fail git fetch empty-bundle
|
||||||
|
'
|
||||||
|
|
||||||
>empty-bundle && test_must_fail git fetch empty-bundle
|
# This triggers a bug in older versions where the resulting line (with
|
||||||
|
# --pretty=oneline) was longer than a 1024-char buffer.
|
||||||
|
test_expect_success 'ridiculously long subject in boundary' '
|
||||||
|
: >file4 &&
|
||||||
|
test_tick &&
|
||||||
|
git add file4 &&
|
||||||
|
printf "%01200d\n" 0 | git commit -F - &&
|
||||||
|
test_commit fifth &&
|
||||||
|
git bundle create long-subject-bundle.bdl HEAD^..HEAD &&
|
||||||
|
git bundle list-heads long-subject-bundle.bdl >heads &&
|
||||||
|
test -s heads &&
|
||||||
|
git fetch long-subject-bundle.bdl &&
|
||||||
|
sed -n "/^-/{p;q}" long-subject-bundle.bdl >boundary &&
|
||||||
|
grep "^-$_x40 " boundary
|
||||||
'
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user