1. 31 3月, 2012 1 次提交
  2. 13 1月, 2012 1 次提交
    • J
      thin-pack: try harder to use preferred base objects as base · 15f07e06
      Jeff King 提交于
      When creating a pack using objects that reside in existing packs, we try
      to avoid recomputing futile delta between an object (trg) and a candidate
      for its base object (src) if they are stored in the same packfile, and trg
      is not recorded as a delta already. This heuristics makes sense because it
      is likely that we tried to express trg as a delta based on src but it did
      not produce a good delta when we created the existing pack.
      
      As the pack heuristics prefer producing delta to remove data, and Linus's
      law dictates that the size of a file grows over time, we tend to record
      the newest version of the file as inflated, and older ones as delta
      against it.
      
      When creating a thin-pack to transfer recent history, it is likely that we
      will try to send an object that is recorded in full, as it is newer.  But
      the heuristics to avoid recomputing futile delta effectively forbids us
      from attempting to express such an object as a delta based on another
      object. Sending an object in full is often more expensive than sending a
      suboptimal delta based on other objects, and it is even more so if we
      could use an object we know the receiving end already has (i.e. preferred
      base object) as the delta base.
      
      Tweak the recomputation avoidance logic, so that we do not punt on
      computing delta against a preferred base object.
      
      The effect of this change can be seen on two simulated upload-pack
      workloads. The first is based on 44 reflog entries from my git.git
      origin/master reflog, and represents the packs that kernel.org sent me git
      updates for the past month or two. The second workload represents much
      larger fetches, going from git's v1.0.0 tag to v1.1.0, then v1.1.0 to
      v1.2.0, and so on.
      
      The table below shows the average generated pack size and the average CPU
      time consumed for each dataset, both before and after the patch:
      
                        dataset
                  | reflog | tags
      ---------------------------------
           before | 53358  | 2750977
      size  after | 32398  | 2668479
           change |   -39% |      -3%
      ---------------------------------
           before |  0.18  | 1.12
      CPU   after |  0.18  | 1.15
           change |    +0% |      +3%
      
      This patch makes a much bigger difference for packs with a shorter slice
      of history (since its effect is seen at the boundaries of the pack) though
      it has some benefit even for larger packs.
      Signed-off-by: NJeff King <peff@peff.net>
      Acked-by: NNicolas Pitre <nico@fluxnic.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      15f07e06
  3. 07 1月, 2012 3 次提交
  4. 06 1月, 2012 1 次提交
  5. 04 1月, 2012 1 次提交
    • J
      write first for-merge ref to FETCH_HEAD first · 96890f4c
      Joey Hess 提交于
      The FETCH_HEAD refname is supposed to refer to the ref that was fetched
      and should be merged. However all fetched refs are written to
      .git/FETCH_HEAD in an arbitrary order, and resolve_ref_unsafe simply
      takes the first ref as the FETCH_HEAD, which is often the wrong one,
      when other branches were also fetched.
      
      The solution is to write the for-merge ref(s) to FETCH_HEAD first.
      Then, unless --append is used, the FETCH_HEAD refname behaves as intended.
      If the user uses --append, they presumably are doing so in order to
      preserve the old FETCH_HEAD.
      
      While we are at it, update an old example in the read-tree documentation
      that implied that each entry in FETCH_HEAD only has the object name, which
      is not true for quite a while.
      
      [jc: adjusted tests]
      Signed-off-by: NJoey Hess <joey@kitenet.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      96890f4c
  6. 28 12月, 2011 1 次提交
  7. 22 12月, 2011 4 次提交
  8. 21 12月, 2011 2 次提交
  9. 18 12月, 2011 1 次提交
  10. 17 12月, 2011 2 次提交
    • T
      grep: disable threading in non-worktree case · 53b8d931
      Thomas Rast 提交于
      Measurements by various people have shown that grepping in parallel is
      not beneficial when the object store is involved.  For example, with a
      simple regex:
      
        Threads     | --cached case            | worktree case
        ----------------------------------------------------------------
        8 (default) | 2.88u 0.21s 0:02.94real  | 0.19u 0.32s 0:00.16real
        4           | 2.89u 0.29s 0:02.99real  | 0.16u 0.34s 0:00.17real
        2           | 2.83u 0.36s 0:02.87real  | 0.18u 0.32s 0:00.26real
        NO_PTHREADS | 2.16u 0.08s 0:02.25real  | 0.12u 0.17s 0:00.31real
      
      This happens because all the threads contend on read_sha1_mutex almost
      all of the time.  A more complex regex allows the threads to do more
      work in parallel, but as Jeff King found out, the "super boost" (much
      higher clock when only one core is active) feature of recent CPUs
      still causes the unthreaded case to win by a large margin.
      
      So until the pack machinery allows unthreaded access, we disable
      grep's threading in all but the worktree case.
      Helped-by: NRené Scharfe <rene.scharfe@lsrfire.ath.cx>
      Helped-by: NJeff King <peff@peff.net>
      Signed-off-by: NThomas Rast <trast@student.ethz.ch>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      53b8d931
    • T
      grep: enable threading with -p and -W using lazy attribute lookup · 0579f91d
      Thomas Rast 提交于
      Lazily load the userdiff attributes in match_funcname().  Use a
      separate mutex around this loading to protect the (not thread-safe)
      attributes machinery.  This lets us re-enable threading with -p and
      -W while reducing the overhead caused by looking up attributes.
      Signed-off-by: NThomas Rast <trast@student.ethz.ch>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      0579f91d
  11. 16 12月, 2011 7 次提交
  12. 14 12月, 2011 5 次提交
    • J
      blame: don't overflow time buffer · c3ea0515
      Jeff King 提交于
      When showing the raw timestamp, we format the numeric
      seconds-since-epoch into a buffer, followed by the timezone
      string. This string has come straight from the commit
      object. A well-formed object should have a timezone string
      of only a few bytes, but we could be operating on data
      pushed by a malicious user.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      c3ea0515
    • J
      fetch-pack: match refs exactly · 1e7ba0f9
      Jeff King 提交于
      When we are determining the list of refs to fetch via
      fetch-pack, we have two sets of refs to compare: those on
      the remote side, and a "match" list of things we want to
      fetch. We iterate through the remote refs alphabetically,
      seeing if each one is wanted by the "match" list.
      
      Since def88e9a (Commit first cut at "git-fetch-pack",
      2005-07-04), we have used the "path_match" function to do a
      suffix match, where a remote ref is considered wanted if
      any of the "match" elements is a suffix of the remote
      refname.
      
      This enables callers of fetch-pack to specify unqualified
      refs and have them matched up with remote refs (e.g., ask
      for "A" and get remote's "refs/heads/A"). However, if you
      provide a fully qualified ref, then there are corner cases
      where we provide the wrong answer. For example, given a
      remote with two refs:
      
         refs/foo/refs/heads/master
         refs/heads/master
      
      asking for "refs/heads/master" will first match
      "refs/foo/refs/heads/master" by the suffix rule, and we will
      erroneously fetch it instead of refs/heads/master.
      
      As it turns out, all callers of fetch_pack do provide
      fully-qualified refs for the match list. There are two ways
      fetch_pack can get match lists:
      
        1. Through the transport code (i.e., via git-fetch)
      
        2. On the command-line of git-fetch-pack
      
      In the first case, we will always be providing the names of
      fully-qualified refs from "struct ref" objects. We will have
      pre-matched those ref objects already (since we have to
      handle more advanced matching, like wildcard refspecs), and
      are just providing a list of the refs whose objects we need.
      
      In the second case, users could in theory be providing
      non-qualified refs on the command-line. However, the
      fetch-pack documentation claims that refs should be fully
      qualified (and has always done so since it was written in
      2005).
      
      Let's change this path_match call to simply check for string
      equality, matching what the callers of fetch_pack are
      expecting.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      1e7ba0f9
    • J
      drop "match" parameter from get_remote_heads · afe7c5ff
      Jeff King 提交于
      The get_remote_heads function reads the list of remote refs
      during git protocol session. It dates all the way back to
      def88e9a (Commit first cut at "git-fetch-pack", 2005-07-04).
      At that time, the idea was to come up with a list of refs we
      were interested in, and then filter the list as we got it
      from the remote side.
      
      Later, 1baaae5e (Make maximal use of the remote refs,
      2005-10-28) stopped filtering at the get_remote_heads layer,
      letting us use the non-matching refs to find common history.
      
      As a result, all callers now simply pass an empty match
      list (and any future callers will want to do the same). So
      let's drop these now-useless parameters.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      afe7c5ff
    • N
      Rename resolve_ref() to resolve_ref_unsafe() · 8cad4744
      Nguyễn Thái Ngọc Duy 提交于
      resolve_ref() may return a pointer to a shared buffer and can be
      overwritten by the next resolve_ref() calls. Callers need to
      pay attention, not to keep the pointer when the next call happens.
      
      Rename with "_unsafe" suffix to warn developers (or reviewers) before
      introducing new call sites.
      
      This patch is generated using the following command
      
      git grep -l 'resolve_ref(' -- '*.[ch]'|xargs sed -i 's/resolve_ref(/resolve_ref_unsafe(/g'
      Signed-off-by: NNguyễn Thái Ngọc Duy <pclouds@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      8cad4744
    • N
  13. 13 12月, 2011 11 次提交
    • C
      Update documentation for stripspace · 497215d8
      Conrad Irwin 提交于
      Tell the user what this command is intended for, and expand the
      description of what it does.
      Signed-off-by: NConrad Irwin <conrad.irwin@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      497215d8
    • J
      mv: be quiet about overwriting · 534376ca
      Jeff King 提交于
      When a user asks us to force a mv and overwrite the
      destination, we print a warning. However, since a typical
      use would be:
      
        $ git mv one two
        fatal: destination exists, source=one, destination=two
        $ git mv -f one two
        warning: overwriting 'two'
      
      this warning is just noise. We already know we're
      overwriting; that's why we gave -f!
      
      This patch silences the warning unless "--verbose" is given.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      534376ca
    • J
      mv: improve overwrite warning · cd40b05d
      Jeff King 提交于
      When we try to "git mv" over an existing file, the error
      message is fairly informative:
      
        $ git mv one two
        fatal: destination exists, source=one, destination=two
      
      When the user forces the overwrite, we give a warning:
      
        $ git mv -f one two
        warning: destination exists; will overwrite!
      
      This is less informative, but still sufficient in the simple
      rename case, as there is only one rename happening.
      
      But when moving files from one directory to another, it
      becomes useless:
      
        $ mkdir three
        $ touch one two three/one
        $ git add .
        $ git mv one two three
        fatal: destination exists, source=one, destination=three/one
        $ git mv -f one two three
        warning: destination exists; will overwrite!
      
      The first message is helpful, but the second one gives us no
      clue about what was overwritten. Let's mention the name of
      the destination file:
      
        $ git mv -f one two three
        warning: overwriting 'three/one'
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      cd40b05d
    • J
      revert: stop creating and removing sequencer-old directory · d596118d
      Jonathan Nieder 提交于
      Now that "git reset" no longer implicitly removes .git/sequencer that
      the operator may or may not have wanted to keep, the logic to write a
      backup copy of .git/sequencer and remove it when stale is not needed
      any more.  Simplify the sequencer API and repository layout by
      dropping it.
      Signed-off-by: NJonathan Nieder <jrnieder@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      d596118d
    • J
      revert: do not remove state until sequence is finished · 218b65fb
      Jonathan Nieder 提交于
      As v1.7.8-rc0~141^2~4 (2011-08-04) explains, git cherry-pick removes
      the sequencer state just before applying the final patch.  In the
      single-pick case, that was a good thing, since --abort and --continue
      work fine without access to such state and removing it provides a
      signal that git should not complain about the need to clobber it ("a
      cherry-pick or revert is already in progress") in sequences like the
      following:
      
      	git cherry-pick foo
      	git read-tree -m -u HEAD; # forget that; let's try a different one
      	git cherry-pick bar
      
      After the recent patch "allow single-pick in the middle of cherry-pick
      sequence" we don't need that hack any more.  In the new regime, a
      traditional "git cherry-pick <commit>" command never looks at
      .git/sequencer, so we do not need to cripple "git cherry-pick
      <commit>..<commit>" for it any more.
      
      So now you can run "git cherry-pick --abort" near the end of a
      multi-pick sequence and it will abort the entire sequence, instead of
      misbehaving and aborting just the final commit.
      Signed-off-by: NJonathan Nieder <jrnieder@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      218b65fb
    • J
      revert: allow single-pick in the middle of cherry-pick sequence · 7acaaac2
      Jonathan Nieder 提交于
      After messing up a difficult conflict resolution in the middle of a
      cherry-pick sequence, it can be useful to be able to
      
      	git checkout HEAD . && git cherry-pick that-one-commit
      
      to restart the conflict resolution. The current code however errors out
      saying that another cherry-pick is already in progress.
      Suggested-by: NJohannes Sixt <j6t@kdbg.org>
      Signed-off-by: NJonathan Nieder <jrnieder@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      7acaaac2
    • J
      revert: pass around rev-list args in already-parsed form · 7f13334e
      Jonathan Nieder 提交于
      Since 7e2bfd3f (revert: allow cherry-picking more than one commit,
      2010-07-02), the pick/revert machinery has kept track of the set of
      commits to be cherry-picked or reverted using commit_argc and
      commit_argv variables, storing the corresponding command-line
      parameters.
      
      Future callers as other commands are built in (am, rebase, sequencer)
      may find it easier to pass rev-list options to this machinery in
      already-parsed form.  Teach cmd_cherry_pick and cmd_revert to parse
      the rev-list arguments in advance and pass the commit set to
      pick_revisions() as a rev_info structure.
      
      Original patch by Jonathan, tweaks and test from Ram.
      Signed-off-by: NJonathan Nieder <jrnieder@gmail.com>
      Improved-by: NRamkumar Ramachandra <artagnon@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      7f13334e
    • J
      revert: allow cherry-pick --continue to commit before resuming · 093a3091
      Jonathan Nieder 提交于
      When "git cherry-pick ..bar" encounters conflicts, permit the operator
      to use cherry-pick --continue after resolving them as a shortcut for
      "git commit && git cherry-pick --continue" to record the resolution
      and carry on with the rest of the sequence.
      
      This improves the analogy with "git rebase" (in olden days --continue
      was the way to preserve authorship when a rebase encountered
      conflicts) and fits well with a general UI goal of making "git cmd
      --continue" save humans the trouble of deciding what to do next.
      
      Example: after encountering a conflict from running "git cherry-pick
      foo bar baz":
      
      	CONFLICT (content): Merge conflict in main.c
      	error: could not apply f78a8d98c... bar!
      	hint: after resolving the conflicts, mark the corrected paths
      	hint: with 'git add <paths>' or 'git rm <paths>'
      	hint: and commit the result with 'git commit'
      
      We edit main.c to resolve the conflict, mark it acceptable with "git
      add main.c", and can run "cherry-pick --continue" to resume the
      sequence.
      
      	$ git cherry-pick --continue
      	[editor opens to confirm commit message]
      	[master 78c8a8c98] bar!
      	 1 files changed, 1 insertions(+), 1 deletions(-)
      	[master 87ca8798c] baz!
      	 1 files changed, 1 insertions(+), 1 deletions(-)
      
      This is done for both codepaths to pick multiple commits and a single
      commit.
      Signed-off-by: NJonathan Nieder <jrnieder@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      093a3091
    • J
      revert: give --continue handling its own function · 1df9bf46
      Jonathan Nieder 提交于
      This makes pick_revisions() a little shorter and easier to read
      straight through.
      Signed-off-by: NJonathan Nieder <jrnieder@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      1df9bf46
    • J
      mv: make non-directory destination error more clear · 77471646
      Jeff King 提交于
      If you try to "git mv" multiple files onto another
      non-directory file, you confusingly get the "usage" message:
      
        $ touch one two three
        $ git add .
        $ git mv one two three
        usage: git mv [options] <source>... <destination>
        [...]
      
      From the user's perspective, that makes no sense. They just
      gave parameters that exactly match that usage!
      
      This behavior dates back to the original C version of "git
      mv", which had a usage message like:
      
        usage: git mv (<source> <destination> | <source>...  <destination>)
      
      This was slightly less confusing, because it at least
      mentions that there are two ways to invoke (but it still
      isn't clear why what the user provided doesn't work).
      
      Instead, let's show an error message like:
      
        $ git mv one two three
        fatal: destination 'three' is not a directory
      
      We could leave the usage message in place, too, but it
      doesn't actually help here. It contains no hints that there
      are two forms, nor that multi-file form requires that the
      endpoint be a directory. So it just becomes useless noise
      that distracts from the real error.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      77471646
    • J
      mv: honor --verbose flag · 07b87389
      Jeff King 提交于
      The code for a verbose flag has been here since "git mv" was
      converted to C many years ago, but actually getting the "-v"
      flag from the command line was accidentally lost in the
      transition.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      07b87389