Permalink
Commits on Jan 3, 2019
  1. transport-helper: drop read/write errno checks

    peff authored and gitster committed Jan 11, 2018
    Since we use xread() and xwrite() here, EINTR, EAGAIN, and
    EWOULDBLOCK retries are already handled for us, and we will
    never see these errno values ourselves. We can drop these
    conditions entirely, making the code easier to follow.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
Commits on Nov 24, 2018
  1. odb_load_loose_cache: fix strbuf leak

    peff authored and gitster committed Nov 22, 2018
    Commit 3a2e082 ("object-store: provide helpers for loose_objects_cache",
    2018-11-12) moved the cache-loading code from find_short_object_filename(),
    but forgot the line that releases the path strbuf.
    
    Reported-by: René Scharfe <l.s.r@web.de>
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  2. t5562: fix perl path

    peff authored and gitster committed Nov 22, 2018
    Some systems do not have perl installed to /usr/bin. Use the variable
    from the build settiings, and call perl directly than via shebang.
    
    Signed-off-by: Max Kirillov <max@max630.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
Commits on Nov 21, 2018
  1. pack-objects: fix off-by-one in delta-island tree-depth computation

    peff authored and gitster committed Nov 20, 2018
    When delta-islands are in use, we need to record the deepest path at
    which we find each tree and blob. Our loop to do so counts slashes, so
    "foo" is depth 0, "foo/bar" is depth 1, and so on.
    
    However, this neglects root trees, which are represented by the empty
    string. Those also have depth 0, but are at a layer above "foo". Thus,
    "foo" should be 1, "foo/bar" at 2, and so on. We use this depth to
    topo-sort the trees in resolve_tree_islands(). As a result, we may fail
    to visit a root tree before the sub-trees it contains, and therefore not
    correctly pass down the island marks.
    
    That in turn could lead to missing some delta opportunities (objects are
    in the same island, but we didn't realize it) or creating unwanted
    cross-island deltas (one object is in an island another isn't, but we
    don't realize). In practice, it seems to have only a small effect.  Some
    experiments on the real-world git/git fork network at GitHub showed an
    improvement of only 0.14% in the resulting clone size.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  2. pack-objects: zero-initialize tree_depth/layer arrays

    peff authored and gitster committed Nov 20, 2018
    Commit 108f530 (pack-objects: move tree_depth into 'struct
    packing_data', 2018-08-16) started maintaining a tree_depth array that
    matches the "objects" array. We extend the array when:
    
      1. The objects array is extended, in which case we use realloc to
         extend the tree_depth array.
    
      2. A caller asks to store a tree_depth for object N, and this is the
         first such request; we create the array from scratch and store the
         value for N.
    
    In the latter case, though, we use regular xmalloc(), and the depth
    values for any objects besides N is undefined. This happens to not
    trigger a bug with the current code, but the reasons are quite subtle:
    
     - we never ask about the depth for any object with index i < N. This is
       because we store the depth immediately for all trees and blobs. So
       any such "i" must be a non-tree, and therefore we will never need to
       care about its depth (in fact, we really only care about the depth of
       trees).
    
     - there are no objects at this point with index i > N, because we
       always fill in the depth for a tree immediately after its object
       entry is created (we may still allocate uninitialized depth entries,
       but they'll be initialized by packlist_alloc() when it initializes
       the entry in the "objects" array).
    
    So it works, but only by chance. To be defensive, let's zero the array,
    which matches the "unset" values which would be handed out by
    oe_tree_depth() already.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  3. pack-objects: fix tree_depth and layer invariants

    peff authored and gitster committed Nov 20, 2018
    Commit 108f530 (pack-objects: move tree_depth into 'struct
    packing_data', 2018-08-16) dynamically manages a tree_depth array in
    packing_data that maintains one of these invariants:
    
      1. tree_depth is NULL (i.e., the requested options don't require us to
         track tree depths)
    
      2. tree_depth is non-NULL and has as many entries as the "objects"
         array
    
    We maintain (2) by:
    
      a. When the objects array grows, grow tree_depth to the same size
         (unless it's NULL, in which case we can leave it).
    
      b. When a caller asks to set a depth via oe_set_tree_depth(), if
         tree_depth is NULL we allocate it.
    
    But in (b), we use the number of stored objects, _not_ the allocated
    size of the objects array. So we can run into a situation like this:
    
      1. packlist_alloc() needs to store the Nth object, so it grows the
         objects array to M, where M > N.
    
      2. oe_set_tree_depth() wants to store a depth, so it allocates an
         array of length N. Now we've violated our invariant.
    
      3. packlist_alloc() needs to store the N+1th object. But it _doesn't_
         grow the objects array, since N <= M still holds. We try to assign
         to tree_depth[N+1], which is out of bounds.
    
    That doesn't happen in our test scripts, because the repositories they
    use are so small, but it's easy to trigger by running:
    
      echo HEAD | git pack-objects --revs --delta-islands --stdout >/dev/null
    
    in any reasonably-sized repo (like git.git).
    
    We can fix it by always growing the array to match pack->nr_alloc, not
    pack->nr_objects. Likewise for the "layer" array from fe0ac2f
    (pack-objects: move 'layer' into 'struct packing_data', 2018-08-16),
    which has the same bug.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
Commits on Nov 17, 2018
  1. bundle: dup() output descriptor closer to point-of-use

    peff authored and gitster committed Nov 16, 2018
    When writing a bundle to a file, the bundle code actually creates
    "your.bundle.lock" using our lockfile interface. We feed that output
    descriptor to a child git-pack-objects via run-command, which has the
    quirk that it closes the output descriptor in the parent.
    
    To avoid confusing the lockfile code (which still thinks the descriptor
    is valid), we dup() it, and operate on the duplicate.
    
    However, this has a confusing side effect: after the dup() but before we
    call pack-objects, we have _two_ descriptors open to the lockfile. If we
    call die() during that time, the lockfile code will try to clean up the
    partially-written file. It knows to close() the file before unlinking,
    since on some platforms (i.e., Windows) the open file would block the
    deletion. But it doesn't know about the duplicate descriptor. On
    Windows, triggering an error at the right part of the code will result
    in the cleanup failing and the lockfile being left in the filesystem.
    
    We can solve this by moving the dup() much closer to start_command(),
    shrinking the window in which we have the second descriptor open. It's
    easy to place this in such a way that no die() is possible. We could
    still die due to a signal in the exact wrong moment, but we already
    tolerate races there (e.g., a signal could come before we manage to put
    the file on the cleanup list in the first place).
    
    As a bonus, this shields create_bundle() itself from the duplicate-fd
    trick, and we can simplify its error handling (note that the lock
    rollback now happens unconditionally, but that's OK; it's a noop if we
    didn't open the lock in the first place).
    
    The included test uses an empty bundle to cause a failure at the right
    spot in the code, because that's easy to trigger (the other likely
    errors are write() problems like ENOSPC).  Note that it would already
    pass on non-Windows systems (because they are happy to unlink an
    already-open file).
    
    Based-on-a-patch-by: Gaël Lhez <gael.lhez@gmail.com>
    Signed-off-by: Jeff King <peff@peff.net>
    Tested-by: Johannes Schindelin <johannes.schindelin@gmx.de>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
Commits on Nov 13, 2018
  1. fetch-pack: drop custom loose object cache

    peff authored and gitster committed Nov 12, 2018
    Commit 024aa46 (fetch-pack.c: use oidset to check existence of loose
    object, 2018-03-14) added a cache to avoid calling stat() for a bunch of
    loose objects we don't have.
    
    Now that OBJECT_INFO_QUICK handles this caching itself, we can drop the
    custom solution.
    
    Note that this might perform slightly differently, as the original code
    stopped calling readdir() when we saw more loose objects than there were
    refs. So:
    
      1. The old code might have spent work on readdir() to fill the cache,
         but then decided there were too many loose objects, wasting that
         effort.
    
      2. The new code might spend a lot of time on readdir() if you have a
         lot of loose objects, even though there are very few objects to
         ask about.
    
    In practice it probably won't matter either way; see the previous commit
    for some discussion of the tradeoff.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  2. sha1-file: use loose object cache for quick existence check

    peff authored and gitster committed Nov 12, 2018
    In cases where we expect to ask has_sha1_file() about a lot of objects
    that we are not likely to have (e.g., during fetch negotiation), we
    already use OBJECT_INFO_QUICK to sacrifice accuracy (due to racing with
    a simultaneous write or repack) for speed (we avoid re-scanning the pack
    directory).
    
    However, even checking for loose objects can be expensive, as we will
    stat() each one. On many systems this cost isn't too noticeable, but
    stat() can be particularly slow on some operating systems, or due to
    network filesystems.
    
    Since the QUICK flag already tells us that we're OK with a slightly
    stale answer, we can use that as a cue to look in our in-memory cache of
    each object directory. That basically trades an in-memory binary search
    for a stat() call.
    
    Note that it is possible for this to actually be _slower_. We'll do a
    full readdir() to fill the cache, so if you have a very large number of
    loose objects and a very small number of lookups, that readdir() may end
    up more expensive.
    
    This shouldn't be a big deal in practice. If you have a large number of
    reachable loose objects, you'll already run into performance problems
    (which you should remedy by repacking). You may have unreachable objects
    which wouldn't otherwise impact performance. Usually these would go away
    with the prune step of "git gc", but they may be held for up to 2 weeks
    in the default configuration.
    
    So it comes down to how many such objects you might reasonably expect to
    have, how much slower is readdir() on N entries versus M stat() calls
    (and here we really care about the syscall backing readdir(), like
    getdents() on Linux, but I'll just call this readdir() below).
    
    If N is much smaller than M (a typical packed repo), we know this is a
    big win (few readdirs() followed by many uses of the resulting cache).
    When N and M are similar in size, it's also a win. We care about the
    latency of making a syscall, and readdir() should be giving us many
    values in a single call. How many?
    
    On Linux, running "strace -e getdents ls" shows a 32k buffer getting 512
    entries per call (which is 64 bytes per entry; the name itself is 38
    bytes, plus there are some other fields). So we can imagine that this is
    always a win as long as the number of loose objects in the repository is
    a factor of 500 less than the number of lookups you make. It's hard to
    auto-tune this because we don't generally know up front how many lookups
    we're going to do. But it's unlikely for this to perform significantly
    worse.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  3. object-store: provide helpers for loose_objects_cache

    peff authored and gitster committed Nov 12, 2018
    Our object_directory struct has a loose objects cache that all users of
    the struct can see. But the only one that knows how to load the cache is
    find_short_object_filename(). Let's extract that logic in to a reusable
    function.
    
    While we're at it, let's also reset the cache when we re-read the object
    directories. This shouldn't have an impact on performance, as re-reads
    are meant to be rare (and are already expensive, so we avoid them with
    things like OBJECT_INFO_QUICK).
    
    Since the cache is already meant to be an approximation, it's tempting
    to skip even this bit of safety. But it's necessary to allow more code
    to use it. For instance, fetch-pack explicitly re-reads the object
    directory after performing its fetch, and would be confused if we didn't
    clear the cache.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  4. sha1-file: use an object_directory for the main object dir

    peff authored and gitster committed Nov 12, 2018
    Our handling of alternate object directories is needlessly different
    from the main object directory. As a result, many places in the code
    basically look like this:
    
      do_something(r->objects->objdir);
    
      for (odb = r->objects->alt_odb_list; odb; odb = odb->next)
            do_something(odb->path);
    
    That gets annoying when do_something() is non-trivial, and we've
    resorted to gross hacks like creating fake alternates (see
    find_short_object_filename()).
    
    Instead, let's give each raw_object_store a unified list of
    object_directory structs. The first will be the main store, and
    everything after is an alternate. Very few callers even care about the
    distinction, and can just loop over the whole list (and those who care
    can just treat the first element differently).
    
    A few observations:
    
      - we don't need r->objects->objectdir anymore, and can just
        mechanically convert that to r->objects->odb->path
    
      - object_directory's path field needs to become a real pointer rather
        than a FLEX_ARRAY, in order to fill it with expand_base_dir()
    
      - we'll call prepare_alt_odb() earlier in many functions (i.e.,
        outside of the loop). This may result in us calling it even when our
        function would be satisfied looking only at the main odb.
    
        But this doesn't matter in practice. It's not a very expensive
        operation in the first place, and in the majority of cases it will
        be a noop. We call it already (and cache its results) in
        prepare_packed_git(), and we'll generally check packs before loose
        objects. So essentially every program is going to call it
        immediately once per program.
    
        Arguably we should just prepare_alt_odb() immediately upon setting
        up the repository's object directory, which would save us sprinkling
        calls throughout the code base (and forgetting to do so has been a
        source of subtle bugs in the past). But I've stopped short of that
        here, since there are already a lot of other moving parts in this
        patch.
    
      - Most call sites just get shorter. The check_and_freshen() functions
        are an exception, because they have entry points to handle local and
        nonlocal directories separately.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  5. handle alternates paths the same as the main object dir

    peff authored and gitster committed Nov 12, 2018
    When we generate loose file paths for the main object directory, the
    caller provides a buffer to loose_object_path (formerly sha1_file_name).
    The callers generally keep their own static buffer to avoid excessive
    reallocations.
    
    But for alternate directories, each struct carries its own scratch
    buffer. This is needlessly different; let's unify them.
    
    We could go either direction here, but this patch moves the alternates
    struct over to the main directory style (rather than vice-versa).
    Technically the alternates style is more efficient, as it avoids
    rewriting the object directory name on each call. But this is unlikely
    to matter in practice, as we avoid reallocations either way (and nobody
    has ever noticed or complained that the main object directory is copying
    a few extra bytes before making a much more expensive system call).
    
    And this has the advantage that the reusable buffers are tied to
    particular calls, which makes the invalidation rules simpler (for
    example, the return value from stat_sha1_file() used to be invalidated
    by basically any other object call, but now it is affected only by other
    calls to stat_sha1_file()).
    
    We do steal the trick from alt_sha1_path() of returning a pointer to the
    filled buffer, which makes a few conversions more convenient.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  6. sha1_file_name(): overwrite buffer instead of appending

    peff authored and gitster committed Nov 12, 2018
    The sha1_file_name() function is used to generate the path to a loose
    object in the object directory. It doesn't make much sense for it to
    append, since the the path we write may be absolute (i.e., you cannot
    reliably build up a path with it). Because many callers use it with a
    static buffer, they have to strbuf_reset() manually before each call
    (and the other callers always use an empty buffer, so they don't care
    either way). Let's handle this automatically.
    
    Since we're changing the semantics, let's take the opportunity to give
    it a more hash-neutral name (which will also catch any callers from
    topics in flight).
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  7. rename "alternate_object_database" to "object_directory"

    peff authored and gitster committed Nov 12, 2018
    In preparation for unifying the handling of alt odb's and the normal
    repo object directory, let's use a more neutral name. This patch is
    purely mechanical, swapping the type name, and converting any variables
    named "alt" to "odb". There should be no functional change, but it will
    reduce the noise in subsequent diffs.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  8. submodule--helper: prefer strip_suffix() to ends_with()

    peff authored and gitster committed Nov 12, 2018
    Using strip_suffix() lets us avoid repeating ourselves. It also makes
    the handling of "/" a bit less subtle (we strip one less character than
    we matched in order to leave it in place, but we can just as easily
    include the "/" when we add more path components).
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  9. fsck: do not reuse child_process structs

    peff authored and gitster committed Nov 12, 2018
    The run-command API makes no promises about what is left in a struct
    child_process after a command finishes, and it's not safe to simply
    reuse it again for a similar command. In particular:
    
     - if you use child->args or child->env_array, they are cleared after
       finish_command()
    
     - likewise, start_command() may point child->argv at child->args->argv;
       reusing that would lead to accessing freed memory
    
     - the in/out/err may hold pipe descriptors from the previous run
    
    These two calls are _probably_ OK because they do not use any of those
    features. But it's only by chance, and may break in the future; let's
    reinitialize our struct for each program we run.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
Commits on Nov 7, 2018
  1. approxidate: fix NULL dereference in date_time()

    peff authored and gitster committed Nov 7, 2018
    When we see a time like "noon", we pass "12" to our date_time() helper,
    which sets the hour to 12pm. If the current time is before noon, then we
    wrap around to yesterday using date_yesterday(). But unlike the normal
    calls to date_yesterday() from approxidate_alpha(), we pass a NULL "num"
    parameter. Since c27cc94 (approxidate: handle pending number for
    "specials", 2018-11-02), that causes a segfault.
    
    One way to fix this is by checking for NULL. But arguably date_time() is
    abusing our helper by passing NULL in the first place (and this is the
    only case where one of these "special" parsers is used this way). So
    instead, let's have it just do the 1-day subtraction itself. It's still
    just a one-liner due to our update_tm() helper.
    
    Note that the test added here is a little funny, as we say "10am noon",
    which makes the "10am" seem pointless.  But this bug can only be
    triggered when it the currently-parsed hour is before the special time.
    The latest special time is "tea" at 1700, but t0006 uses a hard-coded
    TEST_DATE_NOW of 1900. We could reset TEST_DATE_NOW, but that may lead
    to confusion in other tests. Just saying "10am noon" makes this test
    self-contained.
    
    Reported-by: Carlo Arenas <carenas@gmail.com>
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  2. pull: handle --verify-signatures for unborn branch

    peff authored and gitster committed Nov 6, 2018
    We usually just forward the --verify-signatures option along to
    git-merge, and trust it to do the right thing. However, when we are on
    an unborn branch (i.e., there is no HEAD yet), we handle this case
    ourselves without even calling git-merge. And in this code path, we do
    not respect the verification option at all.
    
    It may be more maintainable in the long run to call git-merge for the
    unborn case. That would fix this bug, as well as prevent similar ones in
    the future. But unfortunately it's not easy to do. As t5520.3
    demonstrates, there are some special cases that git-merge does not
    handle, like "git pull .. master:master" (by the time git-merge is
    invoked, we've overwritten the unborn HEAD).
    
    So for now let's just teach git-pull to handle this feature.
    
    Reported-by: Felix Eckhofer <felix@eckhofer.com>
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  3. merge: handle --verify-signatures for unborn branch

    peff authored and gitster committed Nov 6, 2018
    When git-merge sees that we are on an unborn branch (i.e., there is no
    HEAD), it follows a totally separate code path than the usual merge
    logic. This code path does not know about verify_signatures, and so we
    fail to notice bad or missing signatures.
    
    This has been broken since --verify-signatures was added in efed002
    (merge/pull: verify GPG signatures of commits being merged, 2013-03-31).
    In an ideal world, we'd unify the flow for this case with the regular
    merge logic, which would fix this bug and avoid introducing similar
    ones. But because the unborn case is so different, it would be a burden
    on the rest of the function to continually handle the missing HEAD. So
    let's just port the verification check to this special case.
    
    Reported-by: Felix Eckhofer <felix@eckhofer.com>
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  4. merge: extract verify_merge_signature() helper

    peff authored and gitster committed Nov 6, 2018
    The logic to implement "merge --verify-signatures" is inline in
    cmd_merge(), but this site misses some cases. Let's extract the logic
    into a function so we can call it from more places.
    
    We'll move it to commit.[ch], since one of the callers (git-pull) is
    outside our source file. This function isn't all that general (after
    all, its main function is to exit the program) but it's not worth trying
    to fix that. The heavy lifting is done by check_commit_signature(), and
    our purpose here is just sharing the die() logic. We'll mark it with a
    comment to make that clear.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
Commits on Nov 6, 2018
  1. midx: double-check large object write loop

    peff authored and gitster committed Nov 4, 2018
    The write_midx_large_offsets() function takes an array of object
    entries, the number of entries in the array (nr_objects), and the number
    of entries with large offsets (nr_large_offset). But we never actually
    use nr_objects; instead we keep walking down the array and counting down
    nr_large_offset until we've seen all of the large entries.
    
    This is correct, but we can be a bit more defensive. If there were ever
    a mismatch between nr_large_offset and the actual set of large-offset
    objects, we'd walk off the end of the array.
    
    Since we know the size of the array, we can use nr_objects to make sure
    we don't walk too far.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Reviewed-by: Derrick Stolee <dstolee@microsoft.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  2. assert NOARG/NONEG behavior of parse-options callbacks

    peff authored and gitster committed Nov 5, 2018
    When we define a parse-options callback, the flags we put in the option
    struct must match what the callback expects. For example, a callback
    which does not handle the "unset" parameter should only be used with
    PARSE_OPT_NONEG. But since the callback and the option struct are not
    defined next to each other, it's easy to get this wrong (as earlier
    patches in this series show).
    
    Fortunately, the compiler can help us here: compiling with
    -Wunused-parameters can show us which callbacks ignore their "unset"
    parameters (and likewise, ones that ignore "arg" expect to be triggered
    with PARSE_OPT_NOARG).
    
    But after we've inspected a callback and determined that all of its
    callers use the right flags, what do we do next? We'd like to silence
    the compiler warning, but do so in a way that will catch any wrong calls
    in the future.
    
    We can do that by actually checking those variables and asserting that
    they match our expectations. Because this is such a common pattern,
    we'll introduce some helper macros. The resulting messages aren't
    as descriptive as we could make them, but the file/line information from
    BUG() is enough to identify the problem (and anyway, the point is that
    these should never be seen).
    
    Each of the annotated callbacks in this patch triggers
    -Wunused-parameters, and was manually inspected to make sure all callers
    use the correct options (so none of these BUGs should be triggerable).
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  3. parse-options: drop OPT_DATE()

    peff authored and gitster committed Nov 5, 2018
    There are no users of OPT_DATE except for test-parse-options; its
    only caller went away in 27ec394 (prune: introduce OPT_EXPIRY_DATE()
    and use it, 2013-04-25).
    
    It also has a bug: it does not specify PARSE_OPT_NONEG, but its callback
    does not respect the "unset" flag, and will feed NULL to approxidate()
    and segfault. Probably this should be marked with NONEG, or the callback
    should set the timestamp to some sentinel value (e.g,. "0", or
    "(time_t)-1").
    
    But since there are no callers, deleting it means we don't even have to
    think about what the right behavior should be.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  4. apply: return -1 from option callback instead of calling exit(1)

    peff authored and gitster committed Nov 5, 2018
    The option callback for "apply --whitespace" exits with status "1" on
    error. It makes more sense for it to just return an error to
    parse-options. That code will exit, too, but it will use status "129"
    that is customary for option errors.
    
    The exit() dates back to aaf6c44 (builtin/apply: make
    parse_whitespace_option() return -1 instead of die()ing, 2016-08-08).
    That commit gives no reason why we'd prefer the current exit status (it
    looks like it was just bumping the "die" up a level in the callstack,
    but did not go as far as it could have).
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  5. cat-file: report an error on multiple --batch options

    peff authored and gitster committed Nov 5, 2018
    The options callback for --batch and --batch-check detects when the two
    mutually incompatible options are used. But it simply returns an error
    code to parse-options, meaning the program will quit without any kind of
    message to the user.
    
    Instead, let's use error() to print something and return -1. Note that
    this flips the error return from 1 to -1, but negative values are more
    idiomatic here (and parse-options treats them the same).
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  6. tag: mark "--message" option with NONEG

    peff authored and gitster committed Nov 5, 2018
    We do not allow "--no-message" to work now, as the option callback
    returns "-1" when it sees a NULL arg. However, that will cause
    parse-options to exit(129) without printing anything further, leaving
    the user confused about what happened.
    
    Instead, let's explicitly mark it as PARSE_OPT_NONEG, which will give a
    useful error message (and print the usual -h output).
    
    In theory this could be used to override an earlier "-m", but it's not
    clear how it would interact with other message options (e.g., would it
    also clear data read for "-F"?). Since it's already disabled and nobody
    is asking for it, let's punt on that and just improve the error message.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  7. show-branch: mark --reflog option as NONEG

    peff authored and gitster committed Nov 5, 2018
    Running "git show-branch --no-reflog" will behave as if "--reflog" was
    given with no options, which makes no sense.
    
    In theory this option might be used to cancel an earlier "--reflog"
    option, but the semantics are not clear. Let's punt on it and just
    disallow the broken option.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  8. format-patch: mark "--no-numbered" option with NONEG

    peff authored and gitster committed Nov 5, 2018
    We have separate parse-options entries for "numbered" and "no-numbered",
    which means that we accept "--no-no-numbered". It does not behave
    sensibly, though (it ignores the "unset" flag and acts like
    "--no-numbered").
    
    We could fix that, but obviously this is silly and unintentional. Let's
    just disallow it.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  9. status: mark --find-renames option with NONEG

    peff authored and gitster committed Nov 5, 2018
    If you run "git status --no-find-renames", it will behave the same as
    "--find-renames", because we ignore the "unset" parameter (we see a NULL
    "arg", but since the score argument is optional, we just think that the
    user did not provide a score).
    
    We already have a separate "--no-renames" to disable renames, so there's
    not much point in supporting "--no-find-renames". Let's just flag it as
    an error.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  10. cat-file: mark batch options with NONEG

    peff authored and gitster committed Nov 5, 2018
    Running "cat-file --no-batch" will behave as if "--batch" was given,
    since the option callback does not handle the "unset" flag (likewise for
    "--no-batch-check").
    
    In theory this might be used to cancel an earlier --batch, but it's not
    immediately obvious how that would interact with --batch-check. Let's
    just disallow the negated form of both options.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  11. pack-objects: mark index-version option as NONEG

    peff authored and gitster committed Nov 5, 2018
    Running "git pack-objects --no-index-version" will segfault, since the
    callback is not prepared to handle the "unset" flag.
    
    In theory this might be used to counteract an earlier "--index-version",
    or override a pack.indexversion config setting. But the semantics aren't
    immediately obvious, and it's unlikely anybody wants this. Let's just
    disable the broken option for now.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  12. ls-files: mark exclude options as NONEG

    peff authored and gitster committed Nov 5, 2018
    Running "git ls-files --no-exclude" will currently segfault, as its
    option callback does not handle the "unset" parameter.
    
    In theory this could be used to clear the exclude list, but it is not
    clear how that would interact with the other exclude options, nor is the
    current code capable of clearing the list. Let's just disable the broken
    option.
    
    Note that --no-exclude-from will similarly segfault, but
    --no-exclude-standard will not. It just silently does the wrong thing
    (pretending as if --exclude-standard was specified).
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  13. am: handle --no-patch-format option

    peff authored and gitster committed Nov 5, 2018
    Running "git am --no-patch-format" will currently segfault, since it
    tries to parse a NULL argument. Instead, let's have it cancel any
    previous --patch-format option.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
  14. apply: mark include/exclude options as NONEG

    peff authored and gitster committed Nov 5, 2018
    The options callback for "git apply --no-include" is not ready to handle
    the "unset" parameter, and as a result will segfault when it adds a NULL
    argument to the include list (likewise for "--no-exclude").
    
    In theory this might be used to clear the list, but since both
    "--include" and "--exclude" add to the same list, it's not immediately
    obvious what the semantics should be. Let's punt on that for now and
    just disallow the broken options.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
Commits on Nov 5, 2018
  1. xdiff-interface: drop parse_hunk_header()

    peff authored and gitster committed Nov 2, 2018
    This function was used only for parsing the hunk headers generated by
    xdiff. Now that we can use hunk callbacks to get that information
    directly, it has outlived its usefulness.
    
    Note to anyone who wants to resurrect it: the "len" parameter was
    totally unused, meaning that the function could read past the end of the
    "line" array. In practice this never happened, because we only used it
    to parse xdiff's generated header lines. But it would be dangerous to
    use it for other cases without fixing this defect.
    
    Signed-off-by: Jeff King <peff@peff.net>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>