Skip to content

Commit

Permalink
Merge branch 'jl/submodule-mv'
Browse files Browse the repository at this point in the history
"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
  ...
  • Loading branch information
gitster committed Sep 9, 2013
2 parents de9a253 + 95c1641 commit b02f5ae
Show file tree
Hide file tree
Showing 62 changed files with 1,891 additions and 881 deletions.
10 changes: 9 additions & 1 deletion Documentation/git-mv.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ SYNOPSIS

DESCRIPTION
-----------
This script is used to move or rename a file, directory or symlink.
Move or rename a file, directory or symlink.

git mv [-v] [-f] [-n] [-k] <source> <destination>
git mv [-v] [-f] [-n] [-k] <source> ... <destination directory>
Expand Down Expand Up @@ -44,6 +44,14 @@ OPTIONS
--verbose::
Report the names of files as they are moved.

SUBMODULES
----------
Moving a submodule using a gitfile (which means they were cloned
with a Git version 1.7.8 or newer) will update the gitfile and
core.worktree setting to make the submodule work in the new location.
It also will attempt to update the submodule.<name>.path setting in
the linkgit:gitmodules[5] file and stage that file (unless -n is used).

GIT
---
Part of the linkgit:git[1] suite
8 changes: 5 additions & 3 deletions Documentation/git-rm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,16 @@ use the following command:
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
----------------

Submodules
~~~~~~~~~~
SUBMODULES
----------
Only submodules using a gitfile (which means they were cloned
with a Git version 1.7.8 or newer) will be removed from the work
tree, as their repository lives inside the .git directory of the
superproject. If a submodule (or one of those nested inside it)
still uses a .git directory, `git rm` will fail - no matter if forced
or not - to protect the submodule's history.
or not - to protect the submodule's history. If it exists the
submodule.<name> section in the linkgit:gitmodules[5] file will also
be removed and that file will be staged (unless --cached or -n are used).

A submodule is considered up-to-date when the HEAD is the same as
recorded in the index, no tracked files are modified and no untracked
Expand Down
31 changes: 29 additions & 2 deletions Documentation/git.txt
Original file line number Diff line number Diff line change
Expand Up @@ -457,10 +457,25 @@ help ...`.
linkgit:git-replace[1] for more information.

--literal-pathspecs::
Treat pathspecs literally, rather than as glob patterns. This is
equivalent to setting the `GIT_LITERAL_PATHSPECS` environment
Treat pathspecs literally (i.e. no globbing, no pathspec magic).
This is equivalent to setting the `GIT_LITERAL_PATHSPECS` environment
variable to `1`.

--glob-pathspecs:
Add "glob" magic to all pathspec. This is equivalent to setting
the `GIT_GLOB_PATHSPECS` environment variable to `1`. Disabling
globbing on individual pathspecs can be done using pathspec
magic ":(literal)"

--noglob-pathspecs:
Add "literal" magic to all pathspec. This is equivalent to setting
the `GIT_NOGLOB_PATHSPECS` environment variable to `1`. Enabling
globbing on individual pathspecs can be done using pathspec
magic ":(glob)"

--icase-pathspecs:
Add "icase" magic to all pathspec. This is equivalent to setting
the `GIT_ICASE_PATHSPECS` environment variable to `1`.

GIT COMMANDS
------------
Expand Down Expand Up @@ -867,6 +882,18 @@ GIT_LITERAL_PATHSPECS::
literal paths to Git (e.g., paths previously given to you by
`git ls-tree`, `--raw` diff output, etc).

GIT_GLOB_PATHSPECS::
Setting this variable to `1` will cause Git to treat all
pathspecs as glob patterns (aka "glob" magic).

GIT_NOGLOB_PATHSPECS::
Setting this variable to `1` will cause Git to treat all
pathspecs as literal (aka "literal" magic).

GIT_ICASE_PATHSPECS::
Setting this variable to `1` will cause Git to treat all
pathspecs as case-insensitive.


Discussion[[Discussion]]
------------------------
Expand Down
52 changes: 48 additions & 4 deletions Documentation/glossary-content.txt
Original file line number Diff line number Diff line change
Expand Up @@ -322,10 +322,54 @@ and a close parentheses `)`, and the remainder is the pattern to match
against the path.
+
The "magic signature" consists of an ASCII symbol that is not
alphanumeric. Currently only the slash `/` is recognized as a
"magic signature": it makes the pattern match from the root of
the working tree, even when you are running the command from
inside a subdirectory.
alphanumeric.
+
--
top `/`;;
The magic word `top` (mnemonic: `/`) makes the pattern match
from the root of the working tree, even when you are running
the command from inside a subdirectory.

literal;;
Wildcards in the pattern such as `*` or `?` are treated
as literal characters.

icase;;
Case insensitive match.

glob;;
Git treats the pattern as a shell glob suitable for
consumption by fnmatch(3) with the FNM_PATHNAME flag:
wildcards in the pattern will not match a / in the pathname.
For example, "Documentation/{asterisk}.html" matches
"Documentation/git.html" but not "Documentation/ppc/ppc.html"
or "tools/perf/Documentation/perf.html".
+
Two consecutive asterisks ("`**`") in patterns matched against
full pathname may have special meaning:

- A leading "`**`" followed by a slash means match in all
directories. For example, "`**/foo`" matches file or directory
"`foo`" anywhere, the same as pattern "`foo`". "**/foo/bar"
matches file or directory "`bar`" anywhere that is directly
under directory "`foo`".

- A trailing "/**" matches everything inside. For example,
"abc/**" matches all files inside directory "abc", relative
to the location of the `.gitignore` file, with infinite depth.

- A slash followed by two consecutive asterisks then a slash
matches zero or more directories. For example, "`a/**/b`"
matches "`a/b`", "`a/x/b`", "`a/x/y/b`" and so on.

- Other consecutive asterisks are considered invalid.
+
Glob magic is incompatible with literal magic.
--
+
Currently only the slash `/` is recognized as the "magic signature",
but it is envisioned that we will support more types of magic in later
versions of Git.
+
A pathspec with only a colon means "there is no pathspec". This form
should not be combined with other pathspec.
Expand Down
38 changes: 37 additions & 1 deletion Documentation/technical/api-setup.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,42 @@ Talk about
* is_inside_git_dir()
* is_inside_work_tree()
* setup_work_tree()
* get_pathspec()

(Dscho)

Pathspec
--------

See glossary-context.txt for the syntax of pathspec. In memory, a
pathspec set is represented by "struct pathspec" and is prepared by
parse_pathspec(). This function takes several arguments:

- magic_mask specifies what features that are NOT supported by the
following code. If a user attempts to use such a feature,
parse_pathspec() can reject it early.

- flags specifies other things that the caller wants parse_pathspec to
perform.

- prefix and args come from cmd_* functions

get_pathspec() is obsolete and should never be used in new code.

parse_pathspec() helps catch unsupported features and reject them
politely. At a lower level, different pathspec-related functions may
not support the same set of features. Such pathspec-sensitive
functions are guarded with GUARD_PATHSPEC(), which will die in an
unfriendly way when an unsupported feature is requested.

The command designers are supposed to make sure that GUARD_PATHSPEC()
never dies. They have to make sure all unsupported features are caught
by parse_pathspec(), not by GUARD_PATHSPEC. grepping GUARD_PATHSPEC()
should give the designers all pathspec-sensitive codepaths and what
features they support.

A similar process is applied when a new pathspec magic is added. The
designer lifts the GUARD_PATHSPEC restriction in the functions that
support the new magic. At the same time (s)he has to make sure this
new feature will be caught at parse_pathspec() in commands that cannot
handle the new magic in some cases. grepping parse_pathspec() should
help.
18 changes: 11 additions & 7 deletions archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ int write_archive_entries(struct archiver_args *args,
struct archiver_context context;
struct unpack_trees_options opts;
struct tree_desc t;
struct pathspec pathspec;
int err;

if (args->baselen > 0 && args->base[args->baselen - 1] == '/') {
Expand Down Expand Up @@ -186,10 +185,8 @@ int write_archive_entries(struct archiver_args *args,
git_attr_set_direction(GIT_ATTR_INDEX, &the_index);
}

init_pathspec(&pathspec, args->pathspec);
err = read_tree_recursive(args->tree, "", 0, 0, &pathspec,
err = read_tree_recursive(args->tree, "", 0, 0, &args->pathspec,
write_archive_entry, &context);
free_pathspec(&pathspec);
if (err == READ_TREE_RECURSIVE)
err = 0;
return err;
Expand Down Expand Up @@ -222,7 +219,7 @@ static int path_exists(struct tree *tree, const char *path)
struct pathspec pathspec;
int ret;

init_pathspec(&pathspec, paths);
parse_pathspec(&pathspec, 0, 0, "", paths);
ret = read_tree_recursive(tree, "", 0, 0, &pathspec, reject_entry, NULL);
free_pathspec(&pathspec);
return ret != 0;
Expand All @@ -231,11 +228,18 @@ static int path_exists(struct tree *tree, const char *path)
static void parse_pathspec_arg(const char **pathspec,
struct archiver_args *ar_args)
{
ar_args->pathspec = pathspec = get_pathspec("", pathspec);
/*
* must be consistent with parse_pathspec in path_exists()
* Also if pathspec patterns are dependent, we're in big
* trouble as we test each one separately
*/
parse_pathspec(&ar_args->pathspec, 0,
PATHSPEC_PREFER_FULL,
"", pathspec);
if (pathspec) {
while (*pathspec) {
if (**pathspec && !path_exists(ar_args->tree, *pathspec))
die("path not found: %s", *pathspec);
die(_("pathspec '%s' did not match any files"), *pathspec);
pathspec++;
}
}
Expand Down
4 changes: 3 additions & 1 deletion archive.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
#ifndef ARCHIVE_H
#define ARCHIVE_H

#include "pathspec.h"

struct archiver_args {
const char *base;
size_t baselen;
struct tree *tree;
const unsigned char *commit_sha1;
const struct commit *commit;
time_t time;
const char **pathspec;
struct pathspec pathspec;
unsigned int verbose : 1;
unsigned int worktree_attributes : 1;
unsigned int convert : 1;
Expand Down
Loading

0 comments on commit b02f5ae

Please sign in to comment.