From: Junio C Hamano Date: Tue, 28 Dec 2010 19:26:55 +0000 (-0800) Subject: Merge branch 'nd/setup' X-Git-Tag: v1.7.4-rc0~4 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/f3bb8b4b8452f1b7add220e787ef56c737ceff6a?ds=inline;hp=-c Merge branch 'nd/setup' * nd/setup: (47 commits) setup_work_tree: adjust relative $GIT_WORK_TREE after moving cwd git.txt: correct where --work-tree path is relative to Revert "Documentation: always respect core.worktree if set" t0001: test git init when run via an alias Remove all logic from get_git_work_tree() setup: rework setup_explicit_git_dir() setup: clean up setup_discovered_git_dir() t1020-subdirectory: test alias expansion in a subdirectory setup: clean up setup_bare_git_dir() setup: limit get_git_work_tree()'s to explicit setup case only Use git_config_early() instead of git_config() during repo setup Add git_config_early() git-rev-parse.txt: clarify --git-dir t1510: setup case #31 t1510: setup case #30 t1510: setup case #29 t1510: setup case #28 t1510: setup case #27 t1510: setup case #26 t1510: setup case #25 ... --- f3bb8b4b8452f1b7add220e787ef56c737ceff6a diff --combined .gitignore index 87b833c9d8,1dcc082a88..3dd6ef7d25 --- a/.gitignore +++ b/.gitignore @@@ -112,8 -112,6 +112,8 @@@ /git-remote-https /git-remote-ftp /git-remote-ftps +/git-remote-fd +/git-remote-ext /git-remote-testgit /git-repack /git-replace @@@ -177,6 -175,7 +177,7 @@@ /test-sha1 /test-sigchain /test-string-pool + /test-subprocess /test-svn-fe /test-treap /common-cmds.h diff --combined Documentation/config.txt index 54597f1897,d85563d764..a8759cff80 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@@ -317,24 -317,17 +317,17 @@@ false), while all other repositories ar = true). core.worktree:: - Set the path to the root of the work tree. + Set the path to the working tree. The value will not be + used in combination with repositories found automatically in + a .git directory (i.e. $GIT_DIR is not set). This can be overridden by the GIT_WORK_TREE environment variable and the '--work-tree' command line option. It can be - an absolute path or a relative path to the .git directory, - either specified by --git-dir or GIT_DIR, or automatically - discovered. - If --git-dir or GIT_DIR are specified but none of + an absolute path or relative path to the directory specified by + --git-dir or GIT_DIR. + Note: If --git-dir or GIT_DIR are specified but none of --work-tree, GIT_WORK_TREE and core.worktree is specified, - the current working directory is regarded as the root of the - work tree. - + - Note that this variable is honored even when set in a configuration - file in a ".git" subdirectory of a directory, and its value differs - from the latter directory (e.g. "/path/to/.git/config" has - core.worktree set to "/different/path"), which is most likely a - misconfiguration. Running git commands in "/path/to" directory will - still use "/different/path" as the root of the work tree and can cause - great confusion to the users. + the current working directory is regarded as the top directory + of your working tree. core.logAllRefUpdates:: Enable the reflog. Updates to a ref is logged to the file @@@ -374,15 -367,6 +367,15 @@@ core.warnAmbiguousRefs: If true, git will warn you if the ref name you passed it is ambiguous and might match multiple refs in the .git/refs/ tree. True by default. +core.abbrevguard:: + Even though git makes sure that it uses enough hexdigits to show + an abbreviated object name unambiguously, as more objects are + added to the repository over time, a short name that used to be + unique will stop being unique. Git uses this many extra hexdigits + that are more than necessary to make the object name currently + unique, in the hope that its output will stay unique a bit longer. + Defaults to 0. + core.compression:: An integer -1..9, indicating a default compression level. -1 is the zlib default. 0 means no compression, @@@ -522,9 -506,6 +515,9 @@@ core.whitespace: part of the line terminator, i.e. with it, `trailing-space` does not trigger if the character before such a carriage-return is not a whitespace (not enabled by default). +* `tabwidth=` tells how many character positions a tab occupies; this + is relevant for `indent-with-non-tab` and when git fixes `tab-in-indent` + errors. The default tab width is 8. Allowed values are 1 to 63. core.fsyncobjectfiles:: This boolean will enable 'fsync()' when writing object files. @@@ -566,13 -547,9 +559,13 @@@ core.sparseCheckout: linkgit:git-read-tree[1] for more information. add.ignore-errors:: +add.ignoreErrors:: Tells 'git add' to continue adding files when some files cannot be added due to indexing errors. Equivalent to the '--ignore-errors' - option of linkgit:git-add[1]. + option of linkgit:git-add[1]. Older versions of git accept only + `add.ignore-errors`, which does not follow the usual naming + convention for configuration variables. Newer versions of git + honor `add.ignoreErrors` as well. alias.*:: Command aliases for the linkgit:git[1] command wrapper - e.g. @@@ -617,9 -594,8 +610,9 @@@ branch.autosetupmerge: this behavior can be chosen per-branch using the `--track` and `--no-track` options. The valid settings are: `false` -- no automatic setup is done; `true` -- automatic setup is done when the - starting point is a remote branch; `always` -- automatic setup is - done when the starting point is either a local branch or remote + starting point is a remote-tracking branch; `always` -- + automatic setup is done when the starting point is either a + local branch or remote-tracking branch. This option defaults to true. branch.autosetuprebase:: @@@ -630,7 -606,7 +623,7 @@@ When `local`, rebase is set to true for tracked branches of other local branches. When `remote`, rebase is set to true for tracked branches of - remote branches. + remote-tracking branches. When `always`, rebase will be set to true for all tracking branches. See "branch.autosetupmerge" for details on how to set up a @@@ -697,7 -673,7 +690,7 @@@ color.branch: color.branch.:: Use customized color for branch coloration. `` is one of `current` (the current branch), `local` (a local branch), - `remote` (a tracking branch in refs/remotes/), `plain` (other + `remote` (a remote-tracking branch in refs/remotes/), `plain` (other refs). + The value for these configuration variables is a list of colors (at most @@@ -725,7 -701,7 +718,7 @@@ color.diff.: color.decorate.:: Use customized color for 'git log --decorate' output. `` is one of `branch`, `remoteBranch`, `tag`, `stash` or `HEAD` for local - branches, remote tracking branches, tags, stash and HEAD, respectively. + branches, remote-tracking branches, tags, stash and HEAD, respectively. color.grep:: When set to `always`, always highlight matches. When `false` (or @@@ -790,8 -766,7 +783,8 @@@ color.status.: one of `header` (the header text of the status message), `added` or `updated` (files which are added but not committed), `changed` (files which are changed but not added in the index), - `untracked` (files which are not tracked by git), or + `untracked` (files which are not tracked by git), + `branch` (the current branch), or `nobranch` (the color the 'no branch' warning is shown in, defaulting to red). The values of these variables may be specified as in color.branch.. @@@ -897,11 -872,6 +890,11 @@@ diff.wordRegex: sequences that match the regular expression are "words", all other characters are *ignorable* whitespace. +fetch.recurseSubmodules:: + A boolean value which changes the behavior for fetch and pull, the + default is to not recursively fetch populated sumodules unless + configured otherwise. + fetch.unpackLimit:: If the number of objects fetched over the git native transfer is below this @@@ -996,7 -966,7 +989,7 @@@ gc.packrefs: Running `git pack-refs` in a repository renders it unclonable by Git versions prior to 1.5.1.2 over dumb transports such as HTTP. This variable determines whether - 'git gc' runs `git pack-refs`. This can be set to `nobare` + 'git gc' runs `git pack-refs`. This can be set to `notbare` to enable it within all non-bare repos or it can be set to a boolean value. The default is `true`. @@@ -1125,7 -1095,7 +1118,7 @@@ gui.newbranchtemplate: linkgit:git-gui[1]. gui.pruneduringfetch:: - "true" if linkgit:git-gui[1] should prune tracking branches when + "true" if linkgit:git-gui[1] should prune remote-tracking branches when performing a fetch. The default value is "false". gui.trustmtime:: @@@ -1554,13 -1524,11 +1547,13 @@@ pack.packSizeLimit: supported. pager.:: - Allows turning on or off pagination of the output of a - particular git subcommand when writing to a tty. If - `\--paginate` or `\--no-pager` is specified on the command line, - it takes precedence over this option. To disable pagination for - all commands, set `core.pager` or `GIT_PAGER` to `cat`. + If the value is boolean, turns on or off pagination of the + output of a particular git subcommand when writing to a tty. + Otherwise, turns on pagination for the subcommand using the + pager specified by the value of `pager.`. If `\--paginate` + or `\--no-pager` is specified on the command line, it takes + precedence over this option. To disable pagination for all + commands, set `core.pager` or `GIT_PAGER` to `cat`. pretty.:: Alias for a --pretty= format string, as specified in @@@ -1816,13 -1784,6 +1809,13 @@@ submodule..update: URL and other values found in the `.gitmodules` file. See linkgit:git-submodule[1] and linkgit:gitmodules[5] for details. +submodule..fetchRecurseSubmodules:: + This option can be used to enable/disable recursive fetching of this + submodule. It can be overriden by using the --[no-]recurse-submodules + command line option to "git fetch" and "git pull". + This setting will override that from in the linkgit:gitmodules[5] + file. + submodule..ignore:: Defines under what circumstances "git status" and the diff family show a submodule as modified. When set to "all", it will never be considered diff --combined Documentation/git.txt index 012837145e,7433601f35..72e98aaa0f --- a/Documentation/git.txt +++ b/Documentation/git.txt @@@ -44,39 -44,31 +44,39 @@@ unreleased) version of git, that is ava branch of the `git.git` repository. Documentation for older releases are available here: -* link:v1.7.3.2/git.html[documentation for release 1.7.3.2] +* link:v1.7.3.4/git.html[documentation for release 1.7.3.4] * release notes for + link:RelNotes/1.7.3.4.txt[1.7.3.4], + link:RelNotes/1.7.3.3.txt[1.7.3.3], link:RelNotes/1.7.3.2.txt[1.7.3.2], link:RelNotes/1.7.3.1.txt[1.7.3.1], link:RelNotes/1.7.3.txt[1.7.3]. -* link:v1.7.2.3/git.html[documentation for release 1.7.2.3] +* link:v1.7.2.5/git.html[documentation for release 1.7.2.5] * release notes for + link:RelNotes/1.7.2.5.txt[1.7.2.5], + link:RelNotes/1.7.2.4.txt[1.7.2.4], link:RelNotes/1.7.2.3.txt[1.7.2.3], link:RelNotes/1.7.2.2.txt[1.7.2.2], link:RelNotes/1.7.2.1.txt[1.7.2.1], link:RelNotes/1.7.2.txt[1.7.2]. -* link:v1.7.1.2/git.html[documentation for release 1.7.1.2] +* link:v1.7.1.4/git.html[documentation for release 1.7.1.4] * release notes for + link:RelNotes/1.7.1.4.txt[1.7.1.4], + link:RelNotes/1.7.1.3.txt[1.7.1.3], link:RelNotes/1.7.1.2.txt[1.7.1.2], link:RelNotes/1.7.1.1.txt[1.7.1.1], link:RelNotes/1.7.1.txt[1.7.1]. -* link:v1.7.0.7/git.html[documentation for release 1.7.0.7] +* link:v1.7.0.9/git.html[documentation for release 1.7.0.9] * release notes for + link:RelNotes/1.7.0.9.txt[1.7.0.9], + link:RelNotes/1.7.0.8.txt[1.7.0.8], link:RelNotes/1.7.0.7.txt[1.7.0.7], link:RelNotes/1.7.0.6.txt[1.7.0.6], link:RelNotes/1.7.0.5.txt[1.7.0.5], @@@ -86,18 -78,16 +86,18 @@@ link:RelNotes/1.7.0.1.txt[1.7.0.1], link:RelNotes/1.7.0.txt[1.7.0]. -* link:v1.6.6.2/git.html[documentation for release 1.6.6.2] +* link:v1.6.6.3/git.html[documentation for release 1.6.6.3] * release notes for + link:RelNotes/1.6.6.3.txt[1.6.6.3], link:RelNotes/1.6.6.2.txt[1.6.6.2], link:RelNotes/1.6.6.1.txt[1.6.6.1], link:RelNotes/1.6.6.txt[1.6.6]. -* link:v1.6.5.8/git.html[documentation for release 1.6.5.8] +* link:v1.6.5.9/git.html[documentation for release 1.6.5.9] * release notes for + link:RelNotes/1.6.5.9.txt[1.6.5.9], link:RelNotes/1.6.5.8.txt[1.6.5.8], link:RelNotes/1.6.5.7.txt[1.6.5.7], link:RelNotes/1.6.5.6.txt[1.6.5.6], @@@ -108,10 -98,9 +108,10 @@@ link:RelNotes/1.6.5.1.txt[1.6.5.1], link:RelNotes/1.6.5.txt[1.6.5]. -* link:v1.6.4.4/git.html[documentation for release 1.6.4.4] +* link:v1.6.4.5/git.html[documentation for release 1.6.4.5] * release notes for + link:RelNotes/1.6.4.5.txt[1.6.4.5], 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], @@@ -296,7 -285,7 +296,7 @@@ help ...` This can also be controlled by setting the GIT_WORK_TREE environment variable and the core.worktree configuration variable. It can be an absolute path or relative path to - the directory specified by --git-dir or GIT_DIR. + current working directory. Note: If --git-dir or GIT_DIR are specified but none of --work-tree, GIT_WORK_TREE and core.worktree is specified, the current working directory is regarded as the top directory diff --combined Makefile index ff35154375,f96d990d5a..775ee838c3 --- a/Makefile +++ b/Makefile @@@ -70,11 -70,6 +70,11 @@@ all: # # Define NO_STRTOK_R if you don't have strtok_r in the C library. # +# Define NO_FNMATCH if you don't have fnmatch in the C library. +# +# Define NO_FNMATCH_CASEFOLD if your fnmatch function doesn't have the +# FNM_CASEFOLD GNU extension. +# # Define NO_LIBGEN_H if you don't have libgen.h. # # Define NEEDS_LIBGEN if your libgen needs -lgen when linking @@@ -167,13 -162,13 +167,13 @@@ # Define NO_ST_BLOCKS_IN_STRUCT_STAT if your platform does not have st_blocks # field that counts the on-disk footprint in 512-byte blocks. # -# Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8 +# Define ASCIIDOC7 if you want to format documentation with AsciiDoc 7 # # Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72 # (not v1.73 or v1.71). # -# Define ASCIIDOC_NO_ROFF if your DocBook XSL escapes raw roff directives -# (versions 1.72 and later and 1.68.1 and earlier). +# Define ASCIIDOC_ROFF if your DocBook XSL does not escape raw roff directives +# (versions 1.68.1 through v1.72). # # Define GNU_ROFF if your target system uses GNU groff. This forces # apostrophes to be ASCII so that cut&pasting examples to the shell @@@ -406,7 -401,6 +406,7 @@@ EXTRA_PROGRAMS # ... and all the rest that could be moved out of bindir to gitexecdir PROGRAMS += $(EXTRA_PROGRAMS) +PROGRAM_OBJS += daemon.o PROGRAM_OBJS += fast-import.o PROGRAM_OBJS += imap-send.o PROGRAM_OBJS += shell.o @@@ -431,6 -425,7 +431,7 @@@ TEST_PROGRAMS_NEED_X += test-run-comman TEST_PROGRAMS_NEED_X += test-sha1 TEST_PROGRAMS_NEED_X += test-sigchain TEST_PROGRAMS_NEED_X += test-string-pool + TEST_PROGRAMS_NEED_X += test-subprocess TEST_PROGRAMS_NEED_X += test-svn-fe TEST_PROGRAMS_NEED_X += test-treap TEST_PROGRAMS_NEED_X += test-index-version @@@ -502,9 -497,6 +503,9 @@@ LIB_H += compat/bswap. LIB_H += compat/cygwin.h LIB_H += compat/mingw.h LIB_H += compat/win32/pthread.h +LIB_H += compat/win32/syslog.h +LIB_H += compat/win32/sys/poll.h +LIB_H += compat/win32/dirent.h LIB_H += csum-file.h LIB_H += decorate.h LIB_H += delta.h @@@ -526,7 -518,6 +527,7 @@@ LIB_H += mailmap. LIB_H += merge-recursive.h LIB_H += notes.h LIB_H += notes-cache.h +LIB_H += notes-merge.h LIB_H += object.h LIB_H += pack.h LIB_H += pack-refs.h @@@ -617,7 -608,6 +618,7 @@@ LIB_OBJS += merge-recursive. LIB_OBJS += name-hash.o LIB_OBJS += notes.o LIB_OBJS += notes-cache.o +LIB_OBJS += notes-merge.o LIB_OBJS += object.o LIB_OBJS += pack-check.o LIB_OBJS += pack-refs.o @@@ -673,7 -663,6 +674,7 @@@ LIB_OBJS += write_or_die. LIB_OBJS += ws.o LIB_OBJS += wt-status.o LIB_OBJS += xdiff-interface.o +LIB_OBJS += zlib.o BUILTIN_OBJS += builtin/add.o BUILTIN_OBJS += builtin/annotate.o @@@ -740,8 -729,6 +741,8 @@@ BUILTIN_OBJS += builtin/read-tree. BUILTIN_OBJS += builtin/receive-pack.o BUILTIN_OBJS += builtin/reflog.o BUILTIN_OBJS += builtin/remote.o +BUILTIN_OBJS += builtin/remote-ext.o +BUILTIN_OBJS += builtin/remote-fd.o BUILTIN_OBJS += builtin/replace.o BUILTIN_OBJS += builtin/rerere.o BUILTIN_OBJS += builtin/reset.o @@@ -860,7 -847,6 +861,7 @@@ ifeq ($(uname_S),SunOS NO_MKDTEMP = YesPlease NO_MKSTEMPS = YesPlease NO_REGEX = YesPlease + NO_FNMATCH_CASEFOLD = YesPlease ifeq ($(uname_R),5.6) SOCKLEN_T = int NO_HSTRERROR = YesPlease @@@ -1003,7 -989,6 +1004,7 @@@ ifeq ($(uname_S),IRIX # issue, comment out the NO_MMAP statement. NO_MMAP = YesPlease NO_REGEX = YesPlease + NO_FNMATCH_CASEFOLD = YesPlease SNPRINTF_RETURNS_BOGUS = YesPlease SHELL_PATH = /usr/gnu/bin/bash NEEDS_LIBGEN = YesPlease @@@ -1023,7 -1008,6 +1024,7 @@@ ifeq ($(uname_S),IRIX64 # issue, comment out the NO_MMAP statement. NO_MMAP = YesPlease NO_REGEX = YesPlease + NO_FNMATCH_CASEFOLD = YesPlease SNPRINTF_RETURNS_BOGUS = YesPlease SHELL_PATH=/usr/gnu/bin/bash NEEDS_LIBGEN = YesPlease @@@ -1069,7 -1053,6 +1070,7 @@@ ifeq ($(uname_S),Windows NO_STRCASESTR = YesPlease NO_STRLCPY = YesPlease NO_STRTOK_R = YesPlease + NO_FNMATCH = YesPlease NO_MEMMEM = YesPlease # NEEDS_LIBICONV = YesPlease NO_ICONV = YesPlease @@@ -1082,6 -1065,7 +1083,6 @@@ 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 @@@ -1092,19 -1076,16 +1093,19 @@@ NO_CURL = YesPlease NO_PYTHON = YesPlease BLK_SHA1 = YesPlease + NO_POSIX_GOODIES = UnfortunatelyYes NATIVE_CRLF = 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/win32/pthread.o - COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -Icompat/win32 -DSTRIP_EXTENSION=\".exe\" + COMPAT_OBJS = compat/msvc.o compat/winansi.o \ + compat/win32/pthread.o compat/win32/syslog.o \ + compat/win32/sys/poll.o compat/win32/dirent.o + COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/regex -Icompat/win32 -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 + EXTLIBS = user32.lib advapi32.lib shell32.lib wininet.lib ws2_32.lib PTHREAD_LIBS = lib = ifndef DEBUG @@@ -1116,25 -1097,6 +1117,25 @@@ els endif X = .exe endif +ifeq ($(uname_S),Interix) + NO_SYS_POLL_H = YesPlease + NO_INTTYPES_H = YesPlease + NO_INITGROUPS = YesPlease + NO_IPV6 = YesPlease + NO_MEMMEM = YesPlease + NO_MKDTEMP = YesPlease + NO_STRTOUMAX = YesPlease + NO_NSEC = YesPlease + NO_MKSTEMPS = YesPlease + ifeq ($(uname_R),3.5) + NO_INET_NTOP = YesPlease + NO_INET_PTON = YesPlease + endif + ifeq ($(uname_R),5.2) + NO_INET_NTOP = YesPlease + NO_INET_PTON = YesPlease + endif +endif ifneq (,$(findstring MINGW,$(uname_S))) pathsep = ; NO_PREAD = YesPlease @@@ -1146,7 -1108,6 +1147,7 @@@ NO_STRCASESTR = YesPlease NO_STRLCPY = YesPlease NO_STRTOK_R = YesPlease + NO_FNMATCH = YesPlease NO_MEMMEM = YesPlease NEEDS_LIBICONV = YesPlease OLD_ICONV = YesPlease @@@ -1157,6 -1118,7 +1158,6 @@@ 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 @@@ -1167,14 -1129,10 +1168,14 @@@ NO_PYTHON = YesPlease BLK_SHA1 = YesPlease ETAGS_TARGET = ETAGS - COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch -Icompat/win32 + NO_INET_PTON = YesPlease + NO_INET_NTOP = YesPlease + NO_POSIX_GOODIES = UnfortunatelyYes + COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/win32 COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\" - COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \ - compat/win32/pthread.o + COMPAT_OBJS += compat/mingw.o compat/winansi.o \ + compat/win32/pthread.o compat/win32/syslog.o \ + compat/win32/sys/poll.o compat/win32/dirent.o EXTLIBS += -lws2_32 PTHREAD_LIBS = X = .exe @@@ -1289,6 -1247,9 +1290,6 @@@ ifdef ZLIB_PAT endif EXTLIBS += -lz -ifndef NO_POSIX_ONLY_PROGRAMS - PROGRAM_OBJS += daemon.o -endif ifndef NO_OPENSSL OPENSSL_LIBSSL = -lssl ifdef OPENSSLDIR @@@ -1305,15 -1266,11 +1306,15 @@@ els BLK_SHA1 = 1 OPENSSL_LIBSSL = endif +ifdef NO_OPENSSL + LIB_4_CRYPTO = +else ifdef NEEDS_SSL_WITH_CRYPTO LIB_4_CRYPTO = $(OPENSSL_LINK) -lcrypto -lssl else LIB_4_CRYPTO = $(OPENSSL_LINK) -lcrypto endif +endif ifdef NEEDS_LIBICONV ifdef ICONVDIR BASIC_CFLAGS += -I$(ICONVDIR)/include @@@ -1386,17 -1343,6 +1387,17 @@@ ifdef NO_STRTOK_ COMPAT_CFLAGS += -DNO_STRTOK_R COMPAT_OBJS += compat/strtok_r.o endif +ifdef NO_FNMATCH + COMPAT_CFLAGS += -Icompat/fnmatch + COMPAT_CFLAGS += -DNO_FNMATCH + COMPAT_OBJS += compat/fnmatch/fnmatch.o +else +ifdef NO_FNMATCH_CASEFOLD + COMPAT_CFLAGS += -Icompat/fnmatch + COMPAT_CFLAGS += -DNO_FNMATCH_CASEFOLD + COMPAT_OBJS += compat/fnmatch/fnmatch.o +endif +endif ifdef NO_SETENV COMPAT_CFLAGS += -DNO_SETENV COMPAT_OBJS += compat/setenv.o @@@ -1415,15 -1361,6 +1416,15 @@@ endi ifdef NO_SYS_SELECT_H BASIC_CFLAGS += -DNO_SYS_SELECT_H endif +ifdef NO_SYS_POLL_H + BASIC_CFLAGS += -DNO_SYS_POLL_H +endif +ifdef NO_INTTYPES_H + BASIC_CFLAGS += -DNO_INTTYPES_H +endif +ifdef NO_INITGROUPS + BASIC_CFLAGS += -DNO_INITGROUPS +endif ifdef NO_MMAP COMPAT_CFLAGS += -DNO_MMAP COMPAT_OBJS += compat/mmap.o @@@ -1461,11 -1398,9 +1462,11 @@@ endi endif ifdef NO_INET_NTOP LIB_OBJS += compat/inet_ntop.o + BASIC_CFLAGS += -DNO_INET_NTOP endif ifdef NO_INET_PTON LIB_OBJS += compat/inet_pton.o + BASIC_CFLAGS += -DNO_INET_PTON endif ifdef NO_ICONV @@@ -1480,10 -1415,6 +1481,10 @@@ ifdef NO_DEFLATE_BOUN BASIC_CFLAGS += -DNO_DEFLATE_BOUND endif +ifdef NO_POSIX_GOODIES + BASIC_CFLAGS += -DNO_POSIX_GOODIES +endif + ifdef BLK_SHA1 SHA1_HEADER = "block-sha1/sha1.h" LIB_OBJS += block-sha1/sha1.o @@@ -1588,8 -1519,8 +1589,8 @@@ ifndef endif endif -ifdef ASCIIDOC8 - export ASCIIDOC8 +ifdef ASCIIDOC7 + export ASCIIDOC7 endif # Shell quote (do not use $(call) to accommodate ancient setups); @@@ -1681,8 -1612,6 +1682,8 @@@ git$X: git.o $(BUILTIN_OBJS) $(GITLIBS $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \ $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS) +help.o: common-cmds.h + builtin/help.o: common-cmds.h builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \ '-DGIT_HTML_PATH="$(htmldir_SQ)"' \ @@@ -1838,8 -1767,6 +1839,8 @@@ XDIFF_OBJS = xdiff/xdiffi.o xdiff/xprep xdiff/xmerge.o xdiff/xpatience.o VCSSVN_OBJS = vcs-svn/string_pool.o vcs-svn/line_buffer.o \ vcs-svn/repo_tree.o vcs-svn/fast_export.o vcs-svn/svndump.o +VCSSVN_TEST_OBJS = test-obj-pool.o test-string-pool.o \ + test-line-buffer.o test-treap.o OBJECTS := $(GIT_OBJS) $(XDIFF_OBJS) $(VCSSVN_OBJS) dep_files := $(foreach f,$(OBJECTS),$(dir $f).depend/$(notdir $f).d) @@@ -1948,26 -1875,25 +1949,26 @@@ builtin/branch.o builtin/checkout.o bui builtin/bundle.o bundle.o transport.o: bundle.h builtin/bisect--helper.o builtin/rev-list.o bisect.o: bisect.h builtin/clone.o builtin/fetch-pack.o transport.o: fetch-pack.h -builtin/grep.o: thread-utils.h +builtin/grep.o builtin/pack-objects.o transport-helper.o: thread-utils.h builtin/send-pack.o transport.o: send-pack.h builtin/log.o builtin/shortlog.o: shortlog.h builtin/prune.o builtin/reflog.o reachable.o: reachable.h builtin/commit.o builtin/revert.o wt-status.o: wt-status.h builtin/tar-tree.o archive-tar.o: tar.h -builtin/pack-objects.o: thread-utils.h connect.o transport.o http-backend.o: url.h http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h -http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h +http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h url.h xdiff-interface.o $(XDIFF_OBJS): \ xdiff/xinclude.h xdiff/xmacros.h xdiff/xdiff.h xdiff/xtypes.h \ xdiff/xutils.h xdiff/xprepare.h xdiff/xdiffi.h xdiff/xemit.h -$(VCSSVN_OBJS): \ +$(VCSSVN_OBJS) $(VCSSVN_TEST_OBJS): $(LIB_H) \ vcs-svn/obj_pool.h vcs-svn/trp.h vcs-svn/string_pool.h \ vcs-svn/line_buffer.h vcs-svn/repo_tree.h vcs-svn/fast_export.h \ vcs-svn/svndump.h + +test-svn-fe.o: vcs-svn/svndump.h endif exec_cmd.s exec_cmd.o: EXTRA_CPPFLAGS = \ @@@ -2002,7 -1928,7 +2003,7 @@@ git-%$X: %.o $(GITLIBS git-imap-send$X: imap-send.o $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ - $(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL) + $(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL) $(LIB_4_CRYPTO) git-http-fetch$X: revision.o http.o http-walker.o http-fetch.o $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ diff --combined cache.h index 32170c293d,123dd4bb93..d83d68c859 --- a/cache.h +++ b/cache.h @@@ -170,26 -170,26 +170,26 @@@ struct cache_entry * * In-memory only flags */ -#define CE_UPDATE (0x10000) -#define CE_REMOVE (0x20000) -#define CE_UPTODATE (0x40000) -#define CE_ADDED (0x80000) +#define CE_UPDATE (1 << 16) +#define CE_REMOVE (1 << 17) +#define CE_UPTODATE (1 << 18) +#define CE_ADDED (1 << 19) -#define CE_HASHED (0x100000) -#define CE_UNHASHED (0x200000) -#define CE_CONFLICTED (0x800000) +#define CE_HASHED (1 << 20) +#define CE_UNHASHED (1 << 21) +#define CE_WT_REMOVE (1 << 22) /* remove in work directory */ +#define CE_CONFLICTED (1 << 23) -#define CE_WT_REMOVE (0x400000) /* remove in work directory */ - -#define CE_UNPACKED (0x1000000) +#define CE_UNPACKED (1 << 24) +#define CE_NEW_SKIP_WORKTREE (1 << 25) /* * Extended on-disk flags */ -#define CE_INTENT_TO_ADD 0x20000000 -#define CE_SKIP_WORKTREE 0x40000000 +#define CE_INTENT_TO_ADD (1 << 29) +#define CE_SKIP_WORKTREE (1 << 30) /* CE_EXTENDED2 is for future extension */ -#define CE_EXTENDED2 0x80000000 +#define CE_EXTENDED2 (1 << 31) #define CE_EXTENDED_FLAGS (CE_INTENT_TO_ADD | CE_SKIP_WORKTREE) @@@ -428,7 -428,7 +428,7 @@@ extern const char **get_pathspec(const extern void setup_work_tree(void); extern const char *setup_git_directory_gently(int *); extern const char *setup_git_directory(void); -extern const char *prefix_path(const char *prefix, int len, const char *path); +extern char *prefix_path(const char *prefix, int len, const char *path); extern const char *prefix_filename(const char *prefix, int len, const char *path); extern int check_filename(const char *prefix, const char *name); extern void verify_filename(const char *prefix, const char *name); @@@ -545,7 -545,6 +545,7 @@@ extern int assume_unchanged extern int prefer_symlink_refs; extern int log_all_ref_updates; extern int warn_ambiguous_refs; +extern int unique_abbrev_extra_length; extern int shared_repository; extern const char *apply_default_whitespace; extern const char *apply_default_ignorewhitespace; @@@ -860,7 -859,7 +860,7 @@@ struct cache_def extern int has_symlink_leading_path(const char *name, int len); extern int threaded_has_symlink_leading_path(struct cache_def *, const char *, int); -extern int has_symlink_or_noent_leading_path(const char *name, int len); +extern int check_leading_path(const char *name, int len); extern int has_dirs_only_path(const char *name, int len, int prefix_len); extern void schedule_dir_for_removal(const char *name, int len); extern void remove_scheduled_dirs(void); @@@ -987,6 -986,7 +987,7 @@@ extern int git_config_parse_parameter(c extern int git_config_parse_environment(void); extern int git_config_from_parameters(config_fn_t fn, void *data); extern int git_config(config_fn_t fn, void *); + extern int git_config_early(config_fn_t fn, void *, const char *repo_config); extern int git_parse_ulong(const char *, unsigned long *); extern int git_config_int(const char *, const char *); extern unsigned long git_config_ulong(const char *, const char *); @@@ -1004,9 -1004,6 +1005,9 @@@ extern int git_env_bool(const char *, i extern int git_config_system(void); extern int git_config_global(void); extern int config_error_nonbool(const char *); +extern const char *get_log_output_encoding(void); +extern const char *get_commit_output_encoding(void); + extern const char *config_exclusive_filename; #define MAX_GITNAME (1000) @@@ -1066,6 -1063,7 +1067,7 @@@ __attribute__((format (printf, 1, 2)) extern void trace_printf(const char *format, ...); __attribute__((format (printf, 2, 3))) extern void trace_argv_printf(const char **argv, const char *format, ...); + extern void trace_repo_setup(const char *prefix); /* convert.c */ /* returns 1 if *dst was used */ @@@ -1091,17 -1089,15 +1093,17 @@@ void shift_tree_by(const unsigned char /* * whitespace rules. * used by both diff and apply + * last two digits are tab width */ -#define WS_BLANK_AT_EOL 01 -#define WS_SPACE_BEFORE_TAB 02 -#define WS_INDENT_WITH_NON_TAB 04 -#define WS_CR_AT_EOL 010 -#define WS_BLANK_AT_EOF 020 -#define WS_TAB_IN_INDENT 040 +#define WS_BLANK_AT_EOL 0100 +#define WS_SPACE_BEFORE_TAB 0200 +#define WS_INDENT_WITH_NON_TAB 0400 +#define WS_CR_AT_EOL 01000 +#define WS_BLANK_AT_EOF 02000 +#define WS_TAB_IN_INDENT 04000 #define WS_TRAILING_SPACE (WS_BLANK_AT_EOL|WS_BLANK_AT_EOF) -#define WS_DEFAULT_RULE (WS_TRAILING_SPACE|WS_SPACE_BEFORE_TAB) +#define WS_DEFAULT_RULE (WS_TRAILING_SPACE|WS_SPACE_BEFORE_TAB|8) +#define WS_TAB_WIDTH_MASK 077 extern unsigned whitespace_rule_cfg; extern unsigned whitespace_rule(const char *); extern unsigned parse_whitespace_rule(const char *); @@@ -1110,7 -1106,6 +1112,7 @@@ extern void ws_check_emit(const char *l extern char *whitespace_error_string(unsigned ws); extern void ws_fix_copy(struct strbuf *, const char *, int, unsigned, int *); extern int ws_blank_line(const char *line, int len, unsigned ws_rule); +#define ws_tab_width(rule) ((rule) & WS_TAB_WIDTH_MASK) /* ls-files */ int report_path_error(const char *ps_matched, const char **pathspec, int prefix_offset); @@@ -1124,7 -1119,6 +1126,7 @@@ const char *split_cmdline_strerror(int /* git.c */ struct startup_info { int have_repository; + const char *prefix; }; extern struct startup_info *startup_info; diff --combined config.c index d73b090b6a,c431f41c5a..625e051876 --- a/config.c +++ b/config.c @@@ -410,7 -410,7 +410,7 @@@ unsigned long git_config_ulong(const ch return ret; } -int git_config_maybe_bool(const char *name, const char *value) +static int git_config_maybe_bool_text(const char *name, const char *value) { if (!value) return 1; @@@ -427,19 -427,9 +427,19 @@@ return -1; } +int git_config_maybe_bool(const char *name, const char *value) +{ + long v = git_config_maybe_bool_text(name, value); + if (0 <= v) + return v; + if (git_parse_long(value, &v)) + return !!v; + return -1; +} + int git_config_bool_or_int(const char *name, const char *value, int *is_bool) { - int v = git_config_maybe_bool(name, value); + int v = git_config_maybe_bool_text(name, value); if (0 <= v) { *is_bool = 1; return v; @@@ -499,13 -489,6 +499,13 @@@ static int git_default_core_config(cons return 0; } + if (!strcmp(var, "core.abbrevguard")) { + unique_abbrev_extra_length = git_config_int(var, value); + if (unique_abbrev_extra_length < 0) + unique_abbrev_extra_length = 0; + return 0; + } + if (!strcmp(var, "core.bare")) { is_bare_repository_cfg = git_config_bool(var, value); return 0; @@@ -852,10 -835,9 +852,9 @@@ int git_config_from_parameters(config_f return 0; } - int git_config(config_fn_t fn, void *data) + int git_config_early(config_fn_t fn, void *data, const char *repo_config) { int ret = 0, found = 0; - char *repo_config = NULL; const char *home = NULL; /* Setting $GIT_CONFIG makes git read _only_ the given config file. */ @@@ -877,20 -859,32 +876,30 @@@ free(user_config); } - repo_config = git_pathdup("config"); - if (!access(repo_config, R_OK)) { + if (repo_config && !access(repo_config, R_OK)) { ret += git_config_from_file(fn, repo_config, data); found += 1; } - free(repo_config); ret += git_config_from_parameters(fn, data); if (config_parameters) found += 1; - if (found == 0) - return -1; - return ret; + return ret == 0 ? found : ret; } + int git_config(config_fn_t fn, void *data) + { + char *repo_config = NULL; + int ret; + + repo_config = git_pathdup("config"); + ret = git_config_early(fn, data, repo_config); + if (repo_config) + free(repo_config); + return ret; + } + /* * Find all the stuff for git_config_set() below. */ diff --combined environment.c index c79f2a9b56,149c132304..9564475f42 --- a/environment.c +++ b/environment.c @@@ -21,7 -21,6 +21,7 @@@ int prefer_symlink_refs int is_bare_repository_cfg = -1; /* unspecified */ int log_all_ref_updates = -1; /* unspecified */ int warn_ambiguous_refs = 1; +int unique_abbrev_extra_length; int repository_format_version; const char *git_commit_encoding; const char *git_log_output_encoding; @@@ -88,7 -87,6 +88,7 @@@ const char * const local_repo_env[LOCAL static void setup_git_env(void) { git_dir = getenv(GIT_DIR_ENVIRONMENT); + git_dir = git_dir ? xstrdup(git_dir) : NULL; if (!git_dir) { git_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT); git_dir = git_dir ? xstrdup(git_dir) : NULL; @@@ -139,30 -137,20 +139,20 @@@ static int git_work_tree_initialized */ void set_git_work_tree(const char *new_work_tree) { - if (is_bare_repository_cfg >= 0) - die("cannot set work tree after initialization"); + if (git_work_tree_initialized) { + new_work_tree = make_absolute_path(new_work_tree); + if (strcmp(new_work_tree, work_tree)) + die("internal error: work tree has already been set\n" + "Current worktree: %s\nNew worktree: %s", + work_tree, new_work_tree); + return; + } git_work_tree_initialized = 1; - free(work_tree); work_tree = xstrdup(make_absolute_path(new_work_tree)); - is_bare_repository_cfg = 0; } const char *get_git_work_tree(void) { - if (!git_work_tree_initialized) { - work_tree = getenv(GIT_WORK_TREE_ENVIRONMENT); - /* core.bare = true overrides implicit and config work tree */ - if (!work_tree && is_bare_repository_cfg < 1) { - work_tree = git_work_tree_cfg; - /* make_absolute_path also normalizes the path */ - if (work_tree && !is_absolute_path(work_tree)) - work_tree = xstrdup(make_absolute_path(git_path("%s", work_tree))); - } else if (work_tree) - work_tree = xstrdup(make_absolute_path(work_tree)); - git_work_tree_initialized = 1; - if (work_tree) - is_bare_repository_cfg = 0; - } return work_tree; } @@@ -173,43 -161,6 +163,43 @@@ char *get_object_directory(void return git_object_dir; } +int odb_mkstemp(char *template, size_t limit, const char *pattern) +{ + int fd; + /* + * we let the umask do its job, don't try to be more + * restrictive except to remove write permission. + */ + int mode = 0444; + snprintf(template, limit, "%s/%s", + get_object_directory(), pattern); + fd = git_mkstemp_mode(template, mode); + if (0 <= fd) + return fd; + + /* slow path */ + /* some mkstemp implementations erase template on failure */ + snprintf(template, limit, "%s/%s", + get_object_directory(), pattern); + safe_create_leading_directories(template); + return xmkstemp_mode(template, mode); +} + +int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1) +{ + int fd; + + snprintf(name, namesz, "%s/pack/pack-%s.keep", + get_object_directory(), sha1_to_hex(sha1)); + fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600); + if (0 <= fd) + return fd; + + /* slow path */ + safe_create_leading_directories(name); + return open(name, O_RDWR|O_CREAT|O_EXCL, 0600); +} + char *get_index_file(void) { if (!git_index_file) @@@ -231,14 -182,3 +221,14 @@@ int set_git_dir(const char *path setup_git_env(); return 0; } + +const char *get_log_output_encoding(void) +{ + return git_log_output_encoding ? git_log_output_encoding + : get_commit_output_encoding(); +} + +const char *get_commit_output_encoding(void) +{ + return git_commit_encoding ? git_commit_encoding : "UTF-8"; +} diff --combined git.c index d532576cdf,6793178210..68334f6a31 --- a/git.c +++ b/git.c @@@ -19,22 -19,14 +19,22 @@@ static struct startup_info git_startup_ static int use_pager = -1; struct pager_config { const char *cmd; - int val; + int want; + char *value; }; static int pager_command_config(const char *var, const char *value, void *data) { struct pager_config *c = data; - if (!prefixcmp(var, "pager.") && !strcmp(var + 6, c->cmd)) - c->val = git_config_bool(var, value); + if (!prefixcmp(var, "pager.") && !strcmp(var + 6, c->cmd)) { + int b = git_config_maybe_bool(var, value); + if (b >= 0) + c->want = b; + else { + c->want = 1; + c->value = xstrdup(value); + } + } return 0; } @@@ -43,12 -35,9 +43,12 @@@ int check_pager_config(const char *cmd { struct pager_config c; c.cmd = cmd; - c.val = -1; + c.want = -1; + c.value = NULL; git_config(pager_command_config, &c); - return c.val; + if (c.value) + pager_program = c.value; + return c.want; } static void commit_pager_choice(void) { @@@ -275,6 -264,10 +275,10 @@@ static int run_builtin(struct cmd_struc use_pager = check_pager_config(p->cmd); if (use_pager == -1 && p->option & USE_PAGER) use_pager = 1; + + if ((p->option & (RUN_SETUP | RUN_SETUP_GENTLY)) && + startup_info->have_repository) /* get_git_dir() may set up repo, avoid that */ + trace_repo_setup(prefix); } commit_pager_choice(); @@@ -385,8 -378,6 +389,8 @@@ static void handle_internal_command(in { "receive-pack", cmd_receive_pack }, { "reflog", cmd_reflog, RUN_SETUP }, { "remote", cmd_remote, RUN_SETUP }, + { "remote-ext", cmd_remote_ext }, + { "remote-fd", cmd_remote_fd }, { "replace", cmd_replace, RUN_SETUP }, { "repo-config", cmd_config, RUN_SETUP_GENTLY }, { "rerere", cmd_rerere, RUN_SETUP }, diff --combined setup.c index 91887a40b7,be550af42a..3d732697af --- a/setup.c +++ b/setup.c @@@ -4,7 -4,7 +4,7 @@@ static int inside_git_dir = -1; static int inside_work_tree = -1; -const char *prefix_path(const char *prefix, int len, const char *path) +char *prefix_path(const char *prefix, int len, const char *path) { const char *orig = path; char *sanitized = xmalloc(len + strlen(path) + 1); @@@ -46,7 -46,7 +46,7 @@@ const char *prefix_filename(const char { static char path[PATH_MAX]; #ifndef WIN32 - if (!pfx || !*pfx || is_absolute_path(arg)) + if (!pfx_len || is_absolute_path(arg)) return arg; memcpy(path, pfx, pfx_len); strcpy(path + pfx_len, arg); @@@ -55,7 -55,7 +55,7 @@@ /* don't add prefix to absolute paths, but still replace '\' by '/' */ if (is_absolute_path(arg)) pfx_len = 0; - else + else if (pfx_len) memcpy(path, pfx, pfx_len); strcpy(path + pfx_len, arg); for (p = path + pfx_len; *p; p++) @@@ -208,24 -208,6 +208,6 @@@ int is_inside_work_tree(void return inside_work_tree; } - /* - * set_work_tree() is only ever called if you set GIT_DIR explicitly. - * The old behaviour (which we retain here) is to set the work tree root - * to the cwd, unless overridden by the config, the command line, or - * GIT_WORK_TREE. - */ - static const char *set_work_tree(const char *dir) - { - char buffer[PATH_MAX + 1]; - - if (!getcwd(buffer, sizeof(buffer))) - die ("Could not get the current working directory"); - git_work_tree_cfg = xstrdup(buffer); - inside_work_tree = 1; - - return NULL; - } - void setup_work_tree(void) { const char *work_tree, *git_dir; @@@ -239,13 -221,33 +221,33 @@@ git_dir = make_absolute_path(git_dir); if (!work_tree || chdir(work_tree)) die("This operation must be run in a work tree"); + + /* + * Make sure subsequent git processes find correct worktree + * if $GIT_WORK_TREE is set relative + */ + if (getenv(GIT_WORK_TREE_ENVIRONMENT)) + setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1); + set_git_dir(make_relative_path(git_dir, work_tree)); initialized = 1; } - static int check_repository_format_gently(int *nongit_ok) + static int check_repository_format_gently(const char *gitdir, int *nongit_ok) { - git_config(check_repository_format_version, NULL); + char repo_config[PATH_MAX+1]; + + /* + * git_config() can't be used here because it calls git_pathdup() + * to get $GIT_CONFIG/config. That call will make setup_git_env() + * set git_dir to ".git". + * + * We are in gitdir setup, no git dir has been found useable yet. + * Use a gentler version of git_config() to check if this repo + * is a good one. + */ + snprintf(repo_config, PATH_MAX, "%s/config", gitdir); + git_config_early(check_repository_format_version, NULL, repo_config); if (GIT_REPO_VERSION < repository_format_version) { if (!nongit_ok) die ("Expected git repo version <= %d, found %d", @@@ -314,64 -316,115 +316,115 @@@ const char *read_gitfile_gently(const c } static const char *setup_explicit_git_dir(const char *gitdirenv, - const char *work_tree_env, int *nongit_ok) + char *cwd, int len, + int *nongit_ok) { - static char buffer[1024 + 1]; - const char *retval; + const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT); + const char *worktree; + char *gitfile; if (PATH_MAX - 40 < strlen(gitdirenv)) die("'$%s' too big", GIT_DIR_ENVIRONMENT); + + gitfile = (char*)read_gitfile_gently(gitdirenv); + if (gitfile) { + gitfile = xstrdup(gitfile); + gitdirenv = gitfile; + } + if (!is_git_directory(gitdirenv)) { if (nongit_ok) { *nongit_ok = 1; + free(gitfile); return NULL; } die("Not a git repository: '%s'", gitdirenv); } - if (!work_tree_env) { - retval = set_work_tree(gitdirenv); - /* config may override worktree */ - if (check_repository_format_gently(nongit_ok)) - return NULL; - return retval; + + if (check_repository_format_gently(gitdirenv, nongit_ok)) { + free(gitfile); + return NULL; } - if (check_repository_format_gently(nongit_ok)) + + /* #3, #7, #11, #15, #19, #23, #27, #31 (see t1510) */ + if (work_tree_env) + set_git_work_tree(work_tree_env); + else if (is_bare_repository_cfg > 0) { + if (git_work_tree_cfg) /* #22.2, #30 */ + die("core.bare and core.worktree do not make sense"); + + /* #18, #26 */ + set_git_dir(gitdirenv); + free(gitfile); return NULL; - retval = get_relative_cwd(buffer, sizeof(buffer) - 1, - get_git_work_tree()); - if (!retval || !*retval) + } + else if (git_work_tree_cfg) { /* #6, #14 */ + if (is_absolute_path(git_work_tree_cfg)) + set_git_work_tree(git_work_tree_cfg); + else { + char core_worktree[PATH_MAX]; + if (chdir(gitdirenv)) + die_errno("Could not chdir to '%s'", gitdirenv); + if (chdir(git_work_tree_cfg)) + die_errno("Could not chdir to '%s'", git_work_tree_cfg); + if (!getcwd(core_worktree, PATH_MAX)) + die_errno("Could not get directory '%s'", git_work_tree_cfg); + if (chdir(cwd)) + die_errno("Could not come back to cwd"); + set_git_work_tree(core_worktree); + } + } + else /* #2, #10 */ + set_git_work_tree("."); + + /* set_git_work_tree() must have been called by now */ + worktree = get_git_work_tree(); + + /* both get_git_work_tree() and cwd are already normalized */ + if (!strcmp(cwd, worktree)) { /* cwd == worktree */ + set_git_dir(gitdirenv); + free(gitfile); return NULL; - set_git_dir(make_absolute_path(gitdirenv)); - if (chdir(work_tree_env) < 0) - die_errno ("Could not chdir to '%s'", work_tree_env); - strcat(buffer, "/"); - return retval; - } + } - static int cwd_contains_git_dir(const char **gitfile_dirp) - { - const char *gitfile_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT); - *gitfile_dirp = gitfile_dir; - if (gitfile_dir) { - if (set_git_dir(gitfile_dir)) - die("Repository setup failed"); - return 1; + if (!prefixcmp(cwd, worktree) && + cwd[strlen(worktree)] == '/') { /* cwd inside worktree */ + set_git_dir(make_absolute_path(gitdirenv)); + if (chdir(worktree)) + die_errno("Could not chdir to '%s'", worktree); + cwd[len++] = '/'; + cwd[len] = '\0'; + free(gitfile); + return cwd + strlen(worktree) + 1; } - return is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT); + + /* cwd outside worktree */ + set_git_dir(gitdirenv); + free(gitfile); + return NULL; } - static const char *setup_discovered_git_dir(const char *work_tree_env, - int offset, int len, char *cwd, int *nongit_ok) + static const char *setup_discovered_git_dir(const char *gitdir, + char *cwd, int offset, int len, + int *nongit_ok) { - int root_len; + if (check_repository_format_gently(gitdir, nongit_ok)) + return NULL; - inside_git_dir = 0; - if (!work_tree_env) - inside_work_tree = 1; - root_len = offset_1st_component(cwd); - git_work_tree_cfg = xstrndup(cwd, offset > root_len ? offset : root_len); - if (check_repository_format_gently(nongit_ok)) + /* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */ + if (is_bare_repository_cfg > 0) { + set_git_dir(offset == len ? gitdir : make_absolute_path(gitdir)); + if (chdir(cwd)) + die_errno("Could not come back to cwd"); return NULL; + } + + /* #0, #1, #5, #8, #9, #12, #13 */ + set_git_work_tree("."); + if (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT)) + set_git_dir(gitdir); + inside_git_dir = 0; + inside_work_tree = 1; if (offset == len) return NULL; @@@ -382,23 -435,25 +435,25 @@@ return cwd + offset; } - static const char *setup_bare_git_dir(const char *work_tree_env, - int offset, int len, char *cwd, int *nongit_ok) + /* #16.1, #17.1, #20.1, #21.1, #22.1 (see t1510) */ + static const char *setup_bare_git_dir(char *cwd, int offset, int len, int *nongit_ok) { int root_len; + if (check_repository_format_gently(".", nongit_ok)) + return NULL; + inside_git_dir = 1; - if (!work_tree_env) - inside_work_tree = 0; + inside_work_tree = 0; if (offset != len) { if (chdir(cwd)) die_errno("Cannot come back to cwd"); root_len = offset_1st_component(cwd); cwd[offset > root_len ? offset : root_len] = '\0'; set_git_dir(cwd); - } else + } + else set_git_dir("."); - check_repository_format_gently(nongit_ok); return NULL; } @@@ -428,11 -483,10 +483,10 @@@ static dev_t get_device_or_die(const ch */ static const char *setup_git_directory_gently_1(int *nongit_ok) { - const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT); const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT); static char cwd[PATH_MAX+1]; - const char *gitdirenv; - const char *gitfile_dir; + const char *gitdirenv, *ret; + char *gitfile; int len, offset, ceil_offset; dev_t current_device = 0; int one_filesystem = 1; @@@ -445,6 -499,10 +499,10 @@@ if (nongit_ok) *nongit_ok = 0; + if (!getcwd(cwd, sizeof(cwd)-1)) + die_errno("Unable to read current working directory"); + offset = len = strlen(cwd); + /* * If GIT_DIR is set explicitly, we're not going * to do any discovery, but we still do repository @@@ -452,10 -510,7 +510,7 @@@ */ gitdirenv = getenv(GIT_DIR_ENVIRONMENT); if (gitdirenv) - return setup_explicit_git_dir(gitdirenv, work_tree_env, nongit_ok); - - if (!getcwd(cwd, sizeof(cwd)-1)) - die_errno("Unable to read current working directory"); + return setup_explicit_git_dir(gitdirenv, cwd, len, nongit_ok); ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs); if (ceil_offset < 0 && has_dos_drive_prefix(cwd)) @@@ -472,17 -527,30 +527,30 @@@ * - ../../.git/ * etc. */ - offset = len = strlen(cwd); one_filesystem = !git_env_bool("GIT_DISCOVERY_ACROSS_FILESYSTEM", 0); if (one_filesystem) current_device = get_device_or_die(".", NULL); for (;;) { - if (cwd_contains_git_dir(&gitfile_dir)) - return setup_discovered_git_dir(work_tree_env, offset, - len, cwd, nongit_ok); + gitfile = (char*)read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT); + if (gitfile) + gitdirenv = gitfile = xstrdup(gitfile); + else { + if (is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT)) + gitdirenv = DEFAULT_GIT_DIR_ENVIRONMENT; + } + + if (gitdirenv) { + ret = setup_discovered_git_dir(gitdirenv, + cwd, offset, len, + nongit_ok); + free(gitfile); + return ret; + } + free(gitfile); + if (is_git_directory(".")) - return setup_bare_git_dir(work_tree_env, offset, - len, cwd, nongit_ok); + return setup_bare_git_dir(cwd, offset, len, nongit_ok); + while (--offset > ceil_offset && cwd[offset] != '/'); if (offset <= ceil_offset) return setup_nongit(cwd, nongit_ok); @@@ -512,10 -580,8 +580,10 @@@ const char *setup_git_directory_gently( const char *prefix; prefix = setup_git_directory_gently_1(nongit_ok); - if (startup_info) + if (startup_info) { startup_info->have_repository = !nongit_ok || !*nongit_ok; + startup_info->prefix = prefix; + } return prefix; } @@@ -592,7 -658,7 +660,7 @@@ int check_repository_format_version(con int check_repository_format(void) { - return check_repository_format_gently(NULL); + return check_repository_format_gently(get_git_dir(), NULL); } /* @@@ -603,19 -669,5 +671,5 @@@ */ const char *setup_git_directory(void) { - const char *retval = setup_git_directory_gently(NULL); - - /* If the work tree is not the default one, recompute prefix */ - if (inside_work_tree < 0) { - static char buffer[PATH_MAX + 1]; - char *rel; - if (retval && chdir(retval)) - die_errno ("Could not jump back into original cwd"); - rel = get_relative_cwd(buffer, PATH_MAX, get_git_work_tree()); - if (rel && *rel && chdir(get_git_work_tree())) - die_errno ("Could not jump to working directory"); - return rel && *rel ? strcat(rel, "/") : NULL; - } - - return retval; + return setup_git_directory_gently(NULL); } diff --combined t/t0001-init.sh index d44194c35f,28c1858c2b..af8b9c52a9 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@@ -25,7 -25,7 +25,7 @@@ check_config () test_expect_success 'plain' ' ( - unset GIT_DIR GIT_WORK_TREE + sane_unset GIT_DIR GIT_WORK_TREE && mkdir plain && cd plain && git init @@@ -33,9 -33,65 +33,65 @@@ check_config plain/.git false unset ' + test_expect_success 'plain nested in bare' ' + ( + unset GIT_DIR GIT_WORK_TREE && + git init --bare bare-ancestor.git && + cd bare-ancestor.git && + mkdir plain-nested && + cd plain-nested && + git init + ) && + check_config bare-ancestor.git/plain-nested/.git false unset + ' + + test_expect_success 'plain through aliased command, outside any git repo' ' + ( + unset GIT_DIR GIT_WORK_TREE GIT_CONFIG_NOGLOBAL && + HOME=$(pwd)/alias-config && + export HOME && + mkdir alias-config && + echo "[alias] aliasedinit = init" >alias-config/.gitconfig && + + GIT_CEILING_DIRECTORIES=$(pwd) && + export GIT_CEILING_DIRECTORIES && + + mkdir plain-aliased && + cd plain-aliased && + git aliasedinit + ) && + check_config plain-aliased/.git false unset + ' + + test_expect_failure 'plain nested through aliased command' ' + ( + unset GIT_DIR GIT_WORK_TREE && + git init plain-ancestor-aliased && + cd plain-ancestor-aliased && + echo "[alias] aliasedinit = init" >>.git/config && + mkdir plain-nested && + cd plain-nested && + git aliasedinit + ) && + check_config plain-ancestor-aliased/plain-nested/.git false unset + ' + + test_expect_failure 'plain nested in bare through aliased command' ' + ( + unset GIT_DIR GIT_WORK_TREE && + git init --bare bare-ancestor-aliased.git && + cd bare-ancestor-aliased.git && + echo "[alias] aliasedinit = init" >>config && + mkdir plain-nested && + cd plain-nested && + git aliasedinit + ) && + check_config bare-ancestor-aliased.git/plain-nested/.git false unset + ' + test_expect_success 'plain with GIT_WORK_TREE' ' if ( - unset GIT_DIR + sane_unset GIT_DIR && mkdir plain-wt && cd plain-wt && GIT_WORK_TREE=$(pwd) git init @@@ -48,7 -104,7 +104,7 @@@ test_expect_success 'plain bare' ' ( - unset GIT_DIR GIT_WORK_TREE GIT_CONFIG + sane_unset GIT_DIR GIT_WORK_TREE GIT_CONFIG && mkdir plain-bare-1 && cd plain-bare-1 && git --bare init @@@ -58,7 -114,7 +114,7 @@@ test_expect_success 'plain bare with GIT_WORK_TREE' ' if ( - unset GIT_DIR GIT_CONFIG + sane_unset GIT_DIR GIT_CONFIG && mkdir plain-bare-2 && cd plain-bare-2 && GIT_WORK_TREE=$(pwd) git --bare init @@@ -72,7 -128,7 +128,7 @@@ test_expect_success 'GIT_DIR bare' ' ( - unset GIT_CONFIG + sane_unset GIT_CONFIG && mkdir git-dir-bare.git && GIT_DIR=git-dir-bare.git git init ) && @@@ -82,7 -138,7 +138,7 @@@ test_expect_success 'init --bare' ' ( - unset GIT_DIR GIT_WORK_TREE GIT_CONFIG + sane_unset GIT_DIR GIT_WORK_TREE GIT_CONFIG && mkdir init-bare.git && cd init-bare.git && git init --bare @@@ -93,7 -149,7 +149,7 @@@ test_expect_success 'GIT_DIR non-bare' ' ( - unset GIT_CONFIG + sane_unset GIT_CONFIG && mkdir non-bare && cd non-bare && GIT_DIR=.git git init @@@ -104,7 -160,7 +160,7 @@@ test_expect_success 'GIT_DIR & GIT_WORK_TREE (1)' ' ( - unset GIT_CONFIG + sane_unset GIT_CONFIG && mkdir git-dir-wt-1.git && GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-1.git git init ) && @@@ -114,7 -170,7 +170,7 @@@ test_expect_success 'GIT_DIR & GIT_WORK_TREE (2)' ' if ( - unset GIT_CONFIG + sane_unset GIT_CONFIG && mkdir git-dir-wt-2.git && GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-2.git git --bare init ) @@@ -127,7 -183,7 +183,7 @@@ test_expect_success 'reinit' ' ( - unset GIT_CONFIG GIT_WORK_TREE GIT_CONFIG + sane_unset GIT_CONFIG GIT_WORK_TREE GIT_CONFIG && mkdir again && cd again && @@@ -175,8 -231,8 +231,8 @@@ test_expect_success 'init with init.tem git config -f "$test_config" init.templatedir "${HOME}/templatedir-source" && mkdir templatedir-set && cd templatedir-set && - unset GIT_CONFIG_NOGLOBAL && - unset GIT_TEMPLATE_DIR && + sane_unset GIT_CONFIG_NOGLOBAL && + sane_unset GIT_TEMPLATE_DIR && NO_SET_GIT_TEMPLATE_DIR=t && export NO_SET_GIT_TEMPLATE_DIR && git init @@@ -187,7 -243,7 +243,7 @@@ test_expect_success 'init --bare/--shared overrides system/global config' ' ( test_config="$HOME"/.gitconfig && - unset GIT_CONFIG_NOGLOBAL && + sane_unset GIT_CONFIG_NOGLOBAL && git config -f "$test_config" core.bare false && git config -f "$test_config" core.sharedRepository 0640 && mkdir init-bare-shared-override && @@@ -202,7 -258,7 +258,7 @@@ test_expect_success 'init honors global core.sharedRepository' ' ( test_config="$HOME"/.gitconfig && - unset GIT_CONFIG_NOGLOBAL && + sane_unset GIT_CONFIG_NOGLOBAL && git config -f "$test_config" core.sharedRepository 0666 && mkdir shared-honor-global && cd shared-honor-global && diff --combined trace.c index 0fb2a2c64b,bdb5d2fa77..02279b82c4 --- a/trace.c +++ b/trace.c @@@ -25,6 -25,10 +25,6 @@@ #include "cache.h" #include "quote.h" -void do_nothing(size_t unused) -{ -} - /* Get a trace file descriptor from GIT_TRACE env variable. */ static int get_trace_fd(int *need_close) { @@@ -72,7 -76,7 +72,7 @@@ void trace_printf(const char *fmt, ... if (!fd) return; - set_try_to_free_routine(do_nothing); /* is never reset */ + set_try_to_free_routine(NULL); /* is never reset */ strbuf_init(&buf, 64); va_start(ap, fmt); len = vsnprintf(buf.buf, strbuf_avail(&buf), fmt, ap); @@@ -104,7 -108,7 +104,7 @@@ void trace_argv_printf(const char **arg if (!fd) return; - set_try_to_free_routine(do_nothing); /* is never reset */ + set_try_to_free_routine(NULL); /* is never reset */ strbuf_init(&buf, 64); va_start(ap, fmt); len = vsnprintf(buf.buf, strbuf_avail(&buf), fmt, ap); @@@ -127,3 -131,45 +127,45 @@@ if (need_close) close(fd); } + + static const char *quote_crnl(const char *path) + { + static char new_path[PATH_MAX]; + const char *p2 = path; + char *p1 = new_path; + + if (!path) + return NULL; + + while (*p2) { + switch (*p2) { + case '\\': *p1++ = '\\'; *p1++ = '\\'; break; + case '\n': *p1++ = '\\'; *p1++ = 'n'; break; + case '\r': *p1++ = '\\'; *p1++ = 'r'; break; + default: + *p1++ = *p2; + } + p2++; + } + *p1 = '\0'; + return new_path; + } + + /* FIXME: move prefix to startup_info struct and get rid of this arg */ + void trace_repo_setup(const char *prefix) + { + char cwd[PATH_MAX]; + char *trace = getenv("GIT_TRACE"); + + if (!trace || !strcmp(trace, "") || + !strcmp(trace, "0") || !strcasecmp(trace, "false")) + return; + + if (!getcwd(cwd, PATH_MAX)) + die("Unable to get current working directory"); + + trace_printf("setup: git_dir: %s\n", quote_crnl(get_git_dir())); + trace_printf("setup: worktree: %s\n", quote_crnl(get_git_work_tree())); + trace_printf("setup: cwd: %s\n", quote_crnl(cwd)); + trace_printf("setup: prefix: %s\n", quote_crnl(prefix)); + }