]> git.scripts.mit.edu Git - git.git/commitdiff
Merge branch 'jl/submodule-mv'
authorJunio C Hamano <gitster@pobox.com>
Mon, 9 Sep 2013 21:36:15 +0000 (14:36 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 9 Sep 2013 21:36:15 +0000 (14:36 -0700)
"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
  ...

38 files changed:
1  2 
Documentation/git.txt
builtin/add.c
builtin/blame.c
builtin/check-ignore.c
builtin/checkout.c
builtin/clean.c
builtin/commit.c
builtin/grep.c
builtin/log.c
builtin/ls-files.c
builtin/ls-tree.c
builtin/mv.c
builtin/reset.c
builtin/rm.c
builtin/update-index.c
cache.h
combine-diff.c
commit.h
diff-lib.c
diff.h
dir.c
git.c
line-log.c
merge-recursive.c
path.c
pathspec.c
read-cache.c
rerere.c
resolve-undo.c
revision.c
setup.c
submodule.c
t/t0008-ignores.sh
t/t7400-submodule-basic.sh
tree-walk.c
tree.c
wt-status.c
wt-status.h

Simple merge
diff --cc builtin/add.c
Simple merge
diff --cc builtin/blame.c
Simple merge
Simple merge
Simple merge
diff --cc builtin/clean.c
index 4b6fd42be7aeae55c71c7b79ee45fb73973ec0d5,d540ca4a0a862ae33222df34bad63d799941774e..615cd57caf1d4cbeafc73e7037bae81a6915df59
  #include "refs.h"
  #include "string-list.h"
  #include "quote.h"
 +#include "column.h"
 +#include "color.h"
+ #include "pathspec.h"
  
  static int force = -1; /* unset */
 +static int interactive;
 +static struct string_list del_list = STRING_LIST_INIT_DUP;
 +static unsigned int colopts;
  
  static const char *const builtin_clean_usage[] = {
 -      N_("git clean [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."),
 +      N_("git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."),
        NULL
  };
  
@@@ -861,15 -149,13 +862,14 @@@ int cmd_clean(int argc, const char **ar
        int dry_run = 0, remove_directories = 0, quiet = 0, ignored = 0;
        int ignored_only = 0, config_set = 0, errors = 0, gone = 1;
        int rm_flags = REMOVE_DIR_KEEP_NESTED_GIT;
 -      struct strbuf directory = STRBUF_INIT;
 +      struct strbuf abs_path = STRBUF_INIT;
        struct dir_struct dir;
-       static const char **pathspec;
+       struct pathspec pathspec;
        struct strbuf buf = STRBUF_INIT;
        struct string_list exclude_list = STRING_LIST_INIT_NODUP;
        struct exclude_list *el;
 +      struct string_list_item *item;
        const char *qname;
-       char *seen = NULL;
        struct option options[] = {
                OPT__QUIET(&quiet, N_("do not print names of files removed")),
                OPT__DRY_RUN(&dry_run, N_("dry run")),
                                continue; /* Yup, this one exists unmerged */
                }
  
 -              /*
 -               * we might have removed this as part of earlier
 -               * recursive directory removal, so lstat() here could
 -               * fail with ENOENT.
 -               */
                if (lstat(ent->name, &st))
 -                      continue;
 +                      die_errno("Cannot lstat '%s'", ent->name);
  
-               if (pathspec) {
-                       memset(seen, 0, argc > 0 ? argc : 1);
-                       matches = match_pathspec(pathspec, ent->name, len,
-                                                0, seen);
-               }
+               if (pathspec.nr)
+                       matches = match_pathspec_depth(&pathspec, ent->name,
+                                                      len, 0, NULL);
  
                if (S_ISDIR(st.st_mode)) {
 -                      strbuf_addstr(&directory, ent->name);
                        if (remove_directories || (matches == MATCHED_EXACTLY)) {
 -                              if (remove_dirs(&directory, prefix, rm_flags, dry_run, quiet, &gone))
 -                                      errors++;
 -                              if (gone && !quiet) {
 -                                      qname = quote_path_relative(directory.buf, directory.len, &buf, prefix);
 -                                      printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname);
 -                              }
 +                              rel = relative_path(ent->name, prefix, &buf);
 +                              string_list_append(&del_list, rel);
                        }
 -                      strbuf_reset(&directory);
                } else {
-                       if (pathspec && !matches)
+                       if (pathspec.nr && !matches)
                                continue;
 -                      res = dry_run ? 0 : unlink(ent->name);
 +                      rel = relative_path(ent->name, prefix, &buf);
 +                      string_list_append(&del_list, rel);
 +              }
 +      }
 +
 +      if (interactive && del_list.nr > 0)
 +              interactive_main_loop();
 +
 +      for_each_string_list_item(item, &del_list) {
 +              struct stat st;
 +
 +              if (prefix)
 +                      strbuf_addstr(&abs_path, prefix);
 +
 +              strbuf_addstr(&abs_path, item->string);
 +
 +              /*
 +               * we might have removed this as part of earlier
 +               * recursive directory removal, so lstat() here could
 +               * fail with ENOENT.
 +               */
 +              if (lstat(abs_path.buf, &st))
 +                      continue;
 +
 +              if (S_ISDIR(st.st_mode)) {
 +                      if (remove_dirs(&abs_path, prefix, rm_flags, dry_run, quiet, &gone))
 +                              errors++;
 +                      if (gone && !quiet) {
 +                              qname = quote_path_relative(item->string, NULL, &buf);
 +                              printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname);
 +                      }
 +              } else {
 +                      res = dry_run ? 0 : unlink(abs_path.buf);
                        if (res) {
 -                              qname = quote_path_relative(ent->name, -1, &buf, prefix);
 +                              qname = quote_path_relative(item->string, NULL, &buf);
                                warning(_(msg_warn_remove_failed), qname);
                                errors++;
                        } else if (!quiet) {
                                printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname);
                        }
                }
 +              strbuf_reset(&abs_path);
        }
-       free(seen);
  
 -      strbuf_release(&directory);
 +      strbuf_release(&abs_path);
 +      strbuf_release(&buf);
 +      string_list_clear(&del_list, 0);
        string_list_clear(&exclude_list, 0);
        return (errors != 0);
  }
Simple merge
diff --cc builtin/grep.c
Simple merge
diff --cc builtin/log.c
Simple merge
Simple merge
Simple merge
diff --cc builtin/mv.c
index be6fa77d0481c60b82a22ca01e9b8714d9849e71,7dd6bb491cbde95f41ba6311bbd9344a80e19b31..aec79d18386b52a943b20e6ebe0dfc9b6f074f0f
@@@ -62,10 -64,10 +64,10 @@@ int cmd_mv(int argc, const char **argv
                OPT__VERBOSE(&verbose, N_("be verbose")),
                OPT__DRY_RUN(&show_only, N_("dry run")),
                OPT__FORCE(&force, N_("force move/rename even if target exists")),
 -              OPT_BOOLEAN('k', NULL, &ignore_errors, N_("skip move/rename errors")),
 +              OPT_BOOL('k', NULL, &ignore_errors, N_("skip move/rename errors")),
                OPT_END(),
        };
-       const char **source, **destination, **dest_path;
+       const char **source, **destination, **dest_path, **submodule_gitfile;
        enum update_mode { BOTH = 0, WORKING_DIRECTORY, INDEX } *modes;
        struct stat st;
        struct string_list src_for_dst = STRING_LIST_INIT_NODUP;
diff --cc builtin/reset.c
Simple merge
diff --cc builtin/rm.c
index 18bf2189992439caafb66b103df9fbe3e76c4e37,c848dad1d01273e9b5f571d19cd65b3259a3e1b2..9b59ab3a64e00cfe3a6a73d6493001085c31d683
@@@ -311,40 -314,45 +313,45 @@@ int cmd_rm(int argc, const char **argv
                }
        }
  
-       pathspec = get_pathspec(prefix, argv);
-       refresh_index(&the_index, REFRESH_QUIET, pathspec, NULL, NULL);
+       parse_pathspec(&pathspec, 0, PATHSPEC_PREFER_CWD, prefix, argv);
+       refresh_index(&the_index, REFRESH_QUIET, &pathspec, NULL, NULL);
  
-       for (i = 0; pathspec[i] ; i++)
-               /* nothing */;
-       seen = xcalloc(i, 1);
+       seen = xcalloc(pathspec.nr, 1);
  
        for (i = 0; i < active_nr; i++) {
 -              struct cache_entry *ce = active_cache[i];
 +              const struct cache_entry *ce = active_cache[i];
-               if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen))
+               if (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), 0, seen))
                        continue;
                ALLOC_GROW(list.entry, list.nr + 1, list.alloc);
                list.entry[list.nr].name = ce->name;
-               list.entry[list.nr++].is_submodule = S_ISGITLINK(ce->ce_mode);
+               list.entry[list.nr].is_submodule = S_ISGITLINK(ce->ce_mode);
+               if (list.entry[list.nr++].is_submodule &&
+                   !is_staging_gitmodules_ok())
+                       die (_("Please, stage your changes to .gitmodules or stash them to proceed"));
        }
  
-       seen_any = 0;
-       for (i = 0; (match = pathspec[i]) != NULL ; i++) {
-               if (!seen[i]) {
-                       if (!ignore_unmatch) {
-                               die(_("pathspec '%s' did not match any files"),
-                                   match);
+       if (pathspec.nr) {
+               const char *original;
+               int seen_any = 0;
+               for (i = 0; i < pathspec.nr; i++) {
+                       original = pathspec.items[i].original;
+                       if (!seen[i]) {
+                               if (!ignore_unmatch) {
+                                       die(_("pathspec '%s' did not match any files"),
+                                           original);
+                               }
                        }
+                       else {
+                               seen_any = 1;
+                       }
+                       if (!recursive && seen[i] == MATCHED_RECURSIVELY)
+                               die(_("not removing '%s' recursively without -r"),
+                                   *original ? original : ".");
                }
-               else {
-                       seen_any = 1;
-               }
-               if (!recursive && seen[i] == MATCHED_RECURSIVELY)
-                       die(_("not removing '%s' recursively without -r"),
-                           *match ? match : ".");
 -              if (! seen_any)
++              if (!seen_any)
+                       exit(0);
        }
-       if (!seen_any)
-               exit(0);
  
        /*
         * If not forced, the file, the index and the HEAD (if exists)
Simple merge
diff --cc cache.h
index 558ccb91f675e87b079e54bc688706ce8b19fa44,3cff825d5c369f20dae01ab2dabedd98fc4381c1..bd6fb9f66418b5dc6441fb47fbeb63ae50f7f335
+++ b/cache.h
@@@ -761,7 -744,8 +747,8 @@@ int is_directory(const char *)
  const char *real_path(const char *path);
  const char *real_path_if_valid(const char *path);
  const char *absolute_path(const char *path);
 -const char *relative_path(const char *abs, const char *base);
 +const char *relative_path(const char *in, const char *prefix, struct strbuf *sb);
+ int normalize_path_copy_len(char *dst, const char *src, int *prefix_len);
  int normalize_path_copy(char *dst, const char *src);
  int longest_ancestor_length(const char *path, struct string_list *prefixes);
  char *strip_path_suffix(const char *path, const char *suffix);
diff --cc combine-diff.c
Simple merge
diff --cc commit.h
Simple merge
diff --cc diff-lib.c
Simple merge
diff --cc diff.h
Simple merge
diff --cc dir.c
Simple merge
diff --cc git.c
Simple merge
diff --cc line-log.c
Simple merge
Simple merge
diff --cc path.c
Simple merge
diff --cc pathspec.c
index 6ea0867493ad3e8cfd613dd57fa5ac9649507b47,d9f41432221ab5f886aaf0a6e306cb263892ab33..4b32cc32cb5b0be495ac941c5e96d8aee8fd8ff9
@@@ -32,8 -32,8 +32,8 @@@ void add_pathspec_matches_against_index
        if (!num_unmatched)
                return;
        for (i = 0; i < active_nr; i++) {
 -              struct cache_entry *ce = active_cache[i];
 +              const struct cache_entry *ce = active_cache[i];
-               match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen);
+               match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen);
        }
  }
  
diff --cc read-cache.c
Simple merge
diff --cc rerere.c
Simple merge
diff --cc resolve-undo.c
index 77101f51c153ab014ecb80a02ca52daaa16cb10d,4b78e6f8b82002848b1d3472de870b74894b3d25..c09b00664e6892c84424bb4984152883460d3df6
@@@ -181,8 -181,8 +181,8 @@@ void unmerge_index(struct index_state *
                return;
  
        for (i = 0; i < istate->cache_nr; i++) {
 -              struct cache_entry *ce = istate->cache[i];
 +              const struct cache_entry *ce = istate->cache[i];
-               if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, NULL))
+               if (!match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, NULL))
                        continue;
                i = unmerge_index_entry_at(istate, i);
        }
diff --cc revision.c
Simple merge
diff --cc setup.c
Simple merge
diff --cc submodule.c
Simple merge
Simple merge
Simple merge
diff --cc tree-walk.c
Simple merge
diff --cc tree.c
Simple merge
diff --cc wt-status.c
index cb24f1fa9b9f9632e5fd92bbcceb44008619fa14,33baf0a698176c7df93e14046b388b0750fcaee4..ff4b32426a36db38fba9e4cc51e09a988efe34a6
@@@ -475,10 -475,9 +475,9 @@@ static void wt_status_collect_changes_i
        for (i = 0; i < active_nr; i++) {
                struct string_list_item *it;
                struct wt_status_change_data *d;
 -              struct cache_entry *ce = active_cache[i];
 +              const struct cache_entry *ce = active_cache[i];
  
-               if (!ce_path_match(ce, &pathspec))
+               if (!ce_path_match(ce, &s->pathspec))
                        continue;
                it = string_list_insert(&s->change, ce->name);
                d = it->util;
diff --cc wt-status.h
Simple merge