/git-remote-https
/git-remote-ftp
/git-remote-ftps
+/git-remote-fd
+/git-remote-ext
/git-remote-testgit
/git-repack
/git-replace
/test-sha1
/test-sigchain
/test-string-pool
+ /test-subprocess
/test-svn-fe
/test-treap
/common-cmds.h
= 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 <ref> is logged to the file
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,
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=<n>` 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.
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.
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::
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
color.branch.<slot>::
Use customized color for branch coloration. `<slot>` 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
color.decorate.<slot>::
Use customized color for 'git log --decorate' output. `<slot>` 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
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.<slot>.
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
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`.
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::
supported.
pager.<cmd>::
- 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.<cmd>`. 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.<name>::
Alias for a --pretty= format string, as specified in
URL and other values found in the `.gitmodules` file. See
linkgit:git-submodule[1] and linkgit:gitmodules[5] for details.
+submodule.<name>.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.<name>.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
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],
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],
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],
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
#
# 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
# 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
# ... 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
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
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
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
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
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
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
NO_MKDTEMP = YesPlease
NO_MKSTEMPS = YesPlease
NO_REGEX = YesPlease
+ NO_FNMATCH_CASEFOLD = YesPlease
ifeq ($(uname_R),5.6)
SOCKLEN_T = int
NO_HSTRERROR = YesPlease
# 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
# 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
NO_STRCASESTR = YesPlease
NO_STRLCPY = YesPlease
NO_STRTOK_R = YesPlease
+ NO_FNMATCH = YesPlease
NO_MEMMEM = YesPlease
# NEEDS_LIBICONV = YesPlease
NO_ICONV = 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
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
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
NO_STRCASESTR = YesPlease
NO_STRLCPY = YesPlease
NO_STRTOK_R = YesPlease
+ NO_FNMATCH = YesPlease
NO_MEMMEM = YesPlease
NEEDS_LIBICONV = YesPlease
OLD_ICONV = 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
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
endif
EXTLIBS += -lz
-ifndef NO_POSIX_ONLY_PROGRAMS
- PROGRAM_OBJS += daemon.o
-endif
ifndef NO_OPENSSL
OPENSSL_LIBSSL = -lssl
ifdef OPENSSLDIR
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
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
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
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
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
endif
endif
-ifdef ASCIIDOC8
- export ASCIIDOC8
+ifdef ASCIIDOC7
+ export ASCIIDOC7
endif
# Shell quote (do not use $(call) to accommodate ancient setups);
$(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)"' \
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)
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 = \
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,$^) \
*
* 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)
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);
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;
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);
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 *);
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)
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 */
/*
* 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 *);
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);
/* git.c */
struct startup_info {
int have_repository;
+ const char *prefix;
};
extern struct startup_info *startup_info;
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;
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;
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;
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. */
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.
*/
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;
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;
*/
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;
}
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)
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";
+}
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;
}
{
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) {
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();
{ "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 },
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);
{
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);
/* 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++)
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;
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",
}
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;
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;
}
*/
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;
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
*/
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))
* - ../../.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);
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;
}
int check_repository_format(void)
{
- return check_repository_format_gently(NULL);
+ return check_repository_format_gently(get_git_dir(), NULL);
}
/*
*/
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);
}
test_expect_success 'plain' '
(
- unset GIT_DIR GIT_WORK_TREE
+ sane_unset GIT_DIR GIT_WORK_TREE &&
mkdir plain &&
cd plain &&
git init
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
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
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
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
) &&
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
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
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
) &&
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
)
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 &&
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
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 &&
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 &&
#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)
{
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);
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);
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));
+ }