The code will end up calling lstat() to check whether the
file still exists; obviously this doesn't work if we're not
in the worktree.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Tab completion makes it easy to add a trailing slash to a submodule path.
As it is completely clear what the user actually wanted to say, be nice
and strip that slash at the end.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Both versions have the same functionality. This removes any
redundancy.
This also adds makes two extensions to match_pathspec:
- If pathspec is NULL, return 1. This reflects the behavior of git
commands, for which no paths usually means "match all paths".
- If seen is NULL, do not use it.
Signed-off-by: Clemens Buchacher <drizzd@aon.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Originally --with-tree=<tree> was designed for the sole purpose of
checking if a given pathspec makes sense as a parameter to git-commit
using it in conjunction with --error-unmatch. It had logic to avoid
showing the same entry (one came from the original index, another from the
overlayed tree) twice so that it works with -c (i.e. "show-cached"), but
otherwise it was not designed to work with the flags such as -m, -d, etc.
This teaches the same logic to cover the codepath for -m and -d.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When the "git status" display code was originally converted
to C, we copied the code from ls-files to discover whether a
pathname returned by read_directory was an "other", or
untracked, file.
Much later, 5698454e updated the code in ls-files to handle
some new cases caused by gitlinks. This left the code in
wt-status.c broken: it would display submodule directories
as untracked directories. Nobody noticed until now, however,
because unless status.showUntrackedFiles was set to "all",
submodule directories were not actually reported by
read_directory. So the bug was only triggered in the
presence of a submodule _and_ this config option.
This patch pulls the ls-files code into a new function,
cache_name_is_other, and uses it in both places. This should
leave the ls-files functionality the same and fix the bug
in status.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This is a mechanical conversion of all '*.c' files with:
s/((?:die|error|warning)\("git)-(\S+:)/$1 $2/;
The result was manually inspected and no false positive was found.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When you misuse a git command, you are shown the usage string.
But this is currently shown in the dashed form. So if you just
copy what you see, it will not work, when the dashed form
is no longer supported.
This patch makes git commands show the dash-less version.
For shell scripts that do not specify OPTIONS_SPEC, git-sh-setup.sh
generates a dash-less usage string now.
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
git_config() only had a function parameter, but no callback data
parameter. This assumes that all callback functions only modify
global variables.
With this patch, every callback gets a void * parameter, and it is hoped
that this will help the libification effort.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When get_pathspec() was originally made absolute-path capable,
we botched the interface to it, without dying inside the function
when given a path that is outside the work tree, and made it the
responsibility of callers to check the condition in a roundabout
way. This is made unnecessary with the previous patch.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When we process "foo/" entries in gitignore files on a system
that does not have d_type member in "struct dirent", the earlier
implementation ran lstat(2) separately when matching with
entries that came from the command line, in-tree .gitignore
files, and $GIT_DIR/info/excludes file.
This optimizes it by delaying the lstat(2) call until it becomes
absolutely necessary.
The initial idea for this change was by Jeff King, but I
optimized it further to pass pointers to around.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
A pattern "foo/" in the exclude list did not match directory
"foo", but a pattern "foo" did. This attempts to extend the
exclude mechanism so that it would while not matching a regular
file or a symbolic link "foo". In order to differentiate a
directory and non directory, this passes down the type of path
being checked to excluded() function.
A downside is that the recursive directory walk may need to run
lstat(2) more often on systems whose "struct dirent" do not give
the type of the entry; earlier it did not have to do so for an
excluded path, but we now need to figure out if a path is a
directory before deciding to exclude it. This is especially bad
because an idea similar to the earlier CE_UPTODATE optimization
to reduce number of lstat(2) calls would by definition not apply
to the codepaths involved, as (1) directories will not be
registered in the index, and (2) excluded paths will not be in
the index anyway.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The prefix_path() function called from get_pathspec() is
responsible for translating list of user-supplied pathspecs to
list of pathspecs that is relative to the root of the work
tree. When working inside a subdirectory, the user-supplied
pathspecs are taken to be relative to the current subdirectory.
Among special path components in pathspecs, we used to accept
and interpret only "." ("the directory", meaning a no-op) and
".." ("up one level") at the beginning. Everything else was
passed through as-is.
For example, if you are in Documentation/ directory of the
project, you can name Documentation/howto/maintain-git.txt as:
howto/maintain-git.txt
../Documentation/howto/maitain-git.txt
../././Documentation/howto/maitain-git.txt
but not as:
howto/./maintain-git.txt
$(pwd)/howto/maintain-git.txt
This patch updates prefix_path() in several ways:
- If the pathspec is not absolute, prefix (i.e. the current
subdirectory relative to the root of the work tree, with
terminating slash, if not empty) and the pathspec is
concatenated first and used in the next step. Otherwise,
that absolute pathspec is used in the next step.
- Then special path components "." (no-op) and ".." (up one
level) are interpreted to simplify the path. It is an error
to have too many ".." to cause the intermediate result to
step outside of the input to this step.
- If the original pathspec was not absolute, the result from
the previous step is the resulting "sanitized" pathspec.
Otherwise, the result from the previous step is still
absolute, and it is an error if it does not begin with the
directory that corresponds to the root of the work tree. The
directory is stripped away from the result and is returned.
- In any case, the resulting pathspec in the array
get_pathspec() returns omit the ones that caused errors.
With this patch, the last two examples also behave as expected.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This converts the index explicitly on read and write to its on-disk
format, allowing the in-core format to contain more flags, and be
simpler.
In particular, the in-core format is now host-endian (as opposed to the
on-disk one that is network endian in order to be able to be shared
across machines) and as a result we can dispense with all the
htonl/ntohl on accesses to the cache_entry fields.
This will make it easier to make use of various temporary flags that do
not exist in the on-disk format.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This exports three helper functions from ls-files.
* pathspec_match() checks if a given path matches a set of pathspecs
and optionally records which pathspec was used. This function used
to be called "match()" but renamed to be a bit less vague.
* report_path_error() takes a set of pathspecs and the record
pathspec_match() above leaves, and gives error message. This
was split out of the main function of ls-files.
* overlay_tree_on_cache() takes a tree-ish (typically "HEAD")
and overlays it on the current in-core index. By iterating
over the resulting index, the caller can find out the paths
in either the index or the HEAD. This function used to be
called "overlay_tree()" but renamed to be a bit more
descriptive.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This provides a way for scripts to get at the new standard exclude
function.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Mike Hommey <mh@glandium.org>
Acked-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The index cache is not static, growing as new entries are added. If
entries are added after prune_cache is called, cache will no longer
point at the base of the allocation, and realloc will not be happy.
I verified that this was the only place in the current source which
modified any index_state.cache elements aside from the alloc/realloc
calls in read-cache by changing the type of the element to 'struct
cache_entry ** const cache' and recompiling.
A more efficient patch would create a separate 'cache_base' value to
track the allocation and then fix things up when reallocation was
necessary, instead of the brute-force memmove used here.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
* quote_c_style works on a strbuf instead of a wild buffer.
* quote_c_style is now clever enough to not add double quotes if not needed.
* write_name_quoted inherits those advantages, but also take a different
set of arguments. Now instead of asking for quotes or not, you pass a
"terminator". If it's \0 then we assume you don't want to escape, else C
escaping is performed. In any case, the terminator is also appended to the
stream. It also no longer takes the prefix/prefix_len arguments, as it's
seldomly used, and makes some optimizations harder.
* write_name_quotedpfx is created to work like write_name_quoted and take
the prefix/prefix_len arguments.
Thanks to those API changes, diff.c has somehow lost weight, thanks to the
removal of functions that were wrappers around the old write_name_quoted
trying to give it a semantics like the new one, but performing a lot of
allocations for this goal. Now we always write directly to the stream, no
intermediate allocation is performed.
As a side effect of the refactor in builtin-apply.c, the length of the bar
graphs in diffstats are not affected anymore by the fact that the path was
clipped.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
When making a partial commit, git-commit uses git-ls-files with
the --error-unmatch option to expand and sanity check the user
supplied path patterns. When any path pattern does not match
with the paths known to the index, it errors out, in order to
catch a common mistake to say "git commit Makefiel cache.h"
and end up with a commit that touches only cache.h (notice the
misspelled "Makefile"). This detection however does not work
well when the path has already been removed from the index.
If you drop a path from the index and try to commit that
partially, i.e.
$ git rm COPYING
$ git commit -m 'Remove COPYING' COPYING
the command complains because git does not know anything about
COPYING anymore.
This introduces a new option --with-tree to git-ls-files and
uses it in git-commit when we build a temporary index to
write a tree object for the partial commit.
When --with-tree=<tree-ish> option is specified, names from the
given tree are added to the set of names the index knows about,
so we can treat COPYING file in the example as known.
Of course, there is no reason to use "git rm" and git-aware
people have long time done:
$ rm COPYING
$ git commit -m 'Remove COPYING' COPYING
which works just fine. But this caused a constant confusion.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When making a partial commit, git-commit uses git-ls-files with
the --error-unmatch option to expand and sanity check the user
supplied path patterns. When any path pattern does not match
with the paths known to the index, it errors out, in order to
catch a common mistake to say "git commit Makefiel cache.h"
and end up with a commit that touches only cache.h (notice the
misspelled "Makefile"). This detection however does not work
well when the path has already been removed from the index.
If you drop a path from the index and try to commit that
partially, i.e.
$ git rm COPYING
$ git commit -m 'Remove COPYING' COPYING
the command complains because git does not know anything about
COPYING anymore.
This introduces a new option --with-tree to git-ls-files and
uses it in git-commit when we build a temporary index to
write a tree object for the partial commit.
When --with-tree=<tree-ish> option is specified, names from the
given tree are added to the set of names the index knows about,
so we can treat COPYING file in the example as known.
Of course, there is no reason to use "git rm" and git-aware
people have long time done:
$ rm COPYING
$ git commit -m 'Remove COPYING' COPYING
which works just fine. But this caused a constant confusion.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This is most visible when you do "git commit Makefile Makefile"; it
may be a stupid request, but that is not a reason to fail the command.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The old version of work-tree support was an unholy mess, barely readable,
and not to the point.
For example, why do you have to provide a worktree, when it is not used?
As in "git status". Now it works.
Another riddle was: if you can have work trees inside the git dir, why
are some programs complaining that they need a work tree?
IOW it is allowed to call
$ git --git-dir=../ --work-tree=. bla
when you really want to. In this case, you are both in the git directory
and in the working tree. So, programs have to actually test for the right
thing, namely if they are inside a working tree, and not if they are
inside a git directory.
Also, GIT_DIR=../.git should behave the same as if no GIT_DIR was
specified, unless there is a repository in the current working directory.
It does now.
The logic to determine if a repository is bare, or has a work tree
(tertium non datur), is this:
--work-tree=bla overrides GIT_WORK_TREE, which overrides core.bare = true,
which overrides core.worktree, which overrides GIT_DIR/.. when GIT_DIR
ends in /.git, which overrides the directory in which .git/ was found.
In related news, a long standing bug was fixed: when in .git/bla/x.git/,
which is a bare repository, git formerly assumed ../.. to be the
appropriate git dir. This problem was reported by Shawn Pearce to have
caused much pain, where a colleague mistakenly ran "git init" in "/" a
long time ago, and bare repositories just would not work.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This uses "git-apply --whitespace=strip" to fix whitespace errors that have
crept in to our source files over time. There are a few files that need
to have trailing whitespaces (most notably, test vectors). The results
still passes the test, and build result in Documentation/ area is unchanged.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Up to now to check for a working tree this was used:
!is_bare && !inside_git_dir
(the check for bare is redundant because is_inside_git_dir
returned already 1 for bare repositories).
Now the check is:
inside_work_tree && !inside_git_dir
Signed-off-by: Matthias Lederhofer <matled@gmx.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Since "git ls-files" doesn't really pass down any details on what it
really wants done to the directory walking code, the directory walking
code doesn't really know whether the caller wants to know about gitlink
directories, or whether it wants to just know about ignored files.
So the directory walking code will return those gitlink directories unless
the caller has explicitly told it not to ("dir->show_other_directories"
tells the directory walker to only show "other" directories).
This kind of confuses "git ls-files -o", because
- it didn't really expect to see entries listed that were already in the
index, unless they were unmerged, and would die on that unexpected
setup, rather than just "continue".
- it didn't know how to match directory entries with the final "/"
This trivial change updates the "show_other_files()" function to handle
both of these issues gracefully. There really was no reason to die, when
the obviously correct thing for the function was to just ignore files it
already knew about (that's what "other" means here!).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
The way things are set up, you can now pass a "pathspec" to the
"read_directory()" function. If you pass NULL, it acts exactly
like it used to do (read everything). If you pass a non-NULL
pointer, it will simplify it into a "these are the prefixes
without any special characters", and stop any readdir() early if
the path in question doesn't match any of the prefixes.
NOTE! This does *not* obviate the need for the caller to do the *exact*
pathspec match later. It's a first-level filter on "read_directory()", but
it does not do the full pathspec thing. Maybe it should. But in the
meantime, builtin-add.c really does need to do first
read_directory(dir, .., pathspec);
if (pathspec)
prune_directory(dir, pathspec, baselen);
ie the "prune_directory()" part will do the *exact* pathspec pruning,
while the "read_directory()" will use the pathspec just to do some quick
high-level pruning of the directories it will recurse into.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This mechanically converts strncmp() to use prefixcmp(), but only when
the parameters match specific patterns, so that they can be verified
easily. Leftover from this will be fixed in a separate step, including
idiotic conversions like
if (!strncmp("foo", arg, 3))
=>
if (!(-prefixcmp(arg, "foo")))
This was done by using this script in px.perl
#!/usr/bin/perl -i.bak -p
if (/strncmp\(([^,]+), "([^\\"]*)", (\d+)\)/ && (length($2) == $3)) {
s|strncmp\(([^,]+), "([^\\"]*)", (\d+)\)|prefixcmp($1, "$2")|;
}
if (/strncmp\("([^\\"]*)", ([^,]+), (\d+)\)/ && (length($1) == $3)) {
s|strncmp\("([^\\"]*)", ([^,]+), (\d+)\)|(-prefixcmp($2, "$1"))|;
}
and running:
$ git grep -l strncmp -- '*.c' | xargs perl px.perl
Signed-off-by: Junio C Hamano <junkio@cox.net>
This patch helps when you accidentally run something like git-clean
in the git directory instead of the work tree.
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This is a mechanical clean-up of the way *.c files include
system header files.
(1) sources under compat/, platform sha-1 implementations, and
xdelta code are exempt from the following rules;
(2) the first #include must be "git-compat-util.h" or one of
our own header file that includes it first (e.g. config.h,
builtin.h, pkt-line.h);
(3) system headers that are included in "git-compat-util.h"
need not be included in individual C source files.
(4) "git-compat-util.h" does not have to include subsystem
specific header files (e.g. expat.h).
Signed-off-by: Junio C Hamano <junkio@cox.net>
Without this patch "git commit file.c file2.c" produces the not
so stellar output:
error: pathspec 'file.c' did not match any.
error: pathspec 'file2.c' did not match any.
With this patch, the output is changed to:
error: pathspec 'file.c' did not match any file(s) known to git.
error: pathspec 'file2.c' did not match any file(s) known to git.
Did you forget to 'git add'?
Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
[jc: I needed to hand merge the changes to the updated codebase,
so the result needs to be checked.]
Signed-off-by: David Rientjes <rientjes@google.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
git-ls-files was broken by the setup_git_directory() calling changes,
because I had missed the fact that the "prefix" variable in that file was
static to the whole file, and unlike git-ls-tree (where I had fixed it
up), it ended up using two different variables with the same name
depending on what the scoping happened to be.
This fixes it up properly (by just removing the static variable, and
passing the automatic one around properly), and git-ls-files should work
again.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This changes the calling convention of built-in commands and
passes the "prefix" (i.e. pathname of $PWD relative to the
project root level) down to them.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This moves the code to add the per-directory ignore files for the base
directory into the library routine.
That not only allows us to turn the function push_exclude_per_directory()
static again, it also simplifies the library interface a lot (the caller
no longer needs to worry about any of the per-directory exclude files at
all).
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This moves the core directory traversal and filename exclusion logic
into the general git library, making it available for other users
directly.
If we ever want to do "git commit" or "git add" as a built-in (and we
do), we want to be able to handle most of git-ls-files as a library.
NOTE! Not all of git-ls-files is libified by this. The index matching
and pathspec prefix calculation is still in ls-files.c, but this is a
big part of it.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Without the --directory flag, git-ls-files wouldn't ever list directories,
producing no output for empty directories, which is good since they cannot
be added and they bear no content, even untracked one (if Git ever starts
tracking directories on their own, this should obviously change since the
content notion will change).
With the --directory flag however, git-ls-files would list even empty
directories. This may be good in some situations but sometimes you want to
prevent that. This patch adds a --no-empty-directory option which makes
git-ls-files omit empty directories.
Signed-off-by: Petr Baudis <pasky@suse.cz>
Without this patch, the last line of an exclude file is silently
ignored if it doesn't end with a newline.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Make git-ls-files --others --ignored recurse into non-excluded
subdirectories.
Typically when asking git-ls-files to display all files which are
ignored by one or more exclude patterns one would want it to recurse
into subdirectories which are not themselves excluded to see if
there are any excluded files contained within those subdirectories.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Earlier patch mistakenly used prefix_len when it meant
prefix_offset. The latter is to strip the leading directories
when run from a subdirectory.
Signed-off-by: Junio C Hamano <junkio@cox.net>
When you say "git commit Documentaiton" to make partial commit
for the files only in that directory, we did not detect that as
a misspelled pathname and attempted to commit index without
change. If nothing matched, there is no harm done, but if the
index gets modified otherwise by having another valid pathspec
or after an explicit update-index, a user will not notice
without paying attention to the "git status" preview.
This introduces --error-unmatch option to ls-files, and uses it
to detect this common user error.
Signed-off-by: Junio C Hamano <junkio@cox.net>
To preserve compatibility with scripts that expect uppercase
letters to be shown, do not make '-t' to unconditionally show
the valid bit. Introduce '-v' option for that.
Signed-off-by: Junio C Hamano <junkio@cox.net>
When git-ls-files -o --exclude-per-directory=.gitignore is run
from a subdirectory, it did not read from .gitignore from its
parent directory. Reading from them makes output from these two
commands consistent:
$ git ls-files -o --exclude-per-directory=.gitignore Documentation
$ cd Documentation &&
git ls-files -o --exclude-per-directory=.gitignore
Signed-off-by: Junio C Hamano <junkio@cox.net>
This is not really part of the proposed updates for CE_VALID,
but with this change, ls-files -t shows CE_VALID paths with
lowercase tag letters instead of the usual uppercase. Useful
for checking out what is going on.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This adds a trailing slash to directory names in the output
when "--others --directory" option shows only untracked
directories and not their contents, to make them stand out.
Signed-off-by: Junio C Hamano <junkio@cox.net>
When both howto-index.sh and howto/make-dist.txt exist under
Documentation/ directory, dir_exists() mistakenly checked it
without the trailing slash to see if there was something under
Documentation/howto directory, and did not realize there was,
because '-' sorts earlier than '/' and cache_name_pos() finds
howto-index.sh, which is not under howto/ directory. This
caused --others --directory to show it which was incorrect.
Check the directory name with the trailing slash, because having
an entry that has such as a prefix is what we are looking for.
Signed-off-by: Junio C Hamano <junkio@cox.net>