1. 17 Jan, 2017 17 commits
    • Junio C Hamano's avatar
      Merge branch 'js/normalize-path-copy-ceil' into maint · 07ec05d9
      Junio C Hamano authored
      A pathname that begins with "//" or "\\" on Windows is special but
      path normalization logic was unaware of it.
      * js/normalize-path-copy-ceil:
        normalize_path_copy(): fix pushing to //server/share/dir on Windows
    • Junio C Hamano's avatar
      Merge branch 'ak/commit-only-allow-empty' into maint · 9d2a2486
      Junio C Hamano authored
      "git commit --allow-empty --only" (no pathspec) with dirty index
      ought to be an acceptable way to create a new commit that does not
      change any paths, but it was forbidden, perhaps because nobody
      needed it so far.
      * ak/commit-only-allow-empty:
        commit: remove 'Clever' message for --only --amend
        commit: make --only --allow-empty work without paths
    • Junio C Hamano's avatar
      Merge branch 'da/difftool-dir-diff-fix' into maint · 935a4783
      Junio C Hamano authored
      "git difftool --dir-diff" had a minor regression when started from
      a subdirectory, which has been fixed.
      * da/difftool-dir-diff-fix:
        difftool: fix dir-diff index creation when in a subdirectory
    • Junio C Hamano's avatar
      Merge branch 'jb/diff-no-index-no-abbrev' into maint · 28c8a447
      Junio C Hamano authored
      "git diff --no-index" did not take "--no-abbrev" option.
      * jb/diff-no-index-no-abbrev:
        diff: handle --no-abbrev in no-index case
    • Junio C Hamano's avatar
      Merge branch 'jk/stash-disable-renames-internally' into maint · 12361d02
      Junio C Hamano authored
      When diff.renames configuration is on (and with Git 2.9 and later,
      it is enabled by default, which made it worse), "git stash"
      misbehaved if a file is removed and another file with a very
      similar content is added.
      * jk/stash-disable-renames-internally:
        stash: prefer plumbing over git-diff
    • Junio C Hamano's avatar
      Merge branch 'jk/http-walker-limit-redirect' into maint · 5ce6f51f
      Junio C Hamano authored
      Update the error messages from the dumb-http client when it fails
      to obtain loose objects; we used to give sensible error message
      only upon 404 but we now forbid unexpected redirects that needs to
      be reported with something sensible.
      * jk/http-walker-limit-redirect:
        http-walker: complain about non-404 loose object errors
        http: treat http-alternates like redirects
        http: make redirects more obvious
        remote-curl: rename shadowed options variable
        http: always update the base URL for redirects
        http: simplify update_url_from_redirect
    • Junio C Hamano's avatar
      Merge branch 'jc/renormalize-merge-kill-safer-crlf' into maint · 7479ca4b
      Junio C Hamano authored
      Fix a corner case in merge-recursive regression that crept in
      during 2.10 development cycle.
      * jc/renormalize-merge-kill-safer-crlf:
        convert: git cherry-pick -Xrenormalize did not work
        merge-recursive: handle NULL in add_cacheinfo() correctly
        cherry-pick: demonstrate a segmentation fault
    • Junio C Hamano's avatar
      Merge branch 'ls/p4-empty-file-on-lfs' into maint · cf479b4f
      Junio C Hamano authored
      "git p4" LFS support was broken when LFS stores an empty blob.
      * ls/p4-empty-file-on-lfs:
        git-p4: fix empty file processing for large file system backend GitLFS
    • Junio C Hamano's avatar
      Merge branch 'da/mergetool-trust-exit-code' into maint · b3dac9c0
      Junio C Hamano authored
      mergetool.<tool>.trustExitCode configuration variable did not apply
      to built-in tools, but now it does.
      * da/mergetool-trust-exit-code:
        mergetools/vimdiff: trust Vim's exit code
        mergetool: honor mergetool.$tool.trustExitCode for built-in tools
    • Junio C Hamano's avatar
      Merge branch 'nd/worktree-list-fixup' into maint · 430fd1ca
      Junio C Hamano authored
      The output from "git worktree list" was made in readdir() order,
      and was unstable.
      * nd/worktree-list-fixup:
        worktree list: keep the list sorted
        worktree.c: get_worktrees() takes a new flag argument
        get_worktrees() must return main worktree as first item even on error
        worktree: reorder an if statement
        worktree.c: zero new 'struct worktree' on allocation
    • Junio C Hamano's avatar
      Merge branch 'bw/push-dry-run' into maint · 3075e40c
      Junio C Hamano authored
      "git push --dry-run --recurse-submodule=on-demand" wasn't
      "--dry-run" in the submodules.
      * bw/push-dry-run:
        push: fix --dry-run to not push submodules
        push: --dry-run updates submodules when --recurse-submodules=on-demand
    • Junio C Hamano's avatar
      Merge branch 'hv/submodule-not-yet-pushed-fix' into maint · 9da9965b
      Junio C Hamano authored
      The code in "git push" to compute if any commit being pushed in the
      superproject binds a commit in a submodule that hasn't been pushed
      out was overly inefficient, making it unusable even for a small
      project that does not have any submodule but have a reasonable
      number of refs.
      * hv/submodule-not-yet-pushed-fix:
        submodule_needs_pushing(): explain the behaviour when we cannot answer
        batch check whether submodule needs pushing into one call
        serialize collection of refs that contain submodule changes
        serialize collection of changed submodules
    • Junio C Hamano's avatar
      Merge branch 'dt/empty-submodule-in-merge' into maint · 0f47d3d7
      Junio C Hamano authored
      An empty directory in a working tree that can simply be nuked used
      to interfere while merging or cherry-picking a change to create a
      submodule directory there, which has been fixed..
      * dt/empty-submodule-in-merge:
        submodules: allow empty working-tree dirs in merge/cherry-pick
    • Junio C Hamano's avatar
      Merge branch 'jk/rev-parse-symbolic-parents-fix' into maint · 7b0490f8
      Junio C Hamano authored
      "git rev-parse --symbolic" failed with a more recent notation like
      "HEAD^-1" and "HEAD^!".
      * jk/rev-parse-symbolic-parents-fix:
        rev-parse: fix parent shorthands with --symbolic
    • Junio C Hamano's avatar
      Merge branch 'js/mingw-isatty' into maint · 0ab8606e
      Junio C Hamano authored
      Update the isatty() emulation for Windows by updating the previous
      hack that depended on internals of (older) MSVC runtime.
      * js/mingw-isatty:
        mingw: replace isatty() hack
        mingw: fix colourization on Cygwin pseudo terminals
        mingw: adjust is_console() to work with stdin
        mingw: intercept isatty() to handle /dev/null as Git expects it
    • Junio C Hamano's avatar
      Merge branch 'bb/unicode-9.0' into maint · 9d1e8ddc
      Junio C Hamano authored
      The character width table has been updated to match Unicode 9.0
      * bb/unicode-9.0:
        unicode_width.h: update the width tables to Unicode 9.0
        update_unicode.sh: remove the plane filter
        update_unicode.sh: automatically download newer definition files
        update_unicode.sh: pin the uniset repo to a known good commit
        update_unicode.sh: remove an unnecessary subshell level
        update_unicode.sh: move it into contrib/update-unicode
    • Junio C Hamano's avatar
      Merge branch 'ls/travis-update-p4-and-lfs' into maint · d27381ee
      Junio C Hamano authored
      The default Travis-CI configuration specifies newer P4 and GitLFS.
      * ls/travis-update-p4-and-lfs:
        travis-ci: update P4 to 16.2 and GitLFS to 1.5.2 in Linux build
  2. 22 Dec, 2016 3 commits
  3. 16 Dec, 2016 1 commit
    • Johannes Sixt's avatar
      normalize_path_copy(): fix pushing to //server/share/dir on Windows · 7814fbe3
      Johannes Sixt authored
      normalize_path_copy() is not prepared to keep the double-slash of a
      //server/share/dir kind of path, but treats it like a regular POSIX
      style path and transforms it to /server/share/dir.
      The bug manifests when 'git push //server/share/dir master' is run,
      because tmp_objdir_add_as_alternate() uses the path in normalized
      form when it registers the quarantine object database via
      link_alt_odb_entries(). Needless to say that the directory cannot be
      accessed using the wrongly normalized path.
      Fix it by skipping all of the root part, not just a potential drive
      prefix. offset_1st_component takes care of this, see the
      implementation in compat/mingw.c::mingw_offset_1st_component().
      Signed-off-by: default avatarJohannes Sixt <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
  4. 14 Dec, 2016 6 commits
  5. 12 Dec, 2016 1 commit
  6. 09 Dec, 2016 1 commit
  7. 08 Dec, 2016 2 commits
    • Jack Bates's avatar
      diff: handle --no-abbrev in no-index case · 43d1948b
      Jack Bates authored
      There are two different places where the --no-abbrev option is parsed,
      and two different places where SHA-1s are abbreviated. We normally parse
      --no-abbrev with setup_revisions(), but in the no-index case, "git diff"
      calls diff_opt_parse() directly, and diff_opt_parse() didn't handle
      --no-abbrev until now. (It did handle --abbrev, however.) We normally
      abbreviate SHA-1s with find_unique_abbrev(), but commit 4f03666a ("diff:
      handle sha1 abbreviations outside of repository, 2016-10-20) recently
      introduced a special case when you run "git diff" outside of a
      setup_revisions() does also call diff_opt_parse(), but not for --abbrev
      or --no-abbrev, which it handles itself. setup_revisions() sets
      rev_info->abbrev, and later copies that to diff_options->abbrev. It
      handles --no-abbrev by setting abbrev to zero. (This change doesn't
      touch that.)
      Setting abbrev to zero was broken in the outside-of-a-repository special
      case, which until now resulted in a truly zero-length SHA-1, rather than
      taking zero to mean do not abbreviate. The only way to trigger this bug,
      however, was by running "git diff --raw" without either the --abbrev or
      --no-abbrev options, because 1) without --raw it doesn't respect abbrev
      (which is bizarre, but has been that way forever), 2) we silently clamp
      --abbrev=0 to MINIMUM_ABBREV, and 3) --no-abbrev wasn't handled until
      The outside-of-a-repository case is one of three no-index cases. The
      other two are when one of the files you're comparing is outside of the
      repository you're in, and the --no-index option.
      Signed-off-by: Jack Bates's avatarJack Bates <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
    • David Aguilar's avatar
      difftool: fix dir-diff index creation when in a subdirectory · 853e10c1
      David Aguilar authored
      9ec26e79 (difftool: fix argument handling in subdirs, 2016-07-18)
      corrected how path arguments are handled in a subdirectory, but
      it introduced a regression in how entries outside of the
      subdirectory are handled by dir-diff.
      When preparing the right-side of the diff we only include the
      changed paths in the temporary area.
      The left side of the diff is constructed from a temporary
      index that is built from the same set of changed files, but it
      was being constructed from within the subdirectory.  This is a
      problem because the indexed paths are toplevel-relative, and
      thus they were not getting added to the index.
      Teach difftool to chdir to the toplevel of the repository before
      preparing its temporary indexes.  This ensures that all of the
      toplevel-relative paths are valid.
      Add test cases to more thoroughly exercise this scenario.
      Reported-by: default avatarFrank Becker <[email protected]>
      Signed-off-by: David Aguilar's avatarDavid Aguilar <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
  8. 06 Dec, 2016 8 commits
    • Jeff King's avatar
      stash: prefer plumbing over git-diff · 9d4e28ea
      Jeff King authored
      When creating a stash, we need to look at the diff between
      the working tree and HEAD, and do so using the git-diff
      porcelain.  Because git-diff enables porcelain config like
      renames by default, this causes at least one problem. The
      --name-only format will not mention the source side of a
      rename, meaning we will fail to stash a deletion that is
      part of a rename.
      We could fix that case by passing --no-renames, but this is
      a symptom of a larger problem. We should be using the
      diff-index plumbing here, which does not have renames
      enabled by default, and also does not respect any
      potentially confusing config options.
      Reported-by: default avatarMatthew Patey <[email protected]>
      Signed-off-by: default avatarJeff King <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
    • Jeff King's avatar
      http-walker: complain about non-404 loose object errors · 3680f16f
      Jeff King authored
      Since commit 17966c0a (http: avoid disconnecting on 404s
      for loose objects, 2016-07-11), we turn off curl's
      FAILONERROR option and instead manually deal with failing
      HTTP codes.
      However, the logic to do so only recognizes HTTP 404 as a
      failure. This is probably the most common result, but if we
      were to get another code, the curl result remains CURLE_OK,
      and we treat it as success. We still end up detecting the
      failure when we try to zlib-inflate the object (which will
      fail), but instead of reporting the HTTP error, we just
      claim that the object is corrupt.
      Instead, let's catch anything in the 300's or above as an
      error (300's are redirects which are not an error at the
      HTTP level, but are an indication that we've explicitly
      disabled redirects, so we should treat them as such; we
      certainly don't have the resulting object content).
      Note that we also fill in req->errorstr, which we didn't do
      before. Without FAILONERROR, curl will not have filled this
      in, and it will remain a blank string. This never mattered
      for the 404 case, because in the logic below we hit the
      "missing_target()" branch and print nothing. But for other
      errors, we'd want to say _something_, if only to fill in the
      blank slot in the error message.
      Signed-off-by: default avatarJeff King <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
    • Junio C Hamano's avatar
      Merge branch 'ew/http-walker' into jk/http-walker-limit-redirect · 43ec089e
      Junio C Hamano authored
      * ew/http-walker:
        list: avoid incompatibility with *BSD sys/queue.h
        http-walker: reduce O(n) ops with doubly-linked list
        http: avoid disconnecting on 404s for loose objects
        http-walker: remove unused parameter from fetch_object
    • Jeff King's avatar
      http: treat http-alternates like redirects · cb4d2d35
      Jeff King authored
      The previous commit made HTTP redirects more obvious and
      tightened up the default behavior. However, there's another
      way for a server to ask a git client to fetch arbitrary
      content: by having an http-alternates file (or a regular
      alternates file, which is used as a backup).
      Similar to the HTTP redirect case, a malicious server can
      claim to have refs pointing at object X, return a 404 when
      the client asks for X, but point to some other URL via
      http-alternates, which the client will transparently fetch.
      The end result is that it looks from the user's perspective
      like the objects came from the malicious server, as the
      other URL is not mentioned at all.
      Worse, because we feed the new URL to curl ourselves, the
      usual protocol restrictions do not kick in (neither curl's
      default of disallowing file://, nor the protocol
      whitelisting in f4113cac (http: limit redirection to
      protocol-whitelist, 2015-09-22).
      Let's apply the same rules here as we do for HTTP redirects.
        - unless http.followRedirects is set to "always", we will
          not follow remote redirects from http-alternates (or
          alternates) at all
          restrict ourselves to a known-safe set and respect any
          user-provided whitelist.
        - mention alternate object stores on stderr so that the
          user is aware another source of objects may be involved
      The first item may prove to be too restrictive. The most
      common use of alternates is to point to another path on the
      same server. While it's possible for a single-server
      redirect to be an attack, it takes a fairly obscure setup
      (victim and evil repository on the same host, host speaks
      dumb http, and evil repository has access to edit its own
      http-alternates file).
      So we could make the checks more specific, and only cover
      cross-server redirects. But that means parsing the URLs
      ourselves, rather than letting curl handle them. This patch
      goes for the simpler approach. Given that they are only used
      with dumb http, http-alternates are probably pretty rare.
      And there's an escape hatch: the user can allow redirects on
      a specific server by setting http.<url>.followRedirects to
      Reported-by: default avatarJann Horn <[email protected]>
      Signed-off-by: default avatarJeff King <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
    • Jeff King's avatar
      http: make redirects more obvious · 50d34137
      Jeff King authored
      We instruct curl to always follow HTTP redirects. This is
      convenient, but it creates opportunities for malicious
      servers to create confusing situations. For instance,
      imagine Alice is a git user with access to a private
      repository on Bob's server. Mallory runs her own server and
      wants to access objects from Bob's repository.
      Mallory may try a few tricks that involve asking Alice to
      clone from her, build on top, and then push the result:
        1. Mallory may simply redirect all fetch requests to Bob's
           server. Git will transparently follow those redirects
           and fetch Bob's history, which Alice may believe she
           got from Mallory. The subsequent push seems like it is
           just feeding Mallory back her own objects, but is
           actually leaking Bob's objects. There is nothing in
           git's output to indicate that Bob's repository was
           involved at all.
           The downside (for Mallory) of this attack is that Alice
           will have received Bob's entire repository, and is
           likely to notice that when building on top of it.
        2. If Mallory happens to know the sha1 of some object X in
           Bob's repository, she can instead build her own history
           that references that object. She then runs a dumb http
           server, and Alice's client will fetch each object
           individually. When it asks for X, Mallory redirects her
           to Bob's server. The end result is that Alice obtains
           objects from Bob, but they may be buried deep in
           history. Alice is less likely to notice.
      Both of these attacks are fairly hard to pull off. There's a
      social component in getting Mallory to convince Alice to
      work with her. Alice may be prompted for credentials in
      accessing Bob's repository (but not always, if she is using
      a credential helper that caches). Attack (1) requires a
      certain amount of obliviousness on Alice's part while making
      a new commit. Attack (2) requires that Mallory knows a sha1
      in Bob's repository, that Bob's server supports dumb http,
      and that the object in question is loose on Bob's server.
      But we can probably make things a bit more obvious without
      any loss of functionality. This patch does two things to
      that end.
      First, when we encounter a whole-repo redirect during the
      initial ref discovery, we now inform the user on stderr,
      making attack (1) much more obvious.
      Second, the decision to follow redirects is now
      configurable. The truly paranoid can set the new
      http.followRedirects to false to avoid any redirection
      entirely. But for a more practical default, we will disallow
      redirects only after the initial ref discovery. This is
      enough to thwart attacks similar to (2), while still
      allowing the common use of redirects at the repository
      level. Since c93c92f3 (http: update base URLs when we see
      redirects, 2013-09-28) we re-root all further requests from
      the redirect destination, which should generally mean that
      no further redirection is necessary.
      As an escape hatch, in case there really is a server that
      needs to redirect individual requests, the user can set
      http.followRedirects to "true" (and this can be done on a
      per-server basis via http.*.followRedirects config).
      Reported-by: default avatarJann Horn <[email protected]>
      Signed-off-by: default avatarJeff King <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
    • Jeff King's avatar
      remote-curl: rename shadowed options variable · fcaa6e64
      Jeff King authored
      The discover_refs() function has a local "options" variable
      to hold the http_get_options we pass to http_get_strbuf().
      But this shadows the global "struct options" that holds our
      program-level options, which cannot be accessed from this
      Let's give the local one a more descriptive name so we can
      tell the two apart.
      Signed-off-by: default avatarJeff King <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
    • Jeff King's avatar
      http: always update the base URL for redirects · 6628eb41
      Jeff King authored
      If a malicious server redirects the initial ref
      advertisement, it may be able to leak sha1s from other,
      unrelated servers that the client has access to. For
      example, imagine that Alice is a git user, she has access to
      a private repository on a server hosted by Bob, and Mallory
      runs a malicious server and wants to find out about Bob's
      private repository.
      Mallory asks Alice to clone an unrelated repository from her
      over HTTP. When Alice's client contacts Mallory's server for
      the initial ref advertisement, the server issues an HTTP
      redirect for Bob's server. Alice contacts Bob's server and
      gets the ref advertisement for the private repository. If
      there is anything to fetch, she then follows up by asking
      the server for one or more sha1 objects. But who is the
      If it is still Mallory's server, then Alice will leak the
      existence of those sha1s to her.
      Since commit c93c92f3 (http: update base URLs when we see
      redirects, 2013-09-28), the client usually rewrites the base
      URL such that all further requests will go to Bob's server.
      But this is done by textually matching the URL. If we were
      originally looking for "http://mallory/repo.git/info/refs",
      and we got pointed at "http://bob/other.git/info/refs", then
      we know that the right root is "http://bob/other.git".
      If the redirect appears to change more than just the root,
      we punt and continue to use the original server. E.g.,
      imagine the redirect adds a URL component that Bob's server
      will ignore, like "http://bob/other.git/info/refs?dummy=1".
      We can solve this by aborting in this case rather than
      silently continuing to use Mallory's server. In addition to
      protecting from sha1 leakage, it's arguably safer and more
      sane to refuse a confusing redirect like that in general.
      For example, part of the motivation in c93c92f3 is
      avoiding accidentally sending credentials over clear http,
      just to get a response that says "try again over https". So
      even in a non-malicious case, we'd prefer to err on the side
      of caution.
      The downside is that it's possible this will break a
      legitimate but complicated server-side redirection scheme.
      The setup given in the newly added test does work, but it's
      convoluted enough that we don't need to care about it. A
      more plausible case would be a server which redirects a
      request for "info/refs?service=git-upload-pack" to just
      "info/refs" (because it does not do smart HTTP, and for some
      reason really dislikes query parameters).  Right now we
      would transparently downgrade to dumb-http, but with this
      patch, we'd complain (and the user would have to set
      GIT_SMART_HTTP=0 to fetch).
      Reported-by: default avatarJann Horn <[email protected]>
      Signed-off-by: default avatarJeff King <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
    • Jeff King's avatar
      http: simplify update_url_from_redirect · 986d7f4d
      Jeff King authored
      This function looks for a common tail between what we asked
      for and where we were redirected to, but it open-codes the
      comparison. We can avoid some confusing subtractions by
      using strip_suffix_mem().
      Signed-off-by: default avatarJeff King <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
  9. 05 Dec, 2016 1 commit