Merge branch 'st/maint-tag' into maint
authorJunio C Hamano <gitster@pobox.com>
Mon, 1 Dec 2008 02:18:50 +0000 (18:18 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 1 Dec 2008 02:18:50 +0000 (18:18 -0800)
* st/maint-tag:
tag: Add more tests about mixing incompatible modes and options
tag: Check that options are only allowed in the appropriate mode

66 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-bisect.txt
Documentation/git-check-attr.txt
Documentation/git-cherry-pick.txt
Documentation/git-commit.txt
Documentation/git-format-patch.txt
Documentation/git-svn.txt
Documentation/gitcore-tutorial.txt
Documentation/gitglossary.txt
Documentation/rev-list-options.txt
Documentation/urls-remotes.txt
Documentation/user-manual.txt
Makefile
RelNotes
builtin-apply.c
builtin-branch.c
builtin-checkout.c
builtin-config.c
builtin-diff.c
builtin-fast-export.c
builtin-ls-files.c
builtin-ls-remote.c
builtin-pack-objects.c
builtin-read-tree.c
builtin-reflog.c
builtin-remote.c
builtin-reset.c
builtin-revert.c
builtin-send-pack.c
builtin-tag.c
builtin-update-ref.c
bundle.c
cache.h
config.c
contrib/completion/git-completion.bash
contrib/fast-import/git-p4
date.c
environment.c
fsck.c
generate-cmdlist.sh
git-request-pull.sh
git-submodule.sh
git.spec.in
grep.c
path.c
perl/Git.pm
read-cache.c
receive-pack.c
refs.c
remote.c
rerere.c
revision.c
server-info.c
sha1_file.c
sha1_name.c
t/t1400-update-ref.sh
t/t2011-checkout-invalid-head.sh [new file with mode: 0755]
t/t3200-branch.sh
t/t3210-pack-refs.sh
t/t4020-diff-external.sh
t/t5300-pack-object.sh
t/t5516-fetch-push.sh
t/t9301-fast-export.sh
unpack-trees.c
index db1002e8c70693e34aaa0e7976218af81a335d3b..d522661d315c3aab445bf3aa123bbd0abd9db251 100644 (file)
@@ -16,6 +16,9 @@ Fixes since v1.6.0.3
 * 'git push --mirror' tried and failed to push the stash; there is no
   point in sending it to begin with.
 
+* 'git push' did not update the remote tracking reference if the corresponding
+  ref on the remote end happened to be already up to date.
+
 * 'git pull $there $branch:$current_branch' did not work when you were on
   a branch yet to be born.
 
@@ -27,14 +30,10 @@ 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.
 
 * Plugged small memleaks here and there.
 
 * Also contains many documentation updates.
-
---
-exec >/var/tmp/1
-O=v1.6.0.3-34-gf6276b7
-echo O=$(git describe maint)
-git shortlog --no-merges $O..maint
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..62f95e6
--- /dev/null
@@ -0,0 +1,21 @@
+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 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.
+
+* '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.
+
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 c7981efcd9b86287bbea9ddcaf187a9bd48c77eb..39034ec7d6dff42f4be282c4216a7e13ff255d91 100644 (file)
@@ -26,7 +26,7 @@ on the subcommand:
  git bisect log
  git bisect run <cmd>...
 
-This command uses 'git-rev-list --bisect' to help drive the
+This command uses 'git rev-list --bisect' to help drive the
 binary search process to find which change introduced a bug, given an
 old "good" commit object name and a later "bad" commit object name.
 
@@ -101,7 +101,7 @@ $ git bisect visualize
 to see the currently remaining suspects in 'gitk'.  `visualize` is a bit
 too long to type and `view` is provided as a synonym.
 
-If 'DISPLAY' environment variable is not set, 'git-log' is used
+If 'DISPLAY' environment variable is not set, 'git log' is used
 instead.  You can even give command line options such as `-p` and
 `--stat`.
 
@@ -215,7 +215,7 @@ tweaks (e.g., s/#define DEBUG 0/#define DEBUG 1/ in a header file, or
 work around other problem this bisection is not interested in")
 applied to the revision being tested.
 
-To cope with such a situation, after the inner 'git-bisect' finds the
+To cope with such a situation, after the inner 'git bisect' finds the
 next revision to test, with the "run" script, you can apply that tweak
 before compiling, run the real test, and after the test decides if the
 revision (possibly with the needed tweaks) passed the test, rewind the
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 adb4ea7b1b6c70fb6fc2486487ef34ed280ec015..7426109f6251b7e4b3b37e0b785157c0d46ee9f7 100644 (file)
@@ -46,7 +46,8 @@ applies to that command line and you do not get "everything
 since the beginning of the time".  If you want to format
 everything since project inception to one commit, say "git
 format-patch \--root <commit>" to make it clear that it is the
-latter case.
+latter case.  If you want to format a single commit, you can do
+this with "git format-patch -1 <commit>".
 
 By default, each output file is numbered sequentially from 1, and uses the
 first line of the commit message (massaged for pathname safety) as
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 5df35ce519e27e3fa20a0f3732ac4ddb58d9ab69..1023ac2b59c139cad2d9634a7a88b812d7761102 100644 (file)
@@ -285,7 +285,7 @@ See also linkgit:git-reflog[1].
 History Simplification
 ~~~~~~~~~~~~~~~~~~~~~~
 
-When optional paths are given, 'git-rev-list' simplifies commits with
+When optional paths are given, 'git rev-list' simplifies commits with
 various strategies, according to the options you have selected.
 
 Suppose you specified `foo` as the <paths>.  We shall call commits
@@ -424,14 +424,14 @@ Limit output to the one commit object which is roughly halfway between
 the included and excluded commits. Thus, if
 
 -----------------------------------------------------------------------
-       $ git-rev-list --bisect foo ^bar ^baz
+       $ git rev-list --bisect foo ^bar ^baz
 -----------------------------------------------------------------------
 
 outputs 'midpoint', the output of the two commands
 
 -----------------------------------------------------------------------
-       $ git-rev-list foo ^midpoint
-       $ git-rev-list midpoint ^bar ^baz
+       $ git rev-list foo ^midpoint
+       $ git rev-list midpoint ^bar ^baz
 -----------------------------------------------------------------------
 
 would be of roughly the same length.  Finding the change which
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..39c0167e1ec5755a9c9aa9ceb71f60f1fee9644a 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
index becd008e04c265f7a822eeb74cfe218491710c7e..186a8efd1b74a0510e67e75a6191206a1a6818c2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1329,7 +1329,16 @@ check-sha1:: test-sha1$X
        ./test-sha1.sh
 
 check: common-cmds.h
-       for i in *.c; do sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; done
+       if sparse; \
+       then \
+               for i in *.c; \
+               do \
+                       sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; \
+               done; \
+       else \
+               echo 2>&1 "Did you mean 'make test'?"; \
+               exit 1; \
+       fi
 
 remove-dashes:
        ./fixup-builtins $(BUILT_INS) $(PROGRAMS) $(SCRIPTS)
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 e9d49f133afd559d2df3f09997c08a61dfc2ff86..50b623e54c003fb5bbe183568d13f496c3c41c25 100644 (file)
@@ -2850,8 +2850,8 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned
                unsigned int nr = getpid();
 
                for (;;) {
-                       const char *newpath;
-                       newpath = mkpath("%s~%u", path, nr);
+                       char newpath[PATH_MAX];
+                       mksnpath(newpath, sizeof(newpath), "%s~%u", path, nr);
                        if (!try_create_file(newpath, mode, buf, size)) {
                                if (!rename(newpath, path))
                                        return;
index b1a2ad7a6b3b150cda8d031a87352a4daedc40ea..4b4abfd3639d2c6a1405e2e056ed5362b4b73abb 100644 (file)
@@ -160,7 +160,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)
                        continue;
                }
 
-               if (delete_ref(name, sha1)) {
+               if (delete_ref(name, sha1, 0)) {
                        error("Error deleting %sbranch '%s'", remote,
                               argv[i]);
                        ret = 1;
index 1deda927cdfcbcdcb751aca3338ac77ef0aad836..c107fd643a452edb016f7ad867d4b2a555d9abaf 100644 (file)
@@ -32,7 +32,7 @@ static int post_checkout_hook(struct commit *old, struct commit *new,
 
        memset(&proc, 0, sizeof(proc));
        argv[0] = name;
-       argv[1] = xstrdup(sha1_to_hex(old->object.sha1));
+       argv[1] = xstrdup(sha1_to_hex(old ? old->object.sha1 : null_sha1));
        argv[2] = xstrdup(sha1_to_hex(new->object.sha1));
        argv[3] = changed ? "1" : "0";
        argv[4] = NULL;
@@ -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;
@@ -360,10 +359,10 @@ static void update_refs_for_switch(struct checkout_opts *opts,
 
        strbuf_init(&msg, 0);
        old_desc = old->name;
-       if (!old_desc)
+       if (!old_desc && old->commit)
                old_desc = sha1_to_hex(old->commit->object.sha1);
        strbuf_addf(&msg, "checkout: moving from %s to %s",
-                   old_desc, new->name);
+                   old_desc ? old_desc : "(invalid)", new->name);
 
        if (new->path) {
                create_symref("HEAD", new->path, msg.buf);
@@ -419,10 +418,10 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
         * a new commit, we want to mention the old commit once more
         * to remind the user that it might be lost.
         */
-       if (!opts->quiet && !old.path && new->commit != old.commit)
+       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 91fdc4985d8e64fae12209174dd4aa2d887793e5..f71016204b540d0d935323c909a0ffccb1abdbe2 100644 (file)
@@ -84,7 +84,7 @@ static int get_value(const char* key_, const char* regex_)
        local = config_exclusive_filename;
        if (!local) {
                const char *home = getenv("HOME");
-               local = repo_config = xstrdup(git_path("config"));
+               local = repo_config = git_pathdup("config");
                if (git_config_global() && home)
                        global = xstrdup(mkpath("%s/.gitconfig", home));
                if (git_config_system())
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 c21b841e7c5e8d27a6e66e7f70786d77aa4653b5..78a88f74769645f0be86aa77d3dee3f5e99c916f 100644 (file)
@@ -4,7 +4,7 @@
 #include "remote.h"
 
 static const char ls_remote_usage[] =
-"git ls-remote [--upload-pack=<git-upload-pack>] [<host>:]<directory>";
+"git ls-remote [--heads] [--tags]  [-u <exec> | --upload-pack <exec>] <repository> <refs>...";
 
 /*
  * Is there one among the list of patterns that match the tail part
index b0dddbee4f93de462090218554e1b1b6d1038c34..8fe51244e069da96b669c260a37f4b7cf831026f 100644 (file)
@@ -245,8 +245,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 196fa03b7fac795475a0e12f0fa3b443cb34bd1d..da96da317be01c24ae9711206976f48f33e39f97 100644 (file)
@@ -277,11 +277,11 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
        lock = lock_any_ref_for_update(ref, sha1, 0);
        if (!lock)
                return error("cannot lock ref '%s'", ref);
-       log_file = xstrdup(git_path("logs/%s", ref));
+       log_file = git_pathdup("logs/%s", ref);
        if (!file_exists(log_file))
                goto finish;
        if (!cmd->dry_run) {
-               newlog_path = xstrdup(git_path("logs/%s.lock", ref));
+               newlog_path = git_pathdup("logs/%s.lock", ref);
                cb.newlog = fopen(newlog_path, "w");
        }
 
index 90a4e35828697f349a38ba3486c40813db32cee0..5af4e643eb9dceccc62a5ce44069e0164bc12311 100644 (file)
@@ -323,7 +323,7 @@ static int add_branch_for_removal(const char *refname,
 
        /* make sure that symrefs are deleted */
        if (flags & REF_ISSYMREF)
-               return unlink(git_path(refname));
+               return unlink(git_path("%s", refname));
 
        item = string_list_append(refname, branches->branches);
        item->util = xmalloc(20);
@@ -340,7 +340,7 @@ static int remove_branches(struct string_list *branches)
                const char *refname = item->string;
                unsigned char *sha1 = item->util;
 
-               if (delete_ref(refname, sha1))
+               if (delete_ref(refname, sha1, 0))
                        result |= error("Could not remove branch %s", refname);
        }
        return result;
@@ -570,7 +570,7 @@ static int prune(int argc, const char **argv)
                        const char *refname = states.stale.items[i].util;
 
                        if (!dry_run)
-                               result |= delete_ref(refname, NULL);
+                               result |= delete_ref(refname, NULL, 0);
 
                        printf(" * [%s] %s\n", dry_run ? "would prune" : "pruned",
                               abbrev_ref(refname, "refs/remotes/"));
index 16e6bb20f1af6a7a684a747b3c0cc26ceabe8ce7..9514b77f8c0b4e8a576e888df905b501e198df24 100644 (file)
@@ -279,7 +279,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
                update_ref(msg, "ORIG_HEAD", orig, old_orig, 0, MSG_ON_ERR);
        }
        else if (old_orig)
-               delete_ref("ORIG_HEAD", old_orig);
+               delete_ref("ORIG_HEAD", old_orig, 0);
        prepend_reflog_action("updating HEAD", msg, sizeof(msg));
        update_ref_status = update_ref(msg, "HEAD", sha1, orig, 0, MSG_ON_ERR);
 
index 786a956f26486856c97e15ce8ab464dfb25dcbc5..74845ef8e6f9c635bbafbf5dfea5e73cf6e11aa0 100644 (file)
@@ -269,7 +269,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)
        int i;
        char *oneline, *reencoded_message = NULL;
        const char *message, *encoding;
-       char *defmsg = xstrdup(git_path("MERGE_MSG"));
+       char *defmsg = git_pathdup("MERGE_MSG");
 
        git_config(git_default_config, NULL);
        me = action == REVERT ? "revert" : "cherry-pick";
index 301f23043262059dcb28994527334ba1909671f0..e428eace2b2213750d4dfa0fe4da9c07bd656892 100644 (file)
@@ -222,7 +222,7 @@ static void update_tracking_ref(struct remote *remote, struct ref *ref)
 {
        struct refspec rs;
 
-       if (ref->status != REF_STATUS_OK)
+       if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
                return;
 
        rs.src = ref->name;
@@ -232,7 +232,7 @@ static void update_tracking_ref(struct remote *remote, struct ref *ref)
                if (args.verbose)
                        fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
                if (ref->deletion) {
-                       delete_ref(rs.dst, NULL);
+                       delete_ref(rs.dst, NULL, 0);
                } else
                        update_ref("update by push", rs.dst,
                                        ref->new_sha1, NULL, 0, 0);
@@ -424,24 +424,19 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
         */
        new_refs = 0;
        for (ref = remote_refs; ref; ref = ref->next) {
-               const unsigned char *new_sha1;
-
-               if (!ref->peer_ref) {
-                       if (!args.send_mirror)
-                               continue;
-                       new_sha1 = null_sha1;
-               }
-               else
-                       new_sha1 = ref->peer_ref->new_sha1;
 
+               if (ref->peer_ref)
+                       hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
+               else if (!args.send_mirror)
+                       continue;
 
-               ref->deletion = is_null_sha1(new_sha1);
+               ref->deletion = is_null_sha1(ref->new_sha1);
                if (ref->deletion && !allow_deleting_refs) {
                        ref->status = REF_STATUS_REJECT_NODELETE;
                        continue;
                }
                if (!ref->deletion &&
-                   !hashcmp(ref->old_sha1, new_sha1)) {
+                   !hashcmp(ref->old_sha1, ref->new_sha1)) {
                        ref->status = REF_STATUS_UPTODATE;
                        continue;
                }
@@ -469,14 +464,13 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
                    !ref->deletion &&
                    !is_null_sha1(ref->old_sha1) &&
                    (!has_sha1_file(ref->old_sha1)
-                     || !ref_newer(new_sha1, ref->old_sha1));
+                     || !ref_newer(ref->new_sha1, ref->old_sha1));
 
                if (ref->nonfastforward && !ref->force && !args.force_update) {
                        ref->status = REF_STATUS_REJECT_NONFASTFORWARD;
                        continue;
                }
 
-               hashcpy(ref->new_sha1, new_sha1);
                if (!ref->deletion)
                        new_refs++;
 
index 50cafc814d3774bf358288c23cafbf2cbcecf673..11b91b3c3b2289d396c72067f7b3ded2ec6a0b64 100644 (file)
@@ -125,7 +125,7 @@ static int for_each_tag_name(const char **argv, each_tag_name_fn fn)
 static int delete_tag(const char *name, const char *ref,
                                const unsigned char *sha1)
 {
-       if (delete_ref(ref, sha1))
+       if (delete_ref(ref, sha1, 0))
                return 1;
        printf("Deleted tag '%s'\n", name);
        return 0;
@@ -283,7 +283,7 @@ static void create_tag(const unsigned char *object, const char *tag,
                int fd;
 
                /* write the template message before editing: */
-               path = xstrdup(git_path("TAG_EDITMSG"));
+               path = git_pathdup("TAG_EDITMSG");
                fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
                if (fd < 0)
                        die("could not create file '%s': %s",
index 56a0b1b39cf4c4fc51dbbff256240655bc36a038..378dc1b7a6bb4d56d301a34a4d44dae2f9a37e44 100644 (file)
@@ -13,7 +13,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
 {
        const char *refname, *oldval, *msg=NULL;
        unsigned char sha1[20], oldsha1[20];
-       int delete = 0, no_deref = 0;
+       int delete = 0, no_deref = 0, flags = 0;
        struct option options[] = {
                OPT_STRING( 'm', NULL, &msg, "reason", "reason of the update"),
                OPT_BOOLEAN('d', NULL, &delete, "deletes the reference"),
@@ -47,9 +47,11 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
        if (oldval && *oldval && get_sha1(oldval, oldsha1))
                die("%s: not a valid old SHA1", oldval);
 
+       if (no_deref)
+               flags = REF_NODEREF;
        if (delete)
-               return delete_ref(refname, oldval ? oldsha1 : NULL);
+               return delete_ref(refname, oldval ? oldsha1 : NULL, flags);
        else
                return update_ref(msg, refname, sha1, oldval ? oldsha1 : NULL,
-                                 no_deref ? REF_NODEREF : 0, DIE_ON_ERR);
+                                 flags, DIE_ON_ERR);
 }
index 7d17a1fde16204859849aaf28945739aaa685f91..daecd8e1cad4a301e2faa3888c561746d029f09d 100644 (file)
--- a/bundle.c
+++ b/bundle.c
@@ -114,7 +114,7 @@ int verify_bundle(struct bundle_header *header, int verbose)
                        continue;
                }
                if (++ret == 1)
-                       error(message);
+                       error("%s", message);
                error("%s %s", sha1_to_hex(e->sha1), e->name);
        }
        if (revs.pending.nr != p->nr)
@@ -139,7 +139,7 @@ int verify_bundle(struct bundle_header *header, int verbose)
        for (i = 0; i < req_nr; i++)
                if (!(refs.objects[i].item->flags & SHOWN)) {
                        if (++ret == 1)
-                               error(message);
+                               error("%s", message);
                        error("%s %s", sha1_to_hex(refs.objects[i].item->sha1),
                                refs.objects[i].name);
                }
diff --git a/cache.h b/cache.h
index 74339edaaa2bc5fbf3e920d66a8bca9cc5b785d3..3960931a9559e9f292f4ea4f01488f7294057148 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 *);
@@ -424,7 +426,7 @@ extern int commit_locked_index(struct lock_file *);
 extern void set_alternate_index_output(const char *);
 extern int close_lock_file(struct lock_file *);
 extern void rollback_lock_file(struct lock_file *);
-extern int delete_ref(const char *, const unsigned char *sha1);
+extern int delete_ref(const char *, const unsigned char *sha1, int delopt);
 
 /* Environment bits from configuration mechanism */
 extern int trust_executable_bit;
@@ -484,6 +486,13 @@ extern int check_repository_format(void);
 #define DATA_CHANGED    0x0020
 #define TYPE_CHANGED    0x0040
 
+extern char *mksnpath(char *buf, size_t n, const char *fmt, ...)
+       __attribute__((format (printf, 3, 4)));
+extern char *git_snpath(char *buf, size_t n, const char *fmt, ...)
+       __attribute__((format (printf, 3, 4)));
+extern char *git_pathdup(const char *fmt, ...)
+       __attribute__((format (printf, 1, 2)));
+
 /* Return a statically allocated filename matching the sha1 signature */
 extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
 extern char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
index 53f04a076a7275965090edd4ca2a34652c4f5679..82807c83b20ef8fbabfda7d476feff92f2dbb823 100644 (file)
--- a/config.c
+++ b/config.c
@@ -630,7 +630,7 @@ int git_config(config_fn_t fn, void *data)
                free(user_config);
        }
 
-       repo_config = xstrdup(git_path("config"));
+       repo_config = git_pathdup("config");
        ret += git_config_from_file(fn, repo_config, data);
        free(repo_config);
        return ret;
@@ -872,7 +872,7 @@ int git_config_set_multivar(const char* key, const char* value,
        if (config_exclusive_filename)
                config_filename = xstrdup(config_exclusive_filename);
        else
-               config_filename = xstrdup(git_path("config"));
+               config_filename = git_pathdup("config");
 
        /*
         * Since "key" actually contains the section name and the real
@@ -1132,7 +1132,7 @@ int git_config_rename_section(const char *old_name, const char *new_name)
        if (config_exclusive_filename)
                config_filename = xstrdup(config_exclusive_filename);
        else
-               config_filename = xstrdup(git_path("config"));
+               config_filename = git_pathdup("config");
        out_fd = hold_lock_file_for_update(lock, config_filename, 0);
        if (out_fd < 0) {
                ret = error("could not lock config file %s", config_filename);
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 0c6d11f6a0c6fa5dbab2f36c4b4ad4de5aba4ac9..9ebf485a738740fe6ad0ebaa5c5bf4695ee527ef 100644 (file)
@@ -71,7 +71,7 @@ static void setup_git_env(void)
        }
        git_graft_file = getenv(GRAFT_ENVIRONMENT);
        if (!git_graft_file)
-               git_graft_file = xstrdup(git_path("info/grafts"));
+               git_graft_file = git_pathdup("info/grafts");
 }
 
 int is_bare_repository(void)
@@ -113,7 +113,7 @@ const char *get_git_work_tree(void)
                        work_tree = git_work_tree_cfg;
                        /* make_absolute_path also normalizes the path */
                        if (work_tree && !is_absolute_path(work_tree))
-                               work_tree = xstrdup(make_absolute_path(git_path(work_tree)));
+                               work_tree = xstrdup(make_absolute_path(git_path("%s", work_tree)));
                } else if (work_tree)
                        work_tree = xstrdup(make_absolute_path(work_tree));
                git_work_tree_initialized = 1;
diff --git a/fsck.c b/fsck.c
index 797e3178ae279f444d2efa7e3758652ad0898dd7..ab64c18a2baf5e88de8e98d9d8526ba3a7dfed14 100644 (file)
--- a/fsck.c
+++ b/fsck.c
@@ -327,7 +327,7 @@ int fsck_error_function(struct object *obj, int type, const char *fmt, ...)
                        die("this should not happen, your snprintf is broken");
        }
 
-       error(sb.buf);
+       error("%s", sb.buf);
        strbuf_release(&sb);
        return 1;
 }
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 5888735e4f2dac852f43c31195f430a1a6d23446..97e4d9a1ef9478f54613144e74e9e12314230877 100755 (executable)
@@ -294,7 +294,7 @@ cmd_update()
                        # Only mention uninitialized submodules when its
                        # path have been specified
                        test "$#" != "0" &&
-                       say "Submodule path '$path' not initialized"
+                       say "Submodule path '$path' not initialized" &&
                        say "Maybe you want to use 'update --init'?"
                        continue
                fi
index c6492e5be2763eab81358424ff625a34a5ff2fba..6733b6f5551e43835fcf46793142d9d7ffbe27f9 100644 (file)
@@ -145,6 +145,7 @@ rm -rf $RPM_BUILD_ROOT
 %files cvs
 %defattr(-,root,root)
 %doc Documentation/*git-cvs*.txt
+%{_bindir}/git-cvsserver
 %{_libexecdir}/git-core/*cvs*
 %{!?_without_docs: %{_mandir}/man1/*cvs*.1*}
 %{!?_without_docs: %doc Documentation/*git-cvs*.html }
@@ -188,6 +189,9 @@ rm -rf $RPM_BUILD_ROOT
 # No files for you!
 
 %changelog
+* Fri Sep 12 2008 Quy Tonthat <qtonthat@gmail.com>
+- move git-cvsserver to bindir.
+
 * Sun Jun 15 2008 Junio C Hamano <gitster@pobox.com>
 - Remove curl from Requires list.
 
diff --git a/grep.c b/grep.c
index 706351197fc26efa10c4666d38433f8fbdf1d6b5..13c18ff6529f437e6aea2671ab0003d4fd047ac7 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -507,7 +507,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
                                if (from <= last_shown)
                                        from = last_shown + 1;
                                if (last_shown && from != last_shown + 1)
-                                       printf(hunk_mark);
+                                       fputs(hunk_mark, stdout);
                                while (from < lno) {
                                        pcl = &prev[lno-from-1];
                                        show_line(opt, pcl->bol, pcl->eol,
@@ -517,7 +517,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
                                last_shown = lno-1;
                        }
                        if (last_shown && lno != last_shown + 1)
-                               printf(hunk_mark);
+                               fputs(hunk_mark, stdout);
                        if (!opt->count)
                                show_line(opt, bol, eol, name, lno, ':');
                        last_shown = last_hit = lno;
@@ -528,7 +528,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
                         * we need to show this line.
                         */
                        if (last_shown && lno != last_shown + 1)
-                               printf(hunk_mark);
+                               fputs(hunk_mark, stdout);
                        show_line(opt, bol, eol, name, lno, '-');
                        last_shown = lno;
                }
diff --git a/path.c b/path.c
index c1cb54b7b8b478c717861a0205e537ded3fbbfc9..a074aea64921eb1fb90f079ede9087e6b8109f6a 100644 (file)
--- a/path.c
+++ b/path.c
@@ -32,6 +32,60 @@ static char *cleanup_path(char *path)
        return path;
 }
 
+char *mksnpath(char *buf, size_t n, const char *fmt, ...)
+{
+       va_list args;
+       unsigned len;
+
+       va_start(args, fmt);
+       len = vsnprintf(buf, n, fmt, args);
+       va_end(args);
+       if (len >= n) {
+               strlcpy(buf, bad_path, n);
+               return buf;
+       }
+       return cleanup_path(buf);
+}
+
+static char *git_vsnpath(char *buf, size_t n, const char *fmt, va_list args)
+{
+       const char *git_dir = get_git_dir();
+       size_t len;
+
+       len = strlen(git_dir);
+       if (n < len + 1)
+               goto bad;
+       memcpy(buf, git_dir, len);
+       if (len && !is_dir_sep(git_dir[len-1]))
+               buf[len++] = '/';
+       len += vsnprintf(buf + len, n - len, fmt, args);
+       if (len >= n)
+               goto bad;
+       return cleanup_path(buf);
+bad:
+       strlcpy(buf, bad_path, n);
+       return buf;
+}
+
+char *git_snpath(char *buf, size_t n, const char *fmt, ...)
+{
+       va_list args;
+       va_start(args, fmt);
+       (void)git_vsnpath(buf, n, fmt, args);
+       va_end(args);
+       return buf;
+}
+
+char *git_pathdup(const char *fmt, ...)
+{
+       char path[PATH_MAX];
+       va_list args;
+       va_start(args, fmt);
+       (void)git_vsnpath(path, sizeof(path), fmt, args);
+       va_end(args);
+       return xstrdup(path);
+}
+
 char *mkpath(const char *fmt, ...)
 {
        va_list args;
index 6aab712e6ac6513b0b46958d93d536ef975276b4..ba94453781c98a97a95c65999873fc28b013340d 100644 (file)
@@ -1203,8 +1203,7 @@ =head1 COPYRIGHT
 # the method was called upon an instance and (undef, @args) if
 # it was called directly.
 sub _maybe_self {
-       # This breaks inheritance. Oh well.
-       ref $_[0] eq 'Git' ? @_ : (undef, @_);
+       UNIVERSAL::isa($_[0], 'Git') ? @_ : (undef, @_);
 }
 
 # Check if the command id is something reasonable.
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 d44c19e6b577023dcbaa188a0e67130ff4e5bd9a..f0145bd9011689b29e3aad3db5fb55cd94aacb2a 100644 (file)
@@ -222,7 +222,7 @@ static const char *update(struct command *cmd)
                        warning ("Allowing deletion of corrupt ref.");
                        old_sha1 = NULL;
                }
-               if (delete_ref(name, old_sha1)) {
+               if (delete_ref(name, old_sha1, 0)) {
                        error("failed to delete %s", name);
                        return "failed to delete";
                }
diff --git a/refs.c b/refs.c
index 9e422dcccbb3d499b55df5f39612b12c3c3f52e0..be095cb07d23ca9f0e20d2cc46df33827a123274 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -401,7 +401,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
                *flag = 0;
 
        for (;;) {
-               const char *path = git_path("%s", ref);
+               char path[PATH_MAX];
                struct stat st;
                char *buf;
                int fd;
@@ -409,6 +409,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
                if (--depth < 0)
                        return NULL;
 
+               git_snpath(path, sizeof(path), "%s", ref);
                /* Special case: non-existing file.
                 * Not having the refs/heads/new-branch is OK
                 * if we are writing into it, so is .git/HEAD
@@ -788,10 +789,10 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char
        char *ref_file;
        const char *orig_ref = ref;
        struct ref_lock *lock;
-       struct stat st;
        int last_errno = 0;
        int type, lflags;
        int mustexist = (old_sha1 && !is_null_sha1(old_sha1));
+       int missing = 0;
 
        lock = xcalloc(1, sizeof(struct ref_lock));
        lock->lock_fd = -1;
@@ -819,12 +820,13 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char
                        orig_ref, strerror(errno));
                goto error_return;
        }
+       missing = is_null_sha1(lock->old_sha1);
        /* When the ref did not exist and we are creating it,
         * make sure there is no existing ref that is packed
         * whose name begins with our refname, nor a ref whose
         * name is a proper prefix of our refname.
         */
-       if (is_null_sha1(lock->old_sha1) &&
+       if (missing &&
             !is_refname_available(ref, NULL, get_packed_refs(), 0))
                goto error_return;
 
@@ -838,7 +840,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char
        lock->ref_name = xstrdup(ref);
        lock->orig_ref_name = xstrdup(orig_ref);
        ref_file = git_path("%s", ref);
-       if (lstat(ref_file, &st) && errno == ENOENT)
+       if (missing)
                lock->force_write = 1;
        if ((flags & REF_NODEREF) && (type & REF_ISSYMREF))
                lock->force_write = 1;
@@ -915,25 +917,33 @@ static int repack_without_ref(const char *refname)
        return commit_lock_file(&packlock);
 }
 
-int delete_ref(const char *refname, const unsigned char *sha1)
+int delete_ref(const char *refname, const unsigned char *sha1, int delopt)
 {
        struct ref_lock *lock;
-       int err, i, ret = 0, flag = 0;
+       int err, i = 0, ret = 0, flag = 0;
 
        lock = lock_ref_sha1_basic(refname, sha1, 0, &flag);
        if (!lock)
                return 1;
-       if (!(flag & REF_ISPACKED)) {
+       if (!(flag & REF_ISPACKED) || flag & REF_ISSYMREF) {
                /* loose */
-               i = strlen(lock->lk->filename) - 5; /* .lock */
-               lock->lk->filename[i] = 0;
-               err = unlink(lock->lk->filename);
+               const char *path;
+
+               if (!(delopt & REF_NODEREF)) {
+                       i = strlen(lock->lk->filename) - 5; /* .lock */
+                       lock->lk->filename[i] = 0;
+                       path = lock->lk->filename;
+               } else {
+                       path = git_path("%s", refname);
+               }
+               err = unlink(path);
                if (err && errno != ENOENT) {
                        ret = 1;
                        error("unlink(%s) failed: %s",
-                             lock->lk->filename, strerror(errno));
+                             path, strerror(errno));
                }
-               lock->lk->filename[i] = '.';
+               if (!(delopt & REF_NODEREF))
+                       lock->lk->filename[i] = '.';
        }
        /* removing the loose one could have resurrected an earlier
         * packed one.  Also, if it was not loose we need to repack
@@ -958,11 +968,16 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
        struct ref_lock *lock;
        struct stat loginfo;
        int log = !lstat(git_path("logs/%s", oldref), &loginfo);
+       const char *symref = NULL;
 
-       if (S_ISLNK(loginfo.st_mode))
+       if (log && S_ISLNK(loginfo.st_mode))
                return error("reflog for %s is a symlink", oldref);
 
-       if (!resolve_ref(oldref, orig_sha1, 1, &flag))
+       symref = resolve_ref(oldref, orig_sha1, 1, &flag);
+       if (flag & REF_ISSYMREF)
+               return error("refname %s is a symbolic ref, renaming it is not supported",
+                       oldref);
+       if (!symref)
                return error("refname %s not found", oldref);
 
        if (!is_refname_available(newref, oldref, get_packed_refs(), 0))
@@ -982,12 +997,12 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
                return error("unable to move logfile logs/%s to tmp-renamed-log: %s",
                        oldref, strerror(errno));
 
-       if (delete_ref(oldref, orig_sha1)) {
+       if (delete_ref(oldref, orig_sha1, REF_NODEREF)) {
                error("unable to delete old %s", oldref);
                goto rollback;
        }
 
-       if (resolve_ref(newref, sha1, 1, &flag) && delete_ref(newref, sha1)) {
+       if (resolve_ref(newref, sha1, 1, &flag) && delete_ref(newref, sha1, REF_NODEREF)) {
                if (errno==EISDIR) {
                        if (remove_empty_directories(git_path("%s", newref))) {
                                error("Directory not empty: %s", newref);
@@ -1030,7 +1045,6 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
                error("unable to lock %s for update", newref);
                goto rollback;
        }
-
        lock->force_write = 1;
        hashcpy(lock->old_sha1, orig_sha1);
        if (write_ref_sha1(lock, orig_sha1, logmsg)) {
@@ -1124,13 +1138,14 @@ static int log_ref_write(const char *ref_name, const unsigned char *old_sha1,
        int logfd, written, oflags = O_APPEND | O_WRONLY;
        unsigned maxlen, len;
        int msglen;
-       char *log_file, *logrec;
+       char log_file[PATH_MAX];
+       char *logrec;
        const char *committer;
 
        if (log_all_ref_updates < 0)
                log_all_ref_updates = !is_bare_repository();
 
-       log_file = git_path("logs/%s", ref_name);
+       git_snpath(log_file, sizeof(log_file), "logs/%s", ref_name);
 
        if (log_all_ref_updates &&
            (!prefixcmp(ref_name, "refs/heads/") ||
@@ -1259,7 +1274,7 @@ int create_symref(const char *ref_target, const char *refs_heads_master,
        const char *lockpath;
        char ref[1000];
        int fd, len, written;
-       char *git_HEAD = xstrdup(git_path("%s", ref_target));
+       char *git_HEAD = git_pathdup("%s", ref_target);
        unsigned char old_sha1[20], new_sha1[20];
 
        if (logmsg && read_ref(ref_target, old_sha1))
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 2b7a99d729e13b09239f1d9175d3d6c0048821b0..a0d477aaca73ff7ec8b12dc6c8255b69dbd677a5 100644 (file)
--- a/rerere.c
+++ b/rerere.c
@@ -345,7 +345,7 @@ int setup_rerere(struct string_list *merge_rr)
        if (!is_rerere_enabled())
                return -1;
 
-       merge_rr_path = xstrdup(git_path("MERGE_RR"));
+       merge_rr_path = git_pathdup("MERGE_RR");
        fd = hold_lock_file_for_update(&write_lock, merge_rr_path,
                                       LOCK_DIE_ON_ERROR);
        read_rr(merge_rr);
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 c1c073b2f05a48772a45602cdc711eef6e211695..66b0d9d878a011393582b837301eb1fd5caf2e40 100644 (file)
@@ -25,7 +25,7 @@ static int add_info_ref(const char *path, const unsigned char *sha1, int flag, v
 
 static int update_info_refs(int force)
 {
-       char *path0 = xstrdup(git_path("info/refs"));
+       char *path0 = git_pathdup("info/refs");
        int len = strlen(path0);
        char *path1 = xmalloc(len + 2);
 
index 12fc767ee57103739e568a959981ca559417ecf4..4e05429aba880a5d6672cf3fc2033e872798e970 100644 (file)
@@ -2220,7 +2220,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;
@@ -2246,7 +2246,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 4fb77f8863ec075de38b84171d3ef039a00cee4c..75a5a7e96f292bed344a7609fca2f3a45ba4314e 100644 (file)
@@ -245,11 +245,13 @@ int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
 
        *ref = NULL;
        for (p = ref_rev_parse_rules; *p; p++) {
+               char fullref[PATH_MAX];
                unsigned char sha1_from_ref[20];
                unsigned char *this_result;
 
                this_result = refs_found ? sha1_from_ref : sha1;
-               r = resolve_ref(mkpath(*p, len, str), this_result, 1, NULL);
+               mksnpath(fullref, sizeof(fullref), *p, len, str);
+               r = resolve_ref(fullref, this_result, 1, NULL);
                if (r) {
                        if (!refs_found++)
                                *ref = xstrdup(r);
@@ -272,7 +274,7 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
                char path[PATH_MAX];
                const char *ref, *it;
 
-               strcpy(path, mkpath(*p, len, str));
+               mksnpath(path, sizeof(path), *p, len, str);
                ref = resolve_ref(path, hash, 1, NULL);
                if (!ref)
                        continue;
index 04c2b164bcba0bdead45a50bbb14ceff19e8411f..bd589268fcf459f07ff6c53e43d41e66fe1e7903 100755 (executable)
@@ -75,6 +75,24 @@ test_expect_success "delete $m (by HEAD)" '
 '
 rm -f .git/$m
 
+cp -f .git/HEAD .git/HEAD.orig
+test_expect_success "delete symref without dereference" '
+       git update-ref --no-deref -d HEAD &&
+       ! test -f .git/HEAD
+'
+cp -f .git/HEAD.orig .git/HEAD
+
+test_expect_success "delete symref without dereference when the referred ref is packed" '
+       echo foo >foo.c &&
+       git add foo.c &&
+       git commit -m foo &&
+       git pack-refs --all &&
+       git update-ref --no-deref -d HEAD &&
+       ! test -f .git/HEAD
+'
+cp -f .git/HEAD.orig .git/HEAD
+git update-ref -d $m
+
 test_expect_success '(not) create HEAD with old sha1' "
        test_must_fail git update-ref HEAD $A $B
 "
diff --git a/t/t2011-checkout-invalid-head.sh b/t/t2011-checkout-invalid-head.sh
new file mode 100755 (executable)
index 0000000..764bb0a
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+test_description='checkout switching away from an invalid branch'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+       echo hello >world &&
+       git add world &&
+       git commit -m initial
+'
+
+test_expect_success 'checkout master from invalid HEAD' '
+       echo 0000000000000000000000000000000000000000 >.git/HEAD &&
+       git checkout master --
+'
+
+test_done
index 2147eacc5057128facc08816a2980646bed28ec5..25e9971fd86af10c1031f4e8061c31a0c80725a7 100755 (executable)
@@ -112,6 +112,15 @@ test_expect_success 'config information was renamed, too' \
        "test $(git config branch.s.dummy) = Hello &&
         test_must_fail git config branch.s/s/dummy"
 
+test_expect_success 'renaming a symref is not allowed' \
+'
+       git symbolic-ref refs/heads/master2 refs/heads/master &&
+       test_must_fail git branch -m master2 master3 &&
+       git symbolic-ref refs/heads/master2 &&
+       test -f .git/refs/heads/master &&
+       ! test -f .git/refs/heads/master3
+'
+
 test_expect_success \
     'git branch -m u v should fail when the reflog for u is a symlink' '
      git branch -l u &&
index 087ef75061f4d56fcb6350284d91820485249087..413019acafc98646a61e77960527f042a8f96ac6 100755 (executable)
@@ -96,6 +96,13 @@ test_expect_success \
      git branch -d n/o/p &&
      git branch n'
 
+test_expect_success \
+       'see if up-to-date packed refs are preserved' \
+       'git branch q &&
+        git pack-refs --all --prune &&
+        git update-ref refs/heads/q refs/heads/q &&
+        ! test -f .git/refs/heads/q'
+
 test_expect_success 'pack, prune and repack' '
        git tag foo &&
        git pack-refs --all --prune &&
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 f0030ad00e4a6478fcb3ccfc503e576bd58003bd..f9e878022a93657a8b8d81339670f4d910392755 100755 (executable)
@@ -437,6 +437,37 @@ test_expect_success 'push updates local refs' '
 
 '
 
+test_expect_success 'push updates up-to-date local refs' '
+
+       rm -rf parent child &&
+       mkdir parent &&
+       (cd parent && git init &&
+               echo one >foo && git add foo && git commit -m one) &&
+       git clone parent child1 &&
+       git clone parent child2 &&
+       (cd child1 &&
+               echo two >foo && git commit -a -m two &&
+               git push) &&
+       (cd child2 &&
+               git pull ../child1 master &&
+               git push &&
+       test $(git rev-parse master) = $(git rev-parse remotes/origin/master))
+
+'
+
+test_expect_success 'push preserves up-to-date packed refs' '
+
+       rm -rf parent child &&
+       mkdir parent &&
+       (cd parent && git init &&
+               echo one >foo && git add foo && git commit -m one) &&
+       git clone parent child &&
+       (cd child &&
+               git push &&
+       ! test -f .git/refs/remotes/origin/master)
+
+'
+
 test_expect_success 'push does not update local refs on failure' '
 
        rm -rf parent child &&
@@ -463,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 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
index e5749ef638b4a9a490894d9d4fc5876d904ab9ac..54f301da67be879c80426bc21776427fdd38c02e 100644 (file)
@@ -352,7 +352,7 @@ static int unpack_failed(struct unpack_trees_options *o, const char *message)
        discard_index(&o->result);
        if (!o->gently) {
                if (message)
-                       return error(message);
+                       return error("%s", message);
                return -1;
        }
        return -1;