Merge branch 'bc/maint-keep-pack' into maint
authorJunio C Hamano <gitster@pobox.com>
Wed, 3 Dec 2008 07:00:04 +0000 (23:00 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 3 Dec 2008 07:00:04 +0000 (23:00 -0800)
* bc/maint-keep-pack:
repack: only unpack-unreachable if we are deleting redundant packs
t7700: test that 'repack -a' packs alternate packed objects
pack-objects: extend --local to mean ignore non-local loose objects too
sha1_file.c: split has_loose_object() into local and non-local counterparts
t7700: demonstrate mishandling of loose objects in an alternate ODB
builtin-gc.c: use new pack_keep bitfield to detect .keep file existence
repack: do not fall back to incremental repacking with [-a|-A]
repack: don't repack local objects in packs with .keep file
pack-objects: new option --honor-pack-keep
packed_git: convert pack_local flag into a bitfield and add pack_keep
t7700: demonstrate mishandling of objects in packs with a .keep file

35 files changed:
Documentation/RelNotes-1.6.0.4.txt
Documentation/RelNotes-1.6.0.5.txt [new file with mode: 0644]
Documentation/config.txt
Documentation/git-check-attr.txt
Documentation/git-cherry-pick.txt
Documentation/git-commit.txt
Documentation/git-svn.txt
Documentation/gitcore-tutorial.txt
Documentation/gitglossary.txt
Documentation/urls-remotes.txt
Documentation/user-manual.txt
RelNotes
builtin-checkout.c
builtin-diff.c
builtin-fast-export.c
builtin-ls-files.c
builtin-pack-objects.c
builtin-read-tree.c
builtin-tag.c
cache.h
compat/mingw.c
contrib/completion/git-completion.bash
contrib/fast-import/git-p4
date.c
generate-cmdlist.sh
git-request-pull.sh
read-cache.c
remote.c
revision.c
sha1_file.c
t/t4020-diff-external.sh
t/t5300-pack-object.sh
t/t5516-fetch-push.sh
t/t7004-tag.sh
t/t9301-fast-export.sh
index fba3f30a89e22474ec3df358441cd79d29ff2bec..d522661d315c3aab445bf3aa123bbd0abd9db251 100644 (file)
@@ -30,7 +30,7 @@ Fixes since v1.6.0.3
 * 'git status' incorrectly reported a submodule directory as an untracked
   directory.
 
-* 'git svn' used deprecated 'git-foo' form of subcommand invocaition.
+* 'git svn' used deprecated 'git-foo' form of subcommand invocation.
 
 * 'git update-ref -d' to remove a reference did not honor --no-deref option.
 
diff --git a/Documentation/RelNotes-1.6.0.5.txt b/Documentation/RelNotes-1.6.0.5.txt
new file mode 100644 (file)
index 0000000..1dc101c
--- /dev/null
@@ -0,0 +1,43 @@
+GIT v1.6.0.5 Release Notes
+==========================
+
+Fixes since v1.6.0.4
+--------------------
+
+* 'git checkout' used to crash when your HEAD was pointing at a deleted
+  branch.
+
+* 'git checkout' from an un-checked-out state did not allow switching out
+  of the current branch.
+
+* 'git diff' always allowed GIT_EXTERNAL_DIFF and --no-ext-diff was no-op for
+  the command.
+
+* 'git fast-export' did not export all tags.
+
+* 'git ls-files --with-tree=<tree>' did not work with options other
+  than -c, most notably with -m.
+
+* 'git pack-objects' did not make its best effort to honor --max-pack-size
+  option when a single first object already busted the given limit and
+  placed many objects in a single pack.
+
+* 'git-p4' fast import frontend was too eager to trigger its keyword expansion
+  logic, even on a keyword-looking string that does not have closing '$' on the
+  same line.
+
+* 'git push $there' when the remote $there is defined in $GIT_DIR/branches/$there
+  behaves more like what cg-push from Cogito used to work.
+
+* 'git tag' did not complain when given mutually incompatible set of options.
+
+* 'make check' cannot be run without sparse; people may have meant to say
+  'make test' instead, so suggest that.
+
+* Many unsafe call to sprintf() style varargs functions are corrected.
+
+* Also contains quite a few documentation updates.
+
+--
+O=v1.6.0.4-39-g27f6496
+
index 87b028fbc1817c9c641e5fe03aab641e3bd5eb63..113d9d1438891b51d11f2fee2764c88e69024921 100644 (file)
@@ -561,9 +561,6 @@ color.status.<slot>::
        to red). The values of these variables may be specified as in
        color.branch.<slot>.
 
-commit.template::
-       Specify a file to use as the template for new commit messages.
-
 color.ui::
        When set to `always`, always use colors in all git commands which
        are capable of colored output. When false (or `never`), never. When
@@ -571,6 +568,9 @@ color.ui::
        terminal. When more specific variables of color.* are set, they always
        take precedence over this setting. Defaults to false.
 
+commit.template::
+       Specify a file to use as the template for new commit messages.
+
 diff.autorefreshindex::
        When using 'git-diff' to compare with work tree
        files, do not consider stat-only change as changed.
@@ -682,18 +682,6 @@ gc.rerereunresolved::
        kept for this many days when 'git-rerere gc' is run.
        The default is 15 days.  See linkgit:git-rerere[1].
 
-rerere.autoupdate::
-       When set to true, `git-rerere` updates the index with the
-       resulting contents after it cleanly resolves conflicts using
-       previously recorded resolution.  Defaults to false.
-
-rerere.enabled::
-       Activate recording of resolved conflicts, so that identical
-       conflict hunks can be resolved automatically, should they
-       be encountered again.  linkgit:git-rerere[1] command is by
-       default enabled if you create `rr-cache` directory under
-       `$GIT_DIR`, but can be disabled by setting this option to false.
-
 gitcvs.enabled::
        Whether the CVS server interface is enabled for this repository.
        See linkgit:git-cvsserver[1].
@@ -852,6 +840,10 @@ i18n.logOutputEncoding::
        Character encoding the commit messages are converted to when
        running 'git-log' and friends.
 
+imap::
+       The configuration variables in the 'imap' section are described
+       in linkgit:git-imap-send[1].
+
 instaweb.browser::
        Specify the program that will be used to browse your working
        repository in gitweb. See linkgit:git-instaweb[1].
@@ -887,8 +879,6 @@ man.viewer::
        Specify the programs that may be used to display help in the
        'man' format. See linkgit:git-help[1].
 
-include::merge-config.txt[]
-
 man.<tool>.cmd::
        Specify the command to invoke the specified man viewer. The
        specified command is evaluated in shell with the man page
@@ -898,6 +888,8 @@ man.<tool>.path::
        Override the path for the given tool that may be used to
        display help in the 'man' format. See linkgit:git-help[1].
 
+include::merge-config.txt[]
+
 mergetool.<tool>.path::
        Override the path for the given tool.  This is useful in case
        your tool is not in the PATH.
@@ -1006,6 +998,28 @@ pull.octopus::
 pull.twohead::
        The default merge strategy to use when pulling a single branch.
 
+receive.fsckObjects::
+       If it is set to true, git-receive-pack will check all received
+       objects. It will abort in the case of a malformed object or a
+       broken link. The result of an abort are only dangling objects.
+       Defaults to false.
+
+receive.unpackLimit::
+       If the number of objects received in a push is below this
+       limit then the objects will be unpacked into loose object
+       files. However if the number of received objects equals or
+       exceeds this limit then the received pack will be stored as
+       a pack, after adding any missing delta bases.  Storing the
+       pack from a push can make the push operation complete faster,
+       especially on slow filesystems.  If not set, the value of
+       `transfer.unpackLimit` is used instead.
+
+receive.denyNonFastForwards::
+       If set to true, git-receive-pack will deny a ref update which is
+       not a fast forward. Use this to prevent such an update via a push,
+       even if that push is forced. This configuration variable is
+       set when initializing a shared repository.
+
 remote.<name>.url::
        The URL of a remote repository.  See linkgit:git-fetch[1] or
        linkgit:git-push[1].
@@ -1055,6 +1069,18 @@ repack.usedeltabaseoffset::
        "false" and repack. Access from old git versions over the
        native protocol are unaffected by this option.
 
+rerere.autoupdate::
+       When set to true, `git-rerere` updates the index with the
+       resulting contents after it cleanly resolves conflicts using
+       previously recorded resolution.  Defaults to false.
+
+rerere.enabled::
+       Activate recording of resolved conflicts, so that identical
+       conflict hunks can be resolved automatically, should they
+       be encountered again.  linkgit:git-rerere[1] command is by
+       default enabled if you create `rr-cache` directory under
+       `$GIT_DIR`, but can be disabled by setting this option to false.
+
 showbranch.default::
        The default set of branches for linkgit:git-show-branch[1].
        See linkgit:git-show-branch[1].
@@ -1091,6 +1117,11 @@ tar.umask::
        archiving user's umask will be used instead.  See umask(2) and
        linkgit:git-archive[1].
 
+transfer.unpackLimit::
+       When `fetch.unpackLimit` or `receive.unpackLimit` are
+       not set, the value of this variable is used instead.
+       The default value is 100.
+
 url.<base>.insteadOf::
        Any URL that starts with this value will be rewritten to
        start, instead, with <base>. In cases where some site serves a
@@ -1119,37 +1150,6 @@ user.signingkey::
        unchanged to gpg's --local-user parameter, so you may specify a key
        using any method that gpg supports.
 
-imap::
-       The configuration variables in the 'imap' section are described
-       in linkgit:git-imap-send[1].
-
-receive.fsckObjects::
-       If it is set to true, git-receive-pack will check all received
-       objects. It will abort in the case of a malformed object or a
-       broken link. The result of an abort are only dangling objects.
-       Defaults to false.
-
-receive.unpackLimit::
-       If the number of objects received in a push is below this
-       limit then the objects will be unpacked into loose object
-       files. However if the number of received objects equals or
-       exceeds this limit then the received pack will be stored as
-       a pack, after adding any missing delta bases.  Storing the
-       pack from a push can make the push operation complete faster,
-       especially on slow filesystems.  If not set, the value of
-       `transfer.unpackLimit` is used instead.
-
-receive.denyNonFastForwards::
-       If set to true, git-receive-pack will deny a ref update which is
-       not a fast forward. Use this to prevent such an update via a push,
-       even if that push is forced. This configuration variable is
-       set when initializing a shared repository.
-
-transfer.unpackLimit::
-       When `fetch.unpackLimit` or `receive.unpackLimit` are
-       not set, the value of this variable is used instead.
-       The default value is 100.
-
 web.browser::
        Specify a web browser that may be used by some commands.
        Currently only linkgit:git-instaweb[1] and linkgit:git-help[1]
index 4b3c2b0b06e9821124759d0cc6240d0a1953d2fa..043274b1b71cb9fbced92fabca16acc4453f6458 100644 (file)
@@ -3,7 +3,7 @@ git-check-attr(1)
 
 NAME
 ----
-git-check-attr - Display gitattributes information.
+git-check-attr - Display gitattributes information
 
 
 SYNOPSIS
index 837fb08b7971a8b948dd7d039bab4a3c2e54cac7..b764130d26eb750d2b5173dcc98366828e413046 100644 (file)
@@ -55,13 +55,12 @@ OPTIONS
 
 -n::
 --no-commit::
-       Usually the command automatically creates a commit with
-       a commit log message stating which commit was
-       cherry-picked.  This flag applies the change necessary
-       to cherry-pick the named commit to your working tree
-       and the index, but does not make the commit.  In addition,
-       when this option is used, your index does not have to match
-       the HEAD commit.  The cherry-pick is done against the
+       Usually the command automatically creates a commit.
+       This flag applies the change necessary to cherry-pick
+       the named commit to your working tree and the index,
+       but does not make the commit.  In addition, when this
+       option is used, your index does not have to match the
+       HEAD commit.  The cherry-pick is done against the
        beginning state of your index.
 +
 This is useful when cherry-picking more than one commits'
index 79be4f1c0086fd1193734412019feeef8b07d669..77604d021603fa7002e416356ae197648093b69d 100644 (file)
@@ -92,7 +92,7 @@ OPTIONS
 
 -s::
 --signoff::
-       Add Signed-off-by line by the commiter at the end of the commit
+       Add Signed-off-by line by the committer at the end of the commit
        log message.
 
 -n::
index 82d03b4ced9cb7e34feca325d0ac7b41923de976..5d6d30f764a7bca813295461104c8f6f46ad0e35 100644 (file)
@@ -109,7 +109,7 @@ COMMANDS
 
 This works similarly to `svn update` or 'git-pull' except that
 it preserves linear history with 'git-rebase' instead of
-'git-merge' for ease of dcommiting with 'git-svn'.
+'git-merge' for ease of dcommitting with 'git-svn'.
 
 This accepts all options that 'git-svn fetch' and 'git-rebase'
 accept.  However, '--fetch-all' only fetches from the current
@@ -522,6 +522,8 @@ have each person clone that repository with 'git-clone':
        git remote add origin server:/pub/project
        git config --add remote.origin.fetch '+refs/remotes/*:refs/remotes/*'
        git fetch
+# Create a local branch from one of the branches just fetched
+       git checkout -b master FETCH_HEAD
 # Initialize git-svn locally (be sure to use the same URL and -T/-b/-t options as were used on server)
        git svn init http://svn.example.com/project
 # Pull the latest changes from Subversion
index a417e592ac6a7ed72186dcfc241592ccdc25c9d2..61fc5d7be8effd65f24fccbcc42f86e6dbea6742 100644 (file)
@@ -1690,8 +1690,10 @@ to follow, not easier.
 
 SEE ALSO
 --------
-linkgit:gittutorial[7], linkgit:gittutorial-2[7],
-linkgit:everyday[7], linkgit:gitcvs-migration[7],
+linkgit:gittutorial[7],
+linkgit:gittutorial-2[7],
+linkgit:gitcvs-migration[7],
+link:everyday.html[Everyday git],
 link:user-manual.html[The Git User's Manual]
 
 GIT
index 565719ed5f8516e17229ec11bbec5e1354580397..d77a45aed678522344d58498f1ee20ca14e0895e 100644 (file)
@@ -16,8 +16,10 @@ include::glossary-content.txt[]
 
 SEE ALSO
 --------
-linkgit:gittutorial[7], linkgit:gittutorial-2[7],
-linkgit:everyday[7], linkgit:gitcvs-migration[7],
+linkgit:gittutorial[7],
+linkgit:gittutorial-2[7],
+linkgit:gitcvs-migration[7],
+link:everyday.html[Everyday git],
 link:user-manual.html[The Git User's Manual]
 
 GIT
index 504ae8a53bca42d7c9ec560b65ddfe14699387a4..41ec7774f481fd2d70492be4ab2b5e0bf887fc0b 100644 (file)
@@ -68,13 +68,22 @@ This file should have the following format:
 ------------
 
 `<url>` is required; `#<head>` is optional.
-When you do not provide a refspec on the command line,
-git will use the following refspec, where `<head>` defaults to `master`,
-and `<repository>` is the name of this file
-you provided in the command line.
+
+Depending on the operation, git will use one of the following
+refspecs, if you don't provide one on the command line.
+`<branch>` is the name of this file in `$GIT_DIR/branches` and
+`<head>` defaults to `master`.
+
+git fetch uses:
+
+------------
+       refs/heads/<head>:refs/heads/<branch>
+------------
+
+git push uses:
 
 ------------
-       refs/heads/<head>:<repository>
+       HEAD:refs/heads/<head>
 ------------
 
 
index 08d1310bf5fc5590ada1ee5b2af77d361ff4d874..b6533fa206a37aaccbb9f78712839e31ac94856e 100644 (file)
@@ -536,7 +536,7 @@ $ git bisect skip
 -------------------------------------------------
 
 In this case, though, git may not eventually be able to tell the first
-bad one between some first skipped commits and a latter bad commit.
+bad one between some first skipped commits and a later bad commit.
 
 There are also ways to automate the bisecting process if you have a
 test script that can tell a good from a bad commit. See
@@ -4560,4 +4560,3 @@ Alternates, clone -reference, etc.
 More on recovery from repository corruption.  See:
        http://marc.theaimsgroup.com/?l=git&m=117263864820799&w=2
        http://marc.theaimsgroup.com/?l=git&m=117147855503798&w=2
-       http://marc.theaimsgroup.com/?l=git&m=117147855503798&w=2
index f9eb5528732ad3d45b5f685728b5f8943d435522..ebf508f2d7ccb5b3c32dd298dfbfcd243a006947 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes-1.6.0.4.txt
\ No newline at end of file
+Documentation/RelNotes-1.6.0.5.txt
\ No newline at end of file
index 05eee4ecc71d7a20d9faf59c849d3c693ae4cc8d..c107fd643a452edb016f7ad867d4b2a555d9abaf 100644 (file)
@@ -269,8 +269,7 @@ static int merge_working_tree(struct checkout_opts *opts,
                }
 
                /* 2-way merge to the new branch */
-               topts.initial_checkout = (!active_nr &&
-                                         (old->commit == new->commit));
+               topts.initial_checkout = is_cache_unborn();
                topts.update = 1;
                topts.merge = 1;
                topts.gently = opts->merge;
@@ -422,7 +421,7 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
        if (!opts->quiet && !old.path && old.commit && new->commit != old.commit)
                describe_detached_head("Previous HEAD position was", old.commit);
 
-       if (!old.commit) {
+       if (!old.commit && !opts->force) {
                if (!opts->quiet) {
                        fprintf(stderr, "warning: You appear to be on a branch yet to be born.\n");
                        fprintf(stderr, "warning: Forcing checkout of %s.\n", new->name);
index d5fe775fc135c0905cabec6731104009ca3bfef3..26cf6785918300f3a0998a1811adb71ec6ec7b73 100644 (file)
@@ -290,6 +290,9 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
        /* Otherwise, we are doing the usual "git" diff */
        rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index;
 
+       /* Default to let external be used */
+       DIFF_OPT_SET(&rev.diffopt, ALLOW_EXTERNAL);
+
        if (nongit)
                die("Not a git repository");
        argc = setup_revisions(argc, argv, &rev, NULL);
@@ -298,7 +301,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
                if (diff_setup_done(&rev.diffopt) < 0)
                        die("diff_setup_done failed");
        }
-       DIFF_OPT_SET(&rev.diffopt, ALLOW_EXTERNAL);
+
        DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
 
        /*
index 7c93eb878d7da87b39959fb9599e4b7b6b81570b..7d5d57ad7568b8c0bf7396cdbd581c67ab4600e2 100644 (file)
@@ -354,7 +354,7 @@ static void get_tags_and_duplicates(struct object_array *pending,
                case OBJ_TAG:
                        tag = (struct tag *)e->item;
                        while (tag && tag->object.type == OBJ_TAG) {
-                               string_list_insert(full_name, extra_refs)->util = tag;
+                               string_list_append(full_name, extra_refs)->util = tag;
                                tag = (struct tag *)tag->tagged;
                        }
                        if (!tag)
@@ -374,7 +374,7 @@ static void get_tags_and_duplicates(struct object_array *pending,
                }
                if (commit->util)
                        /* more than one name for the same object */
-                       string_list_insert(full_name, extra_refs)->util = commit;
+                       string_list_append(full_name, extra_refs)->util = commit;
                else
                        commit->util = full_name;
        }
index b48327db950e5d8a54045f4956fa92b7879227bc..f72eb854756f602e4d114964f4585bc5a8c55e20 100644 (file)
@@ -227,6 +227,8 @@ static void show_files(struct dir_struct *dir, const char *prefix)
                        int dtype = ce_to_dtype(ce);
                        if (excluded(dir, ce->name, &dtype) != dir->show_ignored)
                                continue;
+                       if (ce->ce_flags & CE_UPDATE)
+                               continue;
                        err = lstat(ce->name, &st);
                        if (show_deleted && err)
                                show_ce_entry(tag_removed, ce);
@@ -329,7 +331,7 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)
        if (prefix) {
                static const char *(matchbuf[2]);
                matchbuf[0] = prefix;
-               matchbuf [1] = NULL;
+               matchbuf[1] = NULL;
                match = matchbuf;
        } else
                match = NULL;
index 85bd795d3b811aaba42aa1165c30137b8a6105e8..4411a480c1067f6841181e838ffba54edbec823f 100644 (file)
@@ -246,8 +246,16 @@ static unsigned long write_object(struct sha1file *f,
        type = entry->type;
 
        /* write limit if limited packsize and not first object */
-       limit = pack_size_limit && nr_written ?
-                       pack_size_limit - write_offset : 0;
+       if (!pack_size_limit || !nr_written)
+               limit = 0;
+       else if (pack_size_limit <= write_offset)
+               /*
+                * the earlier object did not fit the limit; avoid
+                * mistaking this with unlimited (i.e. limit = 0).
+                */
+               limit = 1;
+       else
+               limit = pack_size_limit - write_offset;
 
        if (!entry->delta)
                usable_delta = 0;       /* no delta */
index 0706c958181c54aeb18d91f6e3dbe7c9f572b94d..38fef34d3fb6c24ab89043951f1ecf6c96e9bf51 100644 (file)
@@ -206,7 +206,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
                        break;
                case 2:
                        opts.fn = twoway_merge;
-                       opts.initial_checkout = !active_nr;
+                       opts.initial_checkout = is_cache_unborn();
                        break;
                case 3:
                default:
index 843e9ac056c88bb2c9a8c6ded464096a99f13aff..11b91b3c3b2289d396c72067f7b3ded2ec6a0b64 100644 (file)
@@ -344,7 +344,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
        const char *object_ref, *tag;
        struct ref_lock *lock;
 
-       int annotate = 0, sign = 0, force = 0, lines = 0,
+       int annotate = 0, sign = 0, force = 0, lines = -1,
                list = 0, delete = 0, verify = 0;
        const char *msgfile = NULL, *keyid = NULL;
        struct msg_arg msg = { 0, STRBUF_INIT };
@@ -380,9 +380,19 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
        }
        if (sign)
                annotate = 1;
+       if (argc == 0 && !(delete || verify))
+               list = 1;
 
+       if ((annotate || msg.given || msgfile || force) &&
+           (list || delete || verify))
+               usage_with_options(git_tag_usage, options);
+
+       if (list + delete + verify > 1)
+               usage_with_options(git_tag_usage, options);
        if (list)
-               return list_tags(argv[0], lines);
+               return list_tags(argv[0], lines == -1 ? 0 : lines);
+       if (lines != -1)
+               die("-n option is only allowed with -l.");
        if (delete)
                return for_each_tag_name(argv, delete_tag);
        if (verify)
@@ -407,11 +417,6 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                }
        }
 
-       if (argc == 0) {
-               if (annotate)
-                       usage_with_options(git_tag_usage, options);
-               return list_tags(NULL, lines);
-       }
        tag = argv[0];
 
        object_ref = argc == 2 ? argv[1] : "HEAD";
diff --git a/cache.h b/cache.h
index 7595c149ea10aa847f01235a2c1ca17129d43fe4..d1cd6aaf738f94930b94ebbee303fc267064e2ac 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -255,6 +255,7 @@ static inline void remove_name_hash(struct cache_entry *ce)
 
 #define read_cache() read_index(&the_index)
 #define read_cache_from(path) read_index_from(&the_index, (path))
+#define is_cache_unborn() is_index_unborn(&the_index)
 #define read_cache_unmerged() read_index_unmerged(&the_index)
 #define write_cache(newfd, cache, entries) write_index(&the_index, (newfd))
 #define discard_cache() discard_index(&the_index)
@@ -360,6 +361,7 @@ extern int init_db(const char *template_dir, unsigned int flags);
 /* Initialize and use the cache information */
 extern int read_index(struct index_state *);
 extern int read_index_from(struct index_state *, const char *path);
+extern int is_index_unborn(struct index_state *);
 extern int read_index_unmerged(struct index_state *);
 extern int write_index(const struct index_state *, int newfd);
 extern int discard_index(struct index_state *);
index 772cad510d5d260fdf33b4f7d6ff79f9f3367b05..45733f9e04eb87409a896898cb5a92b37e87a920 100644 (file)
@@ -865,6 +865,8 @@ int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz)
 #undef rename
 int mingw_rename(const char *pold, const char *pnew)
 {
+       DWORD attrs;
+
        /*
         * Try native rename() first to get errno right.
         * It is based on MoveFile(), which cannot overwrite existing files.
@@ -876,12 +878,19 @@ int mingw_rename(const char *pold, const char *pnew)
        if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
                return 0;
        /* TODO: translate more errors */
-       if (GetLastError() == ERROR_ACCESS_DENIED) {
-               DWORD attrs = GetFileAttributes(pnew);
-               if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) {
+       if (GetLastError() == ERROR_ACCESS_DENIED &&
+           (attrs = GetFileAttributes(pnew)) != INVALID_FILE_ATTRIBUTES) {
+               if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
                        errno = EISDIR;
                        return -1;
                }
+               if ((attrs & FILE_ATTRIBUTE_READONLY) &&
+                   SetFileAttributes(pnew, attrs & ~FILE_ATTRIBUTE_READONLY)) {
+                       if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
+                               return 0;
+                       /* revert file attributes on failure */
+                       SetFileAttributes(pnew, attrs);
+               }
        }
        errno = EACCES;
        return -1;
index 39a1ce5a3979e6160b8450a0d9dd08ec6b6cd7a2..554a03ff4fbc61e8b02b6010c9ffb9fad632f195 100755 (executable)
@@ -650,21 +650,12 @@ _git_branch ()
 
 _git_bundle ()
 {
-       local mycword="$COMP_CWORD"
-       case "${COMP_WORDS[0]}" in
-       git)
-               local cmd="${COMP_WORDS[2]}"
-               mycword="$((mycword-1))"
-               ;;
-       git-bundle*)
-               local cmd="${COMP_WORDS[1]}"
-               ;;
-       esac
-       case "$mycword" in
-       1)
+       local cmd="${COMP_WORDS[2]}"
+       case "$COMP_CWORD" in
+       2)
                __gitcomp "create list-heads verify unbundle"
                ;;
-       2)
+       3)
                # looking for a file
                ;;
        *)
@@ -812,12 +803,7 @@ _git_fetch ()
                        __gitcomp "$(__git_refs)" "$pfx" "${cur#*:}"
                        ;;
                *)
-                       local remote
-                       case "${COMP_WORDS[0]}" in
-                       git-fetch) remote="${COMP_WORDS[1]}" ;;
-                       git)       remote="${COMP_WORDS[2]}" ;;
-                       esac
-                       __gitcomp "$(__git_refs2 "$remote")"
+                       __gitcomp "$(__git_refs2 "${COMP_WORDS[2]}")"
                        ;;
                esac
        fi
@@ -1060,12 +1046,7 @@ _git_pull ()
        if [ "$COMP_CWORD" = 2 ]; then
                __gitcomp "$(__git_remotes)"
        else
-               local remote
-               case "${COMP_WORDS[0]}" in
-               git-pull)  remote="${COMP_WORDS[1]}" ;;
-               git)       remote="${COMP_WORDS[2]}" ;;
-               esac
-               __gitcomp "$(__git_refs "$remote")"
+               __gitcomp "$(__git_refs "${COMP_WORDS[2]}")"
        fi
 }
 
@@ -1078,19 +1059,13 @@ _git_push ()
        else
                case "$cur" in
                *:*)
-                       local remote
-                       case "${COMP_WORDS[0]}" in
-                       git-push)  remote="${COMP_WORDS[1]}" ;;
-                       git)       remote="${COMP_WORDS[2]}" ;;
-                       esac
-
                        local pfx=""
                        case "$COMP_WORDBREAKS" in
                        *:*) : great ;;
                        *)   pfx="${cur%%:*}:" ;;
                        esac
 
-                       __gitcomp "$(__git_refs "$remote")" "$pfx" "${cur#*:}"
+                       __gitcomp "$(__git_refs "${COMP_WORDS[2]}")" "$pfx" "${cur#*:}"
                        ;;
                +*)
                        __gitcomp "$(__git_refs)" + "${cur#+}"
@@ -1369,7 +1344,7 @@ _git_revert ()
                return
                ;;
        esac
-       COMPREPLY=()
+       __gitcomp "$(__git_refs)"
 }
 
 _git_rm ()
@@ -1591,7 +1566,7 @@ _git_tag ()
        -m|-F)
                COMPREPLY=()
                ;;
-       -*|tag|git-tag)
+       -*|tag)
                if [ $f = 1 ]; then
                        __gitcomp "$(__git_tags)"
                else
index 46136d49bf99f61a5c85a548bec055742ed140f8..2b122d3f5159d9a8206e16be9db7aca7dfe89bb6 100755 (executable)
@@ -963,7 +963,7 @@ class P4Sync(Command):
             if stat['type'] in ('text+ko', 'unicode+ko', 'binary+ko'):
                 text = re.sub(r'(?i)\$(Id|Header):[^$]*\$',r'$\1$', text)
             elif stat['type'] in ('text+k', 'ktext', 'kxtext', 'unicode+k', 'binary+k'):
-                text = re.sub(r'\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$]*\$',r'$\1$', text)
+                text = re.sub(r'\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$\n]*\$',r'$\1$', text)
 
             contents[stat['depotFile']] = text
 
diff --git a/date.c b/date.c
index 35a52576c53e5e1406d40ed4402b8834a29b9f0e..950b88fdcf74f550a582684f1702ffb58c62c7f9 100644 (file)
--- a/date.c
+++ b/date.c
@@ -402,6 +402,15 @@ static int match_multi_number(unsigned long num, char c, const char *date, char
        return end - date;
 }
 
+/* Have we filled in any part of the time/date yet? */
+static inline int nodate(struct tm *tm)
+{
+       return tm->tm_year < 0 &&
+               tm->tm_mon < 0 &&
+               tm->tm_mday < 0 &&
+               !(tm->tm_hour | tm->tm_min | tm->tm_sec);
+}
+
 /*
  * We've seen a digit. Time? Year? Date?
  */
@@ -418,7 +427,7 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt
         * more than 8 digits. This is because we don't want to rule out
         * numbers like 20070606 as a YYYYMMDD date.
         */
-       if (num >= 100000000) {
+       if (num >= 100000000 && nodate(tm)) {
                time_t time = num;
                if (gmtime_r(&time, tm)) {
                        *tm_gmt = 1;
@@ -462,6 +471,13 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt
                return n;
        }
 
+       /*
+        * Ignore lots of numerals. We took care of 4-digit years above.
+        * Days or months must be one or two digits.
+        */
+       if (n > 2)
+               return n;
+
        /*
         * NOTE! We will give precedence to day-of-month over month or
         * year numbers in the 1-12 range. So 05 is always "mday 5",
@@ -488,10 +504,6 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt
 
        if (num > 0 && num < 32) {
                tm->tm_mday = num;
-       } else if (num > 1900) {
-               tm->tm_year = num - 1900;
-       } else if (num > 70) {
-               tm->tm_year = num;
        } else if (num > 0 && num < 13) {
                tm->tm_mon = num-1;
        }
@@ -823,7 +835,9 @@ static const char *approxidate_digit(const char *date, struct tm *tm, int *num)
                }
        }
 
-       *num = number;
+       /* Accept zero-padding only for small numbers ("Dec 02", never "Dec 0002") */
+       if (date[0] != '0' || end - date <= 2)
+               *num = number;
        return end;
 }
 
index a2913c2a2cd1ec158157ada3e2deb666892b734b..75c68d948fd3105272f893ff2f901007519f62f5 100755 (executable)
@@ -14,7 +14,7 @@ sort |
 while read cmd
 do
      sed -n '
-     /NAME/,/git-'"$cmd"'/H
+     /^NAME/,/git-'"$cmd"'/H
      ${
             x
             s/.*git-'"$cmd"' - \(.*\)/  {"'"$cmd"'", "\1"},/
index 073a314c8043e0ff30afde65e012e356ff0d186f..a2cf5b82150a77fd9ddb775fea1bc8d5e8ee7392 100755 (executable)
@@ -4,9 +4,9 @@
 # This file is licensed under the GPL v2, or a later version
 # at the discretion of Linus Torvalds.
 
-USAGE='<commit> <url> [<head>]'
-LONG_USAGE='Summarizes the changes since <commit> to the standard output,
-and includes <url> in the message generated.'
+USAGE='<start> <url> [<end>]'
+LONG_USAGE='Summarizes the changes between two commits to the standard output,
+and includes the given URL in the generated summary.'
 SUBDIRECTORY_OK='Yes'
 OPTIONS_SPEC=
 . git-sh-setup
index 967f483f783693eff4fd4e252dae7a0cc8b12ada..525d138e90c524d08ef3d9755f1a2486c34adc39 100644 (file)
@@ -1239,6 +1239,11 @@ int read_index_from(struct index_state *istate, const char *path)
        die("index file corrupt");
 }
 
+int is_index_unborn(struct index_state *istate)
+{
+       return (!istate->cache_nr && !istate->alloc && !istate->timestamp);
+}
+
 int discard_index(struct index_state *istate)
 {
        istate->cache_nr = 0;
index 7688f3b04d197007bce64a2bcc54c0b62c0b5922..91f1b7cd81f5461b13c2553bf3dd3e4b5c76ab14 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -298,6 +298,17 @@ static void read_branches_file(struct remote *remote)
        }
        add_url_alias(remote, p);
        add_fetch_refspec(remote, strbuf_detach(&branch, 0));
+       /*
+        * Cogito compatible push: push current HEAD to remote #branch
+        * (master if missing)
+        */
+       strbuf_init(&branch, 0);
+       strbuf_addstr(&branch, "HEAD");
+       if (frag)
+               strbuf_addf(&branch, ":refs/heads/%s", frag);
+       else
+               strbuf_addstr(&branch, ":refs/heads/master");
+       add_push_refspec(remote, strbuf_detach(&branch, 0));
        remote->fetch_tags = 1; /* always auto-follow */
 }
 
index 270294af8321c0b81f720db0f36e8f7f9eddbc88..45fd7a366055d254529c53b21a06c6340427fa49 100644 (file)
@@ -968,7 +968,7 @@ static void add_ignore_packed(struct rev_info *revs, const char *name)
        int num = ++revs->num_ignore_packed;
 
        revs->ignore_packed = xrealloc(revs->ignore_packed,
-                                      sizeof(const char **) * (num + 1));
+                                      sizeof(const char *) * (num + 1));
        revs->ignore_packed[num-1] = name;
        revs->ignore_packed[num] = NULL;
 }
index 0203de5855cde2de6268ffb0ec90985490080ece..c35469d488596bd1279c06bc391d744565f35e59 100644 (file)
@@ -2232,7 +2232,7 @@ static int create_tmpfile(char *buffer, size_t bufsiz, const char *filename)
        memcpy(buffer, filename, dirlen);
        strcpy(buffer + dirlen, "tmp_obj_XXXXXX");
        fd = mkstemp(buffer);
-       if (fd < 0 && dirlen) {
+       if (fd < 0 && dirlen && errno == ENOENT) {
                /* Make sure the directory exists */
                memcpy(buffer, filename, dirlen);
                buffer[dirlen-1] = 0;
@@ -2258,7 +2258,7 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
        filename = sha1_file_name(sha1);
        fd = create_tmpfile(tmpfile, sizeof(tmpfile), filename);
        if (fd < 0) {
-               if (errno == EPERM)
+               if (errno == EACCES)
                        return error("insufficient permission for adding an object to repository database %s\n", get_object_directory());
                else
                        return error("unable to create temporary sha1 filename %s: %s\n", tmpfile, strerror(errno));
index 637b4e19d52e81cf1472a4ed9dcfb0c9ff00da2b..22ef7d44b08ac7ec20e799a194e27205c794c290 100755 (executable)
@@ -43,6 +43,13 @@ test_expect_success 'GIT_EXTERNAL_DIFF environment should apply only to diff' '
 
 '
 
+test_expect_success 'GIT_EXTERNAL_DIFF environment and --no-ext-diff' '
+
+       GIT_EXTERNAL_DIFF=echo git diff --no-ext-diff |
+       grep "^diff --git a/file b/file"
+
+'
+
 test_expect_success 'diff attribute' '
 
        git config diff.parrot.command echo &&
@@ -68,6 +75,13 @@ test_expect_success 'diff attribute should apply only to diff' '
 
 '
 
+test_expect_success 'diff attribute and --no-ext-diff' '
+
+       git diff --no-ext-diff |
+       grep "^diff --git a/file b/file"
+
+'
+
 test_expect_success 'diff attribute' '
 
        git config --unset diff.parrot.command &&
@@ -94,6 +108,13 @@ test_expect_success 'diff attribute should apply only to diff' '
 
 '
 
+test_expect_success 'diff attribute and --no-ext-diff' '
+
+       git diff --no-ext-diff |
+       grep "^diff --git a/file b/file"
+
+'
+
 test_expect_success 'no diff with -diff' '
        echo >.gitattributes "file -diff" &&
        git diff | grep Binary
index 3a0ef8759c9d7a55b95c56ca38cd3c37ac2432fa..2852a0326546f50f0cbefb4d5621c889b52f33c9 100755 (executable)
@@ -375,4 +375,10 @@ test_expect_success 'index-pack with --strict' '
        )
 '
 
+test_expect_success 'tolerate absurdly small packsizelimit' '
+       git config pack.packSizeLimit 2 &&
+       packname_9=$(git pack-objects test-9 <obj-list) &&
+       test $(wc -l <obj-list) = $(ls test-9-*.pack | wc -l)
+'
+
 test_done
index 598664ce7fa1747436c0a66d13e464398cac5674..f9e878022a93657a8b8d81339670f4d910392755 100755 (executable)
@@ -494,4 +494,54 @@ test_expect_success 'allow deleting an invalid remote ref' '
 
 '
 
+test_expect_success 'fetch with branches' '
+       mk_empty &&
+       git branch second $the_first_commit &&
+       git checkout second &&
+       echo ".." > testrepo/.git/branches/branch1 &&
+       (cd testrepo &&
+               git fetch branch1 &&
+               r=$(git show-ref -s --verify refs/heads/branch1) &&
+               test "z$r" = "z$the_commit" &&
+               test 1 = $(git for-each-ref refs/heads | wc -l)
+       ) &&
+       git checkout master
+'
+
+test_expect_success 'fetch with branches containing #' '
+       mk_empty &&
+       echo "..#second" > testrepo/.git/branches/branch2 &&
+       (cd testrepo &&
+               git fetch branch2 &&
+               r=$(git show-ref -s --verify refs/heads/branch2) &&
+               test "z$r" = "z$the_first_commit" &&
+               test 1 = $(git for-each-ref refs/heads | wc -l)
+       ) &&
+       git checkout master
+'
+
+test_expect_success 'push with branches' '
+       mk_empty &&
+       git checkout second &&
+       echo "testrepo" > .git/branches/branch1 &&
+       git push branch1 &&
+       (cd testrepo &&
+               r=$(git show-ref -s --verify refs/heads/master) &&
+               test "z$r" = "z$the_first_commit" &&
+               test 1 = $(git for-each-ref refs/heads | wc -l)
+       )
+'
+
+test_expect_success 'push with branches containing #' '
+       mk_empty &&
+       echo "testrepo#branch3" > .git/branches/branch2 &&
+       git push branch2 &&
+       (cd testrepo &&
+               r=$(git show-ref -s --verify refs/heads/branch3) &&
+               test "z$r" = "z$the_first_commit" &&
+               test 1 = $(git for-each-ref refs/heads | wc -l)
+       ) &&
+       git checkout master
+'
+
 test_done
index 33cde705953acc9a30d8535da77fe0f90e2b3118..c616deb0d0315acc41da93a81145494bc9f455c1 100755 (executable)
@@ -1090,4 +1090,15 @@ test_expect_success 'filename for the message is relative to cwd' '
        git cat-file tag tag-from-subdir-2 | grep "in sub directory"
 '
 
+# mixing modes and options:
+
+test_expect_success 'mixing incompatibles modes and options is forbidden' '
+       test_must_fail git tag -a
+       test_must_fail git tag -l -v
+       test_must_fail git tag -n 100
+       test_must_fail git tag -l -m msg
+       test_must_fail git tag -l -F some file
+       test_must_fail git tag -v -s
+'
+
 test_done
index c19b4a2bab586b21da43c7a838ba85626f913568..638c858dc7b640fdff4af5902ed79c95e9d9d040 100755 (executable)
@@ -231,4 +231,12 @@ test_expect_success 'fast-export -C -C | fast-import' '
 
 '
 
+test_expect_success 'fast-export | fast-import when master is tagged' '
+
+       git tag -m msg last &&
+       git fast-export -C -C --signed-tags=strip --all > output &&
+       test $(grep -c "^tag " output) = 3
+
+'
+
 test_done