{"thread":{"id":"124","subject":"More patches","startedAt":"2005-04-19T01:48:07Z","lastAt":"2005-04-19T05:31:22Z","messageCount":12,"participants":["Daniel Barkalow","Petr Baudis","David A. Wheeler","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"760","messageId":"Pine.LNX.4.21.0504182139250.30848-100000@iabervon.org","threadId":"124","inReplyTo":null,"subject":"More patches","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-04-19T01:48:07Z","receivedAt":"2005-04-19T01:48:07Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"Here are the things I was saving for after the previous set:\n\n 1: Report the actual contents of trees\n 2: Add functions for scanning history by date\n 3: Add http-pull, a program to fetch the objects you need by HTTP\n 4: Change merge-base to find the most recent common ancestor\n\n1 and 2 are core extensions. 3 might be best for the pasky tree. 4 is\nmostly a demo of 2 and because Linus thought it was a better algorithm.\n\n\t-Daniel\n*This .sig left intentionally blank*\n\n"},{"id":"762","messageId":"Pine.LNX.4.21.0504182148330.30848-100000@iabervon.org","threadId":"124","inReplyTo":"Pine.LNX.4.21.0504182139250.30848-100000@iabervon.org","subject":"[1/4] Report info from trees","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-04-19T01:51:55Z","receivedAt":"2005-04-19T01:51:55Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"This patch adds actual information to struct tree, making it possible to\ntell what sorts of things the referenced objects are. This is needed for\nhttp-pull, and Junio wanted something of the sort.\n\nSigned-Off-By: Daniel Barkalow <barkalow@iabervon.org>\nIndex: tree.c\n===================================================================\n--- 1172a9b8f45b2fd640985595cc5258db3b027828/tree.c  (mode:100644 sha1:7c5e5e46f4967b0812b06c0114946c3a6432c8d8)\n+++ 7e5a0d93117ecadfb15de3a6bebdb1aa94234fde/tree.c  (mode:100644 sha1:39f9cbd1908e9046c148339f816025c9313ec142)\n@@ -27,6 +27,7 @@\n \tchar type[20];\n \tvoid *buffer, *bufptr;\n \tunsigned long size;\n+\tstruct tree_entry_list **list_p;\n \tif (item->object.parsed)\n \t\treturn 0;\n \titem->object.parsed = 1;\n@@ -38,8 +39,10 @@\n \tif (strcmp(type, tree_type))\n \t\treturn error(\"Object %s not a tree\",\n \t\t\t     sha1_to_hex(item->object.sha1));\n+\tlist_p = &item->entries;\n \twhile (size) {\n \t\tstruct object *obj;\n+\t\tstruct tree_entry_list *entry;\n \t\tint len = 1+strlen(bufptr);\n \t\tunsigned char *file_sha1 = bufptr + len;\n \t\tchar *path = strchr(bufptr, ' ');\n@@ -48,6 +51,11 @@\n \t\t    sscanf(bufptr, \"%o\", &mode) != 1)\n \t\t\treturn -1;\n \n+\t\tentry = malloc(sizeof(struct tree_entry_list));\n+\t\tentry->directory = S_ISDIR(mode);\n+\t\tentry->executable = mode & S_IXUSR;\n+\t\tentry->next = NULL;\n+\n \t\t/* Warn about trees that don't do the recursive thing.. */\n \t\tif (strchr(path, '/')) {\n \t\t\titem->has_full_path = 1;\n@@ -56,12 +64,17 @@\n \t\tbufptr += len + 20;\n \t\tsize -= len + 20;\n \n-\t\tif (S_ISDIR(mode)) {\n-\t\t\tobj = &lookup_tree(file_sha1)->object;\n+\t\tif (entry->directory) {\n+\t\t\tentry->item.tree = lookup_tree(file_sha1);\n+\t\t\tobj = &entry->item.tree->object;\n \t\t} else {\n-\t\t\tobj = &lookup_blob(file_sha1)->object;\n+\t\t\tentry->item.blob = lookup_blob(file_sha1);\n+\t\t\tobj = &entry->item.blob->object;\n \t\t}\n \t\tadd_ref(&item->object, obj);\n+\n+\t\t*list_p = entry;\n+\t\tlist_p = &entry->next;\n \t}\n \treturn 0;\n }\nIndex: tree.h\n===================================================================\n--- 1172a9b8f45b2fd640985595cc5258db3b027828/tree.h  (mode:100644 sha1:14ebbacded09d5e058c7f94652dcb9e12bc31cae)\n+++ 7e5a0d93117ecadfb15de3a6bebdb1aa94234fde/tree.h  (mode:100644 sha1:985500e2a9130fe8c33134ca121838af9320c465)\n@@ -5,9 +5,20 @@\n \n extern const char *tree_type;\n \n+struct tree_entry_list {\n+\tstruct tree_entry_list *next;\n+\tunsigned directory : 1;\n+\tunsigned executable : 1;\n+\tunion {\n+\t\tstruct tree *tree;\n+\t\tstruct blob *blob;\n+\t} item;\n+};\n+\n struct tree {\n \tstruct object object;\n \tunsigned has_full_path : 1;\n+\tstruct tree_entry_list *entries;\n };\n \n struct tree *lookup_tree(unsigned char *sha1);\n\n"},{"id":"763","messageId":"Pine.LNX.4.21.0504182152000.30848-100000@iabervon.org","threadId":"124","inReplyTo":"Pine.LNX.4.21.0504182139250.30848-100000@iabervon.org","subject":"[2/4] Sorting commits by date","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-04-19T01:54:56Z","receivedAt":"2005-04-19T01:54:56Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"Functions for a date-ordered queue of commits, progressively pulled out of\nthe history incrementally. Linus wanted this for finding the most recent\ncommon ancestor, and it might be relevant to logging.\n\nSigned-Off-By: Daniel Barkalow <barkalow@iabervon.org>\nIndex: commit.c\n===================================================================\n--- b3cf8daf9b619ae9f06a28f42a4ae01b69729206/commit.c  (mode:100644 sha1:0099baa63971d86ee30ef2a7da25057f0f45a964)\n+++ 7e5a0d93117ecadfb15de3a6bebdb1aa94234fde/commit.c  (mode:100644 sha1:ef9af397471817837e1799d72f6707e0ccc949b9)\n@@ -83,3 +83,47 @@\n \t\tfree(temp);\n \t}\n }\n+\n+static void insert_by_date(struct commit_list **list, struct commit *item)\n+{\n+\tstruct commit_list **pp = list;\n+\tstruct commit_list *p;\n+\twhile ((p = *pp) != NULL) {\n+\t\tif (p->item->date < item->date) {\n+\t\t\tbreak;\n+\t\t}\n+\t\tpp = &p->next;\n+\t}\n+\tstruct commit_list *insert = malloc(sizeof(struct commit_list));\n+\tinsert->next = *pp;\n+\t*pp = insert;\n+\tinsert->item = item;\n+}\n+\n+\t\n+void sort_by_date(struct commit_list **list)\n+{\n+\tstruct commit_list *ret = NULL;\n+\twhile (*list) {\n+\t\tinsert_by_date(&ret, (*list)->item);\n+\t\t*list = (*list)->next;\n+\t}\n+\t*list = ret;\n+}\n+\n+struct commit *pop_most_recent_commit(struct commit_list **list)\n+{\n+\tstruct commit *ret = (*list)->item;\n+\tstruct commit_list *parents = ret->parents;\n+\tstruct commit_list *old = *list;\n+\n+\t*list = (*list)->next;\n+\tfree(old);\n+\n+\twhile (parents) {\n+\t\tparse_commit(parents->item);\n+\t\tinsert_by_date(list, parents->item);\n+\t\tparents = parents->next;\n+\t}\n+\treturn ret;\n+}\nIndex: commit.h\n===================================================================\n--- b3cf8daf9b619ae9f06a28f42a4ae01b69729206/commit.h  (mode:100644 sha1:8cd20b046875f5f7e534b0607fdd97f330f53272)\n+++ 7e5a0d93117ecadfb15de3a6bebdb1aa94234fde/commit.h  (mode:100644 sha1:35679482132ae5a6b7d72bbb684f21472470717c)\n@@ -24,4 +24,8 @@\n \n void free_commit_list(struct commit_list *list);\n \n+void sort_by_date(struct commit_list **list);\n+\n+struct commit *pop_most_recent_commit(struct commit_list **list);\n+\n #endif /* COMMIT_H */\n\n"},{"id":"764","messageId":"Pine.LNX.4.21.0504182155010.30848-100000@iabervon.org","threadId":"124","inReplyTo":"Pine.LNX.4.21.0504182139250.30848-100000@iabervon.org","subject":"[3/4] Add http-pull","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-04-19T01:57:32Z","receivedAt":"2005-04-19T01:57:32Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"This adds a command to pull a commit and dependant objects from an HTTP\nserver.\n\nSigned-Off-By: Daniel Barkalow <barkalow@iabervon.org>\nIndex: Makefile\n===================================================================\n--- 50afb5dd4184842d8da1da8dcb9ca6a591dfc5b0/Makefile  (mode:100644 sha1:803f1d49c436efa570d779db6d350efbceb29ddd)\n+++ f7f62e0d2a822ad0937fd98a826f65ac7f938217/Makefile  (mode:100644 sha1:a3d26213c085e8b6bbc1ec352df0996e558e7c38)\n@@ -15,7 +15,7 @@\n \n PROG=   update-cache show-diff init-db write-tree read-tree commit-tree \\\n \tcat-file fsck-cache checkout-cache diff-tree rev-tree show-files \\\n-\tcheck-files ls-tree merge-base merge-cache unpack-file\n+\tcheck-files ls-tree merge-base merge-cache unpack-file http-pull\n \n all: $(PROG)\n \n@@ -81,6 +81,11 @@\n unpack-file: unpack-file.o $(LIB_FILE)\n \t$(CC) $(CFLAGS) -o unpack-file unpack-file.o $(LIBS)\n \n+http-pull: LIBS += -lcurl\n+\n+http-pull: http-pull.o $(LIB_FILE)\n+\t$(CC) $(CFLAGS) -o http-pull http-pull.o $(LIBS)\n+\n blob.o: $(LIB_H)\n cat-file.o: $(LIB_H)\n check-files.o: $(LIB_H)\n@@ -105,6 +110,7 @@\n usage.o: $(LIB_H)\n unpack-file.o: $(LIB_H)\n write-tree.o: $(LIB_H)\n+http-pull.o: $(LIB_H)\n \n clean:\n \trm -f *.o $(PROG) $(LIB_FILE)\nIndex: http-pull.c\n===================================================================\n--- /dev/null  (tree:50afb5dd4184842d8da1da8dcb9ca6a591dfc5b0)\n+++ f7f62e0d2a822ad0937fd98a826f65ac7f938217/http-pull.c  (mode:100644 sha1:bd251f9e0748784bbd2cd5cf720f126d852fe888)\n@@ -0,0 +1,170 @@\n+#include <fcntl.h>\n+#include <unistd.h>\n+#include <string.h>\n+#include <stdlib.h>\n+#include \"cache.h\"\n+#include \"commit.h\"\n+#include <errno.h>\n+#include <stdio.h>\n+\n+#include <curl/curl.h>\n+#include <curl/easy.h>\n+\n+static CURL *curl;\n+\n+static char *base;\n+\n+static int tree = 0;\n+static int commits = 0;\n+static int all = 0;\n+\n+static int has(unsigned char *sha1)\n+{\n+\tchar *filename = sha1_file_name(sha1);\n+\tstruct stat st;\n+\n+\tif (!stat(filename, &st))\n+\t\treturn 1;\n+\treturn 0;\n+}\n+\n+static int fetch(unsigned char *sha1)\n+{\n+\tchar *hex = sha1_to_hex(sha1);\n+\tchar *filename = sha1_file_name(sha1);\n+\n+\tchar *url;\n+\tchar *posn;\n+\tFILE *local;\n+\tstruct stat st;\n+\n+\tif (!stat(filename, &st)) {\n+\t\treturn 0;\n+\t}\n+\n+\tlocal = fopen(filename, \"w\");\n+\n+\tif (!local)\n+\t\treturn error(\"Couldn't open %s\\n\", filename);\n+\n+\tcurl_easy_setopt(curl, CURLOPT_FILE, local);\n+\n+\turl = malloc(strlen(base) + 50);\n+\tstrcpy(url, base);\n+\tposn = url + strlen(base);\n+\tstrcpy(posn, \"objects/\");\n+\tposn += 8;\n+\tmemcpy(posn, hex, 2);\n+\tposn += 2;\n+\t*(posn++) = '/';\n+\tstrcpy(posn, hex + 2);\n+\n+\tcurl_easy_setopt(curl, CURLOPT_URL, url);\n+\n+\tprintf(\"Getting %s\\n\", hex);\n+\n+\tif (curl_easy_perform(curl))\n+\t\treturn error(\"Couldn't get %s for %s\\n\", url, hex);\n+\n+\tfclose(local);\n+\t\n+\treturn 0;\n+}\n+\n+static int process_tree(unsigned char *sha1)\n+{\n+\tstruct tree *tree = lookup_tree(sha1);\n+\tstruct tree_entry_list *entries;\n+\n+\tif (parse_tree(tree))\n+\t\treturn -1;\n+\n+\tfor (entries = tree->entries; entries; entries = entries->next) {\n+\t\tif (fetch(entries->item.tree->object.sha1))\n+\t\t\treturn -1;\n+\t\tif (entries->directory) {\n+\t\t\tif (process_tree(entries->item.tree->object.sha1))\n+\t\t\t\treturn -1;\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n+static int process_commit(unsigned char *sha1)\n+{\n+\tstruct commit *obj = lookup_commit(sha1);\n+\n+\tif (fetch(sha1))\n+\t\treturn -1;\n+\n+\tif (parse_commit(obj))\n+\t\treturn -1;\n+\n+\tif (tree) {\n+\t\tif (fetch(obj->tree->object.sha1))\n+\t\t\treturn -1;\n+\t\tif (process_tree(obj->tree->object.sha1))\n+\t\t\treturn -1;\n+\t\tif (!all)\n+\t\t\ttree = 0;\n+\t}\n+\tif (commits) {\n+\t\tstruct commit_list *parents = obj->parents;\n+\t\tfor (; parents; parents = parents->next) {\n+\t\t\tif (has(parents->item->object.sha1))\n+\t\t\t\tcontinue;\n+\t\t\tif (fetch(parents->item->object.sha1)) {\n+\t\t\t\t/* The server might not have it, and\n+\t\t\t\t * we don't mind. \n+\t\t\t\t */\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\tif (process_commit(parents->item->object.sha1))\n+\t\t\t\treturn -1;\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n+int main(int argc, char **argv)\n+{\n+\tchar *commit_id;\n+\tchar *url;\n+\tint arg = 1;\n+\tunsigned char sha1[20];\n+\n+\twhile (arg < argc && argv[arg][0] == '-') {\n+\t\tif (argv[arg][1] == 't') {\n+\t\t\ttree = 1;\n+\t\t} else if (argv[arg][1] == 'c') {\n+\t\t\tcommits = 1;\n+\t\t} else if (argv[arg][1] == 'a') {\n+\t\t\tall = 1;\n+\t\t\ttree = 1;\n+\t\t\tcommits = 1;\n+\t\t}\n+\t\targ++;\n+\t}\n+\tif (argc < arg + 2) {\n+\t\tusage(\"http-pull [-c] [-t] [-a] commit-id url\");\n+\t\treturn 1;\n+\t}\n+\tcommit_id = argv[arg];\n+\turl = argv[arg + 1];\n+\n+\tget_sha1_hex(commit_id, sha1);\n+\n+\tcurl_global_init(CURL_GLOBAL_ALL);\n+\n+\tcurl = curl_easy_init();\n+\n+\tbase = url;\n+\n+\tif (fetch(sha1))\n+\t\treturn 1;\n+\tif (process_commit(sha1))\n+\t\treturn 1;\n+\n+\tcurl_global_cleanup();\n+\treturn 0;\n+}\n\n"},{"id":"765","messageId":"Pine.LNX.4.21.0504182157370.30848-100000@iabervon.org","threadId":"124","inReplyTo":"Pine.LNX.4.21.0504182139250.30848-100000@iabervon.org","subject":"[4/4] Make merge-base use dates to find answer","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-04-19T02:00:18Z","receivedAt":"2005-04-19T02:00:18Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"This changes merge-base to use the dates of commit to search the\nhistory. It will find the most recent common ancestor, rather than the one\nthe fewest generations away. It also demonstrates scanning the history by\ndate.\n\nSigned-Off-By: Daniel Barkalow <barkalow@iabervon.org>\nIndex: merge-base.c\n===================================================================\n--- fb7b671eb0da01b9a9998ab58b3717da9f983456/merge-base.c  (mode:100644 sha1:414ff419c679dba122b2f21b698c1e2c8abdd965)\n+++ 7e5a0d93117ecadfb15de3a6bebdb1aa94234fde/merge-base.c  (mode:100644 sha1:61e408e5d158f3dde6153ccbe9ee6fbbf1136225)\n@@ -5,42 +5,30 @@\n static struct commit *process_list(struct commit_list **list_p, int this_mark,\n \t\t\t\t   int other_mark)\n {\n-\tstruct commit_list *parent, *temp;\n-\tstruct commit_list *posn = *list_p;\n-\t*list_p = NULL;\n-\twhile (posn) {\n-\t\tparse_commit(posn->item);\n-\t\tif (posn->item->object.flags & this_mark) {\n-\t\t\t/*\n-\t\t\t  printf(\"%d already seen %s %x\\n\",\n-\t\t\t  this_mark\n-\t\t\t  sha1_to_hex(posn->parent->sha1),\n-\t\t\t  posn->parent->flags);\n-\t\t\t*/\n-\t\t\t/* do nothing; this indicates that this side\n-\t\t\t * split and reformed, and we only need to\n-\t\t\t * mark it once.\n-\t\t\t */\n-\t\t} else if (posn->item->object.flags & other_mark) {\n-\t\t\treturn posn->item;\n-\t\t} else {\n-\t\t\t/*\n-\t\t\t  printf(\"%d based on %s\\n\",\n-\t\t\t  this_mark,\n-\t\t\t  sha1_to_hex(posn->parent->sha1));\n-\t\t\t*/\n-\t\t\tposn->item->object.flags |= this_mark;\n-\t\t\t\n-\t\t\tparent = posn->item->parents;\n-\t\t\twhile (parent) {\n-\t\t\t\ttemp = malloc(sizeof(struct commit_list));\n-\t\t\t\ttemp->next = *list_p;\n-\t\t\t\ttemp->item = parent->item;\n-\t\t\t\t*list_p = temp;\n-\t\t\t\tparent = parent->next;\n-\t\t\t}\n-\t\t}\n-\t\tposn = posn->next;\n+\tstruct commit *item = (*list_p)->item;\n+\t\n+\tif (item->object.flags & this_mark) {\n+\t\t/*\n+\t\t  printf(\"%d already seen %s %x\\n\",\n+\t\t  this_mark\n+\t\t  sha1_to_hex(posn->parent->sha1),\n+\t\t  posn->parent->flags);\n+\t\t*/\n+\t\t/* do nothing; this indicates that this side\n+\t\t * split and reformed, and we only need to\n+\t\t * mark it once.\n+\t\t */\n+\t\t*list_p = (*list_p)->next;\n+\t} else if (item->object.flags & other_mark) {\n+\t\treturn item;\n+\t} else {\n+\t\t/*\n+\t\t  printf(\"%d based on %s\\n\",\n+\t\t  this_mark,\n+\t\t  sha1_to_hex(posn->parent->sha1));\n+\t\t*/\n+\t\tpop_most_recent_commit(list_p);\n+\t\titem->object.flags |= this_mark;\n \t}\n \treturn NULL;\n }\n@@ -56,16 +44,27 @@\n \trev2list->item = rev2;\n \trev2list->next = NULL;\n \n+\tparse_commit(rev1);\n+\tparse_commit(rev2);\n+\n \twhile (rev1list || rev2list) {\n \t\tstruct commit *ret;\n-\t\tret = process_list(&rev1list, 0x1, 0x2);\n-\t\tif (ret) {\n-\t\t\t/* XXXX free lists */\n-\t\t\treturn ret;\n+\t\tif (!rev1list) {\n+\t\t\t// process 2\n+\t\t\tret = process_list(&rev2list, 0x2, 0x1);\n+\t\t} else if (!rev2list) {\n+\t\t\t// process 1\n+\t\t\tret = process_list(&rev1list, 0x1, 0x2);\n+\t\t} else if (rev1list->item->date < rev2list->item->date) {\n+\t\t\t// process 2\n+\t\t\tret = process_list(&rev2list, 0x2, 0x1);\n+\t\t} else {\n+\t\t\t// process 1\n+\t\t\tret = process_list(&rev1list, 0x1, 0x2);\n \t\t}\n-\t\tret = process_list(&rev2list, 0x2, 0x1);\n \t\tif (ret) {\n-\t\t\t/* XXXX free lists */\n+\t\t\tfree_commit_list(rev1list);\n+\t\t\tfree_commit_list(rev2list);\n \t\t\treturn ret;\n \t\t}\n \t}\n\n"},{"id":"769","messageId":"20050419021338.GX5554@pasky.ji.cz","threadId":"124","inReplyTo":"Pine.LNX.4.21.0504182152000.30848-100000@iabervon.org","subject":"Re: [2/4] Sorting commits by date","fromName":"Petr Baudis","fromEmail":"pasky@ucw.cz","sentAt":"2005-04-19T02:13:38Z","receivedAt":"2005-04-19T02:13:38Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Tue, Apr 19, 2005 at 03:54:56AM CEST, I got a letter\nwhere Daniel Barkalow <barkalow@iabervon.org> told me that...\n> Index: commit.c\n> ===================================================================\n> --- b3cf8daf9b619ae9f06a28f42a4ae01b69729206/commit.c  (mode:100644 sha1:0099baa63971d86ee30ef2a7da25057f0f45a964)\n> +++ 7e5a0d93117ecadfb15de3a6bebdb1aa94234fde/commit.c  (mode:100644 sha1:ef9af397471817837e1799d72f6707e0ccc949b9)\n> @@ -83,3 +83,47 @@\n>  \t\tfree(temp);\n>  \t}\n>  }\n> +\n> +static void insert_by_date(struct commit_list **list, struct commit *item)\n> +{\n> +\tstruct commit_list **pp = list;\n> +\tstruct commit_list *p;\n> +\twhile ((p = *pp) != NULL) {\n> +\t\tif (p->item->date < item->date) {\n> +\t\t\tbreak;\n> +\t\t}\n> +\t\tpp = &p->next;\n> +\t}\n> +\tstruct commit_list *insert = malloc(sizeof(struct commit_list));\n> +\tinsert->next = *pp;\n> +\t*pp = insert;\n> +\tinsert->item = item;\n> +}\n\nNote that you are breaking gcc-2.95 compatibility when using declarator\nin the middle of a block. Not that it might be a necessarily bad thing\n;-) (although I still use gcc-2.95 a lot), just to ring a bell so that\nit doesn't slip through unnoticed and we can decide on a policy\nregarding this.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nC++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor\n"},{"id":"771","messageId":"42646EB3.8070701@dwheeler.com","threadId":"124","inReplyTo":"20050419021338.GX5554@pasky.ji.cz","subject":"Re: [2/4] Sorting commits by date","fromName":"David A. Wheeler","fromEmail":"dwheeler@dwheeler.com","sentAt":"2005-04-19T02:36:35Z","receivedAt":"2005-04-19T02:36:35Z","isPatch":false,"sender":{"key":"dwheeler@dwheeler.com","avatar":"https://avatars.githubusercontent.com/u/813150?v=4"},"body":"Petr Baudis wrote:\n> [Re: Daniel Barkalow <barkalow@iabervon.org>'s patch] \n> Note that you are breaking gcc-2.95 compatibility when using declarator\n> in the middle of a block. Not that it might be a necessarily bad thing\n> ;-) (although I still use gcc-2.95 a lot), just to ring a bell so that\n> it doesn't slip through unnoticed and we can decide on a policy\n> regarding this.\n\nI, at least, would REALLY like to see _highly_ portable C code;\nI'm looking at git as a potential long-term useful SCM tool for\nLOTS of projects, and if you're going to write C, it'd be nice\nto just write it portably to start with. There's certainly\nno crisis in using separate declarators.\n\nIn fact, in the LONG term I'd like to see the shell code\nreplaced with code that easily runs \"everywhere\" (Windows, etc.),\nagain, for portability's sake.  I think that would be unwise to\ndo that right now; the shell is an excellent prototyping tool.\nBut once things have settled down & there's been some experience\nwith the tools, the pieces could be slowly recoded.\n(Yes, I know of & use Cygwin. And I prefer Python over Perl,\nbut I'm really uninterested in language wars.)\n\n--- David A. Wheeler\n"},{"id":"774","messageId":"Pine.LNX.4.21.0504182236050.30848-100000@iabervon.org","threadId":"124","inReplyTo":"42646EB3.8070701@dwheeler.com","subject":"Re: [2/4] Sorting commits by date","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-04-19T02:52:26Z","receivedAt":"2005-04-19T02:52:26Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Mon, 18 Apr 2005, David A. Wheeler wrote:\n\n> Petr Baudis wrote:\n> > [Re: Daniel Barkalow <barkalow@iabervon.org>'s patch] \n> > Note that you are breaking gcc-2.95 compatibility when using declarator\n> > in the middle of a block. Not that it might be a necessarily bad thing\n> > ;-) (although I still use gcc-2.95 a lot), just to ring a bell so that\n> > it doesn't slip through unnoticed and we can decide on a policy\n> > regarding this.\n> \n> I, at least, would REALLY like to see _highly_ portable C code;\n> I'm looking at git as a potential long-term useful SCM tool for\n> LOTS of projects, and if you're going to write C, it'd be nice\n> to just write it portably to start with. There's certainly\n> no crisis in using separate declarators.\n\nMixing declarations and code is the least of portability issues; it's in\nthe current C standard unlike a number of other things. I've personally\nnever found a system where -lz has deflateBound but gcc doesn't support\nC99, although they obviously exist. I have no problem with fixing things\nup for old GCC, although I'm going to have a hard time finding such things\nbecause I can't find a way to make recent GCC reject C99 features but not\nold GNU extensions.\n\n\t-Daniel\n*This .sig left intentionally blank*\n\n"},{"id":"775","messageId":"20050419025340.GZ5554@pasky.ji.cz","threadId":"124","inReplyTo":"Pine.LNX.4.21.0504182236050.30848-100000@iabervon.org","subject":"Re: [2/4] Sorting commits by date","fromName":"Petr Baudis","fromEmail":"pasky@ucw.cz","sentAt":"2005-04-19T02:53:40Z","receivedAt":"2005-04-19T02:53:40Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Tue, Apr 19, 2005 at 04:52:26AM CEST, I got a letter\nwhere Daniel Barkalow <barkalow@iabervon.org> told me that...\n> because I can't find a way to make recent GCC reject C99 features but not\n> old GNU extensions.\n\nDo we use any?\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nC++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor\n"},{"id":"778","messageId":"Pine.LNX.4.21.0504182256490.30848-100000@iabervon.org","threadId":"124","inReplyTo":"20050419025340.GZ5554@pasky.ji.cz","subject":"Re: [2/4] Sorting commits by date","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-04-19T03:06:33Z","receivedAt":"2005-04-19T03:06:33Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Tue, 19 Apr 2005, Petr Baudis wrote:\n\n> Dear diary, on Tue, Apr 19, 2005 at 04:52:26AM CEST, I got a letter\n> where Daniel Barkalow <barkalow@iabervon.org> told me that...\n> > because I can't find a way to make recent GCC reject C99 features but not\n> > old GNU extensions.\n> \n> Do we use any?\n\nQuite a few: \"?:\", arithmetic on void pointers, C++/99-style comments in\nplaces (if we aren't being C99), zero-size arrays. They're the usual\nthings that building Linux requires, so I think they are common extensions\nbeyond gcc.\n\n\t-Daniel\n*This .sig left intentionally blank*\n\n"},{"id":"782","messageId":"7vsm1nqr6x.fsf@assigned-by-dhcp.cox.net","threadId":"124","inReplyTo":"Pine.LNX.4.21.0504182148330.30848-100000@iabervon.org","subject":"Re: [1/4] Report info from trees","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-04-19T05:19:18Z","receivedAt":"2005-04-19T05:19:18Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":">>>>> \"DB\" == Daniel Barkalow <barkalow@iabervon.org> writes:\n\nDB> This patch adds actual information to struct tree, making it possible to\nDB> tell what sorts of things the referenced objects are. This is needed for\nDB> http-pull, and Junio wanted something of the sort.\n\nThanks for keeping me in the loop, but...\n\nDB> --- 1172a9b8f45b2fd640985595cc5258db3b027828/tree.h  (mode:100644 sha1:14ebbacded09d5e058c7f94652dcb9e12bc31cae)\nDB> +++ 7e5a0d93117ecadfb15de3a6bebdb1aa94234fde/tree.h  (mode:100644 sha1:985500e2a9130fe8c33134ca121838af9320c465)\nDB> @@ -5,9 +5,20 @@\n \nDB>  extern const char *tree_type;\n \nDB> +struct tree_entry_list {\nDB> +\tstruct tree_entry_list *next;\nDB> +\tunsigned directory : 1;\nDB> +\tunsigned executable : 1;\nDB> +\tunion {\nDB> +\t\tstruct tree *tree;\nDB> +\t\tstruct blob *blob;\nDB> +\t} item;\nDB> +};\nDB> +\nDB>  struct tree {\nDB>  \tstruct object object;\nDB>  \tunsigned has_full_path : 1;\nDB> +\tstruct tree_entry_list *entries;\nDB>  };\n \n... what about names?  When somebody other than connectivity\nchecker walks a tree, it would be more likely than not that \nit wants to know what each entry is called, wound't it?\n\nI can get the type of the object, either tree or blob, from\ntree->object.type, so I do not think the single-bit are needed.\n\nInstead, how about something simpler like this?\n\n    struct tree {\n        struct object object; /* the tree node itself as an object */\n        unsigned child_nr;\n        unsigned child_alloc;\n        struct {\n            struct object *object;\n            char *name;\n        } **child;\n    };\n\nThe tree->child[n].object would point at the same object as one\nof the object_list elements in tree->object.refs chain (i.e. you\ndo not need to read the same object twice).  Before the tree is\nparsed, tree->child would be NULL.  You do not need child_alloc\nif the intended use of this API is only parsing existing object\ntree.  Otherwise keep that and realloc tree->child as needed.\n\n\n\n"},{"id":"784","messageId":"Pine.LNX.4.21.0504190123180.30848-100000@iabervon.org","threadId":"124","inReplyTo":"7vsm1nqr6x.fsf@assigned-by-dhcp.cox.net","subject":"Re: [1/4] Report info from trees","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-04-19T05:31:22Z","receivedAt":"2005-04-19T05:31:22Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Mon, 18 Apr 2005, Junio C Hamano wrote:\n\n> ... what about names?  When somebody other than connectivity\n> checker walks a tree, it would be more likely than not that \n> it wants to know what each entry is called, wound't it?\n\nYes; just add the name to the tree_entry_list.\n\n> I can get the type of the object, either tree or blob, from\n> tree->object.type, so I do not think the single-bit are needed.\n\nYou still need the mode bit (executable or not); also, the current code\ncan't create an object without being told in advance what it is, so you\nneed to use the directory bit.\n\n> Instead, how about something simpler like this?\n> \n>     struct tree {\n>         struct object object; /* the tree node itself as an object */\n>         unsigned child_nr;\n>         unsigned child_alloc;\n>         struct {\n>             struct object *object;\n>             char *name;\n>         } **child;\n>     };\n\nI think the linked list is easier to deal with, and matches the other code\nbetter.\n\n> The tree->child[n].object would point at the same object as one\n> of the object_list elements in tree->object.refs chain (i.e. you\n> do not need to read the same object twice). \n\nThe object code handles causing lookup_* to return the same object every\ntime, so this isn't an issue. Note that each struct object has to be\nembedded in a struct <type> of the appropriate type, which means that we\ncan only create a struct object by either knowing what type it is supposed\nto be or actually reading the file to find out what it actually is.\n\n\t-Daniel\n*This .sig left intentionally blank*\n\n"}]}