From 12efe45a3363ebecd8954d04caadb23eba2e5020 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 13 Sep 2009 11:23:34 -0700 Subject: [PATCH 01/31] git-commit doc: remove duplicated --dry-run description 60c2993 (Documentation/git-commit.txt: describe --dry-run, 2009-08-15) wanted to update the documentation to say that "git status" is not the same as "git commit --dry-run" anymore, but it screwed up and also added the description of --dry-run that was already present. Noticed by Johannes Gilger. Signed-off-by: Junio C Hamano --- Documentation/git-commit.txt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 64f94cfe12..0578a40d84 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] 'git commit' [-a | --interactive] [-s] [-v] [-u] [--amend] [--dry-run] - [(-c | -C) ] [-F | -m ] [--dry-run] + [(-c | -C) ] [-F | -m ] [--allow-empty] [--no-verify] [-e] [--author=] [--cleanup=] [--] [[-i | -o ]...] @@ -69,12 +69,6 @@ OPTIONS Like '-C', but with '-c' the editor is invoked, so that the user can further edit the commit message. ---dry-run:: - Do not actually make a commit, but show the list of paths - with updates in the index, paths with changes in the work tree, - and paths that are untracked, similar to the one that is given - in the commit log editor. - -F :: --file=:: Take the commit message from the given file. Use '-' to From 9f67fee2f0190e0b10e73862cbb88a3f7216f619 Mon Sep 17 00:00:00 2001 From: Nelson Elhage Date: Sun, 13 Sep 2009 12:56:45 -0400 Subject: [PATCH 02/31] git-push: Accept -n as a synonym for --dry-run. git-push is not currently using -n for anything else, and it seems unlikely we will want to use it to mean anything else in the future, so add it as an alias for convenience. Signed-off-by: Nelson Elhage Signed-off-by: Junio C Hamano --- Documentation/git-push.txt | 3 ++- builtin-push.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index 58d2bd5d4a..ba6a8a2fb2 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -9,7 +9,7 @@ git-push - Update remote refs along with associated objects SYNOPSIS -------- [verse] -'git push' [--all | --mirror | --tags] [--dry-run] [--receive-pack=] +'git push' [--all | --mirror | --tags] [-n | --dry-run] [--receive-pack=] [--repo=] [-f | --force] [-v | --verbose] [ ...] @@ -82,6 +82,7 @@ nor in any Push line of the corresponding remotes file---see below). if the configuration option `remote..mirror` is set. +-n:: --dry-run:: Do everything except actually send the updates. diff --git a/builtin-push.c b/builtin-push.c index 6eda372a55..3cb1ee46d1 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -10,7 +10,7 @@ #include "parse-options.h" static const char * const push_usage[] = { - "git push [--all | --mirror] [--dry-run] [--porcelain] [--tags] [--receive-pack=] [--repo=] [-f | --force] [-v] [ ...]", + "git push [--all | --mirror] [-n | --dry-run] [--porcelain] [--tags] [--receive-pack=] [--repo=] [-f | --force] [-v] [ ...]", NULL, }; @@ -182,7 +182,7 @@ int cmd_push(int argc, const char **argv, const char *prefix) OPT_BIT( 0 , "mirror", &flags, "mirror all refs", (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)), OPT_BOOLEAN( 0 , "tags", &tags, "push tags"), - OPT_BIT( 0 , "dry-run", &flags, "dry run", TRANSPORT_PUSH_DRY_RUN), + OPT_BIT('n' , "dry-run", &flags, "dry run", TRANSPORT_PUSH_DRY_RUN), OPT_BIT( 0, "porcelain", &flags, "machine-readable output", TRANSPORT_PUSH_PORCELAIN), OPT_BIT('f', "force", &flags, "force updates", TRANSPORT_PUSH_FORCE), OPT_BOOLEAN( 0 , "thin", &thin, "use thin pack"), From 65d15ed992746068d34b5fa7397ab39a940d2c69 Mon Sep 17 00:00:00 2001 From: Johannes Gilger Date: Sun, 13 Sep 2009 15:35:05 +0200 Subject: [PATCH 03/31] git-clone doc: typofix Signed-off-by: Johannes Gilger Signed-off-by: Junio C Hamano --- Documentation/git-clone.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index f23100e509..aacf4fd327 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -130,7 +130,7 @@ objects from the source repository into a pack in the cloned repository. --branch :: -b :: Instead of pointing the newly created HEAD to the branch pointed - to by the cloned repositoroy's HEAD, point to branch + to by the cloned repository's HEAD, point to branch instead. In a non-bare repository, this is the branch that will be checked out. From 98df233e2d7d815b1f2e2e253b9d6c6ce1bfe58f Mon Sep 17 00:00:00 2001 From: Clemens Buchacher Date: Sun, 13 Sep 2009 12:49:45 +0200 Subject: [PATCH 04/31] test local clone by copying Test the effect of an earlier change by f7835a2 (preserve mtime of local clone, 2009-09-12) to keep stale loose object files stale in the new repository when a local clone is made by copying files in .git/ directory. Signed-off-by: Clemens Buchacher Signed-off-by: Junio C Hamano --- t/t5304-prune.sh | 54 +++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh index 55ed7c7935..3c6687abec 100755 --- a/t/t5304-prune.sh +++ b/t/t5304-prune.sh @@ -6,6 +6,17 @@ test_description='prune' . ./test-lib.sh +day=$((60*60*24)) +week=$(($day*7)) + +add_blob() { + before=$(git count-objects | sed "s/ .*//") && + BLOB=$(echo aleph_0 | git hash-object -w --stdin) && + BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") && + test $((1 + $before)) = $(git count-objects | sed "s/ .*//") && + test -f $BLOB_FILE +} + test_expect_success setup ' : > file && @@ -31,11 +42,7 @@ test_expect_success 'prune stale packs' ' test_expect_success 'prune --expire' ' - before=$(git count-objects | sed "s/ .*//") && - BLOB=$(echo aleph | git hash-object -w --stdin) && - BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") && - test $((1 + $before)) = $(git count-objects | sed "s/ .*//") && - test -f $BLOB_FILE && + add_blob && git prune --expire=1.hour.ago && test $((1 + $before)) = $(git count-objects | sed "s/ .*//") && test -f $BLOB_FILE && @@ -48,16 +55,12 @@ test_expect_success 'prune --expire' ' test_expect_success 'gc: implicit prune --expire' ' - before=$(git count-objects | sed "s/ .*//") && - BLOB=$(echo aleph_0 | git hash-object -w --stdin) && - BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") && - test $((1 + $before)) = $(git count-objects | sed "s/ .*//") && - test -f $BLOB_FILE && - test-chmtime =-$((86400*14-30)) $BLOB_FILE && + add_blob && + test-chmtime =-$((2*$week-30)) $BLOB_FILE && git gc && test $((1 + $before)) = $(git count-objects | sed "s/ .*//") && test -f $BLOB_FILE && - test-chmtime =-$((86400*14+1)) $BLOB_FILE && + test-chmtime =-$((2*$week+1)) $BLOB_FILE && git gc && test $before = $(git count-objects | sed "s/ .*//") && ! test -f $BLOB_FILE @@ -114,12 +117,8 @@ test_expect_success 'prune: do not prune heads listed as an argument' ' test_expect_success 'gc --no-prune' ' - before=$(git count-objects | sed "s/ .*//") && - BLOB=$(echo aleph_0 | git hash-object -w --stdin) && - BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") && - test $((1 + $before)) = $(git count-objects | sed "s/ .*//") && - test -f $BLOB_FILE && - test-chmtime =-$((86400*5001)) $BLOB_FILE && + add_blob && + test-chmtime =-$((5001*$day)) $BLOB_FILE && git config gc.pruneExpire 2.days.ago && git gc --no-prune && test 1 = $(git count-objects | sed "s/ .*//") && @@ -140,9 +139,8 @@ test_expect_success 'gc respects gc.pruneExpire' ' test_expect_success 'gc --prune=' ' - BLOB=$(echo aleph_0 | git hash-object -w --stdin) && - BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") && - test-chmtime =-$((86400*5001)) $BLOB_FILE && + add_blob && + test-chmtime =-$((5001*$day)) $BLOB_FILE && git gc --prune=5002.days.ago && test -f $BLOB_FILE && git gc --prune=5000.days.ago && @@ -150,4 +148,18 @@ test_expect_success 'gc --prune=' ' ' +test_expect_success 'gc: prune old objects after local clone' ' + add_blob && + test-chmtime =-$((2*$week+1)) $BLOB_FILE && + git clone --no-hardlinks . aclone && + ( + cd aclone && + test 1 = $(git count-objects | sed "s/ .*//") && + test -f $BLOB_FILE && + git gc --prune && + test 0 = $(git count-objects | sed "s/ .*//") && + ! test -f $BLOB_FILE + ) +' + test_done From 05d3951ec9c531d348fe0dbb9ae058d38728a550 Mon Sep 17 00:00:00 2001 From: Dmitry Potapov Date: Sun, 13 Sep 2009 16:05:52 +0400 Subject: [PATCH 05/31] git-archive: add '-o' as a alias for '--output' The '-o' option is commonly used in many tools to specify the output file. Typing '--output' every time is a bit too long to be a practical alternative to redirecting output. But specifying the output name has the advantage of making possible to guess the desired output format by filename extension. Signed-off-by: Dmitry Potapov Signed-off-by: Junio C Hamano --- Documentation/git-archive.txt | 3 ++- archive.c | 2 +- builtin-archive.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt index 92444ddf10..1917f2e8a8 100644 --- a/Documentation/git-archive.txt +++ b/Documentation/git-archive.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git archive' [--format=] [--list] [--prefix=/] [] - [--output=] [--worktree-attributes] + [-o | --output=] [--worktree-attributes] [--remote= [--exec=]] [path...] @@ -48,6 +48,7 @@ OPTIONS --prefix=/:: Prepend / to each filename in the archive. +-o :: --output=:: Write the archive to instead of stdout. diff --git a/archive.c b/archive.c index 0bca9ca403..73b8e8a56d 100644 --- a/archive.c +++ b/archive.c @@ -283,7 +283,7 @@ static int parse_archive_args(int argc, const char **argv, OPT_STRING(0, "format", &format, "fmt", "archive format"), OPT_STRING(0, "prefix", &base, "prefix", "prepend prefix to each pathname in the archive"), - OPT_STRING(0, "output", &output, "file", + OPT_STRING('o', "output", &output, "file", "write the archive to this file"), OPT_BOOLEAN(0, "worktree-attributes", &worktree_attributes, "read .gitattributes in working directory"), diff --git a/builtin-archive.c b/builtin-archive.c index f9a4bea41e..565314b04c 100644 --- a/builtin-archive.c +++ b/builtin-archive.c @@ -71,7 +71,7 @@ int cmd_archive(int argc, const char **argv, const char *prefix) const char *output = NULL; const char *remote = NULL; struct option local_opts[] = { - OPT_STRING(0, "output", &output, "file", + OPT_STRING('o', "output", &output, "file", "write the archive to this file"), OPT_STRING(0, "remote", &remote, "repo", "retrieve the archive from remote repository "), From 518ef8f07f72271dff4040c1e7452ab6de73d199 Mon Sep 17 00:00:00 2001 From: Todd Zullinger Date: Fri, 11 Sep 2009 19:23:45 -0400 Subject: [PATCH 06/31] completion: Replace config --list with --get-regexp James Bardin noted that the completion spewed warnings when no git config file is present. This is likely a bug to be fixed in git config, but it's also good to simplify the completion code by using the --get-regexp option as Jeff King pointed out. Signed-off-by: Todd Zullinger Trivially-acked-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 30 ++++++++------------------ 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 98592040d1..2d2d5794ad 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -318,13 +318,9 @@ __git_remotes () echo ${i#$d/remotes/} done [ "$ngoff" ] && shopt -u nullglob - for i in $(git --git-dir="$d" config --list); do - case "$i" in - remote.*.url=*) - i="${i#remote.}" - echo "${i/.url=*/}" - ;; - esac + for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do + i="${i#remote.}" + echo "${i/.url*/}" done } @@ -605,13 +601,9 @@ __git_porcelain_commandlist="$(__git_porcelain_commands 2>/dev/null)" __git_aliases () { local i IFS=$'\n' - for i in $(git --git-dir="$(__gitdir)" config --list); do - case "$i" in - alias.*) - i="${i#alias.}" - echo "${i/=*/}" - ;; - esac + for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do + i="${i#alias.}" + echo "${i/ */}" done } @@ -1769,13 +1761,9 @@ _git_remote () ;; update) local i c='' IFS=$'\n' - for i in $(git --git-dir="$(__gitdir)" config --list); do - case "$i" in - remotes.*) - i="${i#remotes.}" - c="$c ${i/=*/}" - ;; - esac + for i in $(git --git-dir="$(__gitdir)" config --get-regexp "remotes\..*" 2>/dev/null); do + i="${i#remotes.}" + c="$c ${i/ */}" done __gitcomp "$c" ;; From 0f4b377c20fb7d93f8bfeec39efb2b9392d6aebc Mon Sep 17 00:00:00 2001 From: Dmitry Potapov Date: Mon, 14 Sep 2009 00:17:01 +0400 Subject: [PATCH 07/31] git-archive: infer output format from filename when unspecified A command line $ git archive -o my-v2.0.zip v2.0 almost certainly wants the output in zip format, even though it does not specify any --format option. When --format is not given, but output filename is, try to infer what format is requested from the filename extension. Currently this code only knows about '.zip'. When the format is unspecified and the filename does not tell us, the output will be in 'tar' format as before. Of course, an explicit --format will not trigger this guesswork. Signed-off-by: Dmitry Potapov Signed-off-by: Junio C Hamano --- Documentation/git-archive.txt | 13 +++++++++++-- builtin-archive.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt index 1917f2e8a8..3d1c1e75b7 100644 --- a/Documentation/git-archive.txt +++ b/Documentation/git-archive.txt @@ -34,8 +34,11 @@ OPTIONS ------- --format=:: - Format of the resulting archive: 'tar' or 'zip'. The default - is 'tar'. + Format of the resulting archive: 'tar' or 'zip'. If this option + is not given, and the output file is specified, the format is + inferred from the filename if possible (e.g. writing to "foo.zip" + makes the output to be in the zip format). Otherwise the output + format is `tar`. -l:: --list:: @@ -130,6 +133,12 @@ git archive --format=zip --prefix=git-docs/ HEAD:Documentation/ > git-1.4.0-docs Put everything in the current head's Documentation/ directory into 'git-1.4.0-docs.zip', with the prefix 'git-docs/'. +git archive -o latest.zip HEAD:: + + Create a Zip archive that contains the contents of the latest + commit on the current branch. Note that the output format is + inferred by the extension of the output file. + SEE ALSO -------- diff --git a/builtin-archive.c b/builtin-archive.c index 565314b04c..12351e9dd5 100644 --- a/builtin-archive.c +++ b/builtin-archive.c @@ -60,6 +60,17 @@ static int run_remote_archiver(int argc, const char **argv, return !!rv; } +static const char *format_from_name(const char *filename) +{ + const char *ext = strrchr(filename, '.'); + if (!ext) + return NULL; + ext++; + if (!strcasecmp(ext, "zip")) + return "zip"; + return NULL; +} + #define PARSE_OPT_KEEP_ALL ( PARSE_OPT_KEEP_DASHDASH | \ PARSE_OPT_KEEP_ARGV0 | \ PARSE_OPT_KEEP_UNKNOWN | \ @@ -70,6 +81,7 @@ int cmd_archive(int argc, const char **argv, const char *prefix) const char *exec = "git-upload-archive"; const char *output = NULL; const char *remote = NULL; + const char *format = NULL; struct option local_opts[] = { OPT_STRING('o', "output", &output, "file", "write the archive to this file"), @@ -77,14 +89,31 @@ int cmd_archive(int argc, const char **argv, const char *prefix) "retrieve the archive from remote repository "), OPT_STRING(0, "exec", &exec, "cmd", "path to the remote git-upload-archive command"), + OPT_STRING(0, "format", &format, "fmt", "archive format"), OPT_END() }; + char fmt_opt[32]; argc = parse_options(argc, argv, prefix, local_opts, NULL, PARSE_OPT_KEEP_ALL); - if (output) + if (output) { create_output_file(output); + if (!format) + format = format_from_name(output); + } + + if (format) { + sprintf(fmt_opt, "--format=%s", format); + /* + * This is safe because either --format and/or --output must + * have been given on the original command line if we get to + * this point, and parse_options() must have eaten at least + * one argument, i.e. we have enough room to append to argv[]. + */ + argv[argc++] = fmt_opt; + argv[argc] = NULL; + } if (remote) return run_remote_archiver(argc, argv, remote, exec); From 03aa8ff3be3b35522b2e378651e65e0e86778018 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 14 Sep 2009 02:41:16 -0400 Subject: [PATCH 08/31] Nicolas Pitre has a new email address Due to problems at cam.org, my nico@cam.org email address is no longer valid. From now on, nico@fluxnic.net should be used instead. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- .mailmap | 1 + diff-delta.c | 2 +- git.spec.in | 2 +- patch-delta.c | 2 +- progress.c | 2 +- test-delta.c | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.mailmap b/.mailmap index 373476bdc0..975e6758ef 100644 --- a/.mailmap +++ b/.mailmap @@ -41,6 +41,7 @@ Michele Ballabio Nanako Shiraishi Nanako Shiraishi Nguyễn Thái Ngọc Duy + Philippe Bruhat Ramsay Allan Jones René Scharfe diff --git a/diff-delta.c b/diff-delta.c index a4e28df714..464ac3ffc0 100644 --- a/diff-delta.c +++ b/diff-delta.c @@ -4,7 +4,7 @@ * This code was greatly inspired by parts of LibXDiff from Davide Libenzi * http://www.xmailserver.org/xdiff-lib.html * - * Rewritten for GIT by Nicolas Pitre , (C) 2005-2007 + * Rewritten for GIT by Nicolas Pitre , (C) 2005-2007 * * This code is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/git.spec.in b/git.spec.in index 4be0834f0b..ab224f7eae 100644 --- a/git.spec.in +++ b/git.spec.in @@ -233,7 +233,7 @@ rm -rf $RPM_BUILD_ROOT * Tue Mar 27 2007 Eygene Ryabinkin - Added the git-p4 package: Perforce import stuff. -* Mon Feb 13 2007 Nicolas Pitre +* Mon Feb 13 2007 Nicolas Pitre - Update core package description (Git isn't as stupid as it used to be) * Mon Feb 12 2007 Junio C Hamano diff --git a/patch-delta.c b/patch-delta.c index ef748ce96d..e02e13bd4e 100644 --- a/patch-delta.c +++ b/patch-delta.c @@ -2,7 +2,7 @@ * patch-delta.c: * recreate a buffer from a source and the delta produced by diff-delta.c * - * (C) 2005 Nicolas Pitre + * (C) 2005 Nicolas Pitre * * This code is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/progress.c b/progress.c index 621c34edc2..132ed95a3d 100644 --- a/progress.c +++ b/progress.c @@ -1,7 +1,7 @@ /* * Simple text-based progress display module for GIT * - * Copyright (c) 2007 by Nicolas Pitre + * Copyright (c) 2007 by Nicolas Pitre * * This code is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/test-delta.c b/test-delta.c index 3d885ff37e..af40a3c49e 100644 --- a/test-delta.c +++ b/test-delta.c @@ -1,7 +1,7 @@ /* * test-delta.c: test code to exercise diff-delta.c and patch-delta.c * - * (C) 2005 Nicolas Pitre + * (C) 2005 Nicolas Pitre * * This code is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as From 39c448c19de7269e6130b6e183645c5b9afe0579 Mon Sep 17 00:00:00 2001 From: Heiko Voigt Date: Mon, 14 Sep 2009 10:47:06 +0200 Subject: [PATCH 09/31] remove logical typo in documentation of sample update hook Signed-off-by: Heiko Voigt Signed-off-by: Junio C Hamano --- Documentation/githooks.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index 79f633e837..06e0f315c3 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -245,7 +245,7 @@ Both standard output and standard error output are forwarded to for the user. The default 'update' hook, when enabled--and with -`hooks.allowunannotated` config option turned on--prevents +`hooks.allowunannotated` config option unset or set to false--prevents unannotated tags to be pushed. [[post-receive]] From 20f34902d154f390ebaa7eed7f42ad14140b8acb Mon Sep 17 00:00:00 2001 From: Heiko Voigt Date: Mon, 14 Sep 2009 10:49:01 +0200 Subject: [PATCH 10/31] web--browse: fix Mac OS X GUI detection for 10.6 Since OS X 10.6 the variable $SECURITYSESSIONID does not exist anymore, so lets look for the $TERM_PROGRAM variable as backup. Signed-off-by: Heiko Voigt Signed-off-by: Junio C Hamano --- git-web--browse.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/git-web--browse.sh b/git-web--browse.sh index 4f5c740df5..a578c3a732 100755 --- a/git-web--browse.sh +++ b/git-web--browse.sh @@ -111,7 +111,8 @@ if test -z "$browser" ; then browser_candidates="w3m links lynx" fi # SECURITYSESSIONID indicates an OS X GUI login session - if test -n "$SECURITYSESSIONID"; then + if test -n "$SECURITYSESSIONID" \ + -o "$TERM_PROGRAM" = "Apple_Terminal" ; then browser_candidates="open $browser_candidates" fi # /bin/start indicates MinGW From b2025146d0718d953036352f8435cfa392b1d799 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 14 Sep 2009 14:48:15 -0700 Subject: [PATCH 11/31] http.c: avoid freeing an uninitialized pointer An earlier 59b8d38 (http.c: remove verification of remote packs) left the variable "url" uninitialized; "goto cleanup" codepath can free it which is not very nice. Signed-off-by: Junio C Hamano --- http.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http.c b/http.c index d0cc1b3340..15926d8d6d 100644 --- a/http.c +++ b/http.c @@ -866,7 +866,7 @@ static int fetch_pack_index(unsigned char *sha1, const char *base_url) int ret = 0; char *hex = xstrdup(sha1_to_hex(sha1)); char *filename; - char *url; + char *url = NULL; struct strbuf buf = STRBUF_INIT; if (has_pack_index(sha1)) { From cb572206d9dac4ba52878e7e1a4a7028d85707ab Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 16 Sep 2009 14:53:26 -0700 Subject: [PATCH 12/31] GIT 1.6.4.4 Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.6.4.4.txt | 26 ++++++++++++++++++++++++++ Documentation/git.txt | 3 ++- GIT-VERSION-GEN | 2 +- RelNotes | 2 +- 4 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 Documentation/RelNotes-1.6.4.4.txt diff --git a/Documentation/RelNotes-1.6.4.4.txt b/Documentation/RelNotes-1.6.4.4.txt new file mode 100644 index 0000000000..0ead45fc72 --- /dev/null +++ b/Documentation/RelNotes-1.6.4.4.txt @@ -0,0 +1,26 @@ +GIT v1.6.4.4 Release Notes +========================== + +Fixes since v1.6.4.4 +-------------------- + +* The workaround for Github server that sometimes gave 500 (Internal server + error) response to HEAD requests in 1.6.4.3 introduced a regression that + caused re-fetching projects over http to segfault in certain cases due + to uninitialized pointer being freed. + +* "git pull" on an unborn branch used to consider anything in the work + tree and the index discardable. + +* "git diff -b/w" did not work well on the incomplete line at the end of + the file, due to an incorrect hashing of lines in the low-level xdiff + routines. + +* "git checkout-index --prefix=$somewhere" used to work when $somewhere is + a symbolic link to a directory elsewhere, but v1.6.4.2 broke it. + +* "git unpack-objects --strict", invoked when receive.fsckobjects + configuration is set in the receiving repository of "git push", did not + properly check the objects, especially the submodule links, it received. + +Other minor documentation updates are included. diff --git a/Documentation/git.txt b/Documentation/git.txt index f91cabb4ce..20b573e37c 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,9 +43,10 @@ unreleased) version of git, that is available from 'master' branch of the `git.git` repository. Documentation for older releases are available here: -* link:v1.6.4.3/git.html[documentation for release 1.6.4.3] +* link:v1.6.4.4/git.html[documentation for release 1.6.4.4] * release notes for + link:RelNotes-1.6.4.4.txt[1.6.4.4], link:RelNotes-1.6.4.3.txt[1.6.4.3], link:RelNotes-1.6.4.2.txt[1.6.4.2], link:RelNotes-1.6.4.1.txt[1.6.4.1], diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 7956bc94a3..68b95733c7 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.6.4.3 +DEF_VER=v1.6.4.4 LF=' ' diff --git a/RelNotes b/RelNotes index ed984e3b41..2dad8b277d 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes-1.6.4.3.txt \ No newline at end of file +Documentation/RelNotes-1.6.4.4.txt \ No newline at end of file From e481b1d8db9947681a5c124545ef06951f42155d Mon Sep 17 00:00:00 2001 From: Clemens Buchacher Date: Thu, 17 Sep 2009 09:21:02 +0200 Subject: [PATCH 13/31] cvs: initialize empty password If we do not read a password from the command line, and there are no passwords stored in .cvspass, we have to initialize the password with just "A". This fixes a regression introduced by 3fb9d582 (Do not scramble password read from .cvspass). Signed-off-by: Clemens Buchacher Signed-off-by: Junio C Hamano --- git-cvsimport.perl | 1 + 1 file changed, 1 insertion(+) diff --git a/git-cvsimport.perl b/git-cvsimport.perl index d7411151dd..1ad20ac964 100755 --- a/git-cvsimport.perl +++ b/git-cvsimport.perl @@ -253,6 +253,7 @@ sub conn { } } }; + $pass = "A" unless $pass; } my ($s, $rep); From 1f986c4ac4df6fcac4b19bc9cd3a8b6c8f0ffdea Mon Sep 17 00:00:00 2001 From: Thiago Farina Date: Thu, 17 Sep 2009 13:20:53 -0400 Subject: [PATCH 14/31] Update the usage bundle string. "git bundle -h" gives a single long line that is hard to read. Rewrite it into a multi-line format similar to the one used by other commands, e.g "git stash -h". Signed-off-by: Thiago Farina Signed-off-by: Junio C Hamano --- builtin-bundle.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/builtin-bundle.c b/builtin-bundle.c index 9b58152047..2006cc5cd5 100644 --- a/builtin-bundle.c +++ b/builtin-bundle.c @@ -9,7 +9,11 @@ * bundle supporting "fetch", "pull", and "ls-remote". */ -static const char *bundle_usage="git bundle (create | verify | list-heads [refname]... | unbundle [refname]... )"; +static const char builtin_bundle_usage[] = + "git bundle create \n" + " or: git bundle verify \n" + " or: git bundle list-heads [refname...]\n" + " or: git bundle unbundle [refname...]"; int cmd_bundle(int argc, const char **argv, const char *prefix) { @@ -20,7 +24,7 @@ int cmd_bundle(int argc, const char **argv, const char *prefix) char buffer[PATH_MAX]; if (argc < 3) - usage(bundle_usage); + usage(builtin_bundle_usage); cmd = argv[1]; bundle_file = argv[2]; @@ -59,5 +63,5 @@ int cmd_bundle(int argc, const char **argv, const char *prefix) return !!unbundle(&header, bundle_fd) || list_bundle_refs(&header, argc, argv); } else - usage(bundle_usage); + usage(builtin_bundle_usage); } From 812bdbc31b246fcd5f3293e4dbac27eaec1ef4fa Mon Sep 17 00:00:00 2001 From: Thiago Farina Date: Fri, 18 Sep 2009 12:11:52 -0700 Subject: [PATCH 15/31] pack-objects: remove SP at the end of usage string These spaces immediately before the end of lines are unnecessary. While at it, instead of using a single string literal with backslashes at end of each line, split the lines into individual string literals and tell the compiler to concatenate them. Signed-off-by: Thiago Farina Signed-off-by: Junio C Hamano --- builtin-pack-objects.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 7a390e1d44..02f9246cdb 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -22,15 +22,15 @@ #include #endif -static const char pack_usage[] = "\ -git pack-objects [{ -q | --progress | --all-progress }] \n\ - [--max-pack-size=N] [--local] [--incremental] \n\ - [--window=N] [--window-memory=N] [--depth=N] \n\ - [--no-reuse-delta] [--no-reuse-object] [--delta-base-offset] \n\ - [--threads=N] [--non-empty] [--revs [--unpacked | --all]*] [--reflog] \n\ - [--stdout | base-name] [--include-tag] \n\ - [--keep-unreachable | --unpack-unreachable] \n\ - [ Date: Wed, 16 Sep 2009 10:20:17 +0200 Subject: [PATCH 16/31] Avoid declaration after statement MSVC does not understand this C99 style. Signed-off-by: Frank Li Signed-off-by: Marius Storm-Olsen Acked-by: Johannes Sixt Signed-off-by: Junio C Hamano --- compat/mingw.c | 14 ++++++++++---- help.c | 3 ++- run-command.c | 2 ++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index 36ef8d3214..5478b747ce 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -123,13 +123,17 @@ int mingw_open (const char *filename, int oflags, ...) { va_list args; unsigned mode; + int fd; + va_start(args, oflags); mode = va_arg(args, int); va_end(args); if (!strcmp(filename, "/dev/null")) filename = "nul"; - int fd = open(filename, oflags, mode); + + fd = open(filename, oflags, mode); + if (fd < 0 && (oflags & O_CREAT) && errno == EACCES) { DWORD attrs = GetFileAttributes(filename); if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) @@ -580,10 +584,11 @@ static char **get_path_split(void) static void free_path_split(char **path) { + char **p = path; + if (!path) return; - char **p = path; while (*p) free(*p++); free(path); @@ -1120,9 +1125,9 @@ int sigaction(int sig, struct sigaction *in, struct sigaction *out) #undef signal sig_handler_t mingw_signal(int sig, sig_handler_t handler) { + sig_handler_t old = timer_fn; if (sig != SIGALRM) return signal(sig, handler); - sig_handler_t old = timer_fn; timer_fn = handler; return old; } @@ -1209,8 +1214,9 @@ struct dirent *mingw_readdir(DIR *dir) if (dir->dd_handle == (long)INVALID_HANDLE_VALUE && dir->dd_stat == 0) { + DWORD lasterr; handle = FindFirstFileA(dir->dd_name, &buf); - DWORD lasterr = GetLastError(); + lasterr = GetLastError(); dir->dd_handle = (long)handle; if (handle == INVALID_HANDLE_VALUE && (lasterr != ERROR_NO_MORE_FILES)) { errno = err_win_to_posix(lasterr); diff --git a/help.c b/help.c index 294337e71c..fd51b8e8ef 100644 --- a/help.c +++ b/help.c @@ -127,7 +127,7 @@ static int is_executable(const char *name) return 0; #ifdef __MINGW32__ - /* cannot trust the executable bit, peek into the file instead */ +{ /* cannot trust the executable bit, peek into the file instead */ char buf[3] = { 0 }; int n; int fd = open(name, O_RDONLY); @@ -140,6 +140,7 @@ static int is_executable(const char *name) st.st_mode |= S_IXUSR; close(fd); } +} #endif return st.st_mode & S_IXUSR; } diff --git a/run-command.c b/run-command.c index ac314a5a8d..02aaedfb8c 100644 --- a/run-command.c +++ b/run-command.c @@ -134,6 +134,7 @@ fail_pipe: error("cannot fork() for %s: %s", cmd->argv[0], strerror(failed_errno = errno)); #else +{ int s0 = -1, s1 = -1, s2 = -1; /* backups of stdin, stdout, stderr */ const char **sargv = cmd->argv; char **env = environ; @@ -197,6 +198,7 @@ fail_pipe: dup2(s1, 1), close(s1); if (s2 >= 0) dup2(s2, 2), close(s2); +} #endif if (cmd->pid < 0) { From 627735f9bf322c5c964b396f4a55d14e18d34aa2 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 16 Sep 2009 10:20:18 +0200 Subject: [PATCH 17/31] Add include guards to compat/win32.h Signed-off-by: Marius Storm-Olsen Acked-by: Johannes Sixt Signed-off-by: Junio C Hamano --- compat/win32.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compat/win32.h b/compat/win32.h index c26384e595..e8c178d8cd 100644 --- a/compat/win32.h +++ b/compat/win32.h @@ -1,3 +1,6 @@ +#ifndef WIN32_H +#define WIN32_H + /* common Win32 functions for MinGW and Cygwin */ #include @@ -32,3 +35,5 @@ static inline int get_file_attr(const char *fname, WIN32_FILE_ATTRIBUTE_DATA *fd return ENOENT; } } + +#endif From 3f83bf3784d49e162532212230a271a8cc8edbf0 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Wed, 16 Sep 2009 10:20:19 +0200 Subject: [PATCH 18/31] Change regerror() declaration from K&R style to ANSI C (C89) The MSVC headers typedef errcode as int, and thus confused the compiler in the K&R style definition. ANSI style deconfuses it. Signed-off-by: Frank Li Signed-off-by: Marius Storm-Olsen Acked-by: Johannes Sixt Signed-off-by: Junio C Hamano --- compat/regex/regex.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/compat/regex/regex.c b/compat/regex/regex.c index 5ea007567d..67d5c370a0 100644 --- a/compat/regex/regex.c +++ b/compat/regex/regex.c @@ -4852,11 +4852,8 @@ regexec (preg, string, nmatch, pmatch, eflags) from either regcomp or regexec. We don't use PREG here. */ size_t -regerror (errcode, preg, errbuf, errbuf_size) - int errcode; - const regex_t *preg; - char *errbuf; - size_t errbuf_size; +regerror(int errcode, const regex_t *preg, + char *errbuf, size_t errbuf_size) { const char *msg; size_t msg_size; From a6ca8c62467570d5d227eba4f2b838ce4b9940e8 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 16 Sep 2009 10:20:20 +0200 Subject: [PATCH 19/31] Set _O_BINARY as default fmode for both MinGW and MSVC MinGW set the _CRT_fmode to set both the default fmode and _O_BINARY on stdin/stdout/stderr. Rather use the main() define in mingw.h to set this for both MinGW and MSVC. This will ensure that a MinGW and MSVC build will handle input and output identically. Signed-off-by: Marius Storm-Olsen Acked-by: Johannes Sixt Signed-off-by: Junio C Hamano --- compat/mingw.c | 2 -- compat/mingw.h | 5 +++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index 5478b747ce..5a8fae8b31 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -3,8 +3,6 @@ #include #include "../strbuf.h" -unsigned int _CRT_fmode = _O_BINARY; - static int err_win_to_posix(DWORD winerr) { int error = ENOSYS; diff --git a/compat/mingw.h b/compat/mingw.h index c43917cd6e..bcd23b0a45 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -227,12 +227,17 @@ void free_environ(char **env); /* * A replacement of main() that ensures that argv[0] has a path + * and that default fmode and std(in|out|err) are in binary mode */ #define main(c,v) dummy_decl_mingw_main(); \ static int mingw_main(); \ int main(int argc, const char **argv) \ { \ + _fmode = _O_BINARY; \ + _setmode(_fileno(stdin), _O_BINARY); \ + _setmode(_fileno(stdout), _O_BINARY); \ + _setmode(_fileno(stderr), _O_BINARY); \ argv[0] = xstrdup(_pgmptr); \ return mingw_main(argc, argv); \ } \ From d7fa500fb598d725bda3427535e87f06caf93ee8 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Wed, 16 Sep 2009 10:20:21 +0200 Subject: [PATCH 20/31] Fix __stdcall placement and function prototype MSVC requires __stdcall to be between the functions return value and the function name, and that the function pointer type is in the form of return_type (WINAPI *function_name)(arguments...) Signed-off-by: Frank Li Signed-off-by: Marius Storm-Olsen Acked-by: Johannes Sixt Signed-off-by: Junio C Hamano --- compat/mingw.c | 4 ++-- run-command.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index 5a8fae8b31..34ee427baf 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1027,7 +1027,7 @@ static sig_handler_t timer_fn = SIG_DFL; * length to call the signal handler. */ -static __stdcall unsigned ticktack(void *dummy) +static unsigned __stdcall ticktack(void *dummy) { while (WaitForSingleObject(timer_event, timer_interval) == WAIT_TIMEOUT) { if (timer_fn == SIG_DFL) @@ -1154,7 +1154,7 @@ void mingw_open_html(const char *unixpath) int link(const char *oldpath, const char *newpath) { - typedef BOOL WINAPI (*T)(const char*, const char*, LPSECURITY_ATTRIBUTES); + typedef BOOL (WINAPI *T)(const char*, const char*, LPSECURITY_ATTRIBUTES); static T create_hard_link = NULL; if (!create_hard_link) { create_hard_link = (T) GetProcAddress( diff --git a/run-command.c b/run-command.c index 02aaedfb8c..bb76750cd0 100644 --- a/run-command.c +++ b/run-command.c @@ -316,7 +316,7 @@ int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const } #ifdef __MINGW32__ -static __stdcall unsigned run_thread(void *data) +static unsigned __stdcall run_thread(void *data) { struct async *async = data; return async->proc(async->fd_for_proc, async->data); From 71064e3f86fbf2eb5c2b55a3024051f9542ae229 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Wed, 16 Sep 2009 10:20:22 +0200 Subject: [PATCH 21/31] Test for WIN32 instead of __MINGW32_ The code which is conditional on MinGW32 is actually conditional on Windows. Use the WIN32 symbol, which is defined by the MINGW32 and MSVC environments, but not by Cygwin. Define SNPRINTF_SIZE_CORR=1 for MSVC too, as its vsnprintf function does not add NUL at the end of the buffer if the result fits the buffer size exactly. Signed-off-by: Frank Li Signed-off-by: Marius Storm-Olsen Acked-by: Johannes Sixt Signed-off-by: Junio C Hamano --- compat/snprintf.c | 10 ++++++---- help.c | 2 +- pager.c | 4 ++-- run-command.c | 8 ++++---- run-command.h | 2 +- setup.c | 2 +- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/compat/snprintf.c b/compat/snprintf.c index 4d07087abd..e1e0e7543d 100644 --- a/compat/snprintf.c +++ b/compat/snprintf.c @@ -2,12 +2,14 @@ /* * The size parameter specifies the available space, i.e. includes - * the trailing NUL byte; but Windows's vsnprintf expects the - * number of characters to write, and does not necessarily write the - * trailing NUL. + * the trailing NUL byte; but Windows's vsnprintf uses the entire + * buffer and avoids the trailing NUL, should the buffer be exactly + * big enough for the result. Defining SNPRINTF_SIZE_CORR to 1 will + * therefore remove 1 byte from the reported buffer size, so we + * always have room for a trailing NUL byte. */ #ifndef SNPRINTF_SIZE_CORR -#if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ < 4 +#if defined(WIN32) && (!defined(__GNUC__) || __GNUC__ < 4) #define SNPRINTF_SIZE_CORR 1 #else #define SNPRINTF_SIZE_CORR 0 diff --git a/help.c b/help.c index fd51b8e8ef..e8db31f60f 100644 --- a/help.c +++ b/help.c @@ -126,7 +126,7 @@ static int is_executable(const char *name) !S_ISREG(st.st_mode)) return 0; -#ifdef __MINGW32__ +#ifdef WIN32 { /* cannot trust the executable bit, peek into the file instead */ char buf[3] = { 0 }; int n; diff --git a/pager.c b/pager.c index f416d38ac2..86facec7b4 100644 --- a/pager.c +++ b/pager.c @@ -9,7 +9,7 @@ static int spawned_pager; -#ifndef __MINGW32__ +#ifndef WIN32 static void pager_preexec(void) { /* @@ -72,7 +72,7 @@ void setup_pager(void) static const char *env[] = { "LESS=FRSX", NULL }; pager_process.env = env; } -#ifndef __MINGW32__ +#ifndef WIN32 pager_process.preexec_cb = pager_preexec; #endif if (start_command(&pager_process)) diff --git a/run-command.c b/run-command.c index bb76750cd0..cf2d8f7fae 100644 --- a/run-command.c +++ b/run-command.c @@ -75,7 +75,7 @@ fail_pipe: trace_argv_printf(cmd->argv, "trace: run_command:"); -#ifndef __MINGW32__ +#ifndef WIN32 fflush(NULL); cmd->pid = fork(); if (!cmd->pid) { @@ -315,7 +315,7 @@ int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const return run_command(&cmd); } -#ifdef __MINGW32__ +#ifdef WIN32 static unsigned __stdcall run_thread(void *data) { struct async *async = data; @@ -331,7 +331,7 @@ int start_async(struct async *async) return error("cannot create pipe: %s", strerror(errno)); async->out = pipe_out[0]; -#ifndef __MINGW32__ +#ifndef WIN32 /* Flush stdio before fork() to avoid cloning buffers */ fflush(NULL); @@ -360,7 +360,7 @@ int start_async(struct async *async) int finish_async(struct async *async) { -#ifndef __MINGW32__ +#ifndef WIN32 int ret = wait_or_whine(async->pid, "child process", 0); #else DWORD ret = 0; diff --git a/run-command.h b/run-command.h index 0c00b25ff2..fb342090e3 100644 --- a/run-command.h +++ b/run-command.h @@ -70,7 +70,7 @@ struct async { int (*proc)(int fd, void *data); void *data; int out; /* caller reads from here and closes it */ -#ifndef __MINGW32__ +#ifndef WIN32 pid_t pid; #else HANDLE tid; diff --git a/setup.c b/setup.c index e3781b656d..029371e584 100644 --- a/setup.c +++ b/setup.c @@ -41,7 +41,7 @@ const char *prefix_path(const char *prefix, int len, const char *path) const char *prefix_filename(const char *pfx, int pfx_len, const char *arg) { static char path[PATH_MAX]; -#ifndef __MINGW32__ +#ifndef WIN32 if (!pfx || !*pfx || is_absolute_path(arg)) return arg; memcpy(path, pfx, pfx_len); From 55fcb06482c9971d95f3575274a8617c0d9f5d92 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 16 Sep 2009 10:20:23 +0200 Subject: [PATCH 22/31] Add empty header files for MSVC port MSVC lacks many of the header files included by git-compat-util.h; add blank header files for these instead of going ifdef crazy. Signed-off-by: Marius Storm-Olsen Acked-by: Johannes Sixt Signed-off-by: Junio C Hamano --- compat/vcbuild/include/arpa/inet.h | 1 + compat/vcbuild/include/grp.h | 1 + compat/vcbuild/include/inttypes.h | 1 + compat/vcbuild/include/netdb.h | 1 + compat/vcbuild/include/netinet/in.h | 1 + compat/vcbuild/include/netinet/tcp.h | 1 + compat/vcbuild/include/pwd.h | 1 + compat/vcbuild/include/sys/ioctl.h | 1 + compat/vcbuild/include/sys/param.h | 1 + compat/vcbuild/include/sys/poll.h | 1 + compat/vcbuild/include/sys/select.h | 1 + compat/vcbuild/include/sys/socket.h | 1 + compat/vcbuild/include/sys/time.h | 1 + compat/vcbuild/include/sys/wait.h | 1 + 14 files changed, 14 insertions(+) create mode 100644 compat/vcbuild/include/arpa/inet.h create mode 100644 compat/vcbuild/include/grp.h create mode 100644 compat/vcbuild/include/inttypes.h create mode 100644 compat/vcbuild/include/netdb.h create mode 100644 compat/vcbuild/include/netinet/in.h create mode 100644 compat/vcbuild/include/netinet/tcp.h create mode 100644 compat/vcbuild/include/pwd.h create mode 100644 compat/vcbuild/include/sys/ioctl.h create mode 100644 compat/vcbuild/include/sys/param.h create mode 100644 compat/vcbuild/include/sys/poll.h create mode 100644 compat/vcbuild/include/sys/select.h create mode 100644 compat/vcbuild/include/sys/socket.h create mode 100644 compat/vcbuild/include/sys/time.h create mode 100644 compat/vcbuild/include/sys/wait.h diff --git a/compat/vcbuild/include/arpa/inet.h b/compat/vcbuild/include/arpa/inet.h new file mode 100644 index 0000000000..0d8552a2c6 --- /dev/null +++ b/compat/vcbuild/include/arpa/inet.h @@ -0,0 +1 @@ +/* Intentionally empty file to support building git with MSVC */ diff --git a/compat/vcbuild/include/grp.h b/compat/vcbuild/include/grp.h new file mode 100644 index 0000000000..0d8552a2c6 --- /dev/null +++ b/compat/vcbuild/include/grp.h @@ -0,0 +1 @@ +/* Intentionally empty file to support building git with MSVC */ diff --git a/compat/vcbuild/include/inttypes.h b/compat/vcbuild/include/inttypes.h new file mode 100644 index 0000000000..0d8552a2c6 --- /dev/null +++ b/compat/vcbuild/include/inttypes.h @@ -0,0 +1 @@ +/* Intentionally empty file to support building git with MSVC */ diff --git a/compat/vcbuild/include/netdb.h b/compat/vcbuild/include/netdb.h new file mode 100644 index 0000000000..0d8552a2c6 --- /dev/null +++ b/compat/vcbuild/include/netdb.h @@ -0,0 +1 @@ +/* Intentionally empty file to support building git with MSVC */ diff --git a/compat/vcbuild/include/netinet/in.h b/compat/vcbuild/include/netinet/in.h new file mode 100644 index 0000000000..0d8552a2c6 --- /dev/null +++ b/compat/vcbuild/include/netinet/in.h @@ -0,0 +1 @@ +/* Intentionally empty file to support building git with MSVC */ diff --git a/compat/vcbuild/include/netinet/tcp.h b/compat/vcbuild/include/netinet/tcp.h new file mode 100644 index 0000000000..0d8552a2c6 --- /dev/null +++ b/compat/vcbuild/include/netinet/tcp.h @@ -0,0 +1 @@ +/* Intentionally empty file to support building git with MSVC */ diff --git a/compat/vcbuild/include/pwd.h b/compat/vcbuild/include/pwd.h new file mode 100644 index 0000000000..0d8552a2c6 --- /dev/null +++ b/compat/vcbuild/include/pwd.h @@ -0,0 +1 @@ +/* Intentionally empty file to support building git with MSVC */ diff --git a/compat/vcbuild/include/sys/ioctl.h b/compat/vcbuild/include/sys/ioctl.h new file mode 100644 index 0000000000..0d8552a2c6 --- /dev/null +++ b/compat/vcbuild/include/sys/ioctl.h @@ -0,0 +1 @@ +/* Intentionally empty file to support building git with MSVC */ diff --git a/compat/vcbuild/include/sys/param.h b/compat/vcbuild/include/sys/param.h new file mode 100644 index 0000000000..0d8552a2c6 --- /dev/null +++ b/compat/vcbuild/include/sys/param.h @@ -0,0 +1 @@ +/* Intentionally empty file to support building git with MSVC */ diff --git a/compat/vcbuild/include/sys/poll.h b/compat/vcbuild/include/sys/poll.h new file mode 100644 index 0000000000..0d8552a2c6 --- /dev/null +++ b/compat/vcbuild/include/sys/poll.h @@ -0,0 +1 @@ +/* Intentionally empty file to support building git with MSVC */ diff --git a/compat/vcbuild/include/sys/select.h b/compat/vcbuild/include/sys/select.h new file mode 100644 index 0000000000..0d8552a2c6 --- /dev/null +++ b/compat/vcbuild/include/sys/select.h @@ -0,0 +1 @@ +/* Intentionally empty file to support building git with MSVC */ diff --git a/compat/vcbuild/include/sys/socket.h b/compat/vcbuild/include/sys/socket.h new file mode 100644 index 0000000000..0d8552a2c6 --- /dev/null +++ b/compat/vcbuild/include/sys/socket.h @@ -0,0 +1 @@ +/* Intentionally empty file to support building git with MSVC */ diff --git a/compat/vcbuild/include/sys/time.h b/compat/vcbuild/include/sys/time.h new file mode 100644 index 0000000000..0d8552a2c6 --- /dev/null +++ b/compat/vcbuild/include/sys/time.h @@ -0,0 +1 @@ +/* Intentionally empty file to support building git with MSVC */ diff --git a/compat/vcbuild/include/sys/wait.h b/compat/vcbuild/include/sys/wait.h new file mode 100644 index 0000000000..0d8552a2c6 --- /dev/null +++ b/compat/vcbuild/include/sys/wait.h @@ -0,0 +1 @@ +/* Intentionally empty file to support building git with MSVC */ From 16fe1e03694e75a3923c3a757ec946aa6098aec7 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Wed, 16 Sep 2009 10:20:24 +0200 Subject: [PATCH 23/31] Add MinGW header files to build git with MSVC Added the header files dirent.h, unistd.h and utime.h Add alloca.h, which simply includes malloc.h, which defines alloca(). Signed-off-by: Frank Li Signed-off-by: Marius Storm-Olsen Acked-by: Johannes Sixt Signed-off-by: Junio C Hamano --- compat/vcbuild/include/alloca.h | 1 + compat/vcbuild/include/dirent.h | 128 +++++++++++++++++++++++++++++ compat/vcbuild/include/sys/utime.h | 34 ++++++++ compat/vcbuild/include/unistd.h | 92 +++++++++++++++++++++ compat/vcbuild/include/utime.h | 1 + 5 files changed, 256 insertions(+) create mode 100644 compat/vcbuild/include/alloca.h create mode 100644 compat/vcbuild/include/dirent.h create mode 100644 compat/vcbuild/include/sys/utime.h create mode 100644 compat/vcbuild/include/unistd.h create mode 100644 compat/vcbuild/include/utime.h diff --git a/compat/vcbuild/include/alloca.h b/compat/vcbuild/include/alloca.h new file mode 100644 index 0000000000..c0d7985b7e --- /dev/null +++ b/compat/vcbuild/include/alloca.h @@ -0,0 +1 @@ +#include diff --git a/compat/vcbuild/include/dirent.h b/compat/vcbuild/include/dirent.h new file mode 100644 index 0000000000..440618db0d --- /dev/null +++ b/compat/vcbuild/include/dirent.h @@ -0,0 +1,128 @@ +/* + * DIRENT.H (formerly DIRLIB.H) + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * + * The mingw-runtime package and its code is distributed in the hope that it + * will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR + * IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to + * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You are free to use this package and its code without limitation. + */ +#ifndef _DIRENT_H_ +#define _DIRENT_H_ +#include + +#define PATH_MAX 512 + +#define __MINGW_NOTHROW + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +struct dirent +{ + long d_ino; /* Always zero. */ + unsigned short d_reclen; /* Always zero. */ + unsigned short d_namlen; /* Length of name in d_name. */ + char d_name[FILENAME_MAX]; /* File name. */ +}; + +/* + * This is an internal data structure. Good programmers will not use it + * except as an argument to one of the functions below. + * dd_stat field is now int (was short in older versions). + */ +typedef struct +{ + /* disk transfer area for this dir */ + struct _finddata_t dd_dta; + + /* dirent struct to return from dir (NOTE: this makes this thread + * safe as long as only one thread uses a particular DIR struct at + * a time) */ + struct dirent dd_dir; + + /* _findnext handle */ + long dd_handle; + + /* + * Status of search: + * 0 = not started yet (next entry to read is first entry) + * -1 = off the end + * positive = 0 based index of next entry + */ + int dd_stat; + + /* given path for dir with search pattern (struct is extended) */ + char dd_name[PATH_MAX+3]; +} DIR; + +DIR* __cdecl __MINGW_NOTHROW opendir (const char*); +struct dirent* __cdecl __MINGW_NOTHROW readdir (DIR*); +int __cdecl __MINGW_NOTHROW closedir (DIR*); +void __cdecl __MINGW_NOTHROW rewinddir (DIR*); +long __cdecl __MINGW_NOTHROW telldir (DIR*); +void __cdecl __MINGW_NOTHROW seekdir (DIR*, long); + + +/* wide char versions */ + +struct _wdirent +{ + long d_ino; /* Always zero. */ + unsigned short d_reclen; /* Always zero. */ + unsigned short d_namlen; /* Length of name in d_name. */ + wchar_t d_name[FILENAME_MAX]; /* File name. */ +}; + +/* + * This is an internal data structure. Good programmers will not use it + * except as an argument to one of the functions below. + */ +typedef struct +{ + /* disk transfer area for this dir */ + //struct _wfinddata_t dd_dta; + + /* dirent struct to return from dir (NOTE: this makes this thread + * safe as long as only one thread uses a particular DIR struct at + * a time) */ + struct _wdirent dd_dir; + + /* _findnext handle */ + long dd_handle; + + /* + * Status of search: + * 0 = not started yet (next entry to read is first entry) + * -1 = off the end + * positive = 0 based index of next entry + */ + int dd_stat; + + /* given path for dir with search pattern (struct is extended) */ + wchar_t dd_name[1]; +} _WDIR; + + + +_WDIR* __cdecl __MINGW_NOTHROW _wopendir (const wchar_t*); +struct _wdirent* __cdecl __MINGW_NOTHROW _wreaddir (_WDIR*); +int __cdecl __MINGW_NOTHROW _wclosedir (_WDIR*); +void __cdecl __MINGW_NOTHROW _wrewinddir (_WDIR*); +long __cdecl __MINGW_NOTHROW _wtelldir (_WDIR*); +void __cdecl __MINGW_NOTHROW _wseekdir (_WDIR*, long); + + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _DIRENT_H_ */ diff --git a/compat/vcbuild/include/sys/utime.h b/compat/vcbuild/include/sys/utime.h new file mode 100644 index 0000000000..582589c70a --- /dev/null +++ b/compat/vcbuild/include/sys/utime.h @@ -0,0 +1,34 @@ +#ifndef _UTIME_H_ +#define _UTIME_H_ +/* + * UTIME.H + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * + * The mingw-runtime package and its code is distributed in the hope that it + * will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR + * IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to + * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You are free to use this package and its code without limitation. + */ + +/* + * Structure used by _utime function. + */ +struct _utimbuf +{ + time_t actime; /* Access time */ + time_t modtime; /* Modification time */ +}; + +#ifndef _NO_OLDNAMES +/* NOTE: Must be the same as _utimbuf above. */ +struct utimbuf +{ + time_t actime; + time_t modtime; +}; +#endif /* Not _NO_OLDNAMES */ + +#endif diff --git a/compat/vcbuild/include/unistd.h b/compat/vcbuild/include/unistd.h new file mode 100644 index 0000000000..2a4f276869 --- /dev/null +++ b/compat/vcbuild/include/unistd.h @@ -0,0 +1,92 @@ +#ifndef _UNISTD_ +#define _UNISTD_ + +/* Win32 define for porting git*/ + +#ifndef _MODE_T_ +#define _MODE_T_ +typedef unsigned short _mode_t; + +#ifndef _NO_OLDNAMES +typedef _mode_t mode_t; +#endif +#endif /* Not _MODE_T_ */ + +#ifndef _SSIZE_T_ +#define _SSIZE_T_ +typedef long _ssize_t; + +#ifndef _OFF_T_ +#define _OFF_T_ +typedef long _off_t; + +#ifndef _NO_OLDNAMES +typedef _off_t off_t; +#endif +#endif /* Not _OFF_T_ */ + + +#ifndef _NO_OLDNAMES +typedef _ssize_t ssize_t; +#endif +#endif /* Not _SSIZE_T_ */ + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned uint32_t; +typedef long long int64_t; +typedef unsigned long long uint64_t; + +typedef long long intmax_t; +typedef unsigned long long uintmax_t; + +typedef int64_t off64_t; + +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +/* Some defines for _access nAccessMode (MS doesn't define them, but + * it doesn't seem to hurt to add them). */ +#define F_OK 0 /* Check for file existence */ +/* Well maybe it does hurt. On newer versions of MSVCRT, an access mode + of 1 causes invalid parameter error. */ +#define X_OK 0 /* MS access() doesn't check for execute permission. */ +#define W_OK 2 /* Check for write permission */ +#define R_OK 4 /* Check for read permission */ + +#define _S_IFIFO 0x1000 /* FIFO */ +#define _S_IFCHR 0x2000 /* Character */ +#define _S_IFBLK 0x3000 /* Block: Is this ever set under w32? */ +#define _S_IFDIR 0x4000 /* Directory */ +#define _S_IFREG 0x8000 /* Regular */ + +#define _S_IFMT 0xF000 /* File type mask */ + +#define _S_IXUSR _S_IEXEC +#define _S_IWUSR _S_IWRITE +#define _S_IRUSR _S_IREAD +#define _S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) + +#define S_IFIFO _S_IFIFO +#define S_IFCHR _S_IFCHR +#define S_IFBLK _S_IFBLK +#define S_IFDIR _S_IFDIR +#define S_IFREG _S_IFREG +#define S_IFMT _S_IFMT +#define S_IEXEC _S_IEXEC +#define S_IWRITE _S_IWRITE +#define S_IREAD _S_IREAD +#define S_IRWXU _S_IRWXU +#define S_IXUSR _S_IXUSR +#define S_IWUSR _S_IWUSR +#define S_IRUSR _S_IRUSR + + +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) + +#endif diff --git a/compat/vcbuild/include/utime.h b/compat/vcbuild/include/utime.h new file mode 100644 index 0000000000..8285f38fde --- /dev/null +++ b/compat/vcbuild/include/utime.h @@ -0,0 +1 @@ +#include From d75f8e61315cc502c34aec6600db00a7c7192ffd Mon Sep 17 00:00:00 2001 From: Frank Li Date: Wed, 16 Sep 2009 10:20:25 +0200 Subject: [PATCH 24/31] Add platform files for porting to MSVC Add msvc.c and msvc.h to build git under MSVC. Signed-off-by: Frank Li Signed-off-by: Marius Storm-Olsen Acked-by: Johannes Sixt Signed-off-by: Junio C Hamano --- compat/msvc.c | 35 ++++++++++++++++++++++++++++++ compat/msvc.h | 55 +++++++++++++++++++++++++++++++++++++++++++++++ git-compat-util.h | 3 +++ 3 files changed, 93 insertions(+) create mode 100644 compat/msvc.c create mode 100644 compat/msvc.h diff --git a/compat/msvc.c b/compat/msvc.c new file mode 100644 index 0000000000..ac04a4ccbd --- /dev/null +++ b/compat/msvc.c @@ -0,0 +1,35 @@ +#include "../git-compat-util.h" +#include "win32.h" +#include +#include "../strbuf.h" + +DIR *opendir(const char *name) +{ + int len; + DIR *p; + p = (DIR*)malloc(sizeof(DIR)); + memset(p, 0, sizeof(DIR)); + strncpy(p->dd_name, name, PATH_MAX); + len = strlen(p->dd_name); + p->dd_name[len] = '/'; + p->dd_name[len+1] = '*'; + + if (p == NULL) + return NULL; + + p->dd_handle = _findfirst(p->dd_name, &p->dd_dta); + + if (p->dd_handle == -1) { + free(p); + return NULL; + } + return p; +} +int closedir(DIR *dir) +{ + _findclose(dir->dd_handle); + free(dir); + return 0; +} + +#include "mingw.c" diff --git a/compat/msvc.h b/compat/msvc.h new file mode 100644 index 0000000000..6daf313e8c --- /dev/null +++ b/compat/msvc.h @@ -0,0 +1,55 @@ +#ifndef __MSVC__HEAD +#define __MSVC__HEAD + +/* Define minimize windows version */ +#define WINVER 0x0500 +#define _WIN32_WINNT 0x0500 +#define _WIN32_WINDOWS 0x0410 +#define _WIN32_IE 0x0700 +#define NTDDI_VERSION NTDDI_WIN2KSP1 +#include +#include +#include +#include + +/* porting function */ +#define inline __inline +#define __inline__ __inline +#define __attribute__(x) +#define va_copy(dst, src) ((dst) = (src)) + +static __inline int strcasecmp (const char *s1, const char *s2) +{ + int size1 = strlen(s1); + int sisz2 = strlen(s2); + return _strnicmp(s1, s2, sisz2 > size1 ? sisz2 : size1); +} + +#undef ERROR +#undef stat +#undef _stati64 +#include "compat/mingw.h" +#undef stat +#define stat _stati64 +#define _stat64(x,y) mingw_lstat(x,y) + +/* + Even though _stati64 is normally just defined at _stat64 + on Windows, we specify it here as a proper struct to avoid + compiler warnings about macro redefinition due to magic in + mingw.h. Struct taken from ReactOS (GNU GPL license). +*/ +struct _stati64 { + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + __int64 st_size; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; +}; +#endif diff --git a/git-compat-util.h b/git-compat-util.h index e5e9f39c56..8ea444fdc0 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -113,6 +113,9 @@ /* pull in Windows compatibility stuff */ #include "compat/mingw.h" #endif /* __MINGW32__ */ +#ifdef _MSC_VER +#include "compat/msvc.h" +#endif #ifndef NO_LIBGEN_H #include From 435bdf8c7ffa493f8f6f2e8f329f8cc22db16ce6 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 16 Sep 2009 10:20:26 +0200 Subject: [PATCH 25/31] Make usage of windows.h lean and mean Centralize the include of windows.h in git-compat-util.h, turn on WIN32_LEAN_AND_MEAN to avoid including plenty of other header files which is not needed in Git. Also ensure we load winsock2.h first, so we don't load the older winsock definitions at a later stage, since they contain duplicate definitions. When moving windows.h into git-compat-util.h, we need to protect the definition of struct pollfd in mingw.h, since this file is used by both MinGW and MSVC, and the latter defines this struct in winsock2.h. We need to keep the windows.h include in compat/win32.h, since its shared by both MinGW and Cygwin, and we're not touching Cygwin in this commit. The include in git-compat-util.h is protected with an ifdef WIN32, which is not the case when compiling for Cygwin. Signed-off-by: Marius Storm-Olsen Acked-by: Johannes Sixt Signed-off-by: Junio C Hamano --- compat/mingw.c | 2 ++ compat/mingw.h | 2 ++ compat/msvc.h | 7 ------- compat/win32.h | 2 ++ compat/winansi.c | 1 - git-compat-util.h | 6 ++++++ thread-utils.c | 5 +---- 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index 34ee427baf..6b5b5b2c70 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -3,6 +3,8 @@ #include #include "../strbuf.h" +#include + static int err_win_to_posix(DWORD winerr) { int error = ENOSYS; diff --git a/compat/mingw.h b/compat/mingw.h index bcd23b0a45..5b5258bceb 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -41,6 +41,7 @@ struct passwd { extern char *getpass(const char *prompt); +#ifndef POLLIN struct pollfd { int fd; /* file descriptor */ short events; /* requested events */ @@ -48,6 +49,7 @@ struct pollfd { }; #define POLLIN 1 #define POLLHUP 2 +#endif typedef void (__cdecl *sig_handler_t)(int); struct sigaction { diff --git a/compat/msvc.h b/compat/msvc.h index 6daf313e8c..53a6d30c02 100644 --- a/compat/msvc.h +++ b/compat/msvc.h @@ -1,13 +1,6 @@ #ifndef __MSVC__HEAD #define __MSVC__HEAD -/* Define minimize windows version */ -#define WINVER 0x0500 -#define _WIN32_WINNT 0x0500 -#define _WIN32_WINDOWS 0x0410 -#define _WIN32_IE 0x0700 -#define NTDDI_VERSION NTDDI_WIN2KSP1 -#include #include #include #include diff --git a/compat/win32.h b/compat/win32.h index e8c178d8cd..8ce91048de 100644 --- a/compat/win32.h +++ b/compat/win32.h @@ -2,7 +2,9 @@ #define WIN32_H /* common Win32 functions for MinGW and Cygwin */ +#ifndef WIN32 /* Not defined by Cygwin */ #include +#endif static inline int file_attr_to_st_mode (DWORD attr) { diff --git a/compat/winansi.c b/compat/winansi.c index 9217c24b43..dedce2104e 100644 --- a/compat/winansi.c +++ b/compat/winansi.c @@ -2,7 +2,6 @@ * Copyright 2008 Peter Harris */ -#include #include "../git-compat-util.h" /* diff --git a/git-compat-util.h b/git-compat-util.h index 8ea444fdc0..8d6e29cdea 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -65,6 +65,12 @@ #define _NETBSD_SOURCE 1 #define _SGI_SOURCE 1 +#ifdef WIN32 /* Both MinGW and MSVC */ +#define WIN32_LEAN_AND_MEAN /* stops windows.h including winsock.h */ +#include +#include +#endif + #include #include #include diff --git a/thread-utils.c b/thread-utils.c index 55e7e2904e..4f9c829c2d 100644 --- a/thread-utils.c +++ b/thread-utils.c @@ -1,9 +1,6 @@ #include "cache.h" -#ifdef _WIN32 -# define WIN32_LEAN_AND_MEAN -# include -#elif defined(hpux) || defined(__hpux) || defined(_hpux) +#if defined(hpux) || defined(__hpux) || defined(_hpux) # include #endif From 386ac45102df71e186d4de62b63a41ae35e71089 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 16 Sep 2009 10:20:27 +0200 Subject: [PATCH 26/31] Define strncasecmp and ftruncate for MSVC Signed-off-by: Marius Storm-Olsen Acked-by: Johannes Sixt Signed-off-by: Junio C Hamano --- compat/msvc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compat/msvc.h b/compat/msvc.h index 53a6d30c02..9c753a560f 100644 --- a/compat/msvc.h +++ b/compat/msvc.h @@ -10,6 +10,8 @@ #define __inline__ __inline #define __attribute__(x) #define va_copy(dst, src) ((dst) = (src)) +#define strncasecmp _strnicmp +#define ftruncate _chsize static __inline int strcasecmp (const char *s1, const char *s2) { From 164a5e3faab931a6c6459b56acae7f91dde6337d Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 16 Sep 2009 10:20:28 +0200 Subject: [PATCH 27/31] Add MSVC to Makefile Enable MSVC builds with GNU Make by simply calling make MSVC=1 (Debug build possible by adding DEBUG=1 as well) Two scripts, clink.pl and lib.pl, are used to convert certain GCC specific command line options into something MSVC understands. By building for MSVC with GNU Make, we can ensure that the MSVC port always follows the latest code, and does not lag behind due to unmaintained NMake Makefile or IDE projects. Signed-off-by: Marius Storm-Olsen Acked-by: Johannes Sixt Signed-off-by: Junio C Hamano --- Makefile | 55 ++++++++++++++++++++++++++++++++- compat/vcbuild/scripts/clink.pl | 48 ++++++++++++++++++++++++++++ compat/vcbuild/scripts/lib.pl | 26 ++++++++++++++++ 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 compat/vcbuild/scripts/clink.pl create mode 100644 compat/vcbuild/scripts/lib.pl diff --git a/Makefile b/Makefile index d4958b832a..dcc086ad49 100644 --- a/Makefile +++ b/Makefile @@ -876,6 +876,58 @@ ifneq (,$(findstring CYGWIN,$(uname_S))) COMPAT_OBJS += compat/cygwin.o UNRELIABLE_FSTAT = UnfortunatelyYes endif +ifdef MSVC + pathsep = ; + NO_PREAD = YesPlease + NO_OPENSSL = YesPlease + NO_LIBGEN_H = YesPlease + NO_SYMLINK_HEAD = YesPlease + NO_IPV6 = YesPlease + NO_SETENV = YesPlease + NO_UNSETENV = YesPlease + NO_STRCASESTR = YesPlease + NO_STRLCPY = YesPlease + NO_MEMMEM = YesPlease + # NEEDS_LIBICONV = YesPlease + NO_ICONV = YesPlease + NO_C99_FORMAT = YesPlease + NO_STRTOUMAX = YesPlease + NO_STRTOULL = YesPlease + NO_MKDTEMP = YesPlease + NO_MKSTEMPS = YesPlease + SNPRINTF_RETURNS_BOGUS = YesPlease + NO_SVN_TESTS = YesPlease + NO_PERL_MAKEMAKER = YesPlease + RUNTIME_PREFIX = YesPlease + NO_POSIX_ONLY_PROGRAMS = YesPlease + NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease + NO_NSEC = YesPlease + USE_WIN32_MMAP = YesPlease + # USE_NED_ALLOCATOR = YesPlease + UNRELIABLE_FSTAT = UnfortunatelyYes + OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo + NO_REGEX = YesPlease + NO_CURL = YesPlease + NO_PTHREADS = YesPlease + + CC = compat/vcbuild/scripts/clink.pl + AR = compat/vcbuild/scripts/lib.pl + CFLAGS = + BASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32-D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE + COMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o + COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -DSTRIP_EXTENSION=\".exe\" + BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib + EXTLIBS = advapi32.lib shell32.lib wininet.lib ws2_32.lib + lib = +ifndef DEBUG + BASIC_CFLAGS += -GL -Os -MT + BASIC_LDFLAGS += -LTCG + AR += -LTCG +else + BASIC_CFLAGS += -Zi -MTd +endif + X = .exe +else ifneq (,$(findstring MINGW,$(uname_S))) pathsep = ; NO_PREAD = YesPlease @@ -924,6 +976,7 @@ else NO_PTHREADS = YesPlease endif endif +endif -include config.mak.autogen -include config.mak @@ -1326,7 +1379,7 @@ strip: $(PROGRAMS) git$X git.o: git.c common-cmds.h GIT-CFLAGS $(QUIET_CC)$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \ '-DGIT_HTML_PATH="$(htmldir_SQ)"' \ - $(ALL_CFLAGS) -c $(filter %.c,$^) + $(ALL_CFLAGS) -o $@ -c $(filter %.c,$^) git$X: git.o $(BUILTIN_OBJS) $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \ diff --git a/compat/vcbuild/scripts/clink.pl b/compat/vcbuild/scripts/clink.pl new file mode 100644 index 0000000000..0ffd59f9fb --- /dev/null +++ b/compat/vcbuild/scripts/clink.pl @@ -0,0 +1,48 @@ +#!/usr/bin/perl -w +###################################################################### +# Compiles or links files +# +# This is a wrapper to facilitate the compilation of Git with MSVC +# using GNU Make as the build system. So, instead of manipulating the +# Makefile into something nasty, just to support non-space arguments +# etc, we use this wrapper to fix the command line options +# +# Copyright (C) 2009 Marius Storm-Olsen +###################################################################### +use strict; +my @args = (); +my @cflags = (); +my $is_linking = 0; +while (@ARGV) { + my $arg = shift @ARGV; + if ("$arg" =~ /^-[DIMGO]/) { + push(@cflags, $arg); + } elsif ("$arg" eq "-o") { + my $file_out = shift @ARGV; + if ("$file_out" =~ /exe$/) { + $is_linking = 1; + push(@args, "-OUT:$file_out"); + } else { + push(@args, "-Fo$file_out"); + } + } elsif ("$arg" eq "-lz") { + push(@args, "zlib.lib"); + } elsif ("$arg" eq "-liconv") { + push(@args, "iconv.lib"); + } elsif ("$arg" =~ /^-L/ && "$arg" ne "-LTCG") { + $arg =~ s/^-L/-LIBPATH:/; + push(@args, $arg); + } elsif ("$arg" =~ /^-R/) { + # eat + } else { + push(@args, $arg); + } +} +if ($is_linking) { + unshift(@args, "link.exe"); +} else { + unshift(@args, "cl.exe"); + push(@args, @cflags); +} +#printf("**** @args\n"); +exit system(@args); diff --git a/compat/vcbuild/scripts/lib.pl b/compat/vcbuild/scripts/lib.pl new file mode 100644 index 0000000000..68f66446ea --- /dev/null +++ b/compat/vcbuild/scripts/lib.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl -w +###################################################################### +# Libifies files on Windows +# +# This is a wrapper to facilitate the compilation of Git with MSVC +# using GNU Make as the build system. So, instead of manipulating the +# Makefile into something nasty, just to support non-space arguments +# etc, we use this wrapper to fix the command line options +# +# Copyright (C) 2009 Marius Storm-Olsen +###################################################################### +use strict; +my @args = (); +while (@ARGV) { + my $arg = shift @ARGV; + if ("$arg" eq "rcs") { + # Consume the rcs option + } elsif ("$arg" =~ /\.a$/) { + push(@args, "-OUT:$arg"); + } else { + push(@args, $arg); + } +} +unshift(@args, "lib.exe"); +# printf("**** @args\n"); +exit system(@args); From a2c6bf0e7661a4e6eafe7810cca1cd08187d311f Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 16 Sep 2009 10:20:29 +0200 Subject: [PATCH 28/31] Add README for MSVC build Based on original README patch from Frank Li, describe the steps to build git with VS2008 (aka MSVC). Signed-off-by: Marius Storm-Olsen Acked-by: Johannes Sixt Signed-off-by: Junio C Hamano --- compat/vcbuild/README | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 compat/vcbuild/README diff --git a/compat/vcbuild/README b/compat/vcbuild/README new file mode 100644 index 0000000000..354526af8b --- /dev/null +++ b/compat/vcbuild/README @@ -0,0 +1,39 @@ +The Steps of Build Git with VS2008 + +1. You need the build environment, which contains the Git dependencies + to be able to compile, link and run Git with MSVC. + + You can either use the binary repository: + + WWW: http://repo.or.cz/w/msvcgit.git + Git: git clone git://repo.or.cz/msvcgit.git + Zip: http://repo.or.cz/w/msvcgit.git?a=snapshot;h=master;sf=zip + + and call the setup_32bit_env.cmd batch script before compiling Git, + (see repo/package README for details), or the source repository: + + WWW: http://repo.or.cz/w/gitbuild.git + Git: git clone git://repo.or.cz/gitbuild.git + Zip: (None, as it's a project with submodules) + + and build the support libs as instructed in that repo/package. + +2. Ensure you have the msysgit environment in your path, so you have + GNU Make, bash and perl available. + + WWW: http://repo.or.cz/w/msysgit.git + Git: git clone git://repo.or.cz/msysgit.git + Zip: http://repo.or.cz/w/msysgit.git?a=snapshot;h=master;sf=zip + + This environment is also needed when you use the resulting + executables, since Git might need to run scripts which are part of + the git operations. + +3. Inside Git's directory run the command: + make common-cmds.h + to generate the common-cmds.h file needed to compile git. + +4. Then build Git with the GNU Make Makefile in the Git projects root + make MSVC=1 + +Done! From 259d87c354954e8ee3b241dce1393c27186e8ee7 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 16 Sep 2009 10:20:30 +0200 Subject: [PATCH 29/31] Add scripts to generate projects for other buildsystems (MSVC vcproj, QMake) These scripts generate projects for the MSVC IDE (.vcproj files) or QMake (.pro files), based on the output of a 'make -n MSVC=1 V=1' run. This enables us to simply do the necesarry changes in the Makefile, and you can update the other buildsystems by regenerating the files. Keeping the other buildsystems up-to-date with main development. The generator system is designed to easily drop in pm's for other buildsystems as well, if someone has an itch. However, the focus has been Windows development, so the 'engine' might need patches to support any platform. Also add some .gitignore entries for MSVC files. Signed-off-by: Marius Storm-Olsen Acked-by: Johannes Sixt Signed-off-by: Junio C Hamano --- .gitignore | 11 + compat/vcbuild/README | 13 +- contrib/buildsystems/Generators.pm | 42 ++ contrib/buildsystems/Generators/QMake.pm | 189 +++++++ contrib/buildsystems/Generators/Vcproj.pm | 639 ++++++++++++++++++++++ contrib/buildsystems/engine.pl | 353 ++++++++++++ contrib/buildsystems/generate | 29 + contrib/buildsystems/parse.pl | 228 ++++++++ 8 files changed, 1503 insertions(+), 1 deletion(-) create mode 100644 contrib/buildsystems/Generators.pm create mode 100644 contrib/buildsystems/Generators/QMake.pm create mode 100644 contrib/buildsystems/Generators/Vcproj.pm create mode 100644 contrib/buildsystems/engine.pl create mode 100644 contrib/buildsystems/generate create mode 100644 contrib/buildsystems/parse.pl diff --git a/.gitignore b/.gitignore index 47672b0c15..51a37b1af7 100644 --- a/.gitignore +++ b/.gitignore @@ -179,3 +179,14 @@ configure tags TAGS cscope* +*.obj +*.lib +*.sln +*.suo +*.ncb +*.vcproj +*.user +*.idb +*.pdb +Debug/ +Release/ diff --git a/compat/vcbuild/README b/compat/vcbuild/README index 354526af8b..df8a6574c9 100644 --- a/compat/vcbuild/README +++ b/compat/vcbuild/README @@ -33,7 +33,18 @@ The Steps of Build Git with VS2008 make common-cmds.h to generate the common-cmds.h file needed to compile git. -4. Then build Git with the GNU Make Makefile in the Git projects root +4. Then either build Git with the GNU Make Makefile in the Git projects + root make MSVC=1 + or generate Visual Studio solution/projects (.sln/.vcproj) with the + command + perl contrib/buildsystems/generate -g Vcproj + and open and build the solution with the IDE + devenv git.sln /useenv + or build with the IDE build engine directly from the command line + devenv git.sln /useenv /build "Release|Win32" + The /useenv option is required, so Visual Studio picks up the + environment variables for the support libraries required to build + Git, which you set up in step 1. Done! diff --git a/contrib/buildsystems/Generators.pm b/contrib/buildsystems/Generators.pm new file mode 100644 index 0000000000..408ef714b8 --- /dev/null +++ b/contrib/buildsystems/Generators.pm @@ -0,0 +1,42 @@ +package Generators; +require Exporter; + +use strict; +use File::Basename; +no strict 'refs'; +use vars qw($VERSION @AVAILABLE); + +our $VERSION = '1.00'; +our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE); +@ISA = qw(Exporter); + +BEGIN { + local(*D); + my $me = $INC{"Generators.pm"}; + die "Couldn't find myself in \@INC, which is required to load the generators!" if ("$me" eq ""); + $me = dirname($me); + if (opendir(D,"$me/Generators")) { + foreach my $gen (readdir(D)) { + next if ($gen =~ /^\.\.?$/); + require "${me}/Generators/$gen"; + $gen =~ s,\.pm,,; + push(@AVAILABLE, $gen); + } + closedir(D); + my $gens = join(', ', @AVAILABLE); + } + + push @EXPORT_OK, qw(available); +} + +sub available { + return @AVAILABLE; +} + +sub generate { + my ($gen, $git_dir, $out_dir, $rel_dir, %build_structure) = @_; + return eval("Generators::${gen}::generate(\$git_dir, \$out_dir, \$rel_dir, \%build_structure)") if grep(/^$gen$/, @AVAILABLE); + die "Generator \"${gen}\" is not available!\nAvailable generators are: @AVAILABLE\n"; +} + +1; diff --git a/contrib/buildsystems/Generators/QMake.pm b/contrib/buildsystems/Generators/QMake.pm new file mode 100644 index 0000000000..ff3b657e61 --- /dev/null +++ b/contrib/buildsystems/Generators/QMake.pm @@ -0,0 +1,189 @@ +package Generators::QMake; +require Exporter; + +use strict; +use vars qw($VERSION); + +our $VERSION = '1.00'; +our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE); +@ISA = qw(Exporter); + +BEGIN { + push @EXPORT_OK, qw(generate); +} + +sub generate { + my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_; + + my @libs = @{$build_structure{"LIBS"}}; + foreach (@libs) { + createLibProject($_, $git_dir, $out_dir, $rel_dir, %build_structure); + } + + my @apps = @{$build_structure{"APPS"}}; + foreach (@apps) { + createAppProject($_, $git_dir, $out_dir, $rel_dir, %build_structure); + } + + createGlueProject($git_dir, $out_dir, $rel_dir, %build_structure); + return 0; +} + +sub createLibProject { + my ($libname, $git_dir, $out_dir, $rel_dir, %build_structure) = @_; + print "Generate $libname lib project\n"; + $rel_dir = "../$rel_dir"; + + my $sources = join(" \\\n\t", sort(map("$rel_dir/$_", @{$build_structure{"LIBS_${libname}_SOURCES"}}))); + my $defines = join(" \\\n\t", sort(@{$build_structure{"LIBS_${libname}_DEFINES"}})); + my $includes= join(" \\\n\t", sort(map("$rel_dir/$_", @{$build_structure{"LIBS_${libname}_INCLUDES"}}))); + my $cflags = join(" ", sort(@{$build_structure{"LIBS_${libname}_CFLAGS"}})); + + my $cflags_debug = $cflags; + $cflags_debug =~ s/-MT/-MTd/; + $cflags_debug =~ s/-O.//; + + my $cflags_release = $cflags; + $cflags_release =~ s/-MTd/-MT/; + + my @tmp = @{$build_structure{"LIBS_${libname}_LFLAGS"}}; + my @tmp2 = (); + foreach (@tmp) { + if (/^-LTCG/) { + } elsif (/^-L/) { + $_ =~ s/^-L/-LIBPATH:$rel_dir\//; + } + push(@tmp2, $_); + } + my $lflags = join(" ", sort(@tmp)); + + my $target = $libname; + $target =~ s/\//_/g; + $defines =~ s/-D//g; + $defines =~ s/"/\\\\"/g; + $includes =~ s/-I//g; + mkdir "$target" || die "Could not create the directory $target for lib project!\n"; + open F, ">$target/$target.pro" || die "Could not open $target/$target.pro for writing!\n"; + print F << "EOM"; +TEMPLATE = lib +TARGET = $target +DESTDIR = $rel_dir + +CONFIG -= qt +CONFIG += static + +QMAKE_CFLAGS = +QMAKE_CFLAGS_RELEASE = $cflags_release +QMAKE_CFLAGS_DEBUG = $cflags_debug +QMAKE_LIBFLAGS = $lflags + +DEFINES += \\ + $defines + +INCLUDEPATH += \\ + $includes + +SOURCES += \\ + $sources +EOM + close F; +} + +sub createAppProject { + my ($appname, $git_dir, $out_dir, $rel_dir, %build_structure) = @_; + print "Generate $appname app project\n"; + $rel_dir = "../$rel_dir"; + + my $sources = join(" \\\n\t", sort(map("$rel_dir/$_", @{$build_structure{"APPS_${appname}_SOURCES"}}))); + my $defines = join(" \\\n\t", sort(@{$build_structure{"APPS_${appname}_DEFINES"}})); + my $includes= join(" \\\n\t", sort(map("$rel_dir/$_", @{$build_structure{"APPS_${appname}_INCLUDES"}}))); + my $cflags = join(" ", sort(@{$build_structure{"APPS_${appname}_CFLAGS"}})); + + my $cflags_debug = $cflags; + $cflags_debug =~ s/-MT/-MTd/; + $cflags_debug =~ s/-O.//; + + my $cflags_release = $cflags; + $cflags_release =~ s/-MTd/-MT/; + + my $libs; + foreach (sort(@{$build_structure{"APPS_${appname}_LIBS"}})) { + $_ =~ s/\//_/g; + $libs .= " $_"; + } + my @tmp = @{$build_structure{"APPS_${appname}_LFLAGS"}}; + my @tmp2 = (); + foreach (@tmp) { + # next if ($_ eq "-NODEFAULTLIB:MSVCRT.lib"); + if (/^-LTCG/) { + } elsif (/^-L/) { + $_ =~ s/^-L/-LIBPATH:$rel_dir\//; + } + push(@tmp2, $_); + } + my $lflags = join(" ", sort(@tmp)); + + my $target = $appname; + $target =~ s/\.exe//; + $target =~ s/\//_/g; + $defines =~ s/-D//g; + $defines =~ s/"/\\\\"/g; + $includes =~ s/-I//g; + mkdir "$target" || die "Could not create the directory $target for app project!\n"; + open F, ">$target/$target.pro" || die "Could not open $target/$target.pro for writing!\n"; + print F << "EOM"; +TEMPLATE = app +TARGET = $target +DESTDIR = $rel_dir + +CONFIG -= qt embed_manifest_exe +CONFIG += console + +QMAKE_CFLAGS = +QMAKE_CFLAGS_RELEASE = $cflags_release +QMAKE_CFLAGS_DEBUG = $cflags_debug +QMAKE_LFLAGS = $lflags +LIBS = $libs + +DEFINES += \\ + $defines + +INCLUDEPATH += \\ + $includes + +win32:QMAKE_LFLAGS += -LIBPATH:$rel_dir +else: QMAKE_LFLAGS += -L$rel_dir + +SOURCES += \\ + $sources +EOM + close F; +} + +sub createGlueProject { + my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_; + my $libs = join(" \\ \n", map("\t$_|$_.pro", @{$build_structure{"LIBS"}})); + my $apps = join(" \\ \n", map("\t$_|$_.pro", @{$build_structure{"APPS"}})); + $libs =~ s/\.a//g; + $libs =~ s/\//_/g; + $libs =~ s/\|/\//g; + $apps =~ s/\.exe//g; + $apps =~ s/\//_/g; + $apps =~ s/\|/\//g; + + my $filename = $out_dir; + $filename =~ s/.*\/([^\/]+)$/$1/; + $filename =~ s/\/$//; + print "Generate glue project $filename.pro\n"; + open F, ">$filename.pro" || die "Could not open $filename.pro for writing!\n"; + print F << "EOM"; +TEMPLATE = subdirs +CONFIG += ordered +SUBDIRS += \\ +$libs \\ +$apps +EOM + close F; +} + +1; diff --git a/contrib/buildsystems/Generators/Vcproj.pm b/contrib/buildsystems/Generators/Vcproj.pm new file mode 100644 index 0000000000..00ec0c1369 --- /dev/null +++ b/contrib/buildsystems/Generators/Vcproj.pm @@ -0,0 +1,639 @@ +package Generators::Vcproj; +require Exporter; + +use strict; +use vars qw($VERSION); + +our $VERSION = '1.00'; +our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE); +@ISA = qw(Exporter); + +BEGIN { + push @EXPORT_OK, qw(generate); +} + +my $guid_index = 0; +my @GUIDS = ( + "{E07B9989-2BF7-4F21-8918-BE22BA467AC3}", + "{278FFB51-0296-4A44-A81A-22B87B7C3592}", + "{7346A2C4-F0FD-444F-9EBE-1AF23B2B5650}", + "{67F421AC-EB34-4D49-820B-3196807B423F}", + "{385DCFE1-CC8C-4211-A451-80FCFC31CA51}", + "{97CC46C5-D2CC-4D26-B634-E75792B79916}", + "{C7CE21FE-6EF8-4012-A5C7-A22BCEDFBA11}", + "{51575134-3FDF-42D1-BABD-3FB12669C6C9}", + "{0AE195E4-9823-4B87-8E6F-20C5614AF2FF}", + "{4B918255-67CA-43BB-A46C-26704B666E6B}", + "{18CCFEEF-C8EE-4CC1-A265-26F95C9F4649}", + "{5D5D90FA-01B7-4973-AFE5-CA88C53AC197}", + "{1F054320-036D-49E1-B384-FB5DF0BC8AC0}", + "{7CED65EE-F2D9-4171-825B-C7D561FE5786}", + "{8D341679-0F07-4664-9A56-3BA0DE88B9BC}", + "{C189FEDC-2957-4BD7-9FA4-7622241EA145}", + "{66844203-1B9F-4C53-9274-164FFF95B847}", + "{E4FEA145-DECC-440D-AEEA-598CF381FD43}", + "{73300A8E-C8AC-41B0-B555-4F596B681BA7}", + "{873FDEB1-D01D-40BF-A1BF-8BBC58EC0F51}", + "{7922C8BE-76C5-4AC6-8BF7-885C0F93B782}", + "{E245D370-308B-4A49-BFC1-1E527827975F}", + "{F6FA957B-66FC-4ED7-B260-E59BBE4FE813}", + "{E6055070-0198-431A-BC49-8DB6CEE770AE}", + "{54159234-C3EB-43DA-906B-CE5DA5C74654}", + "{594CFC35-0B60-46F6-B8EF-9983ACC1187D}", + "{D93FCAB7-1F01-48D2-B832-F761B83231A5}", + "{DBA5E6AC-E7BE-42D3-8703-4E787141526E}", + "{6171953F-DD26-44C7-A3BE-CC45F86FC11F}", + "{9E19DDBE-F5E4-4A26-A2FE-0616E04879B8}", + "{AE81A615-99E3-4885-9CE0-D9CAA193E867}", + "{FBF4067E-1855-4F6C-8BCD-4D62E801A04D}", + "{17007948-6593-4AEB-8106-F7884B4F2C19}", + "{199D4C8D-8639-4DA6-82EF-08668C35DEE0}", + "{E085E50E-C140-4CF3-BE4B-094B14F0DDD6}", + "{00785268-A9CC-4E40-AC29-BAC0019159CE}", + "{4C06F56A-DCDB-46A6-B67C-02339935CF12}", + "{3A62D3FD-519E-4EC9-8171-D2C1BFEA022F}", + "{3A62D3FD-519E-4EC9-8171-D2C1BFEA022F}", + "{9392EB58-D7BA-410B-B1F0-B2FAA6BC89A7}", + "{2ACAB2D5-E0CE-4027-BCA0-D78B2D7A6C66}", + "{86E216C3-43CE-481A-BCB2-BE5E62850635}", + "{FB631291-7923-4B91-9A57-7B18FDBB7A42}", + "{0A176EC9-E934-45B8-B87F-16C7F4C80039}", + "{DF55CA80-46E8-4C53-B65B-4990A23DD444}", + "{3A0F9895-55D2-4710-BE5E-AD7498B5BF44}", + "{294BDC5A-F448-48B6-8110-DD0A81820F8C}", + "{4B9F66E9-FAC9-47AB-B1EF-C16756FBFD06}", + "{72EA49C6-2806-48BD-B81B-D4905102E19C}", + "{5728EB7E-8929-486C-8CD5-3238D060E768}" +); + +sub generate { + my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_; + my @libs = @{$build_structure{"LIBS"}}; + foreach (@libs) { + createLibProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure); + } + + my @apps = @{$build_structure{"APPS"}}; + foreach (@apps) { + createAppProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure); + } + + createGlueProject($git_dir, $out_dir, $rel_dir, %build_structure); + return 0; +} + +sub createLibProject { + my ($libname, $git_dir, $out_dir, $rel_dir, $build_structure) = @_; + print "Generate $libname vcproj lib project\n"; + $rel_dir = "..\\$rel_dir"; + $rel_dir =~ s/\//\\/g; + + my $target = $libname; + $target =~ s/\//_/g; + $target =~ s/\.a//; + + my $uuid = $GUIDS[$guid_index]; + $$build_structure{"LIBS_${target}_GUID"} = $uuid; + $guid_index += 1; + + my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"LIBS_${libname}_SOURCES"}})); + my @sources; + foreach (@srcs) { + $_ =~ s/\//\\/g; + push(@sources, $_); + } + my $defines = join(",", sort(@{$$build_structure{"LIBS_${libname}_DEFINES"}})); + my $includes= join(";", sort(map(""$rel_dir\\$_"", @{$$build_structure{"LIBS_${libname}_INCLUDES"}}))); + my $cflags = join(" ", sort(@{$$build_structure{"LIBS_${libname}_CFLAGS"}})); + $cflags =~ s/\"/"/g; + + my $cflags_debug = $cflags; + $cflags_debug =~ s/-MT/-MTd/; + $cflags_debug =~ s/-O.//; + + my $cflags_release = $cflags; + $cflags_release =~ s/-MTd/-MT/; + + my @tmp = @{$$build_structure{"LIBS_${libname}_LFLAGS"}}; + my @tmp2 = (); + foreach (@tmp) { + if (/^-LTCG/) { + } elsif (/^-L/) { + $_ =~ s/^-L/-LIBPATH:$rel_dir\//; + } + push(@tmp2, $_); + } + my $lflags = join(" ", sort(@tmp)); + + $defines =~ s/-D//g; + $defines =~ s/\"/\\"/g; + $defines =~ s/\'//g; + $includes =~ s/-I//g; + mkdir "$target" || die "Could not create the directory $target for lib project!\n"; + open F, ">$target/$target.vcproj" || die "Could not open $target/$target.pro for writing!\n"; + print F << "EOM"; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +EOM + foreach(@sources) { + print F << "EOM"; + +EOM + } + print F << "EOM"; + + + + + +EOM + close F; +} + +sub createAppProject { + my ($appname, $git_dir, $out_dir, $rel_dir, $build_structure) = @_; + print "Generate $appname vcproj app project\n"; + $rel_dir = "..\\$rel_dir"; + $rel_dir =~ s/\//\\/g; + + my $target = $appname; + $target =~ s/\//_/g; + $target =~ s/\.exe//; + + my $uuid = $GUIDS[$guid_index]; + $$build_structure{"APPS_${target}_GUID"} = $uuid; + $guid_index += 1; + + my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"APPS_${appname}_SOURCES"}})); + my @sources; + foreach (@srcs) { + $_ =~ s/\//\\/g; + push(@sources, $_); + } + my $defines = join(",", sort(@{$$build_structure{"APPS_${appname}_DEFINES"}})); + my $includes= join(";", sort(map(""$rel_dir\\$_"", @{$$build_structure{"APPS_${appname}_INCLUDES"}}))); + my $cflags = join(" ", sort(@{$$build_structure{"APPS_${appname}_CFLAGS"}})); + $cflags =~ s/\"/"/g; + + my $cflags_debug = $cflags; + $cflags_debug =~ s/-MT/-MTd/; + $cflags_debug =~ s/-O.//; + + my $cflags_release = $cflags; + $cflags_release =~ s/-MTd/-MT/; + + my $libs; + foreach (sort(@{$$build_structure{"APPS_${appname}_LIBS"}})) { + $_ =~ s/\//_/g; + $libs .= " $_"; + } + my @tmp = @{$$build_structure{"APPS_${appname}_LFLAGS"}}; + my @tmp2 = (); + foreach (@tmp) { + if (/^-LTCG/) { + } elsif (/^-L/) { + $_ =~ s/^-L/-LIBPATH:$rel_dir\//; + } + push(@tmp2, $_); + } + my $lflags = join(" ", sort(@tmp)) . " -LIBPATH:$rel_dir"; + + $defines =~ s/-D//g; + $defines =~ s/\"/\\"/g; + $defines =~ s/\'//g; + $defines =~ s/\\\\/\\/g; + $includes =~ s/-I//g; + mkdir "$target" || die "Could not create the directory $target for lib project!\n"; + open F, ">$target/$target.vcproj" || die "Could not open $target/$target.pro for writing!\n"; + print F << "EOM"; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +EOM + foreach(@sources) { + print F << "EOM"; + +EOM + } + print F << "EOM"; + + + + + +EOM + close F; +} + +sub createGlueProject { + my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_; + print "Generate solutions file\n"; + $rel_dir = "..\\$rel_dir"; + $rel_dir =~ s/\//\\/g; + my $SLN_HEAD = "Microsoft Visual Studio Solution File, Format Version 10.00\n"; + my $SLN_PRE = "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = "; + my $SLN_POST = "\nEndProject\n"; + + my @libs = @{$build_structure{"LIBS"}}; + my @tmp; + foreach (@libs) { + $_ =~ s/\//_/g; + $_ =~ s/\.a//; + push(@tmp, $_); + } + @libs = @tmp; + + my @apps = @{$build_structure{"APPS"}}; + @tmp = (); + foreach (@apps) { + $_ =~ s/\//_/g; + $_ =~ s/\.exe//; + push(@tmp, $_); + } + @apps = @tmp; + + open F, ">git.sln" || die "Could not open git.sln for writing!\n"; + print F "$SLN_HEAD"; + foreach (@libs) { + my $libname = $_; + my $uuid = $build_structure{"LIBS_${libname}_GUID"}; + print F "$SLN_PRE"; + print F "\"${libname}\", \"${libname}\\${libname}.vcproj\", \"${uuid}\""; + print F "$SLN_POST"; + } + foreach (@apps) { + my $appname = $_; + my $uuid = $build_structure{"APPS_${appname}_GUID"}; + print F "$SLN_PRE"; + print F "\"${appname}\", \"${appname}\\${appname}.vcproj\", \"${uuid}\""; + print F "$SLN_POST"; + } + + print F << "EOM"; +Global + GlobalSection(SolutionConfiguration) = preSolution + ConfigName.0 = Debug|Win32 + ConfigName.1 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution +EOM + foreach (@{$build_structure{"APPS"}}) { + my $appname = $_; + my $appname_clean = $_; + $appname_clean =~ s/\//_/g; + $appname_clean =~ s/\.exe//; + + my $uuid = $build_structure{"APPS_${appname_clean}_GUID"}; + my $dep_index = 0; + foreach(@{$build_structure{"APPS_${appname}_LIBS"}}) { + my $libname = $_; + $libname =~ s/\//_/g; + $libname =~ s/\.(a|lib)//; + my $libuuid = $build_structure{"LIBS_${libname}_GUID"}; + if (defined $libuuid) { + print F "\t\t${uuid}.${dep_index} = ${libuuid}\n"; + $dep_index += 1; + } + } + } + + print F << "EOM"; + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution +EOM + foreach (@libs) { + my $libname = $_; + my $uuid = $build_structure{"LIBS_${libname}_GUID"}; + print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n"; + print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n"; + print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n"; + print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n"; + } + foreach (@apps) { + my $appname = $_; + my $uuid = $build_structure{"APPS_${appname}_GUID"}; + print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n"; + print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n"; + print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n"; + print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n"; + } + + print F << "EOM"; + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal +EOM + close F; +} + +1; diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl new file mode 100644 index 0000000000..20bd061b3e --- /dev/null +++ b/contrib/buildsystems/engine.pl @@ -0,0 +1,353 @@ +#!/usr/bin/perl -w +###################################################################### +# Do not call this script directly! +# +# The generate script ensures that @INC is correct before the engine +# is executed. +# +# Copyright (C) 2009 Marius Storm-Olsen +###################################################################### +use strict; +use File::Basename; +use File::Spec; +use Cwd; +use Generators; + +my (%build_structure, %compile_options, @makedry); +my $out_dir = getcwd(); +my $git_dir = $out_dir; +$git_dir =~ s=\\=/=g; +$git_dir = dirname($git_dir) while (!-e "$git_dir/git.c" && "$git_dir" ne ""); +die "Couldn't find Git repo" if ("$git_dir" eq ""); + +my @gens = Generators::available(); +my $gen = "Vcproj"; + +sub showUsage +{ + my $genlist = join(', ', @gens); + print << "EOM"; +generate usage: + -g --gen Specify the buildsystem generator (default: $gen) + Available: $genlist + -o --out Specify output directory generation (default: .) + -i --in Specify input file, instead of running GNU Make + -h,-? --help This help +EOM + exit 0; +} + +# Parse command-line options +while (@ARGV) { + my $arg = shift @ARGV; + if ("$arg" eq "-h" || "$arg" eq "--help" || "$arg" eq "-?") { + showUsage(); + exit(0); + } elsif("$arg" eq "--out" || "$arg" eq "-o") { + $out_dir = shift @ARGV; + } elsif("$arg" eq "--gen" || "$arg" eq "-g") { + $gen = shift @ARGV; + } elsif("$arg" eq "--in" || "$arg" eq "-i") { + my $infile = shift @ARGV; + open(F, "<$infile") || die "Couldn't open file $infile"; + @makedry = ; + close(F); + } +} + +# NOT using File::Spec->rel2abs($path, $base) here, as +# it fails badly for me in the msysgit environment +$git_dir = File::Spec->rel2abs($git_dir); +$out_dir = File::Spec->rel2abs($out_dir); +my $rel_dir = makeOutRel2Git($git_dir, $out_dir); + +# Print some information so the user feels informed +print << "EOM"; +----- +Generator: $gen +Git dir: $git_dir +Out dir: $out_dir +----- +Running GNU Make to figure out build structure... +EOM + +# Pipe a make --dry-run into a variable, if not already loaded from file +@makedry = `cd $git_dir && make -n MSVC=1 V=1 2>/dev/null` if !@makedry; + +# Parse the make output into usable info +parseMakeOutput(); + +# Finally, ask the generator to start generating.. +Generators::generate($gen, $git_dir, $out_dir, $rel_dir, %build_structure); + +# main flow ends here +# ------------------------------------------------------------------------------------------------- + + +# 1) path: /foo/bar/baz 2) path: /foo/bar/baz 3) path: /foo/bar/baz +# base: /foo/bar/baz/temp base: /foo/bar base: /tmp +# rel: .. rel: baz rel: ../foo/bar/baz +sub makeOutRel2Git +{ + my ($path, $base) = @_; + my $rel; + if ("$path" eq "$base") { + return "."; + } elsif ($base =~ /^$path/) { + # case 1 + my $tmp = $base; + $tmp =~ s/^$path//; + foreach (split('/', $tmp)) { + $rel .= "../" if ("$_" ne ""); + } + } elsif ($path =~ /^$base/) { + # case 2 + $rel = $path; + $rel =~ s/^$base//; + $rel = "./$rel"; + } else { + my $tmp = $base; + foreach (split('/', $tmp)) { + $rel .= "../" if ("$_" ne ""); + } + $rel .= $path; + } + $rel =~ s/\/\//\//g; # simplify + $rel =~ s/\/$//; # don't end with / + return $rel; +} + +sub parseMakeOutput +{ + print "Parsing GNU Make output to figure out build structure...\n"; + my $line = 0; + while (my $text = shift @makedry) { + my $ate_next; + do { + $ate_next = 0; + $line++; + chomp $text; + chop $text if ($text =~ /\r$/); + if ($text =~ /\\$/) { + $text =~ s/\\$//; + $text .= shift @makedry; + $ate_next = 1; + } + } while($ate_next); + + if($text =~ / -c /) { + # compilation + handleCompileLine($text, $line); + + } elsif ($text =~ / -o /) { + # linking executable + handleLinkLine($text, $line); + + } elsif ($text =~ /\.o / && $text =~ /\.a /) { + # libifying + handleLibLine($text, $line); +# +# } elsif ($text =~ /^cp /) { +# # copy file around +# +# } elsif ($text =~ /^rm -f /) { +# # shell command +# +# } elsif ($text =~ /^make[ \[]/) { +# # make output +# +# } elsif ($text =~ /^echo /) { +# # echo to file +# +# } elsif ($text =~ /^if /) { +# # shell conditional +# +# } elsif ($text =~ /^tclsh /) { +# # translation stuff +# +# } elsif ($text =~ /^umask /) { +# # handling boilerplates +# +# } elsif ($text =~ /\$\(\:\)/) { +# # ignore +# +# } elsif ($text =~ /^FLAGS=/) { +# # flags check for dependencies +# +# } elsif ($text =~ /^'\/usr\/bin\/perl' -MError -e/) { +# # perl commands for copying files +# +# } elsif ($text =~ /generate-cmdlist\.sh/) { +# # command for generating list of commands +# +# } elsif ($text =~ /^test / && $text =~ /|| rm -f /) { +# # commands removing executables, if they exist +# +# } elsif ($text =~ /new locations or Tcl/) { +# # command for detecting Tcl/Tk changes +# +# } elsif ($text =~ /mkdir -p/) { +# # command creating path +# +# } elsif ($text =~ /: no custom templates yet/) { +# # whatever +# +# } else { +# print "Unhandled (line: $line): $text\n"; + } + } + +# use Data::Dumper; +# print "Parsed build structure:\n"; +# print Dumper(%build_structure); +} + +# variables for the compilation part of each step +my (@defines, @incpaths, @cflags, @sources); + +sub clearCompileStep +{ + @defines = (); + @incpaths = (); + @cflags = (); + @sources = (); +} + +sub removeDuplicates +{ + my (%dupHash, $entry); + %dupHash = map { $_, 1 } @defines; + @defines = keys %dupHash; + + %dupHash = map { $_, 1 } @incpaths; + @incpaths = keys %dupHash; + + %dupHash = map { $_, 1 } @cflags; + @cflags = keys %dupHash; +} + +sub handleCompileLine +{ + my ($line, $lineno) = @_; + my @parts = split(' ', $line); + my $sourcefile; + shift(@parts); # ignore cmd + while (my $part = shift @parts) { + if ("$part" eq "-o") { + # ignore object file + shift @parts; + } elsif ("$part" eq "-c") { + # ignore compile flag + } elsif ("$part" eq "-c") { + } elsif ($part =~ /^.?-I/) { + push(@incpaths, $part); + } elsif ($part =~ /^.?-D/) { + push(@defines, $part); + } elsif ($part =~ /^-/) { + push(@cflags, $part); + } elsif ($part =~ /\.(c|cc|cpp)$/) { + $sourcefile = $part; + } else { + die "Unhandled compiler option @ line $lineno: $part"; + } + } + @{$compile_options{"${sourcefile}_CFLAGS"}} = @cflags; + @{$compile_options{"${sourcefile}_DEFINES"}} = @defines; + @{$compile_options{"${sourcefile}_INCPATHS"}} = @incpaths; + clearCompileStep(); +} + +sub handleLibLine +{ + my ($line, $lineno) = @_; + my (@objfiles, @lflags, $libout, $part); + # kill cmd and rm 'prefix' + $line =~ s/^rm -f .* && .* rcs //; + my @parts = split(' ', $line); + while ($part = shift @parts) { + if ($part =~ /^-/) { + push(@lflags, $part); + } elsif ($part =~ /\.(o|obj)$/) { + push(@objfiles, $part); + } elsif ($part =~ /\.(a|lib)$/) { + $libout = $part; + $libout =~ s/\.a$//; + } else { + die "Unhandled lib option @ line $lineno: $part"; + } + } +# print "LibOut: '$libout'\nLFlags: @lflags\nOfiles: @objfiles\n"; +# exit(1); + foreach (@objfiles) { + my $sourcefile = $_; + $sourcefile =~ s/\.o/.c/; + push(@sources, $sourcefile); + push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}}); + push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}}); + push(@incpaths, @{$compile_options{"${sourcefile}_INCPATHS"}}); + } + removeDuplicates(); + + push(@{$build_structure{"LIBS"}}, $libout); + @{$build_structure{"LIBS_${libout}"}} = ("_DEFINES", "_INCLUDES", "_CFLAGS", "_SOURCES", + "_OBJECTS"); + @{$build_structure{"LIBS_${libout}_DEFINES"}} = @defines; + @{$build_structure{"LIBS_${libout}_INCLUDES"}} = @incpaths; + @{$build_structure{"LIBS_${libout}_CFLAGS"}} = @cflags; + @{$build_structure{"LIBS_${libout}_LFLAGS"}} = @lflags; + @{$build_structure{"LIBS_${libout}_SOURCES"}} = @sources; + @{$build_structure{"LIBS_${libout}_OBJECTS"}} = @objfiles; + clearCompileStep(); +} + +sub handleLinkLine +{ + my ($line, $lineno) = @_; + my (@objfiles, @lflags, @libs, $appout, $part); + my @parts = split(' ', $line); + shift(@parts); # ignore cmd + while ($part = shift @parts) { + if ($part =~ /^-IGNORE/) { + push(@lflags, $part); + } elsif ($part =~ /^-[GRIMDO]/) { + # eat compiler flags + } elsif ("$part" eq "-o") { + $appout = shift @parts; + } elsif ("$part" eq "-lz") { + push(@libs, "zlib.lib"); + } elsif ($part =~ /^-/) { + push(@lflags, $part); + } elsif ($part =~ /\.(a|lib)$/) { + $part =~ s/\.a$/.lib/; + push(@libs, $part); + } elsif ($part =~ /\.(o|obj)$/) { + push(@objfiles, $part); + } else { + die "Unhandled lib option @ line $lineno: $part"; + } + } +# print "AppOut: '$appout'\nLFlags: @lflags\nLibs : @libs\nOfiles: @objfiles\n"; +# exit(1); + foreach (@objfiles) { + my $sourcefile = $_; + $sourcefile =~ s/\.o/.c/; + push(@sources, $sourcefile); + push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}}); + push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}}); + push(@incpaths, @{$compile_options{"${sourcefile}_INCPATHS"}}); + } + removeDuplicates(); + + removeDuplicates(); + push(@{$build_structure{"APPS"}}, $appout); + @{$build_structure{"APPS_${appout}"}} = ("_DEFINES", "_INCLUDES", "_CFLAGS", "_LFLAGS", + "_SOURCES", "_OBJECTS", "_LIBS"); + @{$build_structure{"APPS_${appout}_DEFINES"}} = @defines; + @{$build_structure{"APPS_${appout}_INCLUDES"}} = @incpaths; + @{$build_structure{"APPS_${appout}_CFLAGS"}} = @cflags; + @{$build_structure{"APPS_${appout}_LFLAGS"}} = @lflags; + @{$build_structure{"APPS_${appout}_SOURCES"}} = @sources; + @{$build_structure{"APPS_${appout}_OBJECTS"}} = @objfiles; + @{$build_structure{"APPS_${appout}_LIBS"}} = @libs; + clearCompileStep(); +} diff --git a/contrib/buildsystems/generate b/contrib/buildsystems/generate new file mode 100644 index 0000000000..bc10f25ff2 --- /dev/null +++ b/contrib/buildsystems/generate @@ -0,0 +1,29 @@ +#!/usr/bin/perl -w +###################################################################### +# Generate buildsystem files +# +# This script generate buildsystem files based on the output of a +# GNU Make --dry-run, enabling Windows users to develop Git with their +# trusted IDE with native projects. +# +# Note: +# It is not meant as *the* way of building Git with MSVC, but merely a +# convenience. The correct way of building Git with MSVC is to use the +# GNU Make tool to build with the maintained Makefile in the root of +# the project. If you have the msysgit environment installed and +# available in your current console, together with the Visual Studio +# environment you wish to build for, all you have to do is run the +# command: +# make MSVC=1 +# +# Copyright (C) 2009 Marius Storm-Olsen +###################################################################### +use strict; +use File::Basename; +use Cwd; + +my $git_dir = getcwd(); +$git_dir =~ s=\\=/=g; +$git_dir = dirname($git_dir) while (!-e "$git_dir/git.c" && "$git_dir" ne ""); +die "Couldn't find Git repo" if ("$git_dir" eq ""); +exec join(" ", ("PERL5LIB=${git_dir}/contrib/buildsystems ${git_dir}/contrib/buildsystems/engine.pl", @ARGV)); diff --git a/contrib/buildsystems/parse.pl b/contrib/buildsystems/parse.pl new file mode 100644 index 0000000000..c9656ece99 --- /dev/null +++ b/contrib/buildsystems/parse.pl @@ -0,0 +1,228 @@ +#!/usr/bin/perl -w +###################################################################### +# Do not call this script directly! +# +# The generate script ensures that @INC is correct before the engine +# is executed. +# +# Copyright (C) 2009 Marius Storm-Olsen +###################################################################### +use strict; +use File::Basename; +use Cwd; + +my $file = $ARGV[0]; +die "No file provided!" if !defined $file; + +my ($cflags, $target, $type, $line); + +open(F, "<$file") || die "Couldn't open file $file"; +my @data = ; +close(F); + +while (my $text = shift @data) { + my $ate_next; + do { + $ate_next = 0; + $line++; + chomp $text; + chop $text if ($text =~ /\r$/); + if ($text =~ /\\$/) { + $text =~ s/\\$//; + $text .= shift @data; + $ate_next = 1; + } + } while($ate_next); + + if($text =~ / -c /) { + # compilation + handleCompileLine($text, $line); + + } elsif ($text =~ / -o /) { + # linking executable + handleLinkLine($text, $line); + + } elsif ($text =~ /\.o / && $text =~ /\.a /) { + # libifying + handleLibLine($text, $line); + +# } elsif ($text =~ /^cp /) { +# # copy file around +# +# } elsif ($text =~ /^rm -f /) { +# # shell command +# +# } elsif ($text =~ /^make[ \[]/) { +# # make output +# +# } elsif ($text =~ /^echo /) { +# # echo to file +# +# } elsif ($text =~ /^if /) { +# # shell conditional +# +# } elsif ($text =~ /^tclsh /) { +# # translation stuff +# +# } elsif ($text =~ /^umask /) { +# # handling boilerplates +# +# } elsif ($text =~ /\$\(\:\)/) { +# # ignore +# +# } elsif ($text =~ /^FLAGS=/) { +# # flags check for dependencies +# +# } elsif ($text =~ /^'\/usr\/bin\/perl' -MError -e/) { +# # perl commands for copying files +# +# } elsif ($text =~ /generate-cmdlist\.sh/) { +# # command for generating list of commands +# +# } elsif ($text =~ /^test / && $text =~ /|| rm -f /) { +# # commands removing executables, if they exist +# +# } elsif ($text =~ /new locations or Tcl/) { +# # command for detecting Tcl/Tk changes +# +# } elsif ($text =~ /mkdir -p/) { +# # command creating path +# +# } elsif ($text =~ /: no custom templates yet/) { +# # whatever + + } else { +# print "Unhandled (line: $line): $text\n"; + } +} +close(F); + +# use Data::Dumper; +# print "Parsed build structure:\n"; +# print Dumper(%build_structure); + +# ------------------------------------------------------------------- +# Functions under here +# ------------------------------------------------------------------- +my (%build_structure, @defines, @incpaths, @cflags, @sources); + +sub clearCompileStep +{ + @defines = (); + @incpaths = (); + @cflags = (); + @sources = (); +} + +sub removeDuplicates +{ + my (%dupHash, $entry); + %dupHash = map { $_, 1 } @defines; + @defines = keys %dupHash; + + %dupHash = map { $_, 1 } @incpaths; + @incpaths = keys %dupHash; + + %dupHash = map { $_, 1 } @cflags; + @cflags = keys %dupHash; + + %dupHash = map { $_, 1 } @sources; + @sources = keys %dupHash; +} + +sub handleCompileLine +{ + my ($line, $lineno) = @_; + my @parts = split(' ', $line); + shift(@parts); # ignore cmd + while (my $part = shift @parts) { + if ("$part" eq "-o") { + # ignore object file + shift @parts; + } elsif ("$part" eq "-c") { + # ignore compile flag + } elsif ("$part" eq "-c") { + } elsif ($part =~ /^.?-I/) { + push(@incpaths, $part); + } elsif ($part =~ /^.?-D/) { + push(@defines, $part); + } elsif ($part =~ /^-/) { + push(@cflags, $part); + } elsif ($part =~ /\.(c|cc|cpp)$/) { + push(@sources, $part); + } else { + die "Unhandled compiler option @ line $lineno: $part"; + } + } + #print "Sources: @sources\nCFlags: @cflags\nDefine: @defines\nIncpat: @incpaths\n"; + #exit(1); +} + +sub handleLibLine +{ + my ($line, $lineno) = @_; + my (@objfiles, @lflags, $libout, $part); + # kill cmd and rm 'prefix' + $line =~ s/^rm -f .* && .* rcs //; + my @parts = split(' ', $line); + while ($part = shift @parts) { + if ($part =~ /^-/) { + push(@lflags, $part); + } elsif ($part =~ /\.(o|obj)$/) { + push(@objfiles, $part); + } elsif ($part =~ /\.(a|lib)$/) { + $libout = $part; + } else { + die "Unhandled lib option @ line $lineno: $part"; + } + } + #print "LibOut: '$libout'\nLFlags: @lflags\nOfiles: @objfiles\n"; + #exit(1); + removeDuplicates(); + push(@{$build_structure{"LIBS"}}, $libout); + @{$build_structure{"LIBS_${libout}"}} = ("_DEFINES", "_INCLUDES", "_CFLAGS", "_SOURCES", + "_OBJECTS"); + @{$build_structure{"LIBS_${libout}_DEFINES"}} = @defines; + @{$build_structure{"LIBS_${libout}_INCLUDES"}} = @incpaths; + @{$build_structure{"LIBS_${libout}_CFLAGS"}} = @cflags; + @{$build_structure{"LIBS_${libout}_SOURCES"}} = @sources; + @{$build_structure{"LIBS_${libout}_OBJECTS"}} = @objfiles; + clearCompileStep(); +} + +sub handleLinkLine +{ + my ($line, $lineno) = @_; + my (@objfiles, @lflags, @libs, $appout, $part); + my @parts = split(' ', $line); + shift(@parts); # ignore cmd + while ($part = shift @parts) { + if ($part =~ /^-[GRIDO]/) { + # eat compiler flags + } elsif ("$part" eq "-o") { + $appout = shift @parts; + } elsif ($part =~ /^-/) { + push(@lflags, $part); + } elsif ($part =~ /\.(a|lib)$/) { + push(@libs, $part); + } elsif ($part =~ /\.(o|obj)$/) { + push(@objfiles, $part); + } else { + die "Unhandled lib option @ line $lineno: $part"; + } + } + #print "AppOut: '$appout'\nLFlags: @lflags\nLibs : @libs\nOfiles: @objfiles\n"; + #exit(1); + removeDuplicates(); + push(@{$build_structure{"APPS"}}, $appout); + @{$build_structure{"APPS_${appout}"}} = ("_DEFINES", "_INCLUDES", "_CFLAGS", "_LFLAGS", + "_SOURCES", "_OBJECTS", "_LIBS"); + @{$build_structure{"APPS_${appout}_DEFINES"}} = @defines; + @{$build_structure{"APPS_${appout}_INCLUDES"}} = @incpaths; + @{$build_structure{"APPS_${appout}_CFLAGS"}} = @cflags; + @{$build_structure{"APPS_${appout}_LFLAGS"}} = @lflags; + @{$build_structure{"APPS_${appout}_SOURCES"}} = @sources; + @{$build_structure{"APPS_${appout}_OBJECTS"}} = @objfiles; + @{$build_structure{"APPS_${appout}_LIBS"}} = @libs; + clearCompileStep(); +} From f5c3178151e3963cc8cf73fdc200831850b7a632 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 16 Sep 2009 10:20:31 +0200 Subject: [PATCH 30/31] Tag GIT_VERSION when Git is built with MSVC This may help us debug issues on Windows, as we now can build Git natively on Windows with both MinGW and MSVC. Signed-off-by: Marius Storm-Olsen Acked-by: Johannes Sixt Signed-off-by: Junio C Hamano --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index dcc086ad49..12defd4c97 100644 --- a/Makefile +++ b/Makefile @@ -877,6 +877,7 @@ ifneq (,$(findstring CYGWIN,$(uname_S))) UNRELIABLE_FSTAT = UnfortunatelyYes endif ifdef MSVC + GIT_VERSION := $(GIT_VERSION).MSVC pathsep = ; NO_PREAD = YesPlease NO_OPENSSL = YesPlease From bb8cccd01762d26c832b85d3b09798650e294c5f Mon Sep 17 00:00:00 2001 From: Matthieu Moy Date: Sun, 20 Sep 2009 19:33:20 +0200 Subject: [PATCH 31/31] push: Correctly initialize nonfastforward in transport_push. The variable is assigned unconditionally in print_push_status, but print_push_status is not reached by all codepaths. In particular, this fixes a bug where "git push ... nonexisting-branch" was complaining about non-fast forward. Signed-off-by: Matthieu Moy Signed-off-by: Junio C Hamano --- transport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/transport.c b/transport.c index f231b355f2..ce1d25e46e 100644 --- a/transport.c +++ b/transport.c @@ -1001,8 +1001,9 @@ int transport_set_option(struct transport *transport, int transport_push(struct transport *transport, int refspec_nr, const char **refspec, int flags, - int * nonfastforward) + int *nonfastforward) { + *nonfastforward = 0; verify_remote_names(refspec_nr, refspec); if (transport->push)