{"thread":{"id":"8034","subject":"[PATCH] Add a birdview-on-the-source-code section to the user manual","startedAt":"2007-05-08T15:10:47Z","lastAt":"2007-05-10T21:14:23Z","messageCount":33,"participants":["Johannes Schindelin","Karl Hasselström","J. Bruce Fields","Junio C Hamano","Daniel Barkalow","Petr Baudis"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"41463","messageId":"Pine.LNX.4.64.0705081709230.4167@racer.site","threadId":"8034","inReplyTo":null,"subject":"[PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-08T15:10:47Z","receivedAt":"2007-05-08T15:10:47Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nIn http://thread.gmane.org/gmane.comp.version-control.git/42479,\na birdview on the source code was requested.\n\nJ. Bruce Fields suggested that my reply should be included in the\nuser manual, and there was nothing of an outcry, so here it is,\nnot even 2 months later.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Documentation/user-manual.txt |  196 +++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 196 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt\nindex 67f5b9b..3c67b68 100644\n--- a/Documentation/user-manual.txt\n+++ b/Documentation/user-manual.txt\n@@ -3161,6 +3161,202 @@ confusing and scary messages, but it won't actually do anything bad. In\n contrast, running \"git prune\" while somebody is actively changing the \n repository is a *BAD* idea).\n \n+[[birdview-on-the-source-code]]\n+A birdview on Git's source code\n+-----------------------------\n+\n+While Git's source code is quite elegant, it is not always easy for \n+new  developers to find their way through it.  A good idea is to look \n+at the contents of the initial commit: \n+_e83c5163316f89bfbde7d9ab23ca2e25604af290_ (also known as _v0.99~954_).\n+\n+Tip: you can see what files are in there with\n+\n+----------------------------------------------------\n+$ git show e83c5163316f89bfbde7d9ab23ca2e25604af290:\n+----------------------------------------------------\n+\n+and look at those files with something like\n+\n+-----------------------------------------------------------\n+$ git show e83c5163316f89bfbde7d9ab23ca2e25604af290:cache.h\n+-----------------------------------------------------------\n+\n+Be sure to read the README in that revision _after_ you are familiar with \n+the terminology (<<glossary>>), since the terminology has changed a little \n+since then.  For example, we call the things \"commits\" now, which are \n+described in that README as \"changesets\".\n+\n+Actually a lot of the structure as it is now can be explained by that \n+initial commit.\n+\n+For example, we do not call it \"cache\" any more, but \"index\", however, the \n+file is still called `cache.h`.  Remark: Not much reason to change it now, \n+especially since there is no good single name for it anyway, because it is \n+basically _the_ header file which is included by _all_ of Git's C sources.\n+\n+If you grasp the ideas in that initial commit (it is really small and you \n+can get into it really fast, and it will help you recognize things in the \n+much larger code base we have now), you should go on skimming `cache.h`, \n+`object.h` and `commit.h`.\n+\n+By now, you know what the index is (and find the corresponding data \n+structures in `cache.h`), and that there are just a couple of object types \n+(blobs, trees, commits and tags) which inherit their common structure from \n+`struct object`, which is their first member (and thus, you can cast e.g. \n+`(struct object *)commit` to achieve the _same_ as `&commit->object`, i.e. \n+get at the object name and flags).\n+\n+Now is a good point to take a break to let this information sink in.\n+\n+Next step: get familiar with the object naming.  Read <<naming-commits>>.\n+There are quite a few ways to name an object (and not only revisions!).  \n+All of these are handled in `sha1_name.c`. Just have a quick look at \n+the function `get_sha1()`. A lot of the special handling is done by \n+functions like `get_sha1_basic()` or the likes.\n+\n+This is just to get you into the groove for the most libified part of Git: \n+the revision walker.\n+\n+Basically, the initial version of `git log` was a shell script:\n+\n+----------------------------------------------------------------\n+$ git-rev-list --pretty $(git-rev-parse --default HEAD \"$@\") | \\\n+\tLESS=-S ${PAGER:-less}\n+----------------------------------------------------------------\n+\n+What does this mean?\n+\n+`git-rev-list` is the original version of the revision walker, which \n+_always_ printed a list of revisions to stdout.  It is still functional, \n+and needs to, since most new Git programs start out as scripts using \n+`git-rev-list`.\n+\n+`git-rev-parse` is not as important any more; it was only used to filter out \n+options that were relevant for the different plumbing commands that were \n+called by the script.\n+\n+Most of what `git-rev-list` did is contained in `revision.c` and \n+`revision.h`.  It wraps the options in a struct named rev_info, which \n+controls how and what revisions are walked, and more.\n+\n+Nowadays, `git log` is a builtin, which means that it is _contained_ in the \n+command `git`.  The source side of a builtin is\n+\n+- a function called `cmd_<bla>`, typically defined in `builtin-<bla>.c`, \n+  and declared in `builtin.h`,\n+\n+- an entry in the `commands[]` array in `git.c`, and\n+\n+- an entry in `BUILTIN_OBJECTS` in the `Makefile`.\n+\n+Sometimes, more than one builtin is contained in one source file.  For \n+example, `cmd_whatchanged()` and `cmd_log()` both reside in `builtin-log.c`, \n+since they share quite a bit of code.  In that case, the commands which are \n+_not_ named like the `.c` file in which they live have to be listed in \n+`BUILT_INS` in the `Makefile`.\n+\n+`git log` looks more complicated in C than it does in the original script, \n+but that allows for a much greater flexibility and performance.\n+\n+Here again it is a good point to take a pause.\n+\n+Lesson three is: study the code.  Really, it is the best way to learn about \n+the organization of Git (after you know the basic concepts).\n+\n+So, think about something which you are interested in, say, \"how can I \n+access a blob just knowing the object name of it?\".  The first step is to \n+find a Git command with which you can do it.  In this example, it is either \n+`git show` or `git cat-file`.\n+\n+For the sake of clarity, let's stay with `git cat-file`, because it\n+\n+- is plumbing, and\n+\n+- was around even in the initial commit (it literally went only through \n+  some 20 revisions as `cat-file.c`, was renamed to `builtin-cat-file.c` \n+  when made a builtin, and then saw less than 10 versions).\n+\n+So, look into `builtin-cat-file.c`, search for `cmd_cat_file()` and look what \n+it does.\n+\n+------------------------------------------------------------------\n+        git_config(git_default_config);\n+        if (argc != 3)\n+                usage(\"git-cat-file [-t|-s|-e|-p|<type>] <sha1>\");\n+        if (get_sha1(argv[2], sha1))\n+                die(\"Not a valid object name %s\", argv[2]);\n+------------------------------------------------------------------\n+\n+Let's skip over the obvious details; the only really interesting part \n+here is the call to `get_sha1()`.  It tries to interpret `argv[2]` as an \n+object name, and if it refers to an object which is present in the current \n+repository, it writes the resulting SHA-1 into the variable `sha1`.\n+\n+Two things are interesting here:\n+\n+- `get_sha1()` returns 0 on _success_.  This might surprise some new \n+  Git hackers, but there is a long tradition in UNIX to return different \n+  negative numbers in case of different errors -- and 0 on success.\n+\n+- the variable `sha1` in the function signature of `get_sha1()` is `unsigned \n+  char *`, but is actually expected to be a pointer to `unsigned \n+  char[20]`.  This variable will contain the big endian version of the \n+  40-character hex string representation of the SHA-1.\n+\n+You will see both of these things throughout the code.\n+\n+Now, for the meat:\n+\n+-----------------------------------------------------------------------------\n+        case 0:\n+                buf = read_object_with_reference(sha1, argv[1], &size, NULL);\n+-----------------------------------------------------------------------------\n+\n+This is how you read a blob (actually, not only a blob, but any type of \n+object).  To know how the function `read_object_with_reference()` actually \n+works, find the source code for it (something like `git grep \n+read_object_with | grep \":[a-z]\"` in the git repository), and read \n+the source.\n+\n+To find out how the result can be used, just read on in `cmd_cat_file()`:\n+\n+-----------------------------------\n+        write_or_die(1, buf, size);\n+-----------------------------------\n+\n+Sometimes, you do not know where to look for a feature.  In many such cases, \n+it helps to search through the output of `git log`, and then `git show` the \n+corresponding commit.\n+\n+Example: If you know that there was some test case for `git bundle`, but \n+do not remember where it was (yes, you _could_ `git grep bundle t/`, but that \n+does not illustrate the point!):\n+\n+------------------------\n+$ git log --no-merges t/\n+------------------------\n+\n+In the pager (`less`), just search for \"bundle\", go a few lines back, \n+and see that it is in commit 18449ab0...  Now just copy this object name, \n+and paste it into the command line\n+\n+-------------------\n+$ git show 18449ab0\n+-------------------\n+\n+Voila.\n+\n+Another example: Find out what to do in order to make some script a \n+builtin:\n+\n+-------------------------------------------------\n+$ git log --no-merges --diff-filter=A builtin-*.c\n+-------------------------------------------------\n+\n+You see, Git is actually the best tool to find out about the source of Git \n+itself!\n+\n [[glossary]]\n include::glossary.txt[]\n \n-- \n1.5.2.rc2.2469.gea95f\n"},{"id":"41500","messageId":"20070508210153.GA3969@diana.vm.bytemark.co.uk","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705081709230.4167@racer.site","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-05-08T21:01:53Z","receivedAt":"2007-05-08T21:01:53Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-05-08 17:10:47 +0200, Johannes Schindelin wrote:\n\n> +  char *`, but is actually expected to be a pointer to `unsigned\n> +  char[20]`.  This variable will contain the big endian version of the\n> +  40-character hex string representation of the SHA-1.\n\nEither it should be \"unsigned char[40]\" (or possibly 41 with a\nterminating \\0), or else you shouldn't be talking about hexadecimal\nsince it's just a 20-byte big-endian unsigned integer. (A third\npossibility is that I'm totally confused.)\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"41501","messageId":"Pine.LNX.4.64.0705082306100.4167@racer.site","threadId":"8034","inReplyTo":"20070508210153.GA3969@diana.vm.bytemark.co.uk","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-08T21:07:04Z","receivedAt":"2007-05-08T21:07:04Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 8 May 2007, Karl Hasselström wrote:\n\n> On 2007-05-08 17:10:47 +0200, Johannes Schindelin wrote:\n> \n> > +  char *`, but is actually expected to be a pointer to `unsigned\n> > +  char[20]`.  This variable will contain the big endian version of the\n> > +  40-character hex string representation of the SHA-1.\n> \n> Either it should be \"unsigned char[40]\" (or possibly 41 with a\n> terminating \\0), or else you shouldn't be talking about hexadecimal\n> since it's just a 20-byte big-endian unsigned integer. (A third\n> possibility is that I'm totally confused.)\n\nIt is 40 hex-character, but 20 _byte_. If you have any ideas how to \nformulate that better than I did...\n\nCiao,\nDscho\n"},{"id":"41504","messageId":"20070508213158.GB3969@diana.vm.bytemark.co.uk","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705082306100.4167@racer.site","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-05-08T21:31:58Z","receivedAt":"2007-05-08T21:31:58Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-05-08 23:07:04 +0200, Johannes Schindelin wrote:\n\n> On Tue, 8 May 2007, Karl Hasselström wrote:\n>\n> > On 2007-05-08 17:10:47 +0200, Johannes Schindelin wrote:\n> >\n> > > +  char *`, but is actually expected to be a pointer to `unsigned\n> > > +  char[20]`.  This variable will contain the big endian version of the\n> > > +  40-character hex string representation of the SHA-1.\n> >\n> > Either it should be \"unsigned char[40]\" (or possibly 41 with a\n> > terminating \\0), or else you shouldn't be talking about\n> > hexadecimal since it's just a 20-byte big-endian unsigned integer.\n> > (A third possibility is that I'm totally confused.)\n>\n> It is 40 hex-character, but 20 _byte_. If you have any ideas how to\n> formulate that better than I did...\n\nI think this is less confusing:\n\n  This variable will contain the 160-bit SHA-1.\n\nIt avoids talking of hex, since it's not really stored in hex format\nany more than any other binary number with a number of bits divisible\nby four. And it avoids saying big-endian, which is not relevant anyway\nsince we don't use hashes as integers.\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"41507","messageId":"Pine.LNX.4.64.0705090105450.4167@racer.site","threadId":"8034","inReplyTo":"20070508213158.GB3969@diana.vm.bytemark.co.uk","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-08T23:10:13Z","receivedAt":"2007-05-08T23:10:13Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 8 May 2007, Karl Hasselström wrote:\n\n> On 2007-05-08 23:07:04 +0200, Johannes Schindelin wrote:\n> \n> > On Tue, 8 May 2007, Karl Hasselström wrote:\n> >\n> > > On 2007-05-08 17:10:47 +0200, Johannes Schindelin wrote:\n> > >\n> > > > +  char *`, but is actually expected to be a pointer to `unsigned\n> > > > +  char[20]`.  This variable will contain the big endian version of the\n> > > > +  40-character hex string representation of the SHA-1.\n> > >\n> > > Either it should be \"unsigned char[40]\" (or possibly 41 with a\n> > > terminating \\0), or else you shouldn't be talking about\n> > > hexadecimal since it's just a 20-byte big-endian unsigned integer.\n> > > (A third possibility is that I'm totally confused.)\n> >\n> > It is 40 hex-character, but 20 _byte_. If you have any ideas how to\n> > formulate that better than I did...\n> \n> I think this is less confusing:\n> \n>   This variable will contain the 160-bit SHA-1.\n> \n> It avoids talking of hex, since it's not really stored in hex format\n> any more than any other binary number with a number of bits divisible\n> by four. And it avoids saying big-endian, which is not relevant anyway\n> since we don't use hashes as integers.\n\nWell, I do not buy into that. First, we _have_ to say that it is \nbig-endian. It was utterly confusing to _me_ that the hash was not little \nendian, as I expected on an Intel processor.\n\nAnd I'd rather mention the hex representation (what you see in git-log and \ngit-ls-tree). This helps debugging, believe me.\n\nCiao,\nDscho\n"},{"id":"41510","messageId":"20070508232251.GA5866@diana.vm.bytemark.co.uk","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705090105450.4167@racer.site","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-05-08T23:22:51Z","receivedAt":"2007-05-08T23:22:51Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-05-09 01:10:13 +0200, Johannes Schindelin wrote:\n\n> On Tue, 8 May 2007, Karl Hasselström wrote:\n>\n> > I think this is less confusing:\n> >\n> >   This variable will contain the 160-bit SHA-1.\n> >\n> > It avoids talking of hex, since it's not really stored in hex\n> > format any more than any other binary number with a number of bits\n> > divisible by four. And it avoids saying big-endian, which is not\n> > relevant anyway since we don't use hashes as integers.\n>\n> Well, I do not buy into that. First, we _have_ to say that it is\n> big-endian. It was utterly confusing to _me_ that the hash was not\n> little endian, as I expected on an Intel processor.\n\nIf you think of it as a integer and not a byte array, then yes. But\nfair enough, if it confused you, it'd probably confuse others as well.\n\n> And I'd rather mention the hex representation (what you see in\n> git-log and git-ls-tree). This helps debugging, believe me.\n\nBut that byte array doesn't store the hex representation!\n\nThere is a trivial transformation that will convert a 20-byte integer\nto a 40-character hex string representation of that integer: translate\neach nibble to one hex digit. But the code snippet you gave uses the\nformer representation, and that's the point I thought you were trying\nto make in the first place.\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"41528","messageId":"20070509031803.GA27980@fieldses.org","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705081709230.4167@racer.site","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-05-09T03:18:04Z","receivedAt":"2007-05-09T03:18:04Z","isPatch":true,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Tue, May 08, 2007 at 05:10:47PM +0200, Johannes Schindelin wrote:\n> \n> In http://thread.gmane.org/gmane.comp.version-control.git/42479,\n> a birdview on the source code was requested.\n> \n> J. Bruce Fields suggested that my reply should be included in the\n> user manual, and there was nothing of an outcry, so here it is,\n> not even 2 months later.\n\nLooks helpful, concise, and to the point.  Neat-o.\n\nAcked-by: J. Bruce Fields <bfields@citi.umich.edu>\n\nComments, nothing major:\n\n> +If you grasp the ideas in that initial commit (it is really small and you \n> +can get into it really fast, and it will help you recognize things in the \n> +much larger code base we have now), you should go on skimming `cache.h`, \n> +`object.h` and `commit.h`.\n\nMight want to add \"in a recent commit\"?--it's not clear that you've\ntransitioned away from talking about the initial commit.\n\n> +This is just to get you into the groove for the most libified part of Git: \n> +the revision walker.\n\nUnless the reader has already been hanging out on the mailing list a\nwhile, \"most libified\" may not mean much to them yet at this point.\n\nThe organization of the next bit is slightly confusing: we're set up to\nexpect a longer lecture on the revision walker, but instead there's just\nthe historical note on git-rev-list, a mention of 'revision.c',\n'revision.h', and 'struct rev_info', and then it rapidly digresses into\ndiscussing builtins.\n\nWhich actually is fine, but just a few small markers of where we are in\nthe discussion might be reassuring--a section header or two, maybe a\nlittle more emphasis on the pointers you're giving, like: \"take a moment\nto go read revision.h and revision.c now, paying special attention to\nstruct rev_info, which ....\".\n\n--b.\n"},{"id":"41530","messageId":"7vps5azlm1.fsf@assigned-by-dhcp.cox.net","threadId":"8034","inReplyTo":"20070509031803.GA27980@fieldses.org","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-09T04:06:46Z","receivedAt":"2007-05-09T04:06:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"J. Bruce Fields\" <bfields@fieldses.org> writes:\n\n> The organization of the next bit is slightly confusing: we're set up to\n> expect a longer lecture on the revision walker, but instead there's just\n> the historical note on git-rev-list, a mention of 'revision.c',\n> 'revision.h', and 'struct rev_info', and then it rapidly digresses into\n> discussing builtins.\n\nI had the same impression.\n\nI was meaning to write a \"code walkthru for git hackers and\nwannabes\" with target audience quite different from the\nuser-manual.  My idea of which areas to cover in what order\nseems to match with what Johannes started.\n\n - sha1_name.c;\n\n - read_sha1_file();\n\n - revision.c::setup_revisions() to talk about parsing but not\n   about walking yet.\n\n - start from builtin-merge-base.c into commit.c to talk about\n   revision traversal done by get_merge_bases().  This codepath\n   is much simpler than the revision.c machinery and is a good\n   primer to understand the latter.\n\n - builtin-diff-tree.c to show one tree and two tree cases, go\n   into log-tree.c then tree-diff.c to show the use of\n   add_remove() and change() callbacks, and then finally talk\n   about diff_flush(), without talking about diffcore\n   transformations yet.\n\n - start from builtin-log.c to review the setup_revisions(),\n   then talk about prepare_revision_walk() and get_revision()\n   machinery, first pass without talking about path limiting and\n   then with path limiting.\n\n - fetch-pack.c and upload-pack.c to talk about the native\n   protocol over ssh and local forking, how revision traversal\n   machinery is used, the \"objects pointed by refs are complete\"\n   contract.\n\n - daemon.c to see how upload-pack is invoked.\n\n - read_cache(), active_cache[], active_nr and friends;\n\n - update-index and write-tree, including how cache-tree\n   optimizes tree writing after small updates.  Advanced students\n   can also look at git-apply here.\n\n - unpack-trees.c and builtin-read-tree.c to talk about index stages.\n\n - diffcore transformations, especially diffcore-rename.\n\n - merge-recursive\n"},{"id":"41533","messageId":"Pine.LNX.4.64.0705090015360.18541@iabervon.org","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705090105450.4167@racer.site","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2007-05-09T04:54:03Z","receivedAt":"2007-05-09T04:54:03Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Wed, 9 May 2007, Johannes Schindelin wrote:\n\n> Hi,\n> \n> On Tue, 8 May 2007, Karl Hasselstr�m wrote:\n> \n> > On 2007-05-08 23:07:04 +0200, Johannes Schindelin wrote:\n> > \n> > > On Tue, 8 May 2007, Karl Hasselstr�m wrote:\n> > >\n> > > > On 2007-05-08 17:10:47 +0200, Johannes Schindelin wrote:\n> > > >\n> > > > > +  char *`, but is actually expected to be a pointer to `unsigned\n> > > > > +  char[20]`.  This variable will contain the big endian version of the\n> > > > > +  40-character hex string representation of the SHA-1.\n> > > >\n> > > > Either it should be \"unsigned char[40]\" (or possibly 41 with a\n> > > > terminating \\0), or else you shouldn't be talking about\n> > > > hexadecimal since it's just a 20-byte big-endian unsigned integer.\n> > > > (A third possibility is that I'm totally confused.)\n> > >\n> > > It is 40 hex-character, but 20 _byte_. If you have any ideas how to\n> > > formulate that better than I did...\n> > \n> > I think this is less confusing:\n> > \n> >   This variable will contain the 160-bit SHA-1.\n> > \n> > It avoids talking of hex, since it's not really stored in hex format\n> > any more than any other binary number with a number of bits divisible\n> > by four. And it avoids saying big-endian, which is not relevant anyway\n> > since we don't use hashes as integers.\n> \n> Well, I do not buy into that. First, we _have_ to say that it is \n> big-endian. It was utterly confusing to _me_ that the hash was not little \n> endian, as I expected on an Intel processor.\n\nSHA-1 is defined as producing a octet sequence, and to have a canonical \nhex digit sequence conversion with the high nibbles first. Internally, it \nis canonically specified using big-endian math, but the same algorithm \ncould equally be specified with little-endian math and different rules for \ninput and output.\n\n> And I'd rather mention the hex representation (what you see in git-log and \n> git-ls-tree). This helps debugging, believe me.\n\nIt's kind of important to distinguish between the hex representation and \nthe octet representation, because your code will not work at all if you \nuse the wrong one. And \"unsigned char *\" or \"unsigned char[20]\" is always \nthe octets; the hex is always \"char *\". Primarily mentioning the one that \nis more intuitive but less frequently used doesn't help with understanding \nthe actual code.\n\n\t-Daniel\n*This .sig left intentionally blank*"},{"id":"41537","messageId":"7v4pmmzivz.fsf@assigned-by-dhcp.cox.net","threadId":"8034","inReplyTo":"7vps5azlm1.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-09T05:05:36Z","receivedAt":"2007-05-09T05:05:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <junkio@cox.net> writes:\n\n> \"J. Bruce Fields\" <bfields@fieldses.org> writes:\n>\n>> The organization of the next bit is slightly confusing: we're set up to\n>> expect a longer lecture on the revision walker, but instead there's just\n>> the historical note on git-rev-list, a mention of 'revision.c',\n>> 'revision.h', and 'struct rev_info', and then it rapidly digresses into\n>> discussing builtins.\n>\n> I had the same impression.\n>\n> I was meaning to write a \"code walkthru for git hackers and\n> wannabes\" with target audience quite different from the\n> user-manual.  My idea of which areas to cover in what order\n> seems to match with what Johannes started.\n\nHaving said that, I do not think the patch belongs to the \"git\nUSER'S manual\".  It is a very good introductory material for a\nseparate \"git hackers manual\", though.\n"},{"id":"41542","messageId":"20070509063113.GA10943@diana.vm.bytemark.co.uk","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705090015360.18541@iabervon.org","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-05-09T06:31:13Z","receivedAt":"2007-05-09T06:31:13Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-05-09 00:54:03 -0400, Daniel Barkalow wrote:\n\n> And \"unsigned char *\" or \"unsigned char[20]\" is always the octets;\n> the hex is always \"char *\".\n\nuint8_t, anyone? :-)\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"41546","messageId":"20070509064858.GB10943@diana.vm.bytemark.co.uk","threadId":"8034","inReplyTo":"20070509031803.GA27980@fieldses.org","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-05-09T06:48:58Z","receivedAt":"2007-05-09T06:48:58Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-05-08 23:18:04 -0400, J. Bruce Fields wrote:\n\n> Looks helpful, concise, and to the point. Neat-o.\n\nYeah, I like it too. I forgot to say that, and got right to the\ncriticism instead. But better late than never, I hope. :-)\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"41564","messageId":"Pine.LNX.4.64.0705091120560.4167@racer.site","threadId":"8034","inReplyTo":"20070509031803.GA27980@fieldses.org","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-09T09:27:21Z","receivedAt":"2007-05-09T09:27:21Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 8 May 2007, J. Bruce Fields wrote:\n\n> On Tue, May 08, 2007 at 05:10:47PM +0200, Johannes Schindelin wrote:\n> > \n> > +If you grasp the ideas in that initial commit (it is really small and you \n> > +can get into it really fast, and it will help you recognize things in the \n> > +much larger code base we have now), you should go on skimming `cache.h`, \n> > +`object.h` and `commit.h`.\n> \n> Might want to add \"in a recent commit\"?--it's not clear that you've\n> transitioned away from talking about the initial commit.\n\nYes, good idea.\n\n> > +This is just to get you into the groove for the most libified part of Git:\n> > +the revision walker.\n> \n> Unless the reader has already been hanging out on the mailing list a \n> while, \"most libified\" may not mean much to them yet at this point.\n\nHow about a sentence way before that, when I talk about the initial \ncommit, like this:\n\n\tIn the early days, Git (in the tradition of UNIX) was a bunch of \n\tprograms which were extremely simple, and which you used in scripts, \n\tpiping the output of one into another. This turned out to be good \n\tfor initial development, since it was easier to test new things. \n\tHowever, recently many of these parts have become builtins, and \n\tsome of the core has been \"libified\", i.e. put into libgit.a for \n\tperformance, portability reasons, and to avoid code duplication.\n\n> The organization of the next bit is slightly confusing: we're set up to\n> expect a longer lecture on the revision walker, but instead there's just\n> the historical note on git-rev-list, a mention of 'revision.c',\n> 'revision.h', and 'struct rev_info', and then it rapidly digresses into\n> discussing builtins.\n> \n> Which actually is fine, but just a few small markers of where we are in\n> the discussion might be reassuring--a section header or two, maybe a\n> little more emphasis on the pointers you're giving, like: \"take a moment\n> to go read revision.h and revision.c now, paying special attention to\n> struct rev_info, which ....\".\n\nOkay. I hope I will be able to make these changes until tomorrow (I will \nbe gone for a few days after that).\n\nCiao,\nDscho\n"},{"id":"41565","messageId":"Pine.LNX.4.64.0705091127310.4167@racer.site","threadId":"8034","inReplyTo":"7v4pmmzivz.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-09T09:33:58Z","receivedAt":"2007-05-09T09:33:58Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 8 May 2007, Junio C Hamano wrote:\n\n> Junio C Hamano <junkio@cox.net> writes:\n> \n> > \"J. Bruce Fields\" <bfields@fieldses.org> writes:\n> >\n> >> The organization of the next bit is slightly confusing: we're set up \n> >> to expect a longer lecture on the revision walker, but instead \n> >> there's just the historical note on git-rev-list, a mention of \n> >> 'revision.c', 'revision.h', and 'struct rev_info', and then it \n> >> rapidly digresses into discussing builtins.\n> >\n> > I had the same impression.\n> >\n> > I was meaning to write a \"code walkthru for git hackers and wannabes\" \n> > with target audience quite different from the user-manual.  My idea of \n> > which areas to cover in what order seems to match with what Johannes \n> > started.\n> \n> Having said that, I do not think the patch belongs to the \"git USER'S \n> manual\".  It is a very good introductory material for a separate \"git \n> hackers manual\", though.\n\nThat is what I was referring to when I mentioned \"no outcry\". Bruce said \nthat he liked the idea to have something like that in the USER's manual. \n\nAnd I have to agree: There might be enough room to actually go and write a \nGit hacker's manual, but IMHO that takes a lot of time which has to be \nfound at first.\n\nAnd even if we actually have such a hacker's manual one day, this \"sneak \npreview\" in the user's manual does not hurt, but could actually entice \npeople to read that manual, too.\n\nCiao,\nDscho\n"},{"id":"41566","messageId":"Pine.LNX.4.64.0705091137190.4167@racer.site","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705090015360.18541@iabervon.org","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-09T09:38:34Z","receivedAt":"2007-05-09T09:38:34Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 9 May 2007, Daniel Barkalow wrote:\n\n> On Wed, 9 May 2007, Johannes Schindelin wrote:\n> \n> > On Tue, 8 May 2007, Karl Hasselstr�m wrote:\n> > \n> > > On 2007-05-08 23:07:04 +0200, Johannes Schindelin wrote:\n> > > \n> > > > On Tue, 8 May 2007, Karl Hasselstr�m wrote:\n> > > >\n> > > > > On 2007-05-08 17:10:47 +0200, Johannes Schindelin wrote:\n> > > > >\n> > > > > > +  char *`, but is actually expected to be a pointer to `unsigned\n> > > > > > +  char[20]`.  This variable will contain the big endian version of the\n> > > > > > +  40-character hex string representation of the SHA-1.\n> > > > >\n> > > > > Either it should be \"unsigned char[40]\" (or possibly 41 with a\n> > > > > terminating \\0), or else you shouldn't be talking about\n> > > > > hexadecimal since it's just a 20-byte big-endian unsigned integer.\n> > > > > (A third possibility is that I'm totally confused.)\n> > > >\n> > > > It is 40 hex-character, but 20 _byte_. If you have any ideas how to\n> > > > formulate that better than I did...\n> > > \n> > > I think this is less confusing:\n> > > \n> > >   This variable will contain the 160-bit SHA-1.\n> > > \n> > > It avoids talking of hex, since it's not really stored in hex format\n> > > any more than any other binary number with a number of bits divisible\n> > > by four. And it avoids saying big-endian, which is not relevant anyway\n> > > since we don't use hashes as integers.\n> > \n> > Well, I do not buy into that. First, we _have_ to say that it is \n> > big-endian. It was utterly confusing to _me_ that the hash was not little \n> > endian, as I expected on an Intel processor.\n> \n> SHA-1 is defined as producing a octet sequence, and to have a canonical \n> hex digit sequence conversion with the high nibbles first. Internally, it \n> is canonically specified using big-endian math, but the same algorithm \n> could equally be specified with little-endian math and different rules for \n> input and output.\n> \n> > And I'd rather mention the hex representation (what you see in git-log and \n> > git-ls-tree). This helps debugging, believe me.\n> \n> It's kind of important to distinguish between the hex representation and \n> the octet representation, because your code will not work at all if you \n> use the wrong one. And \"unsigned char *\" or \"unsigned char[20]\" is always \n> the octets; the hex is always \"char *\". Primarily mentioning the one that \n> is more intuitive but less frequently used doesn't help with understanding \n> the actual code.\n\nThat's a really good idea, to point out that \"unsigned char *\" refers to \noctets, while \"char *\" refers to the ASCII representation. I will add \nthis, together with a simple example (the initial commit).\n\nCiao,\nDscho\n"},{"id":"41569","messageId":"20070509104332.GA14214@diana.vm.bytemark.co.uk","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705091137190.4167@racer.site","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-05-09T10:43:32Z","receivedAt":"2007-05-09T10:43:32Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-05-09 11:38:34 +0200, Johannes Schindelin wrote:\n\n> On Wed, 9 May 2007, Daniel Barkalow wrote:\n>\n> > It's kind of important to distinguish between the hex\n> > representation and the octet representation, because your code\n> > will not work at all if you use the wrong one. And \"unsigned char\n> > *\" or \"unsigned char[20]\" is always the octets; the hex is always\n> > \"char *\". Primarily mentioning the one that is more intuitive but\n> > less frequently used doesn't help with understanding the actual\n> > code.\n>\n> That's a really good idea, to point out that \"unsigned char *\"\n> refers to octets, while \"char *\" refers to the ASCII representation.\n> I will add this, together with a simple example (the initial\n> commit).\n\nThat'll address my complaint nicely, I believe. It was the confusion\nbetween these two formats that I was trying to get at.\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"41575","messageId":"Pine.LNX.4.64.0705091414280.4167@racer.site","threadId":"8034","inReplyTo":"20070509031803.GA27980@fieldses.org","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-09T12:19:03Z","receivedAt":"2007-05-09T12:19:03Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nfor your reviewing pleasure, I made a patch on top of the original one, \nbut I can easily provide a full patch for application.\n\n--\n[PATCH] user-manual: Touch ups on the birdview section\n\n... as suggested by J. Bruce Fields, Karl Hasselström and Daniel Barkalow.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Documentation/user-manual.txt |   31 +++++++++++++++++++++++++++----\n 1 files changed, 27 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt\nindex 2d58bb0..55934db 100644\n--- a/Documentation/user-manual.txt\n+++ b/Documentation/user-manual.txt\n@@ -3197,7 +3197,15 @@ basically _the_ header file which is included by _all_ of Git's C sources.\n If you grasp the ideas in that initial commit (it is really small and you \n can get into it really fast, and it will help you recognize things in the \n much larger code base we have now), you should go on skimming `cache.h`, \n-`object.h` and `commit.h`.\n+`object.h` and `commit.h` in the current version.\n+\n+In the early days, Git (in the tradition of UNIX) was a bunch of programs \n+which were extremely simple, and which you used in scripts, piping the \n+output of one into another. This turned out to be good for initial \n+development, since it was easier to test new things.  However, recently \n+many of these parts have become builtins, and some of the core has been \n+\"libified\", i.e. put into libgit.a for performance, portability reasons, \n+and to avoid code duplication.\n \n By now, you know what the index is (and find the corresponding data \n structures in `cache.h`), and that there are just a couple of object types \n@@ -3236,9 +3244,22 @@ options that were relevant for the different plumbing commands that were\n called by the script.\n \n Most of what `git-rev-list` did is contained in `revision.c` and \n-`revision.h`.  It wraps the options in a struct named rev_info, which \n+`revision.h`.  It wraps the options in a struct named `rev_info`, which \n controls how and what revisions are walked, and more.\n \n+The original job of `git-rev-parse` is now taken by the function \n+`setup_revisions()`, which parses the revisions and the common command line \n+options for the revision walker. This information is stored in the struct \n+`rev_info` for later consumption. You can do your own command line option\n+parsing after calling `setup_revisions()`. After that, you have to call \n+`prepare_revision_walk()` for initialization, and then you can get the \n+commits one by one with the function `get_revision()`.\n+\n+If you are interested in more details of the revision walking process, \n+just have a look at the first implementation of `cmd_log()`; call\n+`git-show v1.3.0~155^2~4` and scroll down to that function (note that you \n+no longer need to call `setup_pager()` directly).\n+\n Nowadays, `git log` is a builtin, which means that it is _contained_ in the \n command `git`.  The source side of a builtin is\n \n@@ -3300,8 +3321,10 @@ Two things are interesting here:\n \n - the variable `sha1` in the function signature of `get_sha1()` is `unsigned \n   char *`, but is actually expected to be a pointer to `unsigned \n-  char[20]`.  This variable will contain the big endian version of the \n-  40-character hex string representation of the SHA-1.\n+  char[20]`.  This variable will contain the 160-bit SHA-1 of the given \n+  commit.  Note that whenever a SHA-1 is passed as \"unsigned char *\", it \n+  is the binary representation (big-endian), as opposed to the ASCII \n+  representation in hex characters, which is passed as \"char *\".\n \n You will see both of these things throughout the code.\n \n-- \n1.5.2.rc2.2502.g46b5cb\n\n"},{"id":"41578","messageId":"20070509123205.GN4489@pasky.or.cz","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705091414280.4167@racer.site","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2007-05-09T12:32:05Z","receivedAt":"2007-05-09T12:32:05Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Wed, May 09, 2007 at 02:19:03PM CEST, Johannes Schindelin wrote:\n> diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt\n> index 2d58bb0..55934db 100644\n> --- a/Documentation/user-manual.txt\n> +++ b/Documentation/user-manual.txt\n> @@ -3197,7 +3197,15 @@ basically _the_ header file which is included by _all_ of Git's C sources.\n>  If you grasp the ideas in that initial commit (it is really small and you \n>  can get into it really fast, and it will help you recognize things in the \n>  much larger code base we have now), you should go on skimming `cache.h`, \n> -`object.h` and `commit.h`.\n> +`object.h` and `commit.h` in the current version.\n> +\n> +In the early days, Git (in the tradition of UNIX) was a bunch of programs \n> +which were extremely simple, and which you used in scripts, piping the \n> +output of one into another. This turned out to be good for initial \n> +development, since it was easier to test new things.  However, recently \n> +many of these parts have become builtins, and some of the core has been \n> +\"libified\", i.e. put into libgit.a for performance, portability reasons, \n> +and to avoid code duplication.\n> \n>  By now, you know what the index is (and find the corresponding data \n>  structures in `cache.h`), and that there are just a couple of object types \n\nI disagree, especially with the past tense of the first half of the\nparagraph. Git is _still_ a bunch of programs you use in scripts, piping\nthe output of one into another. Another point is that\nimplementation-wise many of the code is currently shared in an internal\nlibrary, etc.\n\nI'd be a bit careful to talk about libgit.a so leisurely since it might\ngive the reader an impression that there really _is_ \"the git library\",\nwith API and everything, that they can use externally. Of course you\nneed to mention libgit.a, but I'd also mention that it is so far meant\nonly for internal git's use and has no solidified API.\n\n> @@ -3300,8 +3321,10 @@ Two things are interesting here:\n>  \n>  - the variable `sha1` in the function signature of `get_sha1()` is `unsigned \n>    char *`, but is actually expected to be a pointer to `unsigned \n> -  char[20]`.  This variable will contain the big endian version of the \n> -  40-character hex string representation of the SHA-1.\n> +  char[20]`.  This variable will contain the 160-bit SHA-1 of the given \n> +  commit.  Note that whenever a SHA-1 is passed as \"unsigned char *\", it \n> +  is the binary representation (big-endian), as opposed to the ASCII \n> +  representation in hex characters, which is passed as \"char *\".\n>  \n>  You will see both of these things throughout the code.\n\nTo be honest, I wouldn't even be *thinking* about the endianity of SHA-1\noctet representation (you don't usually really deal with the hash as\nwith a number, so expecting to have it in native endianity is not very\nnatural; you just deal with it as with a data blob) and the\n\"(big-endian)\" would only confuse me and get me thinking about \"huh, do\nthey swap the bytes, or wait, they don't, ...?!\".\n\nBut that's maybe just me.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nEver try. Ever fail. No matter. // Try again. Fail again. Fail better.\n\t\t-- Samuel Beckett\n"},{"id":"41582","messageId":"Pine.LNX.4.64.0705091447110.4167@racer.site","threadId":"8034","inReplyTo":"20070509123205.GN4489@pasky.or.cz","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-09T12:50:41Z","receivedAt":"2007-05-09T12:50:41Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 9 May 2007, Petr Baudis wrote:\n\n> On Wed, May 09, 2007 at 02:19:03PM CEST, Johannes Schindelin wrote:\n> > diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt\n> > index 2d58bb0..55934db 100644\n> > --- a/Documentation/user-manual.txt\n> > +++ b/Documentation/user-manual.txt\n> > @@ -3197,7 +3197,15 @@ basically _the_ header file which is included by _all_ of Git's C sources.\n> >  If you grasp the ideas in that initial commit (it is really small and you \n> >  can get into it really fast, and it will help you recognize things in the \n> >  much larger code base we have now), you should go on skimming `cache.h`, \n> > -`object.h` and `commit.h`.\n> > +`object.h` and `commit.h` in the current version.\n> > +\n> > +In the early days, Git (in the tradition of UNIX) was a bunch of programs \n> > +which were extremely simple, and which you used in scripts, piping the \n> > +output of one into another. This turned out to be good for initial \n> > +development, since it was easier to test new things.  However, recently \n> > +many of these parts have become builtins, and some of the core has been \n> > +\"libified\", i.e. put into libgit.a for performance, portability reasons, \n> > +and to avoid code duplication.\n> > \n> >  By now, you know what the index is (and find the corresponding data \n> >  structures in `cache.h`), and that there are just a couple of object types \n> \n> I disagree, especially with the past tense of the first half of the\n> paragraph. Git is _still_ a bunch of programs you use in scripts, piping\n> the output of one into another. Another point is that\n> implementation-wise many of the code is currently shared in an internal\n> library, etc.\n\nNo. Many parts are _not_ simple programs piped into each other. git-log, \ngit-show, git-mv come to mind. That is why I wrote \"many\" and not \"all\".\n\n> I'd be a bit careful to talk about libgit.a so leisurely since it might \n> give the reader an impression that there really _is_ \"the git library\", \n> with API and everything, that they can use externally. Of course you \n> need to mention libgit.a, but I'd also mention that it is so far meant \n> only for internal git's use and has no solidified API.\n\nFrankly, this is just a birdview thing. If you want to go and make a \nhacker's manual, go ahead!\n\n> > @@ -3300,8 +3321,10 @@ Two things are interesting here:\n> >  \n> >  - the variable `sha1` in the function signature of `get_sha1()` is `unsigned \n> >    char *`, but is actually expected to be a pointer to `unsigned \n> > -  char[20]`.  This variable will contain the big endian version of the \n> > -  40-character hex string representation of the SHA-1.\n> > +  char[20]`.  This variable will contain the 160-bit SHA-1 of the given \n> > +  commit.  Note that whenever a SHA-1 is passed as \"unsigned char *\", it \n> > +  is the binary representation (big-endian), as opposed to the ASCII \n> > +  representation in hex characters, which is passed as \"char *\".\n> >  \n> >  You will see both of these things throughout the code.\n> \n> To be honest, I wouldn't even be *thinking* about the endianity of SHA-1\n> octet representation (you don't usually really deal with the hash as\n> with a number, so expecting to have it in native endianity is not very\n> natural; you just deal with it as with a data blob) and the\n> \"(big-endian)\" would only confuse me and get me thinking about \"huh, do\n> they swap the bytes, or wait, they don't, ...?!\".\n> \n> But that's maybe just me.\n\nBut then, maybe it is just me? I got it completely wrong the first time, \nfully expecting the calculations to be carried out in host endianness for \nperformance reasons.\n\nCiao,\nDscho\n"},{"id":"41588","messageId":"20070509131801.GD14969@fieldses.org","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705091414280.4167@racer.site","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-05-09T13:18:01Z","receivedAt":"2007-05-09T13:18:01Z","isPatch":true,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Wed, May 09, 2007 at 02:19:03PM +0200, Johannes Schindelin wrote:\n> [PATCH] user-manual: Touch ups on the birdview section\n\nThose all look like sensible changes to me, thanks!\n\n--b.\n"},{"id":"41612","messageId":"Pine.LNX.4.64.0705091210570.18541@iabervon.org","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705091447110.4167@racer.site","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2007-05-09T16:18:53Z","receivedAt":"2007-05-09T16:18:53Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Wed, 9 May 2007, Johannes Schindelin wrote:\n\n> > To be honest, I wouldn't even be *thinking* about the endianity of SHA-1\n> > octet representation (you don't usually really deal with the hash as\n> > with a number, so expecting to have it in native endianity is not very\n> > natural; you just deal with it as with a data blob) and the\n> > \"(big-endian)\" would only confuse me and get me thinking about \"huh, do\n> > they swap the bytes, or wait, they don't, ...?!\".\n> > \n> > But that's maybe just me.\n> \n> But then, maybe it is just me? I got it completely wrong the first time, \n> fully expecting the calculations to be carried out in host endianness for \n> performance reasons.\n\nI think the Mozilla implementation carries out calculations in host \nendianness, and transfers data from the input to the internal state and \nfrom the internal state to the final hash with shifts and masks.\n\nWhich calculations are you seeing that involve byte order?\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"41615","messageId":"Pine.LNX.4.64.0705091822590.4167@racer.site","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705091210570.18541@iabervon.org","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-09T16:25:01Z","receivedAt":"2007-05-09T16:25:01Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 9 May 2007, Daniel Barkalow wrote:\n\n> On Wed, 9 May 2007, Johannes Schindelin wrote:\n> \n> > > To be honest, I wouldn't even be *thinking* about the endianity of SHA-1\n> > > octet representation (you don't usually really deal with the hash as\n> > > with a number, so expecting to have it in native endianity is not very\n> > > natural; you just deal with it as with a data blob) and the\n> > > \"(big-endian)\" would only confuse me and get me thinking about \"huh, do\n> > > they swap the bytes, or wait, they don't, ...?!\".\n> > > \n> > > But that's maybe just me.\n> > \n> > But then, maybe it is just me? I got it completely wrong the first time, \n> > fully expecting the calculations to be carried out in host endianness for \n> > performance reasons.\n> \n> I think the Mozilla implementation carries out calculations in host \n> endianness, and transfers data from the input to the internal state and \n> >from the internal state to the final hash with shifts and masks.\n> \n> Which calculations are you seeing that involve byte order?\n\nNone. I only suspected them to be carried out in byte order. From what I \nknow, there are some shifts involved, which might or might not be helped \nby 32-bit arithmetic.\n\nI did not really look into it.\n\n>From my prior debugging experiences on Intel, though, I automatically \nlooked for the least significant bytes at the beginning of those \"sha1\" \nvariables, and came up empty.\n\nCiao,\nDscho\n"},{"id":"41628","messageId":"20070509170725.GB23778@fieldses.org","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705091822590.4167@racer.site","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-05-09T17:07:25Z","receivedAt":"2007-05-09T17:07:25Z","isPatch":true,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Wed, May 09, 2007 at 06:25:01PM +0200, Johannes Schindelin wrote:\n> None. I only suspected them to be carried out in byte order. From what I \n> know, there are some shifts involved, which might or might not be helped \n> by 32-bit arithmetic.\n> \n> I did not really look into it.\n> \n> From my prior debugging experiences on Intel, though, I automatically \n> looked for the least significant bytes at the beginning of those \"sha1\" \n> variables, and came up empty.\n\nSo, I'm confused about what you actually mean by \"big endian\" here.  I\noriginally assumed that you meant that SHA1's are defined as bit arrays,\nand that the first bit of the SHA1 is in the high-order bit of the first\nbyte.  But if you just meant that the first byte of the SHA1 is stored\nin the first byte of the array...  that kind of goes without saying,\ndoesn't it?\n\nIn any case, maybe this is a detail that's best left to the code itself.\n\n--b.\n"},{"id":"41633","messageId":"20070509173622.GE23778@fieldses.org","threadId":"8034","inReplyTo":"7v4pmmzivz.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-05-09T17:36:22Z","receivedAt":"2007-05-09T17:36:22Z","isPatch":true,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Tue, May 08, 2007 at 10:05:36PM -0700, Junio C Hamano wrote:\n> Having said that, I do not think the patch belongs to the \"git\n> USER'S manual\".\n\nWell, we could remove the word \"user\" from the name.  There's a pretty\ngood continuum between users and hackers, and that's as it should be.\n(Where do you document \"porcelain\" level stuff?)\n\n> It is a very good introductory material for a separate \"git hackers\n> manual\", though.\n\nBut that would be OK too, as long as we have a clear idea how we're\ngoing to decide what goes in which manual.  No need to wait until the\nwhole thing's done--we could commit an initial version of it Johannes's\nwork and your outline and fill in the rest later.\n\n--b.\n"},{"id":"41653","messageId":"Pine.LNX.4.64.0705092208230.4167@racer.site","threadId":"8034","inReplyTo":"20070509170725.GB23778@fieldses.org","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-09T20:15:19Z","receivedAt":"2007-05-09T20:15:19Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 9 May 2007, J. Bruce Fields wrote:\n\n> On Wed, May 09, 2007 at 06:25:01PM +0200, Johannes Schindelin wrote:\n> > None. I only suspected them to be carried out in byte order. From what I \n> > know, there are some shifts involved, which might or might not be helped \n> > by 32-bit arithmetic.\n> > \n> > I did not really look into it.\n> > \n> > From my prior debugging experiences on Intel, though, I automatically \n> > looked for the least significant bytes at the beginning of those \"sha1\" \n> > variables, and came up empty.\n> \n> So, I'm confused about what you actually mean by \"big endian\" here.  I\n> originally assumed that you meant that SHA1's are defined as bit arrays,\n> and that the first bit of the SHA1 is in the high-order bit of the first\n> byte.  But if you just meant that the first byte of the SHA1 is stored\n> in the first byte of the array...  that kind of goes without saying,\n> doesn't it?\n\nHm.\n\nLet me explain it in this way:\n\nIf you parse a number, passed to a program, with strtol(argv[1], NULL, 0) \nyou would expect something like this on an Intel processor:\n\nInput 0x1234 -> memory 0x34 0x12 0x00 0x00.\n\nOn a big endian machine, you'd expect 0x00 0x00 0x12 0x34.\n\nThat is what endianness means.\n\nIf you tell Git that it should look for commit e83c6516..., it will store \nthe sha1 as 0xe8 0x3c 0x65 0x16 ... in memory, no matter which \nendianness the processor has.\n\nWhich was positively confusing for me, since I automatically searched for \nthe sequence 0x90 0xf2 0x4a 0x60 ... (which is the tail of that hash).\n\nBut if all this sounds too confusing, I agree to delete the \n\"(big-endian)\".\n\nCiao,\nDscho\n"},{"id":"41660","messageId":"20070509203209.GM23778@fieldses.org","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705092208230.4167@racer.site","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-05-09T20:32:09Z","receivedAt":"2007-05-09T20:32:09Z","isPatch":true,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Wed, May 09, 2007 at 10:15:19PM +0200, Johannes Schindelin wrote:\n> If you parse a number, passed to a program, with strtol(argv[1], NULL, 0) \n> you would expect something like this on an Intel processor:\n> \n> Input 0x1234 -> memory 0x34 0x12 0x00 0x00.\n\nRight, but this is something special to integers.  If it made sense for\nsome strange reason to define the structure carrying a sha1 as int[5]\ninstead of char[20] then I'd understand the confusion, but char[20] is\ntotally unambiguous.\n\n> But if all this sounds too confusing, I agree to delete the \n> \"(big-endian)\".\n\nYeah, I think that'd be best; thanks.\n\n--b.\n"},{"id":"41663","messageId":"Pine.LNX.4.64.0705091625200.18541@iabervon.org","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705092208230.4167@racer.site","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2007-05-09T20:45:08Z","receivedAt":"2007-05-09T20:45:08Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Wed, 9 May 2007, Johannes Schindelin wrote:\n\n> Let me explain it in this way:\n> \n> If you parse a number, passed to a program, with strtol(argv[1], NULL, 0) \n> you would expect something like this on an Intel processor:\n> \n> Input 0x1234 -> memory 0x34 0x12 0x00 0x00.\n> \n> On a big endian machine, you'd expect 0x00 0x00 0x12 0x34.\n> \n> That is what endianness means.\n> \n> If you tell Git that it should look for commit e83c6516..., it will store \n> the sha1 as 0xe8 0x3c 0x65 0x16 ... in memory, no matter which \n> endianness the processor has.\n\nBut it would be really weird to get 0x90 0xf2 0x4a 0x60 ... 0x16 0x65 0x3c \n0xe8 unless you've got a 160-bit little-endian processor. That would be as \nstrange as having \"Test\" stored as 0x74 0x73 0x65 0x54, I think.\n\n> Which was positively confusing for me, since I automatically searched for \n> the sequence 0x90 0xf2 0x4a 0x60 ... (which is the tail of that hash).\n> \n> But if all this sounds too confusing, I agree to delete the \n> \"(big-endian)\".\n\nIf it confused you, there should be something there. Maybe \"(in order)\" or \nsomething else implying that the underlying type is an octet sequence, \nrather than a 160-bit integer?\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"41677","messageId":"Pine.LNX.4.64.0705100015120.4167@racer.site","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705091625200.18541@iabervon.org","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-09T22:23:50Z","receivedAt":"2007-05-09T22:23:50Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 9 May 2007, Daniel Barkalow wrote:\n\n> On Wed, 9 May 2007, Johannes Schindelin wrote:\n> \n> > If you tell Git that it should look for commit e83c6516..., it will \n> > store the sha1 as 0xe8 0x3c 0x65 0x16 ... in memory, no matter which \n> > endianness the processor has.\n> \n> But it would be really weird to get 0x90 0xf2 0x4a 0x60 ... 0x16 0x65 \n> 0x3c 0xe8 unless you've got a 160-bit little-endian processor. That \n> would be as strange as having \"Test\" stored as 0x74 0x73 0x65 0x54, I \n> think.\n\nI was not aware originally, that no arithmetic is involved in SHA-1 \ncomputation.\n\nIf you store large integers, it makes tons of sense to follow the \nendianness, especially if you do _both_ boolean and integer operations on \nthem.\n\n> > Which was positively confusing for me, since I automatically searched \n> > for the sequence 0x90 0xf2 0x4a 0x60 ... (which is the tail of that \n> > hash).\n> > \n> > But if all this sounds too confusing, I agree to delete the \n> > \"(big-endian)\".\n> \n> If it confused you, there should be something there. Maybe \"(in order)\" \n> or something else implying that the underlying type is an octet \n> sequence, rather than a 160-bit integer?\n\nWell, I am convinced by now that nobody could be as stupid as me, so I \nthink it is good without such a hint :-)\n\nCiao,\nDscho\n"},{"id":"41703","messageId":"7vk5vhnwl1.fsf@assigned-by-dhcp.cox.net","threadId":"8034","inReplyTo":"20070509131801.GD14969@fieldses.org","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-10T04:15:06Z","receivedAt":"2007-05-10T04:15:06Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"J. Bruce Fields\" <bfields@fieldses.org> writes:\n\n> On Wed, May 09, 2007 at 02:19:03PM +0200, Johannes Schindelin wrote:\n>> [PATCH] user-manual: Touch ups on the birdview section\n>\n> Those all look like sensible changes to me, thanks!\n\nLikewise, except that big-endian bit I think everybody agrees on\njust dropping.\n"},{"id":"41728","messageId":"Pine.LNX.4.64.0705101233580.4167@racer.site","threadId":"8034","inReplyTo":"7vk5vhnwl1.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-10T10:36:15Z","receivedAt":"2007-05-10T10:36:15Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nIn http://thread.gmane.org/gmane.comp.version-control.git/42479,\na birdview on the source code was requested.\n\nJ. Bruce Fields suggested that my reply should be included in the\nuser manual, and there was nothing of an outcry, so here it is,\nnot 2 months later.\n\nIt includes modifications as suggested by J. Bruce Fields, Karl\nHasselström and Daniel Barkalow.\n\nSigned-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n\n---\n\n\tOn Wed, 9 May 2007, Junio C Hamano wrote:\n\n\t> \"J. Bruce Fields\" <bfields@fieldses.org> writes:\n\t>\n\t> > On Wed, May 09, 2007 at 02:19:03PM +0200, Johannes Schindelin wrote:\n\t> >> [PATCH] user-manual: Touch ups on the birdview section\n\t> >\n\t> > Those all look like sensible changes to me, thanks!\n\t>\n\t> Likewise, except that big-endian bit I think everybody agrees on\n\t> just dropping.\n\n\tAnd here it is, in its full glory, prepared in a way which \n\tappeals to the maintainers, hopefully...\n\n Documentation/user-manual.txt |  219 +++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 219 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt\nindex 13db969..3c3f1b4 100644\n--- a/Documentation/user-manual.txt\n+++ b/Documentation/user-manual.txt\n@@ -3160,6 +3160,225 @@ confusing and scary messages, but it won't actually do anything bad. In\n contrast, running \"git prune\" while somebody is actively changing the \n repository is a *BAD* idea).\n \n+[[birdview-on-the-source-code]]\n+A birdview on Git's source code\n+-----------------------------\n+\n+While Git's source code is quite elegant, it is not always easy for \n+new  developers to find their way through it.  A good idea is to look \n+at the contents of the initial commit: \n+_e83c5163316f89bfbde7d9ab23ca2e25604af290_ (also known as _v0.99~954_).\n+\n+Tip: you can see what files are in there with\n+\n+----------------------------------------------------\n+$ git show e83c5163316f89bfbde7d9ab23ca2e25604af290:\n+----------------------------------------------------\n+\n+and look at those files with something like\n+\n+-----------------------------------------------------------\n+$ git show e83c5163316f89bfbde7d9ab23ca2e25604af290:cache.h\n+-----------------------------------------------------------\n+\n+Be sure to read the README in that revision _after_ you are familiar with \n+the terminology (<<glossary>>), since the terminology has changed a little \n+since then.  For example, we call the things \"commits\" now, which are \n+described in that README as \"changesets\".\n+\n+Actually a lot of the structure as it is now can be explained by that \n+initial commit.\n+\n+For example, we do not call it \"cache\" any more, but \"index\", however, the \n+file is still called `cache.h`.  Remark: Not much reason to change it now, \n+especially since there is no good single name for it anyway, because it is \n+basically _the_ header file which is included by _all_ of Git's C sources.\n+\n+If you grasp the ideas in that initial commit (it is really small and you \n+can get into it really fast, and it will help you recognize things in the \n+much larger code base we have now), you should go on skimming `cache.h`, \n+`object.h` and `commit.h` in the current version.\n+\n+In the early days, Git (in the tradition of UNIX) was a bunch of programs \n+which were extremely simple, and which you used in scripts, piping the \n+output of one into another. This turned out to be good for initial \n+development, since it was easier to test new things.  However, recently \n+many of these parts have become builtins, and some of the core has been \n+\"libified\", i.e. put into libgit.a for performance, portability reasons, \n+and to avoid code duplication.\n+\n+By now, you know what the index is (and find the corresponding data \n+structures in `cache.h`), and that there are just a couple of object types \n+(blobs, trees, commits and tags) which inherit their common structure from \n+`struct object`, which is their first member (and thus, you can cast e.g. \n+`(struct object *)commit` to achieve the _same_ as `&commit->object`, i.e. \n+get at the object name and flags).\n+\n+Now is a good point to take a break to let this information sink in.\n+\n+Next step: get familiar with the object naming.  Read <<naming-commits>>.\n+There are quite a few ways to name an object (and not only revisions!).  \n+All of these are handled in `sha1_name.c`. Just have a quick look at \n+the function `get_sha1()`. A lot of the special handling is done by \n+functions like `get_sha1_basic()` or the likes.\n+\n+This is just to get you into the groove for the most libified part of Git: \n+the revision walker.\n+\n+Basically, the initial version of `git log` was a shell script:\n+\n+----------------------------------------------------------------\n+$ git-rev-list --pretty $(git-rev-parse --default HEAD \"$@\") | \\\n+\tLESS=-S ${PAGER:-less}\n+----------------------------------------------------------------\n+\n+What does this mean?\n+\n+`git-rev-list` is the original version of the revision walker, which \n+_always_ printed a list of revisions to stdout.  It is still functional, \n+and needs to, since most new Git programs start out as scripts using \n+`git-rev-list`.\n+\n+`git-rev-parse` is not as important any more; it was only used to filter out \n+options that were relevant for the different plumbing commands that were \n+called by the script.\n+\n+Most of what `git-rev-list` did is contained in `revision.c` and \n+`revision.h`.  It wraps the options in a struct named `rev_info`, which \n+controls how and what revisions are walked, and more.\n+\n+The original job of `git-rev-parse` is now taken by the function \n+`setup_revisions()`, which parses the revisions and the common command line \n+options for the revision walker. This information is stored in the struct \n+`rev_info` for later consumption. You can do your own command line option\n+parsing after calling `setup_revisions()`. After that, you have to call \n+`prepare_revision_walk()` for initialization, and then you can get the \n+commits one by one with the function `get_revision()`.\n+\n+If you are interested in more details of the revision walking process, \n+just have a look at the first implementation of `cmd_log()`; call\n+`git-show v1.3.0~155^2~4` and scroll down to that function (note that you \n+no longer need to call `setup_pager()` directly).\n+\n+Nowadays, `git log` is a builtin, which means that it is _contained_ in the \n+command `git`.  The source side of a builtin is\n+\n+- a function called `cmd_<bla>`, typically defined in `builtin-<bla>.c`, \n+  and declared in `builtin.h`,\n+\n+- an entry in the `commands[]` array in `git.c`, and\n+\n+- an entry in `BUILTIN_OBJECTS` in the `Makefile`.\n+\n+Sometimes, more than one builtin is contained in one source file.  For \n+example, `cmd_whatchanged()` and `cmd_log()` both reside in `builtin-log.c`, \n+since they share quite a bit of code.  In that case, the commands which are \n+_not_ named like the `.c` file in which they live have to be listed in \n+`BUILT_INS` in the `Makefile`.\n+\n+`git log` looks more complicated in C than it does in the original script, \n+but that allows for a much greater flexibility and performance.\n+\n+Here again it is a good point to take a pause.\n+\n+Lesson three is: study the code.  Really, it is the best way to learn about \n+the organization of Git (after you know the basic concepts).\n+\n+So, think about something which you are interested in, say, \"how can I \n+access a blob just knowing the object name of it?\".  The first step is to \n+find a Git command with which you can do it.  In this example, it is either \n+`git show` or `git cat-file`.\n+\n+For the sake of clarity, let's stay with `git cat-file`, because it\n+\n+- is plumbing, and\n+\n+- was around even in the initial commit (it literally went only through \n+  some 20 revisions as `cat-file.c`, was renamed to `builtin-cat-file.c` \n+  when made a builtin, and then saw less than 10 versions).\n+\n+So, look into `builtin-cat-file.c`, search for `cmd_cat_file()` and look what \n+it does.\n+\n+------------------------------------------------------------------\n+        git_config(git_default_config);\n+        if (argc != 3)\n+                usage(\"git-cat-file [-t|-s|-e|-p|<type>] <sha1>\");\n+        if (get_sha1(argv[2], sha1))\n+                die(\"Not a valid object name %s\", argv[2]);\n+------------------------------------------------------------------\n+\n+Let's skip over the obvious details; the only really interesting part \n+here is the call to `get_sha1()`.  It tries to interpret `argv[2]` as an \n+object name, and if it refers to an object which is present in the current \n+repository, it writes the resulting SHA-1 into the variable `sha1`.\n+\n+Two things are interesting here:\n+\n+- `get_sha1()` returns 0 on _success_.  This might surprise some new \n+  Git hackers, but there is a long tradition in UNIX to return different \n+  negative numbers in case of different errors -- and 0 on success.\n+\n+- the variable `sha1` in the function signature of `get_sha1()` is `unsigned \n+  char *`, but is actually expected to be a pointer to `unsigned \n+  char[20]`.  This variable will contain the 160-bit SHA-1 of the given \n+  commit.  Note that whenever a SHA-1 is passed as \"unsigned char *\", it \n+  is the binary representation, as opposed to the ASCII representation in \n+  hex characters, which is passed as \"char *\".\n+\n+You will see both of these things throughout the code.\n+\n+Now, for the meat:\n+\n+-----------------------------------------------------------------------------\n+        case 0:\n+                buf = read_object_with_reference(sha1, argv[1], &size, NULL);\n+-----------------------------------------------------------------------------\n+\n+This is how you read a blob (actually, not only a blob, but any type of \n+object).  To know how the function `read_object_with_reference()` actually \n+works, find the source code for it (something like `git grep \n+read_object_with | grep \":[a-z]\"` in the git repository), and read \n+the source.\n+\n+To find out how the result can be used, just read on in `cmd_cat_file()`:\n+\n+-----------------------------------\n+        write_or_die(1, buf, size);\n+-----------------------------------\n+\n+Sometimes, you do not know where to look for a feature.  In many such cases, \n+it helps to search through the output of `git log`, and then `git show` the \n+corresponding commit.\n+\n+Example: If you know that there was some test case for `git bundle`, but \n+do not remember where it was (yes, you _could_ `git grep bundle t/`, but that \n+does not illustrate the point!):\n+\n+------------------------\n+$ git log --no-merges t/\n+------------------------\n+\n+In the pager (`less`), just search for \"bundle\", go a few lines back, \n+and see that it is in commit 18449ab0...  Now just copy this object name, \n+and paste it into the command line\n+\n+-------------------\n+$ git show 18449ab0\n+-------------------\n+\n+Voila.\n+\n+Another example: Find out what to do in order to make some script a \n+builtin:\n+\n+-------------------------------------------------\n+$ git log --no-merges --diff-filter=A builtin-*.c\n+-------------------------------------------------\n+\n+You see, Git is actually the best tool to find out about the source of Git \n+itself!\n+\n [[glossary]]\n include::glossary.txt[]\n "},{"id":"41769","messageId":"20070510200155.GB10353@diana.vm.bytemark.co.uk","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705100015120.4167@racer.site","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-05-10T20:01:55Z","receivedAt":"2007-05-10T20:01:55Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-05-10 00:23:50 +0200, Johannes Schindelin wrote:\n\n> I was not aware originally, that no arithmetic is involved in SHA-1\n> computation.\n>\n> If you store large integers, it makes tons of sense to follow the\n> endianness, especially if you do _both_ boolean and integer\n> operations on them.\n\nActually, if you take a look at\n\n  http://en.wikipedia.org/wiki/Sha1#SHA-1_algorithm\n\nyou'll see that in addition to an unholy mess of bitwise operations,\nit does do some additions, on 32-bit big-endian words according to the\narticle.\n\nBut thinking of them as addition gives you the wrong mental picture;\nthey're simply one of many ways for a standard processor to mix bits\nefficiently as far as SHA-1 is concerned. The algorithm is specified\nas yielding a 160-bit binary blob, and can and should be thought of as\na black NSA-certified box with \"warranty void if this seal is broken\"\nstickers. (Unless you're the one implementing it, of course. But then\nyou know what you're doing.)\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"41773","messageId":"7vtzukif5t.fsf@assigned-by-dhcp.cox.net","threadId":"8034","inReplyTo":"Pine.LNX.4.64.0705101233580.4167@racer.site","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-10T20:42:38Z","receivedAt":"2007-05-10T20:42:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt\n> index 13db969..3c3f1b4 100644\n> --- a/Documentation/user-manual.txt\n> +++ b/Documentation/user-manual.txt\n> @@ -3160,6 +3160,225 @@ confusing and scary messages, but it won't actually do anything bad. In\n>  contrast, running \"git prune\" while somebody is actively changing the \n>  repository is a *BAD* idea).\n>  \n> +[[birdview-on-the-source-code]]\n> +A birdview on Git's source code\n> +-----------------------------\n\nPerhaps two dashes too short here...\n\n> +\n> +While Git's source code is quite elegant, it is not always easy for \n> +new  developers to find their way through it.  A good idea is to look \n> +at the contents of the initial commit: \n> +_e83c5163316f89bfbde7d9ab23ca2e25604af290_ (also known as _v0.99~954_).\n\nI am not sure we would need to say \"is quite elegant\".  Why\ndon't we be blunt and say \"It is not always easy for ...\".  That\nholds true for any project of nontrivial size.  I would rewrite\nthe first part like this.\n\n\tIt is not always easy for new developers to find their\n\tway through Git's source code.  This section gives you a\n\tgentle guidance to show where to start.\n\n\tA good place to start is to look at the contents of the\n\tinitial commit, with this command:\n\n\t----------------------------------------------------------------\n        $ git checkout e83c516\n        ----------------------------------------------------------------\n\nand would not bore users with v0.99~954 or \"git show\" details.\n\"git show\" to inspect one file at a time is not a good way to\nget the feel of unknown set of source files, even though it is\nvery handy once you know where things were.  And then continue\non to this part...\n\n> +Be sure to read the README in that revision _after_ you are familiar with \n> +the terminology (<<glossary>>), since the terminology has changed a little \n> +since then.  For example, we call the things \"commits\" now, which are \n> +described in that README as \"changesets\".\n> +\n> +Actually a lot of the structure as it is now can be explained by that \n> +initial commit.\n\nIt is also worth to point out that the initial revision, while\nlaying the foundation of almost every important factor of git we\nhave today, is small enough for reading everything in one\nsitting, probably upfront, instead of making it a parenthesized\ncomment in a later paragraph.  If somebody wants to dive into\ngit development to take a source-code tour, it is not really \"it\nwill help you\", but is a small enough required investment of\ntime.\n\n> +For example, we do not call it \"cache\" any more, but \"index\", however, the \n> +file is still called `cache.h`.  Remark: Not much reason to change it now, \n> +especially since there is no good single name for it anyway, because it is \n> +basically _the_ header file which is included by _all_ of Git's C sources.\n> +\n> +If you grasp the ideas in that initial commit (it is really small and you \n> +can get into it really fast, and it will help you recognize things in the \n> +much larger code base we have now), you should go on skimming `cache.h`, \n> +`object.h` and `commit.h` in the current version.\n\nOther than that, I think this is well written, and if everybody\nthinks it should be in the user's manual, I am fine with it.\n\nBy the way, when I sent the outline of hacker's manual as a\nfollow-up to the discussion, I think I forgot to properly say\nthis, so here it is: Thanks for starting the bird's eye view.\n"},{"id":"41775","messageId":"20070510211423.GA12366@diana.vm.bytemark.co.uk","threadId":"8034","inReplyTo":"7vtzukif5t.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add a birdview-on-the-source-code section to the user manual","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-05-10T21:14:23Z","receivedAt":"2007-05-10T21:14:23Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-05-10 13:42:38 -0700, Junio C Hamano wrote:\n\n> Other than that, I think this is well written, and if everybody\n> thinks it should be in the user's manual, I am fine with it.\n\nOne \"hacking howto\" chapter at the end of the user's manual seems\nperfectly fine to me too. We'll just have to remember to split it out\ninto a manual of its own if it grows too large for one chapter.\n\nIt's the potted plant strategy. :-)\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"}]}