{"thread":{"id":"2434","subject":"[PATCH] C implementation of the 'git' program.","startedAt":"2005-11-10T18:26:31Z","lastAt":"2005-11-11T19:37:30Z","messageCount":9,"participants":["Andreas Ericsson","Linus Torvalds","Petr Baudis","Raja R Harinath","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"11490","messageId":"20051110182631.3C5615BF90@nox.op5.se","threadId":"2434","inReplyTo":null,"subject":"[PATCH] C implementation of the 'git' program.","fromName":"Andreas Ericsson","fromEmail":"exon@op5.se","sentAt":"2005-11-10T18:26:31Z","receivedAt":"2005-11-10T18:26:31Z","isPatch":true,"sender":{"key":"exon@op5.se","avatar":"https://gravatar.com/avatar/b948c4f759e868f8e721e545e37afe2cf89cfa8e2ee8b70a432f0d76aee39891?d=mp&s=160"},"body":"Subject: [PATCH] C implementation of the 'git' program.\n\nThis patch provides a C implementation of the 'git' program and introduces\nsupport for putting the git-* commands in their own directory. It also\nsaves some time on executing git-* commands in a tight loop and it prints\nthe currently available git commands in a nicely formatted list.\n\nThe location of the GIT_LIB can be obtained by running\n\n\tgit --lib\n\nwhich will hopefully give porcelainistas ample time to adapt their heavy-duty\nloops to use the programs in the library directly if they wish, although\nthat's strictly speaking not really necessary any more.\n\nSome timing values for 10000 invocations of git-var >&/dev/null;\ngit.sh: 24.194s\ngit.c: 9.044s\ngit-var: 7.377s\n\nThe git-<tab><tab> behaviour can still be obtained by adding\n\n\tPATH=$PATH:$(git --lib)\n\nto one's .profile.\n\nExperimental libraries can be used by either setting the environment variable\nGIT_LIB, or by using\n\n\tgit --lib=/some/experimental/lib\n\nAs a nice side-effect, the patch also fixes the problem with\n\tmake\n\tmake prefix=/usr install\n\nSigned-off-by: Andreas Ericsson <ae@op5.se>\n\n---\n\n Documentation/git.txt |    6 +\n Makefile              |   24 ++---\n git.c                 |  224 +++++++++++++++++++++++++++++++++++++++++++++++++\n git.sh                |   76 -----------------\n 4 files changed, 239 insertions(+), 91 deletions(-)\n create mode 100644 git.c\n delete mode 100755 git.sh\n\napplies-to: 6466c53ae80cddbb581c5fdb2332f9321fade867\nb2b97ed9901915dce573516e3a6f10a60bc0c04a\ndiff --git a/Documentation/git.txt b/Documentation/git.txt\nindex 2f9622f..848d09a 100644\n--- a/Documentation/git.txt\n+++ b/Documentation/git.txt\n@@ -8,7 +8,7 @@ git - the stupid content tracker\n \n SYNOPSIS\n --------\n-'git-<command>' <args>\n+'git' [--version] [--lib[=GIT_LIB]] [--help] <command> <args>\n \n DESCRIPTION\n -----------\n@@ -535,7 +535,9 @@ include::../README[]\n \n Author\n ------\n-Written by Linus Torvalds <torvalds@osdl.org> and the git-list <git@vger.kernel.org>.\n+git's founding father is Linus Torvalds <torvalds@osdl.org>.\n+The current git nurse is Junio C. Hamano <junkio@cox.net>.\n+Numerous contributions stem from the git-list <git@vger.kernel.org>.\n \n Documentation\n --------------\ndiff --git a/Makefile b/Makefile\nindex b202be1..80d865b 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -59,6 +59,8 @@ ALL_CFLAGS = $(CFLAGS)\n \n prefix = $(HOME)\n bindir = $(prefix)/bin\n+# XXX set libdir to bindir for now to not break the porcelain\n+libdir = $(bindir)\n template_dir = $(prefix)/share/git-core/templates/\n GIT_PYTHON_DIR = $(prefix)/share/git-core/python\n # DESTDIR=\n@@ -86,7 +88,7 @@ SCRIPT_SH = \\\n \tgit-prune.sh git-pull.sh git-push.sh git-rebase.sh \\\n \tgit-repack.sh git-request-pull.sh git-reset.sh \\\n \tgit-resolve.sh git-revert.sh git-sh-setup.sh git-status.sh \\\n-\tgit-tag.sh git-verify-tag.sh git-whatchanged.sh git.sh \\\n+\tgit-tag.sh git-verify-tag.sh git-whatchanged.sh \\\n \tgit-applymbox.sh git-applypatch.sh git-am.sh \\\n \tgit-merge.sh git-merge-stupid.sh git-merge-octopus.sh \\\n \tgit-merge-resolve.sh git-merge-ours.sh git-grep.sh\n@@ -323,19 +325,13 @@ SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)\n export prefix TAR INSTALL DESTDIR SHELL_PATH template_dir\n ### Build rules\n \n-all: $(PROGRAMS) $(SCRIPTS)\n+all: $(PROGRAMS) $(SCRIPTS) git\n \n-all:\n-\t$(MAKE) -C templates\n+git: git.c\n+\t$(CC) $(CFLAGS) $< -o $@ -DDEFAULT_GIT_LIB='\"$(libdir)\"' -DGIT_VERSION='\"$(GIT_VERSION)\"'\n \n-git: git.sh Makefile\n-\trm -f $@+ $@\n-\tsed -e '1s|#!.*/sh|#!$(call shq,$(SHELL_PATH))|' \\\n-\t    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n-\t    -e 's/@@X@@/$(X)/g' \\\n-\t    $(GIT_LIST_TWEAK) <$@.sh >$@+\n-\tchmod +x $@+\n-\tmv $@+ $@\n+# Force rebuild so that \"make prefix=<something> install\" Just Works.\n+.PHONY: git\n \n $(filter-out git,$(patsubst %.sh,%,$(SCRIPT_SH))) : % : %.sh\n \trm -f $@\n@@ -420,8 +416,10 @@ check:\n ### Installation rules\n \n install: $(PROGRAMS) $(SCRIPTS)\n+\t$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(libdir))\n+\t$(INSTALL) $(PROGRAMS) $(SCRIPTS) $(call shellquote,$(DESTDIR)$(libdir))\n \t$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(bindir))\n-\t$(INSTALL) $(PROGRAMS) $(SCRIPTS) $(call shellquote,$(DESTDIR)$(bindir))\n+\t$(INSTALL) git $(call shellquote,$(DESTDIR)$(bindir))\n \t$(MAKE) -C templates install\n \t$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(GIT_PYTHON_DIR))\n \t$(INSTALL) $(PYMODULES) $(call shellquote,$(DESTDIR)$(GIT_PYTHON_DIR))\ndiff --git a/git.c b/git.c\nnew file mode 100644\nindex 0000000..8c01723\n--- /dev/null\n+++ b/git.c\n@@ -0,0 +1,224 @@\n+#include <stdio.h>\n+#include <unistd.h>\n+#include <stdlib.h>\n+#include <string.h>\n+#include <errno.h>\n+#include <limits.h>\n+#include <stdarg.h>\n+#include <glob.h>\n+\n+#ifndef PATH_MAX\n+# define PATH_MAX 4096\n+#endif\n+\n+static const char git_usage[] =\n+\t\"Usage: git [--version] [--lib[=<GIT_LIB>]] COMMAND [ OPTIONS ]\";\n+\n+struct string_list {\n+\tsize_t len;\n+\tchar *str;\n+\tstruct string_list *next;\n+};\n+\n+/* most gui terms set COLUMNS (although some don't export it) */\n+static int columns(void)\n+{\n+\tchar *col_string = getenv(\"COLUMNS\");\n+\tint n_cols = 0;\n+\n+\tif (col_string && (n_cols = atoi(col_string)) > 0)\n+\t\treturn n_cols;\n+\n+\treturn 80;\n+}\n+\n+static inline void mput_char(char c, unsigned int num)\n+{\n+\tunsigned int i;\n+\n+\tfor(i = 0; i < num; i++)\n+\t\tputchar(c);\n+}\n+\n+static void fmt_print_string_list(struct string_list *list, int longest)\n+{\n+\tint cols;\n+\tint space = longest + 1; /* space between start of string1 and string2 */\n+\tint max_cols = columns() - 1;\n+\n+\tcols = max_cols / space;\n+\n+\tif(cols < 1) {\n+\t\tcols = 1;\n+\t\tspace = 0;\n+\t}\n+\n+\twhile (list) {\n+\t\tint c = cols;\n+\t\tprintf(\"  \");\n+\n+\t\tfor(c = cols; c; c--) {\n+\t\t\tif (!list)\n+\t\t\t\tbreak;\n+\n+\t\t\tprintf(\"%s\", list->str);\n+\n+\t\t\tif (space && c != 1)\n+\t\t\t\tmput_char(' ', space - list->len);\n+\n+\t\t\tlist = list->next;\n+\t\t}\n+\n+\t\tputchar('\\n');\n+\t}\n+}\n+\n+#ifdef __GNUC__\n+static void usage(char *path, const char *fmt, ...)\n+\t__attribute__((__format__(__printf__, 2, 3), __noreturn__));\n+#endif\n+\n+static void usage(char *path, const char *fmt, ...)\n+{\n+\tstruct string_list *list, *tail;\n+\tunsigned int longest = 0, i;\n+\tglob_t gl;\n+\n+\tlist = tail = NULL;\n+\n+\tif (!fmt)\n+\t\tputs(git_usage);\n+\telse {\n+\t\tprintf(\"git: \");\n+\t\tva_list ap;\n+\t\tva_start(ap, fmt);\n+\t\tvprintf(fmt, ap);\n+\t\tva_end(ap);\n+\t\tputchar('\\n');\n+\t}\n+\n+\tputchar('\\n');\n+\n+\tif (!path)\n+\t\texit(1);\n+\n+\tif (chdir(path) < 0) {\n+\t\tprintf(\"git: '%s': %s\\n\", path, strerror(errno));\n+\t\texit(1);\n+\t}\n+\n+\ti = glob(\"git-*\", 0, NULL, &gl);\n+\tif (i) {\n+\t\tswitch(i) {\n+\t\tcase GLOB_NOSPACE:\n+\t\t\tputs(\"Out of memory while glob()'ing commands\");\n+\t\t\texit(2);\n+\t\tcase GLOB_ABORTED:\n+\t\t\tprintf(\"'%s': Read error: %s\\n\", path, strerror(errno));\n+\t\t\texit(2);\n+\t\tcase GLOB_NOMATCH:\n+\t\t\tprintf(\"No git commands available in '%s'.\\n\", path);\n+\t\t\tprintf(\"Do you need to specify --lib or set GIT_LIB?\\n\");\n+\t\t\texit(1);\n+\t\t}\n+\t}\n+\n+\tfor (i = 0; i < gl.gl_pathc; i++) {\n+\t\tint len = strlen(gl.gl_pathv[i] + 4);\n+\n+\t\tif(access(gl.gl_pathv[i], X_OK))\n+\t\t\tcontinue;\n+\n+\t\tif (longest < len)\n+\t\t\tlongest = len;\n+\n+\t\tif (!tail)\n+\t\t\ttail = list = malloc(sizeof(struct string_list));\n+\t\telse {\n+\t\t\ttail->next = malloc(sizeof(struct string_list));\n+\t\t\ttail = tail->next;\n+\t\t}\n+\t\ttail->len = len;\n+\t\ttail->str = gl.gl_pathv[i] + 4;\n+\t\ttail->next = NULL;\n+\t}\n+\n+\tprintf(\"git commands available in '%s'\\n\", path);\n+\tprintf(\"----------------------------\");\n+\tmput_char('-', strlen(path));\n+\tputchar('\\n');\n+\tfmt_print_string_list(list, longest);\n+\n+\tputs(\"\\nman-pages can be reached through 'man git-<COMMAND>'\\n\");\n+\n+\texit(1);\n+}\n+\n+int main(int argc, char **argv, char **envp)\n+{\n+\tchar git_command[PATH_MAX + 1];\n+\tchar wd[PATH_MAX + 1];\n+\tchar *git_lib = getenv(\"GIT_LIB\");\n+\tint i, len;\n+\n+\tgetcwd(wd, PATH_MAX);\n+\n+\tif (!git_lib)\n+\t\tgit_lib = DEFAULT_GIT_LIB;\n+\n+\tif (argc == 1)\n+\t\tusage(git_lib, NULL);\n+\n+\tfor (i = 1; i < argc; i++) {\n+\t\tchar *arg = argv[i];\n+\n+\t\tif (strncmp(arg, \"--\", 2))\n+\t\t\tbreak;\n+\n+\t\targ += 2;\n+\n+\t\tif (!strncmp(arg, \"lib\", 3)) {\n+\t\t\targ += 3;\n+\t\t\tif (*arg == '=')\n+\t\t\t\tgit_lib = arg + 1;\n+\t\t\telse {\n+\t\t\t\tputs(git_lib);\n+\t\t\t\texit(0);\n+\t\t\t}\n+\t\t}\n+\t\telse if (!strcmp(arg, \"version\")) {\n+\t\t\tprintf(\"git version %s\\n\", GIT_VERSION);\n+\t\t\texit(0);\n+\t\t}\n+\t\telse if (!strcmp(arg, \"help\"))\n+\t\t\tusage(git_lib, NULL);\n+\t\telse\n+\t\t\tusage(NULL, NULL);\n+\t}\n+\n+\tif (i >= argc)\n+\t\tusage(NULL, NULL);\n+\n+\t/* allow relative paths, but run with exact */\n+\tif (chdir(git_lib)) {\n+\t\tprintf(\"git: '%s': %s\\n\", git_lib, strerror(errno));\n+\t\texit (1);\n+\t}\n+\n+\tgetcwd(git_command, sizeof(git_command));\n+\tchdir(wd);\n+\n+\tlen = strlen(git_command);\n+\tstrncat(&git_command[len], \"/git-\", sizeof(git_command) - len);\n+\tlen += 5;\n+\tstrncat(&git_command[len], argv[i], sizeof(git_command) - len);\n+\n+\tif (access(git_command, X_OK))\n+\t\tusage(git_lib, \"'%s' is not a git-command\", argv[i]);\n+\n+\t/* execve() can only ever return if it fails */\n+\texecve(git_command, &argv[i], envp);\n+\tprintf(\"Failed to run command '%s': %s\\n\", git_command, strerror(errno));\n+\n+\treturn 1;\n+}\ndiff --git a/git.sh b/git.sh\ndeleted file mode 100755\nindex 94940ae..0000000\n--- a/git.sh\n+++ /dev/null\n@@ -1,76 +0,0 @@\n-#!/bin/sh\n-\n-cmd=\n-path=$(dirname \"$0\")\n-case \"$#\" in\n-0)\t;;\n-*)\tcmd=\"$1\"\n-\tshift\n-\tcase \"$cmd\" in\n-\t-v|--v|--ve|--ver|--vers|--versi|--versio|--version)\n-\t\techo \"git version @@GIT_VERSION@@\"\n-\t\texit 0 ;;\n-\tesac\n-\t\n-\ttest -x \"$path/git-$cmd\" && exec \"$path/git-$cmd\" \"$@\"\n-\t\n-\tcase '@@X@@' in\n-\t    '')\n-\t\t;;\n-\t    *)\n-\t\ttest -x \"$path/git-$cmd@@X@@\" &&\n-\t\texec \"$path/git-$cmd@@X@@\" \"$@\"\n-\t\t;;\n-\tesac\n-\t;;\n-esac\n-\n-echo \"Usage: git COMMAND [OPTIONS] [TARGET]\"\n-if [ -n \"$cmd\" ]; then\n-    echo \"git command '$cmd' not found.\"\n-fi\n-echo \"git commands are:\"\n-\n-fmt <<\\EOF | sed -e 's/^/    /'\n-add\n-apply\n-archimport\n-bisect\n-branch\n-checkout\n-cherry\n-clone\n-commit\n-count-objects\n-cvsimport\n-diff\n-fetch\n-format-patch\n-fsck-objects\n-get-tar-commit-id\n-init-db\n-log\n-ls-remote\n-octopus\n-pack-objects\n-parse-remote\n-patch-id\n-prune\n-pull\n-push\n-rebase\n-relink\n-rename\n-repack\n-request-pull\n-reset\n-resolve\n-revert\n-send-email\n-shortlog\n-show-branch\n-status\n-tag\n-verify-tag\n-whatchanged\n-EOF\n---\n0.99.9.GIT\n"},{"id":"11502","messageId":"Pine.LNX.4.64.0511101133550.4627@g5.osdl.org","threadId":"2434","inReplyTo":"20051110182631.3C5615BF90@nox.op5.se","subject":"Re: [PATCH] C implementation of the 'git' program.","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-11-10T19:41:10Z","receivedAt":"2005-11-10T19:41:10Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 10 Nov 2005, Andreas Ericsson wrote:\n> \n> This patch provides a C implementation of the 'git' program and introduces\n> support for putting the git-* commands in their own directory. It also\n> saves some time on executing git-* commands in a tight loop and it prints\n> the currently available git commands in a nicely formatted list.\n\nI think this makes sense - \"git\" may be a very simple program even in \nshell, but hey, it's simple even in C, and while performance may be a \nsecondary issue, when it is in C we will have the option to extend in more \neffectively later.\n\nFor example, we might implement some things directly in the \"git\" wrapper.\n\nAnd the performance difference does seem to be quite noticeable too..\n\n> The location of the GIT_LIB can be obtained by running\n> \n> \tgit --lib\n\nI think this might be a bit ambiguous. When I see \"GIT_LIB\", to me it \nimplies traditional libraries (ie a \"libgit.a\" kind of thing), not the \nkind of \"git executable plugin\" directory.\n\nSo I'd suggest renaming \"--lib\" and \"GIT_LIB\" to be more of a \"--libexec\" \nkind of flavor, if only to avoid that confusion. Even if the actual \ndirectory ends up being /usr/lib/git-<version>/ as in my original \nsuggestion, I think it's good to make it clear that it's not just some \nkind of \"link type\" library, but more of a combination of libraries and \nplugins and executables.\n\nBut maybe that's just me?\n\n\t\tLinus\n"},{"id":"11522","messageId":"4373CEA8.1020900@op5.se","threadId":"2434","inReplyTo":"Pine.LNX.4.64.0511101133550.4627@g5.osdl.org","subject":"Re: [PATCH] C implementation of the 'git' program.","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2005-11-10T22:50:16Z","receivedAt":"2005-11-10T22:50:16Z","isPatch":true,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"Linus Torvalds wrote:\n> \n> And the performance difference does seem to be quite noticeable too..\n> \n\nYes. I was quite astonished when I noticed first, thinking the shell \nkept the parsed script in cache or some such. Apparently it doesn't.\n\n> \n>>The location of the GIT_LIB can be obtained by running\n>>\n>>\tgit --lib\n> \n> \n> I think this might be a bit ambiguous. When I see \"GIT_LIB\", to me it \n> implies traditional libraries (ie a \"libgit.a\" kind of thing), not the \n> kind of \"git executable plugin\" directory.\n> \n> So I'd suggest renaming \"--lib\" and \"GIT_LIB\" to be more of a \"--libexec\" \n> kind of flavor, if only to avoid that confusion.\n\n\nSomeone said libexec was moving out (of Linux, at least), so I thought \nI'd better avoid that. Perhaps GIT_LIBDIR?\n\nBtw, I re-visited ye ole \"git binary directory?\" thread and noticed the \nnifty trick you did with PATH from the wrapper. I'll add that to git.c \nand, unless I get a better suggestion, rename GIT_LIB to GIT_LIBDIR (and \ngit --libdir).\n\n\n> Even if the actual \n> directory ends up being /usr/lib/git-<version>/ as in my original \n> suggestion, I think it's good to make it clear that it's not just some \n> kind of \"link type\" library, but more of a combination of libraries and \n> plugins and executables.\n> \n> But maybe that's just me?\n> \n\nIt's not just you, but GIT_DIR was taken and I felt lazy.\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n"},{"id":"11527","messageId":"20051110233751.GD30496@pasky.or.cz","threadId":"2434","inReplyTo":"4373CEA8.1020900@op5.se","subject":"Re: [PATCH] C implementation of the 'git' program.","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2005-11-10T23:37:51Z","receivedAt":"2005-11-10T23:37:51Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Thu, Nov 10, 2005 at 11:50:16PM CET, I got a letter\nwhere Andreas Ericsson <ae@op5.se> said that...\n> Linus Torvalds wrote:\n> >\n> >And the performance difference does seem to be quite noticeable too..\n> >\n> \n> Yes. I was quite astonished when I noticed first, thinking the shell \n> kept the parsed script in cache or some such. Apparently it doesn't.\n\nThe bulk of the time is likely not spent parsing, but executing\nsubprocesses, that's hideously expensive. Just for fun, you can try to\nmeasure the improvement when you remove the $(dirname \"$0\"). Here, for\n1000 tries it's roughly 9s normal, 7s without dirname and 3s direct\ninvocation, which seems to give you _very roughly_ 2s per subprocess,\nand 2s other shell overhead, which is unusually right.\n\nActually, I can bring the git.sh runtime from 7s to 4.7s:\n\n-       case \"$cmd\" in\n-       -v|--v|--ve|--ver|--vers|--versi|--versio|--version)\n+       if [[ \"$cmd\" = \"-v\" ||\n+             \"$cmd\" = \"--v\" ||\n+             \"$cmd\" = \"--ve\" ||\n+             \"$cmd\" = \"--ver\" ||\n+             \"$cmd\" = \"--vers\" ||\n+             \"$cmd\" = \"--versi\" ||\n+             \"$cmd\" = \"--versio\" ||\n+             \"$cmd\" = \"--version\" ]]; then\n                echo \"git version @@GIT_VERSION@@\"\n                exit 0 ;;\n-       esac\n+       fi\n\t\t\t\t(whitespace-mangled)\n\nWell, subconsciously I never really trusted this case thing. ;-)\n\nThis leaves ~ 1.7s to other shell overhead and execve() (the main\ncommand call is without the fork(), while $(dirname) fork()s).\n\n> >>The location of the GIT_LIB can be obtained by running\n> >>\n> >>\tgit --lib\n> >\n> >\n> >I think this might be a bit ambiguous. When I see \"GIT_LIB\", to me it \n> >implies traditional libraries (ie a \"libgit.a\" kind of thing), not the \n> >kind of \"git executable plugin\" directory.\n> >\n> >So I'd suggest renaming \"--lib\" and \"GIT_LIB\" to be more of a \"--libexec\" \n> >kind of flavor, if only to avoid that confusion.\n> \n> \n> Someone said libexec was moving out (of Linux, at least), so I thought \n> I'd better avoid that. Perhaps GIT_LIBDIR?\n\nThis may not necessarily have anything in common with the actual\ndirectory name. I prefer libexec too (but personally don't care too\nmuch).\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nVI has two modes: the one in which it beeps and the one in which\nit doesn't.\n"},{"id":"11556","messageId":"m3lkzv4qnz.fsf@harinath.blr.novell.com","threadId":"2434","inReplyTo":"20051110182631.3C5615BF90@nox.op5.se","subject":"Re: [PATCH] C implementation of the 'git' program.","fromName":"Raja R Harinath","fromEmail":"rharinath@novell.com","sentAt":"2005-11-11T06:58:08Z","receivedAt":"2005-11-11T06:58:08Z","isPatch":true,"sender":{"key":"rharinath@novell.com","avatar":null},"body":"Hi,\n\nexon@op5.se (Andreas Ericsson) writes:\n\n[snip]\n> As a nice side-effect, the patch also fixes the problem with\n> \tmake\n> \tmake prefix=/usr install\n>\n> Signed-off-by: Andreas Ericsson <ae@op5.se>\n[snip]\n> +# Force rebuild so that \"make prefix=<something> install\" Just Works.\n> +.PHONY: git\n\nThis is bad, since it does the wrong thing for the correct way:\n\n  make prefix=/usr\n  sudo make prefix=/usr install\n\nWith your patch 'git' will be compiled as root.\n\n- Hari\n"},{"id":"11559","messageId":"7vveyzskdk.fsf@assigned-by-dhcp.cox.net","threadId":"2434","inReplyTo":"m3lkzv4qnz.fsf@harinath.blr.novell.com","subject":"Re: [PATCH] C implementation of the 'git' program.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-11T07:40:07Z","receivedAt":"2005-11-11T07:40:07Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Raja R Harinath <rharinath@novell.com> writes:\n\n> This is bad, since it does the wrong thing for the correct way:\n>\n>   make prefix=/usr\n>   sudo make prefix=/usr install\n>\n> With your patch 'git' will be compiled as root.\n\nYou are correct.\n\nWe should allow building as user and installing as root, with\nthe installation step _not_ touching the build directory at all.\nA good litmus test is that you should be able to build and\ninstall from a root-squashed NFS mounted working tree, without\ngiving write permissions to NFS-nobody user (obviously you need\nto give read and search permissions).\n\nAndreas?\n"},{"id":"11582","messageId":"437488E6.2050100@op5.se","threadId":"2434","inReplyTo":"7vveyzskdk.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] C implementation of the 'git' program.","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2005-11-11T12:04:54Z","receivedAt":"2005-11-11T12:04:54Z","isPatch":true,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"Junio C Hamano wrote:\n> Raja R Harinath <rharinath@novell.com> writes:\n> \n> \n>>This is bad, since it does the wrong thing for the correct way:\n>>\n>>  make prefix=/usr\n>>  sudo make prefix=/usr install\n>>\n>>With your patch 'git' will be compiled as root.\n> \n> \n> You are correct.\n> \n> We should allow building as user and installing as root, with\n> the installation step _not_ touching the build directory at all.\n\nSane point. This doesn't work without a ./configure script or some such \nthough (something external to the Makefile that updates a config-file of \nsome sort), as\n\nmake\n(make finishes, user remembers he/she must use prefix= to install somewhere)\nmake prefix=/usr\n\nwouldn't rebuild git so binaries produced would still try to use \n$HOME/bin for libdir. Granted, it's easy enough to do 'touch git.c' \nbefore rebuilding, but it's not exactly intuitive.\n\nI'll hack up a configure-script if that's alright. It should be fairly \nshort and just define the GIT_VERSION and GIT_LIBDIR macros.\n\nI imagine this can be done through the config.mak file, included from \n221 in Makefile, supposing it's forcibly included rather than just if it \nexists, and we'll have the 'git:' target depend on it. I think this is \nthe least intrusive change. OTOH, it might not be bad to move some of \nthe uname_? logic to a shell-script (and have all targets depend on \nconfig.mak).\n\nThoughts? I've got a feeling I've overlooked something here.\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n"},{"id":"11622","messageId":"7vek5nm16d.fsf@assigned-by-dhcp.cox.net","threadId":"2434","inReplyTo":"4373CEA8.1020900@op5.se","subject":"Re: [PATCH] C implementation of the 'git' program.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-11T19:31:22Z","receivedAt":"2005-11-11T19:31:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andreas Ericsson <ae@op5.se> writes:\n\n> Linus Torvalds wrote:\n>\n>> I think this might be a bit ambiguous. When I see \"GIT_LIB\", to me\n>> it implies traditional libraries (ie a \"libgit.a\" kind of thing),\n>> not the kind of \"git executable plugin\" directory.\n>> So I'd suggest renaming \"--lib\" and \"GIT_LIB\" to be more of a\n>> \"--libexec\" kind of flavor, if only to avoid that confusion.\n>\n> Someone said libexec was moving out (of Linux, at least), so I thought \n> I'd better avoid that. Perhaps GIT_LIBDIR?\n\nMore like \"the rest of git executables\".  GIT_EXEC_PATH, with\n\"git --exec-path\" command, perhaps?\n"},{"id":"11623","messageId":"7v7jbfm0w5.fsf@assigned-by-dhcp.cox.net","threadId":"2434","inReplyTo":"437488E6.2050100@op5.se","subject":"Re: [PATCH] C implementation of the 'git' program.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-11T19:37:30Z","receivedAt":"2005-11-11T19:37:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andreas Ericsson <ae@op5.se> writes:\n\n> Thoughts? I've got a feeling I've overlooked something here.\n\nIf you are doing it, it might make sense to include it from\nMakefiles in subdirectories, so that on a platform with non GNU\ntar, you could say:\n\n\t$ cd t\n\t$ make\n\nand get TAR=gtar definition from ../config.mk\n\nI think Smurf's libize repository has something like that; it is\nfound at:\n\n        $ cat .git/remotes/smurf\n        URL: http://netz.smurf.noris.de/git/git.git\n        Pull: libize:libize\n"}]}