All of lore.kernel.org
 help / color / mirror / Atom feed
* git binary directory?
@ 2005-11-05 21:02 Linus Torvalds
  2005-11-05 23:52 ` Linus Torvalds
  2005-11-06  2:49 ` Junio C Hamano
  0 siblings, 2 replies; 28+ messages in thread
From: Linus Torvalds @ 2005-11-05 21:02 UTC (permalink / raw)
  To: Git Mailing List, Junio C Hamano


Just for fun, I did "git-<tab><tab>" a moment ago, and it asked me

	Display all 171 possibilities? (y or n)

which was a bit scary. Now, part of that was because I hadn't cleaned up 
the old git names, so I removed everything, and did a clean "make install" 
with the current git tree. At which point the question became

	Display all 105 possibilities? (y or n)

and pressing "y" shows a really nice list of programs.

Now, this is actually very convenient, and since I tend to install things 
in my own ~/bin directory, it's all good. What's a hundred files more or 
less?

However, doing a "ls /usr/bin/ | wc" shows that on my laptop /usr/bin is 
already 2583 files, and git is actually part of the problem there (hey, 
it's got the git RPM installed - it's not my main machine)..

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.

So I'd really suggest that while the "git-<tab><tab>" thing is perhaps 
useful, we'd actually be better off with an /usr/lib/git directory where 
we put the git executables by default. And just put "git" into /usr/bin.

That way, people who _want_ to use "git-<tab><tab>" can just add the git 
binary directory to their path and directly access all of them. And others 
can just use the plain "git" interface.

That would mean that I'd have to learn to use "git whatchanged" and "git 
diff-tree" instead of "git-whatchanged" and "git-diff-tree", but hey, it's 
why we have that "git" script in the first place.

What do people think?

			Linus

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-05 21:02 git binary directory? Linus Torvalds
@ 2005-11-05 23:52 ` Linus Torvalds
  2005-11-06  0:27   ` Linus Torvalds
  2005-11-06  2:49 ` Junio C Hamano
  1 sibling, 1 reply; 28+ messages in thread
From: Linus Torvalds @ 2005-11-05 23:52 UTC (permalink / raw)
  To: Git Mailing List, Junio C Hamano



On Sat, 5 Nov 2005, Linus Torvalds wrote:
> 
> So I'd really suggest that while the "git-<tab><tab>" thing is perhaps 
> useful, we'd actually be better off with an /usr/lib/git directory where 
> we put the git executables by default. And just put "git" into /usr/bin.

This is a guaranteed BUGGY thing to make the git RPM do something like 
that.

It adds a "gitdir" parameter to "make install", which defaults to the same 
as "bindir" if you don't specify it.

It installs only "git" in "bindir", and all other git programs in 
"gitdir".

It then makes the "git" script use "gitdir" for searching for the 
installed git scripts and programs, and forces PATH to have "gitdir" at 
the head while executing the sub-script (so that when the scripts do 
"git-diff-tree" etc, they'll always use the proper gitdir version).

The RPM specfile is taught to make "gitdir" be "${_libdir}/git-@@VERSION"

This means that if I got everything right, the RPM will build with

	/usr/bin/git

	/usr/lib/git-0.99.9.GIT/git-add
	/usr/lib/git-0.99.9.GIT/git-am
	/usr/lib/git-0.99.9.GIT/git-apply
	..

	/usr/share/doc/git-core-0.99.9.GIT
	/usr/share/doc/git-core-0.99.9.GIT/COPYING
	..

	/usr/share/git-core
	/usr/share/git-core/python
	..

	/usr/share/git-core/templates
	/usr/share/git-core/templates/branches
	..

	/usr/share/man/man1/git-add.1.gz
	/usr/share/man/man1/git-am.1.gz
	..

where the new thing is that "/usr/lib/git-0.99.9.GIT/" usage.

I've tested building the rpm, and that part works. I haven't actually 
tested the end result, though.

Oh, and I have not a clue in hell about how Debian works. In fact, I don't 
have a real clue how RPM files work either, this was done by doing some 
pattern matching on the existing git-core.spec.in file. Somebody who knows 
better really should fix it.

WARNING! I just realized that "gitk" also ends up in that /usr/lib/git.. 
directory, and this isn't visible. My bad. I'm a retard. 

Comments?

What do people think about this? Any daring souls willing to test this?

(Btw: word of caution on something that confused me at first: you have to 
_commit_ this diff in order for "make rpm" to work, since "make rpm" uses 
"git-tar-tree" to create the rpm file, not the current directory contents, 
heh ;)

		Linus

---
diff --git a/Makefile b/Makefile
index 6c01dc2..8df8b50 100644
--- a/Makefile
+++ b/Makefile
@@ -59,6 +59,7 @@ ALL_CFLAGS = $(CFLAGS) $(PLATFORM_DEFINE
 
 prefix = $(HOME)
 bindir = $(prefix)/bin
+gitdir = $(bindir)
 template_dir = $(prefix)/share/git-core/templates/
 GIT_PYTHON_DIR = $(prefix)/share/git-core/python
 # DESTDIR=
@@ -86,7 +87,7 @@ SCRIPT_SH = \
 	git-prune.sh git-pull.sh git-push.sh git-rebase.sh \
 	git-repack.sh git-request-pull.sh git-reset.sh \
 	git-resolve.sh git-revert.sh git-sh-setup.sh git-status.sh \
-	git-tag.sh git-verify-tag.sh git-whatchanged.sh git.sh \
+	git-tag.sh git-verify-tag.sh git-whatchanged.sh \
 	git-applymbox.sh git-applypatch.sh git-am.sh \
 	git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
 	git-merge-resolve.sh git-merge-ours.sh git-grep.sh
@@ -315,7 +316,7 @@ SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)
 export prefix TAR INSTALL DESTDIR SHELL_PATH template_dir
 ### Build rules
 
-all: $(PROGRAMS) $(SCRIPTS)
+all: git $(PROGRAMS) $(SCRIPTS)
 
 all:
 	$(MAKE) -C templates
@@ -323,6 +324,7 @@ all:
 git: git.sh Makefile
 	rm -f $@+ $@
 	sed -e '1s|#!.*/sh|#!$(call shq,$(SHELL_PATH))|' \
+	    -e 's:@@GITDIR@@:$(gitdir):g' \
 	    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
 	    -e 's/@@X@@/$(X)/g' \
 	    $(GIT_LIST_TWEAK) <$@.sh >$@+
@@ -410,9 +412,11 @@ check:
 
 ### Installation rules
 
-install: $(PROGRAMS) $(SCRIPTS)
+install: git $(PROGRAMS) $(SCRIPTS)
 	$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(bindir))
-	$(INSTALL) $(PROGRAMS) $(SCRIPTS) $(call shellquote,$(DESTDIR)$(bindir))
+	$(INSTALL) git $(call shellquote,$(DESTDIR)$(bindir))
+	$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(gitdir))
+	$(INSTALL) $(PROGRAMS) $(SCRIPTS) $(call shellquote,$(DESTDIR)$(gitdir))
 	$(MAKE) -C templates install
 	$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(GIT_PYTHON_DIR))
 	$(INSTALL) $(PYMODULES) $(call shellquote,$(DESTDIR)$(GIT_PYTHON_DIR))
diff --git a/git-core.spec.in b/git-core.spec.in
index 5240dd2..0d0ddf3 100644
--- a/git-core.spec.in
+++ b/git-core.spec.in
@@ -19,17 +19,19 @@ distributed source code management syste
 rudimentary tools that can be used as a SCM, but you should look
 elsewhere for tools for ordinary humans layered on top of this.
 
+%define gitdir %{_libdir}/git-@@VERSION@@
+
 %prep
 %setup -q
 
 %build
 make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" WITH_OWN_SUBPROCESS_PY=YesPlease \
-     prefix=%{_prefix} all %{!?_without_docs: doc}
+     gitdir=%{gitdir} prefix=%{_prefix} all %{!?_without_docs: doc}
 
 %install
 rm -rf $RPM_BUILD_ROOT
 make %{_smp_mflags} DESTDIR=$RPM_BUILD_ROOT WITH_OWN_SUBPROCESS_PY=YesPlease \
-     prefix=%{_prefix} mandir=%{_mandir} \
+     gitdir=%{gitdir} prefix=%{_prefix} mandir=%{_mandir} \
      install %{!?_without_docs: install-doc}
 
 %clean
@@ -38,6 +40,7 @@ rm -rf $RPM_BUILD_ROOT
 %files
 %defattr(-,root,root)
 %{_bindir}/*
+%{gitdir}/*
 %{_datadir}/git-core/
 %doc README COPYING Documentation/*.txt
 %{!?_without_docs: %doc Documentation/*.html }
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"

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-05 23:52 ` Linus Torvalds
@ 2005-11-06  0:27   ` Linus Torvalds
  2005-11-06  7:25     ` Junio C Hamano
  0 siblings, 1 reply; 28+ messages in thread
From: Linus Torvalds @ 2005-11-06  0:27 UTC (permalink / raw)
  To: Git Mailing List, Junio C Hamano



On Sat, 5 Nov 2005, Linus Torvalds wrote:
> 
> This is a guaranteed BUGGY thing to make the git RPM do something like 
> that.
>
> [ ... ]
> 
> WARNING! I just realized that "gitk" also ends up in that /usr/lib/git.. 
> directory, and this isn't visible. My bad. I'm a retard. 

This fixes the gitk thing, by installing it (along with git) in the 
regular $prefix/bin directory (ie default /usr/bin for the RPM).

I'm still a retard, and it's _probably_ still buggy, but at least it is no 
longer GUARANTEED to be buggy.

		Linus

---
diff --git a/Makefile b/Makefile
index 6c01dc2..6ec9dd2 100644
--- a/Makefile
+++ b/Makefile
@@ -59,6 +59,7 @@ ALL_CFLAGS = $(CFLAGS) $(PLATFORM_DEFINE
 
 prefix = $(HOME)
 bindir = $(prefix)/bin
+gitdir = $(bindir)
 template_dir = $(prefix)/share/git-core/templates/
 GIT_PYTHON_DIR = $(prefix)/share/git-core/python
 # DESTDIR=
@@ -86,7 +87,7 @@ SCRIPT_SH = \
 	git-prune.sh git-pull.sh git-push.sh git-rebase.sh \
 	git-repack.sh git-request-pull.sh git-reset.sh \
 	git-resolve.sh git-revert.sh git-sh-setup.sh git-status.sh \
-	git-tag.sh git-verify-tag.sh git-whatchanged.sh git.sh \
+	git-tag.sh git-verify-tag.sh git-whatchanged.sh \
 	git-applymbox.sh git-applypatch.sh git-am.sh \
 	git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
 	git-merge-resolve.sh git-merge-ours.sh git-grep.sh
@@ -310,12 +311,12 @@ DEFINES += -DSHA1_HEADER=$(call shellquo
 SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
 	  $(patsubst %.perl,%,$(SCRIPT_PERL)) \
 	  $(patsubst %.py,%,$(SCRIPT_PYTHON)) \
-	  gitk git-cherry-pick
+	  git-cherry-pick
 
 export prefix TAR INSTALL DESTDIR SHELL_PATH template_dir
 ### Build rules
 
-all: $(PROGRAMS) $(SCRIPTS)
+all: git gitk $(PROGRAMS) $(SCRIPTS)
 
 all:
 	$(MAKE) -C templates
@@ -323,6 +324,7 @@ all:
 git: git.sh Makefile
 	rm -f $@+ $@
 	sed -e '1s|#!.*/sh|#!$(call shq,$(SHELL_PATH))|' \
+	    -e 's:@@GITDIR@@:$(gitdir):g' \
 	    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
 	    -e 's/@@X@@/$(X)/g' \
 	    $(GIT_LIST_TWEAK) <$@.sh >$@+
@@ -410,9 +412,11 @@ check:
 
 ### Installation rules
 
-install: $(PROGRAMS) $(SCRIPTS)
+install: git gitk $(PROGRAMS) $(SCRIPTS)
 	$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(bindir))
-	$(INSTALL) $(PROGRAMS) $(SCRIPTS) $(call shellquote,$(DESTDIR)$(bindir))
+	$(INSTALL) git gitk $(call shellquote,$(DESTDIR)$(bindir))
+	$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(gitdir))
+	$(INSTALL) $(PROGRAMS) $(SCRIPTS) $(call shellquote,$(DESTDIR)$(gitdir))
 	$(MAKE) -C templates install
 	$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(GIT_PYTHON_DIR))
 	$(INSTALL) $(PYMODULES) $(call shellquote,$(DESTDIR)$(GIT_PYTHON_DIR))
@@ -450,7 +454,7 @@ deb: dist
 
 clean:
 	rm -f *.o mozilla-sha1/*.o ppc/*.o compat/*.o $(PROGRAMS) $(LIB_FILE)
-	rm -f $(filter-out gitk,$(SCRIPTS))
+	rm -f $(SCRIPTS)
 	rm -f git-core.spec *.pyc *.pyo
 	rm -rf $(GIT_TARNAME)
 	rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
diff --git a/git-core.spec.in b/git-core.spec.in
index 5240dd2..0d0ddf3 100644
--- a/git-core.spec.in
+++ b/git-core.spec.in
@@ -19,17 +19,19 @@ distributed source code management syste
 rudimentary tools that can be used as a SCM, but you should look
 elsewhere for tools for ordinary humans layered on top of this.
 
+%define gitdir %{_libdir}/git-@@VERSION@@
+
 %prep
 %setup -q
 
 %build
 make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" WITH_OWN_SUBPROCESS_PY=YesPlease \
-     prefix=%{_prefix} all %{!?_without_docs: doc}
+     gitdir=%{gitdir} prefix=%{_prefix} all %{!?_without_docs: doc}
 
 %install
 rm -rf $RPM_BUILD_ROOT
 make %{_smp_mflags} DESTDIR=$RPM_BUILD_ROOT WITH_OWN_SUBPROCESS_PY=YesPlease \
-     prefix=%{_prefix} mandir=%{_mandir} \
+     gitdir=%{gitdir} prefix=%{_prefix} mandir=%{_mandir} \
      install %{!?_without_docs: install-doc}
 
 %clean
@@ -38,6 +40,7 @@ rm -rf $RPM_BUILD_ROOT
 %files
 %defattr(-,root,root)
 %{_bindir}/*
+%{gitdir}/*
 %{_datadir}/git-core/
 %doc README COPYING Documentation/*.txt
 %{!?_without_docs: %doc Documentation/*.html }
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"

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-05 21:02 git binary directory? Linus Torvalds
  2005-11-05 23:52 ` Linus Torvalds
@ 2005-11-06  2:49 ` Junio C Hamano
  2005-11-06  3:12   ` Horst von Brand
  2005-11-06  4:25   ` Linus Torvalds
  1 sibling, 2 replies; 28+ messages in thread
From: Junio C Hamano @ 2005-11-06  2:49 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List

Linus Torvalds <torvalds@osdl.org> 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.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06  2:49 ` Junio C Hamano
@ 2005-11-06  3:12   ` Horst von Brand
  2005-11-06  5:00     ` Kay Sievers
  2005-11-06  8:28     ` Petr Baudis
  2005-11-06  4:25   ` Linus Torvalds
  1 sibling, 2 replies; 28+ messages in thread
From: Horst von Brand @ 2005-11-06  3:12 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Linus Torvalds, Git Mailing List

Junio C Hamano <junkio@cox.net> wrote:
> Linus Torvalds <torvalds@osdl.org> 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.

[...]

> 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,

That is going away. No more /usr/X11R6/{bin,lib,man} junk.

>                                                    we need to
> teach some of our commands that use other git commands to
> prepend /usr/lib/git/ (or /usr/libexec/git)

AFAIU, /usr/libexec/git (or /usr/libexec/git-<version>) would be better.
Including the version would make it possible to have the last stable and a
development version coexisting, like gcc does with -V. Or its -B option,
which tells it where to find the executables that do the real work.

>                                             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.

Explicitly saying where to find all the stuff with -B would help here.


The only downside is that git-<TAB> won't find them anymore, but I'm sure
the bash-completion people will fix that soon ;-)
-- 
Dr. Horst H. von Brand                   User #22616 counter.li.org
Departamento de Informatica                     Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria              +56 32 654239
Casilla 110-V, Valparaiso, Chile                Fax:  +56 32 797513

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06  2:49 ` Junio C Hamano
  2005-11-06  3:12   ` Horst von Brand
@ 2005-11-06  4:25   ` Linus Torvalds
  2005-11-06  5:37     ` Junio C Hamano
  1 sibling, 1 reply; 28+ messages in thread
From: Linus Torvalds @ 2005-11-06  4:25 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List



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

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06  3:12   ` Horst von Brand
@ 2005-11-06  5:00     ` Kay Sievers
  2005-11-06  5:36       ` Junio C Hamano
  2005-11-06  8:28     ` Petr Baudis
  1 sibling, 1 reply; 28+ messages in thread
From: Kay Sievers @ 2005-11-06  5:00 UTC (permalink / raw)
  To: Horst von Brand; +Cc: Junio C Hamano, Linus Torvalds, Git Mailing List

On Sun, Nov 06, 2005 at 12:12:30AM -0300, Horst von Brand wrote:
> Junio C Hamano <junkio@cox.net> wrote:
> > Linus Torvalds <torvalds@osdl.org> 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.
> 
> [...]
> 
> > 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,
> 
> That is going away. No more /usr/X11R6/{bin,lib,man} junk.
> 
> >                                                    we need to
> > teach some of our commands that use other git commands to
> > prepend /usr/lib/git/ (or /usr/libexec/git)
> 
> AFAIU, /usr/libexec/git (or /usr/libexec/git-<version>) would be better.

Note that "libexec" is not LSB conform - whatever that means, but it
should probably not be used for new projects. It states: "Applications
may use a single subdirectory under /usr/lib."

Kay

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06  5:00     ` Kay Sievers
@ 2005-11-06  5:36       ` Junio C Hamano
  2005-11-06  8:23         ` Petr Baudis
  0 siblings, 1 reply; 28+ messages in thread
From: Junio C Hamano @ 2005-11-06  5:36 UTC (permalink / raw)
  To: Kay Sievers; +Cc: Horst von Brand, Linus Torvalds, Git Mailing List

Kay Sievers <kay.sievers@vrfy.org> writes:

> Note that "libexec" is not LSB conform - whatever that means, but it
> should probably not be used for new projects. It states: "Applications
> may use a single subdirectory under /usr/lib."

I had an impression that there are still UNIXy systems that are
not even Linux; do they follow LSB and drop libexec?

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06  4:25   ` Linus Torvalds
@ 2005-11-06  5:37     ` Junio C Hamano
  2005-11-06 16:20       ` Linus Torvalds
  0 siblings, 1 reply; 28+ messages in thread
From: Junio C Hamano @ 2005-11-06  5:37 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List

Linus Torvalds <torvalds@osdl.org> 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'.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06  0:27   ` Linus Torvalds
@ 2005-11-06  7:25     ` Junio C Hamano
  0 siblings, 0 replies; 28+ messages in thread
From: Junio C Hamano @ 2005-11-06  7:25 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List

Linus Torvalds <torvalds@osdl.org> writes:

> This fixes the gitk thing, by installing it (along with git) in the 
> regular $prefix/bin directory (ie default /usr/bin for the RPM).

The other half of the fix needed to gitk is to teach it to use
/usr/lib/git-@@VERSION@@ to locate git-rev-list and friends.

I really hate to do this, but here is an attempt on top of your
patch, which:

 - makes gitk also use the @@GITDIR@@ to find git commands;

 - makes git and gitk honor $GIT_LIBEXEC environment, to let you
   override the hardcoded @@GITDIR@@;

 - makes "make clean" to clean generated file git again.

I am not sure how to handle gitk part, but the best approach
would be to sell this change (including the rename) back to
Paulus the upstream.

---
diff --git a/Makefile b/Makefile
index 2e78089..1948aa1 100644
--- a/Makefile
+++ b/Makefile
@@ -327,6 +327,15 @@ git: git.sh Makefile
 	chmod +x $@+
 	mv $@+ $@
 
+gitk: gitk.tcl Makefile
+	rm -f $@+ $@
+	sed -e '1s|#!.*/sh|#!$(call shq,$(SHELL_PATH))|' \
+	    -e 's:@@GITDIR@@:$(gitdir):g' \
+	    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
+	    <$@.tcl >$@+
+	chmod +x $@+
+	mv $@+ $@
+
 $(filter-out git,$(patsubst %.sh,%,$(SCRIPT_SH))) : % : %.sh
 	rm -f $@
 	sed -e '1s|#!.*/sh|#!$(call shq,$(SHELL_PATH))|' \
@@ -450,7 +459,7 @@ deb: dist
 
 clean:
 	rm -f *.o mozilla-sha1/*.o ppc/*.o compat/*.o $(PROGRAMS) $(LIB_FILE)
-	rm -f $(SCRIPTS)
+	rm -f $(SCRIPTS) git gitk
 	rm -f git-core.spec *.pyc *.pyo
 	rm -rf $(GIT_TARNAME)
 	rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
diff --git a/git.sh b/git.sh
index 9ba1608..f39b373 100755
--- a/git.sh
+++ b/git.sh
@@ -1,7 +1,13 @@
 #!/bin/sh
 
 cmd=
-path="@@GITDIR@@"
+case "$GIT_LIBEXEC" in
+'')
+	GIT_LIBEXEC='@@GITDIR@@'
+	export GIT_LIBEXEC
+	;;
+esac
+path="$GIT_LIBEXEC"
 export PATH="$path:$PATH"
 case "$#" in
 0)	;;
diff --git a/gitk b/gitk.tcl
similarity index 100%
rename from gitk
rename to gitk.tcl
index a9d37d9..be9a79e 100755
--- a/gitk
+++ b/gitk.tcl
@@ -7,6 +7,11 @@ exec wish "$0" -- "$@"
 # and distributed under the terms of the GNU General Public Licence,
 # either version 2, or (at your option) any later version.
 
+if {![info exists env(GIT_LIBEXEC)]} {
+    set env(GIT_LIBEXEC) "@@GITDIR@@"
+}
+set env(PATH) "$env(GIT_LIBEXEC):$env(PATH)"
+
 proc gitdir {} {
     global env
     if {[info exists env(GIT_DIR)]} {

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06  5:36       ` Junio C Hamano
@ 2005-11-06  8:23         ` Petr Baudis
  2005-11-06  8:33           ` Junio C Hamano
  0 siblings, 1 reply; 28+ messages in thread
From: Petr Baudis @ 2005-11-06  8:23 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Kay Sievers, Horst von Brand, Linus Torvalds, Git Mailing List

Dear diary, on Sun, Nov 06, 2005 at 06:36:59AM CET, I got a letter
where Junio C Hamano <junkio@cox.net> told me that...
> Kay Sievers <kay.sievers@vrfy.org> writes:
> 
> > Note that "libexec" is not LSB conform - whatever that means, but it
> > should probably not be used for new projects. It states: "Applications
> > may use a single subdirectory under /usr/lib."
> 
> I had an impression that there are still UNIXy systems that are
> not even Linux; do they follow LSB and drop libexec?

At least BSDs still seem to have libexec, but they are just as likely to
have lib, I would say, while on Linux it is going away (not that I would
be excited about it). So we could either make this per-system, or
default to something that is going to be present everywhere (lib),
I think.

-- 
			Petr "Pasky libdir=$(prefix)/lib/cogito" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06  3:12   ` Horst von Brand
  2005-11-06  5:00     ` Kay Sievers
@ 2005-11-06  8:28     ` Petr Baudis
  1 sibling, 0 replies; 28+ messages in thread
From: Petr Baudis @ 2005-11-06  8:28 UTC (permalink / raw)
  To: Horst von Brand; +Cc: Junio C Hamano, Linus Torvalds, Git Mailing List

Dear diary, on Sun, Nov 06, 2005 at 04:12:30AM CET, I got a letter
where Horst von Brand <vonbrand@inf.utfsm.cl> told me that...
> Junio C Hamano <junkio@cox.net> wrote:
> >                                                    we need to
> > teach some of our commands that use other git commands to
> > prepend /usr/lib/git/ (or /usr/libexec/git)
> 
> AFAIU, /usr/libexec/git (or /usr/libexec/git-<version>) would be better.
> Including the version would make it possible to have the last stable and a
> development version coexisting, like gcc does with -V. Or its -B option,
> which tells it where to find the executables that do the real work.

In Cogito, when including the lib programs, I'm doing

	. ${COGITO_LIB}cg-Xlib || exit 1

and then during installation I do:

	sed -e 's/\$${COGITO_LIB}/"\$${COGITO_LIB:-$(libdir)\/}"/g'

Then I can override it during execution by exporting $COGITO_LIB.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06  8:23         ` Petr Baudis
@ 2005-11-06  8:33           ` Junio C Hamano
  0 siblings, 0 replies; 28+ messages in thread
From: Junio C Hamano @ 2005-11-06  8:33 UTC (permalink / raw)
  To: Petr Baudis
  Cc: Kay Sievers, Horst von Brand, Linus Torvalds, Git Mailing List

Petr Baudis <pasky@suse.cz> writes:

> At least BSDs still seem to have libexec, but they are just as likely to
> have lib, I would say, while on Linux it is going away (not that I would
> be excited about it). So we could either make this per-system, or
> default to something that is going to be present everywhere (lib),
> I think.

Yes, that should definitely be done per system.  The main
Makefile does not have it different from bindir.  In fact, the
main Makefile still installs everything in $HOME/bin by default.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06  5:37     ` Junio C Hamano
@ 2005-11-06 16:20       ` Linus Torvalds
  2005-11-06 20:15         ` Junio C Hamano
  0 siblings, 1 reply; 28+ messages in thread
From: Linus Torvalds @ 2005-11-06 16:20 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List



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

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06 16:20       ` Linus Torvalds
@ 2005-11-06 20:15         ` Junio C Hamano
  2005-11-06 22:19           ` Petr Baudis
  0 siblings, 1 reply; 28+ messages in thread
From: Junio C Hamano @ 2005-11-06 20:15 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git

Linus Torvalds <torvalds@osdl.org> writes:

> 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 ;)

Although I _really_ wanted a 1.0 soonish, I personally feel that
this change is better done now than later, if we are eventually
going to do it anyway.  "Never" _might_ be better than "now",
but I suspect "later" or "post 1.0" is worse.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06 20:15         ` Junio C Hamano
@ 2005-11-06 22:19           ` Petr Baudis
  2005-11-07  0:08             ` Junio C Hamano
  0 siblings, 1 reply; 28+ messages in thread
From: Petr Baudis @ 2005-11-06 22:19 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Linus Torvalds, git

Dear diary, on Sun, Nov 06, 2005 at 09:15:38PM CET, I got a letter
where Junio C Hamano <junkio@cox.net> told me that...
> Linus Torvalds <torvalds@osdl.org> writes:
> 
> > 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 ;)
> 
> Although I _really_ wanted a 1.0 soonish, I personally feel that
> this change is better done now than later, if we are eventually
> going to do it anyway.  "Never" _might_ be better than "now",
> but I suspect "later" or "post 1.0" is worse.

You are also going to break the porcelains (w/o manual user
intervention), so I'm not happy about it but if you are doing it, do it
now, please. :-)

BTW, can I easily get the patch from the 'git' tool, so that I can
extend $PATH appropriately during Cogito initialization?

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06 22:19           ` Petr Baudis
@ 2005-11-07  0:08             ` Junio C Hamano
  2005-11-07  0:43               ` Petr Baudis
  0 siblings, 1 reply; 28+ messages in thread
From: Junio C Hamano @ 2005-11-07  0:08 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Linus Torvalds, git

Petr Baudis <pasky@suse.cz> writes:

> You are also going to break the porcelains (w/o manual user
> intervention), so I'm not happy about it but if you are doing it, do it
> now, please. :-)

I thought Porcelains and people's script can just say 'git foo'
everywhere where it currently says 'git-foo', and it should work
before and after the change, and that is what I did to my
private scripts.  But you are right, it is nicer if 'git-foo'
continued to work with a single patch to cg-Xlib or somewhere
central like that.

> BTW, can I easily get the patch from the 'git' tool, so that I can
> extend $PATH appropriately during Cogito initialization?

Do you mean 'git --show-git-libdir' or something like that?

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-07  0:08             ` Junio C Hamano
@ 2005-11-07  0:43               ` Petr Baudis
  2005-11-07  0:54                 ` Linus Torvalds
  2005-11-09 13:32                 ` Andreas Ericsson
  0 siblings, 2 replies; 28+ messages in thread
From: Petr Baudis @ 2005-11-07  0:43 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Linus Torvalds, git

Dear diary, on Mon, Nov 07, 2005 at 01:08:57AM CET, I got a letter
where Junio C Hamano <junkio@cox.net> told me that...
> Petr Baudis <pasky@suse.cz> writes:
> 
> > You are also going to break the porcelains (w/o manual user
> > intervention), so I'm not happy about it but if you are doing it, do it
> > now, please. :-)
> 
> I thought Porcelains and people's script can just say 'git foo'
> everywhere where it currently says 'git-foo', and it should work
> before and after the change, and that is what I did to my
> private scripts.  But you are right, it is nicer if 'git-foo'
> continued to work with a single patch to cg-Xlib or somewhere
> central like that.

I want to avoid extra fork()s and exec()s. They seem to routinely matter
in orders of magnitude of speed in tight loops.

Besides, I'm more used to the dash form. ;-)

> > BTW, can I easily get the patch from the 'git' tool, so that I can
> > extend $PATH appropriately during Cogito initialization?
> 
> Do you mean 'git --show-git-libdir' or something like that?

Yes. Well... you said you have the gitdir changes in your 'pu' branch,
but http://www.kernel.org/git/?p=git/git.git;a=tree;h=pu;hb=pu doesn't
appear to have the changes...?

Is --show-git-libdir already implemented?

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-07  0:43               ` Petr Baudis
@ 2005-11-07  0:54                 ` Linus Torvalds
  2005-11-07  9:45                   ` Petr Baudis
  2005-11-07 17:27                   ` Junio C Hamano
  2005-11-09 13:32                 ` Andreas Ericsson
  1 sibling, 2 replies; 28+ messages in thread
From: Linus Torvalds @ 2005-11-07  0:54 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Junio C Hamano, git



On Mon, 7 Nov 2005, Petr Baudis wrote:
> 
> I want to avoid extra fork()s and exec()s. They seem to routinely matter
> in orders of magnitude of speed in tight loops.

Yes. The more I think about it, the less I like the separate binary 
directory after all. The "git cmd" format is great for high-level 
commands, but we've always done "git-diff-tree" and "git-rev-list" etc 
without the "git cmd" indirection.

The downsides of a separate binary directory appear to be bigger than the 
upside..

		Linus

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-07  0:54                 ` Linus Torvalds
@ 2005-11-07  9:45                   ` Petr Baudis
  2005-11-07 17:27                   ` Junio C Hamano
  1 sibling, 0 replies; 28+ messages in thread
From: Petr Baudis @ 2005-11-07  9:45 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Junio C Hamano, git

Dear diary, on Mon, Nov 07, 2005 at 01:54:55AM CET, I got a letter
where Linus Torvalds <torvalds@osdl.org> told me that...
> On Mon, 7 Nov 2005, Petr Baudis wrote:
> > 
> > I want to avoid extra fork()s and exec()s. They seem to routinely matter
> > in orders of magnitude of speed in tight loops.
> 
> Yes. The more I think about it, the less I like the separate binary 
> directory after all. The "git cmd" format is great for high-level 
> commands, but we've always done "git-diff-tree" and "git-rev-list" etc 
> without the "git cmd" indirection.
> 
> The downsides of a separate binary directory appear to be bigger than the 
> upside..

Well, _one_ fork per user invocation (subsequent invocations wouldn't
need it, I already "cache" this kind of stuff in the environment) of a
Cogito command (to get the path to the gitdir) is not such a big deal,
I think.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-07  0:54                 ` Linus Torvalds
  2005-11-07  9:45                   ` Petr Baudis
@ 2005-11-07 17:27                   ` Junio C Hamano
  2005-11-10  9:49                     ` Petr Baudis
  1 sibling, 1 reply; 28+ messages in thread
From: Junio C Hamano @ 2005-11-07 17:27 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git, Petr Baudis

Linus Torvalds <torvalds@osdl.org> writes:

> On Mon, 7 Nov 2005, Petr Baudis wrote:
>> 
>> I want to avoid extra fork()s and exec()s. They seem to routinely matter
>> in orders of magnitude of speed in tight loops.
>
> Yes. The more I think about it, the less I like the separate binary 
> directory after all. The "git cmd" format is great for high-level 
> commands, but we've always done "git-diff-tree" and "git-rev-list" etc 
> without the "git cmd" indirection.

Extra fork() and exec() problem still exists, but "git cmd"
format have worked with "git diff-tree" and "git rev-list" for
quite some time (since Jun 14th), so you might've always done it
with dash but that is not a requirement.

It looks like that both you and Pasky are not so enthusiastic
about moving thing out of /usr/bin/, so let's keep things the
way they are for 1.0 release and rethink when we do 2.0 (or
whatever comes after 1.0).

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-07  0:43               ` Petr Baudis
  2005-11-07  0:54                 ` Linus Torvalds
@ 2005-11-09 13:32                 ` Andreas Ericsson
  1 sibling, 0 replies; 28+ messages in thread
From: Andreas Ericsson @ 2005-11-09 13:32 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 854 bytes --]

Petr Baudis wrote:
> 
> I want to avoid extra fork()s and exec()s. They seem to routinely matter
> in orders of magnitude of speed in tight loops.
> 

Give this a whirl. It's still slower than using the git-<something> 
form, but it's quite an improvement anyways.

#############

$ time for i in `seq 1 10000`; do git send-pack --help >/dev/null 2>&1; done

real    0m28.921s
user    0m12.626s
sys     0m14.219s
$ time for i in `seq 1 10000`; do ./git send-pack --help >/dev/null 
2>&1; done

real    0m12.129s
user    0m4.444s
sys     0m7.615s
$ time for i in `seq 1 10000`; do git-send-pack --help >/dev/null 2>&1; done

real    0m9.069s
user    0m3.481s
sys     0m5.558s

##############

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

[-- Attachment #2: git.c --]
[-- Type: text/x-csrc, Size: 3703 bytes --]

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <glob.h>

#ifndef PATH_MAX
# define PATH_MAX 4096
#endif

static const char git_usage[] =
	"Usage: git [ --version ] [ --lib=<GIT_LIB> ] COMMAND [ OPTIONS ] [ TARGET ]";

struct string_list {
	size_t len;
	char *str;
	struct string_list *next;
};

/* most gui terms set COLUMNS (although some don't export it) */
static int columns(void)
{
	char *col_string = getenv("COLUMNS");
	int n_cols = 0;

	if (col_string && (n_cols = atoi(col_string)) > 0)
		return n_cols;

	return 80;
}

static inline void mput_char(char c, unsigned int num)
{
	unsigned int i;

	for(i = 0; i < num; i++)
		putchar(c);
}

static void fmt_print_string_list(struct string_list *list, int longest)
{
	int cols;
	int space = longest + 1; /* space between start of string1 and string2 */
	int max_cols = columns() - 1;

	cols = max_cols / space;

	if(cols < 1) {
		cols = 1;
		space = 0;
	}

	while (list) {
		int c = cols;
		printf("  ");

		for(c = cols; c; c--) {
			if (!list)
				break;

			printf("%s", list->str);

			if (space && c != 1)
				mput_char(' ', space - list->len);

			list = list->next;
		}

		putchar('\n');
	}
}

static void usage(char *path, const char *fmt, ...)
	__attribute__((__format__(__printf__, 2, 3)));

static void usage(char *path, const char *fmt, ...)
{
	struct string_list *list, *tail;
	unsigned int longest = 0, i;
	glob_t gl;

	list = tail = NULL;

	if (!fmt)
		puts(git_usage);
	else {
		printf("git: ");
		va_list ap;
		va_start(ap, fmt);
		vprintf(fmt, ap);
		va_end(ap);
	}

	putchar('\n');

	if (!path)
		exit(1);

	if (chdir(path) < 0) {
		printf("git: '%s': %s\n", path, strerror(errno));
		exit(1);
	}

	printf("\ngit commands available in '%s'\n", path);
	printf("----------------------------");
	mput_char('-', strlen(path));
	putchar('\n');

	glob("git-*", 0, NULL, &gl);
	for (i = 0; i < gl.gl_pathc; i++) {
		int len = strlen(gl.gl_pathv[i] + 4);

		if(access(gl.gl_pathv[i], X_OK))
			continue;

		if (longest < len)
			longest = len;

		if (!tail)
			tail = list = malloc(sizeof(struct string_list));
		else {
			tail->next = malloc(sizeof(struct string_list));
			tail = tail->next;
		}
		tail->len = len;
		tail->str = gl.gl_pathv[i] + 4;
		tail->next = NULL;
	}

	fmt_print_string_list(list, longest);

	puts("\nman-pages can be reached through 'man git-<COMMAND>'\n");

	exit(1);
}

#define DEFAULT_GIT_LIB "/usr/bin"
#define GIT_VERSION "0.99.9.GIT"

int main(int argc, char **argv, char **envp)
{
	char git_command[PATH_MAX + 1];
	char *git_lib = getenv("GIT_LIB");
	char wd[PATH_MAX + 1], libdir[PATH_MAX + 1];

	getcwd(wd, PATH_MAX);

	if(argc == 1) {
		if (git_lib)
			usage(git_lib, NULL);

		usage(DEFAULT_GIT_LIB, NULL);
	}

	argv++;
	/* always *argv since we inc it if we hit an option */
	while (argc-- && !strncmp(*argv, "--", 2)) {
		char *arg = (*argv++) + 2;

		if (!strncmp(arg, "lib=", 3))
			git_lib = arg + 4;
		else if (!strncmp(arg, "version", 7)) {
			printf("git version %s\n", GIT_VERSION);
			exit(0);
		}
		else
			usage (NULL, NULL);
	}

	if (!git_lib)
		git_lib = DEFAULT_GIT_LIB;

	/* allow relative paths, but run with exact */
	if (chdir(git_lib)) {
		printf("git: '%s': %s\n", git_lib, strerror(errno));
		exit (1);
	}

	getcwd(libdir, sizeof(libdir));
	chdir(wd);

	snprintf(git_command, sizeof(git_command), "%s/git-%s", libdir, *argv);

	if (access(git_command, X_OK))
		usage(git_lib, "'%s' is not a git-command", *argv);

	if (execve(git_command, argv, envp)) {
		printf("Failed to run command '%s': %s\n", git_command, strerror(errno));
		return 1;
	}

	/* not reached */

	return 0;
}

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-07 17:27                   ` Junio C Hamano
@ 2005-11-10  9:49                     ` Petr Baudis
  0 siblings, 0 replies; 28+ messages in thread
From: Petr Baudis @ 2005-11-10  9:49 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Linus Torvalds, git

Dear diary, on Mon, Nov 07, 2005 at 06:27:48PM CET, I got a letter
where Junio C Hamano <junkio@cox.net> said that...
> It looks like that both you and Pasky are not so enthusiastic
> about moving thing out of /usr/bin/, so let's keep things the
> way they are for 1.0 release and rethink when we do 2.0 (or
> whatever comes after 1.0).

Well, just to clarify - I'm personally not opposed to it, as long as it
gets done in some timeframe where it won't drastically break backwards
compatibility (that is, not in 1.0.1 or such, but e.g. at some right
moment before 1.0 or at the start of the next development series
whenever that happens), and as long as I get a way to get the path
of the git commands by a single fork().

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06 14:05       ` Johannes Schindelin
@ 2005-11-06 15:03         ` Nikolai Weibull
  0 siblings, 0 replies; 28+ messages in thread
From: Nikolai Weibull @ 2005-11-06 15:03 UTC (permalink / raw)
  To: git

Johannes Schindelin wrote:

> Wouldn't it be lovely if the auto-completion files, as well as the
> list of available programs in git.sh (or git-help.sh), would be
> autogenerated?

Yes.

        nikolai (oblivious to irony and rhetorical questions)

-- 
Nikolai Weibull: now available free of charge at http://bitwi.se/!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06 13:13     ` Nikolai Weibull
@ 2005-11-06 14:05       ` Johannes Schindelin
  2005-11-06 15:03         ` Nikolai Weibull
  0 siblings, 1 reply; 28+ messages in thread
From: Johannes Schindelin @ 2005-11-06 14:05 UTC (permalink / raw)
  To: Nikolai Weibull; +Cc: git

Hi,

Wouldn't it be lovely if the auto-completion files, as well as the list of 
available programs in git.sh (or git-help.sh), would be autogenerated?

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-06  8:56   ` Ben Clifford
@ 2005-11-06 13:13     ` Nikolai Weibull
  2005-11-06 14:05       ` Johannes Schindelin
  0 siblings, 1 reply; 28+ messages in thread
From: Nikolai Weibull @ 2005-11-06 13:13 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 897 bytes --]

Ben Clifford wrote:

> On 6 Nov 2005, at 08:43, Yaacov Akiba Slama wrote:

> > In addition custom tab completion can be quite easily added to bash
> > and zsh.

> Anyone done this already for git? I've been slowly adding bits to
> Paolo Giarrusso's bash/stg tab completion code to provide some
> completion for cogito, but haven't got round to git yet.

Here’s something I’m planning on sending to the Zsh list.  It’s still
incomplete, and I don’t know all the commands well enough yet to write
the more generic completion parts (like completing repositories,
branches, commit ids, remotes, and such).  Perhaps someone can help out
with that?  All comments welcome.

        nikolai

-- 
Nikolai Weibull: now available free of charge at http://bitwi.se/!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}

[-- Attachment #2: _git --]
[-- Type: text/plain, Size: 29048 bytes --]

#compdef git-apply git-checkout-index git-commit-tree git-hash-object git-init-db git-merge-index git-mktag git-pack-objects git-prune-packed git-read-tree git-unpack-objects git-update-index git-write-tree git-cat-file git-diff-index git-diff-files git-diff-stages git-diff-tree git-fsck-objects git-ls-files git-ls-tree git-merge-base git-rev-list git-show-index git-tar-tree git-unpack-file git-var git-verify-pack git-clone-pack git-fetch-pack git-http-fetch git-local-fetch git-peek-remote git-receive-pack git-send-pack git-ssh-fetch git-ssh-upload git-update-server-info git-upload-pack git-add git-applymbox git-bisect git-branch git-checkout git-cherry-pick git-clone git-commit git-diff git-fetch git-format-patch git-grep git-log git-ls-remote git-merge git-octopus git-pull git-push git-rebase git-rename git-repack git-reset git-resolve git-revert git-shortlog git-show-branch git-status git-verify-tag git-whatchanged git-applypatch git-archimport git-convert-objects git-cvsimport git-merge-one-file git-prune git-relink git-sh-setup git-tag git-cherry git-count-objects git-daemon git-get-tar-commit-id git-mailinfo git-mailsplit git-patch-id git-parse-remote git-request-pull git-rev-parse git-send-email git-stripspace

# TODO: most commands need a valid git repository to run, so add a check for it
# so that we can make our handling a little bit cleaner (need to deal with
# GIT_DIR=... stuff as pre-command modifier)

# TODO: tree-ish should probably be using __git_comimit_ids2

local ret=1

_call_function ret _$words[1]

# TODO: perhaps only allow *.patch for files
_git-apply () {
  _arguments \
    '*--exclude=-[skip files matching specified pattern]:file pattern' \
    '*--no-merge[do not use merge behavior]' \
    '*--stat[output diffstat for the input]' \
    '*--summary[output summary of git-diff extended headers]' \
    '*--check[check if patches are applicable]' \
    '*--index[make sure that the patch is applicable to the index]' \
    '*--show-files[show summary of files that are affected by the patches]' \
    '*--apply[apply patches that would otherwise not be applied]' \
    '*:file:_files' && ret=0
}

_git-checkout-index () {
  _arguments -S \
    '(-u --index)'{-u,--index}'[update stat information in index]' \
    '(-q --quiet)'{-q,--quiet}'[do not complain about existing files or missing files]' \
    '(-f --force)'{-f,--force}'[force overwrite of existing files]' \
    '(-a --all)'{-a,--all}'[check out all files in the index]' \
    '(-n --no-create)'{-n,--no-create}'[do not checkout new files]' \
    '*--prefix=-[prefix to use when creating files]:directory:_directories' \
    '*:file:_files' && ret=0
}

_git-commit-tree () {
  if (( CURRENT == 2 )); then
    _guard "[[:xdigit:]]#" "tree object" && ret=0
  else
    local context state line
    typeset -A opt_args

    _arguments \
    '*-p: :_guard "[[\:xdigit\:]]#" "commit object that should act as a parent to the tree"' \
    '*: :->nothing'

    ret=0
  fi
}

_git-hash-object () {
  _arguments \
    '-t[the type of object to create]:object type:((blob\:"a blob of data"
                                                    commit\:"a tree with parent commits"
                                                    tag\:"a symbolic name for another object"
                                                    tree\:"a recursive tree of blobs"))' \
    '-w[write the object to the object database]' \
    '*:file:_files' && ret=0
}

_git-init-db () {
  _arguments \
    '--template=-[directory to use as a template for the object database]:directory:_directories' && ret=0
}

_git-merge-index () {
  if (( CURRENT > 2 )) && [[ $words[CURRENT-1] != -[oq] ]]; then
    _arguments -S \
      '-a[run merge against all files in the index that need merging]' \
      '*:file:_files' && ret=0
  else
    typeset -a arguments

    (( CURRENT == 2 )) && arguments+='-o[skip failed merges]'
    (( CURRENT == 2 || CURRENT == 3 )) && arguments+='(-o)-q[do not complain about failed merges]'
    (( 2 <= CURRENT && CURRENT <= 4 )) && arguments+='*:merge program:_files -g "*(*)"'

    _arguments $arguments && ret=0
  fi
}

_git-mktag () {
  _message 'no arguments allowed; only accepts tags on standard input'
}

_git-pack-objects () {
  _arguments \
    '--incremental[ignore objects that have already been packed]' \
    '--window=-[number of objects to use per delta compression]' \
    '--depth=-[maximum delta depth]' \
    '(:)--stdout[write the pack to standard output]' \
    ':base-name:_files' && ret=0
}

_git-prune-packed () {
  _arguments \
    '-n[only list the objects that would be removed]' && ret=0
}

# TODO: --trivial and --reset (undocumented)
_git-read-tree () {
  if (( CURRENT == 2 )); then
    _arguments \
      ': :_guard "[[\:xdigit\:]]#" "tree-ish to be read into the index"' && ret=0
  elif [[ $words[2] == -m ]]; then
    _arguments \
      '-u[update the work tree after successful merge]' \
      '-i[update only the index; ignore changes in work tree]' \
      '2: :_guard "[[\:xdigit\:]]#" "first tree-ish to be read/merged"' \
      '3: :_guard "[[\:xdigit\:]]#" "second tree-ish to be read/merged"' \
      '4: :_guard "[[\:xdigit\:]]#" "third tree-ish to be read/merged"' && ret=0
  else
    _message 'no more arguments'
  fi
}

_git-unpack-objects () {
  _arguments \
    '-n[only list the objects that would be unpacked]' \
    '-q[run quietly]' && ret=0
}

_git-update-index () {
  _arguments -S \
    '-q[run quietly]' \
    '--add[add files not already in the index]' \
    '--remove[remove files that are in the index but are missing from the work tree]' \
    '--refresh[refresh the index]' \
    '--ignore-missing[ignore missing files when refreshing the index]' \
    '--cacheinfo[insert information directly into the cache]: :_guard "[0-7]#" "octal file mode": :_guard "[[\:xdigit\:]]#" "object id":file:_files' \
    '--info-only[only insert files object-IDs into index]' \
    '--force-remove[remove files from both work tree and the index]' \
    '--replace[replace files already in the index if necessary]' \
    '--stdin[read list of paths from standard input]' \
    '-z[paths are separated with NUL instead of LF for --stdin]' \
    '*:file:_files' && ret=0
}

_git-write-tree () {
  _arguments \
    '--missing-ok[ignore objects in the index that are missing in the object database]' && ret=0
}

_git-cat-file () {
  if (( CURRENT == 2 )); then
    _arguments \
      '-t[show the type of the given object]' \
      '-s[show the size of the given object]' \
      '*: :_values "object type" blob commit tag tree' && ret=0
  elif (( CURRENT == 3 )); then
    _guard "[[:xdigit:]]#" "object id" && ret=0
  else
    _message 'no more arguments'
  fi
}

typeset -ga diff_args

# TODO: -s and --diff-filter are undocumented
diff_args=(
  '-p[generate diff in patch format]'
  '-u[synonym for -p]'
  '-z[use NUL termination on output]'
  '-l-[number of rename/copy targets to run]: :_guard "[[\:digit\:]]#" number'
  '--name-only[show only names of changed files]'
  '--name-status[show only names and status of changed files]'
  '-R[do a reverse diff]'
  '-S-[look for differences that contain the given string]:string'
  '-s[do not produce any output]'
  '-O-[output patch in the order of glob-pattern lines in given file]:file:_files'
  '--diff-filter=-[filter to apply to diff]'
  '--pickaxe-all[when -S finds a change, show all changes in that changeset]'
  '-B-[break complete rewrite changes into pairs of given size]: :_guard "[[\:digit\:]]#" size'
  '-M-[detect renames with given score]: :_guard "[[\:digit\:]]#" size'
  '-C-[detect copies as well as renames with given score]: :_guard "[[\:digit\:]]#" size'
  '--find-copies-harder[try harder to find copies]'
)

typeset -g pretty_arg=
pretty_arg='--pretty=-[pretty print commit messages]::pretty print:((raw\:"the raw commits"
                                                                     medium\:"most parts of the messages"
                                                                     short\:"few headers and only subject of messages"
                                                                     full\:"all parts of the commit messages"
                                                                     oneline\:"commit-ids and subject of messages"))'

_git-diff-index () {
  _arguments -S \
    $diff_args \
    '-r[recurse into subdirectories]' \
    '-m[flag non-checked-out files as up-to-date]' \
    '--cached[do not consider the work tree at all]' \
    ': :_guard "[[\:xdigit\:]]#" "tree-ish"' \
    '*:file:_files' && ret=0
}

_git-diff-files () {
  _arguments \
    $diff_args \
    '-q[do not complain about nonexisting files]' \
    '*:file:_files' && ret=0
}

_git-diff-stages () {
  _arguments \
    $diff_args \
    ': :_guard "[[\:digit\:]]#" "stage 1 number"' \
    ': :_guard "[[\:digit\:]]#" "stage 2 number"' \
    '*:file:_files' && ret=0
}

_git-diff-tree () {
  _arguments -S \
    $diff_args \
    $pretty_arg \
    '-r[recurse into subdirectories]' \
    '-t[show tree entry itself as well as subtrees (implies -r)]' \
    '-m[show merge commits]' \
    '-v[show verbose headers]' \
    '--stdin[read commit and tree information from standard input]' \
    '--root[show diff against the empty tree]' \
    ': :_guard "[[\:xdigit\:]]#" "tree-ish"' \
    ':: :_guard "[[\:xdigit\:]]#" "tree-ish"' \
    '*:file:_files' && ret=0
}

_git-fsck-objects () {
  _arguments -S \
    '--cache[consider objects recorded in the index as head nodes for reachability traces]' \
    '--full[check all object directories]'
    '--root[show root nodes]' \
    '--standalone[check only the current object directory]' \
    '--strict[do strict checking]' \
    '--tags[show tags]' \
    '--unreachable[show objects that are unreferenced in the object database]' \
    '*: :_guard "[[\:xdigit\:]]#" "object id"' && ret=0
}

# TODO: need to handle names with whitespace
# TODO: do we actually need _wanted?
__git_files () {
  local expl

  # TODO: deal with GIT_DIR
  if [[ $_git_file_cache_pwd != $PWD ]]; then
    _git_file_cache=("${(@f)$(git-ls-files 2>/dev/null)}")
    _git_file_cache_pwd=$PWD
  fi

  _wanted files expl 'index file' _multi_parts / _git_file_cache
}

__git_tree_files () {
  local expl
  typeset -a tree_file_cache

  tree_file_cache=("${(@f)$(git-ls-tree -r $1 | awk '{print $4}')}")

  _wanted files expl 'tree file' _multi_parts / tree_file_cache
}

# TODO: am I using _wanted correctly?  Need to learn _wanted and _describe
__git_commit_ids () {
  local commits

  commits=("${(@f)$(git-rev-list HEAD 2>/dev/null)}")
  if (( $? == 0 )); then
    _wanted commits expl 'commit ids' compadd - $commits
  else
    _message 'not a git repository'
  fi
}

__git_commit_ids2 () {
  compset -P '\\\^'
  __git_commit_ids
}

__git_heads () {
  local expl heads

  heads=("${(@f)$(ls "$(git-rev-parse 2>/dev/null)/refs/heads" 2>/dev/null)}")
  if (( $? == 0 )); then
    _wanted heads expl 'heads' compadd - HEAD $heads
  else
    _message 'not a git repository'
  fi
}

_git-ls-files () {
  _arguments -S \
  '(-c --cached)'{-c,--cached}'[show cached files in the output]' \
  '(-d --deleted)'{-d,--deleted}'[show deleted files in the output]' \
  '(-i --ignored)'{-i,--ignored}'[show ignored files in the output]' \
  '(-k --killed)'{-k,--killed}'[show killed files in the output]' \
  '(-m --modified)'{-m,--modified}'[show modified files in the output]' \
  '(-o --others)'{-o,--others}'[show other files in the output]' \
  '(-s --stage)'{-s,--stage}'[show stage files in the output]' \
  '-t[identify each files status]' \
  '(-u --unmerged)'{-u,--unmerged}'[show unmerged files in the output]' \
  '*'{-x,--exclude=-}'[skip files matching given pattern]:file pattern' \
  '*'{-X,--exclude-from=-}'[skip files matching patterns in given file]:file:_files' \
  '*--exclude-per-directory=-[skip directories matching patterns in given file]:file:_files' \
  '-z[use NUL termination on output]' \
  '*:index file:__git_files' && ret=0
}

_git-ls-tree () {
  local tree

  for word in $words[2,-1]; do
    if [[ $word != -* ]]; then
      tree=$word
      break
    fi
  done

  _arguments \
  '-d[do not show children of given tree]' \
  '-r[recurse into subdirectories]' \
  '-z[use NUL termination on output]' \
  ': :_guard "[[\:xdigit\:]]#" "tree-ish"' \
  '*:tree file:{[[ -n $tree ]] && __git_tree_files $tree}' && ret=0
}

_git-merge-base () {
  _arguments \
  '(-a --all)'{-a,--all}'[show all common ancestors]' \
  ':commit id 1:__git_commit_ids' \
  ':commit id 2:__git_commit_ids' && ret=0
}

# TODO: --show-breaks only valid if --merge-order specified
# TODO --all undocumented
_git-rev-list () {
  _arguments \
  $pretty_arg \
  '--all[show all commits]' \
  '--bisect[show only the middlemost commit object]' \
  '--objects[show object ids of objects referenced by the listed commits]' \
  '--max-age[maximum age of commits to output]: :_guard "[[\:digit\:]]#" number' \
  '--max-count[maximum number of commits to output]: :_guard "[[\:digit\:]]#" timestamp' \
  '--merge-order[decompose into minimal and maximal epochs]' \
  '--min-age[minimum age of commits to output]: :_guard "[[\:digit\:]]#" timestamp' \
  '--objects[show all objects]' \
  '--parents[show parent commits]' \
  '--show-breaks[show commit prefixes]' \
  '--unpacked[show only unpacked commits]' \
  '--header[show commit headers]' \
  '*:commit id:__git_commit_ids2' && ret=0
}

_git-show-index () {
  _message 'no arguments allowed; accepts index file on standard input'
}

_git-tar-tree () {
  _arguments \
    ': :_guard "[[\:xdigit\:]]#" "tree-ish"' \
    ':base-name:_files' && ret=0
}

_git-unpack-file () {
  _arguments \
    ': :_guard "[[\:xdigit\:]]#" "blob id"' && ret=0
}

_git-var () {
  _arguments \
    - variables \
      '-l[show logical variables]' \
      ':variable' && ret=0
}

_git-verify-pack () {
  _arguments -S \
    '-v[show objects contained in pack]' \
    '*:index file:_files -g "*.idx"' && ret=0
}
 
# FIXME: these should be imported from _ssh
# TODO: this should take -/ to only get directories
_remote_files () {
  # There should be coloring based on all the different ls -F classifiers.
  local expl rempat remfiles remdispf remdispd args suf ret=1

  if zstyle -T ":completion:${curcontext}:files" remote-access; then
    zparseopts -D -E -a args p: 1 2 4 6 F:
    if [[ -z $QIPREFIX ]]
    then rempat="${PREFIX%%[^./][^/]#}\*"
    else rempat="${(q)PREFIX%%[^./][^/]#}\*"
    fi
    remfiles=(${(M)${(f)"$(_call_program files ssh $args -a -x ${IPREFIX%:} ls -d1FL "$rempat" 2>/dev/null)"}%%[^/]#(|/)})
    compset -P '*/'
    compset -S '/*' || suf='remote file'

#    remdispf=(${remfiles:#*/})
    remdispd=(${(M)remfiles:#*/})

    _tags files
    while _tags; do
      while _next_label files expl ${suf:-remote directory}; do
#        [[ -n $suf ]] && compadd "$@" "$expl[@]" -d remdispf \
#	    ${(q)remdispf%[*=@|]} && ret=0 
	compadd ${suf:+-S/} "$@" "$expl[@]" -d remdispd \
	    ${(q)remdispd%/} && ret=0
      done
      (( ret )) || return 0
    done
    return ret
  else
    _message -e remote-files 'remote file'
  fi
}

typeset -g exec_arg=
exec_arg='--exec=-[specify path to git-upload-pack on remote side]:remote path'

__git-remote-repository () {
  local service

  service= _ssh

  if compset -P '*:'; then
    _remote_files && ret=0
  else
    _alternative \
      'directories::_directories' \
      'hosts:host:_ssh_hosts -S:' && ret=0
  fi
}

__git-any-repositories () {
  _alternative \
    'files::_files' \
    'remote repositories::__git-remote-repository' && ret=0
}

__git_ref_spec () {
} 

# TODO: how about curcontext? (-C)
__git-clone_or_fetch-pack () {
  _arguments \
    $exec_arg \
    '-q[run quietly]' \
    ':remote repository:__git-remote-repository' \
    '*:head:__git_heads' && ret=0
}

_git-clone-pack () {
  __git-clone_or_fetch-pack
}

_git-fetch-pack () {
  __git-clone_or_fetch-pack
}

typeset -ga fetch_args

fetch_args=(
  '-a[fetch all objects]'
  '-c[fetch commit objects]'
  '--recover[recover from a failed fetch]'
  '-t[fetch trees associated with commit objects]'
  '-v[show what is downloaded]'
  '-w[write out the given commit-id to the given file]:new file'
)

__git-http_or_ssh-fetch () {
  _arguments \
    $fetch_args \
    ':commit id:__git_commit_ids' \
    ':URL:_urls' && ret=0
}

# TODO: __git_commit_ids appropriate here?
_git-http-fetch () {
  __git-http_or_ssh-fetch
}

_git-local-fetch () {
  _arguments \
    $fetch_args \
    '-l[hard-link objects]' \
    '-n[do not copy objects]' \
    '-s[sym-link objects]' \
    ':commit id:__git_commit_ids' \
    ':directory:_directories' && ret=0
}

_git-peek-remote () {
  _arguments \
    $exec_arg \
    ':remote repository:__git-remote-repository' && ret=0
}

_git-receive-pack () {
  _arguments \
    ':directory:_directories' && ret=0
}

_git-send-pack () {
  _arguments \
    $exec_arg \
    '--all[update all refs that exist locally]' \
    '--force[update remote orphaned refs]' \
    ':remote repository:__git-remote-repository' \
    '*:remote refs' && ret=0
}

_git-ssh-fetch () {
  __git-http_or_ssh-fetch
}

_git-ssh-upload () {
  __git-http_or_ssh-fetch
}

_git-update-server-info () {
  _arguments \
    '(-f --force)'{-f,--force}'[update the info files from scratch]'
}

_git-upload-pack () {
  _arguments \
    ':directory:_directories' && ret=0
}

_git-add () {
  _arguments \
    '-n[do not actually add files; only show which ones would be added]' \
    '-v[show files as they are added]' \
    '*:file:_files' && ret=0
}

__git_signoff_file () {
  _alternative \
    'signoffs:signoff:(yes true me please)' \
    'files::_files' && ret=0
}

# TODO: for -c: add support for .dotest/ prefix
_git-applymbox () {
  _arguments \
    '-k[do not modify Subject: header]' \
    '-q[apply patches interactively]' \
    '-u[encode commit information in UTF-8]' \
    '(1)-c[restart command after fixing an unclean patch]:patch:_files' \
    ':mbox file:_files' \
    '::signoff file:__git_signoff_file' && ret=0
}

_git-bisect () {
  local bisect_cmds

  bisect_cmds=(
    bad:"mark current or given revision as bad"
    good:"mark current or given revision as good"
    log:"show the log of the current bisection"
    next:"find next bisection to test and check it out"
    replay:"replay a bisection log"
    reset:"finish bisection search and return to the given branch (or master)"
    start:"reset bisection state and start a new bisection"
    visualize:"show the remaining revisions in gitk"
  )

  if (( CURRENT == 2 )); then
    _describe -t command "git-bisect commands" bisect_cmds && ret=0
  else
    case $words[2] in
      (bad)
        _arguments \
          '2:revision:__git_commit_ids' && ret=0
        ;;
      (good)
        _arguments \
          '*:revision:__git_commit_ids' && ret=0
        ;;
      (replay)
        _arguments \
          '2:file:_files' && ret=0
        ;;
      (reset)
        _arguments \
          '2:branch:__git_heads' && ret=0
        ;;
      (*)
        _message 'no arguments allowed' && ret=0
        ;;
    esac
  fi
}

_git-branch () {
  _arguments \
    ':branch-name'
    ':base branch:__git_heads' && ret=0
}

# TODO: here, branch can be any object ID that resolves to a commit.  How do we
# deal with that? _alternative on __git_heads, __git_tags, and __git_commit_ids?
# git-rev-parse?
_git-checkout () {
  _arguments \
    '-f[force a complete re-read]' \
    '-b[create a new branch based at given branch]:branch-name' \
    ':branch:__git_heads' && ret=0
}

_git-cherry-pick () {
  _arguments \
    '(-n --no-commit)'{-n,--no-commit}'[do not make the actually commit]' \
    '(-r --replay)'{-r,--replay}'[use the original commit message intact]' \
    ':commit id:__git_commit_ids' && ret=0
}

# TODO: should support rsync completion here as well
_git-clone () {
  _arguments \
    '(-l --local)'{-l,--local}'[perform a local cloning of a repository]' \
    '(-s --shared)'{-s,--shared}'[share the objects with the source repository]' \
    '(-q --quiet)'{-q,--quiet}'[operate quietly]' \
    '-n[do not checkout HEAD after clone is complete]' \
    '(-u --upload-pack)'{-u,--uploadpack}'[specify path to git-upload-pack on remote side]:remote path' \
    ':repository:__git-any-repositories' \
    ':directory:_directories' && ret=0
}

_git-commit () {
  _arguments -S \
    '(-a --all)'{-a,--all}'[update all paths in the index file]' \
    '(-s --signoff)'{-s,--signoff}'[add Signed-off-by line at the end of the commit message]' \
    '(-v --verify)'{-v,--verify}'[look for suspicious lines the commit introduces]' \
    '(-n --no-verify)'{-n,--no-verify}'[do not look for suspicious lines the commit introduces]' \
    '(-e --edit)'{-e,--edit}'[edit the commit message before committing]' \
    '*:file:_files' \
    - '(message)' \ 
      '(-c -C --reedit-message --reuse-message)'{-c,--reedit-message=}'[use existing commit object and edit log message]::commit id:__git_commit_ids' \
      '(-c -C --reedit-message --reuse-message)'{-c,--reuse-message=}'[use existing commit object with same log message]::commit id:__git_commit_ids' \
      '(-F --file)'{-F,--file=}'[read commit message from given file]:file:_files' \
      '(-m --message)'{-m,--message=}'[use the given message as the commit message]:message' && ret=0
}

_git-diff () {
  _arguments \
    $diff_args \
    '::commit id 1:__git_commit_ids2' \
    '::commit id 2:__git_commit_ids2' \
    '*:file:_files' && ret=0
}

# TODO: --tags undocumented
_git-fetch () {
  _arguments \
    '(-a --append)'{-a,--append}'[append fetched refs instead of overwriting]' \
    '(-f --force)'{-f,--force}'[allow refs that are not ancestors to be updated]' \
    '(-t --tags)'{-t,--tags}'[use tags]' \
    '(-u --update-head-ok)'{-u,--update-head-ok}'[allow updates of current branch head]' \
    ':repository:__git-any-repositories' \
    '*:refspec:__git_ref_spec' && ret=0
}

_git-format-patch () {
  _arguments \
    '(-a --author)'{-a,--author}'[output From: header for your own commits as well]' \
    '--date[output Date: header for your own commits as well]' \
    '-o[store resulting files in given directory]:directory:_directories' \
    '-k[do not strip/add \[PATCH\] from the first line of the commit message]' \
    '--mbox[use true mbox formatted output]' \
    '-n[name output in \[PATCH n/m\] format]' \
    ':their commit id:__git_commit_ids2' \
    '::my commit id:__git_commit_ids2' && ret=0
}


# TODO: repository needs fixing
# TODO: reference needs fixing
# TODO: references can be extracted with this command: $(ls-remote ./.)
# TODO: tags can be extracted with this command: $(ls-remote --tags ./.)
_git-ls-remote () {
  _arguments \
    '--heads[show only refs under refs/heads]' \
    '--tags[show only refs under refs/tags]' \
    ':repository:__git-any-repositories' \
    '*:reference' && ret=0
}

# TODO: document merge strategies
# TODO: <head> argument right?
# TODO: <remote> argument right?
_git-merge () {
  _arguments \
    '(-n --no-summary)'{-n,--no-summary}'[do not show diffstat at end of merge]' \
    {-s,--strategy}'[use given merge strategy]:strategy:(octopus recursive resolve stupid)' \
    ':merge message' \
    ':head:__git_commit_ids2' \
    ':remote:__git_commit_ids2' && ret=0
}

_git-mv () {
  _arguments \
    '-f[force renaming/moving even if targets exist]' \
    '-k[skip move/renames that would lead to errors]' \
    '-n[only show what would happen]' \
    '*:file:_files' && ret=0
}

_git-octupus () {
  _message 'no arguments allowed' && ret=0
}

_git-rebase () {
  _arguments \
    ':upstream branch:__git_commit_ids2' \
    '::working branch:__git_commit_ids2' && ret=0
}

_git-rename () {
  _arguments \
    ':source index file:__git_files' \
    ':destination file:_files' && ret=0
}

# TODO: -l option (--local)
_git-repack () {
  _arguments \
    '-a[pack all objects into a single pack]' \
    '-d[remove redundant packs after packing]' \
    '-n[do not update server information]' && ret=0
}

_git-reset () {
  _arguments \
    - (levels) \
      '--mixed[like --soft but report what has not been updated (default)]' \
      '--soft[do not touch the index file nor the working tree]' \
      '--hard[match the working tree and index to the given tree]' \
      ':commit-ish:__git_commit_ids2' && ret=0
}

_git-resolve () {
  _arguments \
    ':current commit:__git_commit_ids2' \
    ':merged commit:__git_commit_ids2' \
    ':commit message'
}

_git-revert () {
  _arguments \
    '(-n --no-commit)'{-n,--no-commit}'[do not commit the reversion]'
      ':commit:__git_commit_ids2' && ret=0
}

_git-shortlog () {
  _message 'no arguments allowed' && ret=0
}

# TODO: reference ($GIT_DIR/refs)
_git-show-branch () {
  _arguments \
    '--all[show all refs under $GIT_DIR/refs]' \
    '--heads[show all refs under $GIT_DIR/refs/heads]' \
    '--independent[show only the reference that can not be reached from any of the other]' \
    '--list[do not display any commit ancestry]' \
    '--merge-base[act like "git-merge-base -a" but with two heads]' \
    '--more=-[go given number of commit beyond common ancestor (no ancestry if negative)]:number' \
    '--no-name[do not show naming strings for each commit]' \
    '--sha1-name[name commits with unique prefix of object names]' \
    '--tags[show all refs under $GIT_DIR/refs/tags]' \
    '*:reference' && ret=0
}

_git-status () {
  _message 'no arguments allowed' && ret=0
}

# TODO: tag
_git-verify-tag () {
  _arguments \
    ':tag'
}

# ---





_git-applypatch () {
  _arguments \
    ':message file:_files' \
    ':patch file:_files' \
    ':info file:_files' \
    '::signoff file:_files' && ret=0
}

_git-convert-objects () {
  _arguments \
    ': :_guard "[[:xdigit:]]#" "object id"' && ret=0
}




# TODO: right to use __git_commit_ids2?  Should be branches
_git-cherry () {
  _arguments \
    '-v[be verbose]' \
    ':upstream:__git_commit_ids2' \
    '::head:__git_commit_ids2' && ret=0
}

_git-count-objects () {
  _message 'no arguments allowed' && ret=0
}

# TODO: do better than _directory?
_git-daemon () {
  _arguments -S \
    '--export-all[allow pulling from all repositories without verification]' \
    '(--port)--inetd[run server as an inetd service]' \
    '--init-timeout=-[specify timeout between connection and request]' \
    '--port=-[specify port to listen to]' \
    '--syslog[log to syslog instead of stderr]' \
    '--timeout=-[specify timeout for sub-requests]' \
    '--verbose[log details about incoming connections and requested files]' \
    '*:repository:_directory' && ret=0
}

_git-get-tar-commit-id () {
  _message 'no arguments allowed; accepts tar-file on standard input' && ret=0
}

_git-mailinfo () {
  _arguments \
    '-k[do not strip/add \[PATCH\] from the first line of the commit message]' \
    '-u[encode commit information in UTF-8]' \
    ':message file:_files' \
    ':patch file:_files' && ret=0
}

_git-mailsplit () {
  _arguments \
    '-d-[specify number of leading zeros]: :_guard "[[\:digit\:]]#" "precision' \
    ':mbox file/directory:_files' \
    '::directory:_directories' && ret=0
}

_git-patch-id () {
  _message 'no arguments allowed; accepts patch on standard input' && ret=0
}



_git-request-pull () {
  _arguments \
    ':start commit:__git_commit_ids2' \
    ':url:_urls' \
    ':end commit:__git_commit_ids2'
}



_git-send-email () {
  _arguments \
    '--compose[use $EDITOR to edit an introductory message for the patch series]' \
    '--from[specify the sender of the emails]' \
    '--in-reply-to[specify the contents of the first In-Reply-To header]' \
    '--smtp-server[specify the outgoing smtp server]:smtp server:_hosts' \
    '--subject[specify the initial subject of the email thread]' \
    '--to[specify the primary recipient of the emails]' \
    - (chain) \
      '--chain-reply-to[each email will be sent as a reply to the previous one sent]' \
      '--no-chain-reply-to[all emails after the first will be sent as replies to the first one]' && ret=0
}

# TODO: still undocumented
_git-symref () {
}

_git-stripspace () {
  _message 'no arguments allowed; accepts input file on standard input' && ret=0
}

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
  2005-11-05 21:43 ` Yaacov Akiba Slama
@ 2005-11-06  8:56   ` Ben Clifford
  2005-11-06 13:13     ` Nikolai Weibull
  0 siblings, 1 reply; 28+ messages in thread
From: Ben Clifford @ 2005-11-06  8:56 UTC (permalink / raw)
  To: Yaacov Akiba Slama, git

On 6 Nov 2005, at 08:43, Yaacov Akiba Slama wrote:

> In addition custom tab completion can be quite easily added to bash  
> and zsh.

Anyone done this already for git? I've been slowly adding bits to  
Paolo Giarrusso's bash/stg tab completion code to provide some  
completion for cogito, but haven't got round to git yet.

-- 
Ben Clifford
http://www.hawaga.org.uk/ben/

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: git binary directory?
       [not found] <436D2269.6090605@slamail.org>
@ 2005-11-05 21:43 ` Yaacov Akiba Slama
  2005-11-06  8:56   ` Ben Clifford
  0 siblings, 1 reply; 28+ messages in thread
From: Yaacov Akiba Slama @ 2005-11-05 21:43 UTC (permalink / raw)
  To: git

Linus Torvalds wrote:

> So I'd really suggest that while the "git-<tab><tab>" thing is perhaps 
> useful, we'd actually be better off with an /usr/lib/git directory 
> where we put the git executables by default. And just put "git" into 
> /usr/bin.
>
> That way, people who _want_ to use "git-<tab><tab>" can just add the 
> git binary directory to their path and directly access all of them. 
> And others can just use the plain "git" interface.
>
> That would mean that I'd have to learn to use "git whatchanged" and 
> "git diff-tree" instead of "git-whatchanged" and "git-diff-tree", but 
> hey, it's why we have that "git" script in the first place.
>
> What do people think?

I agree with you. I have 3268 entries in /usr/bin and git commands 
account for 3.3% of this number which is a lot.

In addition custom tab completion can be quite easily added to bash and zsh.

If you indeed put only git in /usr/bin, a good idea would be perhaps to 
implement (svn does that for instance) : "git help" to have a simple 
list of command (this is almost already there),  and "git help  
<command>" which can give the same result as "man git-<command>" because 
it's not clear from "man git" that one needs to see the man pages of the 
commands listed in "Porcelain-ish command".



--yas

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2005-11-10  9:50 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-11-05 21:02 git binary directory? Linus Torvalds
2005-11-05 23:52 ` Linus Torvalds
2005-11-06  0:27   ` Linus Torvalds
2005-11-06  7:25     ` Junio C Hamano
2005-11-06  2:49 ` Junio C Hamano
2005-11-06  3:12   ` Horst von Brand
2005-11-06  5:00     ` Kay Sievers
2005-11-06  5:36       ` Junio C Hamano
2005-11-06  8:23         ` Petr Baudis
2005-11-06  8:33           ` Junio C Hamano
2005-11-06  8:28     ` Petr Baudis
2005-11-06  4:25   ` Linus Torvalds
2005-11-06  5:37     ` Junio C Hamano
2005-11-06 16:20       ` Linus Torvalds
2005-11-06 20:15         ` Junio C Hamano
2005-11-06 22:19           ` Petr Baudis
2005-11-07  0:08             ` Junio C Hamano
2005-11-07  0:43               ` Petr Baudis
2005-11-07  0:54                 ` Linus Torvalds
2005-11-07  9:45                   ` Petr Baudis
2005-11-07 17:27                   ` Junio C Hamano
2005-11-10  9:49                     ` Petr Baudis
2005-11-09 13:32                 ` Andreas Ericsson
     [not found] <436D2269.6090605@slamail.org>
2005-11-05 21:43 ` Yaacov Akiba Slama
2005-11-06  8:56   ` Ben Clifford
2005-11-06 13:13     ` Nikolai Weibull
2005-11-06 14:05       ` Johannes Schindelin
2005-11-06 15:03         ` Nikolai Weibull

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.