1. 08 1月, 2015 6 次提交
  2. 01 12月, 2014 1 次提交
    • J
      receive-pack: add another option for receive.denyCurrentBranch · 1404bcbb
      Johannes Schindelin 提交于
      When synchronizing between working directories, it can be handy to update
      the current branch via 'push' rather than 'pull', e.g. when pushing a fix
      from inside a VM, or when pushing a fix made on a user's machine (where
      the developer is not at liberty to install an ssh daemon let alone know
      the user's password).
      
      The common workaround – pushing into a temporary branch and then merging
      on the other machine – is no longer necessary with this patch.
      
      The new option is:
      
      'updateInstead':
      	Update the working tree accordingly, but refuse to do so if there
      	are any uncommitted changes.
      Signed-off-by: NJohannes Schindelin <johannes.schindelin@gmx.de>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      1404bcbb
  3. 26 11月, 2014 1 次提交
  4. 18 11月, 2014 1 次提交
  5. 29 10月, 2014 1 次提交
  6. 20 10月, 2014 1 次提交
  7. 16 10月, 2014 2 次提交
  8. 14 10月, 2014 1 次提交
  9. 02 10月, 2014 1 次提交
  10. 26 9月, 2014 1 次提交
  11. 18 9月, 2014 2 次提交
    • J
      signed push: allow stale nonce in stateless mode · 5732373d
      Junio C Hamano 提交于
      When operating with the stateless RPC mode, we will receive a nonce
      issued by another instance of us that advertised our capability and
      refs some time ago.  Update the logic to check received nonce to
      detect this case, compute how much time has passed since the nonce
      was issued and report the status with a new environment variable
      GIT_PUSH_CERT_NONCE_SLOP to the hooks.
      
      GIT_PUSH_CERT_NONCE_STATUS will report "SLOP" in such a case.  The
      hooks are free to decide how large a slop it is willing to accept.
      
      Strictly speaking, the "nonce" is not really a "nonce" anymore in
      the stateless RPC mode, as it will happily take any "nonce" issued
      by it (which is protected by HMAC and its secret key) as long as it
      is fresh enough.  The degree of this security degradation, relative
      to the native protocol, is about the same as the "we make sure that
      the 'git push' decided to update our refs with new objects based on
      the freshest observation of our refs by making sure the values they
      claim the original value of the refs they ask us to update exactly
      match the current state" security is loosened to accomodate the
      stateless RPC mode in the existing code without this series, so
      there is no need for those who are already using smart HTTP to push
      to their repositories to be alarmed any more than they already are.
      
      In addition, the server operator can set receive.certnonceslop
      configuration variable to specify how stale a nonce can be (in
      seconds).  When this variable is set, and if the nonce received in
      the certificate that passes the HMAC check was less than that many
      seconds old, hooks are given "OK" in GIT_PUSH_CERT_NONCE_STATUS
      (instead of "SLOP") and the received nonce value is given in
      GIT_PUSH_CERT_NONCE, which makes it easier for a simple-minded
      hook to check if the certificate we received is recent enough.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      5732373d
    • J
      signed push: fortify against replay attacks · b89363e4
      Junio C Hamano 提交于
      In order to prevent a valid push certificate for pushing into an
      repository from getting replayed in a different push operation, send
      a nonce string from the receive-pack process and have the signer
      include it in the push certificate.  The receiving end uses an HMAC
      hash of the path to the repository it serves and the current time
      stamp, hashed with a secret seed (the secret seed does not have to
      be per-repository but can be defined in /etc/gitconfig) to generate
      the nonce, in order to ensure that a random third party cannot forge
      a nonce that looks like it originated from it.
      
      The original nonce is exported as GIT_PUSH_CERT_NONCE for the hooks
      to examine and match against the value on the "nonce" header in the
      certificate to notice a replay, but returned "nonce" header in the
      push certificate is examined by receive-pack and the result is
      exported as GIT_PUSH_CERT_NONCE_STATUS, whose value would be "OK"
      if the nonce recorded in the certificate matches what we expect, so
      that the hooks can more easily check.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      b89363e4
  12. 17 9月, 2014 1 次提交
    • J
      receive-pack: allow hooks to ignore its standard input stream · ec7dbd14
      Junio C Hamano 提交于
      The pre-receive and post-receive hooks were designed to be an
      improvement over old style update and post-update hooks, which take
      the update information on their command line and are limited by the
      command line length limit.  The same information is fed from the
      standard input to pre/post-receive hooks instead to lift this
      limitation.  It has been mandatory for these new style hooks to
      consume the update information fully from the standard input stream.
      Otherwise, they would risk killing the receive-pack process via
      SIGPIPE.
      
      If a hook does not want to look at all the information, it is easy
      to send its standard input to /dev/null (perhaps a niche use of hook
      might need to know only the fact that a push was made, without
      having to know what objects have been pushed to update which refs),
      and this has already been done by existing hooks that are written
      carefully.
      
      However, because there is no good way to consistently fail hooks
      that do not consume the input fully (a small push may result in a
      short update record that may fit within the pipe buffer, to which
      the receive-pack process may manage to write before the hook has a
      chance to exit without reading anything, which will not result in a
      death-by-SIGPIPE of receive-pack), it can lead to a hard to diagnose
      "once in a blue moon" phantom failure.
      
      Lift this "hooks must consume their input fully" mandate.  A mandate
      that is not enforced strictly is not helping us to catch mistakes in
      hooks.  If a hook has a good reason to decide the outcome of its
      operation without reading the information we feed it, let it do so
      as it pleases.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      ec7dbd14
  13. 16 9月, 2014 8 次提交
    • J
      signed push: remove duplicated protocol info · 4adf569d
      Junio C Hamano 提交于
      With the interim protocol, we used to send the update commands even
      though we already send a signed copy of the same information when
      push certificate is in use.  Update the send-pack/receive-pack pair
      not to do so.
      
      The notable thing on the receive-pack side is that it makes sure
      that there is no command sent over the traditional protocol packet
      outside the push certificate.  Otherwise a pusher can claim to be
      pushing one set of ref updates in the signed certificate while
      issuing commands to update unrelated refs, and such an update will
      evade later audits.
      
      Finally, start documenting the protocol.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      4adf569d
    • J
      receive-pack: GPG-validate push certificates · d05b9618
      Junio C Hamano 提交于
      Reusing the GPG signature check helpers we already have, verify
      the signature in receive-pack and give the results to the hooks
      via GIT_PUSH_CERT_{SIGNER,KEY,STATUS} environment variables.
      
      Policy decisions, such as accepting or rejecting a good signature by
      a key that is not fully trusted, is left to the hook and kept
      outside of the core.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      d05b9618
    • J
      push: the beginning of "git push --signed" · a85b377d
      Junio C Hamano 提交于
      While signed tags and commits assert that the objects thusly signed
      came from you, who signed these objects, there is not a good way to
      assert that you wanted to have a particular object at the tip of a
      particular branch.  My signing v2.0.1 tag only means I want to call
      the version v2.0.1, and it does not mean I want to push it out to my
      'master' branch---it is likely that I only want it in 'maint', so
      the signature on the object alone is insufficient.
      
      The only assurance to you that 'maint' points at what I wanted to
      place there comes from your trust on the hosting site and my
      authentication with it, which cannot easily audited later.
      
      Introduce a mechanism that allows you to sign a "push certificate"
      (for the lack of better name) every time you push, asserting that
      what object you are pushing to update which ref that used to point
      at what other object.  Think of it as a cryptographic protection for
      ref updates, similar to signed tags/commits but working on an
      orthogonal axis.
      
      The basic flow based on this mechanism goes like this:
      
       1. You push out your work with "git push --signed".
      
       2. The sending side learns where the remote refs are as usual,
          together with what protocol extension the receiving end
          supports.  If the receiving end does not advertise the protocol
          extension "push-cert", an attempt to "git push --signed" fails.
      
          Otherwise, a text file, that looks like the following, is
          prepared in core:
      
      	certificate version 0.1
      	pusher Junio C Hamano <gitster@pobox.com> 1315427886 -0700
      
      	7339ca65... 21580ecb... refs/heads/master
      	3793ac56... 12850bec... refs/heads/next
      
          The file begins with a few header lines, which may grow as we
          gain more experience.  The 'pusher' header records the name of
          the signer (the value of user.signingkey configuration variable,
          falling back to GIT_COMMITTER_{NAME|EMAIL}) and the time of the
          certificate generation.  After the header, a blank line follows,
          followed by a copy of the protocol message lines.
      
          Each line shows the old and the new object name at the tip of
          the ref this push tries to update, in the way identical to how
          the underlying "git push" protocol exchange tells the ref
          updates to the receiving end (by recording the "old" object
          name, the push certificate also protects against replaying).  It
          is expected that new command packet types other than the
          old-new-refname kind will be included in push certificate in the
          same way as would appear in the plain vanilla command packets in
          unsigned pushes.
      
          The user then is asked to sign this push certificate using GPG,
          formatted in a way similar to how signed tag objects are signed,
          and the result is sent to the other side (i.e. receive-pack).
      
          In the protocol exchange, this step comes immediately before the
          sender tells what the result of the push should be, which in
          turn comes before it sends the pack data.
      
       3. When the receiving end sees a push certificate, the certificate
          is written out as a blob.  The pre-receive hook can learn about
          the certificate by checking GIT_PUSH_CERT environment variable,
          which, if present, tells the object name of this blob, and make
          the decision to allow or reject this push.  Additionally, the
          post-receive hook can also look at the certificate, which may be
          a good place to log all the received certificates for later
          audits.
      
      Because a push certificate carry the same information as the usual
      command packets in the protocol exchange, we can omit the latter
      when a push certificate is in use and reduce the protocol overhead.
      This however is not included in this patch to make it easier to
      review (in other words, the series at this step should never be
      released without the remainder of the series, as it implements an
      interim protocol that will be incompatible with the final one).
      As such, the documentation update for the protocol is left out of
      this step.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      a85b377d
    • J
      receive-pack: factor out capability string generation · 52d2ae58
      Junio C Hamano 提交于
      Similar to the previous one for send-pack, make it easier and
      cleaner to add to capability advertisement.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      52d2ae58
    • J
      receive-pack: factor out queueing of command · 39895c74
      Junio C Hamano 提交于
      Make a helper function to accept a line of a protocol message and
      queue an update command out of the code from read_head_info().
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      39895c74
    • J
      receive-pack: do not reuse old_sha1[] for other things · c09b71cc
      Junio C Hamano 提交于
      This piece of code reads object names of shallow boundaries, not
      old_sha1[], i.e. the current value the ref points at, which is to be
      replaced by what is in new_sha1[].
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      c09b71cc
    • J
      receive-pack: parse feature request a bit earlier · 0e3c339b
      Junio C Hamano 提交于
      Ideally, we should have also allowed the first "shallow" to carry
      the feature request trailer, but that is water under the bridge
      now.  This makes the next step to factor out the queuing of commands
      easier to review.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      0e3c339b
    • J
      receive-pack: do not overallocate command structure · 3bfcb95f
      Junio C Hamano 提交于
      An "update" command in the protocol exchange consists of 40-hex old
      object name, SP, 40-hex new object name, SP, and a refname, but the
      first instance is further followed by a NUL with feature requests.
      
      The command structure, which has a flex-array member that stores the
      refname at the end, was allocated based on the whole length of the
      update command, without excluding the trailing feature requests.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      3bfcb95f
  14. 04 9月, 2014 1 次提交
    • R
      receive-pack.c: use a reference transaction for updating the refs · 6629ea2d
      Ronnie Sahlberg 提交于
      Wrap all the ref updates inside a transaction.
      
      In the new API there is no distinction between failure to lock and
      failure to write a ref.  Both can be permanent (e.g., a ref
      "refs/heads/topic" is blocking creation of the lock file
      "refs/heads/topic/1.lock") or transient (e.g., file system full) and
      there's no clear difference in how the client should respond, so
      replace the two statuses "failed to lock" and "failed to write" with
      a single status "failed to update ref".  In both cases a more
      detailed message is sent by sideband to diagnose the problem.
      
      Example, before:
      
       error: there are still refs under 'refs/heads/topic'
       remote: error: failed to lock refs/heads/topic
       To foo
        ! [remote rejected] HEAD -> topic (failed to lock)
      
      After:
      
       error: there are still refs under 'refs/heads/topic'
       remote: error: Cannot lock the ref 'refs/heads/topic'.
       To foo
        ! [remote rejected] HEAD -> topic (failed to update ref)
      Signed-off-by: NRonnie Sahlberg <sahlberg@google.com>
      Reviewed-by: NMichael Haggerty <mhagger@alum.mit.edu>
      Signed-off-by: NJonathan Nieder <jrnieder@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      6629ea2d
  15. 21 8月, 2014 1 次提交
  16. 25 7月, 2014 1 次提交
  17. 14 7月, 2014 1 次提交
    • K
      trace: improve trace performance · 6aa30857
      Karsten Blees 提交于
      The trace API currently rechecks the environment variable and reopens the
      trace file on every API call. This has the ugly side effect that errors
      (e.g. file cannot be opened, or the user specified a relative path) are
      also reported on every call. Performance can be improved by about factor
      three by remembering the environment state and keeping the file open.
      
      Replace the 'const char *key' parameter in the API with a pointer to a
      'struct trace_key' that bundles the environment variable name with
      additional, trace-internal state. Change the call sites of these APIs to
      use a static 'struct trace_key' instead of a string constant.
      
      In trace.c::get_trace_fd(), save and reuse the file descriptor in 'struct
      trace_key'.
      
      Add a 'trace_disable()' API, so that packet_trace() can cleanly disable
      tracing when it encounters packed data (instead of using unsetenv()).
      Signed-off-by: NKarsten Blees <blees@dcon.de>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      6aa30857
  18. 20 6月, 2014 1 次提交
  19. 28 2月, 2014 1 次提交
    • J
      shallow: automatically clean up shallow tempfiles · 0179c945
      Jeff King 提交于
      We sometimes write tempfiles of the form "shallow_XXXXXX"
      during fetch/push operations with shallow repositories.
      Under normal circumstances, we clean up the result when we
      are done. However, we do no take steps to clean up after
      ourselves when we exit due to die() or signal death.
      
      This patch teaches the tempfile creation code to register
      handlers to clean up after ourselves. To handle this, we
      change the ownership semantics of the filename returned by
      setup_temporary_shallow. It now keeps a copy of the filename
      itself, and returns only a const pointer to it.
      
      We can also do away with explicit tempfile removal in the
      callers. They all exit not long after finishing with the
      file, so they can rely on the auto-cleanup, simplifying the
      code.
      
      Note that we keep things simple and maintain only a single
      filename to be cleaned. This is sufficient for the current
      caller, but we future-proof it with a die("BUG").
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      0179c945
  20. 07 1月, 2014 1 次提交
  21. 11 12月, 2013 5 次提交
    • N
    • N
      receive-pack: allow pushes that update .git/shallow · 0a1bc12b
      Nguyễn Thái Ngọc Duy 提交于
      The basic 8 steps to update .git/shallow does not fully apply here
      because the user may choose to accept just a few refs (while fetch
      always accepts all refs). The steps are modified a bit.
      
      1-6. same as before. After calling assign_shallow_commits_to_refs at
         step 6, each shallow commit has a bitmap that marks all refs that
         require it.
      
      7. mark all "ours" shallow commits that are reachable from any
         refs. We will need to do the original step 7 on them later.
      
      8. go over all shallow commit bitmaps, mark refs that require new
         shallow commits.
      
      9. setup a strict temporary shallow file to plug all the holes, even
         if it may cut some of our history short. This file is used by all
         hooks. The hooks could use --shallow-file=$GIT_DIR/shallow to
         overcome this and reach everything in current repo.
      
      10. go over the new refs one by one. For each ref, do the reachability
         test if it needs a shallow commit on the list from step 7. Remove
         it if it's reachable from our refs. Gather all required shallow
         commits, run check_everything_connected() with the new ref, then
         install them to .git/shallow.
      
      This mode is disabled by default and can be turned on with
      receive.shallowupdate
      Signed-off-by: NNguyễn Thái Ngọc Duy <pclouds@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      0a1bc12b
    • N
    • N
      receive-pack: reorder some code in unpack() · 31c42bff
      Nguyễn Thái Ngọc Duy 提交于
      This is the preparation for adding --shallow-file to both
      unpack-objects and index-pack. To sum up:
      
       - struct argv_array used instead of const char **
      
       - status/code, ip/child, unpacker/keeper are moved out to function
         top level
      
       - successful flow now ends at the end of the function
      Signed-off-by: NNguyễn Thái Ngọc Duy <pclouds@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      31c42bff
    • N
      make the sender advertise shallow commits to the receiver · ad491366
      Nguyễn Thái Ngọc Duy 提交于
      If either receive-pack or upload-pack is called on a shallow
      repository, shallow commits (*) will be sent after the ref
      advertisement (but before the packet flush), so that the receiver has
      the full "shape" of the sender's commit graph. This will be needed for
      the receiver to update its .git/shallow if necessary.
      
      This breaks the protocol for all clients trying to push to a shallow
      repo, or fetch from one. Which is basically the same end result as
      today's "is_repository_shallow() && die()" in receive-pack and
      upload-pack. New clients will be made aware of shallow upstream and
      can make use of this information.
      
      The sender must send all shallow commits that are sent in the
      following pack. It may send more shallow commits than necessary.
      
      upload-pack for example may choose to advertise no shallow commits if
      it knows in advance that the pack it's going to send contains no
      shallow commits. But upload-pack is the server, so we choose the
      cheaper way, send full .git/shallow and let the client deal with it.
      
      Smart HTTP is not affected by this patch. Shallow support on
      smart-http comes later separately.
      
      (*) A shallow commit is a commit that terminates the revision
          walker. It is usually put in .git/shallow in order to keep the
          revision walker from going out of bound because there is no
          guarantee that objects behind this commit is available.
      Signed-off-by: NNguyễn Thái Ngọc Duy <pclouds@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      ad491366
  22. 06 12月, 2013 1 次提交
    • C
      replace {pre,suf}fixcmp() with {starts,ends}_with() · 59556548
      Christian Couder 提交于
      Leaving only the function definitions and declarations so that any
      new topic in flight can still make use of the old functions, replace
      existing uses of the prefixcmp() and suffixcmp() with new API
      functions.
      
      The change can be recreated by mechanically applying this:
      
          $ git grep -l -e prefixcmp -e suffixcmp -- \*.c |
            grep -v strbuf\\.c |
            xargs perl -pi -e '
              s|!prefixcmp\(|starts_with\(|g;
              s|prefixcmp\(|!starts_with\(|g;
              s|!suffixcmp\(|ends_with\(|g;
              s|suffixcmp\(|!ends_with\(|g;
            '
      
      on the result of preparatory changes in this series.
      Signed-off-by: NChristian Couder <chriscool@tuxfamily.org>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      59556548