1. 23 2月, 2016 1 次提交
  2. 20 11月, 2015 3 次提交
  3. 27 10月, 2015 1 次提交
  4. 23 10月, 2015 1 次提交
  5. 11 8月, 2015 3 次提交
    • J
      memoize common git-path "constant" files · f932729c
      Jeff King 提交于
      One of the most common uses of git_path() is to pass a
      constant, like git_path("MERGE_MSG"). This has two
      drawbacks:
      
        1. The return value is a static buffer, and the lifetime
           is dependent on other calls to git_path, etc.
      
        2. There's no compile-time checking of the pathname. This
           is OK for a one-off (after all, we have to spell it
           correctly at least once), but many of these constant
           strings appear throughout the code.
      
      This patch introduces a series of functions to "memoize"
      these strings, which are essentially globals for the
      lifetime of the program. We compute the value once, take
      ownership of the buffer, and return the cached value for
      subsequent calls.  cache.h provides a helper macro for
      defining these functions as one-liners, and defines a few
      common ones for global use.
      
      Using a macro is a little bit gross, but it does nicely
      document the purpose of the functions. If we need to touch
      them all later (e.g., because we learned how to change the
      git_dir variable at runtime, and need to invalidate all of
      the stored values), it will be much easier to have the
      complete list.
      
      Note that the shared-global functions have separate, manual
      declarations. We could do something clever with the macros
      (e.g., expand it to a declaration in some places, and a
      declaration _and_ a definition in path.c). But there aren't
      that many, and it's probably better to stay away from
      too-magical macros.
      
      Likewise, if we abandon the C preprocessor in favor of
      generating these with a script, we could get much fancier.
      E.g., normalizing "FOO/BAR-BAZ" into "git_path_foo_bar_baz".
      But the small amount of saved typing is probably not worth
      the resulting confusion to readers who want to grep for the
      function's definition.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      f932729c
    • M
      6e122b44
    • M
      b4fb09e4
  6. 26 5月, 2015 2 次提交
  7. 14 3月, 2015 1 次提交
  8. 16 1月, 2015 1 次提交
  9. 14 1月, 2015 1 次提交
  10. 20 10月, 2014 1 次提交
  11. 02 10月, 2014 2 次提交
  12. 19 9月, 2014 1 次提交
  13. 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
  14. 18 3月, 2014 1 次提交
    • J
      shallow: verify shallow file after taking lock · 78396321
      Jeff King 提交于
      Before writing the shallow file, we stat() the existing file
      to make sure it has not been updated since our operation
      began. However, we do not do so under a lock, so there is a
      possible race:
      
        1. Process A takes the lock.
      
        2. Process B calls check_shallow_file_for_update and finds
           no update.
      
        3. Process A commits the lockfile.
      
        4. Process B takes the lock, then overwrite's process A's
           changes.
      
      We can fix this by doing our check while we hold the lock.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      78396321
  15. 28 2月, 2014 2 次提交
    • 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
    • J
      shallow: use stat_validity to check for up-to-date file · 0cc77c38
      Jeff King 提交于
      When we are about to write the shallow file, we check that
      it has not changed since we last read it. Instead of
      hand-rolling this, we can use stat_validity. This is built
      around the index stat-check, so it is more robust than just
      checking the mtime, as we do now (it uses the same check as
      we do for index files).
      
      The new code also handles the case of a shallow file
      appearing unexpectedly. With the current code, two
      simultaneous processes making us shallow (e.g., two "git
      fetch --depth=1" running at the same time in a non-shallow
      repository) can race to overwrite each other.
      
      As a bonus, we also remove a race in determining the stat
      information of what we read (we stat and then open, leaving
      a race window; instead we should open and then fstat the
      descriptor).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      0cc77c38
  16. 07 1月, 2014 1 次提交
  17. 11 12月, 2013 8 次提交
    • N
      prune: clean .git/shallow after pruning objects · eab3296c
      Nguyễn Thái Ngọc Duy 提交于
      This patch teaches "prune" to remove shallow roots that are no longer
      reachable from any refs (e.g. when the relevant refs are removed).
      Signed-off-by: NNguyễn Thái Ngọc Duy <pclouds@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      eab3296c
    • 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
      add GIT_SHALLOW_FILE to propagate --shallow-file to subprocesses · 069c0532
      Nguyễn Thái Ngọc Duy 提交于
      This may be needed when a hook is run after a new shallow pack is
      received, but .git/shallow is not settled yet. A temporary shallow
      file to plug all loose ends should be used instead. GIT_SHALLOW_FILE
      is overriden by --shallow-file.
      
      --shallow-file does not work in this case because the hook may spawn
      many git subprocesses and the launch commands do not have
      --shallow-file as it's a recent addition.
      Signed-off-by: NNguyễn Thái Ngọc Duy <pclouds@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      069c0532
    • N
      upload-pack: make sure deepening preserves shallow roots · 79d3a236
      Nguyễn Thái Ngọc Duy 提交于
      When "fetch --depth=N" where N exceeds the longest chain of history in
      the source repo, usually we just send an "unshallow" line to the
      client so full history is obtained.
      
      When the source repo is shallow we need to make sure to "unshallow"
      the current shallow point _and_ "shallow" again when the commit
      reaches its shallow bottom in the source repo.
      
      This should fix both cases: large <N> and --unshallow.
      Signed-off-by: NNguyễn Thái Ngọc Duy <pclouds@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      79d3a236
    • N
    • N
      shallow.c: the 8 steps to select new commits for .git/shallow · 58babfff
      Nguyễn Thái Ngọc Duy 提交于
      Suppose a fetch or push is requested between two shallow repositories
      (with no history deepening or shortening). A pack that contains
      necessary objects is transferred over together with .git/shallow of
      the sender. The receiver has to determine whether it needs to update
      .git/shallow if new refs needs new shallow comits.
      
      The rule here is avoid updating .git/shallow by default. But we don't
      want to waste the received pack. If the pack contains two refs, one
      needs new shallow commits installed in .git/shallow and one does not,
      we keep the latter and reject/warn about the former.
      
      Even if .git/shallow update is allowed, we only add shallow commits
      strictly necessary for the former ref (remember the sender can send
      more shallow commits than necessary) and pay attention not to
      accidentally cut the receiver history short (no history shortening is
      asked for)
      
      So the steps to figure out what ref need what new shallow commits are:
      
      1. Split the sender shallow commit list into "ours" and "theirs" list
         by has_sha1_file. Those that exist in current repo in "ours", the
         remaining in "theirs".
      
      2. Check the receiver .git/shallow, remove from "ours" the ones that
         also exist in .git/shallow.
      
      3. Fetch the new pack. Either install or unpack it.
      
      4. Do has_sha1_file on "theirs" list again. Drop the ones that fail
         has_sha1_file. Obviously the new pack does not need them.
      
      5. If the pack is kept, remove from "ours" the ones that do not exist
         in the new pack.
      
      6. Walk the new refs to answer the question "what shallow commits,
         both ours and theirs, are required in .git/shallow in order to add
         this ref?". Shallow commits not associated to any refs are removed
         from their respective list.
      
      7. (*) Check reachability (from the current refs) of all remaining
         commits in "ours". Those reachable are removed. We do not want to
         cut any part of our (reachable) history. We only check up
         commits. True reachability test is done by
         check_everything_connected() at the end as usual.
      
      8. Combine the final "ours" and "theirs" and add them all to
         .git/shallow. Install new refs. The case where some hook rejects
         some refs on a push is explained in more detail in the push
         patches.
      
      Of these steps, #6 and #7 are expensive. Both require walking through
      some commits, or in the worst case all commits. And we rather avoid
      them in at least common case, where the transferred pack does not
      contain any shallow commits that the sender advertises. Let's look at
      each scenario:
      
      1) the sender has longer history than the receiver
      
         All shallow commits from the sender will be put into "theirs" list
         at step 1 because none of them exists in current repo. In the
         common case, "theirs" becomes empty at step 4 and exit early.
      
      2) the sender has shorter history than the receiver
      
         All shallow commits from the sender are likely in "ours" list at
         step 1. In the common case, if the new pack is kept, we could empty
         "ours" and exit early at step 5.
      
         If the pack is not kept, we hit the expensive step 6 then exit
         after "ours" is emptied. There'll be only a handful of objects to
         walk in fast-forward case. If it's forced update, we may need to
         walk to the bottom.
      
      3) the sender has same .git/shallow as the receiver
      
         This is similar to case 2 except that "ours" should be emptied at
         step 2 and exit early.
      
      A fetch after "clone --depth=X" is case 1. A fetch after "clone" (from
      a shallow repo) is case 3. Luckily they're cheap for the common case.
      
      A push from "clone --depth=X" falls into case 2, which is expensive.
      Some more work may be done at the sender/client side to avoid more
      work on the server side: if the transferred pack does not contain any
      shallow commits, send-pack should not send any shallow commits to the
      receive-pack, effectively turning it into a normal push and avoid all
      steps.
      
      This patch implements all steps except #3, already handled by
      fetch-pack and receive-pack, #6 and #7, which has their own patch due
      to their size.
      
      (*) in previous versions step 7 was put before step 3. I reorder it so
          that the common case that keeps the pack does not need to walk
          commits at all. In future if we implement faster commit
          reachability check (maybe with the help of pack bitmaps or commit
          cache), step 7 could become cheap and be moved up before 6 again.
      Signed-off-by: NNguyễn Thái Ngọc Duy <pclouds@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      58babfff
    • N
    • 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
  18. 25 10月, 2013 1 次提交
    • J
      use parse_commit_or_die instead of custom message · 367068e0
      Jeff King 提交于
      Many calls to parse_commit detect errors and die. In some
      cases, the custom error messages are more useful than what
      parse_commit_or_die could produce, because they give some
      context, like which ref the commit came from. Some, however,
      just say "invalid commit". Let's convert the latter to use
      parse_commit_or_die; its message is slightly more informative,
      and it makes the error more consistent throughout git.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      367068e0
  19. 29 8月, 2013 2 次提交
  20. 19 8月, 2013 1 次提交
  21. 16 7月, 2013 1 次提交
  22. 28 5月, 2013 1 次提交
  23. 12 1月, 2013 1 次提交
  24. 30 8月, 2010 1 次提交
  25. 19 2月, 2008 1 次提交