Documentation: git-gui: describe gui.displayuntracked

Signed-off-by: Max Kirillov <max@max630.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
git-prompt.sh: don't put unsanitized branch names in $PS1

Both bash and zsh subject the value of PS1 to parameter expansion,
command substitution, and arithmetic expansion.  Rather than include
the raw, unescaped branch name in PS1 when running in two- or
three-argument mode, construct PS1 to reference a variable that holds
the branch name.  Because the shells do not recursively expand, this
avoids arbitrary code execution by specially-crafted branch names such
as '$(IFS=_;cmd=sudo_rm_-rf_/;$cmd)'.

Signed-off-by: Richard Hansen <rhansen@bbn.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
t9117: use --prefix "" instead of --prefix=""

Versions of Perl's Getopt::Long module before 2.37 do not contain
this fix that first appeared in Getopt::Long version 2.37:

* Bugfix: With gnu_compat, --foo= will no longer trigger "Option
  requires an argument" but return the empty string.

Instead of using --prefix="" use --prefix "" when testing an
explictly empty prefix string in order to work with older versions
of Perl's Getopt::Long module.

Also add a paragraph on this workaround to the documentation of
git-svn itself.

Signed-off-by: Kyle J. McKay <mackyle@gmail.com>
Acked-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
setup: fix windows path buffer over-stepping

Fix a buffer over-stepping issue triggered by providing an absolute path
that is similar to the work tree path.

abspath_part_inside_repo() may currently increment the path pointer by
offset_1st_component() + wtlen, which is too much, since
offset_1st_component() is a subset of wtlen.

For the *nix-style prefix '/', this does (by luck) not cause any issues,
since offset_1st_component() is 1 and there will always be a '/' or '\0'
that can "absorb" this.

In the case of DOS-style prefixes though, the offset_1st_component() is
3 and this can potentially over-step the string buffer. For example if

    work_tree = "c:/r"
    path      = "c:/rl"

Then wtlen is 4, and incrementing the path pointer by (3 + 4) would
end up 2 bytes outside a string buffer of length 6.

Similarly if

    work_tree = "c:/r"
    path      = "c:/rl/d/a"

Then (since the loop starts by also incrementing the pointer one step),
this would mean that the function would miss checking if "c:/rl/d" could
be the work_tree, arguably this is unlikely though, since it would only
be possible with symlinks on windows.

Fix this by simply avoiding to increment by offset_1st_component() and
wtlen at the same time.

Signed-off-by: Martin Erik Werner <martinerikwerner@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Merge branch 'mk/doc-git-gui-display-untracked'

* mk/doc-git-gui-display-untracked:
  Documentation: git-gui: describe gui.displayuntracked
Merge branch 'rh/prompt-pcmode-avoid-eval-on-refname'

* rh/prompt-pcmode-avoid-eval-on-refname:
  git-prompt.sh: don't put unsanitized branch names in $PS1
Merge branch 'km/git-svn-workaround-older-getopt-long'

* km/git-svn-workaround-older-getopt-long:
  t9117: use --prefix "" instead of --prefix=""
Merge branch 'mw/symlinks'

A finishing touch fix to a new change already in 'master'.

* mw/symlinks:
  setup: fix windows path buffer over-stepping
Git 2.0-rc2
dir.c: coding style fix
dir.h: move struct exclude declaration to top level

There is no actual nested struct here. Move it out for clarity.
prep_exclude: remove the artificial PATH_MAX limit

This also fixes the problem of silently ignoring .gitignore if the
full path exceeds PATH_MAX. Now add_excludes_from_file() will report
if it gets ENAMETOOLONG.
dir.c: optionally compute sha-1 of a .gitignore file

This is not used anywhere yet. But the goal is to compare quickly if a
.gitignore file has changed when one has SHA-1 of the old .gitignore.
untracked cache: record .gitignore information and dir hierarchy

The idea is if we can capture all input and output of
read_directory_recursive() and verify at a later time that all the
input is the same, then read_directory_recursive() should produce the
same output, so we can bypass read_directory_recursive() and reuse the
cached output for the directory in question (the bypass code needs to
verify subdirectories separately)

The list of input of read_directory_recursive() is in the big comment
block in dir.h. This cache focuses on only untracked files as the
output from r_d_r(), not ignored files because the number of tracked
files is usually small, so small cache overhead, while the number of
ignored files could go really high (e.g. *.o files mixing with source
code).

This patch captures .gitignore information, check_only bit and the
list of directories that read_directory_recursive() examines.

Two hash_sha1_file() are required for $GIT_DIR/info/exclude and
core.excludesfile unless their stat data matches. hash_sha1_file() is
only needed when .gitignore files in the worktree are modified,
otherwise their SHA-1 in index is used.

We could store stat data for .gitignore files so we don't have to
rehash them if their content is different from index, but I think
.gitignore files are rarely modified, so not worth extra cache data
(and hashing penalty read-cache.c:verify_hdr(), as we will be storing
this as an index extension).

This means if you change .gitignore at root directory, you better add
it to the index soon or you lose all the benefit of untracked cache (a
change at root .gitignore invalidates everything) and pay the cache
overhead for nothing.
untracked cache: initial untracked cache validation
untracked cache: invalidate dirs recursively if .gitignore changes

It's easy to see that if an existing .gitignore changes, its SHA-1
would be different and invalidate_gitignore() is called.

If .gitignore is removed, add_excludes() will treat it like an empty
.gitignore, which again should invalidate the cached directory data.

if .gitignore is added, lookup_untracked() already fills initial
.gitignore SHA-1 as "empty file", so again invalidate_gitignore() is
called.
untracked cache: record/validate dir mtime and reuse cached output

The main readdir loop in read_directory_recursive() is replaced with a
new one that checks if cached results of a directory is still valid.

If a file is added or removed from the index, the containing directory
is invalidated (but not its subdirs). If directory's mtime is changed,
the same happens. If a .gitignore is updated, the containing directory
and all subdirs are invalidated recursively. If dir_struct#flags or
other conditions change, the cache is ignored.

If a directory is invalidated, we opendir/readdir/closedir and run the
exclude machinery on that directory listing as usual. If untracked
cache is also enabled, we'll update the cache along the way. If a
directory is validated, we simply pull the untracked listing out from
the cache. The cache also records the list of direct subdirs that we
have to recurse in. Fully excluded directories are seen as "untracked
files".

In the best case when no dirs are invalidated, read_directory()
becomes a series of stat(dir), open(.gitignore), fstat, read, close
and optionally hash_sha1_file. For comparison, standard
read_directory() is a sequence of opendir, readdir, open(gitignore),
fstat, read, close, (expensive) last_exclude_matching and closedir.

We already try not to open(gitignore) if we know it does not exist, so
open/fstat/read/close sequence does not apply to every directory. The
sequence could be reduced further, as noted in prep_exclude(). So in
theory, the entire best-case read_directory sequence could be reduced
to a series of stat() and nothing else.

This is not a silver bullet approach. When you compile a C file, for
example, the old .o file is removed and a new one with the same name
created, effectively invalidating the containing directory's cache
(but not its subdirectories). If your build process touches every
directory, this cache adds extra overhead for nothing, so it's a good
idea to separate generated files from tracked files.. Editors may use
the same strategy for saving files. And of course you're out of luck
running your repo on an unsupported filesytem and/or operating system.
untracked cache: mark what dirs should be recursed/saved

When we invalidate a cached directory, read_directory_recursive() will
be called again and it will decide what directories to recurse in,
which may not be the same as recorded in the cache.

Mark this "recurse" status for each directory, clear them at
invalidation time and set them again inside r_d_r(). Only dirs with
"recurse" bit set will need to be examined at the next run and be
stored on disk later. Note that we do not invalidate subdirs because
they may be still good for use.
untracked cache: don't open non-existent .gitignore

This cuts down a signficant number of open(.gitignore) because most
directories usually don't have .gitignore files.
untracked cache: save to an index extension

FIXME: save check_only