Merge branch 'fg/submodule-git-file-git-dir'
authorJunio C Hamano <gitster@pobox.com>
Mon, 10 Oct 2011 22:56:16 +0000 (15:56 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 10 Oct 2011 22:56:17 +0000 (15:56 -0700)
* fg/submodule-git-file-git-dir:
Move git-dir for submodules
rev-parse: add option --resolve-git-dir <path>

Conflicts:
cache.h
git-submodule.sh

1  2 
cache.h
git-submodule.sh
setup.c
t/t7400-submodule-basic.sh
diff --combined cache.h
index 82e12c862c0ed4fb0da7fb86fc3cef26558810dc,55ae6976b6961bcc967cf277b95d018009ec57dc..c989f79835a332d879333ee8b927ede150784e54
+++ b/cache.h
@@@ -394,7 -394,6 +394,7 @@@ static inline enum object_type object_t
  }
  
  #define GIT_DIR_ENVIRONMENT "GIT_DIR"
 +#define GIT_NAMESPACE_ENVIRONMENT "GIT_NAMESPACE"
  #define GIT_WORK_TREE_ENVIRONMENT "GIT_WORK_TREE"
  #define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
  #define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
@@@ -435,16 -434,14 +435,17 @@@ extern char *get_object_directory(void)
  extern char *get_index_file(void);
  extern char *get_graft_file(void);
  extern int set_git_dir(const char *path);
 +extern const char *get_git_namespace(void);
 +extern const char *strip_namespace(const char *namespaced_ref);
  extern const char *get_git_work_tree(void);
 -extern const char *read_gitfile_gently(const char *path);
 +extern const char *read_gitfile(const char *path);
+ extern const char *resolve_gitdir(const char *suspect);
  extern void set_git_work_tree(const char *tree);
  
  #define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
  
  extern const char **get_pathspec(const char *prefix, const char **pathspec);
 +extern const char *pathspec_prefix(const char *prefix, const char **pathspec);
  extern void setup_work_tree(void);
  extern const char *setup_git_directory_gently(int *);
  extern const char *setup_git_directory(void);
@@@ -1076,11 -1073,9 +1077,11 @@@ extern int git_config_bool(const char *
  extern int git_config_maybe_bool(const char *, const char *);
  extern int git_config_string(const char **, const char *, const char *);
  extern int git_config_pathname(const char **, const char *, const char *);
 +extern int git_config_set_in_file(const char *, const char *, const char *);
  extern int git_config_set(const char *, const char *);
  extern int git_config_parse_key(const char *, char **, int *);
  extern int git_config_set_multivar(const char *, const char *, const char *, int);
 +extern int git_config_set_multivar_in_file(const char *, const char *, const char *, const char *, int);
  extern int git_config_rename_section(const char *, const char *);
  extern const char *git_etc_gitconfig(void);
  extern int check_repository_format_version(const char *var, const char *value, void *cb);
@@@ -1197,7 -1192,7 +1198,7 @@@ extern int ws_blank_line(const char *li
  #define ws_tab_width(rule)     ((rule) & WS_TAB_WIDTH_MASK)
  
  /* ls-files */
 -int report_path_error(const char *ps_matched, const char **pathspec, int prefix_offset);
 +int report_path_error(const char *ps_matched, const char **pathspec, const char *prefix);
  void overlay_tree_on_cache(const char *tree_name, const char *prefix);
  
  char *alias_lookup(const char *alias);
diff --combined git-submodule.sh
index 814d0d914eaf994462e61559b0692c958f97513b,7576d147695955f3a2b8a92944b5315a2b0f5395..928a62f626fe7ff1db8239713d94ff9aa25158eb
@@@ -122,19 -122,49 +122,55 @@@ module_clone(
        path=$1
        url=$2
        reference="$3"
-       if test -n "$reference"
 +      quiet=
 +      if test -n "$GIT_QUIET"
 +      then
 +              quiet=-q
 +      fi
 +
+       gitdir=
+       gitdir_base=
+       name=$(module_name "$path")
+       base_path=$(dirname "$path")
+       gitdir=$(git rev-parse --git-dir)
+       gitdir_base="$gitdir/modules/$base_path"
+       gitdir="$gitdir/modules/$path"
+       case $gitdir in
+       /*)
+               a="$(cd_to_toplevel && pwd)/"
+               b=$gitdir
+               while [ "$b" ] && [ "${a%%/*}" = "${b%%/*}" ]
+               do
+                       a=${a#*/} b=${b#*/};
+               done
+               rel="$a$name"
+               rel=`echo $rel | sed -e 's|[^/]*|..|g'`
+               rel_gitdir="$rel/$b"
+               ;;
+       *)
+               rel=`echo $name | sed -e 's|[^/]*|..|g'`
+               rel_gitdir="$rel/$gitdir"
+               ;;
+       esac
+       if test -d "$gitdir"
        then
-               git-clone $quiet "$reference" -n "$url" "$path"
+               mkdir -p "$path"
+               echo "gitdir: $rel_gitdir" >"$path/.git"
+               rm -f "$gitdir/index"
        else
-               git-clone $quiet -n "$url" "$path"
-       fi ||
-       die "$(eval_gettext "Clone of '\$url' into submodule path '\$path' failed")"
+               mkdir -p "$gitdir_base"
+               if test -n "$reference"
+               then
 -                      git-clone "$reference" -n "$url" "$path" --separate-git-dir "$gitdir"
++                      git-clone $quiet "$reference" -n "$url" "$path" --separate-git-dir "$gitdir"
+               else
 -                      git-clone -n "$url" "$path" --separate-git-dir "$gitdir"
++                      git-clone $quiet -n "$url" "$path" --separate-git-dir "$gitdir"
+               fi ||
+               die "$(eval_gettext "Clone of '\$url' into submodule path '\$path' failed")"
+       fi
  }
  
  #
@@@ -228,9 -258,12 +264,9 @@@ cmd_add(
  
        if test -z "$force" && ! git add --dry-run --ignore-missing "$path" > /dev/null 2>&1
        then
 -              (
 -                      eval_gettext "The following path is ignored by one of your .gitignore files:
 +              eval_gettextln "The following path is ignored by one of your .gitignore files:
  \$path
 -Use -f if you really want to add it." &&
 -                      echo
 -              ) >&2
 +Use -f if you really want to add it." >&2
                exit 1
        fi
  
        then
                if test -d "$path"/.git -o -f "$path"/.git
                then
 -                      eval_gettext "Adding existing repo at '\$path' to the index"; echo
 +                      eval_gettextln "Adding existing repo at '\$path' to the index"
                else
                        die "$(eval_gettext "'\$path' already exists and is not a valid git repo")"
                fi
@@@ -426,6 -459,6 +462,9 @@@ cmd_update(
                --recursive)
                        recursive=1
                        ;;
++              --checkout)
++                      update="checkout"
++                      ;;
                --)
                        shift
                        break
                fi
                name=$(module_name "$path") || exit
                url=$(git config submodule."$name".url)
--              update_module=$(git config submodule."$name".update)
++              if ! test -z "$update"
++              then
++                      update_module=$update
++              else
++                      update_module=$(git config submodule."$name".update)
++              fi
++
++              if test "$update_module" = "none"
++              then
++                      echo "Skipping submodule '$path'"
++                      continue
++              fi
++
                if test -z "$url"
                then
                        # Only mention uninitialized submodules when its
@@@ -480,11 -513,11 +531,6 @@@ Maybe you want to use 'update --init'?"
                        die "$(eval_gettext "Unable to find current revision in submodule path '\$path'")"
                fi
  
--              if ! test -z "$update"
--              then
--                      update_module=$update
--              fi
--
                if test "$subsha1" != "$sha1"
                then
                        subforce=$force
@@@ -698,7 -731,10 +744,7 @@@ cmd_summary() 
                                ;; # removed
                        *)
                                # unexpected type
 -                              (
 -                                      eval_gettext "unexpected mode \$mod_dst" &&
 -                                      echo
 -                              ) >&2
 +                              eval_gettextln "unexpected mode \$mod_dst" >&2
                                continue ;;
                        esac
                fi
        done |
        if test -n "$for_status"; then
                if [ -n "$files" ]; then
 -                      gettext "# Submodules changed but not updated:"; echo
 +                      gettextln "# Submodules changed but not updated:"
                else
 -                      gettext "# Submodule changes to be committed:"; echo
 +                      gettextln "# Submodule changes to be committed:"
                fi
                echo "#"
                sed -e 's|^|# |' -e 's|^# $|#|'
diff --combined setup.c
index 27c1d4787a2c2efd8420a225b43e36b76464ce42,efad002ed2ec8e54e922baefb9c12d494fb668d7..b2b4872b700ab9776144f145dfb27d5d16dfc945
+++ b/setup.c
@@@ -40,6 -40,34 +40,6 @@@ char *prefix_path(const char *prefix, i
        return sanitized;
  }
  
 -/*
 - * Unlike prefix_path, this should be used if the named file does
 - * not have to interact with index entry; i.e. name of a random file
 - * on the filesystem.
 - */
 -const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
 -{
 -      static char path[PATH_MAX];
 -#ifndef WIN32
 -      if (!pfx_len || is_absolute_path(arg))
 -              return arg;
 -      memcpy(path, pfx, pfx_len);
 -      strcpy(path + pfx_len, arg);
 -#else
 -      char *p;
 -      /* don't add prefix to absolute paths, but still replace '\' by '/' */
 -      if (is_absolute_path(arg))
 -              pfx_len = 0;
 -      else if (pfx_len)
 -              memcpy(path, pfx, pfx_len);
 -      strcpy(path + pfx_len, arg);
 -      for (p = path + pfx_len; *p; p++)
 -              if (*p == '\\')
 -                      *p = '/';
 -#endif
 -      return path;
 -}
 -
  int check_filename(const char *prefix, const char *arg)
  {
        const char *name;
@@@ -236,38 -264,6 +236,38 @@@ const char **get_pathspec(const char *p
        return pathspec;
  }
  
 +const char *pathspec_prefix(const char *prefix, const char **pathspec)
 +{
 +      const char **p, *n, *prev;
 +      unsigned long max;
 +
 +      if (!pathspec)
 +              return prefix ? xmemdupz(prefix, strlen(prefix)) : NULL;
 +
 +      prev = NULL;
 +      max = PATH_MAX;
 +      for (p = pathspec; (n = *p) != NULL; p++) {
 +              int i, len = 0;
 +              for (i = 0; i < max; i++) {
 +                      char c = n[i];
 +                      if (prev && prev[i] != c)
 +                              break;
 +                      if (!c || c == '*' || c == '?')
 +                              break;
 +                      if (c == '/')
 +                              len = i+1;
 +              }
 +              prev = n;
 +              if (len < max) {
 +                      max = len;
 +                      if (!max)
 +                              break;
 +              }
 +      }
 +
 +      return max ? xmemdupz(prev, max) : NULL;
 +}
 +
  /*
   * Test if it looks like we're at a git directory.
   * We want to see:
@@@ -379,7 -375,7 +379,7 @@@ static int check_repository_format_gent
   * Try to read the location of the git directory from the .git file,
   * return path to git directory if found.
   */
 -const char *read_gitfile_gently(const char *path)
 +const char *read_gitfile(const char *path)
  {
        char *buf;
        char *dir;
@@@ -441,7 -437,7 +441,7 @@@ static const char *setup_explicit_git_d
        if (PATH_MAX - 40 < strlen(gitdirenv))
                die("'$%s' too big", GIT_DIR_ENVIRONMENT);
  
 -      gitfile = (char*)read_gitfile_gently(gitdirenv);
 +      gitfile = (char*)read_gitfile(gitdirenv);
        if (gitfile) {
                gitfile = xstrdup(gitfile);
                gitdirenv = gitfile;
@@@ -665,7 -661,7 +665,7 @@@ static const char *setup_git_directory_
        if (one_filesystem)
                current_device = get_device_or_die(".", NULL);
        for (;;) {
 -              gitfile = (char*)read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
 +              gitfile = (char*)read_gitfile(DEFAULT_GIT_DIR_ENVIRONMENT);
                if (gitfile)
                        gitdirenv = gitfile = xstrdup(gitfile);
                else {
@@@ -812,3 -808,10 +812,10 @@@ const char *setup_git_directory(void
  {
        return setup_git_directory_gently(NULL);
  }
 -      return read_gitfile_gently(suspect);
+ const char *resolve_gitdir(const char *suspect)
+ {
+       if (is_git_directory(suspect))
+               return suspect;
++      return read_gitfile(suspect);
+ }
index 69115269c2a284dcfc99abd2f7feb3d87f4e5bcc,270a7d5b81ec8d10b0bbc532a8a0fd2a200ce85f..695f7afdf31cc589e9c31d764d1e713ad64240c0
@@@ -77,8 -77,7 +77,8 @@@ test_expect_success 'submodule add' 
  
        (
                cd addtest &&
 -              git submodule add "$submodurl" submod &&
 +              git submodule add -q "$submodurl" submod >actual &&
 +              test ! -s actual &&
                git submodule init
        ) &&
  
@@@ -276,8 -275,7 +276,8 @@@ test_expect_success 'update should wor
        echo "$rev1" >expect &&
  
        mkdir init &&
 -      git submodule update &&
 +      git submodule update -q >update.out &&
 +      test ! -s update.out &&
  
        inspect init &&
        test_cmp expect head-sha1
@@@ -362,10 -360,10 +362,10 @@@ test_expect_success 'update --init' 
        git submodule update init > update.out &&
        cat update.out &&
        test_i18ngrep "not initialized" update.out &&
-       ! test -d init/.git &&
+       test_must_fail git rev-parse --resolve-git-dir init/.git &&
  
        git submodule update --init init &&
-       test -d init/.git
+       git rev-parse --resolve-git-dir init/.git
  '
  
  test_expect_success 'do not add files from a submodule' '