* [PATCH 1/3] Move bundle specific stuff into bundle.[ch]
@ 2007-07-17 22:49 Johannes Schindelin
2007-07-18 2:48 ` Daniel Barkalow
0 siblings, 1 reply; 11+ messages in thread
From: Johannes Schindelin @ 2007-07-17 22:49 UTC (permalink / raw)
To: git, Daniel Barkalow
The transport specific stuff was moved into libgit.a, and the
bundle specific stuff will not be left behind.
This is a big code move, with one exception: the function
unbundle() no longer outputs the list of refs. You have to call
list_bundle_refs() yourself for that.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
FWIW this patch series is based on the bf_series branch of
git://iabervon.org/~barkalow/git.git, revision a204e4b4.
Makefile | 2 +-
builtin-bundle.c | 330 +-----------------------------------------------------
bundle.c | 310 ++++++++++++++++++++++++++++++++++++++++++++++++++
bundle.h | 25 ++++
4 files changed, 342 insertions(+), 325 deletions(-)
create mode 100644 bundle.c
create mode 100644 bundle.h
diff --git a/Makefile b/Makefile
index 335be8f..a389ee7 100644
--- a/Makefile
+++ b/Makefile
@@ -318,7 +318,7 @@ LIB_OBJS = \
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \
convert.o attr.o decorate.o progress.o mailmap.o symlinks.o remote.o \
- transport.o
+ transport.o bundle.o
BUILTIN_OBJS = \
builtin-add.o \
diff --git a/builtin-bundle.c b/builtin-bundle.c
index 306ad29..22d03a3 100644
--- a/builtin-bundle.c
+++ b/builtin-bundle.c
@@ -1,10 +1,5 @@
#include "cache.h"
-#include "object.h"
-#include "commit.h"
-#include "diff.h"
-#include "revision.h"
-#include "list-objects.h"
-#include "run-command.h"
+#include "bundle.h"
/*
* Basic handler for bundle files to connect repositories via sneakernet.
@@ -15,320 +10,6 @@
static const char *bundle_usage="git-bundle (create <bundle> <git-rev-list args> | verify <bundle> | list-heads <bundle> [refname]... | unbundle <bundle> [refname]... )";
-static const char bundle_signature[] = "# v2 git bundle\n";
-
-struct ref_list {
- unsigned int nr, alloc;
- struct ref_list_entry {
- unsigned char sha1[20];
- char *name;
- } *list;
-};
-
-static void add_to_ref_list(const unsigned char *sha1, const char *name,
- struct ref_list *list)
-{
- if (list->nr + 1 >= list->alloc) {
- list->alloc = alloc_nr(list->nr + 1);
- list->list = xrealloc(list->list,
- list->alloc * sizeof(list->list[0]));
- }
- memcpy(list->list[list->nr].sha1, sha1, 20);
- list->list[list->nr].name = xstrdup(name);
- list->nr++;
-}
-
-struct bundle_header {
- struct ref_list prerequisites;
- struct ref_list references;
-};
-
-/* this function returns the length of the string */
-static int read_string(int fd, char *buffer, int size)
-{
- int i;
- for (i = 0; i < size - 1; i++) {
- ssize_t count = xread(fd, buffer + i, 1);
- if (count < 0)
- return error("Read error: %s", strerror(errno));
- if (count == 0) {
- i--;
- break;
- }
- if (buffer[i] == '\n')
- break;
- }
- buffer[i + 1] = '\0';
- return i + 1;
-}
-
-/* returns an fd */
-static int read_header(const char *path, struct bundle_header *header) {
- char buffer[1024];
- int fd = open(path, O_RDONLY);
-
- if (fd < 0)
- return error("could not open '%s'", path);
- if (read_string(fd, buffer, sizeof(buffer)) < 0 ||
- strcmp(buffer, bundle_signature)) {
- close(fd);
- return error("'%s' does not look like a v2 bundle file", path);
- }
- while (read_string(fd, buffer, sizeof(buffer)) > 0
- && buffer[0] != '\n') {
- int is_prereq = buffer[0] == '-';
- int offset = is_prereq ? 1 : 0;
- int len = strlen(buffer);
- unsigned char sha1[20];
- struct ref_list *list = is_prereq ? &header->prerequisites
- : &header->references;
- char delim;
-
- if (buffer[len - 1] == '\n')
- buffer[len - 1] = '\0';
- if (get_sha1_hex(buffer + offset, sha1)) {
- warning("unrecognized header: %s", buffer);
- continue;
- }
- delim = buffer[40 + offset];
- if (!isspace(delim) && (delim != '\0' || !is_prereq))
- die ("invalid header: %s", buffer);
- add_to_ref_list(sha1, isspace(delim) ?
- buffer + 41 + offset : "", list);
- }
- return fd;
-}
-
-static int list_refs(struct ref_list *r, int argc, const char **argv)
-{
- int i;
-
- for (i = 0; i < r->nr; i++) {
- if (argc > 1) {
- int j;
- for (j = 1; j < argc; j++)
- if (!strcmp(r->list[i].name, argv[j]))
- break;
- if (j == argc)
- continue;
- }
- printf("%s %s\n", sha1_to_hex(r->list[i].sha1),
- r->list[i].name);
- }
- return 0;
-}
-
-#define PREREQ_MARK (1u<<16)
-
-static int verify_bundle(struct bundle_header *header, int verbose)
-{
- /*
- * Do fast check, then if any prereqs are missing then go line by line
- * to be verbose about the errors
- */
- struct ref_list *p = &header->prerequisites;
- struct rev_info revs;
- const char *argv[] = {NULL, "--all"};
- struct object_array refs;
- struct commit *commit;
- int i, ret = 0, req_nr;
- const char *message = "Repository lacks these prerequisite commits:";
-
- init_revisions(&revs, NULL);
- for (i = 0; i < p->nr; i++) {
- struct ref_list_entry *e = p->list + i;
- struct object *o = parse_object(e->sha1);
- if (o) {
- o->flags |= PREREQ_MARK;
- add_pending_object(&revs, o, e->name);
- continue;
- }
- if (++ret == 1)
- error(message);
- error("%s %s", sha1_to_hex(e->sha1), e->name);
- }
- if (revs.pending.nr != p->nr)
- return ret;
- req_nr = revs.pending.nr;
- setup_revisions(2, argv, &revs, NULL);
-
- memset(&refs, 0, sizeof(struct object_array));
- for (i = 0; i < revs.pending.nr; i++) {
- struct object_array_entry *e = revs.pending.objects + i;
- add_object_array(e->item, e->name, &refs);
- }
-
- prepare_revision_walk(&revs);
-
- i = req_nr;
- while (i && (commit = get_revision(&revs)))
- if (commit->object.flags & PREREQ_MARK)
- i--;
-
- for (i = 0; i < req_nr; i++)
- if (!(refs.objects[i].item->flags & SHOWN)) {
- if (++ret == 1)
- error(message);
- error("%s %s", sha1_to_hex(refs.objects[i].item->sha1),
- refs.objects[i].name);
- }
-
- for (i = 0; i < refs.nr; i++)
- clear_commit_marks((struct commit *)refs.objects[i].item, -1);
-
- if (verbose) {
- struct ref_list *r;
-
- r = &header->references;
- printf("The bundle contains %d ref%s\n",
- r->nr, (1 < r->nr) ? "s" : "");
- list_refs(r, 0, NULL);
- r = &header->prerequisites;
- printf("The bundle requires these %d ref%s\n",
- r->nr, (1 < r->nr) ? "s" : "");
- list_refs(r, 0, NULL);
- }
- return ret;
-}
-
-static int list_heads(struct bundle_header *header, int argc, const char **argv)
-{
- return list_refs(&header->references, argc, argv);
-}
-
-static int create_bundle(struct bundle_header *header, const char *path,
- int argc, const char **argv)
-{
- int bundle_fd = -1;
- const char **argv_boundary = xmalloc((argc + 4) * sizeof(const char *));
- const char **argv_pack = xmalloc(5 * sizeof(const char *));
- int i, ref_count = 0;
- char buffer[1024];
- struct rev_info revs;
- struct child_process rls;
-
- bundle_fd = (!strcmp(path, "-") ? 1 :
- open(path, O_CREAT | O_EXCL | O_WRONLY, 0666));
- if (bundle_fd < 0)
- return error("Could not create '%s': %s", path, strerror(errno));
-
- /* write signature */
- write_or_die(bundle_fd, bundle_signature, strlen(bundle_signature));
-
- /* init revs to list objects for pack-objects later */
- save_commit_buffer = 0;
- init_revisions(&revs, NULL);
-
- /* write prerequisites */
- memcpy(argv_boundary + 3, argv + 1, argc * sizeof(const char *));
- argv_boundary[0] = "rev-list";
- argv_boundary[1] = "--boundary";
- argv_boundary[2] = "--pretty=oneline";
- argv_boundary[argc + 2] = NULL;
- memset(&rls, 0, sizeof(rls));
- rls.argv = argv_boundary;
- rls.out = -1;
- rls.git_cmd = 1;
- if (start_command(&rls))
- return -1;
- while ((i = read_string(rls.out, buffer, sizeof(buffer))) > 0) {
- unsigned char sha1[20];
- if (buffer[0] == '-') {
- write_or_die(bundle_fd, buffer, i);
- if (!get_sha1_hex(buffer + 1, sha1)) {
- struct object *object = parse_object(sha1);
- object->flags |= UNINTERESTING;
- add_pending_object(&revs, object, buffer);
- }
- } else if (!get_sha1_hex(buffer, sha1)) {
- struct object *object = parse_object(sha1);
- object->flags |= SHOWN;
- }
- }
- if (finish_command(&rls))
- return error("rev-list died");
-
- /* write references */
- argc = setup_revisions(argc, argv, &revs, NULL);
- if (argc > 1)
- return error("unrecognized argument: %s'", argv[1]);
-
- for (i = 0; i < revs.pending.nr; i++) {
- struct object_array_entry *e = revs.pending.objects + i;
- unsigned char sha1[20];
- char *ref;
-
- if (e->item->flags & UNINTERESTING)
- continue;
- if (dwim_ref(e->name, strlen(e->name), sha1, &ref) != 1)
- continue;
- /*
- * Make sure the refs we wrote out is correct; --max-count and
- * other limiting options could have prevented all the tips
- * from getting output.
- */
- if (!(e->item->flags & SHOWN)) {
- warning("ref '%s' is excluded by the rev-list options",
- e->name);
- continue;
- }
- ref_count++;
- write_or_die(bundle_fd, sha1_to_hex(e->item->sha1), 40);
- write_or_die(bundle_fd, " ", 1);
- write_or_die(bundle_fd, ref, strlen(ref));
- write_or_die(bundle_fd, "\n", 1);
- free(ref);
- }
- if (!ref_count)
- die ("Refusing to create empty bundle.");
-
- /* end header */
- write_or_die(bundle_fd, "\n", 1);
-
- /* write pack */
- argv_pack[0] = "pack-objects";
- argv_pack[1] = "--all-progress";
- argv_pack[2] = "--stdout";
- argv_pack[3] = "--thin";
- argv_pack[4] = NULL;
- memset(&rls, 0, sizeof(rls));
- rls.argv = argv_pack;
- rls.in = -1;
- rls.out = bundle_fd;
- rls.git_cmd = 1;
- if (start_command(&rls))
- return error("Could not spawn pack-objects");
- for (i = 0; i < revs.pending.nr; i++) {
- struct object *object = revs.pending.objects[i].item;
- if (object->flags & UNINTERESTING)
- write(rls.in, "^", 1);
- write(rls.in, sha1_to_hex(object->sha1), 40);
- write(rls.in, "\n", 1);
- }
- if (finish_command(&rls))
- return error ("pack-objects died");
- return 0;
-}
-
-static int unbundle(struct bundle_header *header, int bundle_fd,
- int argc, const char **argv)
-{
- const char *argv_index_pack[] = {"index-pack",
- "--fix-thin", "--stdin", NULL};
- struct child_process ip;
-
- if (verify_bundle(header, 0))
- return -1;
- memset(&ip, 0, sizeof(ip));
- ip.argv = argv_index_pack;
- ip.in = bundle_fd;
- ip.no_stdout = 1;
- ip.git_cmd = 1;
- if (run_command(&ip))
- return error("index-pack died");
- return list_heads(header, argc, argv);
-}
-
int cmd_bundle(int argc, const char **argv, const char *prefix)
{
struct bundle_header header;
@@ -352,8 +33,8 @@ int cmd_bundle(int argc, const char **argv, const char *prefix)
}
memset(&header, 0, sizeof(header));
- if (strcmp(cmd, "create") &&
- (bundle_fd = read_header(bundle_file, &header)) < 0)
+ if (strcmp(cmd, "create") && (bundle_fd =
+ read_bundle_header(bundle_file, &header)) < 0)
return 1;
if (!strcmp(cmd, "verify")) {
@@ -365,7 +46,7 @@ int cmd_bundle(int argc, const char **argv, const char *prefix)
}
if (!strcmp(cmd, "list-heads")) {
close(bundle_fd);
- return !!list_heads(&header, argc, argv);
+ return !!list_bundle_refs(&header, argc, argv);
}
if (!strcmp(cmd, "create")) {
if (nongit)
@@ -374,7 +55,8 @@ int cmd_bundle(int argc, const char **argv, const char *prefix)
} else if (!strcmp(cmd, "unbundle")) {
if (nongit)
die("Need a repository to unbundle.");
- return !!unbundle(&header, bundle_fd, argc, argv);
+ return !!unbundle(&header, bundle_fd) ||
+ list_bundle_refs(&header, argc, argv);
} else
usage(bundle_usage);
}
diff --git a/bundle.c b/bundle.c
new file mode 100644
index 0000000..659b61d
--- /dev/null
+++ b/bundle.c
@@ -0,0 +1,310 @@
+#include "cache.h"
+#include "bundle.h"
+#include "object.h"
+#include "commit.h"
+#include "diff.h"
+#include "revision.h"
+#include "list-objects.h"
+#include "run-command.h"
+
+static const char bundle_signature[] = "# v2 git bundle\n";
+
+static void add_to_ref_list(const unsigned char *sha1, const char *name,
+ struct ref_list *list)
+{
+ if (list->nr + 1 >= list->alloc) {
+ list->alloc = alloc_nr(list->nr + 1);
+ list->list = xrealloc(list->list,
+ list->alloc * sizeof(list->list[0]));
+ }
+ memcpy(list->list[list->nr].sha1, sha1, 20);
+ list->list[list->nr].name = xstrdup(name);
+ list->nr++;
+}
+
+/* this function returns the length of the string */
+static int read_string(int fd, char *buffer, int size)
+{
+ int i;
+ for (i = 0; i < size - 1; i++) {
+ ssize_t count = xread(fd, buffer + i, 1);
+ if (count < 0)
+ return error("Read error: %s", strerror(errno));
+ if (count == 0) {
+ i--;
+ break;
+ }
+ if (buffer[i] == '\n')
+ break;
+ }
+ buffer[i + 1] = '\0';
+ return i + 1;
+}
+
+/* returns an fd */
+int read_bundle_header(const char *path, struct bundle_header *header) {
+ char buffer[1024];
+ int fd = open(path, O_RDONLY);
+
+ if (fd < 0)
+ return error("could not open '%s'", path);
+ if (read_string(fd, buffer, sizeof(buffer)) < 0 ||
+ strcmp(buffer, bundle_signature)) {
+ close(fd);
+ return error("'%s' does not look like a v2 bundle file", path);
+ }
+ while (read_string(fd, buffer, sizeof(buffer)) > 0
+ && buffer[0] != '\n') {
+ int is_prereq = buffer[0] == '-';
+ int offset = is_prereq ? 1 : 0;
+ int len = strlen(buffer);
+ unsigned char sha1[20];
+ struct ref_list *list = is_prereq ? &header->prerequisites
+ : &header->references;
+ char delim;
+
+ if (buffer[len - 1] == '\n')
+ buffer[len - 1] = '\0';
+ if (get_sha1_hex(buffer + offset, sha1)) {
+ warning("unrecognized header: %s", buffer);
+ continue;
+ }
+ delim = buffer[40 + offset];
+ if (!isspace(delim) && (delim != '\0' || !is_prereq))
+ die ("invalid header: %s", buffer);
+ add_to_ref_list(sha1, isspace(delim) ?
+ buffer + 41 + offset : "", list);
+ }
+ return fd;
+}
+
+int create_bundle(struct bundle_header *header, const char *path,
+ int argc, const char **argv)
+{
+ int bundle_fd = -1;
+ const char **argv_boundary = xmalloc((argc + 4) * sizeof(const char *));
+ const char **argv_pack = xmalloc(5 * sizeof(const char *));
+ int i, ref_count = 0;
+ char buffer[1024];
+ struct rev_info revs;
+ struct child_process rls;
+
+ bundle_fd = (!strcmp(path, "-") ? 1 :
+ open(path, O_CREAT | O_EXCL | O_WRONLY, 0666));
+ if (bundle_fd < 0)
+ return error("Could not create '%s': %s", path, strerror(errno));
+
+ /* write signature */
+ write_or_die(bundle_fd, bundle_signature, strlen(bundle_signature));
+
+ /* init revs to list objects for pack-objects later */
+ save_commit_buffer = 0;
+ init_revisions(&revs, NULL);
+
+ /* write prerequisites */
+ memcpy(argv_boundary + 3, argv + 1, argc * sizeof(const char *));
+ argv_boundary[0] = "rev-list";
+ argv_boundary[1] = "--boundary";
+ argv_boundary[2] = "--pretty=oneline";
+ argv_boundary[argc + 2] = NULL;
+ memset(&rls, 0, sizeof(rls));
+ rls.argv = argv_boundary;
+ rls.out = -1;
+ rls.git_cmd = 1;
+ if (start_command(&rls))
+ return -1;
+ while ((i = read_string(rls.out, buffer, sizeof(buffer))) > 0) {
+ unsigned char sha1[20];
+ if (buffer[0] == '-') {
+ write_or_die(bundle_fd, buffer, i);
+ if (!get_sha1_hex(buffer + 1, sha1)) {
+ struct object *object = parse_object(sha1);
+ object->flags |= UNINTERESTING;
+ add_pending_object(&revs, object, buffer);
+ }
+ } else if (!get_sha1_hex(buffer, sha1)) {
+ struct object *object = parse_object(sha1);
+ object->flags |= SHOWN;
+ }
+ }
+ if (finish_command(&rls))
+ return error("rev-list died");
+
+ /* write references */
+ argc = setup_revisions(argc, argv, &revs, NULL);
+ if (argc > 1)
+ return error("unrecognized argument: %s'", argv[1]);
+
+ for (i = 0; i < revs.pending.nr; i++) {
+ struct object_array_entry *e = revs.pending.objects + i;
+ unsigned char sha1[20];
+ char *ref;
+
+ if (e->item->flags & UNINTERESTING)
+ continue;
+ if (dwim_ref(e->name, strlen(e->name), sha1, &ref) != 1)
+ continue;
+ /*
+ * Make sure the refs we wrote out is correct; --max-count and
+ * other limiting options could have prevented all the tips
+ * from getting output.
+ */
+ if (!(e->item->flags & SHOWN)) {
+ warning("ref '%s' is excluded by the rev-list options",
+ e->name);
+ continue;
+ }
+ ref_count++;
+ write_or_die(bundle_fd, sha1_to_hex(e->item->sha1), 40);
+ write_or_die(bundle_fd, " ", 1);
+ write_or_die(bundle_fd, ref, strlen(ref));
+ write_or_die(bundle_fd, "\n", 1);
+ free(ref);
+ }
+ if (!ref_count)
+ die ("Refusing to create empty bundle.");
+
+ /* end header */
+ write_or_die(bundle_fd, "\n", 1);
+
+ /* write pack */
+ argv_pack[0] = "pack-objects";
+ argv_pack[1] = "--all-progress";
+ argv_pack[2] = "--stdout";
+ argv_pack[3] = "--thin";
+ argv_pack[4] = NULL;
+ memset(&rls, 0, sizeof(rls));
+ rls.argv = argv_pack;
+ rls.in = -1;
+ rls.out = bundle_fd;
+ rls.git_cmd = 1;
+ if (start_command(&rls))
+ return error("Could not spawn pack-objects");
+ for (i = 0; i < revs.pending.nr; i++) {
+ struct object *object = revs.pending.objects[i].item;
+ if (object->flags & UNINTERESTING)
+ write(rls.in, "^", 1);
+ write(rls.in, sha1_to_hex(object->sha1), 40);
+ write(rls.in, "\n", 1);
+ }
+ if (finish_command(&rls))
+ return error ("pack-objects died");
+ return 0;
+}
+
+static int list_refs(struct ref_list *r, int argc, const char **argv)
+{
+ int i;
+
+ for (i = 0; i < r->nr; i++) {
+ if (argc > 1) {
+ int j;
+ for (j = 1; j < argc; j++)
+ if (!strcmp(r->list[i].name, argv[j]))
+ break;
+ if (j == argc)
+ continue;
+ }
+ printf("%s %s\n", sha1_to_hex(r->list[i].sha1),
+ r->list[i].name);
+ }
+ return 0;
+}
+
+int list_bundle_refs(struct bundle_header *header, int argc, const char **argv)
+{
+ return list_refs(&header->references, argc, argv);
+}
+
+#define PREREQ_MARK (1u<<16)
+
+int verify_bundle(struct bundle_header *header, int verbose)
+{
+ /*
+ * Do fast check, then if any prereqs are missing then go line by line
+ * to be verbose about the errors
+ */
+ struct ref_list *p = &header->prerequisites;
+ struct rev_info revs;
+ const char *argv[] = {NULL, "--all"};
+ struct object_array refs;
+ struct commit *commit;
+ int i, ret = 0, req_nr;
+ const char *message = "Repository lacks these prerequisite commits:";
+
+ init_revisions(&revs, NULL);
+ for (i = 0; i < p->nr; i++) {
+ struct ref_list_entry *e = p->list + i;
+ struct object *o = parse_object(e->sha1);
+ if (o) {
+ o->flags |= PREREQ_MARK;
+ add_pending_object(&revs, o, e->name);
+ continue;
+ }
+ if (++ret == 1)
+ error(message);
+ error("%s %s", sha1_to_hex(e->sha1), e->name);
+ }
+ if (revs.pending.nr != p->nr)
+ return ret;
+ req_nr = revs.pending.nr;
+ setup_revisions(2, argv, &revs, NULL);
+
+ memset(&refs, 0, sizeof(struct object_array));
+ for (i = 0; i < revs.pending.nr; i++) {
+ struct object_array_entry *e = revs.pending.objects + i;
+ add_object_array(e->item, e->name, &refs);
+ }
+
+ prepare_revision_walk(&revs);
+
+ i = req_nr;
+ while (i && (commit = get_revision(&revs)))
+ if (commit->object.flags & PREREQ_MARK)
+ i--;
+
+ for (i = 0; i < req_nr; i++)
+ if (!(refs.objects[i].item->flags & SHOWN)) {
+ if (++ret == 1)
+ error(message);
+ error("%s %s", sha1_to_hex(refs.objects[i].item->sha1),
+ refs.objects[i].name);
+ }
+
+ for (i = 0; i < refs.nr; i++)
+ clear_commit_marks((struct commit *)refs.objects[i].item, -1);
+
+ if (verbose) {
+ struct ref_list *r;
+
+ r = &header->references;
+ printf("The bundle contains %d ref%s\n",
+ r->nr, (1 < r->nr) ? "s" : "");
+ list_refs(r, 0, NULL);
+ r = &header->prerequisites;
+ printf("The bundle requires these %d ref%s\n",
+ r->nr, (1 < r->nr) ? "s" : "");
+ list_refs(r, 0, NULL);
+ }
+ return ret;
+}
+
+int unbundle(struct bundle_header *header, int bundle_fd)
+{
+ const char *argv_index_pack[] = {"index-pack",
+ "--fix-thin", "--stdin", NULL};
+ struct child_process ip;
+
+ if (verify_bundle(header, 0))
+ return -1;
+ memset(&ip, 0, sizeof(ip));
+ ip.argv = argv_index_pack;
+ ip.in = bundle_fd;
+ ip.no_stdout = 1;
+ ip.git_cmd = 1;
+ if (run_command(&ip))
+ return error("index-pack died");
+ return 0;
+}
+
+
diff --git a/bundle.h b/bundle.h
new file mode 100644
index 0000000..e2aedd6
--- /dev/null
+++ b/bundle.h
@@ -0,0 +1,25 @@
+#ifndef BUNDLE_H
+#define BUNDLE_H
+
+struct ref_list {
+ unsigned int nr, alloc;
+ struct ref_list_entry {
+ unsigned char sha1[20];
+ char *name;
+ } *list;
+};
+
+struct bundle_header {
+ struct ref_list prerequisites;
+ struct ref_list references;
+};
+
+int read_bundle_header(const char *path, struct bundle_header *header);
+int create_bundle(struct bundle_header *header, const char *path,
+ int argc, const char **argv);
+int verify_bundle(struct bundle_header *header, int verbose);
+int unbundle(struct bundle_header *header, int bundle_fd);
+int list_bundle_refs(struct bundle_header *header,
+ int argc, const char **argv);
+
+#endif
--
1.5.3.rc1.16.g9d6f-dirty
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] Move bundle specific stuff into bundle.[ch]
2007-07-17 22:49 [PATCH 1/3] Move bundle specific stuff into bundle.[ch] Johannes Schindelin
@ 2007-07-18 2:48 ` Daniel Barkalow
2007-07-18 3:23 ` Daniel Barkalow
2007-07-18 9:56 ` Johannes Schindelin
0 siblings, 2 replies; 11+ messages in thread
From: Daniel Barkalow @ 2007-07-18 2:48 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
On Tue, 17 Jul 2007, Johannes Schindelin wrote:
> The transport specific stuff was moved into libgit.a, and the
> bundle specific stuff will not be left behind.
>
> This is a big code move, with one exception: the function
> unbundle() no longer outputs the list of refs. You have to call
> list_bundle_refs() yourself for that.
You should use -C on this sort of thing, so that the interesting aspects
of the patch are easier to see. (It actually comes out longer in this
case, but it's far easier to tell that the code in the new file is the
same as the old code.) Can you tell I've been rearranging a lot of code
lately and trying to make the patches not look really scary?
Aside from presentation, it looks good to me. Shall I stick the bundle
changes into my series? I'd like to have them come before the patch to
switch to builtin-fetch, so that there aren't any revisions where "git
fetch" doesn't have bundle support.
And I think it would be best to take part 3 as a review fix to my final
patch.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] Move bundle specific stuff into bundle.[ch]
2007-07-18 2:48 ` Daniel Barkalow
@ 2007-07-18 3:23 ` Daniel Barkalow
2007-07-18 3:29 ` Shawn O. Pearce
2007-07-18 10:09 ` Johannes Schindelin
2007-07-18 9:56 ` Johannes Schindelin
1 sibling, 2 replies; 11+ messages in thread
From: Daniel Barkalow @ 2007-07-18 3:23 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
On Tue, 17 Jul 2007, Daniel Barkalow wrote:
> On Tue, 17 Jul 2007, Johannes Schindelin wrote:
>
> > The transport specific stuff was moved into libgit.a, and the
> > bundle specific stuff will not be left behind.
> >
> > This is a big code move, with one exception: the function
> > unbundle() no longer outputs the list of refs. You have to call
> > list_bundle_refs() yourself for that.
>
> You should use -C on this sort of thing, so that the interesting aspects
> of the patch are easier to see. (It actually comes out longer in this
> case, but it's far easier to tell that the code in the new file is the
> same as the old code.) Can you tell I've been rearranging a lot of code
> lately and trying to make the patches not look really scary?
Actually, I ended up touching this up a tiny bit, too: I ordered the
functions in bundle.c the way they were in builtin-bundle.c (so that the
patch is more trivial) and removed the blank lines at the end of the file.
This makes the "git diff -C" output really obvious.
(Someday, I'd like to have a diff that can show that a substantial block
of '+' lines matches a block of lines from somewhere in the "before"
content, so reviewers can verify that the patch reorders code but doesn't
change it, or changes it in certain ways. But, of course, that's both hard
to generate and hard to display usefully.)
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] Move bundle specific stuff into bundle.[ch]
2007-07-18 3:23 ` Daniel Barkalow
@ 2007-07-18 3:29 ` Shawn O. Pearce
2007-07-18 6:13 ` Junio C Hamano
2007-07-18 10:09 ` Johannes Schindelin
1 sibling, 1 reply; 11+ messages in thread
From: Shawn O. Pearce @ 2007-07-18 3:29 UTC (permalink / raw)
To: Daniel Barkalow; +Cc: Johannes Schindelin, git
Daniel Barkalow <barkalow@iabervon.org> wrote:
> (Someday, I'd like to have a diff that can show that a substantial block
> of '+' lines matches a block of lines from somewhere in the "before"
> content, so reviewers can verify that the patch reorders code but doesn't
> change it, or changes it in certain ways. But, of course, that's both hard
> to generate and hard to display usefully.)
I just moved a huge block in git-gui so I have a great example...
What about a patch format like this? I doubt people move more than
26 blocks in the same patch of the same file, so using a single
character block prefix when the before/after images are identical
might work OK.
diff --git a/git-gui.sh b/git-gui.sh
index 0443129..f13fa80 100755
--- a/git-gui.sh
+++ b/git-gui.sh
a@@ -632,6 +632,43 a@@ You are using [git-version]:
######################################################################
##
a+## feature option selection
a+
a+if {[regexp {^git-(.+)$} [appname] _junk subcommand]} {
a+ unset _junk
a+} else {
a+ set subcommand gui
a+}
a+if {$subcommand eq {gui.sh}} {
a+ set subcommand gui
a+}
a+if {$subcommand eq {gui} && [llength $argv] > 0} {
a+ set subcommand [lindex $argv 0]
a+ set argv [lrange $argv 1 end]
a+}
a+
a+enable_option multicommit
a+enable_option branch
a+enable_option transport
a+
a+switch -- $subcommand {
a+browser -
a+blame {
a+ disable_option multicommit
a+ disable_option branch
a+ disable_option transport
a+}
a+citool {
a+ enable_option singlecommit
a+
a+ disable_option multicommit
a+ disable_option branch
a+ disable_option transport
a+}
a+}
a+
a+######################################################################
a+##
## repository setup
if {[catch {
a@@ -1598,43 +1635,6 a@@ apply_config
######################################################################
##
a-## feature option selection
a-
a-if {[regexp {^git-(.+)$} [appname] _junk subcommand]} {
a- unset _junk
a-} else {
a- set subcommand gui
a-}
a-if {$subcommand eq {gui.sh}} {
a- set subcommand gui
a-}
a-if {$subcommand eq {gui} && [llength $argv] > 0} {
a- set subcommand [lindex $argv 0]
a- set argv [lrange $argv 1 end]
a-}
a-
a-enable_option multicommit
a-enable_option branch
a-enable_option transport
a-
a-switch -- $subcommand {
a-browser -
a-blame {
a- disable_option multicommit
a- disable_option branch
a- disable_option transport
a-}
a-citool {
a- enable_option singlecommit
a-
a- disable_option multicommit
a- disable_option branch
a- disable_option transport
a-}
a-}
a-
a-######################################################################
a-##
## ui construction
set ui_comm {}
--
1.5.3.rc1.818.g84b7
--
Shawn.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] Move bundle specific stuff into bundle.[ch]
2007-07-18 3:29 ` Shawn O. Pearce
@ 2007-07-18 6:13 ` Junio C Hamano
2007-07-18 6:19 ` Shawn O. Pearce
0 siblings, 1 reply; 11+ messages in thread
From: Junio C Hamano @ 2007-07-18 6:13 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Daniel Barkalow, Johannes Schindelin, git
"Shawn O. Pearce" <spearce@spearce.org> writes:
> What about a patch format like this? I doubt people move more than
> 26 blocks in the same patch of the same file, so using a single
> character block prefix when the before/after images are identical
> might work OK.
>
> diff --git a/git-gui.sh b/git-gui.sh
> index 0443129..f13fa80 100755
> --- a/git-gui.sh
> +++ b/git-gui.sh
> a@@ -632,6 +632,43 a@@ You are using [git-version]:
>
> ######################################################################
> ##
> a+## feature option selection
> ...
> a+
> a+######################################################################
> a+##
> ## repository setup
>
> if {[catch {
> a@@ -1598,43 +1635,6 a@@ apply_config
>
> ######################################################################
> ##
> a-## feature option selection
> ....
> a-##
> ## ui construction
>
> set ui_comm {}
Gaah, my eyes, my *eyes*!!
runs, stays in bathroom for 10 minutes and washes, and
comes back...
It might not be actually so bad. But I wonder if it would be
more obvious if you do not show the whole "a-" lines but leave
just a marker there. That is (ugliness of "a@@" and "a-" that
made me wash my eyes needs to be fixed, though -- but that is
only the syntax):
a@@ -1598,43 +1635,6 a@@ apply_config
######################################################################
##
a-<<< Block a was originally here >>>
## ui construction
set ui_comm {}
You are coming up with a new output format that is only used
when it is a straight move and nothing else, so by definition
there is really no need to show both removal and addition.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] Move bundle specific stuff into bundle.[ch]
2007-07-18 6:13 ` Junio C Hamano
@ 2007-07-18 6:19 ` Shawn O. Pearce
2007-07-18 7:26 ` Junio C Hamano
0 siblings, 1 reply; 11+ messages in thread
From: Shawn O. Pearce @ 2007-07-18 6:19 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Daniel Barkalow, Johannes Schindelin, git
Junio C Hamano <gitster@pobox.com> wrote:
> It might not be actually so bad. But I wonder if it would be
> more obvious if you do not show the whole "a-" lines but leave
> just a marker there. That is (ugliness of "a@@" and "a-" that
> made me wash my eyes needs to be fixed, though -- but that is
> only the syntax):
>
> a@@ -1598,43 +1635,6 a@@ apply_config
>
> ######################################################################
> ##
> a-<<< Block a was originally here >>>
> ## ui construction
>
> set ui_comm {}
>
> You are coming up with a new output format that is only used
> when it is a straight move and nothing else, so by definition
> there is really no need to show both removal and addition.
Yea, this I like even better than what I posted. Now we just need
a suck^H^H^H^Hprogrammer to implement a working prototype and see
how folks like more realistic diffs generated with it. ;-)
--
Shawn.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] Move bundle specific stuff into bundle.[ch]
2007-07-18 6:19 ` Shawn O. Pearce
@ 2007-07-18 7:26 ` Junio C Hamano
0 siblings, 0 replies; 11+ messages in thread
From: Junio C Hamano @ 2007-07-18 7:26 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Daniel Barkalow, Johannes Schindelin, git
"Shawn O. Pearce" <spearce@spearce.org> writes:
> Yea, this I like even better than what I posted. Now we just need
> a suck^H^H^H^Hprogrammer to implement a working prototype and see
> how folks like more realistic diffs generated with it. ;-)
I have to disgree.
We on the git list *live* in pretty much git-only world (ok, I
am ignoring git-svn people for now ;-)), so it might feel it
beneficial to add a new output format to git-diff.
But many users of git generated patch needs to interact with
patches that are not generated by git. I think an additional
postprocessor in patchutils/interdiff toolchest would probably
make much more sense. Then a person who reviews a patch that is
supposed to be line movement can use the filter to verify the
parts that should be only line movements are indeed are
movements and nothing else.
Speaking of "diff" output, what I would like to see is a support
of 'copied context' (i.e. traditional 'context diff' format you
would get from "diff -c"), in addition to the 'unified context'
we support. Generating copied context may help people who need
to give patches to others that accept only copied context format
patches (are there important projects that take only cpied
context format patches?). Being able to accept copied context
format patches in 'git-apply' would also be handy.
Of course, we could use interdiff to mangle copied context
format into unified context format, so 'git-apply' is not a big
deal, though.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] Move bundle specific stuff into bundle.[ch]
2007-07-18 3:23 ` Daniel Barkalow
2007-07-18 3:29 ` Shawn O. Pearce
@ 2007-07-18 10:09 ` Johannes Schindelin
1 sibling, 0 replies; 11+ messages in thread
From: Johannes Schindelin @ 2007-07-18 10:09 UTC (permalink / raw)
To: Daniel Barkalow; +Cc: git
Hi,
On Tue, 17 Jul 2007, Daniel Barkalow wrote:
> On Tue, 17 Jul 2007, Daniel Barkalow wrote:
>
> > On Tue, 17 Jul 2007, Johannes Schindelin wrote:
> >
> > > The transport specific stuff was moved into libgit.a, and the bundle
> > > specific stuff will not be left behind.
> > >
> > > This is a big code move, with one exception: the function unbundle()
> > > no longer outputs the list of refs. You have to call
> > > list_bundle_refs() yourself for that.
> >
> > You should use -C on this sort of thing, so that the interesting
> > aspects of the patch are easier to see. (It actually comes out longer
> > in this case, but it's far easier to tell that the code in the new
> > file is the same as the old code.) Can you tell I've been rearranging
> > a lot of code lately and trying to make the patches not look really
> > scary?
>
> Actually, I ended up touching this up a tiny bit, too: I ordered the
> functions in bundle.c the way they were in builtin-bundle.c (so that the
> patch is more trivial) and removed the blank lines at the end of the file.
> This makes the "git diff -C" output really obvious.
Makes sense. Thanks.
> (Someday, I'd like to have a diff that can show that a substantial block
> of '+' lines matches a block of lines from somewhere in the "before"
> content, so reviewers can verify that the patch reorders code but
> doesn't change it, or changes it in certain ways. But, of course, that's
> both hard to generate and hard to display usefully.)
AFAIR from the thread after
http://thread.gmane.org/gmane.linux.kernel/484924/focus=37498
the problem was not so much the displaying as the applying. You have a
diff for builtin-bundle.c. You want to move code to bundle.c. git-diff
has to rearrange the diff so that bundle.c can copy the code from
builtin-bundle.c, and then it is deleted from builtin-bundle.c. If you
move code criss-cross, it is not possible.
However, if you do something like
diff --git a/builtin-bundle.c:10--20 b/bundle.c:0--30
code move
--- a/builtin-bundle.c:10--20
+++ b/bundle.c:1--11
diff --git ...
it should be possible. We could allow generation of such a diff with
--code-moves, which would detect if there is substantial evidence for a
code move, and produce such a diff.
Note: this kind of code movement diff has to come before _both_ the diffs
for builtin-bundle.c and bundle.c, since chances are that the code had to
be touched a little here and there. And probably you would want a little
context, just to make sure it is the correct code when applying the patch.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] Move bundle specific stuff into bundle.[ch]
2007-07-18 2:48 ` Daniel Barkalow
2007-07-18 3:23 ` Daniel Barkalow
@ 2007-07-18 9:56 ` Johannes Schindelin
2007-07-18 16:25 ` Daniel Barkalow
1 sibling, 1 reply; 11+ messages in thread
From: Johannes Schindelin @ 2007-07-18 9:56 UTC (permalink / raw)
To: Daniel Barkalow; +Cc: git
Hi,
On Tue, 17 Jul 2007, Daniel Barkalow wrote:
> On Tue, 17 Jul 2007, Johannes Schindelin wrote:
>
> > The transport specific stuff was moved into libgit.a, and the bundle
> > specific stuff will not be left behind.
> >
> > This is a big code move, with one exception: the function unbundle()
> > no longer outputs the list of refs. You have to call
> > list_bundle_refs() yourself for that.
>
> You should use -C on this sort of thing, so that the interesting aspects
> of the patch are easier to see. (It actually comes out longer in this
> case, but it's far easier to tell that the code in the new file is the
> same as the old code.)
Okay, I wanted it to be kept short, since I really get lost easily in
hundreds of "-" lines, with possibly one in the midst being a "+".
> Can you tell I've been rearranging a lot of code lately and trying to
> make the patches not look really scary?
Sorry, I did not pay that close attention.
> Aside from presentation, it looks good to me. Shall I stick the bundle
> changes into my series? I'd like to have them come before the patch to
> switch to builtin-fetch, so that there aren't any revisions where "git
> fetch" doesn't have bundle support.
Looks fine to me. Seems like you should add a SOB line, too.
> And I think it would be best to take part 3 as a review fix to my final
> patch.
Yes, definitely. This shows again (to me, at least), that just looking at
the code is not enough, you have to run it, too, to review patches.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] Move bundle specific stuff into bundle.[ch]
2007-07-18 9:56 ` Johannes Schindelin
@ 2007-07-18 16:25 ` Daniel Barkalow
2007-07-18 16:33 ` Johannes Schindelin
0 siblings, 1 reply; 11+ messages in thread
From: Daniel Barkalow @ 2007-07-18 16:25 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
On Wed, 18 Jul 2007, Johannes Schindelin wrote:
> Hi,
>
> On Tue, 17 Jul 2007, Daniel Barkalow wrote:
>
> > You should use -C on this sort of thing, so that the interesting aspects
> > of the patch are easier to see. (It actually comes out longer in this
> > case, but it's far easier to tell that the code in the new file is the
> > same as the old code.)
>
> Okay, I wanted it to be kept short, since I really get lost easily in
> hundreds of "-" lines, with possibly one in the midst being a "+".
Actually, putting the functions in the original order made the -C diff
shorter than without -C. In general, a hundred lines of '-' with maybe a
'+' is hard to read, but I think whole functions of '-' without anything
else are easy; scan the left column, and find that the whole thing goes
away. If a patch is discarding blocks which are exactly whole top-level
definitions, those changes are probably either correct or totally broken
(depending on whether those blocks were actually used); you just have to
get suspicious around preprocessor stuff. Your change ended up being
trivially what the message described: bunch of blocks not in one or the
other of the resulting files, some functions make not static, renamed,
and/or had arguments changed, and the function you have to call after
unbundle if you want it.
> > Aside from presentation, it looks good to me. Shall I stick the bundle
> > changes into my series? I'd like to have them come before the patch to
> > switch to builtin-fetch, so that there aren't any revisions where "git
> > fetch" doesn't have bundle support.
>
> Looks fine to me. Seems like you should add a SOB line, too.
Ah, yes. I'll have to see if I'll be the first person in git development
to have a SOB line that's neither first nor last. :)
> > And I think it would be best to take part 3 as a review fix to my final
> > patch.
>
> Yes, definitely. This shows again (to me, at least), that just looking at
> the code is not enough, you have to run it, too, to review patches.
You caught that by running it? I've been running this code, and I've never
done anything with it which caused fetch_refs to fail and then checked the
result. I thought you must have found it by looking for missing checks of
return values. Or did you find it when you'd implemented half of bundle
support and it didn't complain?
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] Move bundle specific stuff into bundle.[ch]
2007-07-18 16:25 ` Daniel Barkalow
@ 2007-07-18 16:33 ` Johannes Schindelin
0 siblings, 0 replies; 11+ messages in thread
From: Johannes Schindelin @ 2007-07-18 16:33 UTC (permalink / raw)
To: Daniel Barkalow; +Cc: git
Hi,
On Wed, 18 Jul 2007, Daniel Barkalow wrote:
> On Wed, 18 Jul 2007, Johannes Schindelin wrote:
>
> > On Tue, 17 Jul 2007, Daniel Barkalow wrote:
> >
> > > You should use -C on this sort of thing, so that the interesting aspects
> > > of the patch are easier to see. (It actually comes out longer in this
> > > case, but it's far easier to tell that the code in the new file is the
> > > same as the old code.)
> >
> > Okay, I wanted it to be kept short, since I really get lost easily in
> > hundreds of "-" lines, with possibly one in the midst being a "+".
>
> Actually, putting the functions in the original order made the -C diff
> shorter than without -C.
True enough!
> > > Aside from presentation, it looks good to me. Shall I stick the
> > > bundle changes into my series? I'd like to have them come before the
> > > patch to switch to builtin-fetch, so that there aren't any revisions
> > > where "git fetch" doesn't have bundle support.
> >
> > Looks fine to me. Seems like you should add a SOB line, too.
>
> Ah, yes. I'll have to see if I'll be the first person in git development
> to have a SOB line that's neither first nor last. :)
We have 28 commits ATM in next's history, having 3 SOB lines:
1e76b702c1e754c7e6df1ced9ce6f1863cb7e092 is the most recent one.
> > > And I think it would be best to take part 3 as a review fix to my
> > > final patch.
> >
> > Yes, definitely. This shows again (to me, at least), that just
> > looking at the code is not enough, you have to run it, too, to review
> > patches.
>
> You caught that by running it? I've been running this code, and I've never
> done anything with it which caused fetch_refs to fail and then checked the
> result. I thought you must have found it by looking for missing checks of
> return values. Or did you find it when you'd implemented half of bundle
> support and it didn't complain?
Exactly. It is the "bundle 1" test that failed.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2007-07-18 16:33 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-17 22:49 [PATCH 1/3] Move bundle specific stuff into bundle.[ch] Johannes Schindelin
2007-07-18 2:48 ` Daniel Barkalow
2007-07-18 3:23 ` Daniel Barkalow
2007-07-18 3:29 ` Shawn O. Pearce
2007-07-18 6:13 ` Junio C Hamano
2007-07-18 6:19 ` Shawn O. Pearce
2007-07-18 7:26 ` Junio C Hamano
2007-07-18 10:09 ` Johannes Schindelin
2007-07-18 9:56 ` Johannes Schindelin
2007-07-18 16:25 ` Daniel Barkalow
2007-07-18 16:33 ` Johannes Schindelin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).