* [ANNOUNCE] GIT 1.5.0-rc3 @ 2007-02-01 0:26 Junio C Hamano 2007-02-01 16:51 ` Bill Lear ` (2 more replies) 0 siblings, 3 replies; 14+ messages in thread From: Junio C Hamano @ 2007-02-01 0:26 UTC (permalink / raw) To: git; +Cc: linux-kernel It's been a week and a half, and here comes the -rc3 http://www.kernel.org/pub/software/scm/git/ git-1.5.0-rc3.tar.{gz,bz2} (tarball) git-htmldocs-1.5.0-rc3.tar.{gz,bz2} (preformatted docs) git-manpages-1.5.0-rc3.tar.{gz,bz2} (preformatted docs) testing/git-*-1.5.0-rc3-1.$arch.rpm (RPM) Hopefully this will be the last -rc before the final 1.5.0. This contains the "git user's manual" by J. Bruce Fields. While it still has its own "To Do" section, it has already been in a very good shape for some time, giving information with coherence and guiding a new user in a carefully chosen order of topics into much more pleasant git experience than before. ---------------------------------------------------------------- Changes since v1.5.0-rc2 are as follows: Alex Riesen (5): Insert ACTIVESTATE_STRING in Git.pm Force Activestate Perl to tie git command pipe handle to a handle class Cleanup uninitialized value in chomp Allow default core.logallrefupdates to be overridden with template's config Fix git-update-index to work with relative pathnames. Alexandre Julliard (1): vc-git.el: Take into account the destination name in vc-checkout. Andy Parkins (5): New files in git weren't being downloaded during CVS update If abbrev is set to zero in git-describe, don't add the unique suffix Allow the tag signing key to be specified in the config file UNIX reference time of 1970-01-01 00:00 is UTC timezone, not local time zone Heavily expanded update hook to send more useful emails than the old hook Aneesh Kumar K.V (2): blameview: Use git-cat-file to read the file content. Update git-cat-file documentation Bill Lear (1): Document --check option to git diff. David Kågedal (1): Improved error message from git-rebase Eric Wong (1): git-svn: remove leading slash when printing removed directories J. Bruce Fields (31): Documentation: add git user's manual Documentation: expand preface and todo's Documentation: git-rebase discussion, miscellaneous user-manual updates Documentation: more user-manual todo's Documentation: reorder development section, todo's Documentation: begin discussion of git-remote in user manual Documentation: rev-list -> rev-parse, other typos, start examples user manual: answer some comments from Junio user-manual: replace init-db by init user-manual: reindent user-manual: rewrap, fix heading levels user-manual: add "quick start" as chapter 1 user-manual: minor quickstart reorganization user-manual: clarify difference between tag and branch user-manual: update references discussion user-manual: update git-gc discussion user-manual: stub discussion of fsck and reflog user-manual: reorganize fetch discussion, add internals, etc. user-manual: git-fsck, dangling objects user-manual: fsck-objects -> fsck user-manual: repo-config -> config user-manual: add references to git-config man page user-manual: typo fix user-manual: fix a header level user-manual: reflogs, other recovery user-manual: rewrap a few long lines user-manual: minor "TODO" updates user-manual: document git-show-branch example user-manual: SHA1 -> object name user-manual: point to README for gitweb information user-manual: todo's Jakub Narebski (3): Documentation/config.txt: Document config file syntax better t/t1300-repo-config.sh: value continued on next line Documentation/config.txt: Correct info about subsection name Jason Riedy (1): Use inttypes.h rather than stdint.h. Jeff King (4): format-patch: fix bug with --stdout in a subdirectory contrib/vim: update syntax for changed commit template diffcore-pickaxe: fix infinite loop on zero-length needle Add a sample program 'blameview' to show how to use git-blame --incremental Johannes Schindelin (2): annotate: use pager reflog inspection: introduce shortcut "-g" Johannes Sixt (1): Add a missing fork() error check. Junio C Hamano (43): User manual: fix typos in examples Documentation/tutorial-2: Fix interesting typo in an example. Revert "prune: --grace=time" Make sure git_connect() always give two file descriptors. is_repository_shallow(): prototype fix. shallow repository: disable unsupported operations for now. git-gc: do not run git-prune by default. cvsimport: activate -a option, really. .mailmap: fix screw-ups in Uwe's name honor --author even with --amend, -C, and -c. reflog gc: a tag that does not point at a commit is not a crime. git-checkout -m: fix merge case git-daemon documentation on enabling services. ls-remote and clone: accept --upload-pack=<path> as well. Refactor the pack header reading function out of receive-pack.c Allow fetch-pack to decide keeping the fetched pack without exploding fetch-pack: remove --keep-auto and make it the default. Consolidate {receive,fetch}.unpackLimit Allow non-developer to clone, checkout and fetch more easily. parse-remote: do not barf on a remote shorthand without any refs to fetch. show-branch -g: default to HEAD Documentation: pack-refs --all vs default behaviour Make sure we do not write bogus reflog entries. git-merge: leave sensible reflog message when used as the first level UI. create_symref: check error return from open(). write_in_full: size_t is unsigned. Don't force everybody to call setup_ident(). git-blame --porcelain: quote filename in c-style when needed. Update describe documentation. Document 'git-blame --incremental' git-fsck-objects is now synonym to git-fsck Two small typofixes. lock_any_ref_for_update(): do not accept malformatted refs. git-commit -s: no extra space when sign-offs appear at the end already. git-blame: somewhat better commenting. git-send-email: remove debugging output. Fix git-tag -u Documentation: "git-checkout <tree> <path>" takes any tree-ish t9200: Re-code non-ascii path test in UTF-8 t9200: do not test -x bit if the filesystem does not support it. git main documentation: point at the user's manual. Do not use hardcoded path to xhmtl.xsl to generate user's manual GIT v1.5.0-rc3 Linus Torvalds (5): fsck-objects: refactor checking for connectivity Fix seriously broken "git pack-refs" Add dangling objects tips. git-blame --incremental git-push through git protocol Mark Wooding (3): wt-status: Actually accept `color.status.BLAH' configuration variables. Documentation/config.txt: Fix documentation of colour config tweaks. Make fsck and fsck-objects be builtins. Nicolas Pitre (3): fix suggested branch creation command when detaching head git-log -g --pretty=oneline should display the reflog message tone down the detached head warning Peter Eriksen (2): sha1_file.c: Avoid multiple calls to find_pack_entry(). Documentation: --amend cannot be combined with -c/-C/-F. René Scharfe (1): git-blame --incremental: don't use pager Sam Vilain (1): contrib/emacs/vc-git.el: support vc-version-other-window Santi Béjar (1): git-fetch: Allow fetching the remote HEAD Shawn O. Pearce (6): Remove unnecessary found variable from describe. Teach git-describe to display distances from tags. Compute accurate distances in git-describe before output. Teach for-each-ref about a little language called Tcl. Don't coredump on bad refs in update-server-info. Escape --upload-pack from expr. Simon 'corecode' Schubert (1): Replace perl code with pure shell code Tom Prince (1): Rename git-repo-config to git-config. Uwe Kleine-König (2): rename --exec to --upload-pack for fetch-pack and peek-remote make --upload-pack option to git-fetch configurable ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [ANNOUNCE] GIT 1.5.0-rc3 2007-02-01 0:26 [ANNOUNCE] GIT 1.5.0-rc3 Junio C Hamano @ 2007-02-01 16:51 ` Bill Lear 2007-02-01 20:34 ` Robin Rosenberg 2007-02-04 9:36 ` What's in git.git (stable) Junio C Hamano 2 siblings, 0 replies; 14+ messages in thread From: Bill Lear @ 2007-02-01 16:51 UTC (permalink / raw) To: Junio C Hamano; +Cc: git, linux-kernel On Wednesday, January 31, 2007 at 16:26:36 (-0800) Junio C Hamano writes: >It's been a week and a half, and here comes the -rc3 > > http://www.kernel.org/pub/software/scm/git/ > > git-1.5.0-rc3.tar.{gz,bz2} (tarball) > git-htmldocs-1.5.0-rc3.tar.{gz,bz2} (preformatted docs) > git-manpages-1.5.0-rc3.tar.{gz,bz2} (preformatted docs) > testing/git-*-1.5.0-rc3-1.$arch.rpm (RPM) There are no such files .*1.5.0-rc3.* on this server. However, there are .*1.5.0.rc3.* files. Bill ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [ANNOUNCE] GIT 1.5.0-rc3 2007-02-01 0:26 [ANNOUNCE] GIT 1.5.0-rc3 Junio C Hamano 2007-02-01 16:51 ` Bill Lear @ 2007-02-01 20:34 ` Robin Rosenberg 2007-02-04 9:36 ` What's in git.git (stable) Junio C Hamano 2 siblings, 0 replies; 14+ messages in thread From: Robin Rosenberg @ 2007-02-01 20:34 UTC (permalink / raw) To: Junio C Hamano; +Cc: git torsdag 01 februari 2007 01:26 skrev Junio C Hamano: > Junio C Hamano (43): > t9200: Re-code non-ascii path test in UTF-8 I sent a patch that converts to "visible" characters when looked at with iso-8859-1/windows-1252 googles. It also tests the file system before executing the test. > t9200: do not test -x bit if the filesystem does not support it. The description is misleading. Git on cygwin chooses to ignore the executable flag by default, not because the filesystem won't handle it, but rather that enough many *other* applications sets it needlessly, that ignoring it becomes less problematic than honouring it. Adding "git config core.filemode true" at the start of this test verifiies that it works on NTFS too. -- robin ^ permalink raw reply [flat|nested] 14+ messages in thread
* What's in git.git (stable) 2007-02-01 0:26 [ANNOUNCE] GIT 1.5.0-rc3 Junio C Hamano 2007-02-01 16:51 ` Bill Lear 2007-02-01 20:34 ` Robin Rosenberg @ 2007-02-04 9:36 ` Junio C Hamano 2007-02-04 18:51 ` Jeff King 2007-02-06 7:40 ` Quick status updates Junio C Hamano 2 siblings, 2 replies; 14+ messages in thread From: Junio C Hamano @ 2007-02-04 9:36 UTC (permalink / raw) To: git Thanks everybody for helping to tie the loose ends for the next release. Thanks to Nico's handful updates, I think his "reflog on HEAD itself" series is ready for inclusion, although tonight's update still has it parked in 'next' (I did try out 'next' with his latest for a couple of hours today). I've already updated the draft release notes for 1.5.0 (v1.5.0.txt in todo branch), with its inclusion in mind. I've re-read the three tutorials and tried to fix them up somewhat to match the recent reality. I'd appreciate somebody can look at JBF's user manual. Several things to note (in the following, substitute $gmane with http://article.gmane.org/gmane.comp.version-control.git): - Working around Tk geometry problem, especially on non Linux+X platforms. I've forwarded Mark Levedahl's patches ($gmane/38361) to Paul Mackerras for his blessing; hopefully he can Ack and/or suggest improvements. I'd really like to have them in 1.5.0 in some form. - Nico's "reflog on HEAD". I'll merge this tomorrow (I just ran out of time today). I will re-try to break its "git reflog expire --stale-fix --all" before actually merging it, though. - Reverting the patch to allow tracking branch names as the value of branch.*.merge ($gmane/38621). I think it is a good idea to revert this before 1.5.0 gets out; just haven't got around to do so. - Teaching "git blame" to also use the working tree files and/or index. I actually think defaulting to working tree when an explicit HEAD is not given (and --cached to use the one in the index) makes a lot of sense, but I haven't got around to code the latter yet. Not defaulting to HEAD changes semantics, so if we ever are going to do it, I think we should do so before 1.5.0. - Preventing push from updating the current branch of non-bare repository. I think doing so unconditionally is a bad idea (and I have Linus's veto to back it up $gmane/38592), but I suspect most people would want the default to be less confusing to new people. If we are ever going to forbid by default and allow pusher to force, that would be a behaviour change and it would be better to do so before 1.5.0. - We might want to allow git-push to use the wildcard refspec, like git-fetch does, for symmetry. It would make the mothership-satellite arrangement much more natural ($gname/38549). Unfortunately I haven't had a chance to start coding it. I think however this could be added post 1.5.0. - "git remote add -t -f -m" and rewrite of "git clone" based on it ($gmane/38470, $gmane/38545). While I think this leads us in right direction, I do not think 1.5.0 needs to wait for it. Certainly I do not want to reimplement "git clone" before 1.5.0, although I think the additions to "git remote add" are relatively safe. - Catering to filesystems whose readdir() returns pathnames that are different from what are used when they were creat()ed will not happen ($gmane/38620). * The 'master' branch has these since v1.5.0-rc3. Andy Parkins (1): doc: hooks.txt said post-commit default sends an email, it doesn't Eric Wong (2): git-svn: do not let Git.pm warn if we prematurely close pipes Disallow invalid --pretty= abbreviations Johannes Schindelin (2): Teach the '@{...}' notation to git-log -g Update the documentation for the new '@{...}' syntax Junio C Hamano (9): detached HEAD -- finishing touches Use "git checkout -q" in git-bisect Tutorial: fix asciidoc formatting of "git add" section. Tutorial-2: Adjust git-status output to recent reality. core-tutorial: http reference link fix fix reflog entries for "git-branch" honor GIT_REFLOG_ACTION in git-commit Why is it bad to rewind a branch that has already been pushed out? combine-diff: special case --unified=0 Mike Coleman (1): Fix some documentation typos and grammar Nicolas Pitre (4): reword the detached head message a little again add a quiet option to git-checkout prevent HEAD reflog to be interpreted as current branch reflog provide a nice @{...} syntax to always mean the current branch reflog Pavel Roskin (2): git-config --rename-section could rename wrong section Assorted typo fixes Shawn O. Pearce (18): Pull out remote listing functions in git-remote. Teach 'git remote' how to cleanup stale tracking branches. Cleanup prepare_packed_git_one to reuse install_packed_git. Correct comment in prepare_packed_git_one. Refactor open_packed_git to return an error code. Don't find objects in packs which aren't available anymore. Don't leak file descriptors from unavailable pack files. Cleanup subcommand documentation for git-remote. Keep untracked files not involved in a merge. Default GIT_MERGE_VERBOSITY to 5 during tests. bash: Remove short option completions for branch/checkout/diff. bash: Classify cat-file and reflog as plumbing. bash: Complete long options to git-add. bash: Add space after unique command name is completed. bash: Classify more commends out of completion. bash: Support unique completion on git-config. bash: Support unique completion when possible. bash: Support internal revlist options better. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: What's in git.git (stable) 2007-02-04 9:36 ` What's in git.git (stable) Junio C Hamano @ 2007-02-04 18:51 ` Jeff King 2007-02-04 19:12 ` Linus Torvalds 2007-02-06 7:40 ` Quick status updates Junio C Hamano 1 sibling, 1 reply; 14+ messages in thread From: Jeff King @ 2007-02-04 18:51 UTC (permalink / raw) To: Junio C Hamano; +Cc: git On Sun, Feb 04, 2007 at 01:36:29AM -0800, Junio C Hamano wrote: > - Teaching "git blame" to also use the working tree files > and/or index. I actually think defaulting to working tree > when an explicit HEAD is not given (and --cached to use the > one in the index) makes a lot of sense, but I haven't got > around to code the latter yet. Not defaulting to HEAD > changes semantics, so if we ever are going to do it, I think > we should do so before 1.5.0. Just a thought, but it might be useful to blame the contents of an arbitrary file (but starting the history at a given pathname). Something like "git blame --contents /tmp/foo.c file.c", with contents defaulting to "file.c". There's much discussion of editor interfaces, and this leaves the possibility of git-blaming the contents of the editor buffer (after writing it out to a temp file) without having to save changes to the working tree file. Admittedly, I think this will be rare, but if you git-blame from an editor, it seems awkward to either be inaccurate (by blaming the last saved working tree file, but comparing it to the buffer) or to save the file as a side effect. -Peff ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: What's in git.git (stable) 2007-02-04 18:51 ` Jeff King @ 2007-02-04 19:12 ` Linus Torvalds 2007-02-04 20:58 ` Theodore Tso 0 siblings, 1 reply; 14+ messages in thread From: Linus Torvalds @ 2007-02-04 19:12 UTC (permalink / raw) To: Jeff King; +Cc: Junio C Hamano, git On Sun, 4 Feb 2007, Jeff King wrote: > > Just a thought, but it might be useful to blame the contents of an > arbitrary file (but starting the history at a given pathname). Something > like "git blame --contents /tmp/foo.c file.c", with contents defaulting > to "file.c". There's much discussion of editor interfaces, and this > leaves the possibility of git-blaming the contents of the editor buffer > (after writing it out to a temp file) without having to save changes to > the working tree file. I agree, that probably would make most sense. If we do this at all. On the other hand, I suspect that most editors would probably want to pipe the contents to the program, not write it to a temp-file. (I think it's a worthy feature, but Junio's patch wasn't exactly pretty, so the question boils down to whether it's really worth it). Linus ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: What's in git.git (stable) 2007-02-04 19:12 ` Linus Torvalds @ 2007-02-04 20:58 ` Theodore Tso 2007-02-04 21:34 ` Jakub Narebski ` (2 more replies) 0 siblings, 3 replies; 14+ messages in thread From: Theodore Tso @ 2007-02-04 20:58 UTC (permalink / raw) To: Linus Torvalds; +Cc: Jeff King, Junio C Hamano, git On Sun, Feb 04, 2007 at 11:12:34AM -0800, Linus Torvalds wrote: > > > On Sun, 4 Feb 2007, Jeff King wrote: > > > > Just a thought, but it might be useful to blame the contents of an > > arbitrary file (but starting the history at a given pathname). Something > > like "git blame --contents /tmp/foo.c file.c", with contents defaulting > > to "file.c". There's much discussion of editor interfaces, and this > > leaves the possibility of git-blaming the contents of the editor buffer > > (after writing it out to a temp file) without having to save changes to > > the working tree file. > > I agree, that probably would make most sense. If we do this at all. On the > other hand, I suspect that most editors would probably want to pipe the > contents to the program, not write it to a temp-file. ... and use it with --incremental, as well. In emacs you can have the annotation take place as it is being written out relatively easily, by arranging to have a callback function get called each time more information is handed back to emacs via a pipe. - Ted ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: What's in git.git (stable) 2007-02-04 20:58 ` Theodore Tso @ 2007-02-04 21:34 ` Jakub Narebski 2007-02-04 22:25 ` David Kågedal 2007-02-05 3:00 ` [PATCH 1/2] Rename get_ident() to fmt_ident() and make it available to outside Junio C Hamano 2007-02-05 3:00 ` [PATCH 2/2] git-blame: no rev means start from the working tree file Junio C Hamano 2 siblings, 1 reply; 14+ messages in thread From: Jakub Narebski @ 2007-02-04 21:34 UTC (permalink / raw) To: git Theodore Tso wrote: > On Sun, Feb 04, 2007 at 11:12:34AM -0800, Linus Torvalds wrote: >> On Sun, 4 Feb 2007, Jeff King wrote: >>> >>> Just a thought, but it might be useful to blame the contents of an >>> arbitrary file (but starting the history at a given pathname). Something >>> like "git blame --contents /tmp/foo.c file.c", with contents defaulting >>> to "file.c". There's much discussion of editor interfaces, and this >>> leaves the possibility of git-blaming the contents of the editor buffer >>> (after writing it out to a temp file) without having to save changes to >>> the working tree file. >> >> I agree, that probably would make most sense. If we do this at all. On the >> other hand, I suspect that most editors would probably want to pipe the >> contents to the program, not write it to a temp-file. > > ... and use it with --incremental, as well. In emacs you can have the > annotation take place as it is being written out relatively easily, by > arranging to have a callback function get called each time more > information is handed back to emacs via a pipe. So perhaps instead of "git blame --contents /tmp/foo.c file.c" we should have "cat /tmp/foo.c | git blame --stdin file.c", hmmm? Editor would then pipe current contents of the buffer to "git blame --stdin --incremental file.c" (where file.c is the name in tree/in HEAD). -- Jakub Narebski Warsaw, Poland ShadeHawk on #git ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: What's in git.git (stable) 2007-02-04 21:34 ` Jakub Narebski @ 2007-02-04 22:25 ` David Kågedal 0 siblings, 0 replies; 14+ messages in thread From: David Kågedal @ 2007-02-04 22:25 UTC (permalink / raw) To: git; +Cc: jnareb Jakub Narebski <jnareb@gmail.com> writes: > Theodore Tso wrote: >> On Sun, Feb 04, 2007 at 11:12:34AM -0800, Linus Torvalds wrote: >>> On Sun, 4 Feb 2007, Jeff King wrote: >>>> >>>> Just a thought, but it might be useful to blame the contents of an >>>> arbitrary file (but starting the history at a given pathname). Something >>>> like "git blame --contents /tmp/foo.c file.c", with contents defaulting >>>> to "file.c". There's much discussion of editor interfaces, and this >>>> leaves the possibility of git-blaming the contents of the editor buffer >>>> (after writing it out to a temp file) without having to save changes to >>>> the working tree file. >>> >>> I agree, that probably would make most sense. If we do this at all. On the >>> other hand, I suspect that most editors would probably want to pipe the >>> contents to the program, not write it to a temp-file. >> >> ... and use it with --incremental, as well. In emacs you can have the >> annotation take place as it is being written out relatively easily, by >> arranging to have a callback function get called each time more >> information is handed back to emacs via a pipe. > > So perhaps instead of "git blame --contents /tmp/foo.c file.c" we should > have "cat /tmp/foo.c | git blame --stdin file.c", hmmm? Editor would then > pipe current contents of the buffer to "git blame --stdin --incremental > file.c" (where file.c is the name in tree/in HEAD). But if we allow the standard convention of using - to mean stdin, the --contents option would be more flexible, since "--contents -" would just be a special case. -- David Kågedal ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/2] Rename get_ident() to fmt_ident() and make it available to outside 2007-02-04 20:58 ` Theodore Tso 2007-02-04 21:34 ` Jakub Narebski @ 2007-02-05 3:00 ` Junio C Hamano 2007-02-05 3:00 ` [PATCH 2/2] git-blame: no rev means start from the working tree file Junio C Hamano 2 siblings, 0 replies; 14+ messages in thread From: Junio C Hamano @ 2007-02-05 3:00 UTC (permalink / raw) To: git; +Cc: Linus Torvalds, Jeff King, Theodore Tso This makes the functionality of ident.c::get_ident() available to other callers. Signed-off-by: Junio C Hamano <junkio@cox.net> --- * This by itself is totally uninteresting, but the second one depends on it. cache.h | 1 + ident.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cache.h b/cache.h index 201704b..38a9bc0 100644 --- a/cache.h +++ b/cache.h @@ -321,6 +321,7 @@ unsigned long approxidate(const char *); extern const char *git_author_info(int); extern const char *git_committer_info(int); +extern const char *fmt_ident(const char *name, const char *email, const char *date_str, int); struct checkout { const char *base_dir; diff --git a/ident.c b/ident.c index a6fc7b5..bb03bdd 100644 --- a/ident.c +++ b/ident.c @@ -185,8 +185,8 @@ static const char *env_hint = "Add --global to set your account\'s default\n" "\n"; -static const char *get_ident(const char *name, const char *email, - const char *date_str, int error_on_no_name) +const char *fmt_ident(const char *name, const char *email, + const char *date_str, int error_on_no_name) { static char buffer[1000]; char date[50]; @@ -233,7 +233,7 @@ static const char *get_ident(const char *name, const char *email, const char *git_author_info(int error_on_no_name) { - return get_ident(getenv("GIT_AUTHOR_NAME"), + return fmt_ident(getenv("GIT_AUTHOR_NAME"), getenv("GIT_AUTHOR_EMAIL"), getenv("GIT_AUTHOR_DATE"), error_on_no_name); @@ -241,7 +241,7 @@ const char *git_author_info(int error_on_no_name) const char *git_committer_info(int error_on_no_name) { - return get_ident(getenv("GIT_COMMITTER_NAME"), + return fmt_ident(getenv("GIT_COMMITTER_NAME"), getenv("GIT_COMMITTER_EMAIL"), getenv("GIT_COMMITTER_DATE"), error_on_no_name); -- 1.5.0.rc3.40.g1f7d ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/2] git-blame: no rev means start from the working tree file. 2007-02-04 20:58 ` Theodore Tso 2007-02-04 21:34 ` Jakub Narebski 2007-02-05 3:00 ` [PATCH 1/2] Rename get_ident() to fmt_ident() and make it available to outside Junio C Hamano @ 2007-02-05 3:00 ` Junio C Hamano 2 siblings, 0 replies; 14+ messages in thread From: Junio C Hamano @ 2007-02-05 3:00 UTC (permalink / raw) To: git; +Cc: Linus Torvalds, Jeff King, Theodore Tso Warning: this changes the semantics. This makes "git blame" without any positive rev to start digging from the working tree copy, which is made into a fake commit whose sole parent is the HEAD. It also adds --contents <file> option to pretend as if the working tree copy has the contents of the named file. You can use '-' to make the command read from the standard input. If you want the command to start annotating from the HEAD commit, you need to explicitly give HEAD parameter. Signed-off-by: Junio C Hamano <junkio@cox.net> --- Theodore Tso <tytso@mit.edu> writes: > On Sun, Feb 04, 2007 at 11:12:34AM -0800, Linus Torvalds wrote: >> >> On Sun, 4 Feb 2007, Jeff King wrote: >> > >> > Just a thought, but it might be useful to blame the contents of an >> > arbitrary file (but starting the history at a given pathname). Something >> > like "git blame --contents /tmp/foo.c file.c", with contents defaulting >> > to "file.c". There's much discussion of editor interfaces, and this >> > leaves the possibility of git-blaming the contents of the editor buffer >> > (after writing it out to a temp file) without having to save changes to >> > the working tree file. >> >> I agree, that probably would make most sense. If we do this at all. On the >> other hand, I suspect that most editors would probably want to pipe the >> contents to the program, not write it to a temp-file. > > ... and use it with --incremental, as well. In emacs you can have the > annotation take place as it is being written out relatively easily, by > arranging to have a callback function get called each time more > information is handed back to emacs via a pipe. * By popular request, this is the second round of the patch. I've splitted out a small change to make ident.c::get_ident() available to this one into a separate commit, which this patch depends on. builtin-blame.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++------- diff-lib.c | 44 +++++++++++- diff.h | 1 + 3 files changed, 228 insertions(+), 26 deletions(-) diff --git a/builtin-blame.c b/builtin-blame.c index 1c21204..897323a 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -15,9 +15,10 @@ #include "revision.h" #include "quote.h" #include "xdiff-interface.h" +#include "cache-tree.h" static char blame_usage[] = -"git-blame [-c] [-l] [-t] [-f] [-n] [-p] [-L n,m] [-S <revs-file>] [-M] [-C] [-C] [commit] [--] file\n" +"git-blame [-c] [-l] [-t] [-f] [-n] [-p] [-L n,m] [-S <revs-file>] [-M] [-C] [-C] [--contents <filename>] [commit] [--] file\n" " -c, --compatibility Use the same output mode as git-annotate (Default: off)\n" " -b Show blank SHA-1 for boundary commits (Default: off)\n" " -l, --long Show long commit SHA1 (Default: off)\n" @@ -29,6 +30,7 @@ static char blame_usage[] = " -L n,m Process only line range n,m, counting from 1\n" " -M, -C Find line movements within and across files\n" " --incremental Show blame entries as we find them, incrementally\n" +" --contents file Use <file>'s contents as the final image\n" " -S revs-file Use revisions from revs-file instead of calling git-rev-list\n"; static int longest_file; @@ -333,9 +335,13 @@ static struct origin *find_origin(struct scoreboard *sb, diff_tree_setup_paths(paths, &diff_opts); if (diff_setup_done(&diff_opts) < 0) die("diff-setup"); - diff_tree_sha1(parent->tree->object.sha1, - origin->commit->tree->object.sha1, - "", &diff_opts); + + if (is_null_sha1(origin->commit->object.sha1)) + do_diff_cache(parent->tree->object.sha1, &diff_opts); + else + diff_tree_sha1(parent->tree->object.sha1, + origin->commit->tree->object.sha1, + "", &diff_opts); diffcore_std(&diff_opts); /* It is either one entry that says "modified", or "created", @@ -402,9 +408,13 @@ static struct origin *find_rename(struct scoreboard *sb, diff_tree_setup_paths(paths, &diff_opts); if (diff_setup_done(&diff_opts) < 0) die("diff-setup"); - diff_tree_sha1(parent->tree->object.sha1, - origin->commit->tree->object.sha1, - "", &diff_opts); + + if (is_null_sha1(origin->commit->object.sha1)) + do_diff_cache(parent->tree->object.sha1, &diff_opts); + else + diff_tree_sha1(parent->tree->object.sha1, + origin->commit->tree->object.sha1, + "", &diff_opts); diffcore_std(&diff_opts); for (i = 0; i < diff_queued_diff.nr; i++) { @@ -1047,9 +1057,12 @@ static int find_copy_in_parent(struct scoreboard *sb, (!porigin || strcmp(target->path, porigin->path))) diff_opts.find_copies_harder = 1; - diff_tree_sha1(parent->tree->object.sha1, - target->commit->tree->object.sha1, - "", &diff_opts); + if (is_null_sha1(target->commit->object.sha1)) + do_diff_cache(parent->tree->object.sha1, &diff_opts); + else + diff_tree_sha1(parent->tree->object.sha1, + target->commit->tree->object.sha1, + "", &diff_opts); if (!diff_opts.find_copies_harder) diffcore_std(&diff_opts); @@ -1336,9 +1349,9 @@ static void get_commit_info(struct commit *commit, tmp += 2; endp = strchr(tmp, '\n'); if (!endp) - goto error_out; + endp = tmp + strlen(tmp); len = endp - tmp; - if (len >= sizeof(summary_buf)) + if (len >= sizeof(summary_buf) || len == 0) goto error_out; memcpy(summary_buf, tmp, len); summary_buf[len] = 0; @@ -1910,6 +1923,137 @@ static int git_blame_config(const char *var, const char *value) return git_default_config(var, value); } +static struct commit *fake_working_tree_commit(const char *path, const char *contents_from) +{ + struct commit *commit; + struct origin *origin; + unsigned char head_sha1[20]; + char *buf; + const char *ident; + int fd; + time_t now; + unsigned long fin_size; + int size, len; + struct cache_entry *ce; + unsigned mode; + + if (get_sha1("HEAD", head_sha1)) + die("No such ref: HEAD"); + + time(&now); + commit = xcalloc(1, sizeof(*commit)); + commit->parents = xcalloc(1, sizeof(*commit->parents)); + commit->parents->item = lookup_commit_reference(head_sha1); + commit->object.parsed = 1; + commit->date = now; + commit->object.type = OBJ_COMMIT; + + origin = make_origin(commit, path); + + if (!contents_from || strcmp("-", contents_from)) { + struct stat st; + const char *read_from; + + if (contents_from) { + if (stat(contents_from, &st) < 0) + die("Cannot stat %s", contents_from); + read_from = contents_from; + } + else { + if (lstat(path, &st) < 0) + die("Cannot lstat %s", path); + read_from = path; + } + fin_size = st.st_size; + buf = xmalloc(fin_size+1); + mode = canon_mode(st.st_mode); + switch (st.st_mode & S_IFMT) { + case S_IFREG: + fd = open(read_from, O_RDONLY); + if (fd < 0) + die("cannot open %s", read_from); + if (read_in_full(fd, buf, fin_size) != fin_size) + die("cannot read %s", read_from); + break; + case S_IFLNK: + if (readlink(read_from, buf, fin_size+1) != fin_size) + die("cannot readlink %s", read_from); + break; + default: + die("unsupported file type %s", read_from); + } + } + else { + /* Reading from stdin */ + contents_from = "standard input"; + buf = NULL; + fin_size = 0; + mode = 0; + while (1) { + ssize_t cnt = 8192; + buf = xrealloc(buf, fin_size + cnt); + cnt = xread(0, buf + fin_size, cnt); + if (cnt < 0) + die("read error %s from stdin", + strerror(errno)); + if (!cnt) + break; + fin_size += cnt; + } + buf = xrealloc(buf, fin_size + 1); + } + buf[fin_size] = 0; + origin->file.ptr = buf; + origin->file.size = fin_size; + write_sha1_file(buf, fin_size, blob_type, origin->blob_sha1); + commit->util = origin; + + /* + * Read the current index, replace the path entry with + * origin->blob_sha1 without mucking with its mode or type + * bits; we are not going to write this index out -- we just + * want to run "diff-index --cached". + */ + discard_cache(); + read_cache(); + + len = strlen(path); + if (!mode) { + int pos = cache_name_pos(path, len); + if (0 <= pos) + mode = ntohl(active_cache[pos]->ce_mode); + else + /* Let's not bother reading from HEAD tree */ + mode = S_IFREG | 0644; + } + size = cache_entry_size(len); + ce = xcalloc(1, size); + hashcpy(ce->sha1, origin->blob_sha1); + memcpy(ce->name, path, len); + ce->ce_flags = create_ce_flags(len, 0); + ce->ce_mode = create_ce_mode(mode); + add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); + + /* + * We are not going to write this out, so this does not matter + * right now, but someday we might optimize diff-index --cached + * with cache-tree information. + */ + cache_tree_invalidate_path(active_cache_tree, path); + + commit->buffer = xmalloc(400); + ident = fmt_ident("Not Committed Yet", "not.committed.yet", NULL, 0); + sprintf(commit->buffer, + "tree 0000000000000000000000000000000000000000\n" + "parent %s\n" + "author %s\n" + "committer %s\n\n" + "Version of %s from %s\n", + sha1_to_hex(head_sha1), + ident, ident, path, contents_from ? contents_from : path); + return commit; +} + int cmd_blame(int argc, const char **argv, const char *prefix) { struct rev_info revs; @@ -1924,6 +2068,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) const char *final_commit_name = NULL; char type[10]; const char *bottomtop = NULL; + const char *contents_from = NULL; git_config(git_blame_config); save_commit_buffer = 0; @@ -1968,6 +2113,11 @@ int cmd_blame(int argc, const char **argv, const char *prefix) die("More than one '-L n,m' option given"); bottomtop = arg; } + else if (!strcmp("--contents", arg)) { + if (++i >= argc) + usage(blame_usage); + contents_from = argv[i]; + } else if (!strcmp("--incremental", arg)) incremental = 1; else if (!strcmp("--score-debug", arg)) @@ -2087,7 +2237,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) argv[unk] = NULL; init_revisions(&revs, NULL); - setup_revisions(unk, argv, &revs, "HEAD"); + setup_revisions(unk, argv, &revs, NULL); memset(&sb, 0, sizeof(sb)); /* @@ -2114,16 +2264,14 @@ int cmd_blame(int argc, const char **argv, const char *prefix) if (!sb.final) { /* * "--not A B -- path" without anything positive; - * default to HEAD. + * do not default to HEAD, but use the working tree + * or "--contents". */ - unsigned char head_sha1[20]; - - final_commit_name = "HEAD"; - if (get_sha1(final_commit_name, head_sha1)) - die("No such ref: HEAD"); - sb.final = lookup_commit_reference(head_sha1); - add_pending_object(&revs, &(sb.final->object), "HEAD"); + sb.final = fake_working_tree_commit(path, contents_from); + add_pending_object(&revs, &(sb.final->object), ":"); } + else if (contents_from) + die("Cannot use --contents with final commit object name"); /* * If we have bottom, this will mark the ancestors of the @@ -2132,11 +2280,22 @@ int cmd_blame(int argc, const char **argv, const char *prefix) */ prepare_revision_walk(&revs); - o = get_origin(&sb, sb.final, path); - if (fill_blob_sha1(o)) - die("no such path %s in %s", path, final_commit_name); + if (is_null_sha1(sb.final->object.sha1)) { + char *buf; + o = sb.final->util; + buf = xmalloc(o->file.size + 1); + memcpy(buf, o->file.ptr, o->file.size + 1); + sb.final_buf = buf; + sb.final_buf_size = o->file.size; + } + else { + o = get_origin(&sb, sb.final, path); + if (fill_blob_sha1(o)) + die("no such path %s in %s", path, final_commit_name); - sb.final_buf = read_sha1_file(o->blob_sha1, type, &sb.final_buf_size); + sb.final_buf = read_sha1_file(o->blob_sha1, type, + &sb.final_buf_size); + } num_read_blob++; lno = prepare_lines(&sb); diff --git a/diff-lib.c b/diff-lib.c index 2c9be60..91cd877 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -7,6 +7,7 @@ #include "diff.h" #include "diffcore.h" #include "revision.h" +#include "cache-tree.h" /* * diff-files @@ -271,7 +272,7 @@ static int diff_cache(struct rev_info *revs, break; } /* Show difference between old and new */ - show_modified(revs,ac[1], ce, 1, + show_modified(revs, ac[1], ce, 1, cached, match_missing); break; case 1: @@ -372,3 +373,44 @@ int run_diff_index(struct rev_info *revs, int cached) diff_flush(&revs->diffopt); return ret; } + +int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) +{ + struct tree *tree; + struct rev_info revs; + int i; + struct cache_entry **dst; + struct cache_entry *last = NULL; + + /* + * This is used by git-blame to run diff-cache internally; + * it potentially needs to repeatedly run this, so we will + * start by removing the higher order entries the last round + * left behind. + */ + dst = active_cache; + for (i = 0; i < active_nr; i++) { + struct cache_entry *ce = active_cache[i]; + if (ce_stage(ce)) { + if (last && !strcmp(ce->name, last->name)) + continue; + cache_tree_invalidate_path(active_cache_tree, + ce->name); + last = ce; + ce->ce_mode = 0; + ce->ce_flags &= ~htons(CE_STAGEMASK); + } + *dst++ = ce; + } + active_nr = dst - active_cache; + + init_revisions(&revs, NULL); + revs.prune_data = opt->paths; + tree = parse_tree_indirect(tree_sha1); + if (!tree) + die("bad tree object %s", sha1_to_hex(tree_sha1)); + if (read_tree(tree, 1, opt->paths)) + return error("unable to read tree %s", sha1_to_hex(tree_sha1)); + return diff_cache(&revs, active_cache, active_nr, revs.prune_data, + 1, 0); +} diff --git a/diff.h b/diff.h index 7a347cf..eece65d 100644 --- a/diff.h +++ b/diff.h @@ -222,6 +222,7 @@ extern int run_diff_files(struct rev_info *revs, int silent_on_removed); extern int run_diff_index(struct rev_info *revs, int cached); +extern int do_diff_cache(const unsigned char *, struct diff_options *); extern int diff_flush_patch_id(struct diff_options *, unsigned char *); #endif /* DIFF_H */ -- 1.5.0.rc3.40.g1f7d ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Quick status updates 2007-02-04 9:36 ` What's in git.git (stable) Junio C Hamano 2007-02-04 18:51 ` Jeff King @ 2007-02-06 7:40 ` Junio C Hamano 2007-02-06 7:48 ` [PATCH] git-push: allow globbing wildcard refspec Junio C Hamano 1 sibling, 1 reply; 14+ messages in thread From: Junio C Hamano @ 2007-02-06 7:40 UTC (permalink / raw) To: git Junio C Hamano <junkio@cox.net> writes: > Several things to note (in the following, substitute $gmane with > http://article.gmane.org/gmane.comp.version-control.git): > > - Working around Tk geometry problem, especially on non Linux+X > platforms. I've forwarded Mark Levedahl's patches > ($gmane/38361) to Paul Mackerras for his blessing; hopefully > he can Ack and/or suggest improvements. I'd really like to > have them in 1.5.0 in some form. Mark and I got a response from Paul; unfortunately he is too busy right now, immediately after post 2.6.20 merge window has opened. I've parked Mark's patches and another one suggested by Linus in response to Johannes Sixt's MinGW work in 'next' for now. Depending on Paul's availablity, I might end up applying them in my tree first. > - Nico's "reflog on HEAD". > - Reverting the patch to allow tracking branch names as the > value of branch.*.merge ($gmane/38621). > - Teaching "git blame" to also use the working tree files > and/or index. > - "git remote add -t -f -m" ($gmane/38470). These four are in ("git clone" rewrite is not). > - We might want to allow git-push to use the wildcard refspec, > like git-fetch does, for symmetry. I've done this which was not too painful -- a patch in a separate message to follow. I also applied a handful patches from early this year that was left unapplied. After reviewing the message I am responding to, and an earlier "a few remaining issues..." ($gmane/35993), I think I am pretty much done with 1.5.0 preparation. After pulling gfi from Shawn and applying the outstanding gitk patches (either via Paul or myself), I'll tag -rc4 and give it a week or so before the final. I should remember to remove git-merge-recur before -rc4 ;-). ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH] git-push: allow globbing wildcard refspec. 2007-02-06 7:40 ` Quick status updates Junio C Hamano @ 2007-02-06 7:48 ` Junio C Hamano 2007-02-06 7:53 ` Shawn O. Pearce 0 siblings, 1 reply; 14+ messages in thread From: Junio C Hamano @ 2007-02-06 7:48 UTC (permalink / raw) To: git This allows you to set up mothership-satellite configuration more symmetrically and naturally by allowing the globbing wildcard refspec for git-push. On your satellite machine: [remote "mothership"] url = mothership:project.git pull = refs/heads/*:refs/remotes/mothership/* push = refs/heads/*:refs/remotes/satellite/* You would say "git fetch mothership" to update your tracking branches under mothership/ to keep track of the progress on the mothership side, and when you are done working on the satellite machine, you would "git push mothership" to update their tracking branches under satellite/. Corresponding configuration on the mothership machine can be used to make "git fetch satellite" update its tracking branch under satellite/. on the mothership. Signed-off-by: Junio C Hamano <junkio@cox.net> --- builtin-push.c | 114 ++++++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 82 insertions(+), 32 deletions(-) diff --git a/builtin-push.c b/builtin-push.c index 5f4d7d3..c45649e 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -54,38 +54,84 @@ static void expand_refspecs(void) for_each_ref(expand_one_ref, NULL); } +struct wildcard_cb { + const char *from_prefix; + int from_prefix_len; + const char *to_prefix; + int to_prefix_len; + int force; +}; + +static int expand_wildcard_ref(const char *ref, const unsigned char *sha1, int flag, void *cb_data) +{ + struct wildcard_cb *cb = cb_data; + int len = strlen(ref); + char *expanded, *newref; + + if (len < cb->from_prefix_len || + memcmp(cb->from_prefix, ref, cb->from_prefix_len)) + return 0; + expanded = xmalloc(len * 2 + cb->force + + (cb->to_prefix_len - cb->from_prefix_len) + 2); + newref = expanded + cb->force; + if (cb->force) + expanded[0] = '+'; + memcpy(newref, ref, len); + newref[len] = ':'; + memcpy(newref + len + 1, cb->to_prefix, cb->to_prefix_len); + strcpy(newref + len + 1 + cb->to_prefix_len, + ref + cb->from_prefix_len); + add_refspec(expanded); + return 0; +} + +static int wildcard_ref(const char *ref) +{ + int len; + const char *colon; + struct wildcard_cb cb; + + memset(&cb, 0, sizeof(cb)); + if (ref[0] == '+') { + cb.force = 1; + ref++; + } + len = strlen(ref); + colon = strchr(ref, ':'); + if (! (colon && ref < colon && + colon[-2] == '/' && colon[-1] == '*' && + /* "<mine>/<asterisk>:<yours>/<asterisk>" is at least 7 bytes */ + 7 <= len && + ref[len-2] == '/' && ref[len-1] == '*') ) + return 0 ; + cb.from_prefix = ref; + cb.from_prefix_len = colon - ref - 1; + cb.to_prefix = colon + 1; + cb.to_prefix_len = len - (colon - ref) - 2; + for_each_ref(expand_wildcard_ref, &cb); + return 1; +} + static void set_refspecs(const char **refs, int nr) { if (nr) { - int pass; - for (pass = 0; pass < 2; pass++) { - /* pass 0 counts and allocates, pass 1 fills */ - int i, cnt; - for (i = cnt = 0; i < nr; i++) { - if (!strcmp("tag", refs[i])) { - int len; - char *tag; - if (nr <= ++i) - die("tag <tag> shorthand without <tag>"); - if (pass) { - len = strlen(refs[i]) + 11; - tag = xmalloc(len); - strcpy(tag, "refs/tags/"); - strcat(tag, refs[i]); - refspec[cnt] = tag; - } - cnt++; - continue; - } - if (pass) - refspec[cnt] = refs[i]; - cnt++; - } - if (!pass) { - size_t bytes = cnt * sizeof(char *); - refspec_nr = cnt; - refspec = xrealloc(refspec, bytes); + int i; + for (i = 0; i < nr; i++) { + const char *ref = refs[i]; + if (!strcmp("tag", ref)) { + char *tag; + int len; + if (nr <= ++i) + die("tag shorthand without <tag>"); + len = strlen(refs[i]) + 11; + tag = xmalloc(len); + strcpy(tag, "refs/tags/"); + strcat(tag, refs[i]); + ref = tag; } + else if (wildcard_ref(ref)) + continue; + add_refspec(ref); } } expand_refspecs(); @@ -129,8 +175,10 @@ static int get_remotes_uri(const char *repo, const char *uri[MAX_URI]) else error("more than %d URL's specified, ignoring the rest", MAX_URI); } - else if (is_refspec && !has_explicit_refspec) - add_refspec(xstrdup(s)); + else if (is_refspec && !has_explicit_refspec) { + if (!wildcard_ref(s)) + add_refspec(xstrdup(s)); + } } fclose(f); if (!n) @@ -156,8 +204,10 @@ static int get_remote_config(const char* key, const char* value) error("more than %d URL's specified, ignoring the rest", MAX_URI); } else if (config_get_refspecs && - !strcmp(key + 7 + config_repo_len, ".push")) - add_refspec(xstrdup(value)); + !strcmp(key + 7 + config_repo_len, ".push")) { + if (!wildcard_ref(value)) + add_refspec(xstrdup(value)); + } else if (config_get_receivepack && !strcmp(key + 7 + config_repo_len, ".receivepack")) { if (!receivepack) { -- 1.5.0.rc3.83.g88293c-dirty ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH] git-push: allow globbing wildcard refspec. 2007-02-06 7:48 ` [PATCH] git-push: allow globbing wildcard refspec Junio C Hamano @ 2007-02-06 7:53 ` Shawn O. Pearce 0 siblings, 0 replies; 14+ messages in thread From: Shawn O. Pearce @ 2007-02-06 7:53 UTC (permalink / raw) To: Junio C Hamano; +Cc: git Junio C Hamano <junkio@cox.net> wrote: > [remote "mothership"] > url = mothership:project.git > pull = refs/heads/*:refs/remotes/mothership/* Don't you mean `fetch = ...` here? -- Shawn. ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2007-02-06 7:53 UTC | newest] Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-02-01 0:26 [ANNOUNCE] GIT 1.5.0-rc3 Junio C Hamano 2007-02-01 16:51 ` Bill Lear 2007-02-01 20:34 ` Robin Rosenberg 2007-02-04 9:36 ` What's in git.git (stable) Junio C Hamano 2007-02-04 18:51 ` Jeff King 2007-02-04 19:12 ` Linus Torvalds 2007-02-04 20:58 ` Theodore Tso 2007-02-04 21:34 ` Jakub Narebski 2007-02-04 22:25 ` David Kågedal 2007-02-05 3:00 ` [PATCH 1/2] Rename get_ident() to fmt_ident() and make it available to outside Junio C Hamano 2007-02-05 3:00 ` [PATCH 2/2] git-blame: no rev means start from the working tree file Junio C Hamano 2007-02-06 7:40 ` Quick status updates Junio C Hamano 2007-02-06 7:48 ` [PATCH] git-push: allow globbing wildcard refspec Junio C Hamano 2007-02-06 7:53 ` Shawn O. Pearce
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).