1. 06 4月, 2012 1 次提交
    • J
      run-command: treat inaccessible directories as ENOENT · 38f865c2
      Jeff King 提交于
      When execvp reports EACCES, it can be one of two things:
      
        1. We found a file to execute, but did not have
           permissions to do so.
      
        2. We did not have permissions to look in some directory
           in the $PATH.
      
      In the former case, we want to consider this a
      permissions problem and report it to the user as such (since
      getting this for something like "git foo" is likely a
      configuration error).
      
      In the latter case, there is a good chance that the
      inaccessible directory does not contain anything of
      interest. Reporting "permission denied" is confusing to the
      user (and prevents our usual "did you mean...?" lookup). It
      also prevents git from trying alias lookup, since we do so
      only when an external command does not exist (not when it
      exists but has an error).
      
      This patch detects EACCES from execvp, checks whether we are
      in case (2), and if so converts errno to ENOENT. This
      behavior matches that of "bash" (but not of simpler shells
      that use execvp more directly, like "dash").
      
      Test stolen from Junio.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      38f865c2
  2. 27 3月, 2012 1 次提交
    • J
      clean up struct ref's nonfastforward field · e339aa92
      Jeff King 提交于
      Each ref structure contains a "nonfastforward" field which
      is set during push to show whether the ref rewound history.
      Originally this was a single bit, but it was changed in
      f25950f3 (push: Provide situational hints for non-fast-forward
      errors) to an enum differentiating a non-ff of the current
      branch versus another branch.
      
      However, we never actually set the member according to the
      enum values, nor did we ever read it expecting anything but
      a boolean value. But we did use the side effect of declaring
      the enum constants to store those values in a totally
      different integer variable. The code as-is isn't buggy, but
      the enum declaration inside "struct ref" is somewhat
      misleading.
      
      Let's convert nonfastforward back into a single bit, and
      then define the NON_FF_* constants closer to where they
      would be used (they are returned via the "int *nonfastforward"
      parameter to transport_push, so we can define them there).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      e339aa92
  3. 24 3月, 2012 1 次提交
  4. 20 3月, 2012 1 次提交
    • C
      push: Provide situational hints for non-fast-forward errors · f25950f3
      Christopher Tiwald 提交于
      Pushing a non-fast-forward update to a remote repository will result in
      an error, but the hint text doesn't provide the correct resolution in
      every case. Give better resolution advice in three push scenarios:
      
      1) If you push your current branch and it triggers a non-fast-forward
      error, you should merge remote changes with 'git pull' before pushing
      again.
      
      2) If you push to a shared repository others push to, and your local
      tracking branches are not kept up to date, the 'matching refs' default
      will generate non-fast-forward errors on outdated branches. If this is
      your workflow, the 'matching refs' default is not for you. Consider
      setting the 'push.default' configuration variable to 'current' or
      'upstream' to ensure only your current branch is pushed.
      
      3) If you explicitly specify a ref that is not your current branch or
      push matching branches with ':', you will generate a non-fast-forward
      error if any pushed branch tip is out of date. You should checkout the
      offending branch and merge remote changes before pushing again.
      
      Teach transport.c to recognize these scenarios and configure push.c
      to hint for them. If 'git push's default behavior changes or we
      discover more scenarios, extension is easy. Standardize on the
      advice API and add three new advice variables, 'pushNonFFCurrent',
      'pushNonFFDefault', and 'pushNonFFMatching'. Setting any of these
      to 'false' will disable their affiliated advice. Setting
      'pushNonFastForward' to false will disable all three, thus preserving the
      config option for users who already set it, but guaranteeing new
      users won't disable push advice accidentally.
      Based-on-patch-by: NJunio C Hamano <gitster@pobox.com>
      Signed-off-by: NChristopher Tiwald <christiwald@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      f25950f3
  5. 11 3月, 2012 1 次提交
    • J
      ident.c: add split_ident_line() to parse formatted ident line · 4b340cfa
      Junio C Hamano 提交于
      The commit formatting logic format_person_part() in pretty.c
      implements the logic to split an author/committer ident line into
      its parts, intermixed with logic to compute its output using these
      piece it computes.
      
      Separate the former out to a helper function split_ident_line() so
      that other codepath can use the same logic, and rewrite the function
      using the helper function.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      4b340cfa
  6. 05 3月, 2012 1 次提交
    • R
      ctype.c: Fix a sparse warning · f1589d10
      Ramsay Jones 提交于
      In particular, sparse complains as follows:
      
              SP ctype.c
          ctype.c:30:12: warning: symbol 'tolower_trans_tbl' was not declared.\
               Should it be static?
      
      An appropriate extern declaration for the 'tolower_trans_tbl' symbol
      is included in the "cache.h" header file. In order to suppress the
      warning, therefore, we could replace the "git-compat-util.h" header
      inclusion with "cache.h", since "cache.h" includes "git-compat-util.h"
      in turn. Here, however, we choose to move the extern declaration for
      'tolower_trans_tbl' into "git-compat-util.h", alongside the other
      extern declaration from ctype.c for 'sane_ctype'.
      Signed-off-by: NRamsay Jones <ramsay@ramsay1.demon.co.uk>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      f1589d10
  7. 03 3月, 2012 1 次提交
  8. 29 2月, 2012 1 次提交
    • J
      grep: use static trans-case table · 0f871cf5
      Junio C Hamano 提交于
      In order to prepare the kwset machinery for a case-insensitive search, we
      used to use a static table of 256 elements and filled it every time before
      calling kwsalloc().  Because the kwset machinery will never modify this
      table, just allocate a single instance globally and fill it at the compile
      time.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      0f871cf5
  9. 17 2月, 2012 4 次提交
    • J
      config: add include directive · 9b25a0b5
      Jeff King 提交于
      It can be useful to split your ~/.gitconfig across multiple
      files. For example, you might have a "main" file which is
      used on many machines, but a small set of per-machine
      tweaks. Or you may want to make some of your config public
      (e.g., clever aliases) while keeping other data back (e.g.,
      your name or other identifying information). Or you may want
      to include a number of config options in some subset of your
      repos without copying and pasting (e.g., you want to
      reference them from the .git/config of participating repos).
      
      This patch introduces an include directive for config files.
      It looks like:
      
        [include]
          path = /path/to/file
      
      This is syntactically backwards-compatible with existing git
      config parsers (i.e., they will see it as another config
      entry and ignore it unless you are looking up include.path).
      
      The implementation provides a "git_config_include" callback
      which wraps regular config callbacks. Callers can pass it to
      git_config_from_file, and it will transparently follow any
      include directives, passing all of the discovered options to
      the real callback.
      
      Include directives are turned on automatically for "regular"
      git config parsing. This includes calls to git_config, as
      well as calls to the "git config" program that do not
      specify a single file (e.g., using "-f", "--global", etc).
      They are not turned on in other cases, including:
      
        1. Parsing of other config-like files, like .gitmodules.
           There isn't a real need, and I'd rather be conservative
           and avoid unnecessary incompatibility or confusion.
      
        2. Reading single files via "git config". This is for two
           reasons:
      
             a. backwards compatibility with scripts looking at
                config-like files.
      
             b. inspection of a specific file probably means you
      	  care about just what's in that file, not a general
                lookup for "do we have this value anywhere at
      	  all". If that is not the case, the caller can
      	  always specify "--includes".
      
        3. Writing files via "git config"; we want to treat
           include.* variables as literal items to be copied (or
           modified), and not expand them. So "git config
           --unset-all foo.bar" would operate _only_ on
           .git/config, not any of its included files (just as it
           also does not operate on ~/.gitconfig).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      9b25a0b5
    • J
      config: eliminate config_exclusive_filename · 4a7bb5ba
      Jeff King 提交于
      This is a magic global variable that was intended as an
      override to the usual git-config lookup process. Once upon a
      time, you could specify GIT_CONFIG to any git program, and
      it would look only at that file. This turned out to be
      confusing and cause a lot of bugs for little gain. As a
      result, dc871831 (Only use GIT_CONFIG in "git config", not
      other programs, 2008-06-30) took this away for all callers
      except git-config.
      
      Since git-config no longer uses it either, the variable can
      just go away. As the diff shows, nobody was setting to
      anything except NULL, so we can just replace any sites where
      it was read with NULL.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      4a7bb5ba
    • J
      config: provide a version of git_config with more options · c9b5e2a5
      Jeff King 提交于
      Callers may want to provide a specific version of a file in which to look
      for config. Right now this can be done by setting the magic global
      config_exclusive_filename variable.  By providing a version of git_config
      that takes a filename, we can take a step towards making this magic global
      go away.
      
      Furthermore, by providing a more "advanced" interface, we now have a a
      natural place to add new options for callers like git-config, which care
      about tweaking the specifics of config lookup, without disturbing the
      large number of "simple" users (i.e., every other part of git).
      
      The astute reader of this patch may notice that the logic for handling
      config_exclusive_filename was taken out of git_config_early, but added
      into git_config. This means that git_config_early will no longer respect
      config_exclusive_filename.  That's OK, because the only other caller of
      git_config_early is check_repository_format_gently, but the only function
      which sets config_exclusive_filename is cmd_config, which does not call
      check_repository_format_gently (and if it did, it would have been a bug,
      anyway, as we would be checking the repository format in the wrong file).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      c9b5e2a5
    • J
      config: teach git_config_rename_section a file argument · 42bd39b5
      Jeff King 提交于
      The other config-writing functions (git_config_set and
      git_config_set_multivar) each have an -"in_file" version to
      write a specific file. Let's add one for rename_section,
      with the eventual goal of moving away from the magic
      config_exclusive_filename global.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      42bd39b5
  10. 15 2月, 2012 1 次提交
  11. 14 2月, 2012 1 次提交
  12. 03 2月, 2012 1 次提交
    • J
      standardize and improve lookup rules for external local repos · b3256eb8
      Jeff King 提交于
      When you specify a local repository on the command line of
      clone, ls-remote, upload-pack, receive-pack, or upload-archive,
      or in a request to git-daemon, we perform a little bit of
      lookup magic, doing things like looking in working trees for
      .git directories and appending ".git" for bare repos.
      
      For clone, this magic happens in get_repo_path. For
      everything else, it happens in enter_repo. In both cases,
      there are some ambiguous or confusing cases that aren't
      handled well, and there is one case that is not handled the
      same by both methods.
      
      This patch tries to provide (and test!) standard, sensible
      lookup rules for both code paths. The intended changes are:
      
        1. When looking up "foo", we have always preferred
           a working tree "foo" (containing "foo/.git" over the
           bare "foo.git". But we did not prefer a bare "foo" over
           "foo.git". With this patch, we do so.
      
        2. We would select directories that existed but didn't
           actually look like git repositories. With this patch,
           we make sure a selected directory looks like a git
           repo. Not only is this more sensible in general, but it
           will help anybody who is negatively affected by change
           (1) negatively (e.g., if they had "foo.git" next to its
           separate work tree "foo", and expect to keep finding
           "foo.git" when they reference "foo").
      
        3. The enter_repo code path would, given "foo", look for
           "foo.git/.git" (i.e., do the ".git" append magic even
           for a repo with working tree). The clone code path did
           not; with this patch, they now behave the same.
      
      In the unlikely case of a working tree overlaying a bare
      repo (i.e., a ".git" directory _inside_ a bare repo), we
      continue to treat it as a working tree (prefering the
      "inner" .git over the bare repo). This is mainly because the
      combination seems nonsensical, and I'd rather stick with
      existing behavior on the off chance that somebody is relying
      on it.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      b3256eb8
  13. 09 1月, 2012 1 次提交
    • J
      server_supports(): parse feature list more carefully · f47182c8
      Junio C Hamano 提交于
      We have been carefully choosing feature names used in the protocol
      extensions so that the vocabulary does not contain a word that is a
      substring of another word, so it is not a real problem, but we have
      recently added "quiet" feature word, which would mean we cannot later
      add some other word with "quiet" (e.g. "quiet-push"), which is awkward.
      
      Let's make sure that we can eventually be able to do so by teaching the
      clients and servers that feature words consist of non whitespace
      letters. This parser also allows us to later add features with parameters
      e.g. "feature=1.5" (parameter values need to be quoted for whitespaces,
      but we will worry about the detauls when we do introduce them).
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      Signed-off-by: NClemens Buchacher <drizzd@aon.at>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      f47182c8
  14. 14 12月, 2011 4 次提交
  15. 13 12月, 2011 2 次提交
  16. 02 12月, 2011 1 次提交
  17. 14 11月, 2011 1 次提交
  18. 08 11月, 2011 1 次提交
    • J
      refs DWIMmery: use the same rule for both "git fetch" and others · dd621df9
      Junio C Hamano 提交于
      "git log frotz" can DWIM to "refs/remotes/frotz/HEAD", but in the remote
      access context, "git fetch frotz" to fetch what the other side happened to
      have fetched from what it calls 'frotz' (which may not have any relation
      to what we consider is 'frotz') the last time would not make much sense,
      so the fetch rules table did not include "refs/remotes/%.*s/HEAD".
      
      When the user really wants to, "git fetch $there remotes/frotz/HEAD" would
      let her do so anyway, so this is not about safety or security; it merely
      is about confusion avoidance and discouraging meaningless usage.
      
      Specifically, it is _not_ about ambiguity avoidance. A name that would
      become ambiguous if we use the same rules table for both fetch and local
      rev-parse would be ambiguous locally at the remote side.
      
      So for the same reason as we added rule to allow "git fetch $there v1.0"
      instead of "git fetch $there tags/v1.0" in the previous commit, here is a
      bit longer rope for the users, which incidentally simplifies our code.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      dd621df9
  19. 27 10月, 2011 2 次提交
  20. 15 10月, 2011 1 次提交
    • J
      pack-objects: protect against disappearing packs · 4c080182
      Jeff King 提交于
      It's possible that while pack-objects is running, a
      simultaneously running prune process might delete a pack
      that we are interested in. Because we load the pack indices
      early on, we know that the pack contains our item, but by
      the time we try to open and map it, it is gone.
      
      Since c715f783, we already protect against this in the normal
      object access code path, but pack-objects accesses the packs
      at a lower level.  In the normal access path, we call
      find_pack_entry, which will call find_pack_entry_one on each
      pack index, which does the actual lookup. If it gets a hit,
      we will actually open and verify the validity of the
      matching packfile (using c715f783's is_pack_valid). If we
      can't open it, we'll issue a warning and pretend that we
      didn't find it, causing us to go on to the next pack (or on
      to loose objects).
      
      Furthermore, we will cache the descriptor to the opened
      packfile. Which means that later, when we actually try to
      access the object, we are likely to still have that packfile
      opened, and won't care if it has been unlinked from the
      filesystem.
      
      Notice the "likely" above. If there is another pack access
      in the interim, and we run out of descriptors, we could
      close the pack. And then a later attempt to access the
      closed pack could fail (we'll try to re-open it, of course,
      but it may have been deleted). In practice, this doesn't
      happen because we tend to look up items and then access them
      immediately.
      
      Pack-objects does not follow this code path. Instead, it
      accesses the packs at a much lower level, using
      find_pack_entry_one directly. This means we skip the
      is_pack_valid check, and may end up with the name of a
      packfile, but no open descriptor.
      
      We can add the same is_pack_valid check here. Unfortunately,
      the access patterns of pack-objects are not quite as nice
      for keeping lookup and object access together. We look up
      each object as we find out about it, and the only later when
      writing the packfile do we necessarily access it. Which
      means that the opened packfile may be closed in the interim.
      
      In practice, however, adding this check still has value, for
      three reasons.
      
        1. If you have a reasonable number of packs and/or a
           reasonable file descriptor limit, you can keep all of
           your packs open simultaneously. If this is the case,
           then the race is impossible to trigger.
      
        2. Even if you can't keep all packs open at once, you
           may end up keeping the deleted one open (i.e., you may
           get lucky).
      
        3. The race window is shortened. You may notice early that
           the pack is gone, and not try to access it. Triggering
           the problem without this check means deleting the pack
           any time after we read the list of index files, but
           before we access the looked-up objects.  Triggering it
           with this check means deleting the pack means deleting
           the pack after we do a lookup (and successfully access
           the packfile), but before we access the object. Which
           is a smaller window.
      Acked-by: NNicolas Pitre <nico@fluxnic.net>
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      4c080182
  21. 08 10月, 2011 1 次提交
    • J
      fix phantom untracked files when core.ignorecase is set · 2548183b
      Jeff King 提交于
      When core.ignorecase is turned on and there are stale index
      entries, "git commit" can sometimes report directories as
      untracked, even though they contain tracked files.
      
      You can see an example of this with:
      
          # make a case-insensitive repo
          git init repo && cd repo &&
          git config core.ignorecase true &&
      
          # with some tracked files in a subdir
          mkdir subdir &&
          > subdir/one &&
          > subdir/two &&
          git add . &&
          git commit -m base &&
      
          # now make the index entries stale
          touch subdir/* &&
      
          # and then ask commit to update those entries and show
          # us the status template
          git commit -a
      
      which will report "subdir/"  as untracked, even though it
      clearly contains two tracked files. What is happening in the
      commit program is this:
      
        1. We load the index, and for each entry, insert it into the index's
           name_hash. In addition, if ignorecase is turned on, we make an
           entry in the name_hash for the directory (e.g., "contrib/"), which
           uses the following code from 5102c617's hash_index_entry_directories:
      
              hash = hash_name(ce->name, ptr - ce->name);
              if (!lookup_hash(hash, &istate->name_hash)) {
                      pos = insert_hash(hash, &istate->name_hash);
      		if (pos) {
      			ce->next = *pos;
      			*pos = ce;
      		}
              }
      
           Note that we only add the directory entry if there is not already an
           entry.
      
        2. We run add_files_to_cache, which gets updated information for each
           cache entry. It helpfully inserts this information into the cache,
           which calls replace_index_entry. This in turn calls
           remove_name_hash() on the old entry, and add_name_hash() on the new
           one. But remove_name_hash doesn't actually remove from the hash, it
           only marks it as "no longer interesting" (from cache.h):
      
            /*
             * We don't actually *remove* it, we can just mark it invalid so that
             * we won't find it in lookups.
             *
             * Not only would we have to search the lists (simple enough), but
             * we'd also have to rehash other hash buckets in case this makes the
             * hash bucket empty (common). So it's much better to just mark
             * it.
             */
            static inline void remove_name_hash(struct cache_entry *ce)
            {
                    ce->ce_flags |= CE_UNHASHED;
            }
      
           This is OK in the specific-file case, since the entries in the hash
           form a linked list, and we can just skip the "not here anymore"
           entries during lookup.
      
           But for the directory hash entry, we will _not_ write a new entry,
           because there is already one there: the old one that is actually no
           longer interesting!
      
        3. While traversing the directories, we end up in the
           directory_exists_in_index_icase function to see if a directory is
           interesting. This in turn checks index_name_exists, which will
           look up the directory in the index's name_hash. We see the old,
           deleted record, and assume there is nothing interesting. The
           directory gets marked as untracked, even though there are index
           entries in it.
      
      The problem is in the code I showed above:
      
              hash = hash_name(ce->name, ptr - ce->name);
              if (!lookup_hash(hash, &istate->name_hash)) {
                      pos = insert_hash(hash, &istate->name_hash);
      		if (pos) {
      			ce->next = *pos;
      			*pos = ce;
      		}
              }
      
      Having a single cache entry that represents the directory is
      not enough; that entry may go away if the index is changed.
      It may be tempting to say that the problem is in our removal
      method; if we removed the entry entirely instead of simply
      marking it as "not here anymore", then we would know we need
      to insert a new entry. But that only covers this particular
      case of remove-replace. In the more general case, consider
      something like this:
      
        1. We add "foo/bar" and "foo/baz" to the index. Each gets
           their own entry in name_hash, plus we make a "foo/"
           entry that points to "foo/bar".
      
        2. We remove the "foo/bar" entry from the index, and from
           the name_hash.
      
        3. We ask if "foo/" exists, and see no entry, even though
           "foo/baz" exists.
      
      So we need that directory entry to have the list of _all_
      cache entries that indicate that the directory is tracked.
      So that implies making a linked list as we do for other
      entries, like:
      
        hash = hash_name(ce->name, ptr - ce->name);
        pos = insert_hash(hash, &istate->name_hash);
        if (pos) {
      	  ce->next = *pos;
      	  *pos = ce;
        }
      
      But that's not right either. In fact, it shows a second bug
      in the current code, which is that the "ce->next" pointer is
      supposed to be linking entries for a specific filename
      entry, but here we are overwriting it for the directory
      entry. So the same cache entry ends up in two linked lists,
      but they share the same "next" pointer.
      
      As it turns out, this second bug can't be triggered in the
      current code. The "if (pos)" conditional is totally dead
      code; pos will only be non-NULL if there was an existing
      hash entry, and we already checked that there wasn't one
      through our call to lookup_hash.
      
      But fixing the first bug means taking out that call to
      lookup_hash, which is going to activate the buggy dead code,
      and we'll end up splicing the two linked lists together.
      
      So we need to have a separate next pointer for the list in
      the directory bucket, and we need to traverse that list in
      index_name_exists when we are looking up a directory.
      
      This bloats "struct cache_entry" by a few bytes. Which is
      annoying, because it's only necessary when core.ignorecase
      is enabled. There's not an easy way around it, short of
      separating out the "next" pointers from cache_entry entirely
      (i.e., having a separate "cache_entry_list" struct that gets
      stored in the name_hash). In practice, it probably doesn't
      matter; we have thousands of cache entries, compared to the
      millions of objects (where adding 4 bytes to the struct
      actually does impact performance).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      2548183b
  22. 07 10月, 2011 1 次提交
    • J
      attr: read core.attributesfile from git_default_core_config · 64589a03
      Junio C Hamano 提交于
      This code calls git_config from a helper function to parse the config entry
      it is interested in.  Calling git_config in this way may cause a problem if
      the helper function can be called after a previous call to git_config by
      another function since the second call to git_config may reset some
      variable to the value in the config file which was previously overridden.
      
      The above is not a problem in this case since the function passed to
      git_config only parses one config entry and the variable it sets is not
      assigned outside of the parsing function.  But a programmer who desires
      all of the standard config options to be parsed may be tempted to modify
      git_attr_config() so that it falls back to git_default_config() and then it
      _would_ be vulnerable to the above described behavior.
      
      So, move the call to git_config up into the top-level cmd_* function and
      move the responsibility for parsing core.attributesfile into the main
      config file parser.
      
      Which is only the logical thing to do ;-)
      Signed-off-by: NBrandon Casey <drafnel@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      64589a03
  23. 06 10月, 2011 2 次提交
  24. 05 10月, 2011 1 次提交
  25. 13 9月, 2011 1 次提交
  26. 07 9月, 2011 1 次提交
  27. 23 8月, 2011 1 次提交
  28. 17 8月, 2011 1 次提交
  29. 12 8月, 2011 1 次提交
    • C
      ls-files: fix pathspec display on error · 0f64bfa9
      Clemens Buchacher 提交于
      The following sequence of commands reveals an issue with error
      reporting of relative paths:
      
       $ mkdir sub
       $ cd sub
       $ git ls-files --error-unmatch ../bbbbb
       error: pathspec 'b' did not match any file(s) known to git.
       $ git commit --error-unmatch ../bbbbb
       error: pathspec 'b' did not match any file(s) known to git.
      
      This bug is visible only if the normalized path (i.e., the relative
      path from the repository root) is longer than the prefix.
      Otherwise, the code skips over the normalized path and reads from
      an unused memory location which still contains a leftover of the
      original command line argument.
      
      So instead, use the existing facilities to deal with relative paths
      correctly.
      
      Also fix inconsistency between "checkout" and "commit", e.g.
      
          $ cd Documentation
          $ git checkout nosuch.txt
          error: pathspec 'Documentation/nosuch.txt' did not match...
          $ git commit nosuch.txt
          error: pathspec 'nosuch.txt' did not match...
      
      by propagating the prefix down the codepath that reports the error.
      Signed-off-by: NClemens Buchacher <drizzd@aon.at>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      0f64bfa9
  30. 05 8月, 2011 1 次提交
  31. 03 8月, 2011 1 次提交
    • C
      commit: allow partial commits with relative paths · 8894d535
      Clemens Buchacher 提交于
      In order to do partial commits, git-commit overlays a tree on the
      cache and checks pathspecs against the result. Currently, the
      overlaying is done using "prefix" which prevents relative pathspecs
      with ".." and absolute pathspec from matching when they refer to
      files not under "prefix" and absent from the index, but still in
      the tree (i.e.  files staged for removal).
      
      The point of providing a prefix at all is performance optimization.
      If we say there is no common prefix for the files of interest, then
      we have to read the entire tree into the index.
      
      But even if we cannot use the working directory as a prefix, we can
      still figure out if there is a common prefix for all given paths,
      and use that instead. The pathspec_prefix() routine from ls-files.c
      does exactly that.
      
      Any use of global variables is removed from pathspec_prefix() so
      that it can be called from commit.c.
      Reported-by: NReuben Thomas <rrt@sc3d.org>
      Analyzed-by: NMichael J Gruber <git@drmicha.warpmail.net>
      Signed-off-by: NClemens Buchacher <drizzd@aon.at>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      8894d535