1. 20 11月, 2015 3 次提交
  2. 27 10月, 2015 1 次提交
  3. 24 10月, 2015 1 次提交
  4. 06 10月, 2015 1 次提交
  5. 26 9月, 2015 3 次提交
    • J
      read_remotes_file: simplify string handling · 0e265a92
      Jeff King 提交于
      The main motivation for this cleanup is to switch our
      line-reading to a strbuf, which removes the use of a
      fixed-size buffer (which limited the size of remote URLs).
      Since we have the strbuf, we can make use of strbuf_rtrim().
      
      While we're here, we can also simplify the parsing of each
      line.  First, we can use skip_prefix() to avoid some magic
      numbers.
      
      But second, we can avoid splitting the parsing and actions
      for each line into two stages. Right now we figure out which
      type of line we have, set an int to a magic number,
      skip any intermediate whitespace, and then act on
      the resulting value based on the magic number.
      
      Instead, let's factor the whitespace skipping into a
      function. That lets us avoid the magic numbers and keep the
      actions close to the parsing.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      0e265a92
    • J
      read_branches_file: simplify string handling · f28e3ab2
      Jeff King 提交于
      This function does a lot of manual string handling, and has
      some unnecessary limits. This patch cleans up a number of
      things:
      
        1. Drop the arbitrary 1000-byte limit on the size of the
           remote name (we do not have such a limit in any of the
           other remote-reading mechanisms).
      
        2. Replace fgets into a fixed-size buffer with a strbuf,
           eliminating any limits on the length of the URL.
      
        3. Replace manual whitespace handling with strbuf_trim
           (since we now have a strbuf). This also gets rid
           of a call to strcpy, and the confusing reuse of the "p"
           pointer for multiple purposes.
      
        4. We currently build up the refspecs over multiple strbuf
           calls. We do this to handle the fact that the URL "frag"
           may not be present. But rather than have multiple
           conditionals, let's just default "frag" to "master".
           This lets us format the refspecs with a single xstrfmt.
           It's shorter, and easier to see what the final string
           looks like.
      
           We also update the misleading comment in this area (the
           local branch is named after the remote name, not after
           the branch name on the remote side).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      f28e3ab2
    • J
      replace trivial malloc + sprintf / strcpy calls with xstrfmt · 75faa45a
      Jeff King 提交于
      It's a common pattern to do:
      
        foo = xmalloc(strlen(one) + strlen(two) + 1 + 1);
        sprintf(foo, "%s %s", one, two);
      
      (or possibly some variant with strcpy()s or a more
      complicated length computation).  We can switch these to use
      xstrfmt, which is shorter, involves less error-prone manual
      computation, and removes many sprintf and strcpy calls which
      make it harder to audit the code for real buffer overflows.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      75faa45a
  6. 26 5月, 2015 2 次提交
  7. 23 5月, 2015 3 次提交
    • J
      remote.c: add branch_get_push · e291c75a
      Jeff King 提交于
      In a triangular workflow, the place you pull from and the
      place you push to may be different. As we have
      branch_get_upstream for the former, this patch adds
      branch_get_push for the latter (and as the former implements
      @{upstream}, so will this implement @{push} in a future
      patch).
      
      Note that the memory-handling for the return value bears
      some explanation. Some code paths require allocating a new
      string, and some let us return an existing string. We should
      provide a consistent interface to the caller, so it knows
      whether to free the result or not.
      
      We could do so by xstrdup-ing any existing strings, and
      having the caller always free. But that makes us
      inconsistent with branch_get_upstream, so we would prefer to
      simply take ownership of the resulting string. We do so by
      storing it inside the "struct branch", just as we do with
      the upstream refname (in that case we compute it when the
      branch is created, but there's no reason not to just fill
      it in lazily in this case).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      e291c75a
    • J
      remote.c: return upstream name from stat_tracking_info · 979cb245
      Jeff King 提交于
      After calling stat_tracking_info, callers often want to
      print the name of the upstream branch (in addition to the
      tracking count). To do this, they have to access
      branch->merge->dst[0] themselves. This is not wrong, as the
      return value from stat_tracking_info tells us whether we
      have an upstream branch or not. But it is a bit leaky, as we
      make an assumption about how it calculated the upstream
      name.
      
      Instead, let's add an out-parameter that lets the caller
      know the upstream name we found.
      
      As a bonus, we can get rid of the unusual tri-state return
      from the function. We no longer need to use it to
      differentiate between "no tracking config" and "tracking ref
      does not exist" (since you can check the upstream_name for
      that), so we can just use the usual 0/-1 convention for
      success/error.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      979cb245
    • J
      remote.c: untangle error logic in branch_get_upstream · 1ca41a19
      Jeff King 提交于
      The error-diagnosis logic in branch_get_upstream was copied
      straight from sha1_name.c in the previous commit. However,
      because we check all error cases and upfront and then later
      diagnose them, the logic is a bit tangled. In particular:
      
        - if branch->merge[0] is NULL, we may end up dereferencing
          it for an error message (in practice, it should never be
          NULL, so this is probably not a triggerable bug).
      
        - We may enter the code path because branch->merge[0]->dst
          is NULL, but we then start our error diagnosis by
          checking whether our local branch exists. But that is
          only relevant to diagnosing missing merge config, not a
          missing tracking ref; our diagnosis may hide the real
          problem.
      
      Instead, let's just use a sequence of "if" blocks to check
      for each error type, diagnose it, and return NULL.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      1ca41a19
  8. 22 5月, 2015 7 次提交
    • J
      remote.c: report specific errors from branch_get_upstream · 3a429d0a
      Jeff King 提交于
      When the previous commit introduced the branch_get_upstream
      helper, there was one call-site that could not be converted:
      the one in sha1_name.c, which gives detailed error messages
      for each possible failure.
      
      Let's teach the helper to optionally report these specific
      errors. This lets us convert another callsite, and means we
      can use the helper in other locations that want to give the
      same error messages.
      
      The logic and error messages come straight from sha1_name.c,
      with the exception that we start each error with a lowercase
      letter, as is our usual style (note that a few tests need
      updated as a result).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      3a429d0a
    • J
      remote.c: introduce branch_get_upstream helper · a9f9f8cc
      Jeff King 提交于
      All of the information needed to find the @{upstream} of a
      branch is included in the branch struct, but callers have to
      navigate a series of possible-NULL values to get there.
      Let's wrap that logic up in an easy-to-read helper.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      a9f9f8cc
    • J
      remote.c: hoist read_config into remote_get_1 · 8770e6fb
      Jeff King 提交于
      Before the previous commit, we had to make sure that
      read_config() was called before entering remote_get_1,
      because we needed to pass pushremote_name by value. But now
      that we pass a function, we can let remote_get_1 handle
      loading the config itself, turning our wrappers into true
      one-liners.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      8770e6fb
    • J
      remote.c: provide per-branch pushremote name · da66b274
      Jeff King 提交于
      When remote.c loads its config, it records the
      branch.*.pushremote for the current branch along with the
      global remote.pushDefault value, and then binds them into a
      single value: the default push for the current branch. We
      then pass this value (which may be NULL) to remote_get_1
      when looking up a remote for push.
      
      This has a few downsides:
      
        1. It's confusing. The early-binding of the "current
           value" led to bugs like the one fixed by 98b406f3
           (remote: handle pushremote config in any order,
           2014-02-24). And the fact that pushremotes fall back to
           ordinary remotes is not explicit at all; it happens
           because remote_get_1 cannot tell the difference between
           "we are not asking for the push remote" and "there is
           no push remote configured".
      
        2. It throws away intermediate data. After read_config()
           finishes, we have no idea what the value of
           remote.pushDefault was, because the string has been
           overwritten by the current branch's
           branch.*.pushremote.
      
        3. It doesn't record other data. We don't note the
           branch.*.pushremote value for anything but the current
           branch.
      
      Let's make this more like the fetch-remote config. We'll
      record the pushremote for each branch, and then explicitly
      compute the correct remote for the current branch at the
      time of reading.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      da66b274
    • J
      remote.c: hoist branch.*.remote lookup out of remote_get_1 · f052154d
      Jeff King 提交于
      We'll want to use this logic as a fallback when looking up
      the pushremote, so let's pull it out into its own function.
      
      We don't technically need to make this available outside of
      remote.c, but doing so will provide a consistent API with
      pushremote_for_branch, which we will add later.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      f052154d
    • J
      remote.c: drop "remote" pointer from "struct branch" · 9e3751d4
      Jeff King 提交于
      When we create each branch struct, we fill in the
      "remote_name" field from the config, and then fill in the
      actual "remote" field (with a "struct remote") based on that
      name. However, it turns out that nobody really cares about
      the latter field. The only two sites that access it at all
      are:
      
        1. git-merge, which uses it to notice when the branch does
           not have a remote defined. But we can easily replace this
           with looking at remote_name instead.
      
        2. remote.c itself, when setting up the @{upstream} merge
           config. But we don't need to save the "remote" in the
           "struct branch" for that; we can just look it up for
           the duration of the operation.
      
      So there is no need to have both fields; they are redundant
      with each other (the struct remote contains the name, or you
      can look up the struct from the name). It would be nice to
      simplify this, especially as we are going to add matching
      pushremote config in a future patch (and it would be nice to
      keep them consistent).
      
      So which one do we keep and which one do we get rid of?
      
      If we had a lot of callers accessing the struct, it would be
      more efficient to keep it (since you have to do a lookup to
      go from the name to the struct, but not vice versa). But we
      don't have a lot of callers; we have exactly one, so
      efficiency doesn't matter. We can decide this based on
      simplicity and readability.
      
      And the meaning of the struct value is somewhat unclear. Is
      it always the remote matching remote_name? If remote_name is
      NULL (i.e., no per-branch config), does the struct fall back
      to the "origin" remote, or is it also NULL? These questions
      will get even more tricky with pushremotes, whose fallback
      behavior is more complicated. So let's just store the name,
      which pretty clearly represents the branch.*.remote config.
      Any lookup or fallback behavior can then be implemented in
      helper functions.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      9e3751d4
    • J
      remote.c: refactor setup of branch->merge list · ee2499fe
      Jeff King 提交于
      When we call branch_get() to lookup or create a "struct
      branch", we make sure the "merge" field is filled in so that
      callers can access it. But the conditions under which we do
      so are a little confusing, and can lead to two funny
      situations:
      
        1. If there's no branch.*.remote config, we cannot provide
           branch->merge (because it is really just an application
           of branch.*.merge to our remote's refspecs). But
           branch->merge_nr may be non-zero, leading callers to be
           believe they can access branch->merge (e.g., in
           branch_merge_matches and elsewhere).
      
           It doesn't look like this can cause a segfault in
           practice, as most code paths dealing with merge config
           will bail early if there is no remote defined. But it's
           a bit of a dangerous construct.
      
           We can fix this by setting merge_nr to "0" explicitly
           when we realize that we have no merge config. Note that
           merge_nr also counts the "merge_name" fields (which we
           _do_ have; that's how merge_nr got incremented), so we
           will "lose" access to them, in the sense that we forget
           how many we had. But no callers actually care; we use
           merge_name only while iteratively reading the config,
           and then convert it to the final "merge" form the first
           time somebody calls branch_get().
      
        2. We set up the "merge" field every time branch_get is
           called, even if it has already been done. This leaks
           memory.
      
           It's not a big deal in practice, since most code paths
           will access only one branch, or perhaps each branch
           only one time. But if you want to be pathological, you
           can leak arbitrary memory with:
      
             yes @{upstream} | head -1000 | git rev-list --stdin
      
           We can fix this by skipping setup when branch->merge is
           already non-NULL.
      
      In addition to those two fixes, this patch pushes the "do we
      need to setup merge?" logic down into set_merge, where it is
      a bit easier to follow.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      ee2499fe
  9. 04 5月, 2015 1 次提交
    • J
      remote.c: drop default_remote_name variable · e41bf352
      Jeff King 提交于
      When we read the remote config from disk, we update a
      default_remote_name variable if we see branch.*.remote
      config for the current branch. This isn't wrong, or even all
      that complicated, but it is a bit simpler (because it
      reduces our overall state) to just lazily compute the
      default when we need it.
      
      The ulterior motive here is that the push config uses a
      similar structure, and _is_ much more complicated as a
      result. That will be simplified in a future patch, and it's
      more readable if the logic for remotes and push-remotes
      matches.
      
      Note that we also used default_remote_name as a signal that
      the remote config has been loaded; after this patch, we now
      use an explicit flag.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      e41bf352
  10. 16 1月, 2015 1 次提交
  11. 14 1月, 2015 1 次提交
  12. 26 11月, 2014 1 次提交
  13. 16 10月, 2014 1 次提交
  14. 15 10月, 2014 1 次提交
    • J
      checkout: report upstream correctly even with loosely defined branch.*.merge · 05e73682
      Junio C Hamano 提交于
      When checking out a branch that is set to build on top of another
      branch (often, a remote-tracking branch), "git checkout" reports how
      your work relates to the other branch, e.g.
      
          Your branch is behind 'origin/master', and can be fast-forwarded.
      
      Back when this feature was introduced, this was only done for
      branches that build on remote-tracking branches, but 5e6e2b48 (Make
      local branches behave like remote branches when --tracked,
      2009-04-01) added support to give the same report for branches that
      build on other local branches (i.e. branches whose branch.*.remote
      variables are set to '.').  Unlike the support for the branches
      building on remote-tracking branches, however, this did not take
      into account the fact that branch.*.merge configuration is allowed
      to record a shortened branch name.
      
      When branch.*.merge is set to 'master' (not 'refs/heads/master'),
      i.e. "my branch builds on the local 'master' branch", this caused
      "git checkout" to report:
      
          Your branch is based on 'master', but the upstream is gone.
      
      The upstream is our repository and is definitely not gone, so this
      output is nonsense.
      
      The fix is fairly obvious; just like the branch name is DWIMed when
      "git pull" merges from the 'master' branch without complaint on such
      a branch, the name of the branch the current branch builds upon
      needs to be DWIMed the same way.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      05e73682
  15. 23 9月, 2014 1 次提交
  16. 13 8月, 2014 1 次提交
  17. 11 8月, 2014 1 次提交
  18. 31 7月, 2014 1 次提交
    • P
      use a hashmap to make remotes faster · d0da003d
      Patrick Reynolds 提交于
      Remotes are stored as an array, so looking one up or adding one without
      duplication is an O(n) operation.  Reading an entire config file full of
      remotes is O(n^2) in the number of remotes.  For a repository with tens of
      thousands of remotes, the running time can hit multiple minutes.
      
      Hash tables are way faster.  So we add a hashmap from remote name to
      struct remote and use it for all lookups.  The time to add a new remote to
      a repo that already has 50,000 remotes drops from ~2 minutes to < 1
      second.
      
      We retain the old array of remotes so iterators proceed in config-file
      order.
      Signed-off-by: NPatrick Reynolds <patrick.reynolds@github.com>
      Reviewed-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      d0da003d
  19. 21 6月, 2014 1 次提交
    • J
      use skip_prefix to avoid repeating strings · 95b567c7
      Jeff King 提交于
      It's a common idiom to match a prefix and then skip past it
      with strlen, like:
      
        if (starts_with(foo, "bar"))
      	  foo += strlen("bar");
      
      This avoids magic numbers, but means we have to repeat the
      string (and there is no compiler check that we didn't make a
      typo in one of the strings).
      
      We can use skip_prefix to handle this case without repeating
      ourselves.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      95b567c7
  20. 20 6月, 2014 1 次提交
    • J
      use xstrfmt in favor of manual size calculations · fa3f60b7
      Jeff King 提交于
      In many parts of the code, we do an ugly and error-prone
      malloc like:
      
        const char *fmt = "something %s";
        buf = xmalloc(strlen(foo) + 10 + 1);
        sprintf(buf, fmt, foo);
      
      This makes the code brittle, and if we ever get the
      allocation wrong, is a potential heap overflow. Let's
      instead favor xstrfmt, which handles the allocation
      automatically, and makes the code shorter and more readable.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      fa3f60b7
  21. 10 6月, 2014 1 次提交
  22. 28 5月, 2014 1 次提交
  23. 01 4月, 2014 1 次提交
  24. 27 3月, 2014 1 次提交
  25. 06 3月, 2014 3 次提交
    • J
      push: detect local refspec errors early · ba928c13
      Jeff King 提交于
      When pushing, we do not even look at our push refspecs until
      after we have made contact with the remote receive-pack and
      gotten its list of refs. This means that we may go to some
      work, including asking the user to log in, before realizing
      we have simple errors like "git push origin matser".
      
      We cannot catch all refspec problems, since fully evaluating
      the refspecs requires knowing what the remote side has. But
      we can do a quick sanity check of the local side and catch a
      few simple error cases.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      ba928c13
    • J
      match_explicit_lhs: allow a "verify only" mode · 471fd3fe
      Jeff King 提交于
      The match_explicit_lhs function has all of the logic
      necessary to verify the refspecs without actually doing any
      work. This patch lets callers pass a NULL "match" pointer to
      indicate they want a "verify only" operation.
      
      For the most part, we just need to avoid writing to the NULL
      pointer. However, we also have to refactor the
      try_explicit_object_name sub-function; it indicates success by
      allocating and returning a new ref. Instead, we give it an
      "out" parameter for the match and return a numeric status.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      471fd3fe
    • J
      match_explicit: hoist refspec lhs checks into their own function · f7ade3d3
      Jeff King 提交于
      In preparation for being able to check the left-hand side of
      our push refspecs separately, this pulls the examination of
      them out into its own function. There should be no behavior
      change.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      f7ade3d3