1. 24 8月, 2016 1 次提交
  2. 29 7月, 2016 1 次提交
    • V
      i18n: config: unfold error messages marked for translation · 1b8132d9
      Vasco Almeida 提交于
      Introduced in 473166b9 ("config: add 'origin_type' to config_source
      struct", 2016-02-19), Git can inform the user about the origin of a
      config error, but the implementation does not allow translators to
      translate the keywords 'file', 'blob, 'standard input', and
      'submodule-blob'. Moreover, for the second message, a reason for the
      error is appended to the message, not allowing translators to translate
      that reason either.
      
      Unfold the message into several templates for each known origin_type.
      That would result in better translation at the expense of code
      verbosity.
      
      Add enum config_oringin_type to ease management of the various
      configuration origin types (blob, file, etc).  Previously origin type
      was considered from command line if cf->origin_type == NULL, i.e.,
      uninitialized. Now we set origin_type to CONFIG_ORIGIN_CMDLINE in
      git_config_from_parameters() and configset_add_value().
      
      For error message in git_parse_source(), use xstrfmt() function to
      prepare the message string, instead of doing something like it's done
      for die_bad_number(), because intelligibility and code conciseness are
      improved for that instance.
      Signed-off-by: NVasco Almeida <vascomalmeida@sapo.pt>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      1b8132d9
  3. 11 6月, 2016 1 次提交
  4. 28 5月, 2016 2 次提交
    • J
      config: add a notion of "scope" · 9acc5911
      Jeff King 提交于
      A config callback passed to git_config() doesn't know very
      much about the context in which it sees a variable. It can
      ask whether the variable comes from a file, and get the file
      name. But without analyzing the filename (which is hard to
      do accurately), it cannot tell whether it is in system-level
      config, user-level config, or repo-specific config.
      
      Generally this doesn't matter; the point of not passing this
      to the callback is that it should treat the config the same
      no matter where it comes from. But some programs, like
      upload-pack, are a special case: we should be able to run
      them in an untrusted repository, which means we cannot use
      any "dangerous" config from the repository config file (but
      it is OK to use it from system or user config).
      
      This patch teaches the config code to record the "scope" of
      each variable, and make it available inside config
      callbacks, similar to how we give access to the filename.
      The scope is the starting source for a particular parsing
      operation, and remains the same even if we include other
      files (so a .git/config which includes another file will
      remain CONFIG_SCOPE_REPO, as it would be similarly
      untrusted).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      9acc5911
    • J
      config: return configset value for current_config_ functions · 0d44a2da
      Jeff King 提交于
      When 473166b9 (config: add 'origin_type' to config_source
      struct, 2016-02-19) added accessor functions for the origin
      type and name, it taught them only to look at the "cf"
      struct that is filled in while we are parsing the config.
      This is sufficient to make it work with git-config, which
      uses git_config_with_options() under the hood. That function
      freshly parses the config files and triggers the callback
      when it parses each key.
      
      Most git programs, however, use git_config(). This interface
      will populate a cache during the actual parse, and then
      serve values from the cache. Calling current_config_filename()
      in a callback here will find a NULL cf and produce an error.
      There are no such callers right now, but let's prepare for
      adding some by making this work.
      
      We already record source information in a struct attached to
      each value. We just need to make it globally available and
      then consult it from the accessor functions.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      0d44a2da
  5. 25 5月, 2016 3 次提交
    • J
      config: set up config_source for command-line config · 3258258f
      Jeff King 提交于
      When we parse a config file, we set up the global "cf"
      variable as a pointer to a "struct config_source" describing
      the file we are parsing. This is used for error messages, as
      well as for lookup functions like current_config_name().
      
      The "cf" variable is NULL in two cases:
      
        1. When we are parsing command-line config, in which case
           there is no source file.
      
        2. When we are not parsing any config at all.
      
      Callers like current_config_name() must assume we are in
      case 1 if they see a NULL "cf". However, this means that if
      they are accidentally used outside of a config parsing
      callback, they will quietly return a bogus answer.
      
      This might seem like an unlikely accident (why would you ask
      for the current config file if you are not parsing config?),
      but it's actually an easy mistake to make due to the
      configset caching. git_config() serves the answers from a
      configset cache, and any calls to current_config_name() will
      claim that we are parsing command-line config, no matter
      what the original source.
      
      So let's distinguish these cases by having the command-line
      config parser set up a config_source with a NULL name (which
      callers already handle properly). We can use this to catch
      programming errors in some cases, and to give better
      messages to the user in others.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      3258258f
    • J
      git_config_parse_parameter: refactor cleanup code · a77d6db6
      Jeff King 提交于
      We have several exits from the function, each of which has
      to do some cleanup. Let's consolidate these in an "out"
      label we can jump to. This doesn't save us much now, but it
      will help as we add more things that need cleanup.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      a77d6db6
    • J
      git_config_with_options: drop "found" counting · c72ee44b
      Jeff King 提交于
      Prior to 1f2baa78 (config: treat non-existent config files as
      empty, 2010-10-21), we returned an error if any config files
      were missing. That commit made this a non-error, but
      returned the number of sources found, in case any caller
      wanted to distinguish this case.
      
      In the past 5+ years, no caller has; the only two places
      which bother to check the return value care only about the
      error case.  Let's drop this code, which complicates the
      function. Similarly, let's drop the "found anything" return
      from git_config_from_parameters, which was present only to
      support this (and similarly has never had other callers care
      for the past 5+ years).
      
      Note that we do need to update a comment in one of the
      callers, even though the code immediately below it doesn't
      care about this case.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      c72ee44b
  6. 12 5月, 2016 1 次提交
    • J
      mingw: introduce the 'core.hideDotFiles' setting · f30afdab
      Johannes Schindelin 提交于
      On Unix (and Linux), files and directories whose names start with a dot
      are usually not shown by default. This convention is used by Git: the
      .git/ directory should be left alone by regular users, and only accessed
      through Git itself.
      
      On Windows, no such convention exists. Instead, there is an explicit flag
      to mark files or directories as hidden.
      
      In the early days, Git for Windows did not mark the .git/ directory (or
      for that matter, any file or directory whose name starts with a dot)
      hidden. This lead to quite a bit of confusion, and even loss of data.
      
      Consequently, Git for Windows introduced the core.hideDotFiles setting,
      with three possible values: true, false, and dotGitOnly, defaulting to
      marking only the .git/ directory as hidden.
      
      The rationale: users do not need to access .git/ directly, and indeed (as
      was demonstrated) should not really see that directory, either. However,
      not all dot files should be hidden by default, as e.g. Eclipse does not
      show them (and the user would therefore be unable to see, say, a
      .gitattributes file).
      
      In over five years since the last attempt to bring this patch into core
      Git, a slightly buggy version of this patch has served Git for Windows'
      users well: no single report indicated problems with the hidden .git/
      directory, and the stream of problems caused by the previously non-hidden
      .git/ directory simply stopped. The bugs have been fixed during the
      process of getting this patch upstream.
      
      Note that there is a funny quirk we have to pay attention to when
      creating hidden files: we use Win32's _wopen() function which
      transmogrifies its arguments and hands off to Win32's CreateFile()
      function. That latter function errors out with ERROR_ACCESS_DENIED (the
      equivalent of EACCES) when the equivalent of the O_CREAT flag was passed
      and the file attributes (including the hidden flag) do not match an
      existing file's. And _wopen() accepts no parameter that would be
      transmogrified into said hidden flag. Therefore, we simply try again
      without O_CREAT.
      
      A slightly different method is required for our fopen()/freopen()
      function as we cannot even *remove* the implicit O_CREAT flag.
      Therefore, we briefly mark existing files as unhidden when opening them
      via fopen()/freopen().
      
      The ERROR_ACCESS_DENIED error can also be triggered by opening a file
      that is marked as a system file (which is unlikely to be tracked in
      Git), and by trying to create a file that has *just* been deleted and is
      awaiting the last open handles to be released (which would be handled
      better by the "Try again?" logic, a story for a different patch series,
      though). In both cases, it does not matter much if we try again without
      the O_CREAT flag, read: it does not hurt, either.
      
      For details how ERROR_ACCESS_DENIED can be triggered, see
      https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858Original-patch-by: NErik Faye-Lund <kusmabite@gmail.com>
      Initial-Test-By: NPat Thoyts <patthoyts@users.sourceforge.net>
      Signed-off-by: NJohannes Schindelin <johannes.schindelin@gmx.de>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      f30afdab
  7. 10 5月, 2016 1 次提交
  8. 05 5月, 2016 1 次提交
    • Æ
      hooks: allow customizing where the hook directory is · 867ad08a
      Ævar Arnfjörð Bjarmason 提交于
      Change the hardcoded lookup for .git/hooks/* to optionally lookup in
      $(git config core.hooksPath)/* instead.
      
      This is essentially a more intrusive version of the git-init ability to
      specify hooks on init time via init templates.
      
      The difference between that facility and this feature is that this can
      be set up after the fact via e.g. ~/.gitconfig or /etc/gitconfig to
      apply for all your personal repositories, or all repositories on the
      system.
      
      I plan on using this on a centralized Git server where users can create
      arbitrary repositories under /gitroot, but I'd like to manage all the
      hooks that should be run centrally via a unified dispatch mechanism.
      Signed-off-by: NÆvar Arnfjörð Bjarmason <avarab@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      867ad08a
  9. 29 4月, 2016 1 次提交
  10. 26 4月, 2016 1 次提交
  11. 11 4月, 2016 3 次提交
    • J
      git_config_set_multivar_in_file: handle "unset" errors · 1cae428e
      Jeff King 提交于
      We pass off to the "_gently" form to do the real work, and
      just die() if it returned an error. However, our die message
      de-references "value", which may be NULL if the request was
      to unset a variable. Nobody using glibc noticed, because it
      simply prints "(null)", which is good enough for the test
      suite (and presumably very few people run across this in
      practice). But other libc implementations (like Solaris) may
      segfault.
      
      Let's not only fix that, but let's make the message more
      clear about what is going on in the "unset" case.
      Reported-by: N"Tom G. Christensen" <tgc@jupiterrise.com>
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      1cae428e
    • J
      git_config_set_multivar_in_file: all non-zero returns are errors · 9c14bb08
      Jeff King 提交于
      This function is just a thin wrapper for the "_gently" form
      of the function. But the gently form is designed to feed
      builtin/config.c, which passes our return code directly to
      its exit status, and thus uses positive error values for
      some cases. We check only negative values, meaning we would
      fail to die in some cases (e.g., a malformed key).
      
      This may or may not be triggerable in practice; we tend to
      use this non-gentle form only when setting internal
      variables, which would not have malformed keys.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      9c14bb08
    • J
      config: lower-case first word of error strings · 8c3ca351
      Jeff King 提交于
      This follows our usual style (both throughout git, and
      throughout the rest of this file).
      
      This covers the whole file, but note that I left the capitalization in
      the multi-sentence:
      
        error: malformed value...
        error: Must be one of ...
      
      because it helps make it clear that we are starting a new sentence in
      the second one.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      8c3ca351
  12. 24 3月, 2016 1 次提交
    • J
      git_config_push_parameter: handle empty GIT_CONFIG_PARAMETERS · d1f88498
      Jeff King 提交于
      The "git -c var=value" option stuffs the config value into
      $GIT_CONFIG_PARAMETERS, so that sub-processes can see it.
      When the config is later read via git_config() or similar,
      we parse it back out of that variable.  The parsing end is a
      little bit picky; it assumes that each entry was generated
      with sq_quote_buf(), and that there is no extraneous
      whitespace.
      
      On the generating end, we are careful to append to an
      existing $GIT_CONFIG_PARAMETERS variable if it exists.
      However, our test for "should we add a space separator" is
      too liberal: it will add one even if the environment
      variable exists but is empty. As a result, you might end up
      with:
      
         GIT_CONFIG_PARAMETERS=" 'core.foo=bar'"
      
      which the parser will choke on.
      
      This was hard to trigger in older versions of git, since we
      only set the variable when we had something to put into it
      (though you could certainly trigger it manually). But since
      14111fc4 (git: submodule honor -c credential.* from command
      line, 2016-02-29), the submodule code will unconditionally
      put the $GIT_CONFIG_PARAMETERS variable into the environment
      of any operation in the submodule, whether it is empty or
      not. So any of those operations which themselves use "git
      -c" will generate the unparseable value and fail.
      
      We can easily fix it by catching this case on the generating
      side. While we're adding a test, let's also check that
      multiple layers of "git -c" work, which was previously not
      tested at all.
      Reported-by: NShin Fan <shinfan@google.com>
      Signed-off-by: NJeff King <peff@peff.net>
      Reviewed-by: NJonathan Nieder <jrnieder@gmail.com>
      Tested-by: NJonathan Nieder <jrnieder@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      d1f88498
  13. 12 3月, 2016 1 次提交
  14. 23 2月, 2016 4 次提交
  15. 20 2月, 2016 1 次提交
  16. 17 2月, 2016 1 次提交
    • P
      config: introduce set_or_die wrappers · b4c8aba6
      Patrick Steinhardt 提交于
      A lot of call-sites for the existing family of `git_config_set`
      functions do not check for errors that may occur, e.g. when the
      configuration file is locked. In many cases we simply want to die
      when such a situation arises.
      
      Introduce wrappers that will cause the program to die in those
      cases. These wrappers are temporary only to ease the transition
      to let `git_config_set` die by default. They will be removed
      later on when `git_config_set` itself has been replaced by
      `git_config_set_gently`.
      Signed-off-by: NPatrick Steinhardt <ps@pks.im>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      b4c8aba6
  17. 28 1月, 2016 2 次提交
    • C
      test-dump-untracked-cache: don't modify the untracked cache · dae6c322
      Christian Couder 提交于
      To correctly perform its testing function,
      test-dump-untracked-cache should not change the state of the
      untracked cache in the index.
      
      As a previous patch makes read_index_from() change the state of
      the untracked cache and as test-dump-untracked-cache indirectly
      calls this function, we need a mechanism to prevent
      read_index_from() from changing the untracked cache state when
      it's called from test-dump-untracked-cache.
      Signed-off-by: NChristian Couder <chriscool@tuxfamily.org>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      dae6c322
    • C
      config: add core.untrackedCache · 435ec090
      Christian Couder 提交于
      When we know that mtime on directory as given by the environment
      is usable for the purpose of untracked cache, we may want the
      untracked cache to be always used without any mtime test or
      kernel name check being performed.
      
      Also when we know that mtime is not usable for the purpose of
      untracked cache, for example because the repo is shared over a
      network file system, we may want the untracked-cache to be
      automatically removed from the index.
      
      Allow the user to express such preference by setting the
      'core.untrackedCache' configuration variable, which can take
      'keep', 'false', or 'true' and default to 'keep'.
      
      When read_index_from() is called, it now adds or removes the
      untracked cache in the index to respect the value of this
      variable. So it does nothing if the value is `keep` or if the
      variable is unset; it adds the untracked cache if the value is
      `true`; and it removes the cache if the value is `false`.
      
      `git update-index --[no-|force-]untracked-cache` still adds the
      untracked cache to, or removes it, from the index, but this
      shows a warning if it goes against the value of
      core.untrackedCache, because the next time the index is read
      the untracked cache will be added or removed if the
      configuration is set to do so.
      
      Also `--untracked-cache` used to check that the underlying
      operating system and file system change `st_mtime` field of a
      directory if files are added or deleted in that directory. But
      because those tests take a long time, `--untracked-cache` no
      longer performs them. Instead, there is now
      `--test-untracked-cache` to perform the tests. This change
      makes `--untracked-cache` the same as `--force-untracked-cache`.
      
      This last change is backward incompatible and should be
      mentioned in the release notes.
      Helped-by: NDuy Nguyen <pclouds@gmail.com>
      Helped-by: NTorsten Bögershausen <tboegi@web.de>
      Helped-by: NStefan Beller <sbeller@google.com>
      Signed-off-by: NChristian Couder <chriscool@tuxfamily.org>
      Signed-off-by: NÆvar Arnfjörð Bjarmason <avarab@gmail.com>
      
      read-cache: Duy'sfixup
      Signed-off-by: NChristian Couder <chriscool@tuxfamily.org>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      435ec090
  18. 02 12月, 2015 1 次提交
    • S
      Make error message after failing commit_lock_file() less confusing · 08a3651f
      SZEDER Gábor 提交于
      The error message after a failing commit_lock_file() call sometimes
      looks like this, causing confusion:
      
        $ git remote add remote git@server.com/repo.git
        error: could not commit config file .git/config
        # Huh?!
        # I didn't want to commit anything, especially not my config file!
      
      While in the narrow context of the lockfile module using the verb
      'commit' in the error message makes perfect sense, in the broader
      context of git the word 'commit' already has a very specific meaning,
      hence the confusion.
      
      Reword these error messages to say "could not write" instead of "could
      not commit".
      
      While at it, include strerror in the error messages after writing the
      config file or the credential store fails to provide some information
      about the cause of the failure, and update the style of the error
      message after writing the reflog fails to match surrounding error
      messages (i.e. no '' around the pathname and no () around the error
      description).
      Signed-off-by: NSZEDER Gábor <szeder@ira.uka.de>
      Signed-off-by: NJeff King <peff@peff.net>
      08a3651f
  19. 24 8月, 2015 1 次提交
    • J
      config: silence warnings for command names with invalid keys · 9e9de18f
      Jeff King 提交于
      When we are running the git command "foo", we may have to
      look up the config keys "pager.foo" and "alias.foo". These
      config schemes are mis-designed, as the command names can be
      anything, but the config syntax has some restrictions. For
      example:
      
        $ git foo_bar
        error: invalid key: pager.foo_bar
        error: invalid key: alias.foo_bar
        git: 'foo_bar' is not a git command. See 'git --help'.
      
      You cannot name an alias with an underscore. And if you have
      an external command with one, you cannot configure its
      pager.
      
      In the long run, we may develop a different config scheme
      for these features. But in the near term (and because we'll
      need to support the existing scheme indefinitely), we should
      at least squelch the error messages shown above.
      
      These errors come from git_config_parse_key. Ideally we
      would pass a "quiet" flag to the config machinery, but there
      are many layers between the pager code and the key parsing.
      Passing a flag through all of those would be an invasive
      change.
      
      Instead, let's provide a config function to report on
      whether a key is syntactically valid, and have the pager and
      alias code skip lookup for bogus keys. We can build this
      easily around the existing git_config_parse_key, with two
      minor modifications:
      
        1. We now handle a NULL store_key, to validate but not
           write out the normalized key.
      
        2. We accept a "quiet" flag to avoid writing to stderr.
           This doesn't need to be a full-blown public "flags"
           field, because we can make the existing implementation
           a static helper function, keeping the mess contained
           inside config.c.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      9e9de18f
  20. 20 8月, 2015 1 次提交
  21. 15 8月, 2015 1 次提交
  22. 11 8月, 2015 1 次提交
  23. 01 7月, 2015 1 次提交
  24. 29 5月, 2015 3 次提交
    • J
      config.c: rewrite ENODEV into EISDIR when mmap fails · 0e8771f1
      Jeff King 提交于
      If we try to mmap a directory, we'll get ENODEV. This
      translates to "no such device" for the user, which is not
      very helpful. Since we've just fstat()'d the file, we can
      easily check whether the problem was a directory to give a
      better message.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      0e8771f1
    • J
      config.c: avoid xmmap error messages · 1570856b
      Jeff King 提交于
      The config-writing code uses xmmap to map the existing
      config file, which will die if the map fails. This has two
      downsides:
      
        1. The error message is not very helpful, as it lacks any
           context about the file we are mapping:
      
             $ mkdir foo
             $ git config --file=foo some.key value
             fatal: Out of memory? mmap failed: No such device
      
        2. We normally do not die in this code path; instead, we'd
           rather report the error and return an appropriate exit
           status (which is part of the public interface
           documented in git-config.1).
      
      This patch introduces a "gentle" form of xmmap which lets us
      produce our own error message. We do not want to use mmap
      directly, because we would like to use the other
      compatibility elements of xmmap (e.g., handling 0-length
      maps portably).
      
      The end result is:
      
          $ git.compile config --file=foo some.key value
          error: unable to mmap 'foo': No such device
          $ echo $?
          3
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      1570856b
    • J
      config.c: fix mmap leak when writing config · 3a1b3126
      Jeff King 提交于
      We mmap the existing config file, but fail to unmap it if we
      hit an error. The function already has a shared exit path,
      so we can fix this by moving the mmap pointer to the
      function scope and clearing it in the shared exit.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      3a1b3126
  25. 07 5月, 2015 1 次提交
  26. 17 4月, 2015 1 次提交
  27. 16 4月, 2015 1 次提交
    • J
      config: use getc_unlocked when reading from file · 260d408e
      Jeff King 提交于
      We read config files character-by-character from a stdio
      handle using fgetc(). This incurs significant locking
      overhead, even though we know that only one thread can
      possibly access the handle. We can speed this up by taking
      the lock ourselves, and then using getc_unlocked to read
      each character.
      
      On a silly pathological case:
      
        perl -le '
          print "[core]";
          print "key$_ = value$_" for (1..1000000)
        ' >input
        git config -f input core.key1
      
      this dropped the time to run git-config from:
      
        real    0m0.263s
        user    0m0.260s
        sys     0m0.000s
      
      to:
      
        real    0m0.159s
        user    0m0.152s
        sys     0m0.004s
      
      for a savings of 39%.  Most config files are not this big,
      but the savings should be proportional to the size of the
      file (i.e., we always save 39%, just of a much smaller
      number).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      260d408e
  28. 06 2月, 2015 2 次提交
    • J
      config_buf_ungetc: warn when pushing back a random character · 1d0655c1
      Jeff King 提交于
      Our config code simulates a stdio stream around a buffer,
      but our fake ungetc() does not behave quite like the real
      one. In particular, we only rewind the position by one
      character, but do _not_ actually put the character from the
      caller into position.
      
      It turns out that this does not matter, because we only ever
      push back the character we just read. In other words, such
      an assignment would be a noop. But because the function is
      called ungetc, and because it takes a character parameter,
      it is a mistake waiting to happen.
      
      Actually assigning the character into the buffer would be
      ideal, but our pointer is actually a "const" copy of the
      buffer. We do not know who the real owner of the buffer is
      in this code, and would not want to munge their contents.
      
      Instead, we can simply add an assertion that matches what
      the current caller does, and will let us know if new callers
      are added that violate the contract.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      1d0655c1
    • J
      config: do not ungetc EOF · 5e0be134
      Jeff King 提交于
      When we are parsing a config value, if we see a carriage
      return, we fgetc the next character to see if it is a
      line feed (in which case we silently drop the CR). If it
      isn't, we then ungetc the character, and take the literal
      CR.
      
      But we never check whether we in fact got a character at
      all. If the config file ends in CR, we will get EOF here,
      and try to ungetc EOF. This works OK for a real stdio
      stream. The ungetc returns an error, and the next fgetc will
      then return EOF again.
      
      However, our custom buffer-based stream is not so fortunate.
      It happily rewinds the position of the stream by one
      character, ignoring the fact that we fed it EOF. The next
      fgetc call returns the final CR again, over and over, and we
      end up in an infinite loop.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      5e0be134