Merge branch 'fc/trivial'
authorJunio C Hamano <gitster@pobox.com>
Tue, 17 Sep 2013 18:42:34 +0000 (11:42 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 17 Sep 2013 18:42:34 +0000 (11:42 -0700)
* fc/trivial:
pull: use $curr_branch_short more
add: trivial style cleanup
reset: trivial style cleanup
branch: trivial style fix
reset: trivial refactoring

1  2 
builtin/add.c
builtin/reset.c
git-pull.sh
diff --combined builtin/add.c
index 31ddabd99472a099ccc34810a9821050883bc1fa,a1e1e0eeb9f2f3548bcdeb77be73175c69ab9ee0..226f758869358444ad1c39e5e0a05c961fb76859
@@@ -166,16 -166,14 +166,16 @@@ static void update_callback(struct diff
        }
  }
  
 -static void update_files_in_cache(const char *prefix, const char **pathspec,
 +static void update_files_in_cache(const char *prefix,
 +                                const struct pathspec *pathspec,
                                  struct update_callback_data *data)
  {
        struct rev_info rev;
  
        init_revisions(&rev, prefix);
        setup_revisions(0, NULL, &rev, NULL);
 -      init_pathspec(&rev.prune_data, pathspec);
 +      if (pathspec)
 +              copy_pathspec(&rev.prune_data, pathspec);
        rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
        rev.diffopt.format_callback = update_callback;
        rev.diffopt.format_callback_data = data;
        run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
  }
  
 -int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
 +int add_files_to_cache(const char *prefix,
 +                     const struct pathspec *pathspec, int flags)
  {
        struct update_callback_data data;
  
  }
  
  #define WARN_IMPLICIT_DOT (1u << 0)
 -static char *prune_directory(struct dir_struct *dir, const char **pathspec,
 +static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec,
                             int prefix, unsigned flag)
  {
        char *seen;
 -      int i, specs;
 +      int i;
        struct dir_entry **src, **dst;
  
 -      for (specs = 0; pathspec[specs];  specs++)
 -              /* nothing */;
 -      seen = xcalloc(specs, 1);
 +      seen = xcalloc(pathspec->nr, 1);
  
        src = dst = dir->entries;
        i = dir->nr;
        while (--i >= 0) {
                struct dir_entry *entry = *src++;
 -              if (match_pathspec(pathspec, entry->name, entry->len,
 -                                 prefix, seen))
 +              if (match_pathspec_depth(pathspec, entry->name, entry->len,
 +                                       prefix, seen))
                        *dst++ = entry;
                else if (flag & WARN_IMPLICIT_DOT)
                        /*
                        warn_pathless_add();
        }
        dir->nr = dst - dir->entries;
 -      add_pathspec_matches_against_index(pathspec, seen, specs);
 +      add_pathspec_matches_against_index(pathspec, seen);
        return seen;
  }
  
 -/*
 - * Checks the index to see whether any path in pathspec refers to
 - * something inside a submodule.  If so, dies with an error message.
 - */
 -static void treat_gitlinks(const char **pathspec)
 -{
 -      int i;
 -
 -      if (!pathspec || !*pathspec)
 -              return;
 -
 -      for (i = 0; pathspec[i]; i++)
 -              pathspec[i] = check_path_for_gitlink(pathspec[i]);
 -}
 -
 -static void refresh(int verbose, const char **pathspec)
 +static void refresh(int verbose, const struct pathspec *pathspec)
  {
        char *seen;
 -      int i, specs;
 +      int i;
  
 -      for (specs = 0; pathspec[specs];  specs++)
 -              /* nothing */;
 -      seen = xcalloc(specs, 1);
 +      seen = xcalloc(pathspec->nr, 1);
        refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
                      pathspec, seen, _("Unstaged changes after refreshing the index:"));
 -      for (i = 0; i < specs; i++) {
 +      for (i = 0; i < pathspec->nr; i++) {
                if (!seen[i])
 -                      die(_("pathspec '%s' did not match any files"), pathspec[i]);
 +                      die(_("pathspec '%s' did not match any files"),
 +                          pathspec->items[i].match);
        }
          free(seen);
  }
  
 -/*
 - * Normalizes argv relative to prefix, via get_pathspec(), and then
 - * runs die_if_path_beyond_symlink() on each path in the normalized
 - * list.
 - */
 -static const char **validate_pathspec(const char **argv, const char *prefix)
 -{
 -      const char **pathspec = get_pathspec(prefix, argv);
 -
 -      if (pathspec) {
 -              const char **p;
 -              for (p = pathspec; *p; p++) {
 -                      die_if_path_beyond_symlink(*p, prefix);
 -              }
 -      }
 -
 -      return pathspec;
 -}
 -
  int run_add_interactive(const char *revision, const char *patch_mode,
 -                      const char **pathspec)
 +                      const struct pathspec *pathspec)
  {
 -      int status, ac, pc = 0;
 +      int status, ac, i;
        const char **args;
  
 -      if (pathspec)
 -              while (pathspec[pc])
 -                      pc++;
 -
 -      args = xcalloc(sizeof(const char *), (pc + 5));
 +      args = xcalloc(sizeof(const char *), (pathspec->nr + 6));
        ac = 0;
        args[ac++] = "add--interactive";
        if (patch_mode)
        if (revision)
                args[ac++] = revision;
        args[ac++] = "--";
 -      if (pc) {
 -              memcpy(&(args[ac]), pathspec, sizeof(const char *) * pc);
 -              ac += pc;
 -      }
 -      args[ac] = NULL;
 +      for (i = 0; i < pathspec->nr; i++)
 +              /* pass original pathspec, to be re-parsed */
 +              args[ac++] = pathspec->items[i].original;
  
        status = run_command_v_opt(args, RUN_GIT_CMD);
        free(args);
  
  int interactive_add(int argc, const char **argv, const char *prefix, int patch)
  {
 -      const char **pathspec = NULL;
 +      struct pathspec pathspec;
  
 -      if (argc) {
 -              pathspec = validate_pathspec(argv, prefix);
 -              if (!pathspec)
 -                      return -1;
 -      }
 +      parse_pathspec(&pathspec, 0,
 +                     PATHSPEC_PREFER_FULL |
 +                     PATHSPEC_SYMLINK_LEADING_PATH |
 +                     PATHSPEC_PREFIX_ORIGIN,
 +                     prefix, argv);
  
        return run_add_interactive(NULL,
                                   patch ? "--patch" : NULL,
 -                                 pathspec);
 +                                 &pathspec);
  }
  
  static int edit_patch(int argc, const char **argv, const char *prefix)
        git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
  
        if (read_cache() < 0)
-               die (_("Could not read the index"));
+               die(_("Could not read the index"));
  
        init_revisions(&rev, prefix);
        rev.diffopt.context = 7;
        DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
        out = open(file, O_CREAT | O_WRONLY, 0666);
        if (out < 0)
-               die (_("Could not open '%s' for writing."), file);
+               die(_("Could not open '%s' for writing."), file);
        rev.diffopt.file = xfdopen(out, "w");
        rev.diffopt.close_file = 1;
        if (run_diff_files(&rev, 0))
-               die (_("Could not write patch"));
+               die(_("Could not write patch"));
  
        launch_editor(file, NULL, NULL);
  
        child.git_cmd = 1;
        child.argv = apply_argv;
        if (run_command(&child))
-               die (_("Could not apply '%s'"), file);
+               die(_("Could not apply '%s'"), file);
  
        unlink(file);
        free(file);
@@@ -406,7 -446,7 +406,7 @@@ int cmd_add(int argc, const char **argv
  {
        int exit_status = 0;
        int newfd;
 -      const char **pathspec;
 +      struct pathspec pathspec;
        struct dir_struct dir;
        int flags;
        int add_new_files;
                fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
                return 0;
        }
 -      pathspec = validate_pathspec(argv, prefix);
  
        if (read_cache() < 0)
                die(_("index file corrupt"));
 -      treat_gitlinks(pathspec);
 +
 +      /*
 +       * Check the "pathspec '%s' did not match any files" block
 +       * below before enabling new magic.
 +       */
 +      parse_pathspec(&pathspec, 0,
 +                     PATHSPEC_PREFER_FULL |
 +                     PATHSPEC_SYMLINK_LEADING_PATH |
 +                     PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE,
 +                     prefix, argv);
  
        if (add_new_files) {
                int baselen;
 +              struct pathspec empty_pathspec;
  
                /* Set up the default git porcelain excludes */
                memset(&dir, 0, sizeof(dir));
                        setup_standard_excludes(&dir);
                }
  
 +              memset(&empty_pathspec, 0, sizeof(empty_pathspec));
                /* This picks up the paths that are not tracked */
 -              baselen = fill_directory(&dir, implicit_dot ? NULL : pathspec);
 -              if (pathspec)
 -                      seen = prune_directory(&dir, pathspec, baselen,
 +              baselen = fill_directory(&dir, implicit_dot ? &empty_pathspec : &pathspec);
 +              if (pathspec.nr)
 +                      seen = prune_directory(&dir, &pathspec, baselen,
                                        implicit_dot ? WARN_IMPLICIT_DOT : 0);
        }
  
        if (refresh_only) {
 -              refresh(verbose, pathspec);
 +              refresh(verbose, &pathspec);
                goto finish;
        }
        if (implicit_dot && prefix)
                refresh_cache(REFRESH_QUIET);
  
 -      if (pathspec) {
 +      if (pathspec.nr) {
                int i;
  
                if (!seen)
 -                      seen = find_pathspecs_matching_against_index(pathspec);
 -              for (i = 0; pathspec[i]; i++) {
 -                      if (!seen[i] && pathspec[i][0]
 -                          && !file_exists(pathspec[i])) {
 +                      seen = find_pathspecs_matching_against_index(&pathspec);
 +
 +              /*
 +               * file_exists() assumes exact match
 +               */
 +              GUARD_PATHSPEC(&pathspec,
 +                             PATHSPEC_FROMTOP |
 +                             PATHSPEC_LITERAL |
 +                             PATHSPEC_GLOB |
 +                             PATHSPEC_ICASE);
 +
 +              for (i = 0; i < pathspec.nr; i++) {
 +                      const char *path = pathspec.items[i].match;
 +                      if (!seen[i] &&
 +                          ((pathspec.items[i].magic &
 +                            (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
 +                           !file_exists(path))) {
                                if (ignore_missing) {
                                        int dtype = DT_UNKNOWN;
 -                                      if (is_excluded(&dir, pathspec[i], &dtype))
 -                                              dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
 +                                      if (is_excluded(&dir, path, &dtype))
 +                                              dir_add_ignored(&dir, path, pathspec.items[i].len);
                                } else
                                        die(_("pathspec '%s' did not match any files"),
 -                                          pathspec[i]);
 +                                          pathspec.items[i].original);
                        }
                }
                free(seen);
                 */
                update_data.implicit_dot = prefix;
                update_data.implicit_dot_len = strlen(prefix);
 -              pathspec = NULL;
 +              free_pathspec(&pathspec);
 +              memset(&pathspec, 0, sizeof(pathspec));
        }
        update_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;
 -      update_files_in_cache(prefix, pathspec, &update_data);
 +      update_files_in_cache(prefix, &pathspec, &update_data);
  
        exit_status |= !!update_data.add_errors;
        if (add_new_files)
  
        unplug_bulk_checkin();
  
 finish:
+ finish:
        if (active_cache_changed) {
                if (write_cache(newfd, active_cache, active_nr) ||
                    commit_locked_index(&lock_file))
diff --combined builtin/reset.c
index 5e4c551531896ebd993d2a2c2903e4b7d257ed31,7e65934a82c0212f176bb604c6f22cd5904c7198..088ccffba07a4227150290492f22dc3bbac56fdc
@@@ -133,13 -133,12 +133,13 @@@ static void update_index_from_diff(stru
        }
  }
  
 -static int read_from_tree(const char **pathspec, unsigned char *tree_sha1)
 +static int read_from_tree(const struct pathspec *pathspec,
 +                        unsigned char *tree_sha1)
  {
        struct diff_options opt;
  
        memset(&opt, 0, sizeof(opt));
 -      diff_tree_setup_paths(pathspec, &opt);
 +      copy_pathspec(&opt.pathspec, pathspec);
        opt.output_format = DIFF_FORMAT_CALLBACK;
        opt.format_callback = update_index_from_diff;
  
                return 1;
        diffcore_std(&opt);
        diff_flush(&opt);
 -      diff_tree_release_paths(&opt);
 +      free_pathspec(&opt.pathspec);
  
        return 0;
  }
@@@ -175,10 -174,7 +175,10 @@@ static void die_if_unmerged_cache(int r
  
  }
  
 -static const char **parse_args(const char **argv, const char *prefix, const char **rev_ret)
 +static void parse_args(struct pathspec *pathspec,
 +                     const char **argv, const char *prefix,
 +                     int patch_mode,
 +                     const char **rev_ret)
  {
        const char *rev = "HEAD";
        unsigned char unused[20];
                }
        }
        *rev_ret = rev;
 -      return argv[0] ? get_pathspec(prefix, argv) : NULL;
 +      parse_pathspec(pathspec, 0,
 +                     PATHSPEC_PREFER_FULL |
 +                     (patch_mode ? PATHSPEC_PREFIX_ORIGIN : 0),
 +                     prefix, argv);
  }
  
  static int update_refs(const char *rev, const unsigned char *sha1)
@@@ -253,7 -246,7 +253,7 @@@ int cmd_reset(int argc, const char **ar
        int patch_mode = 0, unborn;
        const char *rev;
        unsigned char sha1[20];
 -      const char **pathspec = NULL;
 +      struct pathspec pathspec;
        const struct option options[] = {
                OPT__QUIET(&quiet, N_("be quiet, only report errors")),
                OPT_SET_INT(0, "mixed", &reset_type,
                                N_("reset HEAD, index and working tree"), MERGE),
                OPT_SET_INT(0, "keep", &reset_type,
                                N_("reset HEAD but keep local changes"), KEEP),
 -              OPT_BOOLEAN('p', "patch", &patch_mode, N_("select hunks interactively")),
 +              OPT_BOOL('p', "patch", &patch_mode, N_("select hunks interactively")),
                OPT_END()
        };
  
  
        argc = parse_options(argc, argv, prefix, options, git_reset_usage,
                                                PARSE_OPT_KEEP_DASHDASH);
 -      pathspec = parse_args(argv, prefix, &rev);
 +      parse_args(&pathspec, argv, prefix, patch_mode, &rev);
  
        unborn = !strcmp(rev, "HEAD") && get_sha1("HEAD", sha1);
        if (unborn) {
                /* reset on unborn branch: treat as reset to empty tree */
                hashcpy(sha1, EMPTY_TREE_SHA1_BIN);
 -      } else if (!pathspec) {
 +      } else if (!pathspec.nr) {
                struct commit *commit;
                if (get_sha1_committish(rev, sha1))
                        die(_("Failed to resolve '%s' as a valid revision."), rev);
        if (patch_mode) {
                if (reset_type != NONE)
                        die(_("--patch is incompatible with --{hard,mixed,soft}"));
 -              return run_add_interactive(sha1_to_hex(sha1), "--patch=reset", pathspec);
 +              return run_add_interactive(sha1_to_hex(sha1), "--patch=reset", &pathspec);
        }
  
        /* git reset tree [--] paths... can be used to
         * load chosen paths from the tree into the index without
         * affecting the working tree nor HEAD. */
 -      if (pathspec) {
 +      if (pathspec.nr) {
                if (reset_type == MIXED)
                        warning(_("--mixed with paths is deprecated; use 'git reset -- <paths>' instead."));
                else if (reset_type != NONE)
                die_if_unmerged_cache(reset_type);
  
        if (reset_type != SOFT) {
-               struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
+               struct lock_file *lock = xcalloc(1, sizeof(*lock));
                int newfd = hold_locked_index(lock, 1);
                if (reset_type == MIXED) {
 -                      if (read_from_tree(pathspec, sha1))
+                       int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;
 +                      if (read_from_tree(&pathspec, sha1))
                                return 1;
+                       refresh_index(&the_index, flags, NULL, NULL,
+                                     _("Unstaged changes after reset:"));
                } else {
                        int err = reset_index(sha1, reset_type, quiet);
                        if (reset_type == KEEP && !err)
                                die(_("Could not reset index file to revision '%s'."), rev);
                }
  
-               if (reset_type == MIXED) { /* Report what has not been updated. */
-                       int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;
-                       refresh_index(&the_index, flags, NULL, NULL,
-                                     _("Unstaged changes after reset:"));
-               }
                if (write_cache(newfd, active_cache, active_nr) ||
                    commit_locked_index(lock))
                        die(_("Could not write new index file."));
        }
  
 -      if (!pathspec && !unborn) {
 +      if (!pathspec.nr && !unborn) {
                /* Any resets without paths update HEAD to the head being
                 * switched to, saving the previous head in ORIG_HEAD before. */
                update_ref_status = update_refs(rev, sha1);
                if (reset_type == HARD && !update_ref_status && !quiet)
                        print_new_head_line(lookup_commit_reference(sha1));
        }
 -      if (!pathspec)
 +      if (!pathspec.nr)
                remove_branch_state();
  
        return update_ref_status;
diff --combined git-pull.sh
index e11d9a05802432c623b9c2419461558f29f2d233,d8b2708a1dc27da9a894b652c7c1e51c4759a3db..b946fd975bacae7b73645e0dba8ae61da716ccfc
@@@ -4,7 -4,7 +4,7 @@@
  #
  # Fetch one or more remote refs and merge it/them into the current HEAD.
  
 -USAGE='[-n | --no-stat] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s strategy]... [<fetch-options>] <repo> <head>...'
 +USAGE='[-n | --no-stat] [--[no-]commit] [--[no-]squash] [--[no-]ff] [--[no-]rebase|--rebase=preserve] [-s strategy]... [<fetch-options>] <repo> <head>...'
  LONG_USAGE='Fetch one or more remote refs and integrate it/them with the current HEAD.'
  SUBDIRECTORY_OK=Yes
  OPTIONS_SPEC=
@@@ -38,19 -38,15 +38,19 @@@ Please, commit your changes before you 
  test -z "$(git ls-files -u)" || die_conflict
  test -f "$GIT_DIR/MERGE_HEAD" && die_merge
  
 +bool_or_string_config () {
 +      git config --bool "$1" 2>/dev/null || git config "$1"
 +}
 +
  strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
  log_arg= verbosity= progress= recurse_submodules= verify_signatures=
 -merge_args= edit=
 +merge_args= edit= rebase_args=
  curr_branch=$(git symbolic-ref -q HEAD)
  curr_branch_short="${curr_branch#refs/heads/}"
 -rebase=$(git config --bool branch.$curr_branch_short.rebase)
 +rebase=$(bool_or_string_config branch.$curr_branch_short.rebase)
  if test -z "$rebase"
  then
 -      rebase=$(git config --bool pull.rebase)
 +      rebase=$(bool_or_string_config pull.rebase)
  fi
  dry_run=
  while :
@@@ -114,9 -110,6 +114,9 @@@ d
                esac
                merge_args="$merge_args$xx "
                ;;
 +      -r=*|--r=*|--re=*|--reb=*|--reba=*|--rebas=*|--rebase=*)
 +              rebase="${1#*=}"
 +              ;;
        -r|--r|--re|--reb|--reba|--rebas|--rebase)
                rebase=true
                ;;
        shift
  done
  
 +case "$rebase" in
 +preserve)
 +      rebase=true
 +      rebase_args=--preserve-merges
 +      ;;
 +true|false|'')
 +      ;;
 +*)
 +      echo "Invalid value for --rebase, should be true, false, or preserve"
 +      usage
 +      exit 1
 +      ;;
 +esac
 +
  error_on_no_merge_candidates () {
        exec >&2
        for opt
                op_prep=with
        fi
  
-       curr_branch=${curr_branch#refs/heads/}
-       upstream=$(git config "branch.$curr_branch.merge")
-       remote=$(git config "branch.$curr_branch.remote")
+       upstream=$(git config "branch.$curr_branch_short.merge")
+       remote=$(git config "branch.$curr_branch_short.remote")
  
        if [ $# -gt 1 ]; then
                if [ "$rebase" = true ]; then
@@@ -313,7 -291,7 +312,7 @@@ f
  merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
  case "$rebase" in
  true)
 -      eval="git-rebase $diffstat $strategy_args $merge_args $verbosity"
 +      eval="git-rebase $diffstat $strategy_args $merge_args $rebase_args $verbosity"
        eval="$eval --onto $merge_head ${oldremoteref:-$merge_head}"
        ;;
  *)