From 6ebdee5af47df0c64354e452419015a694c25f5f Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sat, 29 Jul 2006 17:12:34 +0100 Subject: [PATCH 1/8] Ensure git-clone exits with error if perl script fails. This helps tests 5400,5600,5700,5710 "fail correctly" rather than give some false positives. Also ensure cleanup actions in exit trap work correctly even if user has alias rm='rm -i'. Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- git-clone.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 From 1fd4da643cb829618bbe76ab37df7f1b4dafc656 Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sat, 29 Jul 2006 17:20:41 +0100 Subject: [PATCH 2/8] Fix annotate test script; notice when git-annotate fails. The t8001-annotate.sh test claimed all tests pass, when in fact the git-annotate perl script failed to run! (prior to fixing the script to work with perl 5.5). Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- t/annotate-tests.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 () { From 7ffe7098dca297016f87a7e10554e6736f7c3ae2 Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sat, 29 Jul 2006 17:25:03 +0100 Subject: [PATCH 3/8] Fix installation of templates on ancient systems. Do not use $(call) for 'shell quoting' paths, and pass DESTDIR down to the templates makefile. [jc: we have fixed the main Makefile long time ago, but somehow forgot to apply the same fix to templates Makefile.] Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- Makefile | 2 +- templates/Makefile | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 15864e23bd..6df93c18fc 100644 --- a/Makefile +++ b/Makefile @@ -712,7 +712,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 $(INSTALL) -d -m755 '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)' $(INSTALL) $(PYMODULES) '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)' if test 'z$(bindir_SQ)' != 'z$(gitexecdir_SQ)'; \ 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 -) From 446c6faec69f7ac521b8b9fc2b1874731729032f Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sat, 29 Jul 2006 18:15:47 +0100 Subject: [PATCH 4/8] New tests and en-passant modifications to mktag. These changes were originally part of the next patch, but have been split out since they were peripheral to the main purpose of that patch. - update comment describing the signature format to reflect the current code. - remove trailing \n in calls to error(), since a \n is already provided by error(). - remove redundant call to get_sha1_hex(). - call sha1_to_hex(sha1) to convert to ascii, rather than attempting to print the raw sha1. The new tests provide a regression suite to support the modifications to git-mktag in this and the next patch. Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- mktag.c | 35 ++++---- t/t3800-mktag.sh | 227 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 245 insertions(+), 17 deletions(-) create mode 100755 t/t3800-mktag.sh diff --git a/mktag.c b/mktag.c index 27f4c4f041..fa4a9e6003 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 @@ -46,45 +47,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%td: 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%td: 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%td: 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,14 +92,17 @@ 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%td: 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%td: 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; 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 From 579d1fbfaf25550254014fa472faac95f88eb779 Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sun, 30 Jul 2006 16:38:28 +0100 Subject: [PATCH 5/8] Add NO_C99_FORMAT to support older compilers. The NO_C99_FORMAT macro allows compilers that lack support for the ll,hh,j,z,t size specifiers (eg. gcc 2.95.2) to adapt the code to avoid runtime errors in the formatted IO functions. Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- Makefile | 8 ++++++++ alloc.c | 15 ++++++++++++++- mktag.c | 18 +++++++++++++----- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 6df93c18fc..e66e9b16a5 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,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. @@ -432,6 +437,9 @@ endif ifdef NO_D_INO_IN_DIRENT ALL_CFLAGS += -DNO_D_INO_IN_DIRENT endif +ifdef NO_C99_FORMAT + ALL_CFLAGS += -DNO_C99_FORMAT +endif ifdef NO_SYMLINK_HEAD ALL_CFLAGS += -DNO_SYMLINK_HEAD endif 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/mktag.c b/mktag.c index fa4a9e6003..09b6e437d4 100644 --- a/mktag.c +++ b/mktag.c @@ -39,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; @@ -67,15 +73,15 @@ static int verify_tag(char *buffer, unsigned long size) /* Verify tag-line */ tag_line = strchr(type_line, '\n'); if (!tag_line) - return error("char%td: could not find next \"\\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", 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", 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; @@ -92,14 +98,14 @@ static int verify_tag(char *buffer, unsigned long size) break; if (c > ' ') continue; - return error("char%td: could not verify tag name", 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\"", 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 */ @@ -108,6 +114,8 @@ static int verify_tag(char *buffer, unsigned long size) return 0; } +#undef PD_FMT + int main(int argc, char **argv) { unsigned long size = 4096; From 8e76483ce0ce256b01345abc4ca97b1f94aed354 Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sun, 30 Jul 2006 17:00:40 +0100 Subject: [PATCH 6/8] Fix header breakage due to redefining PATH_MAX. The header builtin.h was, incorrectly, redefining PATH_MAX which causes a header order dependency in builtin-write-tree.c. The fix is to simply include directly to obtain the correct definition of PATH_MAX. Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- builtin.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/builtin.h b/builtin.h index 1c8637ae22..88c4d84712 100644 --- a/builtin.h +++ b/builtin.h @@ -2,10 +2,7 @@ #define BUILTIN_H #include - -#ifndef PATH_MAX -# define PATH_MAX 4096 -#endif +#include extern const char git_version_string[]; From 822a7d507151e1d6310f52d5b05234d65db11a88 Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sun, 30 Jul 2006 22:42:25 +0100 Subject: [PATCH 7/8] Remove cmd_usage() routine and re-organize the help/usage code. The cmd_usage() routine was causing warning messages due to a NULL format parameter being passed in three out of four calls. This is a problem if you want to compile with -Werror. A simple solution is to simply remove the GNU __attribute__ format pragma from the cmd_usage() declaration in the header file. The function interface was somewhat muddled anyway, so re-write the code to finesse the problem. [jc: this incidentally revealed that t9100 test assumed that the output from "git help" to be fixed in stone, but this patch lower-cases "Usage" to "usage". Update the test not to rely on "git help" output.] Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- builtin-help.c | 54 +++++++++++++++++----------------------- builtin.h | 7 ++---- git.c | 7 ++++-- t/t9100-git-svn-basic.sh | 7 +++--- 4 files changed, 33 insertions(+), 42 deletions(-) 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 88c4d84712..f10d3b77c8 100644 --- a/builtin.h +++ b/builtin.h @@ -5,12 +5,9 @@ #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/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/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 - From da7bad50ed0816cf2ee7f558ed154a7c67fb546d Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sun, 30 Jul 2006 16:52:09 +0100 Subject: [PATCH 8/8] Fix header breakage with _XOPEN_SOURCE. convert-objects.c sets _XOPEN_SOURCE and _XOPEN_SOURCE_EXTENDED before including , in order to get the declaration of strptime(). This leads to breakage in cache.h, due to S_ISLNK and S_IFLNK no longer being defined by . These definitions are protected by the __USE_BSD symbol, which is not set when _XOPEN_SOURCE is set. Moving the #defines and #include below all other #includes does not fix the problem, however, since now _USE_XOPEN, which protects the declaration of strptime(), is now not defined (don't ask!). The fix is to #define _GNU_SOURCE, which enables the definition of practically everything. Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- convert-objects.c | 1 + 1 file changed, 1 insertion(+) 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"