diff --git a/Makefile b/Makefile index bc5d559cfb..2562a2cef9 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,11 @@ all: # Define NO_D_TYPE_IN_DIRENT if your platform defines DT_UNKNOWN but lacks # d_type in struct dirent (latest Cygwin -- will be fixed soonish). # +# Define NO_C99_FORMAT if your formatted IO functions (printf/scanf et.al.) +# do not support the 'size specifiers' introduced by C99, namely ll, hh, +# j, z, t. (representing long long int, char, intmax_t, size_t, ptrdiff_t). +# some c compilers supported these specifiers prior to C99 as an extension. +# # Define NO_STRCASESTR if you don't have strcasestr. # # Define NO_STRLCPY if you don't have strlcpy. @@ -455,6 +460,9 @@ endif ifdef NO_D_INO_IN_DIRENT BASIC_CFLAGS += -DNO_D_INO_IN_DIRENT endif +ifdef NO_C99_FORMAT + BASIC_CFLAGS += -DNO_C99_FORMAT +endif ifdef NO_SYMLINK_HEAD BASIC_CFLAGS += -DNO_SYMLINK_HEAD endif @@ -786,7 +794,7 @@ install: all $(INSTALL) -d -m755 '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL) git$X gitk '$(DESTDIR_SQ)$(bindir_SQ)' - $(MAKE) -C templates install + $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install $(MAKE) -C perl install $(INSTALL) -d -m755 '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)' $(INSTALL) $(PYMODULES) '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)' diff --git a/alloc.c b/alloc.c index e3b22f4322..460db192d5 100644 --- a/alloc.c +++ b/alloc.c @@ -39,8 +39,21 @@ DEFINE_ALLOCATOR(tree) DEFINE_ALLOCATOR(commit) DEFINE_ALLOCATOR(tag) +#ifdef NO_C99_FORMAT +#define SZ_FMT "%u" +#else +#define SZ_FMT "%zu" +#endif + +static void report(const char* name, unsigned int count, size_t size) +{ + fprintf(stderr, "%10s: %8u (" SZ_FMT " kB)\n", name, count, size); +} + +#undef SZ_FMT + #define REPORT(name) \ - fprintf(stderr, "%10s: %8u (%zu kB)\n", #name, name##_allocs, name##_allocs*sizeof(struct name) >> 10) + report(#name, name##_allocs, name##_allocs*sizeof(struct name) >> 10) void alloc_report(void) { diff --git a/builtin-help.c b/builtin-help.c index bb0b03f1ae..fb731cc934 100644 --- a/builtin-help.c +++ b/builtin-help.c @@ -9,8 +9,6 @@ #include "exec_cmd.h" #include "common-cmds.h" -static const char git_usage[] = - "Usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ ARGS ]"; /* most GUI terminals set COLUMNS (although some don't export it) */ static int term_columns(void) @@ -178,31 +176,6 @@ static void list_common_cmds_help(void) puts("(use 'git help -a' to get a list of all installed git commands)"); } -void cmd_usage(int show_all, const char *exec_path, const char *fmt, ...) -{ - if (fmt) { - va_list ap; - - va_start(ap, fmt); - printf("git: "); - vprintf(fmt, ap); - va_end(ap); - putchar('\n'); - } - else - puts(git_usage); - - if (exec_path) { - putchar('\n'); - if (show_all) - list_commands(exec_path, "git-*"); - else - list_common_cmds_help(); - } - - exit(1); -} - static void show_man_page(const char *git_cmd) { const char *page; @@ -221,6 +194,13 @@ static void show_man_page(const char *git_cmd) execlp("man", "man", page, NULL); } +void help_unknown_cmd(const char *cmd) +{ + printf("git: '%s' is not a git-command\n\n", cmd); + list_common_cmds_help(); + exit(1); +} + int cmd_version(int argc, const char **argv, const char *prefix) { printf("git version %s\n", git_version_string); @@ -230,12 +210,24 @@ int cmd_version(int argc, const char **argv, const char *prefix) int cmd_help(int argc, const char **argv, const char *prefix) { const char *help_cmd = argc > 1 ? argv[1] : NULL; - if (!help_cmd) - cmd_usage(0, git_exec_path(), NULL); - else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a")) - cmd_usage(1, git_exec_path(), NULL); + const char *exec_path = git_exec_path(); + + if (!help_cmd) { + printf("usage: %s\n\n", git_usage_string); + list_common_cmds_help(); + exit(1); + } + + else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a")) { + printf("usage: %s\n\n", git_usage_string); + if(exec_path) + list_commands(exec_path, "git-*"); + exit(1); + } + else show_man_page(help_cmd); + return 0; } diff --git a/builtin.h b/builtin.h index 1c8637ae22..f10d3b77c8 100644 --- a/builtin.h +++ b/builtin.h @@ -2,18 +2,12 @@ #define BUILTIN_H #include - -#ifndef PATH_MAX -# define PATH_MAX 4096 -#endif +#include extern const char git_version_string[]; +extern const char git_usage_string[]; -void cmd_usage(int show_all, const char *exec_path, const char *fmt, ...) -#ifdef __GNUC__ - __attribute__((__format__(__printf__, 3, 4), __noreturn__)) -#endif - ; +extern void help_unknown_cmd(const char *cmd); extern int cmd_help(int argc, const char **argv, const char *prefix); extern int cmd_version(int argc, const char **argv, const char *prefix); diff --git a/convert-objects.c b/convert-objects.c index ebea8e472b..168771ed85 100644 --- a/convert-objects.c +++ b/convert-objects.c @@ -1,5 +1,6 @@ #define _XOPEN_SOURCE 500 /* glibc2 and AIX 5.3L need this */ #define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */ +#define _GNU_SOURCE #include #include "cache.h" #include "blob.h" diff --git a/git-clone.sh b/git-clone.sh index a92b22a13d..acc7a51b97 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -205,7 +205,7 @@ dir="$2" [ -e "$dir" ] && echo "$dir already exists." && usage mkdir -p "$dir" && D=$(cd "$dir" && pwd) && -trap 'err=$?; cd ..; rm -r "$D"; exit $err' 0 +trap 'err=$?; cd ..; rm -rf "$D"; exit $err' 0 case "$bare" in yes) GIT_DIR="$D" ;; @@ -324,7 +324,8 @@ test -d "$GIT_DIR/refs/reference-tmp" && rm -fr "$GIT_DIR/refs/reference-tmp" if test -f "$GIT_DIR/CLONE_HEAD" then # Read git-fetch-pack -k output and store the remote branches. - @@PERL@@ -e "$copy_refs" "$GIT_DIR" "$use_separate_remote" "$origin" + @@PERL@@ -e "$copy_refs" "$GIT_DIR" "$use_separate_remote" "$origin" || + exit fi cd "$D" || exit diff --git a/git.c b/git.c index d031eb9a18..110e82e9ac 100644 --- a/git.c +++ b/git.c @@ -15,6 +15,9 @@ #include "builtin.h" +const char git_usage_string[] = + "git [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ ARGS ]"; + static void prepend_to_path(const char *dir, int len) { const char *old_path = getenv("PATH"); @@ -78,7 +81,7 @@ static int handle_options(const char*** argv, int* argc) setenv("GIT_DIR", getcwd(git_dir, 1024), 1); } else { fprintf(stderr, "Unknown option: %s\n", cmd); - cmd_usage(0, NULL, NULL); + usage(git_usage_string); } (*argv)++; @@ -375,7 +378,7 @@ int main(int argc, const char **argv, char **envp) } if (errno == ENOENT) - cmd_usage(0, exec_path, "'%s' is not a git-command", cmd); + help_unknown_cmd(cmd); fprintf(stderr, "Failed to run command '%s': %s\n", cmd, strerror(errno)); diff --git a/mktag.c b/mktag.c index 27f4c4f041..09b6e437d4 100644 --- a/mktag.c +++ b/mktag.c @@ -2,10 +2,11 @@ #include "tag.h" /* - * A signature file has a very simple fixed format: three lines - * of "object " + "type " + "tag ", - * followed by some free-form signature that git itself doesn't - * care about, but that can be verified with gpg or similar. + * A signature file has a very simple fixed format: four lines + * of "object " + "type " + "tag " + + * "tagger ", followed by a blank line, a free-form tag + * message and a signature block that git itself doesn't care about, + * but that can be verified with gpg or similar. * * The first three lines are guaranteed to be at least 63 bytes: * "object \n" is 48 bytes, "type tag\n" at 9 bytes is the @@ -38,6 +39,12 @@ static int verify_object(unsigned char *sha1, const char *expected_type) return ret; } +#ifdef NO_C99_FORMAT +#define PD_FMT "%d" +#else +#define PD_FMT "%td" +#endif + static int verify_tag(char *buffer, unsigned long size) { int typelen; @@ -46,45 +53,42 @@ static int verify_tag(char *buffer, unsigned long size) const char *object, *type_line, *tag_line, *tagger_line; if (size < 64) - return error("wanna fool me ? you obviously got the size wrong !\n"); + return error("wanna fool me ? you obviously got the size wrong !"); buffer[size] = 0; /* Verify object line */ object = buffer; if (memcmp(object, "object ", 7)) - return error("char%d: does not start with \"object \"\n", 0); + return error("char%d: does not start with \"object \"", 0); if (get_sha1_hex(object + 7, sha1)) - return error("char%d: could not get SHA1 hash\n", 7); + return error("char%d: could not get SHA1 hash", 7); /* Verify type line */ type_line = object + 48; if (memcmp(type_line - 1, "\ntype ", 6)) - return error("char%d: could not find \"\\ntype \"\n", 47); + return error("char%d: could not find \"\\ntype \"", 47); /* Verify tag-line */ tag_line = strchr(type_line, '\n'); if (!tag_line) - return error("char%td: could not find next \"\\n\"\n", type_line - buffer); + return error("char" PD_FMT ": could not find next \"\\n\"", type_line - buffer); tag_line++; if (memcmp(tag_line, "tag ", 4) || tag_line[4] == '\n') - return error("char%td: no \"tag \" found\n", tag_line - buffer); + return error("char" PD_FMT ": no \"tag \" found", tag_line - buffer); /* Get the actual type */ typelen = tag_line - type_line - strlen("type \n"); if (typelen >= sizeof(type)) - return error("char%td: type too long\n", type_line+5 - buffer); + return error("char" PD_FMT ": type too long", type_line+5 - buffer); memcpy(type, type_line+5, typelen); type[typelen] = 0; /* Verify that the object matches */ - if (get_sha1_hex(object + 7, sha1)) - return error("char%d: could not get SHA1 hash but this is really odd since i got it before !\n", 7); - if (verify_object(sha1, type)) - return error("char%d: could not verify object %s\n", 7, sha1); + return error("char%d: could not verify object %s", 7, sha1_to_hex(sha1)); /* Verify the tag-name: we don't allow control characters or spaces in it */ tag_line += 4; @@ -94,19 +98,24 @@ static int verify_tag(char *buffer, unsigned long size) break; if (c > ' ') continue; - return error("char%td: could not verify tag name\n", tag_line - buffer); + return error("char" PD_FMT ": could not verify tag name", tag_line - buffer); } /* Verify the tagger line */ tagger_line = tag_line; if (memcmp(tagger_line, "tagger", 6) || (tagger_line[6] == '\n')) - return error("char%td: could not find \"tagger\"\n", tagger_line - buffer); + return error("char" PD_FMT ": could not find \"tagger\"", tagger_line - buffer); + + /* TODO: check for committer info + blank line? */ + /* Also, the minimum length is probably + "tagger .", or 63+8=71 */ /* The actual stuff afterwards we don't care about.. */ return 0; } +#undef PD_FMT + int main(int argc, char **argv) { unsigned long size = 4096; diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh index b6a2edd887..8baf2fef69 100644 --- a/t/annotate-tests.sh +++ b/t/annotate-tests.sh @@ -4,7 +4,8 @@ check_count () { head= case "$1" in -h) head="$2"; shift; shift ;; esac - $PROG file $head | perl -e ' + $PROG file $head >.result || return 1 + cat .result | perl -e ' my %expect = (@ARGV); my %count = (); while () { diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh new file mode 100755 index 0000000000..5b23b7769d --- /dev/null +++ b/t/t3800-mktag.sh @@ -0,0 +1,227 @@ +#!/bin/sh +# +# + +test_description='git-mktag: tag object verify test' + +. ./test-lib.sh + +########################################################### +# check the tag.sig file, expecting verify_tag() to fail, +# and checking that the error message matches the pattern +# given in the expect.pat file. + +check_verify_failure () { + test_expect_success \ + "$1" \ + 'git-mktag message || + egrep -q -f expect.pat message' +} + +########################################################### +# first create a commit, so we have a valid object/type +# for the tag. +echo Hello >A +git-update-index --add A +git-commit -m "Initial commit" +head=$(git-rev-parse --verify HEAD) + +############################################################ +# 1. length check + +cat >tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig +echo -n "type tagsssssssssssssssssssssssssssssss" >>tag.sig + +cat >expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <.git/refs/tags/mytag 2>message' + +############################################################ +# 14. check mytag + +test_expect_success \ + 'check mytag' \ + 'git-tag -l | grep mytag' + + +test_done diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh index bf1d6381d9..34a3ccd31c 100755 --- a/t/t9100-git-svn-basic.sh +++ b/t/t9100-git-svn-basic.sh @@ -170,7 +170,7 @@ then test -L $SVN_TREE/exec-2.sh" name='modify a symlink to become a file' - git help > help || true + echo git help > help || true rm exec-2.sh cp help exec-2.sh git update-index exec-2.sh @@ -217,10 +217,10 @@ name='check imported tree checksums expected tree checksums' rm -f expected if test "$have_utf8" = t then - echo tree f735671b89a7eb30cab1d8597de35bd4271ab813 > expected + echo tree bf522353586b1b883488f2bc73dab0d9f774b9a9 > expected fi cat >> expected <<\EOF -tree 4b9af72bb861eaed053854ec502cf7df72618f0f +tree 83654bb36f019ae4fe77a0171f81075972087624 tree 031b8d557afc6fea52894eaebb45bec52f1ba6d1 tree 0b094cbff17168f24c302e297f55bfac65eb8bd3 tree d667270a1f7b109f5eb3aaea21ede14b56bfdd6e @@ -231,4 +231,3 @@ EOF test_expect_success "$name" "diff -u a expected" test_done - diff --git a/templates/Makefile b/templates/Makefile index 8f7f4fec34..9e1ae1a4e0 100644 --- a/templates/Makefile +++ b/templates/Makefile @@ -6,11 +6,9 @@ prefix ?= $(HOME) template_dir ?= $(prefix)/share/git-core/templates/ # DESTDIR= -# Shell quote; -# Result of this needs to be placed inside '' -shq = $(subst ','\'',$(1)) -# This has surrounding '' -shellquote = '$(call shq,$(1))' +# Shell quote (do not use $(call) to accomodate ancient setups); +DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) +template_dir_SQ = $(subst ','\'',$(template_dir)) all: boilerplates.made custom @@ -43,6 +41,6 @@ clean: rm -rf blt boilerplates.made install: all - $(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(template_dir)) + $(INSTALL) -d -m755 '$(DESTDIR_SQ)$(template_dir_SQ)' (cd blt && $(TAR) cf - .) | \ - (cd $(call shellquote,$(DESTDIR)$(template_dir)) && $(TAR) xf -) + (cd '$(DESTDIR_SQ)$(template_dir_SQ)' && $(TAR) xf -)