Commit graph

215 commits

Author SHA1 Message Date
Junio C Hamano 949d16795c Merge branch 'nd/dwim-wildcards-as-pathspecs'
A heuristic to help the "git <cmd> <revs> <pathspec>" command line
convention to catch mistyped paths is to make sure all the non-rev
parameters in the later part of the command line are names of the
files in the working tree, but that means "git grep $str -- \*.c"
must always be disambiguated with "--", because nobody sane will
create a file whose name literally is asterisk-dot-see.  Loosen the
heuristic to declare that with a wildcard string the user likely
meant to give us a pathspec.

* nd/dwim-wildcards-as-pathspecs:
  pathspec: avoid the need of "--" when wildcard is used
2015-05-19 13:17:58 -07:00
Duy Nguyen 28fcc0b71a pathspec: avoid the need of "--" when wildcard is used
When "--" is lacking from the command line and a command can take
both revs and paths, the idea is if an argument can be seen as both
an extended SHA-1 and a path, then "--" is required or git refuses
to continue. It's currently implemented as:

 (1) if an argument is rev, then it must not exist in worktree

 (2) else, it must exist in worktree

 (3) else, "--" is required.

These rules work for literal paths, but when non-literal pathspec is
involved, it almost always requires the user to add "--" because it
fails (2) and (1) is really rarely met (take "*.c" for example, (1)
is met if there is a ref named "*.c").

This patch modifies the rules a bit by considering any valid (*)
wildcard pathspec "exist in worktree". The rules become:

 (1) if an arg is a rev, then it must either exist in worktree or
     not be a valid wildcard pathspec.

 (2) else, it either exists in worktree or is a wildcard pathspec

 (3) else, "--" is required.

With the new rules, "--" is not needed most of the time when
wildcard pathspec is involved.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-05-03 11:40:13 -07:00
Nguyễn Thái Ngọc Duy 23af91d102 prune: strategies for linked checkouts
(alias R=$GIT_COMMON_DIR/worktrees/<id>)

 - linked checkouts are supposed to keep its location in $R/gitdir up
   to date. The use case is auto fixup after a manual checkout move.

 - linked checkouts are supposed to update mtime of $R/gitdir. If
   $R/gitdir's mtime is older than a limit, and it points to nowhere,
   worktrees/<id> is to be pruned.

 - If $R/locked exists, worktrees/<id> is not supposed to be pruned. If
   $R/locked exists and $R/gitdir's mtime is older than a really long
   limit, warn about old unused repo.

 - "git checkout --to" is supposed to make a hard link named $R/link
   pointing to the .git file on supported file systems to help detect
   the user manually deleting the checkout. If $R/link exists and its
   link count is greated than 1, the repo is kept.

Helped-by: Marc Branchaud <marcnarc@xiplink.com>
Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Helped-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Marc Branchaud <marcnarc@xiplink.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-01 11:00:17 -08:00
Nguyễn Thái Ngọc Duy 31e26ebcb5 setup.c: support multi-checkout repo setup
The repo setup procedure is updated to detect $GIT_DIR/commondir and
set $GIT_COMMON_DIR properly.

The core.worktree is ignored when $GIT_COMMON_DIR is set. This is
because the config file is shared in multi-checkout setup, but
checkout directories _are_ different. Making core.worktree effective
in all checkouts mean it's back to a single checkout.

Helped-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-01 11:00:15 -08:00
Nguyễn Thái Ngọc Duy e61a509a49 setup.c: detect $GIT_COMMON_DIR check_repository_format_gently()
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-01 11:00:15 -08:00
Nguyễn Thái Ngọc Duy 7d0fb0da95 setup.c: convert check_repository_format_gently to use strbuf
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-01 11:00:15 -08:00
Nguyễn Thái Ngọc Duy 4dc4e1457e setup.c: detect $GIT_COMMON_DIR in is_git_directory()
If the file "$GIT_DIR/commondir" exists, it contains the value of
$GIT_COMMON_DIR.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-01 11:00:14 -08:00
Nguyễn Thái Ngọc Duy 1d186b6f35 setup.c: convert is_git_directory() to use strbuf
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-01 11:00:14 -08:00
Junio C Hamano f655651e09 Merge branch 'rs/strbuf-getcwd'
Reduce the use of fixed sized buffer passed to getcwd() calls
by introducing xgetcwd() helper.

* rs/strbuf-getcwd:
  use strbuf_add_absolute_path() to add absolute paths
  abspath: convert absolute_path() to strbuf
  use xgetcwd() to set $GIT_DIR
  use xgetcwd() to get the current directory or die
  wrapper: add xgetcwd()
  abspath: convert real_path_internal() to strbuf
  abspath: use strbuf_getcwd() to remember original working directory
  setup: convert setup_git_directory_gently_1 et al. to strbuf
  unix-sockets: use strbuf_getcwd()
  strbuf: add strbuf_getcwd()
2014-09-02 13:28:44 -07:00
René Scharfe 56b9f6e738 use xgetcwd() to get the current directory or die
Convert several calls of getcwd() and die() to use xgetcwd() instead.
This way we get rid of fixed-size buffers (which can be too small
depending on the used file system) and gain consistent error messages.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-08-26 11:06:06 -07:00
René Scharfe 7333ed1788 setup: convert setup_git_directory_gently_1 et al. to strbuf
Convert setup_git_directory_gently_1() and its helper functions
setup_explicit_git_dir(), setup_discovered_git_dir() and
setup_bare_git_dir() to use a struct strbuf to hold the current working
directory.  Replacing the PATH_MAX-sized buffer used before removes a
path length limition on some file systems.  The functions are converted
all in one go because they all read and write the variable cwd.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-08-26 11:06:04 -07:00
Tanay Abhra 3c8687a73e add config_set API for caching config-like files
Currently `git_config()` uses a callback mechanism and file rereads for
config values. Due to this approach, it is not uncommon for the config
files to be parsed several times during the run of a git program, with
different callbacks picking out different variables useful to themselves.

Add a `config_set`, that can be used to construct an in-memory cache for
config-like files that the caller specifies (i.e., files like `.gitmodules`,
`~/.gitconfig` etc.). Add two external functions `git_configset_get_value`
and `git_configset_get_value_multi` for querying from the config sets.
`git_configset_get_value` follows `last one wins` semantic (i.e. if there
are multiple matches for the queried key in the files of the configset the
value returned will be the last entry in `value_list`).
`git_configset_get_value_multi` returns a list of values sorted in order of
increasing priority (i.e. last match will be at the end of the list). Add
type specific query functions like `git_configset_get_bool` and similar.

Add a default `config_set`, `the_config_set` to cache all key-value pairs
read from usual config files (repo specific .git/config, user wide
~/.gitconfig, XDG config and the global /etc/gitconfig). `the_config_set`
is populated using `git_config()`.

Add two external functions `git_config_get_value` and
`git_config_get_value_multi` for querying in a non-callback manner from
`the_config_set`. Also, add type specific query functions that are
implemented as a thin wrapper around the `config_set` API.

Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Tanay Abhra <tanayabh@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-29 14:29:56 -07:00
Junio C Hamano 648d9c1827 Merge branch 'mw/symlinks'
A finishing touch fix to a new change already in 'master'.

* mw/symlinks:
  setup: fix windows path buffer over-stepping
2014-05-02 13:11:03 -07:00
Martin Erik Werner 6127ff63cf 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>
2014-04-24 13:46:13 -07:00
Junio C Hamano 4c4ac4db2c Merge branch 'nd/daemonize-gc'
Allow running "gc --auto" in the background.

* nd/daemonize-gc:
  gc: config option for running --auto in background
  daemon: move daemonize() to libgit.a
2014-03-05 15:06:39 -08:00
Junio C Hamano 8a342058f6 Merge branch 'mw/symlinks'
All subcommands that take pathspecs mishandled an in-tree symbolic
link when given it as a full path from the root (which arguably is
a sick way to use pathspecs).  "git ls-files -s $(pwd)/RelNotes" in
our tree is an easy reproduction recipe.

* mw/symlinks:
  setup: don't dereference in-tree symlinks for absolute paths
  setup: add abspath_part_inside_repo() function
  t0060: add tests for prefix_path when path begins with work tree
  t0060: add test for prefix_path when path == work tree
  t0060: add test for prefix_path on symlinks via absolute paths
  t3004: add test for ls-files on symlinks via absolute paths
2014-02-27 14:01:37 -08:00
Nguyễn Thái Ngọc Duy de0957ce2e daemon: move daemonize() to libgit.a
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-02-10 10:46:35 -08:00
Martin Erik Werner 655ee9ea3e setup: don't dereference in-tree symlinks for absolute paths
The prefix_path_gently() function currently applies real_path to
everything if given an absolute path, dereferencing symlinks both
outside and inside the work tree.

This causes most high-level functions to misbehave when acting on
symlinks given via absolute paths. For example

	$ git add /dir/repo/symlink

attempts to add the target of the symlink rather than the symlink
itself, which is usually not what the user intends to do.

In order to manipulate symlinks in the work tree using absolute paths,
symlinks should only be dereferenced outside the work tree.

Modify the prefix_path_gently() to first normalize the path in order to
make sure path levels are separated by '/', then pass the result to
'abspath_part_inside_repo' to find the part inside the work tree
(without dereferencing any symlinks inside the work tree).

For absolute paths, prefix_path_gently() did not, nor does now do, any
actual prefixing, hence the result from abspath_part_in_repo() is
returned as-is.

Fixes t0060-82 and t3004-5.

Signed-off-by: Martin Erik Werner <martinerikwerner@gmail.com>
Reviewed-by: Duy Nguyen <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-02-04 12:08:49 -08:00
Martin Erik Werner ddc2a62815 setup: add abspath_part_inside_repo() function
In order to extract the part of an absolute path which lies inside the
repo, it is not possible to directly use real_path, since that would
dereference symlinks both outside and inside the work tree.

Add an abspath_part_inside_repo() function which first checks if the
work tree is already the prefix, then incrementally checks each path
level by temporarily NUL-terminating at each '/' and comparing against
the work tree path. If a match is found, it overwrites the input path
with the remainder past the work tree (which will be the part inside the
work tree).

This function is currently only intended for use in
'prefix_path_gently'.

Signed-off-by: Martin Erik Werner <martinerikwerner@gmail.com>
Reviewed-by: Duy Nguyen <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-02-04 12:08:49 -08:00
Christian Couder 5955654823 replace {pre,suf}fixcmp() with {starts,ends}_with()
Leaving only the function definitions and declarations so that any
new topic in flight can still make use of the old functions, replace
existing uses of the prefixcmp() and suffixcmp() with new API
functions.

The change can be recreated by mechanically applying this:

    $ git grep -l -e prefixcmp -e suffixcmp -- \*.c |
      grep -v strbuf\\.c |
      xargs perl -pi -e '
        s|!prefixcmp\(|starts_with\(|g;
        s|prefixcmp\(|!starts_with\(|g;
        s|!suffixcmp\(|ends_with\(|g;
        s|suffixcmp\(|!ends_with\(|g;
      '

on the result of preparatory changes in this series.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-12-05 14:13:21 -08:00
Felipe Contreras abf03eeb8e setup: trivial style fixes
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-10-31 13:48:32 -07:00
Junio C Hamano e22c1c7f19 Merge branch 'jx/relative-path-regression-fix'
* jx/relative-path-regression-fix:
  Use simpler relative_path when set_git_dir
  relative_path should honor dos-drive-prefix
  test: use unambigous leading path (/foo) for MSYS
2013-10-28 10:42:30 -07:00
Jiang Xin 41894ae3a3 Use simpler relative_path when set_git_dir
Using a relative_path as git_dir first appears in v1.5.6-1-g044bbbc.
It will make git_dir shorter only if git_dir is inside work_tree,
and this will increase performance. But my last refactor effort on
relative_path function (commit v1.8.3-rc2-12-ge02ca72) changed that.
Always use relative_path as git_dir may bring troubles like
$gmane/234434.

Because new relative_path is a combination of original relative_path
from path.c and original path_relative from quote.c, so in order to
restore the origin implementation, save the original relative_path
as remove_leading_path, and call it in setup.c.

Suggested-by: Karsten Blees <karsten.blees@gmail.com>
Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
2013-10-14 07:00:33 -07:00
Junio C Hamano b02f5aeda6 Merge branch 'jl/submodule-mv'
"git mv A B" when moving a submodule A does "the right thing",
inclusing relocating its working tree and adjusting the paths in
the .gitmodules file.

* jl/submodule-mv: (53 commits)
  rm: delete .gitmodules entry of submodules removed from the work tree
  mv: update the path entry in .gitmodules for moved submodules
  submodule.c: add .gitmodules staging helper functions
  mv: move submodules using a gitfile
  mv: move submodules together with their work trees
  rm: do not set a variable twice without intermediate reading.
  t6131 - skip tests if on case-insensitive file system
  parse_pathspec: accept :(icase)path syntax
  pathspec: support :(glob) syntax
  pathspec: make --literal-pathspecs disable pathspec magic
  pathspec: support :(literal) syntax for noglob pathspec
  kill limit_pathspec_to_literal() as it's only used by parse_pathspec()
  parse_pathspec: preserve prefix length via PATHSPEC_PREFIX_ORIGIN
  parse_pathspec: make sure the prefix part is wildcard-free
  rename field "raw" to "_raw" in struct pathspec
  tree-diff: remove the use of pathspec's raw[] in follow-rename codepath
  remove match_pathspec() in favor of match_pathspec_depth()
  remove init_pathspec() in favor of parse_pathspec()
  remove diff_tree_{setup,release}_paths
  convert common_prefix() to use struct pathspec
  ...
2013-09-09 14:36:15 -07:00
Junio C Hamano 988f98f61f Merge branch 'jx/clean-interactive'
Add "interactive" mode to "git clean".

The early part to refactor relative path related helper functions
looked sensible.

* jx/clean-interactive:
  test: run testcases with POSIX absolute paths on Windows
  test: add t7301 for git-clean--interactive
  git-clean: add documentation for interactive git-clean
  git-clean: add ask each interactive action
  git-clean: add select by numbers interactive action
  git-clean: add filter by pattern interactive action
  git-clean: use a git-add-interactive compatible UI
  git-clean: add colors to interactive git-clean
  git-clean: show items of del_list in columns
  git-clean: add support for -i/--interactive
  git-clean: refactor git-clean into two phases
  write_name{_quoted_relative,}(): remove redundant parameters
  quote_path_relative(): remove redundant parameter
  quote.c: substitute path_relative with relative_path
  path.c: refactor relative_path(), not only strip prefix
  test: add test cases for relative_path
2013-07-22 11:24:11 -07:00
Junio C Hamano cb29dfde48 Merge branch 'tr/protect-low-3-fds'
When "git" is spawned in such a way that any of the low 3 file
descriptors is closed, our first open() may yield file descriptor 2,
and writing error message to it would screw things up in a big way.

* tr/protect-low-3-fds:
  git: ensure 0/1/2 are open in main()
  daemon/shell: refactor redirection of 0/1/2 from /dev/null
2013-07-22 11:23:35 -07:00
Thomas Rast 1d999ddd1d daemon/shell: refactor redirection of 0/1/2 from /dev/null
Both daemon.c and shell.c contain logic to open FDs 0/1/2 from
/dev/null if they are not already open.  Move the function in daemon.c
to setup.c and use it in shell.c, too.

While there, remove a 'not' that inverted the meaning of the comment.
The point is indeed to *avoid* messing up.

Signed-off-by: Thomas Rast <trast@inf.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-17 12:50:34 -07:00
Nguyễn Thái Ngọc Duy 645a29c40a parse_pathspec: make sure the prefix part is wildcard-free
Prepending prefix to pathspec is a trick to workaround the fact that
commands can be executed in a subdirectory, but all git commands run
at worktree's root. The prefix part should always be treated as
literal string. Make it so.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-15 10:56:09 -07:00
Nguyễn Thái Ngọc Duy 64acde94ef move struct pathspec and related functions to pathspec.[ch]
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-15 10:56:06 -07:00
Jiang Xin e02ca72f70 path.c: refactor relative_path(), not only strip prefix
Original design of relative_path() is simple, just strip the prefix
(*base) from the absolute path (*abs).

In most cases, we need a real relative path, such as: ../foo,
../../bar.  That's why there is another reimplementation
(path_relative()) in quote.c.

Borrow some codes from path_relative() in quote.c to refactor
relative_path() in path.c, so that it could return real relative
path, and user can reuse this function without reimplementing
his/her own.  The function path_relative() in quote.c will be
substituted, and I would use the new relative_path() function when
implementing the interactive git-clean later.

Different results for relative_path() before and after this refactor:

    abs path  base path  relative (original)  relative (refactor)
    ========  =========  ===================  ===================
    /a/b      /a/b       .                    ./
    /a/b/     /a/b       .                    ./
    /a        /a/b/      /a                   ../
    /         /a/b/      /                    ../../
    /a/c      /a/b/      /a/c                 ../c
    /x/y      /a/b/      /x/y                 ../../x/y

    a/b/      a/b/       .                    ./
    a/b/      a/b        .                    ./
    a         a/b        a                    ../
    x/y       a/b/       x/y                  ../../x/y
    a/c       a/b        a/c                  ../c

    (empty)   (null)     (empty)              ./
    (empty)   (empty)    (empty)              ./
    (empty)   /a/b       (empty)              ./
    (null)    (null)     (null)               ./
    (null)    (empty)    (null)               ./
    (null)    /a/b       (segfault)           ./

You may notice that return value "." has been changed to "./".
It is because:

 * Function quote_path_relative() in quote.c will show the relative
   path as "./" if abs(in) and base(prefix) are the same.

 * Function relative_path() is called only once (in setup.c), and
   it will be OK for the return value as "./" instead of ".".

Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-26 09:59:00 -07:00
Junio C Hamano 51ebd0fe9e Merge branch 'lf/setup-prefix-pathspec'
"git cmd -- ':(top'" was not diagnosed as an invalid syntax, and
instead the parser kept reading beyond the end of the string.

* lf/setup-prefix-pathspec:
  setup.c: check that the pathspec magic ends with ")"
  setup.c: stop prefix_pathspec() from looping past the end of string
2013-03-25 14:01:00 -07:00
Junio C Hamano fb3b7b1f95 Merge branch 'jk/alias-in-bare'
An aliased command spawned from a bare repository that does not say
it is bare with "core.bare = yes" is treated as non-bare by mistake.

* jk/alias-in-bare:
  setup: suppress implicit "." work-tree for bare repos
  environment: add GIT_PREFIX to local_repo_env
  cache.h: drop LOCAL_REPO_ENV_SIZE
2013-03-25 14:00:44 -07:00
Andrew Wong f612a67eac setup.c: check that the pathspec magic ends with ")"
The previous code did not diagnose an incorrectly spelled ":(top"
as an error.

Signed-off-by: Andrew Wong <andrew.kw.w@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-14 09:39:36 -07:00
Andrew Wong 772e47cd67 setup.c: stop prefix_pathspec() from looping past the end of string
The code assumes that the string ends at either `)` or `,`, and does
not handle the case where strcspn() returns length due to end of
string.  So specifying ":(top" as pathspec will cause the loop to go
past the end of string.

Signed-off-by: Andrew Wong <andrew.kw.w@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-14 09:39:09 -07:00
Jeff King 2cd83d10bb setup: suppress implicit "." work-tree for bare repos
If an explicit GIT_DIR is given without a working tree, we
implicitly assume that the current working directory should
be used as the working tree. E.g.,:

  GIT_DIR=/some/repo.git git status

would compare against the cwd.

Unfortunately, we fool this rule for sub-invocations of git
by setting GIT_DIR internally ourselves. For example:

  git init foo
  cd foo/.git
  git status ;# fails, as we expect
  git config alias.st status
  git status ;# does not fail, but should

What happens is that we run setup_git_directory when doing
alias lookup (since we need to see the config), set GIT_DIR
as a result, and then leave GIT_WORK_TREE blank (because we
do not have one). Then when we actually run the status
command, we do setup_git_directory again, which sees our
explicit GIT_DIR and uses the cwd as an implicit worktree.

It's tempting to argue that we should be suppressing that
second invocation of setup_git_directory, as it could use
the values we already found in memory. However, the problem
still exists for sub-processes (e.g., if "git status" were
an external command).

You can see another example with the "--bare" option, which
sets GIT_DIR explicitly. For example:

  git init foo
  cd foo/.git
  git status ;# fails
  git --bare status ;# does NOT fail

We need some way of telling sub-processes "even though
GIT_DIR is set, do not use cwd as an implicit working tree".
We could do it by putting a special token into
GIT_WORK_TREE, but the obvious choice (an empty string) has
some portability problems.

Instead, we add a new boolean variable, GIT_IMPLICIT_WORK_TREE,
which suppresses the use of cwd as a working tree when
GIT_DIR is set. We trigger the new variable when we know we
are in a bare setting.

The variable is left intentionally undocumented, as this is
an internal detail (for now, anyway). If somebody comes up
with a good alternate use for it, and once we are confident
we have shaken any bugs out of it, we can consider promoting
it further.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-08 14:02:40 -08:00
Jeff King a6f7f9a325 environment: add GIT_PREFIX to local_repo_env
The GIT_PREFIX variable is set based on our location within
the working tree. It should therefore be cleared whenever
GIT_WORK_TREE is cleared.

In practice, this doesn't cause any bugs, because none of
the sub-programs we invoke with local_repo_env cleared
actually care about GIT_PREFIX. But this is the right thing
to do, and future proofs us against that assumption changing.

While we're at it, let's define a GIT_PREFIX_ENVIRONMENT
macro; this avoids repetition of the string literal, which
can help catch any spelling mistakes in the code.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-08 14:02:31 -08:00
Junio C Hamano 3e07d2683d Merge branch 'mh/maint-ceil-absolute'
An earlier workaround designed to help people who list logical
directories that will not match what getcwd(3) returns in the
GIT_CEILING_DIRECTORIES had an adverse effect when it is slow to
stat and readlink a directory component of an element listed on it.

* mh/maint-ceil-absolute:
  Provide a mechanism to turn off symlink resolution in ceiling paths
2013-02-27 09:47:28 -08:00
Michael Haggerty 7ec30aaa5b Provide a mechanism to turn off symlink resolution in ceiling paths
Commit 1b77d83cab 'setup_git_directory_gently_1(): resolve symlinks
in ceiling paths' changed the setup code to resolve symlinks in the
entries in GIT_CEILING_DIRECTORIES.  Because those entries are
compared textually to the symlink-resolved current directory, an
entry in GIT_CEILING_DIRECTORIES that contained a symlink would have
no effect.  It was known that this could cause performance problems
if the symlink resolution *itself* touched slow filesystems, but it
was thought that such use cases would be unlikely.  The intention of
the earlier change was to deal with a case when the user has this:

	GIT_CEILING_DIRECTORIES=/home/gitster

but in reality, /home/gitster is a symbolic link to somewhere else,
e.g. /net/machine/home4/gitster. A textual comparison between the
specified value /home/gitster and the location getcwd(3) returns
would not help us, but readlink("/home/gitster") would still be
fast.

After this change was released, Anders Kaseorg <andersk@mit.edu>
reported:

> [...] my computer has been acting so slow when I’m not connected to
> the network.  I put various network filesystem paths in
> $GIT_CEILING_DIRECTORIES, such as
> /afs/athena.mit.edu/user/a/n/andersk (to avoid hitting its parents
> /afs/athena.mit.edu, /afs/athena.mit.edu/user/a, and
> /afs/athena.mit.edu/user/a/n which all live in different AFS
> volumes).  Now when I’m not connected to the network, every
> invocation of Git, including the __git_ps1 in my shell prompt, waits
> for AFS to timeout.

To allow users to work around this problem, give them a mechanism to
turn off symlink resolution in GIT_CEILING_DIRECTORIES entries.  All
the entries that follow an empty entry will not be checked for symbolic
links and used literally in comparison.  E.g. with these:

	GIT_CEILING_DIRECTORIES=:/foo/bar:/xyzzy or
	GIT_CEILING_DIRECTORIES=/foo/bar::/xyzzy

we will not readlink("/xyzzy") because it comes after an empty entry.

With the former (but not with the latter), "/foo/bar" comes after an
empty entry, and we will not readlink it, either.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-02-22 11:37:34 -08:00
Junio C Hamano 7b5196909c Merge branch 'nd/magic-pathspec-from-root'
When giving arguments without "--" disambiguation, object names
that come  earlier on the command line must not be interpretable as
pathspecs and pathspecs that come later on the command line must
not be interpretable as object names.  Tweak the disambiguation
rule so that ":/" (no other string before or after) is always
interpreted as a pathspec, to avoid having to say "git cmd -- :/".

* nd/magic-pathspec-from-root:
  grep: avoid accepting ambiguous revision
  Update :/abc ambiguity check
2013-01-30 08:52:53 -08:00
Junio C Hamano a39b15b4f6 Merge branch 'as/check-ignore'
Add a new command "git check-ignore" for debugging .gitignore
files.

The variable names may want to get cleaned up but that can be done
in-tree.

* as/check-ignore:
  clean.c, ls-files.c: respect encapsulation of exclude_list_groups
  t0008: avoid brace expansion
  add git-check-ignore sub-command
  setup.c: document get_pathspec()
  add.c: extract new die_if_path_beyond_symlink() for reuse
  add.c: extract check_path_for_gitlink() from treat_gitlinks() for reuse
  pathspec.c: rename newly public functions for clarity
  add.c: move pathspec matchers into new pathspec.c for reuse
  add.c: remove unused argument from validate_pathspec()
  dir.c: improve docs for match_pathspec() and match_pathspec_depth()
  dir.c: provide clear_directory() for reclaiming dir_struct memory
  dir.c: keep track of where patterns came from
  dir.c: use a single struct exclude_list per source of excludes

Conflicts:
	builtin/ls-files.c
	dir.c
2013-01-23 21:19:10 -08:00
Nguyễn Thái Ngọc Duy 4db86e8b6e Update :/abc ambiguity check
:/abc may mean two things:

- as a revision, it means the revision that has "abc" in commit
  message.

- as a pathpec, it means "abc" from root.

Currently we see ":/abc" as a rev (most of the time), but never see it
as a pathspec even if "abc" exists and "git log :/abc" will gladly
take ":/abc" as rev even it's ambiguous. This patch makes it:

- ambiguous when "abc" exists on worktree
- a rev if abc does not exist on worktree
- a path if abc is not found in any commits (although better use
  "--" to avoid ambiguation because searching through commit DAG is
  expensive)

A plus from this patch is, because ":/" never matches anything as a
rev, it is never considered a valid rev and because root directory
always exists, ":/" is always unambiguously seen as a pathspec.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-01-21 16:57:24 -08:00
Adam Spiers 1794e6e097 setup.c: document get_pathspec()
Since we have just created a new pathspec-handling library, now is a
good time to add some comments explaining get_pathspec().

Signed-off-by: Adam Spiers <git@adamspiers.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-01-06 14:26:37 -08:00
Michael Haggerty 1b77d83cab setup_git_directory_gently_1(): resolve symlinks in ceiling paths
longest_ancestor_length() relies on a textual comparison of directory
parts to find the part of path that overlaps with one of the paths in
prefix_list.  But this doesn't work if any of the prefixes involves a
symbolic link, because the directories will look different even though
they might logically refer to the same directory.  So canonicalize the
paths listed in GIT_CEILING_DIRECTORIES using real_path_if_valid()
before passing them to longest_ancestor_length().  (Also rename
normalize_ceiling_entry() to canonicalize_ceiling_entry() to reflect
the change.)

path is already in canonical form, so doesn't need to be canonicalized
again.

This fixes some problems with using GIT_CEILING_DIRECTORIES that
contains paths involving symlinks, including t4035 if run with --root
set to a path involving symlinks.

Please note that test t0060 is *not* changed analogously, because that
would make the test suite results dependent on the contents of the
local root directory.  However, real_path() is already tested
independently, and the "ancestor" tests cover the non-normalization
aspects of longest_ancestor_length(), so coverage remains sufficient.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Jeff King <peff@peff.net>
2012-10-29 02:34:58 -04:00
Michael Haggerty 9e2326c7e1 longest_ancestor_length(): require prefix list entries to be normalized
Move the responsibility for normalizing prefixes from
longest_ancestor_length() to its callers. Use slightly different
normalizations at the two callers:

In setup_git_directory_gently_1(), use the old normalization, which
ignores paths that are not usable.  In the next commit we will change
this caller to also resolve symlinks in the paths from
GIT_CEILING_DIRECTORIES as part of the normalization.

In "test-path-utils longest_ancestor_length", use the old
normalization, but die() if any paths are unusable.  Also change t0060
to only pass normalized paths to the test program (no empty entries or
non-absolute paths, strip trailing slashes from the paths, and remove
tests that thereby become redundant).

The point of this change is to reduce the scope of the ancestor_length
tests in t0060 from testing normalization+longest_prefix to testing
only mostly longest_prefix.  This is necessary because when
setup_git_directory_gently_1() starts resolving symlinks as part of
its normalization, it will not be reasonable to do the same in the
test suite, because that would make the test results depend on the
contents of the root directory of the filesystem on which the test is
run.  HOWEVER: under Windows, bash mangles arguments that look like
absolute POSIX paths into DOS paths.  So we have to retain the level
of normalization done by normalize_path_copy() to convert the
bash-mangled DOS paths (which contain backslashes) into paths that use
forward slashes.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Jeff King <peff@peff.net>
2012-10-29 02:34:58 -04:00
Michael Haggerty 31171d9e45 longest_ancestor_length(): take a string_list argument for prefixes
Change longest_ancestor_length() to take the prefixes argument as a
string_list rather than as a colon-separated string.  This will make
it easier for the caller to alter the entries before calling
longest_ancestor_length().

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Jeff King <peff@peff.net>
2012-10-29 02:34:58 -04:00
Junio C Hamano e3f26752b5 Merge branch 'maint-1.7.11' into maint
* maint-1.7.11:
  Almost 1.7.11.6
  gitweb: URL-decode $my_url/$my_uri when stripping PATH_INFO
  rebase -i: use full onto sha1 in reflog
  sh-setup: protect from exported IFS
  receive-pack: do not leak output from auto-gc to standard output
  t/t5400: demonstrate breakage caused by informational message from prune
  setup: clarify error messages for file/revisions ambiguity
  send-email: improve RFC2047 quote parsing
  fsck: detect null sha1 in tree entries
  do not write null sha1s to on-disk index
  diff: do not use null sha1 as a sentinel value
2012-09-10 15:31:06 -07:00
Junio C Hamano 64336ebe34 Merge branch 'mm/die-with-dashdash-help'
When the user gives an argument that can be taken as both a revision
name and a pathname without disambiguating with "--", we used to
give a help message "Use '--' to separate".  The message has been
clarified to show where that '--' goes on the command line.

* mm/die-with-dashdash-help:
  setup: clarify error messages for file/revisions ambiguity
2012-08-22 11:51:53 -07:00
Matthieu Moy 4d4b573977 setup: clarify error messages for file/revisions ambiguity
The previous "Use '--' to separate filenames from revisions" may sound
obvious for an old-time Unix user, but does not make it clear how to use
this '--'. In addition to mentionning this '--', give an idea of what the
new command should look like.

Ideally, we could provide cut-and-paste ready commands based on the
command that just failed, but we have no easy access to argv[] in this
place of the code.

Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-08-03 09:06:30 -07:00
Junio C Hamano 0958a24d73 Merge branch 'jc/sha1-name-more'
Teaches the object name parser things like a "git describe" output
is always a commit object, "A" in "git log A" must be a committish,
and "A" and "B" in "git log A...B" both must be committish, etc., to
prolong the lifetime of abbreviated object names.

* jc/sha1-name-more: (27 commits)
  t1512: match the "other" object names
  t1512: ignore whitespaces in wc -l output
  rev-parse --disambiguate=<prefix>
  rev-parse: A and B in "rev-parse A..B" refer to committish
  reset: the command takes committish
  commit-tree: the command wants a tree and commits
  apply: --build-fake-ancestor expects blobs
  sha1_name.c: add support for disambiguating other types
  revision.c: the "log" family, except for "show", takes committish
  revision.c: allow handle_revision_arg() to take other flags
  sha1_name.c: introduce get_sha1_committish()
  sha1_name.c: teach lookup context to get_sha1_with_context()
  sha1_name.c: many short names can only be committish
  sha1_name.c: get_sha1_1() takes lookup flags
  sha1_name.c: get_describe_name() by definition groks only commits
  sha1_name.c: teach get_short_sha1() a commit-only option
  sha1_name.c: allow get_short_sha1() to take other flags
  get_sha1(): fix error status regression
  sha1_name.c: restructure disambiguation of short names
  sha1_name.c: correct misnamed "canonical" and "res"
  ...
2012-07-22 12:55:07 -07:00
Junio C Hamano 36c5109e4a Merge branch 'th/diff-no-index-fixes' into maint
"git diff --no-index" did not correctly handle relative paths and
did not correctly give exit codes when run under "--quiet" option.

* th/diff-no-index-fixes:
  diff-no-index: exit(1) if 'diff --quiet <repo file> <external file>' finds changes
  diff: handle relative paths in no-index
2012-07-11 12:48:44 -07:00