Linus Torvalds [off-list ref] writes:
Now, I happen to think that 2500+ files in /usr/bin is a bit much (ever
try to use the horrid gnome executable finder on it when you want to
convince firefox to use xpdf instead of that broken crap called "evince"?
Takes absolutely ages and is horrible).
And git made it about 4% worse all on its own.
My pragmatic half agrees with what you said. /usr/bin should
not contain things that are never used by the end user -- things
like git-sh-setup, git-fmt-merge-msg, and git-merge-recursive
should not be there. Not having things like git-show-branch and
git-update-index in /usr/bin is a regression because it needs an
extra fork to call them through 'git' wrapper, but I could live
with that.
My purist half, however, says that it is a wrong solution to the
problem. If having many files in /usr/bin hurts performance,
you should be using a filesystem that handles large directory
better. Modern shells already know how to hash command names
found in $PATH. It is just your gnome executable finder that is
lacking the knowledge of which binaries are appropriate for what
mimetype; perhaps your distribution could help by having a way
for each package to register programs that handle particular
mimetypes well with the system-wide database.
And my lazy remainder (yes, I add up to more then one ;-))
cheers on my purist side.
But common sense prevails at the end of the day. I would not
fight a battle I know I would not be able to win. So what
should we do about this problem? And when?
Since we do not have enough clout to have /usr/bin/git/ and ask
the users to put that in their PATH like X11 does, we need to
teach some of our commands that use other git commands to
prepend /usr/lib/git/ (or /usr/libexec/git) on their PATH while
they run. Although many of the Porcelainish commands include
git-sh-setup, git-sh-setup itself is a prime candidate to be
kicked out of /usr/bin, which means essentially everything needs
to have that PATH trick.
This also is a bit inconvenient for our in-source-tree tests.
We need to be testing what we just built and are about to
install, not what is already installed, so every script needs to
start with something like this:
#!/bin/sh
: ${GIT_BIN_DIR=@@GIT_BIN_DIR@@}
PATH="$GIT_BIN_DIR:$PATH"
git-sh-setup || die "not a git repository"
...
and our test will run with GIT_BIN_DIR set to `pwd`/../../ (they
run in t/trash and what we just built are found at the toplevel
of the source). Also we need to do the same for binaries if they
fork/exec other git commands.
Commands like upload-pack and receive-pack are directly executed
from the ssh connection, and we need to arrange for them to be
found on the PATH of users' non-login shells. This does not
necessarily mean these commands need to stay in /usr/bin, but if
we move them outside standard PATH, we would need to teach
.bash_profile vs .bashrc workaround to all users, which I think
is the yuckiest part of all of the above.
On Sat, 5 Nov 2005, Junio C Hamano wrote:
My purist half, however, says that it is a wrong solution to the
problem. If having many files in /usr/bin hurts performance,
you should be using a filesystem that handles large directory
better.
I disagree with your arguments, even though I'm not convinced we
necessarily need a directory of its own for git.
We have directories for a reason. You might as well argue that everybody
should have a flat namespace, since it should be efficient.
The performance reason for directories is only secondary. The _real_
reason for directories is to keep related things together, and track them
better. Havign a nice directory structure where programs keep their own
files instead of putting them all in the same place is a good thing from
an organization standpoint.
Modern shells already know how to hash command names
found in $PATH.
Right. And we could add the git directory to the path. In fact, that's
exactly what the git wrapper script does: this allows the low-level git
shell scripts to avoid havign to go through the wrapper, since they can
now use the native programs directly.
(In fact, that PATH part of the patch is probably a bug-fix regardless: if
I have two different versions of "git", and I ask for the one that isn't
in my path explicitly, then it should use _its_ git programs, not the
other versions).
It is just your gnome executable finder that is
lacking the knowledge of which binaries are appropriate for what
mimetype;
The gnome file chooser is horrid, but even in the presense of a _nice_
file manager it's actually not very pleasant to have directories with
thousands of files.
Since we do not have enough clout to have /usr/bin/git/ and ask
the users to put that in their PATH like X11 does, we need to
teach some of our commands that use other git commands to
prepend /usr/lib/git/ (or /usr/libexec/git) on their PATH while
they run.
Did you miss that part of my patch? That's exactly what this hunk of it
does:
diff --git a/git.sh b/git.sh
index 94940ae..9ba1608 100755
--- a/git.sh
+++ b/git.sh
@@ -1,7 +1,8 @@
#!/bin/sh
cmd=
-path=$(dirname "$0")
+path="@@GITDIR@@"
+export PATH="$path:$PATH"
case "$#" in
0) ;;
*) cmd="$1"
and as mentioned, I actually think it's a bugfix regardless of anything
else (do a "./git log", and it will _not_ execute "./git-rev-parse" and
"./git-rev-list": it will execute whatever was in the path, usually
/usr/bin/git-rev-xyzzy).
Now, gitk didn't do that, which is a bug.
Although many of the Porcelainish commands include
git-sh-setup, git-sh-setup itself is a prime candidate to be
kicked out of /usr/bin, which means essentially everything needs
to have that PATH trick.
Yes. All porcelain would need to do the PATH thing, I think.
This also is a bit inconvenient for our in-source-tree tests.
We need to be testing what we just built and are about to
install, not what is already installed, so every script needs to
start with something like this:
No, the actual programs and scripts themselves shouldn't change. Nothing
that uses git-sh-setup should change, only the programs that are installed
in /usr/bin would need to know that the helper programs are _not_ there,
and set up the path properly.
But if we do that right, that should be just a couple of executables,
which is the whole point of splitting this up.
But yes, you're right that right now we're not always set up for this, and
git-upload-pack etc that execute directly from the shell would need help.
Linus
Linus Torvalds [off-list ref] writes:
We have directories for a reason. You might as well argue that everybody
should have a flat namespace, since it should be efficient.
The performance reason for directories is only secondary. The _real_
reason for directories is to keep related things together, and track them
better. Havign a nice directory structure where programs keep their own
files instead of putting them all in the same place is a good thing from
an organization standpoint.
My point (actually, my purist half's point) is that /usr/bin is
that nice structure that keeps related things together --- the
relatedness of them being "the end user would want to run them".
Your initial hesitation that the change being discussed would
force you to say "git whatchanged" when you are so accustomed to
type git-whatchanged is valid. Unfortunately, we have far more
commands in /usr/bin than good old V7 days, and while the
_primary_ purpose of /usr/bin is to hold "the end user would
want to run them" things together (hence, shell needs to know
only about handful places to look at), having thousands of
things in one place is inconvenient for purposes other than the
primary purpose of that grouping (i.e. running them), such as
browsing them.
You could deviate from the UNIX tradition and "keep related
things together" in different ways; you _could_ have
/usr/bin/pdf-viewers/, /usr/bin/html-viewers/, etc. to hold
xpdf, acroread, firefox and iexplorer in them if you do not like
/usr/bin/ that has many executables -- but we do not do that.
(In fact, that PATH part of the patch is probably a bug-fix regardless: if
I have two different versions of "git", and I ask for the one that isn't
in my path explicitly, then it should use _its_ git programs, not the
other versions).
I think that is a valid change.
The gnome file chooser is horrid, but even in the presense of a _nice_
file manager it's actually not very pleasant to have directories with
thousands of files.
Yes, but I think we should blame UNIX tradition for that ;-).
Did you miss that part of my patch?
Sorry, my reply was prepared before I actually saw that patch
(you would notice it was a reply to your first message). I
think what you did in your patch makes sense. The end users
should always say 'git update-index' (or know the lib/git path
and it they want to say git-update-index), even when running the
low-level commands, and as long as they use 'git' wrapper that
approach would work.
Yes. All porcelain would need to do the PATH thing, I think.
No, we could just say 'git commit' and 'git' is the only thing
that needs to know the PATH thing, as you did.
But yes, you're right that right now we're not always set up for this, and
git-upload-pack etc that execute directly from the shell would need help.
We _could_ even invoke 'git upload-pack' from 'git-fetch'.
On Sat, 5 Nov 2005, Junio C Hamano wrote:
My point (actually, my purist half's point) is that /usr/bin is
that nice structure that keeps related things together --- the
relatedness of them being "the end user would want to run them".
Yes. I wish there was some way around that.
Right now, for a 1.0 release, I suspect that the "put the git binaries
somewhere else" just isn't worth it. It will break existing scripts that
use the binaries directly (we've already broken the kernel.org snapshot
scripts about a million times with just _renaming_ the binaries ;)
It would still be nice to not screw up peoples /usr/bin too badly. At
least we have the nice property that our git programs sort together and
can pretty much be wild-carded (not everybody uses package installers, and
on one machine I had just done "make prefix=/usr install" and was happy to
be able to basically remove it with "rm /usr/bin/git-*")
Linus