Merge branch 'jk/repack-pack-keep-objects'
authorJunio C Hamano <gitster@pobox.com>
Tue, 18 Mar 2014 20:50:29 +0000 (13:50 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 18 Mar 2014 20:50:29 +0000 (13:50 -0700)
* jk/repack-pack-keep-objects:
repack: add `repack.packKeptObjects` config var

1  2 
Documentation/config.txt
Documentation/git-repack.txt
builtin/repack.c
t/t7700-repack.sh
diff --combined Documentation/config.txt
index 79e576878af5eb44b21fc0763faeb30519e022c3,c0a6e0d05607698e71dd62537eb88fb0f5911475..73c8973aae5bfad789a998e5623fc219959edaf6
@@@ -142,13 -142,19 +142,13 @@@ advice.*:
  --
        pushUpdateRejected::
                Set this variable to 'false' if you want to disable
 -              'pushNonFFCurrent', 'pushNonFFDefault',
 +              'pushNonFFCurrent',
                'pushNonFFMatching', 'pushAlreadyExists',
                'pushFetchFirst', and 'pushNeedsForce'
                simultaneously.
        pushNonFFCurrent::
                Advice shown when linkgit:git-push[1] fails due to a
                non-fast-forward update to the current branch.
 -      pushNonFFDefault::
 -              Advice to set 'push.default' to 'upstream' or 'current'
 -              when you ran linkgit:git-push[1] and pushed 'matching
 -              refs' by default (i.e. you did not provide an explicit
 -              refspec, and no 'push.default' configuration was set)
 -              and it resulted in a non-fast-forward error.
        pushNonFFMatching::
                Advice shown when you ran linkgit:git-push[1] and pushed
                'matching refs' explicitly (i.e. you used ':', or
@@@ -561,10 -567,6 +561,10 @@@ be passed to the shell by Git, which wi
  command to `LESS=FRSX less -+S`. The environment tells the command
  to set the `S` option to chop long lines but the command line
  resets it to the default to fold long lines.
 ++
 +Likewise, when the `LV` environment variable is unset, Git sets it
 +to `-c`.  You can override this setting by exporting `LV` with
 +another value or setting `core.pager` to `lv +c`.
  
  core.whitespace::
        A comma separated list of common whitespace problems to
@@@ -986,14 -988,6 +986,14 @@@ commit.cleanup:
        have to remove the help lines that begin with `#` in the commit log
        template yourself, if you do this).
  
 +commit.gpgsign::
 +
 +      A boolean to specify whether all commits should be GPG signed.
 +      Use of this option when doing operations such as rebase can
 +      result in a large number of commits being signed. It may be
 +      convenient to use an agent to avoid typing your GPG passphrase
 +      several times.
 +
  commit.status::
        A boolean to enable/disable inclusion of status information in the
        commit message template when using an editor to prepare the commit
@@@ -1169,10 -1163,6 +1169,10 @@@ gc.autopacklimit:
        --auto` consolidates them into one larger pack.  The
        default value is 50.  Setting this to 0 disables it.
  
 +gc.autodetach::
 +      Make `git gc --auto` return immediately andrun in background
 +      if the system supports it. Default is true.
 +
  gc.packrefs::
        Running `git pack-refs` in a repository renders it
        unclonable by Git versions prior to 1.5.1.2 over dumb
@@@ -1607,10 -1597,6 +1607,10 @@@ imap:
        The configuration variables in the 'imap' section are described
        in linkgit:git-imap-send[1].
  
 +index.version::
 +      Specify the version with which new index files should be
 +      initialized.  This does not affect existing repositories.
 +
  init.templatedir::
        Specify the directory from which templates will be copied.
        (See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
@@@ -1643,7 -1629,7 +1643,7 @@@ interactive.singlekey:
        linkgit:git-add[1], linkgit:git-checkout[1], linkgit:git-commit[1],
        linkgit:git-reset[1], and linkgit:git-stash[1]. Note that this
        setting is silently ignored if portable keystroke input
 -      is not available.
 +      is not available; requires the Perl module Term::ReadKey.
  
  log.abbrevCommit::
        If true, makes linkgit:git-log[1], linkgit:git-show[1], and
@@@ -1916,16 -1902,6 +1916,16 @@@ pretty.<name>:
        Note that an alias with the same name as a built-in format
        will be silently ignored.
  
 +pull.ff::
 +      By default, Git does not create an extra merge commit when merging
 +      a commit that is a descendant of the current commit. Instead, the
 +      tip of the current branch is fast-forwarded. When set to `false`,
 +      this variable tells Git to create an extra merge commit in such
 +      a case (equivalent to giving the `--no-ff` option from the command
 +      line). When set to `only`, only such fast-forward merges are
 +      allowed (equivalent to giving the `--ff-only` option from the
 +      command line).
 +
  pull.rebase::
        When true, rebase branches on top of the fetched branch, instead
        of merging the default branch from the default remote when "git
@@@ -1978,7 -1954,7 +1978,7 @@@ When pushing to a remote that is differ
  pull from, work as `current`.  This is the safest option and is suited
  for beginners.
  +
 -This mode will become the default in Git 2.0.
 +This mode has become the default in Git 2.0.
  
  * `matching` - push all branches having the same name on both ends.
    This makes the repository you are pushing to remember the set of
@@@ -1997,8 -1973,8 +1997,8 @@@ suitable for pushing into a shared cent
  people may add new branches there, or update the tip of existing
  branches outside your control.
  +
 -This is currently the default, but Git 2.0 will change the default
 -to `simple`.
 +This used to be the default, but not since Git 2.0 (`simple` is the
 +new default).
  
  --
  
@@@ -2075,10 -2051,6 +2075,10 @@@ receive.updateserverinfo:
        If set to true, git-receive-pack will run git-update-server-info
        after receiving data from git-push and updating refs.
  
 +receive.shallowupdate::
 +      If set to true, .git/shallow can be updated when new refs
 +      require new shallow roots. Otherwise those refs are rejected.
 +
  remote.pushdefault::
        The remote to push to by default.  Overrides
        `branch.<name>.remote` for all branches, and is overridden by
@@@ -2140,8 -2112,8 +2140,8 @@@ remote.<name>.vcs:
  
  remote.<name>.prune::
        When set to true, fetching from this remote by default will also
 -      remove any remote-tracking branches which no longer exist on the
 -      remote (as if the `--prune` option was give on the command line).
 +      remove any remote-tracking references that no longer exist on the
 +      remote (as if the `--prune` option was given on the command line).
        Overrides `fetch.prune` settings, if any.
  
  remotes.<group>::
@@@ -2156,6 -2128,13 +2156,13 @@@ repack.usedeltabaseoffset:
        "false" and repack. Access from old Git versions over the
        native protocol are unaffected by this option.
  
+ repack.packKeptObjects::
+       If set to true, makes `git repack` act as if
+       `--pack-kept-objects` was passed. See linkgit:git-repack[1] for
+       details. Defaults to `false` normally, but `true` if a bitmap
+       index is being written (either via `--write-bitmap-index` or
+       `pack.writeBitmaps`).
  rerere.autoupdate::
        When set to true, `git-rerere` updates the index with the
        resulting contents after it cleanly resolves conflicts using
@@@ -2336,13 -2315,6 +2343,13 @@@ transfer.unpackLimit:
        not set, the value of this variable is used instead.
        The default value is 100.
  
 +uploadarchive.allowUnreachable::
 +      If true, allow clients to use `git archive --remote` to request
 +      any tree, whether reachable from the ref tips or not. See the
 +      discussion in the `SECURITY` section of
 +      linkgit:git-upload-archive[1] for more details. Defaults to
 +      `false`.
 +
  uploadpack.hiderefs::
        String(s) `upload-pack` uses to decide which refs to omit
        from its initial advertisement.  Use more than one
index 002cfd5eb959ce7c8afea32388477f3a1062c485,1eedf880ebadae3c95388d930c67296fc9a57088..4786a780b5443e6c021e1ce49c3d0f1d96865aba
@@@ -14,7 -14,7 +14,7 @@@ SYNOPSI
  DESCRIPTION
  -----------
  
 -This script is used to combine all objects that do not currently
 +This command is used to combine all objects that do not currently
  reside in a "pack", into a pack.  It can also be used to re-organize
  existing packs into a single, more efficient pack.
  
@@@ -117,6 -117,14 +117,14 @@@ other objects in that pack they alread
        must be able to refer to all reachable objects. This option
        overrides the setting of `pack.writebitmaps`.
  
+ --pack-kept-objects::
+       Include objects in `.keep` files when repacking.  Note that we
+       still do not delete `.keep` packs after `pack-objects` finishes.
+       This means that we may duplicate objects, but this makes the
+       option safe to use when there are concurrent pushes or fetches.
+       This option is generally only useful if you are writing bitmaps
+       with `-b` or `pack.writebitmaps`, as it ensures that the
+       bitmapped packfile has the necessary objects.
  
  Configuration
  -------------
diff --combined builtin/repack.c
index 49f5857627fd616b1019063f3f2d1937b20004fd,50cc2815279e17b255ddc74d23f619e1259b8a7c..6b0b62dcb2687e78ec433e7de1103f0c0f74a1fc
@@@ -9,6 -9,7 +9,7 @@@
  #include "argv-array.h"
  
  static int delta_base_offset = 1;
+ static int pack_kept_objects = -1;
  static char *packdir, *packtmp;
  
  static const char *const git_repack_usage[] = {
@@@ -22,6 -23,10 +23,10 @@@ static int repack_config(const char *va
                delta_base_offset = git_config_bool(var, value);
                return 0;
        }
+       if (!strcmp(var, "repack.packkeptobjects")) {
+               pack_kept_objects = git_config_bool(var, value);
+               return 0;
+       }
        return git_default_config(var, value, cb);
  }
  
@@@ -78,7 -83,7 +83,7 @@@ static void get_non_kept_pack_filenames
                return;
  
        while ((e = readdir(dir)) != NULL) {
 -              if (suffixcmp(e->d_name, ".pack"))
 +              if (!ends_with(e->d_name, ".pack"))
                        continue;
  
                len = strlen(e->d_name) - strlen(".pack");
@@@ -130,16 -135,16 +135,16 @@@ int cmd_repack(int argc, const char **a
        struct string_list rollback = STRING_LIST_INIT_NODUP;
        struct string_list existing_packs = STRING_LIST_INIT_DUP;
        struct strbuf line = STRBUF_INIT;
 -      int nr_packs, ext, ret, failed;
 +      int ext, ret, failed;
        FILE *out;
  
        /* variables to be filled by option parsing */
        int pack_everything = 0;
        int delete_redundant = 0;
 -      char *unpack_unreachable = NULL;
 -      int window = 0, window_memory = 0;
 -      int depth = 0;
 -      int max_pack_size = 0;
 +      const char *unpack_unreachable = NULL;
 +      const char *window = NULL, *window_memory = NULL;
 +      const char *depth = NULL;
 +      const char *max_pack_size = NULL;
        int no_reuse_delta = 0, no_reuse_object = 0;
        int no_update_server_info = 0;
        int quiet = 0;
                                N_("write bitmap index")),
                OPT_STRING(0, "unpack-unreachable", &unpack_unreachable, N_("approxidate"),
                                N_("with -A, do not loosen objects older than this")),
 -              OPT_INTEGER(0, "window", &window,
 +              OPT_STRING(0, "window", &window, N_("n"),
                                N_("size of the window used for delta compression")),
 -              OPT_INTEGER(0, "window-memory", &window_memory,
 +              OPT_STRING(0, "window-memory", &window_memory, N_("bytes"),
                                N_("same as the above, but limit memory size instead of entries count")),
 -              OPT_INTEGER(0, "depth", &depth,
 +              OPT_STRING(0, "depth", &depth, N_("n"),
                                N_("limits the maximum delta depth")),
 -              OPT_INTEGER(0, "max-pack-size", &max_pack_size,
 +              OPT_STRING(0, "max-pack-size", &max_pack_size, N_("bytes"),
                                N_("maximum size of each packfile")),
+               OPT_BOOL(0, "pack-kept-objects", &pack_kept_objects,
+                               N_("repack objects in packs marked with .keep")),
                OPT_END()
        };
  
        argc = parse_options(argc, argv, prefix, builtin_repack_options,
                                git_repack_usage, 0);
  
+       if (pack_kept_objects < 0)
+               pack_kept_objects = write_bitmap;
        packdir = mkpathdup("%s/pack", get_object_directory());
        packtmp = mkpathdup("%s/.tmp-%d-pack", packdir, (int)getpid());
  
  
        argv_array_push(&cmd_args, "pack-objects");
        argv_array_push(&cmd_args, "--keep-true-parents");
-       argv_array_push(&cmd_args, "--honor-pack-keep");
+       if (!pack_kept_objects)
+               argv_array_push(&cmd_args, "--honor-pack-keep");
        argv_array_push(&cmd_args, "--non-empty");
        argv_array_push(&cmd_args, "--all");
        argv_array_push(&cmd_args, "--reflog");
        if (window)
 -              argv_array_pushf(&cmd_args, "--window=%u", window);
 +              argv_array_pushf(&cmd_args, "--window=%s", window);
        if (window_memory)
 -              argv_array_pushf(&cmd_args, "--window-memory=%u", window_memory);
 +              argv_array_pushf(&cmd_args, "--window-memory=%s", window_memory);
        if (depth)
 -              argv_array_pushf(&cmd_args, "--depth=%u", depth);
 +              argv_array_pushf(&cmd_args, "--depth=%s", depth);
        if (max_pack_size)
 -              argv_array_pushf(&cmd_args, "--max_pack_size=%u", max_pack_size);
 +              argv_array_pushf(&cmd_args, "--max-pack-size=%s", max_pack_size);
        if (no_reuse_delta)
                argv_array_pushf(&cmd_args, "--no-reuse-delta");
        if (no_reuse_object)
        if (ret)
                return ret;
  
 -      nr_packs = 0;
        out = xfdopen(cmd.out, "r");
        while (strbuf_getline(&line, out, '\n') != EOF) {
                if (line.len != 40)
                        die("repack: Expecting 40 character sha1 lines only from pack-objects.");
                string_list_append(&names, line.buf);
 -              nr_packs++;
        }
        fclose(out);
        ret = finish_command(&cmd);
                return ret;
        argv_array_clear(&cmd_args);
  
 -      if (!nr_packs && !quiet)
 +      if (!names.nr && !quiet)
                printf("Nothing new to pack.\n");
  
        /*
        for_each_string_list_item(item, &names) {
                for (ext = 0; ext < ARRAY_SIZE(exts); ext++) {
                        char *fname, *fname_old;
 -                      fname = mkpathdup("%s/%s%s", packdir,
 +                      fname = mkpathdup("%s/pack-%s%s", packdir,
                                                item->string, exts[ext].name);
                        if (!file_exists(fname)) {
                                free(fname);
        for_each_string_list_item(item, &names) {
                for (ext = 0; ext < ARRAY_SIZE(exts); ext++) {
                        char *fname;
 -                      fname = mkpath("%s/old-pack-%s%s",
 +                      fname = mkpath("%s/old-%s%s",
                                        packdir,
                                        item->string,
                                        exts[ext].name);
diff --combined t/t7700-repack.sh
index b45bd1e76cd24940545706c8f5611adce9b3803e,44f949742152c8bf063c2493fb1de67df433de8c..284018e3cdb31e7db179a93f7196fda47578c43c
@@@ -17,11 -17,11 +17,11 @@@ test_expect_success 'objects in packs m
        # The second pack will contain the excluded object
        packsha1=$(git rev-list --objects --all | grep file2 |
                git pack-objects pack) &&
 -      touch -r pack-$packsha1.pack pack-$packsha1.keep &&
 +      >pack-$packsha1.keep &&
        objsha1=$(git verify-pack -v pack-$packsha1.idx | head -n 1 |
                sed -e "s/^\([0-9a-f]\{40\}\).*/\1/") &&
        mv pack-* .git/objects/pack/ &&
-       git repack -A -d -l &&
+       git repack --no-pack-kept-objects -A -d -l &&
        git prune-packed &&
        for p in .git/objects/pack/*.idx; do
                idx=$(basename $p)
        test -z "$found_duplicate_object"
  '
  
+ test_expect_success 'writing bitmaps can duplicate .keep objects' '
+       # build on $objsha1, $packsha1, and .keep state from previous
+       git repack -Adl &&
+       test_when_finished "found_duplicate_object=" &&
+       for p in .git/objects/pack/*.idx; do
+               idx=$(basename $p)
+               test "pack-$packsha1.idx" = "$idx" && continue
+               if git verify-pack -v $p | egrep "^$objsha1"; then
+                       found_duplicate_object=1
+                       echo "DUPLICATE OBJECT FOUND"
+                       break
+               fi
+       done &&
+       test "$found_duplicate_object" = 1
+ '
  test_expect_success 'loose objects in alternate ODB are not repacked' '
        mkdir alt_objects &&
        echo `pwd`/alt_objects > .git/objects/info/alternates &&