{"thread":{"id":"1342","subject":"Linux BKCVS kernel history git import..","startedAt":"2005-07-26T18:57:43Z","lastAt":"2005-08-19T00:50:52Z","messageCount":17,"participants":["Linus Torvalds","Diego Calleja","A Large Angry SCM","David Woodhouse","Junio C Hamano","Matthias Urlichs","Johannes Schindelin","Wolfgang Denk","Paul Mackerras"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"6467","messageId":"Pine.LNX.4.58.0507261136280.19309@g5.osdl.org","threadId":"1342","inReplyTo":null,"subject":"Linux BKCVS kernel history git import..","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-07-26T18:57:43Z","receivedAt":"2005-07-26T18:57:43Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\nOk, I'm uploading my current git CVS import results to kernel.org right\nnow, which is my current best effort (meaning: I may try to improve on it\neven if there aren't any more cvsps bugs/features I have to fix, and\nobviously I'll re-create it if there _are_ cvsps or cvsimport bugs that\ncause the import to have problems).\n\nI've \"verified\" it in the sense that I've done a \"git-whatchanged -p\" at\nvarious stages of the import, and it looked sane. I also compared doing a\ntar-tree-export of the 2.6.12-rc2 release, which exists both in my current\ngit tree _and_ in the old bkcvs tree, and they compared identically apart\nfrom the fact that the bkcvs tree has the BitKeeper/ directory and a\nChangeSet file.\n\nIt's also pretty aggressively packed - I used \"--window=50 --depth=50\"  \n(rather than the default 10 for both) to make the archive smaller, so it's\ngoing to be somewhat more CPU-intensive to use (due to the possibly longer\ndelta chains), but it got the pack-file down from 204MB to 166MB, which I\nthink is pretty damn good for three years of history or whatever it is.\n\nEspecially considering that a gzip -9'd tar-file of the 2.6.12-rc2 release\nis 45MB all on its own, that archive is just 3.6 times a single tree.\n\nOf course, this _is_ the cvs import, which means that it's basically just\na straight-line linearization of the real BK history, but it's a pretty\ngood linearization and so it's certainly useful.\n\nIf somebody adds some logic to \"parse_commit()\" to do the \"fake parent\"\nthing, you can stitch the histories together and see the end result as one\nbig tree. Even without that, you can already do things like\n\n\tgit diff v2.6.10..v2.6.12\n\n(which crosses the BK->git transition) by just copying the 166MB pack-file \nover, along with the tags that come with the thing. I've not verified it, \nbut if that doesn't work, then it's a git bug. It _should_ work.\n\nBIG NOTE! This is definitely one archive you want to \"rsync\" instead of\nclosing with a git repack. The unpacked archive is somewhere in the 2.4GB\nregion, and since I actually used a higher compression ratio than the\ndefault, you'll transfer a smaller pack that way anyway.\n\nIt will probably take a while to mirror out (in fact, as I write this, the\nDSL upload just from my local machine out still has fifteen minutes to\ngo), but it should be visible out there soonish. Please holler if you find\nany problems with the conversion, or if you just have suggestions for\nimprovments.\n\nIt actually took something like 16 hours to do the conversion on my\nmachine (most of it appears to have been due to CVS being slow, the git\nparts were quick), so I won't re-convert for any trivial things.\n\nI'm planning on doing the 2.4 tree too some day - either as a separate\nbranch in the same archive, or as a separate git archive, I haven't quite\ndecided yet. But I was more interested int he 2.6.x tree (for obvious\nreasons), and before I do the 2.4.x one I'd like to give that tree some\ntime for people to check if the conversion was ok.\n\nOne thing that could be verified, for example (but that I have _not_\ndone), is to do a few random \"git diff v2.6.x..v2.6.y\" and comparing the\nresult with the standard diffs that are out there. Just to verify that the\narchive looks ok. I assume there is some \"diff-compare\" out there that can\nhandle the fact that the files are diffed in a different order (and with\ndifferent flags) etc.\n\n\t\tLinus\n"},{"id":"6468","messageId":"20050726213643.7ca44e96.diegocg@gmail.com","threadId":"1342","inReplyTo":"Pine.LNX.4.58.0507261136280.19309@g5.osdl.org","subject":"Re: Linux BKCVS kernel history git import..","fromName":"Diego Calleja","fromEmail":"diegocg@gmail.com","sentAt":"2005-07-26T19:36:43Z","receivedAt":"2005-07-26T19:36:43Z","isPatch":false,"sender":{"key":"diegocg@gmail.com","avatar":null},"body":"El Tue, 26 Jul 2005 11:57:43 -0700 (PDT),\nLinus Torvalds <torvalds@osdl.org> escribió:\n\n> I'm planning on doing the 2.4 tree too some day - either as a separate\n> branch in the same archive, or as a separate git archive, I haven't quite\n\nIt'd be great  to have the same thing but for the 1.0 - 2.2 tree. Of course\nthere are no \"changelogs\" for that, but incremental patches are still\navailable, and it'd be very interesting (for \"historical reasons\") to see how\nthings were added/removed\n"},{"id":"6470","messageId":"42E6B2BC.6060709@gmail.com","threadId":"1342","inReplyTo":"20050726213643.7ca44e96.diegocg@gmail.com","subject":"Re: Linux BKCVS kernel history git import..","fromName":"A Large Angry SCM","fromEmail":"gitzilla@gmail.com","sentAt":"2005-07-26T22:01:32Z","receivedAt":"2005-07-26T22:01:32Z","isPatch":false,"sender":{"key":"gitzilla@gmail.com","avatar":"https://gravatar.com/avatar/354625c442439908ff3dd99757dee330e29e9df7847472384faf7a00add247fb?d=mp&s=160"},"body":"Diego Calleja wrote:\n> El Tue, 26 Jul 2005 11:57:43 -0700 (PDT),\n> Linus Torvalds <torvalds@osdl.org> escribió:\n> \n>>I'm planning on doing the 2.4 tree too some day - either as a separate\n>>branch in the same archive, or as a separate git archive, I haven't quite\n> \n> It'd be great  to have the same thing but for the 1.0 - 2.2 tree. Of course\n> there are no \"changelogs\" for that, but incremental patches are still\n> available, and it'd be very interesting (for \"historical reasons\") to see how\n> things were added/removed\n\nAlso a really good stress test for the various git-blame/git-annotate\nimplementations.\n"},{"id":"6476","messageId":"1122457238.3027.37.camel@baythorne.infradead.org","threadId":"1342","inReplyTo":"Pine.LNX.4.58.0507261136280.19309@g5.osdl.org","subject":"Re: Linux BKCVS kernel history git import..","fromName":"David Woodhouse","fromEmail":"dwmw2@infradead.org","sentAt":"2005-07-27T09:40:38Z","receivedAt":"2005-07-27T09:40:38Z","isPatch":false,"sender":{"key":"dwmw2@infradead.org","avatar":"https://gravatar.com/avatar/7afd4f07e0cf7d7e046ae2d23678296b37777c96488e6f3451e78a5514154ebd?d=mp&s=160"},"body":"On Tue, 2005-07-26 at 11:57 -0700, Linus Torvalds wrote:\n> If somebody adds some logic to \"parse_commit()\" to do the \"fake parent\"\n> thing, you can stitch the histories together and see the end result as one\n> big tree. Even without that, you can already do things like\n> \n>         git diff v2.6.10..v2.6.12\n\nThat's a bit of a hack which really doesn't belong in the git tools.\nIt's not particularly hard to reparent the tree for real -- I'd much\nrather see a tool added to git which can _actually_ change the\n1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 commit to have a parent of\n0bcc493c633d78373d3fcf9efc29d6a710637519, and ripple the corresponding\nSHA1 changes up to the current HEAD.\n\nNote that the latter commit ID I gave there was actually the 2.6.12-rc2\ncommit in Thomas' history import, not your own. Thomas has done a lot of\nwork on it, and it has the full names extracted from the shortlog\nscript, full timestamps, branch/merge history and consistent character\nsets in the commit logs. I'd definitely suggest that you use that\ninstead of the import from bkcvs.\n\nhttp://www.kernel.org/git/?p=linux/kernel/git/tglx/history.git;a=summary\n\n-- \ndwmw2\n"},{"id":"6481","messageId":"Pine.LNX.4.58.0507270819550.3227@g5.osdl.org","threadId":"1342","inReplyTo":"1122457238.3027.37.camel@baythorne.infradead.org","subject":"Re: Linux BKCVS kernel history git import..","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-07-27T15:29:49Z","receivedAt":"2005-07-27T15:29:49Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 27 Jul 2005, David Woodhouse wrote:\n\n> On Tue, 2005-07-26 at 11:57 -0700, Linus Torvalds wrote:\n> > If somebody adds some logic to \"parse_commit()\" to do the \"fake parent\"\n> > thing, you can stitch the histories together and see the end result as one\n> > big tree. Even without that, you can already do things like\n> > \n> >         git diff v2.6.10..v2.6.12\n> \n> That's a bit of a hack which really doesn't belong in the git tools.\n\nActually, it's not a hack at all. It's very fundamentally how git works: \nyou give it two trees that it knows about, and it will show the \ndifferences between them - regardless of whether they share any common \nancestry or not.\n\n> It's not particularly hard to reparent the tree for real -- I'd much\n> rather see a tool added to git which can _actually_ change the\n> 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 commit to have a parent of\n> 0bcc493c633d78373d3fcf9efc29d6a710637519, and ripple the corresponding\n> SHA1 changes up to the current HEAD.\n\nI used to think I wanted to, but these days I really don't. One of the\nreasons is that I expect to try to pretty up the old bkcvs conversion some\ntime: use the name translation from the old \"shortlog\" scripts etc, and\nsee if I can do some other improvements on the conversion (I think I'll\nremove the BK files - \"ChangeSet\" etc).\n\nAnd it's really much easier and more general to have a \"graft\" facility.  \nIt's something that git can do trivially (literally a hook in\n\"parse_commit\" to add a special parent), and it's actually a generic\nmechanism exactly for issues like this (\"project had old history in some\nother format\").\n\nSomebody already asked for having the import history for old historic \npatches - which we _do_ actually have as patches, but which obviously \ndon't have any changelogs except for the version information. Most people \nmay not want that, but the thing is, with a \"graft\" facility, the people \nwho _do_ want that can easily see it all, and it is totally seamless.\n\nSo it's not even a one-time hack - it's a real feature that just in the \nkernel would have several cases we'd be able to use it for, and the same \nis likely true for almost any other project that wasn't started purely \nfrom git..\n\n\t\tLinus\n"},{"id":"6484","messageId":"1122478870.28128.52.camel@hades.cambridge.redhat.com","threadId":"1342","inReplyTo":"Pine.LNX.4.58.0507270819550.3227@g5.osdl.org","subject":"Re: Linux BKCVS kernel history git import..","fromName":"David Woodhouse","fromEmail":"dwmw2@infradead.org","sentAt":"2005-07-27T15:41:09Z","receivedAt":"2005-07-27T15:41:09Z","isPatch":false,"sender":{"key":"dwmw2@infradead.org","avatar":"https://gravatar.com/avatar/7afd4f07e0cf7d7e046ae2d23678296b37777c96488e6f3451e78a5514154ebd?d=mp&s=160"},"body":"On Wed, 2005-07-27 at 08:29 -0700, Linus Torvalds wrote:\n> I used to think I wanted to, but these days I really don't. One of the\n> reasons is that I expect to try to pretty up the old bkcvs conversion some\n> time: use the name translation from the old \"shortlog\" scripts etc, and\n> see if I can do some other improvements on the conversion (I think I'll\n> remove the BK files - \"ChangeSet\" etc).\n\nThomas has done all that; it's on kernel.org already.\n\n> And it's really much easier and more general to have a \"graft\" facility.  \n> It's something that git can do trivially (literally a hook in\n> \"parse_commit\" to add a special parent), and it's actually a generic\n> mechanism exactly for issues like this (\"project had old history in some\n> other format\").\n\nHm, OK. That works and can also be used for the \"fake _absence_ of\nparent\" thing -- if I'm space-constrained and want only the history back\nto some relatively recent point like 2.6.0, I can do that by turning the\n2.6.0 commit into an orphan instead of also using all the rest of the\nhistory back to 2.4.0. \n\n-- \ndwmw2\n"},{"id":"6483","messageId":"Pine.LNX.4.58.0507270846360.3227@g5.osdl.org","threadId":"1342","inReplyTo":"1122478870.28128.52.camel@hades.cambridge.redhat.com","subject":"Re: Linux BKCVS kernel history git import..","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-07-27T15:50:27Z","receivedAt":"2005-07-27T15:50:27Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 27 Jul 2005, David Woodhouse wrote:\n> \n> Hm, OK. That works and can also be used for the \"fake _absence_ of\n> parent\" thing -- if I'm space-constrained and want only the history back\n> to some relatively recent point like 2.6.0, I can do that by turning the\n> 2.6.0 commit into an orphan instead of also using all the rest of the\n> history back to 2.4.0. \n\nYes. The grafting really should work pretty well for various things like\nthis, and at the same time I don't think it's ever going to be a huge \nproblem: people may have a couple of graft-points (if you want to drop \nhistory, you may well have more than one point you need to \"cauterize\": \nyou may not be able to just cut it off at 2.6.0, since there may be merges \nfurhter back in history), but I don't think it's going to explode and \nbecome unwieldly.\n\nI just don't see people having more than a few trees that they might want\nto graft together, and while the \"drop history\" thing might cause more\nissues, even that is bounded by the amount of development parallellism, so \nwhile it probably causes more graft-points than the \"join trees\" usage, it \nshould still be just a small handful of points.\n\n\t\t\tLinus\n"},{"id":"6627","messageId":"7vslxw4tb1.fsf_-_@assigned-by-dhcp.cox.net","threadId":"1342","inReplyTo":"Pine.LNX.4.58.0507270846360.3227@g5.osdl.org","subject":"[PATCH] Teach parse_commit_buffer about grafting.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-07-30T08:00:34Z","receivedAt":"2005-07-30T08:00:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Introduce a new file $GIT_DIR/info/grafts (or $GIT_GRAFT_FILE)\nwhich is a list of \"fake commit parent records\".  Each line of\nthis file is a commit ID, followed by parent commit IDs, all\n40-byte hex SHA1 separated by a single SP in between.  The\nrecords override the parent information we would normally read\nfrom the commit objects, allowing both adding \"fake\" parents\n(i.e. grafting), and pretending as if a commit is not a child of\nsome of its real parents (i.e. cauterizing).\n\nBugs are mine, but the credits for the idea and implementation\noutline all go to Linus, who kept hinting how this thing should\nwork.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\n cache.h     |    2 +\n commit.c    |  114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-\n sha1_file.c |   13 ++++++-\n 3 files changed, 127 insertions(+), 2 deletions(-)\n\n0f16b172aa7f0757b2af50ec7be58dc0e23913a6\ndiff --git a/cache.h b/cache.h\n--- a/cache.h\n+++ b/cache.h\n@@ -127,10 +127,12 @@ extern unsigned int active_nr, active_al\n #define DEFAULT_GIT_DIR_ENVIRONMENT \".git\"\n #define DB_ENVIRONMENT \"GIT_OBJECT_DIRECTORY\"\n #define INDEX_ENVIRONMENT \"GIT_INDEX_FILE\"\n+#define GRAFT_ENVIRONMENT \"GIT_GRAFT_FILE\"\n \n extern char *get_object_directory(void);\n extern char *get_refs_directory(void);\n extern char *get_index_file(void);\n+extern char *get_graft_file(void);\n \n #define ALTERNATE_DB_ENVIRONMENT \"GIT_ALTERNATE_OBJECT_DIRECTORIES\"\n \ndiff --git a/commit.c b/commit.c\n--- a/commit.c\n+++ b/commit.c\n@@ -91,11 +91,108 @@ static unsigned long parse_commit_date(c\n \treturn date;\n }\n \n+static struct commit_graft {\n+\tunsigned char sha1[20];\n+\tint nr_parent;\n+\tunsigned char parent[0][20]; /* more */\n+} **commit_graft;\n+static int commit_graft_alloc, commit_graft_nr;\n+\n+static int commit_graft_pos(const unsigned char *sha1)\n+{\n+\tint lo, hi;\n+\tlo = 0;\n+\thi = commit_graft_nr;\n+\twhile (lo < hi) {\n+\t\tint mi = (lo + hi) / 2;\n+\t\tstruct commit_graft *graft = commit_graft[mi];\n+\t\tint cmp = memcmp(sha1, graft->sha1, 20);\n+\t\tif (!cmp)\n+\t\t\treturn mi;\n+\t\tif (cmp < 0)\n+\t\t\thi = mi;\n+\t\telse\n+\t\t\tlo = mi + 1;\n+\t}\n+\treturn -lo - 1;\n+}\n+\n+static void prepare_commit_graft(void)\n+{\n+\tchar *graft_file = get_graft_file();\n+\tFILE *fp = fopen(graft_file, \"r\");\n+\tchar buf[1024];\n+\tif (!fp) {\n+\t\tcommit_graft = (struct commit_graft **) \"hack\";\n+\t\treturn;\n+\t}\n+\twhile (fgets(buf, sizeof(buf), fp)) {\n+\t\t/* The format is just \"Commit Parent1 Parent2 ...\\n\" */\n+\t\tint len = strlen(buf);\n+\t\tint i;\n+\t\tstruct commit_graft *graft = NULL;\n+\n+\t\tif (buf[len-1] == '\\n')\n+\t\t\tbuf[--len] = 0;\n+\t\tif (buf[0] == '#')\n+\t\t\tcontinue;\n+\t\tif ((len + 1) % 41) {\n+\t\tbad_graft_data:\n+\t\t\terror(\"bad graft data: %s\", buf);\n+\t\t\tfree(graft);\n+\t\t\tcontinue;\n+\t\t}\n+\t\ti = (len + 1) / 41 - 1;\n+\t\tgraft = xmalloc(sizeof(*graft) + 20 * i);\n+\t\tgraft->nr_parent = i;\n+\t\tif (get_sha1_hex(buf, graft->sha1))\n+\t\t\tgoto bad_graft_data;\n+\t\tfor (i = 40; i < len; i += 41) {\n+\t\t\tif (buf[i] != ' ')\n+\t\t\t\tgoto bad_graft_data;\n+\t\t\tif (get_sha1_hex(buf + i + 1, graft->parent[i/41]))\n+\t\t\t\tgoto bad_graft_data;\n+\t\t}\n+\t\ti = commit_graft_pos(graft->sha1);\n+\t\tif (0 <= i) {\n+\t\t\terror(\"duplicate graft data: %s\", buf);\n+\t\t\tfree(graft);\n+\t\t\tcontinue;\n+\t\t}\n+\t\ti = -i - 1;\n+\t\tif (commit_graft_alloc <= ++commit_graft_nr) {\n+\t\t\tcommit_graft_alloc = alloc_nr(commit_graft_alloc);\n+\t\t\tcommit_graft = xrealloc(commit_graft,\n+\t\t\t\t\t\tsizeof(*commit_graft) *\n+\t\t\t\t\t\tcommit_graft_alloc);\n+\t\t}\n+\t\tif (i < commit_graft_nr)\n+\t\t\tmemmove(commit_graft + i + 1,\n+\t\t\t\tcommit_graft + i,\n+\t\t\t\t(commit_graft_nr - i - 1) *\n+\t\t\t\tsizeof(*commit_graft));\n+\t\tcommit_graft[i] = graft;\n+\t}\n+\tfclose(fp);\n+}\n+\n+static struct commit_graft *lookup_commit_graft(const unsigned char *sha1)\n+{\n+\tint pos;\n+\tif (!commit_graft)\n+\t\tprepare_commit_graft();\n+\tpos = commit_graft_pos(sha1);\n+\tif (pos < 0)\n+\t\treturn NULL;\n+\treturn commit_graft[pos];\n+}\n+\n int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)\n {\n \tchar *bufptr = buffer;\n \tunsigned char parent[20];\n \tstruct commit_list **pptr;\n+\tstruct commit_graft *graft;\n \n \tif (item->object.parsed)\n \t\treturn 0;\n@@ -109,17 +206,32 @@ int parse_commit_buffer(struct commit *i\n \t\tadd_ref(&item->object, &item->tree->object);\n \tbufptr += 46; /* \"tree \" + \"hex sha1\" + \"\\n\" */\n \tpptr = &item->parents;\n+\n+\tgraft = lookup_commit_graft(item->object.sha1);\n \twhile (!memcmp(bufptr, \"parent \", 7)) {\n \t\tstruct commit *new_parent;\n \n \t\tif (get_sha1_hex(bufptr + 7, parent) || bufptr[47] != '\\n')\n \t\t\treturn error(\"bad parents in commit %s\", sha1_to_hex(item->object.sha1));\n+\t\tbufptr += 48;\n+\t\tif (graft)\n+\t\t\tcontinue;\n \t\tnew_parent = lookup_commit(parent);\n \t\tif (new_parent) {\n \t\t\tpptr = &commit_list_insert(new_parent, pptr)->next;\n \t\t\tadd_ref(&item->object, &new_parent->object);\n \t\t}\n-\t\tbufptr += 48;\n+\t}\n+\tif (graft) {\n+\t\tint i;\n+\t\tstruct commit *new_parent;\n+\t\tfor (i = 0; i < graft->nr_parent; i++) {\n+\t\t\tnew_parent = lookup_commit(graft->parent[i]);\n+\t\t\tif (!new_parent)\n+\t\t\t\tcontinue;\n+\t\t\tpptr = &commit_list_insert(new_parent, pptr)->next;\n+\t\t\tadd_ref(&item->object, &new_parent->object);\n+\t\t}\n \t}\n \titem->date = parse_commit_date(bufptr);\n \treturn 0;\ndiff --git a/sha1_file.c b/sha1_file.c\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -61,7 +61,8 @@ static int get_sha1_file(const char *pat\n \treturn get_sha1_hex(buffer, result);\n }\n \n-static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir;\n+static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir,\n+\t*git_graft_file;\n static void setup_git_env(void)\n {\n \tgit_dir = gitenv(GIT_DIR_ENVIRONMENT);\n@@ -79,6 +80,9 @@ static void setup_git_env(void)\n \t\tgit_index_file = xmalloc(strlen(git_dir) + 7);\n \t\tsprintf(git_index_file, \"%s/index\", git_dir);\n \t}\n+\tgit_graft_file = gitenv(GRAFT_ENVIRONMENT);\n+\tif (!git_graft_file)\n+\t\tgit_graft_file = strdup(git_path(\"info/grafts\"));\n }\n \n char *get_object_directory(void)\n@@ -102,6 +106,13 @@ char *get_index_file(void)\n \treturn git_index_file;\n }\n \n+char *get_graft_file(void)\n+{\n+\tif (!git_graft_file)\n+\t\tsetup_git_env();\n+\treturn git_graft_file;\n+}\n+\n int safe_create_leading_directories(char *path)\n {\n \tchar *pos = path;\n"},{"id":"6629","messageId":"pan.2005.07.30.08.40.11.725422@smurf.noris.de","threadId":"1342","inReplyTo":"7vslxw4tb1.fsf_-_@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Teach parse_commit_buffer about grafting.","fromName":"Matthias Urlichs","fromEmail":"smurf@smurf.noris.de","sentAt":"2005-07-30T08:40:20Z","receivedAt":"2005-07-30T08:40:20Z","isPatch":true,"sender":{"key":"matthias@urlichs.de","avatar":"https://gravatar.com/avatar/2708905af227313eba6f2b2ae0f7d0259b5ac5d71baef58fe5a13c699ce0bbf0?d=mp&s=160"},"body":"Hi, Junio C Hamano wrote:\n\n> Introduce a new file $GIT_DIR/info/grafts\n\nNice work.\n\nHas anybody git-imported the old tarfile+patch history yet?\nIf not, I'll do it over the weekend.\n\n-- \nMatthias Urlichs   |   {M:U} IT Design @ m-u-it.de   |  smurf@smurf.noris.de\nDisclaimer: The quote was selected randomly. Really. | http://smurf.noris.de\n - -\nWhatever occurs from love is always beyond good and evil.\n\t\t-- Friedrich Nietzsche\n"},{"id":"6632","messageId":"Pine.LNX.4.58.0507301253020.9738@wgmdd8.biozentrum.uni-wuerzburg.de","threadId":"1342","inReplyTo":"7vslxw4tb1.fsf_-_@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Teach parse_commit_buffer about grafting.","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-07-30T10:53:47Z","receivedAt":"2005-07-30T10:53:47Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nis it possible that you forgot to initialize commit_graft_nr to 0?\n\nCiao,\nDscho\n"},{"id":"7481","messageId":"20050818003036.C53FD353BF9@atlas.denx.de","threadId":"1342","inReplyTo":"7vslxw4tb1.fsf_-_@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Teach parse_commit_buffer about grafting.","fromName":"Wolfgang Denk","fromEmail":"wd@denx.de","sentAt":"2005-08-18T00:30:36Z","receivedAt":"2005-08-18T00:30:36Z","isPatch":true,"sender":{"key":"wd@denx.de","avatar":null},"body":"In message <7vslxw4tb1.fsf_-_@assigned-by-dhcp.cox.net> you wrote:\n> Introduce a new file $GIT_DIR/info/grafts (or $GIT_GRAFT_FILE)\n> which is a list of \"fake commit parent records\".  Each line of\n> this file is a commit ID, followed by parent commit IDs, all\n> 40-byte hex SHA1 separated by a single SP in between.  The\n> records override the parent information we would normally read\n> from the commit objects, allowing both adding \"fake\" parents\n> (i.e. grafting), and pretending as if a commit is not a child of\n> some of its real parents (i.e. cauterizing).\n\nHow exactly is this used?\n\nI gave up trying to have CVS  merges  autimatically  recognized  upon\nimport, and tried to follow Matthias Urlichs' advice to fake it using\nthe grafts file.\n\nI have this situation:\n\nBranch point (actually this is the inital import into CVS):\n\nCommit:\t0b666f81da14bf46cada222856762f7fd6641c26\nChild:  9956b03b956994bb4e2cee4161f3626bcfd71924 (Das U-Boot: Universal Boot Loader)\nChild:  7309612797ed5e6b3b20027e28bca970b4f6b8fd (Initial revision)\n\n\nEnd of branch to merge (in CVS 1.1.1.1):\n\nCommit:\td9af3c87df93e1a8126b1a52adf8db978e9a0d40\nParent: 0bb9c6d97b195bd0efcdda02f109e6d1519074a9 (Das U-Boot: Universal Boot Loader)\n<no child>\n\n\nThis is the commit where I would like to show the  branch  merged  in\n(before; this is the first real commit in CVS):\n\nCommit:\t24ee89b97a49826ea800b4a6c0d5c0769328e317\nParent: de180e6daa529dc78668c99bdf17a9cdd440782d (Initial revision)\nChild:  699b13a6064e642280caffaa83c10b359a6c1114 (* Fix mdelay() on TRAB - this was still the debugging version with)\n\n\nI tried with a grafts file like this:\n\n24ee89b97a49826ea800b4a6c0d5c0769328e317 de180e6daa529dc78668c99bdf17a9cdd440782d d9af3c87df93e1a8126b1a52adf8db978e9a0d40\n\n\nThe display in gitk --all gets changed a bit (before the  branch  was\nthe  leftmost  line,  now  it's  the rightmost one), but it's still a\ndangling head, and the selected  \"merge  point\"  (commit  24ee89)  is\nstill  displayed  with  just  one parent (de180e) - I would expect to\nalso see d9af3c listed as parent, and the branch merging in here?\n\nAm I missing something?\n\nBest regards,\n\nWolfgang Denk\n\n-- \nSoftware Engineering:  Embedded and Realtime Systems,  Embedded Linux\nPhone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de\nProgrammer's Lament: (Shakespeare, Macbeth, Act I, Scene vii)\n        \"That we but teach bloody instructions,\n        which, being taught, return to plague the inventor...\"\n"},{"id":"7483","messageId":"7vd5ocouus.fsf@assigned-by-dhcp.cox.net","threadId":"1342","inReplyTo":"20050818003036.C53FD353BF9@atlas.denx.de","subject":"Re: [PATCH] Teach parse_commit_buffer about grafting.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-08-18T02:13:31Z","receivedAt":"2005-08-18T02:13:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Wolfgang Denk <wd@denx.de> writes:\n\n> The display in gitk --all gets changed a bit (before the  branch  was\n> the  leftmost  line,  now  it's  the rightmost one), but it's still a\n> dangling head, and the selected  \"merge  point\"  (commit  24ee89)  is\n> still  displayed  with  just  one parent (de180e) - I would expect to\n> also see d9af3c listed as parent, and the branch merging in here?\n>\n> Am I missing something?\n\nThe graft info is not used by anything other than those that use\nparse_commit() to figure out the commit ancestry information.\n\nThe list of commits that appear in the top pane of the gitk is\ngenerated by git-rev-list which knows how to do it, but the\nparent and child links, and the lines between nodes are drawn by\ngitk using the information it reads directly from the commit\nobjects.\n\nMy Tcl/Tk is really rusty, and I do not like this patch, but\nhere is my stab at teaching the code that reads commit objects\nhow to use grafts as well.\n\n------------\n[PATCH] Teach gitk to use grafts info\n\nFinding commits to draw is done by git-rev-list which knows how\nto do the grafts, but the lines between commits and the\nparent / child links needs to be drawn by reading from the\ncommit objects.  Teach that part of the code how to grok grafts\ninfo so that \"fake\" ancestry is shown sensibly in gitk.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\n gitk |   36 +++++++++++++++++++++++++++++++++++-\n 1 files changed, 35 insertions(+), 1 deletion(-)\n\ndiff --git a/gitk b/gitk\n--- a/gitk\n+++ b/gitk\n@@ -155,7 +155,7 @@ proc readcommit {id} {\n }\n \n proc parsecommit {id contents listed} {\n-    global commitinfo children nchildren parents nparents cdate ncleft\n+    global commitinfo children nchildren parents nparents cdate ncleft grafts\n \n     set inhdr 1\n     set comment {}\n@@ -171,6 +171,23 @@ proc parsecommit {id contents listed} {\n     }\n     set parents($id) {}\n     set nparents($id) 0\n+    set has_graft [array get grafts $id]\n+    if {\"\" != $has_graft} {\n+\tset parents($id) $grafts($id)\n+\tset nparents($id) [llength $parents($id)]\n+\tforeach p $parents($id) {\n+\t    if {![info exists nchildren($p)]} {\n+\t\tset children($p) {}\n+\t\tset nchildren($p) 0\n+\t\tset ncleft($p) 0\n+\t    }\n+\t    if {$listed && [lsearch -exact $children($p) $id] < 0} {\n+\t\tlappend children($p) $id\n+\t\tincr nchildren($p)\n+\t\tincr ncleft($p)\n+\t    }\n+\t}\n+    }\n     foreach line [split $contents \"\\n\"] {\n \tif {$inhdr} {\n \t    if {$line == {}} {\n@@ -178,6 +195,9 @@ proc parsecommit {id contents listed} {\n \t    } else {\n \t\tset tag [lindex $line 0]\n \t\tif {$tag == \"parent\"} {\n+\t\t    if {\"\" != $has_graft} {\n+\t\t\tcontinue\n+\t\t    }\n \t\t    set p [lindex $line 1]\n \t\t    if {![info exists nchildren($p)]} {\n \t\t\tset children($p) {}\n@@ -3194,6 +3214,20 @@ foreach arg $argv {\n \n set history {}\n set historyindex 0\n+set grafts('') nothing\n+array unset grafts ''\n+if {![catch { set graft [exec cat [gitdir]/info/grafts] }]} {\n+    global grafts\n+    foreach line [split $graft \"\\n\"] {\n+\tset commit [lindex $line 0]\n+\tset llen [llength $line]\n+\tset pp {}\n+\tfor {set i 1} {$i < $llen} {incr i} {\n+\t    lappend pp [lindex $line $i]\n+\t}\n+\tset grafts($commit) $pp\n+    }\n+}\n \n set stopped 0\n set redisplaying 0\n"},{"id":"7484","messageId":"17155.64070.264664.926461@cargo.ozlabs.ibm.com","threadId":"1342","inReplyTo":"7vd5ocouus.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Teach parse_commit_buffer about grafting.","fromName":"Paul Mackerras","fromEmail":"paulus@samba.org","sentAt":"2005-08-18T03:02:30Z","receivedAt":"2005-08-18T03:02:30Z","isPatch":true,"sender":{"key":"paulus@samba.org","avatar":"https://avatars.githubusercontent.com/u/1606439?v=4"},"body":"Junio C Hamano writes:\n\n> My Tcl/Tk is really rusty, and I do not like this patch, but\n> here is my stab at teaching the code that reads commit objects\n> how to use grafts as well.\n\nI added support for grafts to gitk just yesterday, and it should be on\nkernel.org by now.  I also committed the changes to send lines into\nhyperspace.\n\nRegards,\nPaul.\n"},{"id":"7486","messageId":"Pine.LNX.4.58.0508172209220.3412@g5.osdl.org","threadId":"1342","inReplyTo":"17155.64070.264664.926461@cargo.ozlabs.ibm.com","subject":"Re: [PATCH] Teach parse_commit_buffer about grafting.","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-08-18T05:16:19Z","receivedAt":"2005-08-18T05:16:19Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 18 Aug 2005, Paul Mackerras wrote:\n> \n> I added support for grafts to gitk just yesterday, and it should be on\n> kernel.org by now.  I also committed the changes to send lines into\n> hyperspace.\n\nPaul, I hate to tell you about yet another flag to git-rev-list, but did \nyou realize that in addition to all the other magic flags, there's a flag \ncalled \"--parents\"?\n\nRight now you use \"git-rev-list --header --topo-order\", which gives you \nboth the commit ID's and the header. Add a \"--parents\" there, and you'll \nnotice that the first line of each NUL-terminated record changes from just \nthe commit ID to the \"commit ID + parent list\".\n\nThat way gitk wouldn't need to actually know about grafts, because it \nwould just pick it up from the git-rev-list output which gets it from the \nregular commit parsing code.\n\nUmm. git-rev-list really does everything. Rule of thumb: if you _ever_\nneed to look at any other internal git information, you're probably doing\nsomething wrong, or you've missed yet another flag ;)\n\n\t\tLinus\n"},{"id":"7529","messageId":"17157.10227.296309.809074@cargo.ozlabs.ibm.com","threadId":"1342","inReplyTo":"Pine.LNX.4.58.0508172209220.3412@g5.osdl.org","subject":"Re: [PATCH] Teach parse_commit_buffer about grafting.","fromName":"Paul Mackerras","fromEmail":"paulus@samba.org","sentAt":"2005-08-19T00:29:39Z","receivedAt":"2005-08-19T00:29:39Z","isPatch":true,"sender":{"key":"paulus@samba.org","avatar":"https://avatars.githubusercontent.com/u/1606439?v=4"},"body":"Linus Torvalds writes:\n\n> Paul, I hate to tell you about yet another flag to git-rev-list, but did \n> you realize that in addition to all the other magic flags, there's a flag \n> called \"--parents\"?\n\nCool.  I didn't realize that.  The current version uses it now.\n\n> Umm. git-rev-list really does everything. Rule of thumb: if you _ever_\n> need to look at any other internal git information, you're probably doing\n> something wrong, or you've missed yet another flag ;)\n\nI still look in [gitdir]/refs/tags/* and [gitdir]/refs/heads/*, what\nflag have I missed? :)  Junio wants me to look at everything under\n[gitdir]/refs, in fact.  Or are the refs not considered internal git\ninformation?\n\nPaul.\n"},{"id":"7530","messageId":"Pine.LNX.4.63.0508190244350.8817@wgmdd8.biozentrum.uni-wuerzburg.de","threadId":"1342","inReplyTo":"17157.10227.296309.809074@cargo.ozlabs.ibm.com","subject":"Re: [PATCH] Teach parse_commit_buffer about grafting.","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-08-19T00:46:24Z","receivedAt":"2005-08-19T00:46:24Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 19 Aug 2005, Paul Mackerras wrote:\n\n> Linus Torvalds writes:\n> \n> > Paul, I hate to tell you about yet another flag [...]\n\nBut why? You're doing such a fine job telling people about flags :-)\n\n> > Umm. git-rev-list really does everything. Rule of thumb: if you _ever_\n> > need to look at any other internal git information, you're probably doing\n> > something wrong, or you've missed yet another flag ;)\n> \n> I still look in [gitdir]/refs/tags/* and [gitdir]/refs/heads/*, what\n> flag have I missed? :)  Junio wants me to look at everything under\n> [gitdir]/refs, in fact.  Or are the refs not considered internal git\n> information?\n\nTime for git-ref-list?\n\nJoking. But there may be a use for a \"--refs\" flag to git-rev-list, which \njust lists all the refs' names together with their object name (SHA1).\n\nCiao,\nDscho\n"},{"id":"7531","messageId":"Pine.LNX.4.58.0508181737220.3412@g5.osdl.org","threadId":"1342","inReplyTo":"17157.10227.296309.809074@cargo.ozlabs.ibm.com","subject":"Re: [PATCH] Teach parse_commit_buffer about grafting.","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-08-19T00:50:52Z","receivedAt":"2005-08-19T00:50:52Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\nOn Fri, 19 Aug 2005, Paul Mackerras wrote:\n> \n> > Umm. git-rev-list really does everything. Rule of thumb: if you _ever_\n> > need to look at any other internal git information, you're probably doing\n> > something wrong, or you've missed yet another flag ;)\n> \n> I still look in [gitdir]/refs/tags/* and [gitdir]/refs/heads/*, what\n> flag have I missed? :)  Junio wants me to look at everything under\n> [gitdir]/refs, in fact.  Or are the refs not considered internal git\n> information?\n\nAhh, ok, fair enough. git-rev-list won't give you that. \n\nAnd yes, the general rule is that anything under .git/refs/ is potentially \na reference. If it's under \"heads/\" or \"tags/\" it's a branch/tag, and then \nthe prefix \"heads/\" or \"tags/\" shouldn't be part of the name - you already \nshow the difference with colors. Anything else is unusual, but bisection \nputs refs in the \".git/refs/bisect\" directory for example, and if gitk \nwere to show those, it should probably show them in yet another color, and \n_with_ the \"bisect/\" prefix..\n\n\t\tLinus\n"}]}