1. 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
  2. 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
  3. 03 3月, 2012 1 次提交
  4. 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
  5. 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
  6. 15 2月, 2012 1 次提交
  7. 14 2月, 2012 1 次提交
  8. 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
  9. 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
  10. 14 12月, 2011 4 次提交
  11. 13 12月, 2011 2 次提交
  12. 02 12月, 2011 1 次提交
  13. 14 11月, 2011 1 次提交
  14. 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
  15. 27 10月, 2011 2 次提交
  16. 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
  17. 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
  18. 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
  19. 06 10月, 2011 2 次提交
  20. 05 10月, 2011 1 次提交
  21. 13 9月, 2011 1 次提交
  22. 07 9月, 2011 1 次提交
  23. 23 8月, 2011 1 次提交
  24. 17 8月, 2011 1 次提交
  25. 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
  26. 05 8月, 2011 1 次提交
  27. 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
  28. 07 7月, 2011 2 次提交
    • J
      core: log offset pack data accesses happened · 5f44324d
      Junio C Hamano 提交于
      In a workload other than "git log" (without pathspec nor any option that
      causes us to inspect trees and blobs), the recency pack order is said to
      cause the access jump around quite a bit. Add a hook to allow us observe
      how bad it is.
      
      "git config core.logpackaccess /var/tmp/pal.txt" will give you the log
      in the specified file.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      5f44324d
    • J
      ref namespaces: infrastructure · a1bea2c1
      Josh Triplett 提交于
      Add support for dividing the refs of a single repository into multiple
      namespaces, each of which can have its own branches, tags, and HEAD.
      Git can expose each namespace as an independent repository to pull from
      and push to, while sharing the object store, and exposing all the refs
      to operations such as git-gc.
      
      Storing multiple repositories as namespaces of a single repository
      avoids storing duplicate copies of the same objects, such as when
      storing multiple branches of the same source.  The alternates mechanism
      provides similar support for avoiding duplicates, but alternates do not
      prevent duplication between new objects added to the repositories
      without ongoing maintenance, while namespaces do.
      
      To specify a namespace, set the GIT_NAMESPACE environment variable to
      the namespace.  For each ref namespace, git stores the corresponding
      refs in a directory under refs/namespaces/.  For example,
      GIT_NAMESPACE=foo will store refs under refs/namespaces/foo/.  You can
      also specify namespaces via the --namespace option to git.
      
      Note that namespaces which include a / will expand to a hierarchy of
      namespaces; for example, GIT_NAMESPACE=foo/bar will store refs under
      refs/namespaces/foo/refs/namespaces/bar/.  This makes paths in
      GIT_NAMESPACE behave hierarchically, so that cloning with
      GIT_NAMESPACE=foo/bar produces the same result as cloning with
      GIT_NAMESPACE=foo and cloning from that repo with GIT_NAMESPACE=bar.  It
      also avoids ambiguity with strange namespace paths such as
      foo/refs/heads/, which could otherwise generate directory/file conflicts
      within the refs directory.
      
      Add the infrastructure for ref namespaces: handle the GIT_NAMESPACE
      environment variable and --namespace option, and support iterating over
      refs in a namespace.
      Signed-off-by: NJosh Triplett <josh@joshtriplett.org>
      Signed-off-by: NJamey Sharp <jamey@minilop.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      a1bea2c1
  29. 23 6月, 2011 1 次提交
  30. 11 6月, 2011 1 次提交
    • J
      zlib: zlib can only process 4GB at a time · ef49a7a0
      Junio C Hamano 提交于
      The size of objects we read from the repository and data we try to put
      into the repository are represented in "unsigned long", so that on larger
      architectures we can handle objects that weigh more than 4GB.
      
      But the interface defined in zlib.h to communicate with inflate/deflate
      limits avail_in (how many bytes of input are we calling zlib with) and
      avail_out (how many bytes of output from zlib are we ready to accept)
      fields effectively to 4GB by defining their type to be uInt.
      
      In many places in our code, we allocate a large buffer (e.g. mmap'ing a
      large loose object file) and tell zlib its size by assigning the size to
      avail_in field of the stream, but that will truncate the high octets of
      the real size. The worst part of this story is that we often pass around
      z_stream (the state object used by zlib) to keep track of the number of
      used bytes in input/output buffer by inspecting these two fields, which
      practically limits our callchain to the same 4GB limit.
      
      Wrap z_stream in another structure git_zstream that can express avail_in
      and avail_out in unsigned long. For now, just die() when the caller gives
      a size that cannot be given to a single zlib call. In later patches in the
      series, we would make git_inflate() and git_deflate() internally loop to
      give callers an illusion that our "improved" version of zlib interface can
      operate on a buffer larger than 4GB in one go.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      ef49a7a0