]> rtime.felk.cvut.cz Git - git.git/commitdiff
Merge branch 'sb/quiet-porcelains'
authorJunio C Hamano <gitster@pobox.com>
Thu, 2 Jul 2009 02:40:50 +0000 (19:40 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 2 Jul 2009 02:40:50 +0000 (19:40 -0700)
* sb/quiet-porcelains:
  stash: teach quiet option
  am, rebase: teach quiet option
  submodule, repack: migrate to git-sh-setup's say()
  git-sh-setup: introduce say() for quiet options
  am: suppress apply errors when using 3-way
  t4150: test applying with a newline in subject

95 files changed:
.gitattributes
Documentation/RelNotes-1.6.3.3.txt [new file with mode: 0644]
Documentation/asciidoc.conf
Documentation/config.txt
Documentation/git-cvsexportcommit.txt
Documentation/git-parse-remote.txt
Documentation/git-send-email.txt
Documentation/git-show-ref.txt
Documentation/git-submodule.txt
Documentation/git-svn.txt
Documentation/git.txt
Documentation/gitmodules.txt
Documentation/gittutorial.txt
Documentation/technical/api-remote.txt
Documentation/urls-remotes.txt
Makefile
attr.c
base85.c
bisect.c
builtin-add.c
builtin-apply.c
builtin-clone.c
builtin-for-each-ref.c
builtin-fsck.c
builtin-help.c
builtin-log.c
builtin-merge.c
builtin-mv.c
builtin-pack-objects.c
builtin-push.c
builtin-remote.c
builtin-tag.c
builtin-unpack-objects.c
builtin-upload-archive.c
builtin-write-tree.c
cache-tree.c
cache-tree.h
configure.ac
connect.c
contrib/completion/git-completion.bash
contrib/fast-import/import-tars.perl
daemon.c
delta.h
diff-lib.c
git-cvsexportcommit.perl
git-parse-remote.sh
git-pull.sh
git-rebase.sh
git-request-pull.sh
git-send-email.perl
git-submodule.sh
git-svn.perl
git.c
gitk-git/gitk
gitk-git/po/de.po
gitweb/README
http-push.c
http.c
imap-send.c
index-pack.c
ll-merge.c
log-tree.c
mailmap.c
merge-recursive.c
parse-options.c
parse-options.h
patch-delta.c
quote.c
remote.c
remote.h
revision.c
revision.h
sha1_file.c
strbuf.c
t/t3505-cherry-pick-empty.sh
t/t3700-add.sh
t/t4007-rename-3.sh
t/t4037-diff-r-t-dirs.sh [new file with mode: 0755]
t/t5000-tar-tree.sh
t/t5505-remote.sh
t/t5516-fetch-push.sh
t/t5520-pull.sh
t/t7002-grep.sh
t/t7406-submodule-update.sh
t/t9001-send-email.sh
t/t9100-git-svn-basic.sh
t/t9138-git-svn-multiple-branches.sh [new file with mode: 0755]
t/t9139-git-svn-reset.sh [new file with mode: 0755]
test-parse-options.c
tree-diff.c
unpack-trees.c
unpack-trees.h
userdiff.c
ws.c
wt-status.c

index 6b9c715d21d5486e59083fb6071566aa6ecd4d42..0636deea9357d2f1e9331119f02fb75fb6b15393 100644 (file)
@@ -1,2 +1,2 @@
 * whitespace=!indent,trail,space
-*.[ch] whitespace
+*.[ch] whitespace=indent,trail,space
diff --git a/Documentation/RelNotes-1.6.3.3.txt b/Documentation/RelNotes-1.6.3.3.txt
new file mode 100644 (file)
index 0000000..1c28398
--- /dev/null
@@ -0,0 +1,38 @@
+GIT v1.6.3.3 Release Notes
+==========================
+
+Fixes since v1.6.3.2
+--------------------
+
+ * "git archive" running on Cygwin can get stuck in an infinite loop.
+
+ * "git daemon" did not correctly parse the initial line that carries
+   virtual host request information.
+
+ * "git diff --textconv" leaked memory badly when the textconv filter
+   errored out.
+
+ * The built-in regular expressions to pick function names to put on
+   hunk header lines for java and objc were very inefficiently written.
+
+ * in certain error situations git-fetch (and git-clone) on Windows didn't
+   detect connection abort and ended up waiting indefinitely.
+
+ * import-tars script (in contrib) did not import symbolic links correctly.
+
+ * http.c used CURLOPT_SSLKEY even on libcURL version 7.9.2, even though
+   it was only available starting 7.9.3.
+
+ * low-level filelevel merge driver used return value from strdup()
+   without checking if we ran out of memory.
+
+ * "git rebase -i" left stray closing parenthesis in its reflog message.
+
+ * "git remote show" did not show all the URLs associated with the named
+   remote, even though "git remote -v" did.  Made them consistent by
+   making the former show all URLs.
+
+ * "whitespace" attribute that is set was meant to detect all errors known
+   to git, but it told git to ignore trailing carriage-returns.
+
+Includes other documentation fixes.
index dc76e7f073f23cd911da0b0d0d49b72726576f1a..87a90f2c3fd48bbb593a2cef135310f88d87e4b4 100644 (file)
@@ -17,6 +17,7 @@ caret=&#94;
 startsb=&#91;
 endsb=&#93;
 tilde=&#126;
+backtick=&#96;
 
 ifdef::backend-docbook[]
 [linkgit-inlinemacro]
index 3a86d1f8f05317717d718a6db7c5e0f9acb47d6b..2fecbe32a68bd981959735dd14e6e311d16b233a 100644 (file)
@@ -1319,6 +1319,9 @@ remote.<name>.url::
        The URL of a remote repository.  See linkgit:git-fetch[1] or
        linkgit:git-push[1].
 
+remote.<name>.pushurl::
+       The push URL of a remote repository.  See linkgit:git-push[1].
+
 remote.<name>.proxy::
        For remotes that require curl (http, https and ftp), the URL to
        the proxy to use for that remote.  Set to the empty string to
index 2da8588f4fd6edb842a9824181165b3f043ec87b..abaaf273bb3f39fef065781d89592fd7203ea620 100644 (file)
@@ -63,6 +63,10 @@ OPTIONS
 -u::
        Update affected files from CVS repository before attempting export.
 
+-k::
+       Reverse CVS keyword expansion (e.g. $Revision: 1.2.3.4$
+       becomes $Revision$) in working CVS checkout before applying patch.
+
 -w::
        Specify the location of the CVS checkout to use for the export. This
        option does not require GIT_DIR to be set before execution if the
index cd43069874d59504627211e011250a3554aeee5a..39d9daa7e00b97ddcca8f3d25d7376234c57c246 100644 (file)
@@ -17,26 +17,6 @@ routines to parse files under $GIT_DIR/remotes/ and
 $GIT_DIR/branches/ and configuration variables that are related
 to fetching, pulling and pushing.
 
-The primary entry points are:
-
-get_remote_refs_for_fetch::
-       Given the list of user-supplied `<repo> <refspec>...`,
-       return the list of refs to fetch after canonicalizing
-       them into `$GIT_DIR` relative paths
-       (e.g. `refs/heads/foo`).  When `<refspec>...` is empty
-       the returned list of refs consists of the defaults
-       for the given `<repo>`, if specified in
-       `$GIT_DIR/remotes/`, `$GIT_DIR/branches/`, or `remote.*.fetch`
-       configuration.
-
-get_remote_refs_for_push::
-       Given the list of user-supplied `<repo> <refspec>...`,
-       return the list of refs to push in a form suitable to be
-       fed to the 'git-send-pack' command.  When `<refspec>...`
-       is empty the returned list of refs consists of the
-       defaults for the given `<repo>`, if specified in
-       `$GIT_DIR/remotes/`.
-
 Author
 ------
 Written by Junio C Hamano.
index 9902da43c7c24342346f2fcdce86c8db9411b28d..fbde2d3be523443c8388f9bb43cc0d5682658f8f 100644 (file)
@@ -193,12 +193,12 @@ Automating
 - 'self' will avoid including the sender
 - 'cc' will avoid including anyone mentioned in Cc lines in the patch header
   except for self (use 'self' for that).
-- 'ccbody' will avoid including anyone mentioned in Cc lines in the
+- 'bodycc' will avoid including anyone mentioned in Cc lines in the
   patch body (commit message) except for self (use 'self' for that).
 - 'sob' will avoid including anyone mentioned in Signed-off-by lines except
    for self (use 'self' for that).
 - 'cccmd' will avoid running the --cc-cmd.
-- 'body' is equivalent to 'sob' + 'ccbody'
+- 'body' is equivalent to 'sob' + 'bodycc'
 - 'all' will suppress all auto cc values.
 --
 +
index 2f173fff356282df7c906da6edeac1fcd4430025..98e294aa869d39575ab32d859ca9fcc3bfcaf789 100644 (file)
@@ -24,7 +24,7 @@ The --exclude-existing form is a filter that does the inverse, it shows the
 refs from stdin that don't exist in the local repository.
 
 Use of this utility is encouraged in favor of directly accessing files under
-in the `.git` directory.
+the `.git` directory.
 
 OPTIONS
 -------
@@ -50,7 +50,7 @@ OPTIONS
 -s::
 --hash::
 
-       Only show the SHA1 hash, not the reference name. When also using
+       Only show the SHA1 hash, not the reference name. When combined with
        --dereference the dereferenced tag will still be shown after the SHA1.
 
 --verify::
index cd8e861ce4ae33b25928a16aa213933d2a38a155..683ba1a1ebe080e6e093d27686068823448e459c 100644 (file)
@@ -115,8 +115,9 @@ init::
 update::
        Update the registered submodules, i.e. clone missing submodules and
        checkout the commit specified in the index of the containing repository.
-       This will make the submodules HEAD be detached unless '--rebase' is
-       specified or the key `submodule.$name.update` is set to `rebase`.
+       This will make the submodules HEAD be detached unless '--rebase' or
+       '--merge' is specified or the key `submodule.$name.update` is set to
+       `rebase` or `merge`.
 +
 If the submodule is not yet initialized, and you just want to use the
 setting as stored in .gitmodules, you can automatically initialize the
@@ -140,8 +141,9 @@ foreach::
        the processing to terminate. This can be overridden by adding '|| :'
        to the end of the command.
 +
-As an example, "git submodule foreach 'echo $path `git rev-parse HEAD`' will
-show the path and currently checked out commit for each submodule.
+As an example, +git submodule foreach \'echo $path {backtick}git
+rev-parse HEAD{backtick}'+ will show the path and currently checked out
+commit for each submodule.
 
 sync::
        Synchronizes submodules' remote URL configuration setting
@@ -180,6 +182,16 @@ OPTIONS
        This option is only valid for the update command.
        Don't fetch new objects from the remote site.
 
+--merge::
+       This option is only valid for the update command.
+       Merge the commit recorded in the superproject into the current branch
+       of the submodule. If this option is given, the submodule's HEAD will
+       not be detached. If a merge failure prevents this process, you will
+       have to resolve the resulting conflicts within the submodule with the
+       usual conflict resolution tools.
+       If the key `submodule.$name.update` is set to `merge`, this option is
+       implicit.
+
 --rebase::
        This option is only valid for the update command.
        Rebase the current branch onto the commit recorded in the
index ca3fc3de1fcfc3509a9d5d1ff268c9673bafc3c0..7e9b9a042347bf286c6ea523bef1952f0c72dec9 100644 (file)
@@ -3,7 +3,7 @@ git-svn(1)
 
 NAME
 ----
-git-svn - Bidirectional operation between a single Subversion branch and git
+git-svn - Bidirectional operation between a Subversion repository and git
 
 SYNOPSIS
 --------
@@ -15,13 +15,12 @@ DESCRIPTION
 It provides a bidirectional flow of changes between a Subversion and a git
 repository.
 
-'git-svn' can track a single Subversion branch simply by using a
-URL to the branch, follow branches laid out in the Subversion recommended
-method (trunk, branches, tags directories) with the --stdlayout option, or
-follow branches in any layout with the -T/-t/-b options (see options to
-'init' below, and also the 'clone' command).
+'git-svn' can track a standard Subversion repository,
+following the common "trunk/branches/tags" layout, with the --stdlayout option.
+It can also follow branches and tags in any layout with the -T/-t/-b options
+(see options to 'init' below, and also the 'clone' command).
 
-Once tracking a Subversion branch (with any of the above methods), the git
+Once tracking a Subversion repository (with any of the above methods), the git
 repository can be updated from Subversion by the 'fetch' command and
 Subversion updated from git by the 'dcommit' command.
 
@@ -48,8 +47,11 @@ COMMANDS
 --stdlayout;;
        These are optional command-line options for init.  Each of
        these flags can point to a relative repository path
-       (--tags=project/tags') or a full url
-       (--tags=https://foo.org/project/tags). The option --stdlayout is
+       (--tags=project/tags) or a full url
+       (--tags=https://foo.org/project/tags).
+       You can specify more than one --tags and/or --branches options, in case
+       your Subversion repository places tags or branches under multiple paths.
+       The option --stdlayout is
        a shorthand way of setting trunk,tags,branches as the relative paths,
        which is the Subversion default. If any of the other options are given
        as well, they take precedence.
@@ -170,8 +172,9 @@ and have no uncommitted changes.
        It is recommended that you run 'git-svn' fetch and rebase (not
        pull or merge) your commits against the latest changes in the
        SVN repository.
-       An optional command-line argument may be specified as an
-       alternative to HEAD.
+       An optional revision or branch argument may be specified, and
+       causes 'git-svn' to do all work on that revision/branch
+       instead of HEAD.
        This is advantageous over 'set-tree' (below) because it produces
        cleaner, more linear history.
 +
@@ -204,6 +207,20 @@ config key: svn.commiturl (overwrites all svn-remote.<name>.commiturl options)
        Create a tag by using the tags_subdir instead of the branches_subdir
        specified during git svn init.
 
+-d;;
+--destination;;
+       If more than one --branches (or --tags) option was given to the 'init'
+       or 'clone' command, you must provide the location of the branch (or
+       tag) you wish to create in the SVN repository.  The value of this
+       option must match one of the paths specified by a --branches (or
+       --tags) option.  You can see these paths with the commands
++
+       git config --get-all svn-remote.<name>.branches
+       git config --get-all svn-remote.<name>.tags
++
+where <name> is the name of the SVN repository as specified by the -R option to
+'init' (or "svn" by default).
+
 'tag'::
        Create a tag in the SVN repository. This is a shorthand for
        'branch -t'.
@@ -215,7 +232,7 @@ config key: svn.commiturl (overwrites all svn-remote.<name>.commiturl options)
 The following features from `svn log' are supported:
 +
 --
---revision=<n>[:<n>];;
+-r/--revision=<n>[:<n>];;
        is supported, non-numeric args are not:
        HEAD, NEXT, BASE, PREV, etc ...
 -v/--verbose;;
@@ -313,6 +330,63 @@ Any other arguments are passed directly to 'git-log'
        Shows the Subversion externals.  Use -r/--revision to specify a
        specific revision.
 
+'reset'::
+       Undoes the effects of 'fetch' back to the specified revision.
+       This allows you to re-'fetch' an SVN revision.  Normally the
+       contents of an SVN revision should never change and 'reset'
+       should not be necessary.  However, if SVN permissions change,
+       or if you alter your --ignore-paths option, a 'fetch' may fail
+       with "not found in commit" (file not previously visible) or
+       "checksum mismatch" (missed a modification).  If the problem
+       file cannot be ignored forever (with --ignore-paths) the only
+       way to repair the repo is to use 'reset'.
+
+Only the rev_map and refs/remotes/git-svn are changed.  Follow 'reset'
+with a 'fetch' and then 'git-reset' or 'git-rebase' to move local
+branches onto the new tree.
+
+-r/--revision=<n>;;
+       Specify the most recent revision to keep.  All later revisions
+       are discarded.
+-p/--parent;;
+       Discard the specified revision as well, keeping the nearest
+       parent instead.
+Example:;;
+Assume you have local changes in "master", but you need to refetch "r2".
+
+------------
+    r1---r2---r3 remotes/git-svn
+                \
+                 A---B master
+------------
+
+Fix the ignore-paths or SVN permissions problem that caused "r2" to
+be incomplete in the first place.  Then:
+
+[verse]
+git svn reset -r2 -p
+git svn fetch
+
+------------
+    r1---r2'--r3' remotes/git-svn
+      \
+       r2---r3---A---B master
+------------
+
+Then fixup "master" with 'git-rebase'.
+Do NOT use 'git-merge' or your history will not be compatible with a
+future 'dcommit'!
+
+[verse]
+git rebase --onto remotes/git-svn A^ master
+
+------------
+    r1---r2'--r3' remotes/git-svn
+                \
+                 A'--B' master
+------------
+
+
 --
 
 OPTIONS
@@ -623,7 +697,7 @@ pulled or merged from.  This is because the author favored
 If you use `git svn set-tree A..B` to commit several diffs and you do
 not have the latest remotes/git-svn merged into my-branch, you should
 use `git svn rebase` to update your work branch instead of `git pull` or
-`git merge`.  `pull`/`merge' can cause non-linear history to be flattened
+`git merge`.  `pull`/`merge` can cause non-linear history to be flattened
 when committing into SVN, which can lead to merge commits reversing
 previous commits in SVN.
 
@@ -669,6 +743,16 @@ already dcommitted.  It is considered bad practice to --amend commits
 you've already pushed to a remote repository for other users, and
 dcommit with SVN is analogous to that.
 
+When using multiple --branches or --tags, 'git-svn' does not automatically
+handle name collisions (for example, if two branches from different paths have
+the same name, or if a branch and a tag have the same name).  In these cases,
+use 'init' to set up your git repository then, before your first 'fetch', edit
+the .git/config file so that the branches and tags are associated with
+different name spaces.  For example:
+
+       branches = stable/*:refs/remotes/svn/stable/*
+       branches = debug/*:refs/remotes/svn/debug/*
+
 BUGS
 ----
 
index 56d47709ac9ec698405215ecac13d66d7c773848..6fa0310e05f2457ea95a8535460634d0f46cbce8 100644 (file)
@@ -43,9 +43,10 @@ unreleased) version of git, that is available from 'master'
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
-* link:v1.6.3.2/git.html[documentation for release 1.6.3.2]
+* link:v1.6.3.3/git.html[documentation for release 1.6.3.3]
 
 * release notes for
+  link:RelNotes-1.6.3.3.txt[1.6.3.3],
   link:RelNotes-1.6.3.2.txt[1.6.3.2],
   link:RelNotes-1.6.3.1.txt[1.6.3.1],
   link:RelNotes-1.6.3.txt[1.6.3].
index 1b67f0a9f12974afca2e8e6948d0fca564b9b17b..5daf750d1942f3b97844b4ef378daf9346cb46d4 100644 (file)
@@ -35,9 +35,11 @@ submodule.<name>.update::
        If 'checkout' (the default), the new commit specified in the
        superproject will be checked out in the submodule on a detached HEAD.
        If 'rebase', the current branch of the submodule will be rebased onto
-       the commit specified in the superproject.
+       the commit specified in the superproject. If 'merge', the commit
+       specified in the superproject will be merged into the current branch
+       in the submodule.
        This config option is overridden if 'git submodule update' is given
-       the '--rebase' option.
+       the '--merge' or '--rebase' options.
 
 
 EXAMPLES
index c7fa949c287f76c5ab8173d975f6da3dd92e6802..cf0689cfeb8b5122f8fa20345d9f5307fee1cd6c 100644 (file)
@@ -332,11 +332,11 @@ alice$ git log -p HEAD..FETCH_HEAD
 ------------------------------------------------
 
 This operation is safe even if Alice has uncommitted local changes.
-The range notation HEAD..FETCH_HEAD" means "show everything that is reachable
-from the FETCH_HEAD but exclude anything that is reachable from HEAD.
+The range notation "HEAD..FETCH_HEAD" means "show everything that is reachable
+from the FETCH_HEAD but exclude anything that is reachable from HEAD".
 Alice already knows everything that leads to her current state (HEAD),
-and reviewing what Bob has in his state (FETCH_HEAD) that she has not
-seen with this command
+and reviews what Bob has in his state (FETCH_HEAD) that she has not
+seen with this command.
 
 If Alice wants to visualize what Bob did since their histories forked
 she can issue the following command:
@@ -375,9 +375,9 @@ it easier:
 alice$ git remote add bob /home/bob/myrepo
 ------------------------------------------------
 
-With this, Alice can perform the first part of the "pull" operation alone using the
-'git-fetch' command without merging them with her own branch,
-using:
+With this, Alice can perform the first part of the "pull" operation
+alone using the 'git-fetch' command without merging them with her own
+branch, using:
 
 -------------------------------------
 alice$ git fetch bob
@@ -566,22 +566,22 @@ $ git log v2.5.. Makefile       # commits since v2.5 which modify
 
 You can also give 'git-log' a "range" of commits where the first is not
 necessarily an ancestor of the second; for example, if the tips of
-the branches "stable-release" and "master" diverged from a common
+the branches "stable" and "master" diverged from a common
 commit some time ago, then
 
 -------------------------------------
-$ git log stable..experimental
+$ git log stable..master
 -------------------------------------
 
-will list commits made in the experimental branch but not in the
+will list commits made in the master branch but not in the
 stable branch, while
 
 -------------------------------------
-$ git log experimental..stable
+$ git log master..stable
 -------------------------------------
 
 will show the list of commits made on the stable branch but not
-the experimental branch.
+the master branch.
 
 The 'git-log' command has a weakness: it must present commits in a
 list.  When the history has lines of development that diverged and
index 073b22bd83badb5aada47e061bb29e48d5f95518..c54b17db69b8420bdec7c6ee0f424a5216957add 100644 (file)
@@ -18,6 +18,10 @@ struct remote
 
        An array of all of the url_nr URLs configured for the remote
 
+`pushurl`::
+
+       An array of all of the pushurl_nr push URLs configured for the remote
+
 `push`::
 
         An array of refspecs configured for pushing, with
index 41ec7774f481fd2d70492be4ab2b5e0bf887fc0b..2a0e7b89441039699a3dc9514f1165cb2112020a 100644 (file)
@@ -27,10 +27,13 @@ config file would appear like this:
 ------------
        [remote "<name>"]
                url = <url>
+               pushurl = <pushurl>
                push = <refspec>
                fetch = <refspec>
 ------------
 
+The `<pushurl>` is used for pushes only. It is optional and defaults
+to `<url>`.
 
 Named file in `$GIT_DIR/remotes`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index 41ab8e9e0db59647b2e872757ec05e86f615ea1c..cdc40d05ca758714e506c0a403790e61fa82125e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1464,7 +1464,7 @@ git-http-push$X: revision.o http.o http-push.o $(GITLIBS)
                $(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
 
 $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
-$(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
+$(patsubst git-%$X,%.o,$(PROGRAMS)) git.o: $(LIB_H) $(wildcard */*.h)
 builtin-revert.o wt-status.o: wt-status.h
 
 $(LIB_FILE): $(LIB_OBJS)
diff --git a/attr.c b/attr.c
index 98eb636f13d314c20e18e646c074e2511b3c891c..55bdb7cdebea7f7ea551231fe7801f272d128d69 100644 (file)
--- a/attr.c
+++ b/attr.c
@@ -35,8 +35,7 @@ static struct git_attr *(git_attr_hash[HASHSIZE]);
 
 static unsigned hash_name(const char *name, int namelen)
 {
-       unsigned val = 0;
-       unsigned char c;
+       unsigned val = 0, c;
 
        while (namelen--) {
                c = *name++;
@@ -556,6 +555,8 @@ static void prepare_attr_stack(const char *path, int dirlen)
                }
        }
 
+       strbuf_release(&pathbuf);
+
        /*
         * Finally push the "info" one at the top of the stack.
         */
index b88270f90844095b3d352cc4213cbebd95a7f420..b417a15bbc83fff7180078a4cf9f73603477a295 100644 (file)
--- a/base85.c
+++ b/base85.c
@@ -91,7 +91,7 @@ void encode_85(char *buf, const unsigned char *data, int bytes)
                unsigned acc = 0;
                int cnt;
                for (cnt = 24; cnt >= 0; cnt -= 8) {
-                       int ch = *data++;
+                       unsigned ch = *data++;
                        acc |= ch << cnt;
                        if (--bytes == 0)
                                break;
index 6fdff05722c3afa8e8e4cdcac200697e4116ea8e..dbeb28752adce639d8729fa7cbb003fc31bd240f 100644 (file)
--- a/bisect.c
+++ b/bisect.c
@@ -454,7 +454,7 @@ static int read_bisect_refs(void)
        return for_each_ref_in("refs/bisect/", register_ref, NULL);
 }
 
-void read_bisect_paths(struct argv_array *array)
+static void read_bisect_paths(struct argv_array *array)
 {
        struct strbuf str = STRBUF_INIT;
        const char *filename = git_path("BISECT_NAMES");
@@ -780,7 +780,7 @@ static void handle_bad_merge_base(void)
        exit(1);
 }
 
-void handle_skipped_merge_base(const unsigned char *mb)
+static void handle_skipped_merge_base(const unsigned char *mb)
 {
        char *mb_hex = sha1_to_hex(mb);
        char *bad_hex = sha1_to_hex(current_bad_sha1);
index c1b229a9d8a026ec88cdbf0492856021cacc8097..4e44148e05843e03befc167f6bdf3a1567d3f8ad 100644 (file)
@@ -189,7 +189,7 @@ int interactive_add(int argc, const char **argv, const char *prefix)
        return status;
 }
 
-int edit_patch(int argc, const char **argv, const char *prefix)
+static int edit_patch(int argc, const char **argv, const char *prefix)
 {
        char *file = xstrdup(git_path("ADD_EDIT.patch"));
        const char *apply_argv[] = { "apply", "--recount", "--cached",
@@ -298,6 +298,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
        int add_new_files;
        int require_pathspec;
 
+       git_config(add_config, NULL);
+
        argc = parse_options(argc, argv, prefix, builtin_add_options,
                          builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
        if (patch_interactive)
@@ -305,8 +307,6 @@ int cmd_add(int argc, const char **argv, const char *prefix)
        if (add_interactive)
                exit(interactive_add(argc - 1, argv + 1, prefix));
 
-       git_config(add_config, NULL);
-
        if (edit_interactive)
                return(edit_patch(argc, argv, prefix));
        argc--;
index 94ba2bdd5bdf0bc2f9924fc8f73c98f0bb159134..4cf819c7905d5997a6ce2a89b4ecce1176a4b045 100644 (file)
@@ -2614,7 +2614,7 @@ static int get_current_sha1(const char *path, unsigned char *sha1)
 static void build_fake_ancestor(struct patch *list, const char *filename)
 {
        struct patch *patch;
-       struct index_state result = { 0 };
+       struct index_state result = { NULL };
        int fd;
 
        /* Once we start supporting the reverse patch, it may be
@@ -3277,9 +3277,11 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
                OPT_BOOLEAN(0, "stat", &diffstat,
                        "instead of applying the patch, output diffstat for the input"),
                { OPTION_BOOLEAN, 0, "allow-binary-replacement", &binary,
-                 NULL, "old option, now no-op", PARSE_OPT_HIDDEN },
+                 NULL, "old option, now no-op",
+                 PARSE_OPT_HIDDEN | PARSE_OPT_NOARG },
                { OPTION_BOOLEAN, 0, "binary", &binary,
-                 NULL, "old option, now no-op", PARSE_OPT_HIDDEN },
+                 NULL, "old option, now no-op",
+                 PARSE_OPT_HIDDEN | PARSE_OPT_NOARG },
                OPT_BOOLEAN(0, "numstat", &numstat,
                        "shows number of added and deleted lines in decimal notation"),
                OPT_BOOLEAN(0, "summary", &summary,
index 5c46496a43a8fe2f91b395563b266e79a8b94429..2ceacb7b3f34c78e64ed047833d8af5a061f065f 100644 (file)
@@ -141,7 +141,7 @@ static char *guess_dir_name(const char *repo, int is_bundle, int is_bare)
        if (is_bare) {
                struct strbuf result = STRBUF_INIT;
                strbuf_addf(&result, "%.*s.git", (int)(end - start), start);
-               dir = strbuf_detach(&result, 0);
+               dir = strbuf_detach(&result, NULL);
        } else
                dir = xstrndup(start, end - start);
        /*
index 784733b25d21f292c6ac895ba34d0a7b88b3073f..d7cc8cafbfb4ea39e347828013b28d21cfe2be74 100644 (file)
@@ -561,14 +561,6 @@ static void populate_value(struct refinfo *ref)
 
        ref->value = xcalloc(sizeof(struct atom_value), used_atom_cnt);
 
-       buf = get_obj(ref->objectname, &obj, &size, &eaten);
-       if (!buf)
-               die("missing object %s for %s",
-                   sha1_to_hex(ref->objectname), ref->refname);
-       if (!obj)
-               die("parse_object_buffer failed on %s for %s",
-                   sha1_to_hex(ref->objectname), ref->refname);
-
        /* Fill in specials first */
        for (i = 0; i < used_atom_cnt; i++) {
                const char *name = used_atom[i];
@@ -621,6 +613,22 @@ static void populate_value(struct refinfo *ref)
                }
        }
 
+       for (i = 0; i < used_atom_cnt; i++) {
+               struct atom_value *v = &ref->value[i];
+               if (v->s == NULL)
+                       goto need_obj;
+       }
+       return;
+
+ need_obj:
+       buf = get_obj(ref->objectname, &obj, &size, &eaten);
+       if (!buf)
+               die("missing object %s for %s",
+                   sha1_to_hex(ref->objectname), ref->refname);
+       if (!obj)
+               die("parse_object_buffer failed on %s for %s",
+                   sha1_to_hex(ref->objectname), ref->refname);
+
        grab_values(ref->value, 0, obj, buf, size);
        if (!eaten)
                free(buf);
@@ -926,7 +934,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
 
        memset(&cbdata, 0, sizeof(cbdata));
        cbdata.grab_pattern = argv;
-       for_each_ref(grab_single_ref, &cbdata);
+       for_each_rawref(grab_single_ref, &cbdata);
        refs = cbdata.grab_array;
        num_refs = cbdata.grab_cnt;
 
index 7da706cac3bef05f03c09955d41b4e5077558d4f..e077e72dea94892e2f74ddd6be528b02bc6ccea4 100644 (file)
@@ -104,7 +104,7 @@ static int mark_object(struct object *obj, int type, void *data)
 
 static void mark_object_reachable(struct object *obj)
 {
-       mark_object(obj, OBJ_ANY, 0);
+       mark_object(obj, OBJ_ANY, NULL);
 }
 
 static int traverse_one_object(struct object *obj, struct object *parent)
@@ -292,7 +292,7 @@ static int fsck_sha1(const unsigned char *sha1)
                fprintf(stderr, "Checking %s %s\n",
                        typename(obj->type), sha1_to_hex(obj->sha1));
 
-       if (fsck_walk(obj, mark_used, 0))
+       if (fsck_walk(obj, mark_used, NULL))
                objerror(obj, "broken links");
        if (fsck_object(obj, check_strict, fsck_error_func))
                return -1;
index 6e53b23833062249485124b827da348a8be206b0..e1eba778a526f500b0a65a6b112e468f04a3f869 100644 (file)
@@ -394,7 +394,7 @@ static void get_html_page_path(struct strbuf *page_path, const char *page)
  * HTML.
  */
 #ifndef open_html
-void open_html(const char *path)
+static void open_html(const char *path)
 {
        execl_git_cmd("web--browse", "-c", "help.browser", path, NULL);
 }
index 0d34050556855d6bab8b4c4121e833cc326324df..44f9a27daec612db6d0f0e502c99d5e5ecaaf842 100644 (file)
@@ -94,7 +94,7 @@ static void show_early_header(struct rev_info *rev, const char *stage, int nr)
        printf("Final output: %d %s\n", nr, stage);
 }
 
-struct itimerval early_output_timer;
+static struct itimerval early_output_timer;
 
 static void log_show_early(struct rev_info *revs, struct commit_list *list)
 {
@@ -977,7 +977,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                strbuf_addch(&buf, '\n');
        }
 
-       rev.extra_headers = strbuf_detach(&buf, 0);
+       rev.extra_headers = strbuf_detach(&buf, NULL);
 
        if (start_number < 0)
                start_number = 1;
index 793f2f4a189e448fb481c5c1e2886be28fddf2e2..af9adab300de98026b23a58b1d8b40f9395ff11a 100644 (file)
@@ -370,7 +370,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
 
        strbuf_addstr(&buf, "refs/heads/");
        strbuf_addstr(&buf, remote);
-       resolve_ref(buf.buf, branch_head, 0, 0);
+       resolve_ref(buf.buf, branch_head, 0, NULL);
 
        if (!hashcmp(remote_head->sha1, branch_head)) {
                strbuf_addf(msg, "%s\t\tbranch '%s' of .\n",
@@ -409,7 +409,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
                strbuf_addstr(&truname, "refs/heads/");
                strbuf_addstr(&truname, remote);
                strbuf_setlen(&truname, truname.len - len);
-               if (resolve_ref(truname.buf, buf_sha, 0, 0)) {
+               if (resolve_ref(truname.buf, buf_sha, 0, NULL)) {
                        strbuf_addf(msg,
                                    "%s\t\tbranch '%s'%s of .\n",
                                    sha1_to_hex(remote_head->sha1),
index 8b81d4b51d78bb2aa49430102ab585afce9cccdf..68f47384dc1cc6404d4db73b6dbea8bceab38df9 100644 (file)
@@ -24,14 +24,10 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec,
        result[count] = NULL;
        for (i = 0; i < count; i++) {
                int length = strlen(result[i]);
-               if (length > 0 && result[i][length - 1] == '/') {
+               if (length > 0 && is_dir_sep(result[i][length - 1]))
                        result[i] = xmemdupz(result[i], length - 1);
-               }
-               if (base_name) {
-                       const char *last_slash = strrchr(result[i], '/');
-                       if (last_slash)
-                               result[i] = last_slash + 1;
-               }
+               if (base_name)
+                       result[i] = basename((char *)result[i]);
        }
        return get_pathspec(prefix, result);
 }
index 9742b45c4da7f9330491d0b4c6d3ed60aadb0f4c..941cc2d73cf5ee6791a0cee8c409dcdb9756b448 100644 (file)
@@ -653,8 +653,7 @@ static void rehash_objects(void)
 
 static unsigned name_hash(const char *name)
 {
-       unsigned char c;
-       unsigned hash = 0;
+       unsigned c, hash = 0;
 
        if (!name)
                return 0;
index c869974013b5c1bb563d4f9b306820362545c9ea..7be12399b6d95c63efd9102df7967dca61655063 100644 (file)
@@ -117,6 +117,8 @@ static int do_push(const char *repo, int flags)
 {
        int i, errs;
        struct remote *remote = remote_get(repo);
+       const char **url;
+       int url_nr;
 
        if (!remote) {
                if (repo)
@@ -152,9 +154,16 @@ static int do_push(const char *repo, int flags)
                        setup_default_push_refspecs();
        }
        errs = 0;
-       for (i = 0; i < remote->url_nr; i++) {
+       if (remote->pushurl_nr) {
+               url = remote->pushurl;
+               url_nr = remote->pushurl_nr;
+       } else {
+               url = remote->url;
+               url_nr = remote->url_nr;
+       }
+       for (i = 0; i < url_nr; i++) {
                struct transport *transport =
-                       transport_get(remote, remote->url[i]);
+                       transport_get(remote, url[i]);
                int err;
                if (receivepack)
                        transport_set_option(transport,
@@ -163,14 +172,14 @@ static int do_push(const char *repo, int flags)
                        transport_set_option(transport, TRANS_OPT_THIN, "yes");
 
                if (flags & TRANSPORT_PUSH_VERBOSE)
-                       fprintf(stderr, "Pushing to %s\n", remote->url[i]);
+                       fprintf(stderr, "Pushing to %s\n", url[i]);
                err = transport_push(transport, refspec_nr, refspec, flags);
                err |= transport_disconnect(transport);
 
                if (!err)
                        continue;
 
-               error("failed to push some refs to '%s'", remote->url[i]);
+               error("failed to push some refs to '%s'", url[i]);
                errs++;
        }
        return !!errs;
index dfc0b9e706507fc557cc2b593632fda4683387bc..2fb76d32f86cb4e699036b40eac9bd9a747fb77f 100644 (file)
@@ -740,7 +740,7 @@ static int rm(int argc, const char **argv)
        return result;
 }
 
-void clear_push_info(void *util, const char *string)
+static void clear_push_info(void *util, const char *string)
 {
        struct push_info *info = util;
        free(info->dest);
@@ -815,7 +815,7 @@ struct show_info {
        int any_rebase;
 };
 
-int add_remote_to_show_info(struct string_list_item *item, void *cb_data)
+static int add_remote_to_show_info(struct string_list_item *item, void *cb_data)
 {
        struct show_info *info = cb_data;
        int n = strlen(item->string);
@@ -825,7 +825,7 @@ int add_remote_to_show_info(struct string_list_item *item, void *cb_data)
        return 0;
 }
 
-int show_remote_info_item(struct string_list_item *item, void *cb_data)
+static int show_remote_info_item(struct string_list_item *item, void *cb_data)
 {
        struct show_info *info = cb_data;
        struct ref_states *states = info->states;
@@ -852,7 +852,7 @@ int show_remote_info_item(struct string_list_item *item, void *cb_data)
        return 0;
 }
 
-int add_local_to_show_info(struct string_list_item *branch_item, void *cb_data)
+static int add_local_to_show_info(struct string_list_item *branch_item, void *cb_data)
 {
        struct show_info *show_info = cb_data;
        struct ref_states *states = show_info->states;
@@ -874,7 +874,7 @@ int add_local_to_show_info(struct string_list_item *branch_item, void *cb_data)
        return 0;
 }
 
-int show_local_info_item(struct string_list_item *item, void *cb_data)
+static int show_local_info_item(struct string_list_item *item, void *cb_data)
 {
        struct show_info *show_info = cb_data;
        struct branch_info *branch_info = item->util;
@@ -906,7 +906,7 @@ int show_local_info_item(struct string_list_item *item, void *cb_data)
        return 0;
 }
 
-int add_push_to_show_info(struct string_list_item *push_item, void *cb_data)
+static int add_push_to_show_info(struct string_list_item *push_item, void *cb_data)
 {
        struct show_info *show_info = cb_data;
        struct push_info *push_info = push_item->util;
@@ -935,7 +935,7 @@ static int cmp_string_with_push(const void *va, const void *vb)
        return cmp ? cmp : strcmp(a_push->dest, b_push->dest);
 }
 
-int show_push_info_item(struct string_list_item *item, void *cb_data)
+static int show_push_info_item(struct string_list_item *item, void *cb_data)
 {
        struct show_info *show_info = cb_data;
        struct push_info *push_info = item->util;
@@ -999,15 +999,25 @@ static int show(int argc, const char **argv)
        info.list = &info_list;
        for (; argc; argc--, argv++) {
                int i;
+               const char **url;
+               int url_nr;
 
                get_remote_ref_states(*argv, &states, query_flag);
 
                printf("* remote %s\n", *argv);
-               if (states.remote->url_nr) {
-                       for (i=0; i < states.remote->url_nr; i++)
-                               printf("  URL: %s\n", states.remote->url[i]);
-               } else
-                       printf("  URL: %s\n", "(no URL)");
+               printf("  Fetch URL: %s\n", states.remote->url_nr > 0 ?
+                       states.remote->url[0] : "(no URL)");
+               if (states.remote->pushurl_nr) {
+                       url = states.remote->pushurl;
+                       url_nr = states.remote->pushurl_nr;
+               } else {
+                       url = states.remote->url;
+                       url_nr = states.remote->url_nr;
+               }
+               for (i=0; i < url_nr; i++)
+                       printf("  Push  URL: %s\n", url[i]);
+               if (!i)
+                       printf("  Push  URL: %s\n", "(no URL)");
                if (no_query)
                        printf("  HEAD branch: (not queried)\n");
                else if (!states.heads.nr)
@@ -1187,7 +1197,7 @@ static int get_one_remote_for_update(struct remote *remote, void *priv)
        return 0;
 }
 
-struct remote_group {
+static struct remote_group {
        const char *name;
        struct string_list *list;
 } remote_group;
@@ -1266,14 +1276,29 @@ static int update(int argc, const char **argv)
 static int get_one_entry(struct remote *remote, void *priv)
 {
        struct string_list *list = priv;
+       struct strbuf url_buf = STRBUF_INIT;
+       const char **url;
+       int i, url_nr;
 
        if (remote->url_nr > 0) {
-               int i;
-
-               for (i = 0; i < remote->url_nr; i++)
-                       string_list_append(remote->name, list)->util = (void *)remote->url[i];
+               strbuf_addf(&url_buf, "%s (fetch)", remote->url[0]);
+               string_list_append(remote->name, list)->util =
+                               strbuf_detach(&url_buf, NULL);
        } else
                string_list_append(remote->name, list)->util = NULL;
+       if (remote->pushurl_nr) {
+               url = remote->pushurl;
+               url_nr = remote->pushurl_nr;
+       } else {
+               url = remote->url;
+               url_nr = remote->url_nr;
+       }
+       for (i = 0; i < url_nr; i++)
+       {
+               strbuf_addf(&url_buf, "%s (push)", url[i]);
+               string_list_append(remote->name, list)->util =
+                               strbuf_detach(&url_buf, NULL);
+       }
 
        return 0;
 }
@@ -1281,7 +1306,10 @@ static int get_one_entry(struct remote *remote, void *priv)
 static int show_all(void)
 {
        struct string_list list = { NULL, 0, 0 };
-       int result = for_each_remote(get_one_entry, &list);
+       int result;
+
+       list.strdup_strings = 1;
+       result = for_each_remote(get_one_entry, &list);
 
        if (!result) {
                int i;
@@ -1299,6 +1327,7 @@ static int show_all(void)
                        }
                }
        }
+       string_list_clear(&list, 1);
        return result;
 }
 
index dc3db628115cc7b3c62c1d54af37c87ba126a5db..080e04a8fc6fc1fc3f10f59a4c1f1aa067b81aa1 100644 (file)
@@ -376,8 +376,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
        struct commit_list *with_commit = NULL;
        struct option options[] = {
                OPT_BOOLEAN('l', NULL, &list, "list tag names"),
-               { OPTION_INTEGER, 'n', NULL, &lines, NULL,
-                               "print n lines of each tag message",
+               { OPTION_INTEGER, 'n', NULL, &lines, "n",
+                               "print <n> lines of each tag message",
                                PARSE_OPT_OPTARG, NULL, 1 },
                OPT_BOOLEAN('d', NULL, &delete, "delete tags"),
                OPT_BOOLEAN('v', NULL, &verify, "verify tags"),
index 9a773239cabab9998bcea829c0fb2abea9bdb8e8..7e3ea73006ecdc74c03580ac7297be4ebee174b3 100644 (file)
@@ -158,7 +158,7 @@ struct obj_info {
 #define FLAG_WRITTEN (1u<<21)
 
 static struct obj_info *obj_list;
-unsigned nr_objects;
+static unsigned nr_objects;
 
 /*
  * Called only from check_object() after it verified this object
@@ -200,7 +200,7 @@ static int check_object(struct object *obj, int type, void *data)
 
        if (fsck_object(obj, 1, fsck_error_function))
                die("Error in object");
-       if (!fsck_walk(obj, check_object, 0))
+       if (!fsck_walk(obj, check_object, NULL))
                die("Error on reachable objects of %s", sha1_to_hex(obj->sha1));
        write_cached_object(obj);
        return 1;
@@ -210,7 +210,7 @@ static void write_rest(void)
 {
        unsigned i;
        for (i = 0; i < nr_objects; i++)
-               check_object(obj_list[i].obj, OBJ_ANY, 0);
+               check_object(obj_list[i].obj, OBJ_ANY, NULL);
 }
 
 static void added_object(unsigned nr, enum object_type type,
@@ -422,8 +422,8 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
 static void unpack_one(unsigned nr)
 {
        unsigned shift;
-       unsigned char *pack, c;
-       unsigned long size;
+       unsigned char *pack;
+       unsigned long size, c;
        enum object_type type;
 
        obj_list[nr].offset = consumed_bytes;
index 0206b416cbf08ae4c1b0d753784fb0b61bac46a1..c4cd1e1327f18ae27b74fac6dfd41938cd9dfe5d 100644 (file)
@@ -80,16 +80,17 @@ static void error_clnt(const char *fmt, ...)
        die("sent error to the client: %s", buf);
 }
 
-static void process_input(int child_fd, int band)
+static ssize_t process_input(int child_fd, int band)
 {
        char buf[16384];
        ssize_t sz = read(child_fd, buf, sizeof(buf));
        if (sz < 0) {
                if (errno != EAGAIN && errno != EINTR)
                        error_clnt("read error: %s\n", strerror(errno));
-               return;
+               return sz;
        }
        send_sideband(1, band, buf, sz, LARGE_PACKET_MAX);
+       return sz;
 }
 
 int cmd_upload_archive(int argc, const char **argv, const char *prefix)
@@ -131,6 +132,7 @@ int cmd_upload_archive(int argc, const char **argv, const char *prefix)
 
        while (1) {
                struct pollfd pfd[2];
+               ssize_t processed[2] = { 0, 0 };
                int status;
 
                pfd[0].fd = fd1[0];
@@ -147,12 +149,12 @@ int cmd_upload_archive(int argc, const char **argv, const char *prefix)
                }
                if (pfd[0].revents & POLLIN)
                        /* Data stream ready */
-                       process_input(pfd[0].fd, 1);
+                       processed[0] = process_input(pfd[0].fd, 1);
                if (pfd[1].revents & POLLIN)
                        /* Status stream ready */
-                       process_input(pfd[1].fd, 2);
+                       processed[1] = process_input(pfd[1].fd, 2);
                /* Always finish to read data when available */
-               if ((pfd[0].revents | pfd[1].revents) & POLLIN)
+               if (processed[0] || processed[1])
                        continue;
 
                if (waitpid(writer, &status, 0) < 0)
index 9d640508dd8eb62201b286490b7f83486470d611..3a24ce8157be7c4209d831027693653b8d65ca13 100644 (file)
@@ -13,7 +13,7 @@ static const char write_tree_usage[] =
 
 int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
 {
-       int missing_ok = 0, ret;
+       int flags = 0, ret;
        const char *prefix = NULL;
        unsigned char sha1[20];
        const char *me = "git-write-tree";
@@ -22,9 +22,15 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
        while (1 < argc) {
                const char *arg = argv[1];
                if (!strcmp(arg, "--missing-ok"))
-                       missing_ok = 1;
+                       flags |= WRITE_TREE_MISSING_OK;
                else if (!prefixcmp(arg, "--prefix="))
                        prefix = arg + 9;
+               else if (!prefixcmp(arg, "--ignore-cache-tree"))
+                       /*
+                        * This is only useful for debugging, so I
+                        * do not bother documenting it.
+                        */
+                       flags |= WRITE_TREE_IGNORE_CACHE_TREE;
                else
                        usage(write_tree_usage);
                argc--; argv++;
@@ -33,7 +39,7 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
        if (argc > 2)
                die("too many options");
 
-       ret = write_cache_as_tree(sha1, missing_ok, prefix);
+       ret = write_cache_as_tree(sha1, flags, prefix);
        switch (ret) {
        case 0:
                printf("%s\n", sha1_to_hex(sha1));
index 37bf35e636f0966662416f0693dbea5c1cc73311..16a65dfac11eccc68acb4a0ed472761f3f84f9c4 100644 (file)
@@ -514,6 +514,8 @@ struct cache_tree *cache_tree_read(const char *buffer, unsigned long size)
 
 static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *path)
 {
+       if (!it)
+               return NULL;
        while (*path) {
                const char *slash;
                struct cache_tree_sub *sub;
@@ -538,28 +540,32 @@ static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *pat
        return it;
 }
 
-int write_cache_as_tree(unsigned char *sha1, int missing_ok, const char *prefix)
+int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix)
 {
        int entries, was_valid, newfd;
+       struct lock_file *lock_file;
 
        /*
         * We can't free this memory, it becomes part of a linked list
         * parsed atexit()
         */
-       struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
+       lock_file = xcalloc(1, sizeof(struct lock_file));
 
        newfd = hold_locked_index(lock_file, 1);
 
        entries = read_cache();
        if (entries < 0)
                return WRITE_TREE_UNREADABLE_INDEX;
+       if (flags & WRITE_TREE_IGNORE_CACHE_TREE)
+               cache_tree_free(&(active_cache_tree));
 
        if (!active_cache_tree)
                active_cache_tree = cache_tree();
 
        was_valid = cache_tree_fully_valid(active_cache_tree);
-
        if (!was_valid) {
+               int missing_ok = flags & WRITE_TREE_MISSING_OK;
+
                if (cache_tree_update(active_cache_tree,
                                      active_cache, active_nr,
                                      missing_ok, 0) < 0)
@@ -625,3 +631,35 @@ void prime_cache_tree(struct cache_tree **it, struct tree *tree)
        *it = cache_tree();
        prime_cache_tree_rec(*it, tree);
 }
+
+/*
+ * find the cache_tree that corresponds to the current level without
+ * exploding the full path into textual form.  The root of the
+ * cache tree is given as "root", and our current level is "info".
+ * (1) When at root level, info->prev is NULL, so it is "root" itself.
+ * (2) Otherwise, find the cache_tree that corresponds to one level
+ *     above us, and find ourselves in there.
+ */
+static struct cache_tree *find_cache_tree_from_traversal(struct cache_tree *root,
+                                                        struct traverse_info *info)
+{
+       struct cache_tree *our_parent;
+
+       if (!info->prev)
+               return root;
+       our_parent = find_cache_tree_from_traversal(root, info->prev);
+       return cache_tree_find(our_parent, info->name.path);
+}
+
+int cache_tree_matches_traversal(struct cache_tree *root,
+                                struct name_entry *ent,
+                                struct traverse_info *info)
+{
+       struct cache_tree *it;
+
+       it = find_cache_tree_from_traversal(root, info);
+       it = cache_tree_find(it, ent->path);
+       if (it && it->entry_count > 0 && !hashcmp(ent->sha1, it->sha1))
+               return it->entry_count;
+       return 0;
+}
index e95883523633a51f833683e96af1738da2868238..3df641f59311f43aa951a2cdfa9f110b97b13a45 100644 (file)
@@ -2,6 +2,7 @@
 #define CACHE_TREE_H
 
 #include "tree.h"
+#include "tree-walk.h"
 
 struct cache_tree;
 struct cache_tree_sub {
@@ -30,11 +31,18 @@ struct cache_tree *cache_tree_read(const char *buffer, unsigned long size);
 int cache_tree_fully_valid(struct cache_tree *);
 int cache_tree_update(struct cache_tree *, struct cache_entry **, int, int, int);
 
+/* bitmasks to write_cache_as_tree flags */
+#define WRITE_TREE_MISSING_OK 1
+#define WRITE_TREE_IGNORE_CACHE_TREE 2
+
+/* error return codes */
 #define WRITE_TREE_UNREADABLE_INDEX (-1)
 #define WRITE_TREE_UNMERGED_INDEX (-2)
 #define WRITE_TREE_PREFIX_ERROR (-3)
 
-int write_cache_as_tree(unsigned char *sha1, int missing_ok, const char *prefix);
+int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix);
 void prime_cache_tree(struct cache_tree **, struct tree *);
 
+extern int cache_tree_matches_traversal(struct cache_tree *, struct name_entry *ent, struct traverse_info *info);
+
 #endif
index 7937e604be34eadddc314c0eff0cea226af19c9c..1885674e396d31cc625d34d029835e15b279dc8d 100644 (file)
@@ -385,6 +385,8 @@ AC_SUBST(NO_EXPAT)
 # some Solaris installations).
 # Define NO_ICONV if neither libc nor libiconv support iconv.
 
+if test -z "$NO_ICONV"; then
+
 GIT_STASH_FLAGS($ICONVDIR)
 
 AC_DEFUN([ICONVTEST_SRC], [
@@ -431,6 +433,12 @@ GIT_UNSTASH_FLAGS($ICONVDIR)
 AC_SUBST(NEEDS_LIBICONV)
 AC_SUBST(NO_ICONV)
 
+if test -n "$NO_ICONV"; then
+    NEEDS_LIBICONV=
+fi
+
+fi
+
 #
 # Define NO_DEFLATE_BOUND if deflateBound is missing from zlib.
 
index 0ce941ef444277957efdd8a359a568775e2b17a4..76e542776abff8d07e7250ecfc8c7ae813302b2d 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -464,7 +464,7 @@ static void git_proxy_connect(int fd[2], char *host)
 
 #define MAX_CMD_LEN 1024
 
-char *get_port(char *host)
+static char *get_port(char *host)
 {
        char *end;
        char *p = strchr(host, ':');
index 80ab4e45eb108898eb80caa32684c3f1308ab3a8..ddb71e26fe8e465dbfa60fa948a01d5ff5c0818b 100755 (executable)
@@ -1299,7 +1299,7 @@ _git_rebase ()
 }
 
 __git_send_email_confirm_options="always never auto cc compose"
-__git_send_email_suppresscc_options="author self cc ccbody sob cccmd body all"
+__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
 
 _git_send_email ()
 {
@@ -1457,7 +1457,7 @@ _git_config ()
        branch.*.*)
                local pfx="${cur%.*}."
                cur="${cur##*.}"
-               __gitcomp "remote merge mergeoptions" "$pfx" "$cur"
+               __gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur"
                return
                ;;
        branch.*)
@@ -1504,7 +1504,7 @@ _git_config ()
                cur="${cur##*.}"
                __gitcomp "
                        url proxy fetch push mirror skipDefaultUpdate
-                       receivepack uploadpack tagopt
+                       receivepack uploadpack tagopt pushurl
                        " "$pfx" "$cur"
                return
                ;;
@@ -1522,6 +1522,7 @@ _git_config ()
                ;;
        esac
        __gitcomp "
+               add.ignore-errors
                alias.
                apply.whitespace
                branch.autosetupmerge
index 6309d146e74a428520d09cbff4dc8d9a429ec001..78e40d2a13e5c754b10a8e68641236bf58394e05 100755 (executable)
@@ -82,10 +82,16 @@ foreach my $tar_file (@ARGV)
                $mtime = oct $mtime;
                next if $typeflag == 5; # directory
 
-               print FI "blob\n", "mark :$next_mark\n", "data $size\n";
-               while ($size > 0 && read(I, $_, 512) == 512) {
-                       print FI substr($_, 0, $size);
-                       $size -= 512;
+               print FI "blob\n", "mark :$next_mark\n";
+               if ($typeflag == 2) { # symbolic link
+                       print FI "data ", length($linkname), "\n", $linkname;
+                       $mode = 0120000;
+               } else {
+                       print FI "data $size\n";
+                       while ($size > 0 && read(I, $_, 512) == 512) {
+                               print FI substr($_, 0, $size);
+                               $size -= 512;
+                       }
                }
                print FI "\n";
 
@@ -118,7 +124,8 @@ EOF
        {
                my ($mark, $mode) = @{$files{$path}};
                $path =~ s,^([^/]+)/,, if $have_top_dir;
-               printf FI "M %o :%i %s\n", $mode & 0111 ? 0755 : 0644, $mark, $path;
+               $mode = $mode & 0111 ? 0755 : 0644 unless $mode == 0120000;
+               printf FI "M %o :%i %s\n", $mode, $mark, $path;
        }
        print FI "\n";
 
index b2babcc076de65b53671157115e63e74fec83a3e..366db37b39f7dcfb29dbb4e79ad5bcc985b75bc6 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -453,7 +453,7 @@ static void parse_host_arg(char *extra_args, int buflen)
                memset(&hints, 0, sizeof(hints));
                hints.ai_flags = AI_CANONNAME;
 
-               gai = getaddrinfo(hostname, 0, &hints, &ai);
+               gai = getaddrinfo(hostname, NULL, &hints, &ai);
                if (!gai) {
                        struct sockaddr_in *sin_addr = (void *)ai->ai_addr;
 
diff --git a/delta.h b/delta.h
index 40ccf5a1e95f62d840a006274f7024fa43208b1c..b9d333dd5a1c64ab35159ed608cf942951504f84 100644 (file)
--- a/delta.h
+++ b/delta.h
@@ -90,12 +90,11 @@ static inline unsigned long get_delta_hdr_size(const unsigned char **datap,
                                               const unsigned char *top)
 {
        const unsigned char *data = *datap;
-       unsigned char cmd;
-       unsigned long size = 0;
+       unsigned long cmd, size = 0;
        int i = 0;
        do {
                cmd = *data++;
-               size |= (cmd & ~0x80) << i;
+               size |= (cmd & 0x7f) << i;
                i += 7;
        } while (cmd & 0x80 && data < top);
        *datap = data;
index 0aba6cda3c01e17b07bb7235b0395ba50256aedd..ad2a4cde74e0c2ec6367a7128aa0732f131f6bdf 100644 (file)
@@ -446,6 +446,8 @@ int run_diff_index(struct rev_info *revs, int cached)
        memset(&opts, 0, sizeof(opts));
        opts.head_idx = 1;
        opts.index_only = cached;
+       opts.diff_index_cached = (cached &&
+                                 !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER));
        opts.merge = 1;
        opts.fn = oneway_diff;
        opts.unpack_data = revs;
@@ -502,6 +504,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)
        memset(&opts, 0, sizeof(opts));
        opts.head_idx = 1;
        opts.index_only = 1;
+       opts.diff_index_cached = !DIFF_OPT_TST(opt, FIND_COPIES_HARDER);
        opts.merge = 1;
        opts.fn = oneway_diff;
        opts.unpack_data = &revs;
index 9ec1df95c0aa8aba01990362c49ae1c15e2e086f..a36df3392652b8a854ca48bdf71977dcf12b244b 100755 (executable)
@@ -8,9 +8,9 @@ use File::Basename qw(basename dirname);
 use File::Spec;
 use Git;
 
-our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m, $opt_d, $opt_u, $opt_w, $opt_W);
+our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m, $opt_d, $opt_u, $opt_w, $opt_W, $opt_k);
 
-getopts('uhPpvcfam:d:w:W');
+getopts('uhPpvcfkam:d:w:W');
 
 $opt_h && usage();
 
@@ -287,7 +287,26 @@ foreach my $f (@files) {
        $dirty = 1;
        warn "File $f not up to date but has status '$cvsstat{$f}' in your CVS checkout!\n";
     }
+
+    # Depending on how your GIT tree got imported from CVS you may
+    # have a conflict between expanded keywords in your CVS tree and
+    # unexpanded keywords in the patch about to be applied.
+    if ($opt_k) {
+       my $orig_file ="$f.orig";
+       rename $f, $orig_file;
+       open(FILTER_IN, "<$orig_file") or die "Cannot open $orig_file\n";
+       open(FILTER_OUT, ">$f") or die "Cannot open $f\n";
+       while (<FILTER_IN>)
+       {
+           my $line = $_;
+           $line =~ s/\$([A-Z][a-z]+):[^\$]+\$/\$\1\$/g;
+           print FILTER_OUT $line;
+       }
+       close FILTER_IN;
+       close FILTER_OUT;
+    }
 }
+
 if ($dirty) {
     if ($opt_f) {      warn "The tree is not clean -- forced merge\n";
        $dirty = 0;
@@ -391,7 +410,7 @@ sleep(1);
 
 sub usage {
        print STDERR <<END;
-Usage: GIT_DIR=/path/to/.git git cvsexportcommit [-h] [-p] [-v] [-c] [-f] [-u] [-w cvsworkdir] [-m msgprefix] [ parent ] commit
+Usage: GIT_DIR=/path/to/.git git cvsexportcommit [-h] [-p] [-v] [-c] [-f] [-u] [-k] [-w cvsworkdir] [-m msgprefix] [ parent ] commit
 END
        exit(1);
 }
index a296719861ec3b7aab5e530e67dc99b58267a56a..5f47b18141a0758c3d0dae2cfe764495c92139c5 100755 (executable)
@@ -60,205 +60,36 @@ get_default_remote () {
        echo ${origin:-origin}
 }
 
-get_remote_default_refs_for_push () {
-       data_source=$(get_data_source "$1")
-       case "$data_source" in
-       '' | branches | self)
-               ;; # no default push mapping, just send matching refs.
-       config)
-               git config --get-all "remote.$1.push" ;;
-       remotes)
-               sed -ne '/^Push: */{
-                       s///p
-               }' "$GIT_DIR/remotes/$1" ;;
-       *)
-               die "internal error: get-remote-default-ref-for-push $1" ;;
-       esac
-}
-
-# Called from canon_refs_list_for_fetch -d "$remote", which
-# is called from get_remote_default_refs_for_fetch to grok
-# refspecs that are retrieved from the configuration, but not
-# from get_remote_refs_for_fetch when it deals with refspecs
-# supplied on the command line.  $ls_remote_result has the list
-# of refs available at remote.
-#
-# The first token returned is either "explicit" or "glob"; this
-# is to help prevent randomly "globbed" ref from being chosen as
-# a merge candidate
-expand_refs_wildcard () {
-       echo "$ls_remote_result" |
-       git fetch--tool expand-refs-wildcard "-" "$@"
-}
-
-# Subroutine to canonicalize remote:local notation.
-canon_refs_list_for_fetch () {
-       # If called from get_remote_default_refs_for_fetch
-       # leave the branches in branch.${curr_branch}.merge alone,
-       # or the first one otherwise; add prefix . to the rest
-       # to prevent the secondary branches to be merged by default.
-       merge_branches=
-       curr_branch=
-       if test "$1" = "-d"
-       then
-               shift ; remote="$1" ; shift
-               set $(expand_refs_wildcard "$remote" "$@")
-               is_explicit="$1"
-               shift
-               if test "$remote" = "$(get_default_remote)"
-               then
-                       curr_branch=$(git symbolic-ref -q HEAD | \
-                           sed -e 's|^refs/heads/||')
-                       merge_branches=$(git config \
-                           --get-all "branch.${curr_branch}.merge")
-               fi
-               if test -z "$merge_branches" && test $is_explicit != explicit
-               then
-                       merge_branches=..this.will.never.match.any.ref..
-               fi
-       fi
-       for ref
-       do
-               force=
-               case "$ref" in
-               +*)
-                       ref=$(expr "z$ref" : 'z+\(.*\)')
-                       force=+
-                       ;;
-               esac
-               expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:"
-               remote=$(expr "z$ref" : 'z\([^:]*\):')
-               local=$(expr "z$ref" : 'z[^:]*:\(.*\)')
-               dot_prefix=.
-               if test -z "$merge_branches"
-               then
-                       merge_branches=$remote
-                       dot_prefix=
-               else
-                       for merge_branch in $merge_branches
-                       do
-                           [ "$remote" = "$merge_branch" ] &&
-                           dot_prefix= && break
-                       done
-               fi
-               case "$remote" in
-               '' | HEAD ) remote=HEAD ;;
-               refs/*) ;;
-               heads/* | tags/* | remotes/* ) remote="refs/$remote" ;;
-               *) remote="refs/heads/$remote" ;;
-               esac
-               case "$local" in
-               '') local= ;;
-               refs/*) ;;
-               heads/* | tags/* | remotes/* ) local="refs/$local" ;;
-               *) local="refs/heads/$local" ;;
-               esac
-
-               if local_ref_name=$(expr "z$local" : 'zrefs/\(.*\)')
-               then
-                  git check-ref-format "$local_ref_name" ||
-                  die "* refusing to create funny ref '$local_ref_name' locally"
-               fi
-               echo "${dot_prefix}${force}${remote}:${local}"
-       done
-}
-
-# Returns list of src: (no store), or src:dst (store)
-get_remote_default_refs_for_fetch () {
-       data_source=$(get_data_source "$1")
-       case "$data_source" in
-       '')
-               echo "HEAD:" ;;
-       self)
-               canon_refs_list_for_fetch -d "$1" \
-                       $(git for-each-ref --format='%(refname):')
-               ;;
-       config)
-               canon_refs_list_for_fetch -d "$1" \
-                       $(git config --get-all "remote.$1.fetch") ;;
-       branches)
-               remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1")
-               case "$remote_branch" in '') remote_branch=master ;; esac
-               echo "refs/heads/${remote_branch}:refs/heads/$1"
-               ;;
-       remotes)
-               canon_refs_list_for_fetch -d "$1" $(sed -ne '/^Pull: */{
-                                               s///p
-                                       }' "$GIT_DIR/remotes/$1")
-               ;;
-       *)
-               die "internal error: get-remote-default-ref-for-fetch $1" ;;
-       esac
-}
-
-get_remote_refs_for_push () {
+get_remote_merge_branch () {
        case "$#" in
-       0) die "internal error: get-remote-refs-for-push." ;;
-       1) get_remote_default_refs_for_push "$@" ;;
-       *) shift; echo "$@" ;;
-       esac
-}
-
-get_remote_refs_for_fetch () {
-       case "$#" in
-       0)
-           die "internal error: get-remote-refs-for-fetch." ;;
-       1)
-           get_remote_default_refs_for_fetch "$@" ;;
-       *)
-           shift
-           tag_just_seen=
-           for ref
-           do
-               if test "$tag_just_seen"
-               then
-                   echo "refs/tags/${ref}:refs/tags/${ref}"
-                   tag_just_seen=
-                   continue
-               else
-                   case "$ref" in
-                   tag)
-                       tag_just_seen=yes
-                       continue
-                       ;;
-                   esac
-               fi
-               canon_refs_list_for_fetch "$ref"
-           done
+       0|1)
+           origin="$1"
+           default=$(get_default_remote)
+           test -z "$origin" && origin=$default
+           curr_branch=$(git symbolic-ref -q HEAD)
+           [ "$origin" = "$default" ] &&
+           echo $(git for-each-ref --format='%(upstream)' $curr_branch)
            ;;
-       esac
-}
-
-resolve_alternates () {
-       # original URL (xxx.git)
-       top_=`expr "z$1" : 'z\([^:]*:/*[^/]*\)/'`
-       while read path
-       do
-               case "$path" in
-               \#* | '')
-                       continue ;;
-               /*)
-                       echo "$top_$path/" ;;
-               ../*)
-                       # relative -- ugly but seems to work.
-                       echo "$1/objects/$path/" ;;
-               *)
-                       # exit code may not be caught by the reader.
-                       echo "bad alternate: $path"
-                       exit 1 ;;
-               esac
-       done
-}
-
-get_uploadpack () {
-       data_source=$(get_data_source "$1")
-       case "$data_source" in
-       config)
-               uplp=$(git config --get "remote.$1.uploadpack")
-               echo ${uplp:-git-upload-pack}
-               ;;
        *)
-               echo "git-upload-pack"
+           repo=$1
+           shift
+           ref=$1
+           # FIXME: It should return the tracking branch
+           #        Currently only works with the default mapping
+           case "$ref" in
+           +*)
+               ref=$(expr "z$ref" : 'z+\(.*\)')
                ;;
+           esac
+           expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:"
+           remote=$(expr "z$ref" : 'z\([^:]*\):')
+           case "$remote" in
+           '' | HEAD ) remote=HEAD ;;
+           heads/*) remote=${remote#heads/} ;;
+           refs/heads/*) remote=${remote#refs/heads/} ;;
+           refs/* | tags/* | remotes/* ) remote=
+           esac
+
+           [ -n "$remote" ] && echo "refs/remotes/$repo/$remote"
        esac
 }
index 35261539ab80ffa46fef945dce1a82c5636c1b49..4b78a0cd37ba70236a05f78fb5bed3f763348096 100755 (executable)
@@ -125,12 +125,9 @@ test true = "$rebase" && {
        die "refusing to pull with rebase: your working tree is not up-to-date"
 
        . git-parse-remote &&
-       origin="$1"
-       test -z "$origin" && origin=$(get_default_remote)
-       reflist="$(get_remote_refs_for_fetch "$@" 2>/dev/null |
-               sed "s|refs/heads/\(.*\):|\1|")" &&
+       reflist="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
        oldremoteref="$(git rev-parse -q --verify \
-               "refs/remotes/$origin/$reflist")"
+               "$reflist")"
 }
 orig_head=$(git rev-parse -q --verify HEAD)
 git fetch $verbosity --update-head-ok "$@" || exit 1
@@ -176,13 +173,11 @@ case "$merge_head" in
 ?*' '?*)
        if test -z "$orig_head"
        then
-               echo >&2 "Cannot merge multiple branches into empty head"
-               exit 1
+               die "Cannot merge multiple branches into empty head"
        fi
        if test true = "$rebase"
        then
-               echo >&2 "Cannot rebase onto multiple branches"
-               exit 1
+               die "Cannot rebase onto multiple branches"
        fi
        ;;
 esac
index 84b5173f936f89ef7750cc9d5b9f6b041c8aef1f..18bc6946cfa592c11cf7499b1c1ff9a6cb378b26 100755 (executable)
@@ -181,10 +181,8 @@ run_pre_rebase_hook () {
        if test -z "$OK_TO_SKIP_PRE_REBASE" &&
           test -x "$GIT_DIR/hooks/pre-rebase"
        then
-               "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
-                       echo >&2 "The pre-rebase hook refused to rebase."
-                       exit 1
-               }
+               "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} ||
+               die "The pre-rebase hook refused to rebase."
        fi
 }
 
@@ -385,8 +383,7 @@ fi
 
 # The tree must be really really clean.
 if ! git update-index --ignore-submodules --refresh; then
-       echo >&2 "cannot rebase: you have unstaged changes"
-       exit 1
+       die "cannot rebase: you have unstaged changes"
 fi
 diff=$(git diff-index --cached --name-status -r --ignore-submodules HEAD --)
 case "$diff" in
index a2cf5b82150a77fd9ddb775fea1bc8d5e8ee7392..5917773240dfb2e8b5f078afee22a3d9bf607ce3 100755 (executable)
@@ -12,6 +12,9 @@ OPTIONS_SPEC=
 . git-sh-setup
 . git-parse-remote
 
+GIT_PAGER=
+export GIT_PAGER
+
 base=$1
 url=$2
 head=${3-HEAD}
@@ -34,7 +37,7 @@ branch=$(git ls-remote "$url" \
        }")
 if [ -z "$branch" ]; then
        echo "warn: No branch of $url is at:" >&2
-       git log --max-count=1 --pretty='format:warn:   %h: %s' $headrev >&2
+       git log --max-count=1 --pretty='tformat:warn:   %h: %s' $headrev >&2
        echo "warn: Are you sure you pushed $head there?" >&2
        echo >&2
        echo >&2
@@ -42,8 +45,6 @@ if [ -z "$branch" ]; then
        status=1
 fi
 
-PAGER=
-export PAGER
 echo "The following changes since commit $baserev:"
 git shortlog --max-count=1 $baserev | sed -e 's/^\(.\)/  \1/'
 
index 303e03a8ce4031a1d9d6d00cb67abda1c30a63f3..8ce6f1fe57579201c09cf960caed98d330ab2bbb 100755 (executable)
@@ -334,7 +334,7 @@ if (@suppress_cc) {
 }
 
 if ($suppress_cc{'all'}) {
-       foreach my $entry (qw (ccmd cc author self sob body bodycc)) {
+       foreach my $entry (qw (cccmd cc author self sob body bodycc)) {
                $suppress_cc{$entry} = 1;
        }
        delete $suppress_cc{'all'};
@@ -1104,7 +1104,7 @@ foreach my $t (@files) {
        close F;
 
        if (defined $cc_cmd && !$suppress_cc{'cccmd'}) {
-               open(F, "$cc_cmd $t |")
+               open(F, "$cc_cmd \Q$t\E |")
                        or die "(cc-cmd) Could not execute '$cc_cmd'";
                while(<F>) {
                        my $c = $_;
index 58d2fd2ccb65925e81b1aab3c8e624359b286a14..ebed711da41a7ac3c4caa7ae9b7f73e0c75f4fe7 100755 (executable)
@@ -5,7 +5,7 @@
 # Copyright (c) 2007 Lars Hjemli
 
 USAGE="[--quiet] [--cached] \
-[add [-b branch] <repo> <path>]|[status|init|update [-i|--init] [-N|--no-fetch]|summary [-n|--summary-limit <n>] [<commit>]] \
+[add [-b branch] <repo> <path>]|[status|init|update [-i|--init] [-N|--no-fetch] [--rebase|--merge]|summary [-n|--summary-limit <n>] [<commit>]] \
 [--] [<path>...]|[foreach <command>]|[sync [--] [<path>...]]"
 OPTIONS_SPEC=
 . git-sh-setup
@@ -344,6 +344,10 @@ cmd_update()
                        reference="$1"
                        shift
                        ;;
+               -m|--merge)
+                       shift
+                       update="merge"
+                       ;;
                --)
                        shift
                        break
@@ -414,6 +418,11 @@ cmd_update()
                                action="rebase"
                                msg="rebased onto"
                                ;;
+                       merge)
+                               command="git merge"
+                               action="merge"
+                               msg="merged in"
+                               ;;
                        *)
                                command="git checkout $force -q"
                                action="checkout"
index 33017974d0a098bdaff707ccf0e8660aa5009079..d1af1a3d2f1e24c068e227f847ccceb7e156ad0d 100755 (executable)
@@ -63,7 +63,7 @@ my ($SVN);
 $sha1 = qr/[a-f\d]{40}/;
 $sha1_short = qr/[a-f\d]{4,40}/;
 my ($_stdin, $_help, $_edit,
-       $_message, $_file,
+       $_message, $_file, $_branch_dest,
        $_template, $_shared,
        $_version, $_fetch_all, $_no_rebase, $_fetch_parent,
        $_merge, $_strategy, $_dry_run, $_local,
@@ -92,11 +92,11 @@ my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent,
                'localtime' => \$Git::SVN::_localtime,
                %remote_opts );
 
-my ($_trunk, $_tags, $_branches, $_stdlayout);
+my ($_trunk, @_tags, @_branches, $_stdlayout);
 my %icv;
 my %init_opts = ( 'template=s' => \$_template, 'shared:s' => \$_shared,
-                  'trunk|T=s' => \$_trunk, 'tags|t=s' => \$_tags,
-                  'branches|b=s' => \$_branches, 'prefix=s' => \$_prefix,
+                  'trunk|T=s' => \$_trunk, 'tags|t=s@' => \@_tags,
+                  'branches|b=s@' => \@_branches, 'prefix=s' => \$_prefix,
                   'stdlayout|s' => \$_stdlayout,
                   'minimize-url|m' => \$Git::SVN::_minimize_url,
                  'no-metadata' => sub { $icv{noMetadata} = 1 },
@@ -141,11 +141,13 @@ my %cmd = (
        branch => [ \&cmd_branch,
                    'Create a branch in the SVN repository',
                    { 'message|m=s' => \$_message,
+                     'destination|d=s' => \$_branch_dest,
                      'dry-run|n' => \$_dry_run,
                      'tag|t' => \$_tag } ],
        tag => [ sub { $_tag = 1; cmd_branch(@_) },
                 'Create a tag in the SVN repository',
                 { 'message|m=s' => \$_message,
+                  'destination|d=s' => \$_branch_dest,
                   'dry-run|n' => \$_dry_run } ],
        'set-tree' => [ \&cmd_set_tree,
                        "Set an SVN repository to a git tree-ish",
@@ -211,6 +213,10 @@ my %cmd = (
        'blame' => [ \&Git::SVN::Log::cmd_blame,
                    "Show what revision and author last modified each line of a file",
                    { 'git-format' => \$_git_format } ],
+       'reset' => [ \&cmd_reset,
+                    "Undo fetches back to the specified SVN revision",
+                    { 'revision|r=s' => \$_revision,
+                      'parent|p' => \$_fetch_parent } ],
 );
 
 my $cmd;
@@ -219,6 +225,9 @@ for (my $i = 0; $i < @ARGV; $i++) {
                $cmd = $ARGV[$i];
                splice @ARGV, $i, 1;
                last;
+       } elsif ($ARGV[$i] eq 'help') {
+               $cmd = $ARGV[$i+1];
+               usage(0);
        }
 };
 
@@ -358,7 +367,7 @@ sub init_subdir {
 sub cmd_clone {
        my ($url, $path) = @_;
        if (!defined $path &&
-           (defined $_trunk || defined $_branches || defined $_tags ||
+           (defined $_trunk || @_branches || @_tags ||
             defined $_stdlayout) &&
            $url !~ m#^[a-z\+]+://#) {
                $path = $url;
@@ -372,14 +381,15 @@ sub cmd_clone {
 sub cmd_init {
        if (defined $_stdlayout) {
                $_trunk = 'trunk' if (!defined $_trunk);
-               $_tags = 'tags' if (!defined $_tags);
-               $_branches = 'branches' if (!defined $_branches);
+               @_tags = 'tags' if (! @_tags);
+               @_branches = 'branches' if (! @_branches);
        }
-       if (defined $_trunk || defined $_branches || defined $_tags) {
+       if (defined $_trunk || @_branches || @_tags) {
                return cmd_multi_init(@_);
        }
        my $url = shift or die "SVN repository location required ",
                               "as a command-line argument\n";
+       $url = canonicalize_url($url);
        init_subdir(@_);
        do_git_init_db();
 
@@ -454,8 +464,22 @@ sub cmd_dcommit {
                'Cannot dcommit with a dirty index.  Commit your changes first, '
                . "or stash them with `git stash'.\n";
        $head ||= 'HEAD';
+
+       my $old_head;
+       if ($head ne 'HEAD') {
+               $old_head = eval {
+                       command_oneline([qw/symbolic-ref -q HEAD/])
+               };
+               if ($old_head) {
+                       $old_head =~ s{^refs/heads/}{};
+               } else {
+                       $old_head = eval { command_oneline(qw/rev-parse HEAD/) };
+               }
+               command(['checkout', $head], STDERR => 0);
+       }
+
        my @refs;
-       my ($url, $rev, $uuid, $gs) = working_head_info($head, \@refs);
+       my ($url, $rev, $uuid, $gs) = working_head_info('HEAD', \@refs);
        unless ($gs) {
                die "Unable to determine upstream SVN information from ",
                    "$head history.\nPerhaps the repository is empty.";
@@ -541,7 +565,7 @@ sub cmd_dcommit {
                        if (@diff) {
                                @refs = ();
                                my ($url_, $rev_, $uuid_, $gs_) =
-                                             working_head_info($head, \@refs);
+                                             working_head_info('HEAD', \@refs);
                                my ($linear_refs_, $parents_) =
                                              linearize_history($gs_, \@refs);
                                if (scalar(@$linear_refs) !=
@@ -579,6 +603,22 @@ sub cmd_dcommit {
                        }
                }
        }
+
+       if ($old_head) {
+               my $new_head = command_oneline(qw/rev-parse HEAD/);
+               my $new_is_symbolic = eval {
+                       command_oneline(qw/symbolic-ref -q HEAD/);
+               };
+               if ($new_is_symbolic) {
+                       print "dcommitted the branch ", $head, "\n";
+               } else {
+                       print "dcommitted on a detached HEAD because you gave ",
+                             "a revision argument.\n",
+                             "The rewritten commit is: ", $new_head, "\n";
+               }
+               command(['checkout', $old_head], STDERR => 0);
+       }
+
        unlink $gs->{index};
 }
 
@@ -593,7 +633,33 @@ sub cmd_branch {
        my ($src, $rev, undef, $gs) = working_head_info($head);
 
        my $remote = Git::SVN::read_all_remotes()->{$gs->{repo_id}};
-       my $glob = $remote->{ $_tag ? 'tags' : 'branches' };
+       my $allglobs = $remote->{ $_tag ? 'tags' : 'branches' };
+       my $glob;
+       if ($#{$allglobs} == 0) {
+               $glob = $allglobs->[0];
+       } else {
+               unless(defined $_branch_dest) {
+                       die "Multiple ",
+                           $_tag ? "tag" : "branch",
+                           " paths defined for Subversion repository.\n",
+                           "You must specify where you want to create the ",
+                           $_tag ? "tag" : "branch",
+                           " with the --destination argument.\n";
+               }
+               foreach my $g (@{$allglobs}) {
+                       # SVN::Git::Editor could probably be moved to Git.pm..
+                       my $re = SVN::Git::Editor::glob2pat($g->{path}->{left});
+                       if ($_branch_dest =~ /$re/) {
+                               $glob = $g;
+                               last;
+                       }
+               }
+               unless (defined $glob) {
+                       die "Unknown ",
+                           $_tag ? "tag" : "branch",
+                           " destination $_branch_dest\n";
+               }
+       }
        my ($lft, $rgt) = @{ $glob->{path} }{qw/left right/};
        my $dst = join '/', $remote->{url}, $lft, $branch_name, ($rgt || ());
 
@@ -741,6 +807,12 @@ sub canonicalize_path {
        return $path;
 }
 
+sub canonicalize_url {
+       my ($url) = @_;
+       $url =~ s#^([^:]+://[^/]*/)(.*)$#$1 . canonicalize_path($2)#e;
+       return $url;
+}
+
 # get_svnprops(PATH)
 # ------------------
 # Helper for cmd_propget and cmd_proplist below.
@@ -800,7 +872,7 @@ sub cmd_proplist {
 
 sub cmd_multi_init {
        my $url = shift;
-       unless (defined $_trunk || defined $_branches || defined $_tags) {
+       unless (defined $_trunk || @_branches || @_tags) {
                usage(1);
        }
 
@@ -810,7 +882,7 @@ sub cmd_multi_init {
 
        $_prefix = '' unless defined $_prefix;
        if (defined $url) {
-               $url =~ s#/+$##;
+               $url = canonicalize_url($url);
                init_subdir(@_);
        }
        do_git_init_db();
@@ -825,10 +897,14 @@ sub cmd_multi_init {
                                                   undef, $trunk_ref);
                }
        }
-       return unless defined $_branches || defined $_tags;
+       return unless @_branches || @_tags;
        my $ra = $url ? Git::SVN::Ra->new($url) : undef;
-       complete_url_ls_init($ra, $_branches, '--branches/-b', $_prefix);
-       complete_url_ls_init($ra, $_tags, '--tags/-t', $_prefix . 'tags/');
+       foreach my $path (@_branches) {
+               complete_url_ls_init($ra, $path, '--branches/-b', $_prefix);
+       }
+       foreach my $path (@_tags) {
+               complete_url_ls_init($ra, $path, '--tags/-t', $_prefix.'tags/');
+       }
 }
 
 sub cmd_multi_fetch {
@@ -1021,6 +1097,20 @@ sub cmd_info {
        print $result, "\n";
 }
 
+sub cmd_reset {
+       my $target = shift || $_revision or die "SVN revision required\n";
+       $target = $1 if $target =~ /^r(\d+)$/;
+       $target =~ /^\d+$/ or die "Numeric SVN revision expected\n";
+       my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
+       unless ($gs) {
+               die "Unable to determine upstream SVN information from ".
+                   "history\n";
+       }
+       my ($r, $c) = $gs->find_rev_before($target, not $_fetch_parent);
+       $gs->rev_map_set($r, $c, 'reset', $uuid);
+       print "r$r = $c ($gs->{ref_id})\n";
+}
+
 ########################### utility functions #########################
 
 sub rebase_cmd {
@@ -1099,6 +1189,7 @@ sub complete_url_ls_init {
                die "--prefix='$pfx' must have a trailing slash '/'\n";
        }
        command_noisy('config',
+                     '--add',
                      "svn-remote.$gs->{repo_id}.$n",
                      "$remote_path:refs/remotes/$pfx*" .
                        ('/*' x (($remote_path =~ tr/*/*/) - 1)) );
@@ -1565,7 +1656,8 @@ sub fetch_all {
        # read the max revs for wildcard expansion (branches/*, tags/*)
        foreach my $t (qw/branches tags/) {
                defined $remote->{$t} or next;
-               push @globs, $remote->{$t};
+               push @globs, @{$remote->{$t}};
+
                my $max_rev = eval { tmp_config(qw/--int --get/,
                                         "svn-remote.$repo_id.${t}-maxRev") };
                if (defined $max_rev && ($max_rev < $base)) {
@@ -1612,15 +1704,16 @@ sub read_all_remotes {
                } elsif (m!^(.+)\.(branches|tags)=
                           (.*):refs/remotes/(.+)\s*$/!x) {
                        my ($p, $g) = ($3, $4);
-                       my $rs = $r->{$1}->{$2} = {
-                                         t => $2,
-                                         remote => $1,
-                                         path => Git::SVN::GlobSpec->new($p),
-                                         ref => Git::SVN::GlobSpec->new($g) };
+                       my $rs = {
+                           t => $2,
+                           remote => $1,
+                           path => Git::SVN::GlobSpec->new($p),
+                           ref => Git::SVN::GlobSpec->new($g) };
                        if (length($rs->{ref}->{right}) != 0) {
                                die "The '*' glob character must be the last ",
                                    "character of '$g'\n";
                        }
+                       push @{ $r->{$1}->{$2} }, $rs;
                }
        }
 
@@ -1760,9 +1853,10 @@ sub find_by_url { # repos_root and, path are optional
                next if defined $repos_root && $repos_root ne $u;
 
                my $fetch = $remotes->{$repo_id}->{fetch} || {};
-               foreach (qw/branches tags/) {
-                       resolve_local_globs($u, $fetch,
-                                           $remotes->{$repo_id}->{$_});
+               foreach my $t (qw/branches tags/) {
+                       foreach my $globspec (@{$remotes->{$repo_id}->{$t}}) {
+                               resolve_local_globs($u, $fetch, $globspec);
+                       }
                }
                my $p = $path;
                my $rwr = rewrite_root({repo_id => $repo_id});
@@ -2990,6 +3084,14 @@ sub _rev_map_set {
          croak "write: $!";
 }
 
+sub _rev_map_reset {
+       my ($fh, $rev, $commit) = @_;
+       my $c = _rev_map_get($fh, $rev);
+       $c eq $commit or die "_rev_map_reset(@_) commit $c does not match!\n";
+       my $offset = sysseek($fh, 0, SEEK_CUR) or croak "seek: $!";
+       truncate $fh, $offset or croak "truncate: $!";
+}
+
 sub mkfile {
        my ($path) = @_;
        unless (-e $path) {
@@ -3006,6 +3108,7 @@ sub rev_map_set {
        my $db = $self->map_path($uuid);
        my $db_lock = "$db.lock";
        my $sig;
+       $update_ref ||= 0;
        if ($update_ref) {
                $SIG{INT} = $SIG{HUP} = $SIG{TERM} = $SIG{ALRM} = $SIG{PIPE} =
                            $SIG{USR1} = $SIG{USR2} = sub { $sig = $_[0] };
@@ -3029,7 +3132,8 @@ sub rev_map_set {
 
        sysopen(my $fh, $db_lock, O_RDWR | O_CREAT)
             or croak "Couldn't open $db_lock: $!\n";
-       _rev_map_set($fh, $rev, $commit);
+       $update_ref eq 'reset' ? _rev_map_reset($fh, $rev, $commit) :
+                                _rev_map_set($fh, $rev, $commit);
        if ($sync) {
                $fh->flush or die "Couldn't flush $db_lock: $!\n";
                $fh->sync or die "Couldn't sync $db_lock: $!\n";
@@ -3037,7 +3141,9 @@ sub rev_map_set {
        close $fh or croak $!;
        if ($update_ref) {
                $_head = $self;
-               command_noisy('update-ref', '-m', "r$rev",
+               my $note = "";
+               $note = " ($update_ref)" if ($update_ref !~ /^\d*$/);
+               command_noisy('update-ref', '-m', "r$rev$note",
                              $self->refname, $commit);
        }
        rename $db_lock, $db or die "rev_map_set(@_): ", "Failed to rename: ",
@@ -3099,12 +3205,19 @@ sub rev_map_get {
        return undef unless -e $map_path;
 
        sysopen(my $fh, $map_path, O_RDONLY) or croak "open: $!";
+       my $c = _rev_map_get($fh, $rev);
+       close($fh) or croak "close: $!";
+       $c
+}
+
+sub _rev_map_get {
+       my ($fh, $rev) = @_;
+
        binmode $fh or croak "binmode: $!";
        my $size = (stat($fh))[7];
        ($size % 24) == 0 or croak "inconsistent size: $size";
 
        if ($size == 0) {
-               close $fh or croak "close: $fh";
                return undef;
        }
 
@@ -3122,11 +3235,9 @@ sub rev_map_get {
                } elsif ($r > $rev) {
                        $u = $i - 24;
                } else { # $r == $rev
-                       close($fh) or croak "close: $!";
                        return $c eq ('0' x 40) ? undef : $c;
                }
        }
-       close($fh) or croak "close: $!";
        undef;
 }
 
@@ -3138,6 +3249,8 @@ sub find_rev_before {
        my ($self, $rev, $eq_ok, $min_rev) = @_;
        --$rev unless $eq_ok;
        $min_rev ||= 1;
+       my $max_rev = $self->rev_map_max;
+       $rev = $max_rev if ($rev > $max_rev);
        while ($rev >= $min_rev) {
                if (my $c = $self->rev_map_get($rev)) {
                        return ($rev, $c);
diff --git a/git.c b/git.c
index 7d7f949f0da85ea124f67ead6f68fdd0ddc75d20..f4d53f40deb152db15f05460860af74b00ad9619 100644 (file)
--- a/git.c
+++ b/git.c
@@ -188,10 +188,9 @@ static int handle_alias(int *argcp, const char ***argv)
                                  alias_command);
 
                new_argv = xrealloc(new_argv, sizeof(char *) *
-                                   (count + *argcp + 1));
+                                   (count + *argcp));
                /* insert after command name */
                memcpy(new_argv + count, *argv + 1, sizeof(char *) * *argcp);
-               new_argv[count+*argcp] = NULL;
 
                *argv = new_argv;
                *argcp += count - 1;
index 1a7887b2528140d63b84a72843c0d0ef64f56538..4604c831fe0c5ac9b855cdef6f71888e99dd9462 100644 (file)
@@ -187,7 +187,8 @@ proc parseviewargs {n arglist} {
            "--until=*" - "--before=*" - "--max-age=*" - "--min-age=*" -
            "--author=*" - "--committer=*" - "--grep=*" - "-[iE]" -
            "--remove-empty" - "--first-parent" - "--cherry-pick" -
-           "-S*" - "--pickaxe-all" - "--pickaxe-regex" {
+           "-S*" - "--pickaxe-all" - "--pickaxe-regex" -
+           "--simplify-by-decoration" {
                # These mean that we get a subset of the commits
                set filtered 1
                lappend glflags $arg
@@ -2145,7 +2146,7 @@ proc makewindow {} {
     label .bleft.mid.labeldiffcontext -text "      [mc "Lines of context"]: "
     pack .bleft.mid.diff .bleft.mid.old .bleft.mid.new -side left
     spinbox .bleft.mid.diffcontext -width 5 -font textfont \
-       -from 1 -increment 1 -to 10000000 \
+       -from 0 -increment 1 -to 10000000 \
        -validate all -validatecommand "diffcontextvalidate %P" \
        -textvariable diffcontextstring
     .bleft.mid.diffcontext set $diffcontext
@@ -3671,17 +3672,36 @@ proc newview {ishighlight} {
 }
 
 set known_view_options {
-    {perm    b    . {}               {mc "Remember this view"}}
-    {args    t50= + {}               {mc "Commits to include (arguments to git log):"}}
-    {all     b    * "--all"          {mc "Use all refs"}}
-    {dorder  b    . {"--date-order" "-d"}      {mc "Strictly sort by date"}}
-    {lright  b    . "--left-right"   {mc "Mark branch sides"}}
-    {since   t15  + {"--since=*" "--after=*"}  {mc "Since date:"}}
-    {until   t15  . {"--until=*" "--before=*"} {mc "Until date:"}}
-    {limit   t10  + "--max-count=*"  {mc "Max count:"}}
-    {skip    t10  . "--skip=*"       {mc "Skip:"}}
-    {first   b    . "--first-parent" {mc "Limit to first parent"}}
-    {cmd     t50= + {}               {mc "Command to generate more commits to include:"}}
+    {perm      b    .  {}               {mc "Remember this view"}}
+    {reflabel  l    +  {}               {mc "References (space separated list):"}}
+    {refs      t15  .. {}               {mc "Branches & tags:"}}
+    {allrefs   b    *. "--all"          {mc "All refs"}}
+    {branches  b    .  "--branches"     {mc "All (local) branches"}}
+    {tags      b    .  "--tags"         {mc "All tags"}}
+    {remotes   b    .  "--remotes"      {mc "All remote-tracking branches"}}
+    {commitlbl l    +  {}               {mc "Commit Info (regular expressions):"}}
+    {author    t15  .. "--author=*"     {mc "Author:"}}
+    {committer t15  .  "--committer=*"  {mc "Committer:"}}
+    {loginfo   t15  .. "--grep=*"       {mc "Commit Message:"}}
+    {allmatch  b    .. "--all-match"    {mc "Matches all Commit Info criteria"}}
+    {changes_l l    +  {}               {mc "Changes to Files:"}}
+    {pickaxe_s r0   .  {}               {mc "Fixed String"}}
+    {pickaxe_t r1   .  "--pickaxe-regex"  {mc "Regular Expression"}}
+    {pickaxe   t15  .. "-S*"            {mc "Search string:"}}
+    {datelabel l    +  {}               {mc "Commit Dates (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, 2009 15:27:38\"):"}}
+    {since     t15  ..  {"--since=*" "--after=*"}  {mc "Since:"}}
+    {until     t15  .   {"--until=*" "--before=*"} {mc "Until:"}}
+    {limit_lbl l    +  {}               {mc "Limit and/or skip a number of revisions (positive integer):"}}
+    {limit     t10  *. "--max-count=*"  {mc "Number to show:"}}
+    {skip      t10  .  "--skip=*"       {mc "Number to skip:"}}
+    {misc_lbl  l    +  {}               {mc "Miscellaneous options:"}}
+    {dorder    b    *. {"--date-order" "-d"}      {mc "Strictly sort by date"}}
+    {lright    b    .  "--left-right"   {mc "Mark branch sides"}}
+    {first     b    .  "--first-parent" {mc "Limit to first parent"}}
+    {smplhst   b    .  "--simplify-by-decoration"   {mc "Simple history"}}
+    {args      t50  *. {}               {mc "Additional arguments to git log:"}}
+    {allpaths  path +  {}               {mc "Enter files and directories to include, one per line:"}}
+    {cmd       t50= +  {}               {mc "Command to generate more commits to include:"}}
     }
 
 proc encode_view_opts {n} {
@@ -3693,13 +3713,19 @@ proc encode_view_opts {n} {
        if {$patterns eq {}} continue
        set pattern [lindex $patterns 0]
 
-       set val $newviewopts($n,[lindex $opt 0])
-       
        if {[lindex $opt 1] eq "b"} {
+           set val $newviewopts($n,[lindex $opt 0])
            if {$val} {
                lappend rargs $pattern
            }
+       } elseif {[regexp {^r(\d+)$} [lindex $opt 1] type value]} {
+           regexp {^(.*_)} [lindex $opt 0] uselessvar button_id
+           set val $newviewopts($n,$button_id)
+           if {$val eq $value} {
+               lappend rargs $pattern
+           }
        } else {
+           set val $newviewopts($n,[lindex $opt 0])
            set val [string trim $val]
            if {$val ne {}} {
                set pfix [string range $pattern 0 end-1]
@@ -3707,6 +3733,7 @@ proc encode_view_opts {n} {
            }
        }
     }
+    set rargs [concat $rargs [shellsplit $newviewopts($n,refs)]]
     return [concat $rargs [shellsplit $newviewopts($n,args)]]
 }
 
@@ -3714,14 +3741,22 @@ proc decode_view_opts {n view_args} {
     global known_view_options newviewopts
 
     foreach opt $known_view_options {
+       set id [lindex $opt 0]
        if {[lindex $opt 1] eq "b"} {
+           # Checkboxes
+           set val 0
+        } elseif {[regexp {^r(\d+)$} [lindex $opt 1]]} {
+           # Radiobuttons
+           regexp {^(.*_)} $id uselessvar id
            set val 0
        } else {
+           # Text fields
            set val {}
        }
-       set newviewopts($n,[lindex $opt 0]) $val
+       set newviewopts($n,$id) $val
     }
     set oargs [list]
+    set refargs [list]
     foreach arg $view_args {
        if {[regexp -- {^-([0-9]+)$} $arg arg cnt]
            && ![info exists found(limit)]} {
@@ -3735,11 +3770,17 @@ proc decode_view_opts {n view_args} {
            if {[info exists found($id)]} continue
            foreach pattern [lindex $opt 3] {
                if {![string match $pattern $arg]} continue
-               if {[lindex $opt 1] ne "b"} {
+               if {[lindex $opt 1] eq "b"} {
+                   # Check buttons
+                   set val 1
+               } elseif {[regexp {^r(\d+)$} [lindex $opt 1] match num]} {
+                   # Radio buttons
+                   regexp {^(.*_)} $id uselessvar id
+                   set val $num
+               } else {
+                   # Text input fields
                    set size [string length $pattern]
                    set val [string range $arg [expr {$size-1}] end]
-               } else {
-                   set val 1
                }
                set newviewopts($n,$id) $val
                set found($id) 1
@@ -3748,8 +3789,13 @@ proc decode_view_opts {n view_args} {
            if {[info exists val]} break
        }
        if {[info exists val]} continue
-       lappend oargs $arg
+       if {[regexp {^-} $arg]} {
+           lappend oargs $arg
+       } else {
+           lappend refargs $arg
+       }
     }
+    set newviewopts($n,refs) [shellarglist $refargs]
     set newviewopts($n,args) [shellarglist $oargs]
 }
 
@@ -3785,16 +3831,16 @@ proc vieweditor {top n title} {
     global known_view_options
 
     toplevel $top
-    wm title $top $title
+    wm title $top [concat $title [mc "-- criteria for selecting revisions"]]
     make_transient $top .
 
     # View name
     frame $top.nfr
-    label $top.nl -text [mc "Name"]
+    label $top.nl -text [mc "View Name:"]
     entry $top.name -width 20 -textvariable newviewname($n)
     pack $top.nfr -in $top -fill x -pady 5 -padx 3
-    pack $top.nl -in $top.nfr -side left -padx {0 30}
-    pack $top.name -in $top.nfr -side left
+    pack $top.nl -in $top.nfr -side left -padx {0 5}
+    pack $top.name -in $top.nfr -side left -padx {0 25}
 
     # View options
     set cframe $top.nfr
@@ -3813,14 +3859,28 @@ proc vieweditor {top n title} {
            frame $cframe
            pack $cframe -in $top -fill x -pady 3 -padx 3
            set cexpand [expr {$flags eq "*"}]
+        } elseif {$flags eq ".." || $flags eq "*."} {
+           set cframe $top.fr$cnt
+           incr cnt
+           frame $cframe
+           pack $cframe -in $top -fill x -pady 3 -padx [list 15 3]
+           set cexpand [expr {$flags eq "*."}]
        } else {
            set lxpad 5
        }
 
-       if {$type eq "b"} {
+       if {$type eq "l"} {
+            label $cframe.l_$id -text $title
+            pack $cframe.l_$id -in $cframe -side left -pady [list 3 0] -anchor w
+       } elseif {$type eq "b"} {
            checkbutton $cframe.c_$id -text $title -variable newviewopts($n,$id)
            pack $cframe.c_$id -in $cframe -side left \
                -padx [list $lxpad 0] -expand $cexpand -anchor w
+       } elseif {[regexp {^r(\d+)$} $type type sz]} {
+           regexp {^(.*_)} $id uselessvar button_id
+           radiobutton $cframe.c_$id -text $title -variable newviewopts($n,$button_id) -value $sz
+           pack $cframe.c_$id -in $cframe -side left \
+               -padx [list $lxpad 0] -expand $cexpand -anchor w
        } elseif {[regexp {^t(\d+)$} $type type sz]} {
            message $cframe.l_$id -aspect 1500 -text $title
            entry $cframe.e_$id -width $sz -background $bgcolor \
@@ -3833,23 +3893,22 @@ proc vieweditor {top n title} {
                -textvariable newviewopts($n,$id)
            pack $cframe.l_$id -in $cframe -side top -pady [list 3 0] -anchor w
            pack $cframe.e_$id -in $cframe -side top -fill x
+       } elseif {$type eq "path"} {
+           message $top.l -aspect 1500 -text $title
+           pack $top.l -in $top -side top -pady [list 3 0] -anchor w -padx 3
+           text $top.t -width 40 -height 5 -background $bgcolor -font uifont
+           if {[info exists viewfiles($n)]} {
+               foreach f $viewfiles($n) {
+                   $top.t insert end $f
+                   $top.t insert end "\n"
+               }
+               $top.t delete {end - 1c} end
+               $top.t mark set insert 0.0
+           }
+           pack $top.t -in $top -side top -pady [list 0 5] -fill both -expand 1 -padx 3
        }
     }
 
-    # Path list
-    message $top.l -aspect 1500 \
-       -text [mc "Enter files and directories to include, one per line:"]
-    pack $top.l -in $top -side top -pady [list 7 0] -anchor w -padx 3
-    text $top.t -width 40 -height 5 -background $bgcolor -font uifont
-    if {[info exists viewfiles($n)]} {
-       foreach f $viewfiles($n) {
-           $top.t insert end $f
-           $top.t insert end "\n"
-       }
-       $top.t delete {end - 1c} end
-       $top.t mark set insert 0.0
-    }
-    pack $top.t -in $top -side top -pady [list 0 5] -fill both -expand 1 -padx 3
     frame $top.buts
     button $top.buts.ok -text [mc "OK"] -command [list newviewok $top $n]
     button $top.buts.apply -text [mc "Apply (F5)"] -command [list newviewok $top $n 1]
@@ -7249,7 +7308,7 @@ proc diffcontextchange {n1 n2 op} {
     global diffcontextstring diffcontext
 
     if {[string is integer -strict $diffcontextstring]} {
-       if {$diffcontextstring > 0} {
+       if {$diffcontextstring >= 0} {
            set diffcontext $diffcontextstring
            reselectline
        }
@@ -7267,8 +7326,13 @@ proc getblobdiffs {ids} {
     global ignorespace
     global limitdiffs vfilelimit curview
     global diffencoding targetline diffnparents
+    global git_version
 
-    set cmd [diffcmd $ids "-p -C --cc --no-commit-id -U$diffcontext"]
+    set textconv {}
+    if {[package vcompare $git_version "1.6.1"] >= 0} {
+       set textconv "--textconv"
+    }
+    set cmd [diffcmd $ids "-p $textconv -C --cc --no-commit-id -U$diffcontext"]
     if {$ignorespace} {
        append cmd " -w"
     }
@@ -11090,6 +11154,7 @@ set nullid2 "0000000000000000000000000000000000000001"
 set nullfile "/dev/null"
 
 set have_tk85 [expr {[package vcompare $tk_version "8.5"] >= 0}]
+set git_version [join [lrange [split [lindex [exec git version] end] .] 0 2] .]
 
 set runq {}
 set history {}
index 825dc98f74b97b577d74dacf61bfb4fe482ee2a8..53ef0d635941b54ddc9590f9df309536631114f8 100644 (file)
@@ -1,14 +1,15 @@
 # Translation of gitk to German.
 # Copyright (C) 2007 Paul Mackerras.
 # This file is distributed under the same license as the gitk package.
-# Christian Stimming <stimming@tuhh.de>, 2007
 #
+# Christian Stimming <stimming@tuhh.de>, 2007.
+# Frederik Schwarzer <schwarzerf@gmail.com>, 2008.
 msgid ""
 msgstr ""
 "Project-Id-Version: git-gui\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-12-06 20:40+0100\n"
-"PO-Revision-Date: 2008-12-06 20:45+0100\n"
+"POT-Creation-Date: 2009-05-12 21:55+0200\n"
+"PO-Revision-Date: 2009-05-12 22:18+0200\n"
 "Last-Translator: Christian Stimming <stimming@tuhh.de>\n"
 "Language-Team: German\n"
 "MIME-Version: 1.0\n"
@@ -17,297 +18,314 @@ msgstr ""
 
 #: gitk:113
 msgid "Couldn't get list of unmerged files:"
-msgstr "Liste der nicht-zusammengeführten Dateien nicht gefunden:"
+msgstr "Liste der nicht zusammengeführten Dateien nicht gefunden:"
 
-#: gitk:272
+#: gitk:268
 msgid "Error parsing revisions:"
 msgstr "Fehler beim Laden der Versionen:"
 
-#: gitk:327
+#: gitk:323
 msgid "Error executing --argscmd command:"
-msgstr "Fehler beim --argscmd Kommando:"
+msgstr "Fehler beim Ausführen des --argscmd-Kommandos:"
 
-#: gitk:340
+#: gitk:336
 msgid "No files selected: --merge specified but no files are unmerged."
 msgstr ""
-"Keine Dateien ausgewählt: --merge angegeben, es existieren aber keine nicht-"
-"zusammengeführten Dateien."
+"Keine Dateien ausgewählt: Es wurde --merge angegeben, aber es existieren "
+"keine nicht zusammengeführten Dateien."
 
-#: gitk:343
+#: gitk:339
 msgid ""
 "No files selected: --merge specified but no unmerged files are within file "
 "limit."
 msgstr ""
-"Keine Dateien ausgewähle: --merge angegeben, aber keine nicht-"
-"zusammengeführten Dateien sind in der Dateiauswahl."
+"Keine Dateien ausgewählt: Es wurde --merge angegeben, aber es sind keine "
+"nicht zusammengeführten Dateien in der Dateiauswahl."
 
-#: gitk:365 gitk:503
+#: gitk:361 gitk:508
 msgid "Error executing git log:"
-msgstr "Fehler beim Ausführen von git-log:"
+msgstr "Fehler beim Ausführen von Â»git log«:"
 
-#: gitk:378
+#: gitk:379 gitk:524
 msgid "Reading"
 msgstr "Lesen"
 
-#: gitk:438 gitk:3462
+#: gitk:439 gitk:4061
 msgid "Reading commits..."
-msgstr "Versionen lesen..."
+msgstr "Versionen werden gelesen ..."
 
-#: gitk:441 gitk:1528 gitk:3465
+#: gitk:442 gitk:1560 gitk:4064
 msgid "No commits selected"
-msgstr "Keine Versionen ausgewählt."
+msgstr "Keine Versionen ausgewählt"
 
-#: gitk:1399
+#: gitk:1436
 msgid "Can't parse git log output:"
-msgstr "Ausgabe von git-log kann nicht erkannt werden:"
+msgstr "Ausgabe von Â»git log« kann nicht erkannt werden:"
 
-#: gitk:1605
+#: gitk:1656
 msgid "No commit information available"
 msgstr "Keine Versionsinformation verfügbar"
 
-#: gitk:1709 gitk:1731 gitk:3259 gitk:7764 gitk:9293 gitk:9466
+#: gitk:1791 gitk:1815 gitk:3854 gitk:8714 gitk:10250 gitk:10422
 msgid "OK"
 msgstr "Ok"
 
-#: gitk:1733 gitk:3260 gitk:7439 gitk:7510 gitk:7613 gitk:7660 gitk:7766
-#: gitk:9294 gitk:9467
+#: gitk:1817 gitk:3856 gitk:8311 gitk:8385 gitk:8495 gitk:8544 gitk:8716
+#: gitk:10251 gitk:10423
 msgid "Cancel"
 msgstr "Abbrechen"
 
-#: gitk:1811
+#: gitk:1917
 msgid "Update"
 msgstr "Aktualisieren"
 
-#: gitk:1812
+#: gitk:1918
 msgid "Reload"
 msgstr "Neu laden"
 
-#: gitk:1813
+#: gitk:1919
 msgid "Reread references"
 msgstr "Zweige neu laden"
 
-#: gitk:1814
+#: gitk:1920
 msgid "List references"
 msgstr "Zweige/Markierungen auflisten"
 
-#: gitk:1915
+#: gitk:1922
 msgid "Start git gui"
 msgstr "»git gui« starten"
 
-#: gitk:1917
+#: gitk:1924
 msgid "Quit"
 msgstr "Beenden"
 
-#: gitk:1810
+#: gitk:1916
 msgid "File"
 msgstr "Datei"
 
-#: gitk:1818
+#: gitk:1928
 msgid "Preferences"
 msgstr "Einstellungen"
 
-#: gitk:1817
+#: gitk:1927
 msgid "Edit"
 msgstr "Bearbeiten"
 
-#: gitk:1821
+#: gitk:1932
 msgid "New view..."
-msgstr "Neue Ansicht..."
+msgstr "Neue Ansicht ..."
 
-#: gitk:1822
+#: gitk:1933
 msgid "Edit view..."
-msgstr "Ansicht bearbeiten..."
+msgstr "Ansicht bearbeiten ..."
 
-#: gitk:1823
+#: gitk:1934
 msgid "Delete view"
-msgstr "Ansicht löschen"
+msgstr "Ansicht entfernen"
 
-#: gitk:1825
+#: gitk:1936
 msgid "All files"
 msgstr "Alle Dateien"
 
-#: gitk:1820 gitk:3196
+#: gitk:1931 gitk:3666
 msgid "View"
 msgstr "Ansicht"
 
-#: gitk:1828 gitk:2487
+#: gitk:1941 gitk:1951 gitk:2650
 msgid "About gitk"
 msgstr "Ãœber gitk"
 
-#: gitk:1829
+#: gitk:1942 gitk:1956
 msgid "Key bindings"
 msgstr "Tastenkürzel"
 
-#: gitk:1827
+#: gitk:1940 gitk:1955
 msgid "Help"
 msgstr "Hilfe"
 
-#: gitk:1887
+#: gitk:2016
 msgid "SHA1 ID: "
 msgstr "SHA1:"
 
-#: gitk:1918
+#: gitk:2047
 msgid "Row"
 msgstr "Zeile"
 
-#: gitk:1949
+#: gitk:2078
 msgid "Find"
 msgstr "Suche"
 
-#: gitk:1950
+#: gitk:2079
 msgid "next"
 msgstr "nächste"
 
-#: gitk:1951
+#: gitk:2080
 msgid "prev"
 msgstr "vorige"
 
-#: gitk:1952
+#: gitk:2081
 msgid "commit"
 msgstr "Version nach"
 
-#: gitk:1955 gitk:1957 gitk:3617 gitk:3640 gitk:3664 gitk:5550 gitk:5621
+#: gitk:2084 gitk:2086 gitk:4222 gitk:4245 gitk:4269 gitk:6210 gitk:6282
+#: gitk:6366
 msgid "containing:"
 msgstr "Beschreibung:"
 
-#: gitk:1958 gitk:2954 gitk:2959 gitk:3692
+#: gitk:2087 gitk:3158 gitk:3163 gitk:4297
 msgid "touching paths:"
 msgstr "Dateien:"
 
-#: gitk:1959 gitk:3697
+#: gitk:2088 gitk:4302
 msgid "adding/removing string:"
 msgstr "Änderungen:"
 
-#: gitk:1968 gitk:1970
+#: gitk:2097 gitk:2099
 msgid "Exact"
 msgstr "Exakt"
 
-#: gitk:1970 gitk:3773 gitk:5518
+#: gitk:2099 gitk:4377 gitk:6178
 msgid "IgnCase"
 msgstr "Kein Groß/Klein"
 
-#: gitk:1970 gitk:3666 gitk:3771 gitk:5514
+#: gitk:2099 gitk:4271 gitk:4375 gitk:6174
 msgid "Regexp"
 msgstr "Regexp"
 
-#: gitk:1972 gitk:1973 gitk:3792 gitk:3822 gitk:3829 gitk:5641 gitk:5708
+#: gitk:2101 gitk:2102 gitk:4396 gitk:4426 gitk:4433 gitk:6302 gitk:6370
 msgid "All fields"
 msgstr "Alle Felder"
 
-#: gitk:1973 gitk:3790 gitk:3822 gitk:5580
+#: gitk:2102 gitk:4394 gitk:4426 gitk:6241
 msgid "Headline"
 msgstr "Ãœberschrift"
 
-#: gitk:1974 gitk:3790 gitk:5580 gitk:5708 gitk:6109
+#: gitk:2103 gitk:4394 gitk:6241 gitk:6370 gitk:6804
 msgid "Comments"
 msgstr "Beschreibung"
 
-#: gitk:1974 gitk:3790 gitk:3794 gitk:3829 gitk:5580 gitk:6045 gitk:7285
-#: gitk:7300
+#: gitk:2103 gitk:4394 gitk:4398 gitk:4433 gitk:6241 gitk:6739 gitk:7991
+#: gitk:8006
 msgid "Author"
 msgstr "Autor"
 
-#: gitk:1974 gitk:3790 gitk:5580 gitk:6047
+#: gitk:2103 gitk:4394 gitk:6241 gitk:6741
 msgid "Committer"
 msgstr "Eintragender"
 
-#: gitk:2003
+#: gitk:2132
 msgid "Search"
-msgstr "Suche"
+msgstr "Suchen"
 
-#: gitk:2010
+#: gitk:2139
 msgid "Diff"
 msgstr "Vergleich"
 
-#: gitk:2012
+#: gitk:2141
 msgid "Old version"
 msgstr "Alte Version"
 
-#: gitk:2014
+#: gitk:2143
 msgid "New version"
 msgstr "Neue Version"
 
-#: gitk:2016
+#: gitk:2145
 msgid "Lines of context"
 msgstr "Kontextzeilen"
 
-#: gitk:2026
+#: gitk:2155
 msgid "Ignore space change"
 msgstr "Leerzeichenänderungen ignorieren"
 
-#: gitk:2084
+#: gitk:2213
 msgid "Patch"
 msgstr "Patch"
 
-#: gitk:2086
+#: gitk:2215
 msgid "Tree"
 msgstr "Baum"
 
-#: gitk:2213 gitk:2226
+#: gitk:2359 gitk:2376
 msgid "Diff this -> selected"
-msgstr "Vergleich diese -> gewählte"
+msgstr "Vergleich: diese -> gewählte"
 
-#: gitk:2214 gitk:2227
+#: gitk:2360 gitk:2377
 msgid "Diff selected -> this"
-msgstr "Vergleich gewählte -> diese"
+msgstr "Vergleich: gewählte -> diese"
 
-#: gitk:2215 gitk:2228
+#: gitk:2361 gitk:2378
 msgid "Make patch"
 msgstr "Patch erstellen"
 
-#: gitk:2216 gitk:7494
+#: gitk:2362 gitk:8369
 msgid "Create tag"
 msgstr "Markierung erstellen"
 
-#: gitk:2217 gitk:7593
+#: gitk:2363 gitk:8475
 msgid "Write commit to file"
 msgstr "Version in Datei schreiben"
 
-#: gitk:2218 gitk:7647
+#: gitk:2364 gitk:8532
 msgid "Create new branch"
 msgstr "Neuen Zweig erstellen"
 
-#: gitk:2219
+#: gitk:2365
 msgid "Cherry-pick this commit"
 msgstr "Diese Version pflücken"
 
-#: gitk:2220
+#: gitk:2366
 msgid "Reset HEAD branch to here"
 msgstr "HEAD-Zweig auf diese Version zurücksetzen"
 
-#: gitk:2234
+#: gitk:2367
+msgid "Mark this commit"
+msgstr "Lesezeichen setzen"
+
+#: gitk:2368
+msgid "Return to mark"
+msgstr "Zum Lesezeichen"
+
+#: gitk:2369
+msgid "Find descendant of this and mark"
+msgstr "Abkömmling von Lesezeichen und dieser Version finden"
+
+#: gitk:2370
+msgid "Compare with marked commit"
+msgstr "Mit Lesezeichen vergleichen"
+
+#: gitk:2384
 msgid "Check out this branch"
 msgstr "Auf diesen Zweig umstellen"
 
-#: gitk:2235
+#: gitk:2385
 msgid "Remove this branch"
 msgstr "Zweig löschen"
 
-#: gitk:2242
+#: gitk:2392
 msgid "Highlight this too"
 msgstr "Diesen auch hervorheben"
 
-#: gitk:2243
+#: gitk:2393
 msgid "Highlight this only"
 msgstr "Nur diesen hervorheben"
 
-#: gitk:2244
+#: gitk:2394
 msgid "External diff"
-msgstr "Externer Vergleich"
+msgstr "Externes Diff-Programm"
 
-#: gitk:2255
+#: gitk:2395
 msgid "Blame parent commit"
 msgstr "Annotieren der Elternversion"
 
-#: gitk:2360
+#: gitk:2402
 msgid "Show origin of this line"
 msgstr "Herkunft dieser Zeile anzeigen"
 
-#: gitk:2361
+#: gitk:2403
 msgid "Run git gui blame on this line"
-msgstr "Annotieren (»git gui blame«) von dieser Zeile"
+msgstr "Diese Zeile annotieren (»git gui blame«)"
 
-#: gitk:2606
+#: gitk:2652
 msgid ""
 "\n"
 "Gitk - a commit viewer for git\n"
@@ -317,504 +335,552 @@ msgid ""
 "Use and redistribute under the terms of the GNU General Public License"
 msgstr ""
 "\n"
-"Gitk - eine Visualisierung der Git Historie\n"
+"Gitk - eine Visualisierung der Git-Historie\n"
 "\n"
 "Copyright Â© 2005-2008 Paul Mackerras\n"
 "\n"
 "Benutzung und Weiterverbreitung gemäß den Bedingungen der GNU General Public "
 "License"
 
-#: gitk:2496 gitk:2557 gitk:7943
+#: gitk:2660 gitk:2722 gitk:8897
 msgid "Close"
 msgstr "Schließen"
 
-#: gitk:2515
+#: gitk:2679
 msgid "Gitk key bindings"
-msgstr "Gitk Tastaturbelegung"
+msgstr "Gitk-Tastaturbelegung"
 
-#: gitk:2517
+#: gitk:2682
 msgid "Gitk key bindings:"
-msgstr "Gitk Tastaturbelegung:"
+msgstr "Gitk-Tastaturbelegung:"
 
-#: gitk:2519
+#: gitk:2684
 #, tcl-format
 msgid "<%s-Q>\t\tQuit"
 msgstr "<%s-Q>\t\tBeenden"
 
-#: gitk:2520
+#: gitk:2685
 msgid "<Home>\t\tMove to first commit"
 msgstr "<Pos1>\t\tZur neuesten Version springen"
 
-#: gitk:2521
+#: gitk:2686
 msgid "<End>\t\tMove to last commit"
 msgstr "<Ende>\t\tZur Ã¤ltesten Version springen"
 
-#: gitk:2522
+#: gitk:2687
 msgid "<Up>, p, i\tMove up one commit"
 msgstr "<Hoch>, p, i\tNächste neuere Version"
 
-#: gitk:2523
+#: gitk:2688
 msgid "<Down>, n, k\tMove down one commit"
 msgstr "<Runter>, n, k\tNächste Ã¤ltere Version"
 
-#: gitk:2524
+#: gitk:2689
 msgid "<Left>, z, j\tGo back in history list"
 msgstr "<Links>, z, j\tEine Version zurückgehen"
 
-#: gitk:2525
+#: gitk:2690
 msgid "<Right>, x, l\tGo forward in history list"
 msgstr "<Rechts>, x, l\tEine Version weitergehen"
 
-#: gitk:2526
+#: gitk:2691
 msgid "<PageUp>\tMove up one page in commit list"
 msgstr "<BildHoch>\tEine Seite nach oben blättern"
 
-#: gitk:2527
+#: gitk:2692
 msgid "<PageDown>\tMove down one page in commit list"
 msgstr "<BildRunter>\tEine Seite nach unten blättern"
 
-#: gitk:2528
+#: gitk:2693
 #, tcl-format
 msgid "<%s-Home>\tScroll to top of commit list"
 msgstr "<%s-Pos1>\tZum oberen Ende der Versionsliste blättern"
 
-#: gitk:2529
+#: gitk:2694
 #, tcl-format
 msgid "<%s-End>\tScroll to bottom of commit list"
 msgstr "<%s-Ende>\tZum unteren Ende der Versionsliste blättern"
 
-#: gitk:2530
+#: gitk:2695
 #, tcl-format
 msgid "<%s-Up>\tScroll commit list up one line"
 msgstr "<%s-Hoch>\tVersionsliste eine Zeile nach oben blättern"
 
-#: gitk:2531
+#: gitk:2696
 #, tcl-format
 msgid "<%s-Down>\tScroll commit list down one line"
 msgstr "<%s-Runter>\tVersionsliste eine Zeile nach unten blättern"
 
-#: gitk:2532
+#: gitk:2697
 #, tcl-format
 msgid "<%s-PageUp>\tScroll commit list up one page"
-msgstr "<%s-BildHoch>\tVersionsliste eine Seite hoch blättern"
+msgstr "<%s-BildHoch>\tVersionsliste eine Seite nach oben blättern"
 
-#: gitk:2533
+#: gitk:2698
 #, tcl-format
 msgid "<%s-PageDown>\tScroll commit list down one page"
 msgstr "<%s-BildRunter>\tVersionsliste eine Seite nach unten blättern"
 
-#: gitk:2534
+#: gitk:2699
 msgid "<Shift-Up>\tFind backwards (upwards, later commits)"
 msgstr "<Umschalt-Hoch>\tRückwärts suchen (nach oben; neuere Versionen)"
 
-#: gitk:2535
+#: gitk:2700
 msgid "<Shift-Down>\tFind forwards (downwards, earlier commits)"
 msgstr "<Umschalt-Runter> Suchen (nach unten; Ã¤ltere Versionen)"
 
-#: gitk:2536
+#: gitk:2701
 msgid "<Delete>, b\tScroll diff view up one page"
 msgstr "<Entf>, b\t\tVergleich eine Seite nach oben blättern"
 
-#: gitk:2537
+#: gitk:2702
 msgid "<Backspace>\tScroll diff view up one page"
 msgstr "<Löschtaste>\tVergleich eine Seite nach oben blättern"
 
-#: gitk:2538
+#: gitk:2703
 msgid "<Space>\t\tScroll diff view down one page"
 msgstr "<Leertaste>\tVergleich eine Seite nach unten blättern"
 
-#: gitk:2539
+#: gitk:2704
 msgid "u\t\tScroll diff view up 18 lines"
-msgstr "u\t\tVergleich um 18 Zeilen nach oben (»up«) blättern"
+msgstr "u\t\tVergleich um 18 Zeilen nach oben blättern"
 
-#: gitk:2540
+#: gitk:2705
 msgid "d\t\tScroll diff view down 18 lines"
-msgstr "d\t\tVergleich um 18 Zeilen nach unten (»down«) blättern"
+msgstr "d\t\tVergleich um 18 Zeilen nach unten blättern"
 
-#: gitk:2541
+#: gitk:2706
 #, tcl-format
 msgid "<%s-F>\t\tFind"
 msgstr "<%s-F>\t\tSuchen"
 
-#: gitk:2542
+#: gitk:2707
 #, tcl-format
 msgid "<%s-G>\t\tMove to next find hit"
 msgstr "<%s-G>\t\tWeitersuchen"
 
-#: gitk:2543
+#: gitk:2708
 msgid "<Return>\tMove to next find hit"
 msgstr "<Eingabetaste>\tWeitersuchen"
 
-#: gitk:2544
-msgid "/\t\tMove to next find hit, or redo find"
-msgstr "/\t\tWeitersuchen oder neue Suche beginnen"
+#: gitk:2709
+msgid "/\t\tFocus the search box"
+msgstr "/\t\tTastaturfokus ins Suchfeld"
 
-#: gitk:2545
+#: gitk:2710
 msgid "?\t\tMove to previous find hit"
 msgstr "?\t\tRückwärts weitersuchen"
 
-#: gitk:2546
+#: gitk:2711
 msgid "f\t\tScroll diff view to next file"
-msgstr "f\t\tVergleich zur nächsten Datei (»file«) blättern"
+msgstr "f\t\tVergleich zur nächsten Datei blättern"
 
-#: gitk:2547
+#: gitk:2712
 #, tcl-format
 msgid "<%s-S>\t\tSearch for next hit in diff view"
 msgstr "<%s-S>\t\tWeitersuchen im Vergleich"
 
-#: gitk:2548
+#: gitk:2713
 #, tcl-format
 msgid "<%s-R>\t\tSearch for previous hit in diff view"
 msgstr "<%s-R>\t\tRückwärts weitersuchen im Vergleich"
 
-#: gitk:2549
+#: gitk:2714
 #, tcl-format
 msgid "<%s-KP+>\tIncrease font size"
-msgstr "<%s-Nummerblock-Plus>\tSchriftgröße vergrößern"
+msgstr "<%s-Nummerblock-Plus>\tSchrift vergrößern"
 
-#: gitk:2550
+#: gitk:2715
 #, tcl-format
 msgid "<%s-plus>\tIncrease font size"
-msgstr "<%s-Plus>\tSchriftgröße vergrößern"
+msgstr "<%s-Plus>\tSchrift vergrößern"
 
-#: gitk:2551
+#: gitk:2716
 #, tcl-format
 msgid "<%s-KP->\tDecrease font size"
-msgstr "<%s-Nummernblock-> Schriftgröße verkleinern"
+msgstr "<%s-Nummernblock-Minus> Schrift verkleinern"
 
-#: gitk:2552
+#: gitk:2717
 #, tcl-format
 msgid "<%s-minus>\tDecrease font size"
-msgstr "<%s-Minus>\tSchriftgröße verkleinern"
+msgstr "<%s-Minus>\tSchrift verkleinern"
 
-#: gitk:2553
+#: gitk:2718
 msgid "<F5>\t\tUpdate"
 msgstr "<F5>\t\tAktualisieren"
 
-#: gitk:2979
+#: gitk:3173
 #, tcl-format
 msgid "Error getting \"%s\" from %s:"
 msgstr "Fehler beim Holen von Â»%s« von Â»%s«:"
 
-#: gitk:3036 gitk:3045
+#: gitk:3230 gitk:3239
 #, tcl-format
 msgid "Error creating temporary directory %s:"
-msgstr "Fehler beim Erzeugen eines temporären Verzeichnisses Â»%s«:"
+msgstr "Fehler beim Erzeugen des temporären Verzeichnisses Â»%s«:"
 
-#: gitk:3058
+#: gitk:3251
 msgid "command failed:"
 msgstr "Kommando fehlgeschlagen:"
 
-#: gitk:3078
+#: gitk:3397
 msgid "No such commit"
 msgstr "Version nicht gefunden"
 
-#: gitk:3083
+#: gitk:3411
 msgid "git gui blame: command failed:"
 msgstr "git gui blame: Kommando fehlgeschlagen:"
 
-#: gitk:3398
+#: gitk:3442
 #, tcl-format
 msgid "Couldn't read merge head: %s"
 msgstr "Zusammenführungs-Spitze konnte nicht gelesen werden: %s"
 
-#: gitk:3406
+#: gitk:3450
 #, tcl-format
 msgid "Error reading index: %s"
 msgstr "Fehler beim Lesen der Bereitstellung (»index«): %s"
 
-#: gitk:3431
+#: gitk:3475
 #, tcl-format
 msgid "Couldn't start git blame: %s"
 msgstr "»git blame« konnte nicht gestartet werden: %s"
 
-#: gitk:3434 gitk:6160
+#: gitk:3478 gitk:6209
 msgid "Searching"
 msgstr "Suchen"
 
-#: gitk:3466
+#: gitk:3510
 #, tcl-format
 msgid "Error running git blame: %s"
 msgstr "Fehler beim Ausführen von Â»git blame«: %s"
 
-#: gitk:3494
+#: gitk:3538
 #, tcl-format
 msgid "That line comes from commit %s,  which is not in this view"
 msgstr ""
-"Diese Zeile stammt aus Version %s, welche nicht in dieser Ansicht gezeigt "
-"wird."
+"Diese Zeile stammt aus Version %s, die nicht in dieser Ansicht gezeigt wird"
 
-#: gitk:3508
+#: gitk:3552
 msgid "External diff viewer failed:"
-msgstr "Externes Vergleich-(Diff-)Programm fehlgeschlagen:"
+msgstr "Externes Diff-Programm fehlgeschlagen:"
 
-#: gitk:3210
+#: gitk:3670
 msgid "Gitk view definition"
-msgstr "Gitk Ansichten"
+msgstr "Gitk-Ansichten"
 
-#: gitk:3630
+#: gitk:3674
 msgid "Remember this view"
 msgstr "Diese Ansicht speichern"
 
-#: gitk:3232
+#: gitk:3675
 msgid "Commits to include (arguments to git log):"
-msgstr "Versionen anzeigen (Argumente von git-log):"
+msgstr "Versionen anzeigen (Argumente von git log):"
 
-#: gitk:3632
+#: gitk:3676
 msgid "Use all refs"
 msgstr "Alle Zweige verwenden"
 
-#: gitk:3633
+#: gitk:3677
 msgid "Strictly sort by date"
 msgstr "Streng nach Datum sortieren"
 
-#: gitk:3634
+#: gitk:3678
 msgid "Mark branch sides"
 msgstr "Zweig-Seiten markieren"
 
-#: gitk:3635
+#: gitk:3679
 msgid "Since date:"
 msgstr "Von Datum:"
 
-#: gitk:3636
+#: gitk:3680
 msgid "Until date:"
 msgstr "Bis Datum:"
 
-#: gitk:3637
+#: gitk:3681
 msgid "Max count:"
 msgstr "Max. Anzahl:"
 
-#: gitk:3638
+#: gitk:3682
 msgid "Skip:"
 msgstr "Ãœberspringen:"
 
-#: gitk:3639
+#: gitk:3683
 msgid "Limit to first parent"
 msgstr "Auf erste Elternversion beschränken"
 
-#: gitk:3640
+#: gitk:3684
 msgid "Command to generate more commits to include:"
 msgstr "Versionsliste durch folgendes Kommando erzeugen lassen:"
 
-#: gitk:3749
+#: gitk:3780
+msgid "Gitk: edit view"
+msgstr "Gitk: Ansicht bearbeiten"
+
+#: gitk:3793
 msgid "Name"
 msgstr "Name"
 
-#: gitk:3797
+#: gitk:3841
 msgid "Enter files and directories to include, one per line:"
 msgstr "Folgende Dateien und Verzeichnisse anzeigen (eine pro Zeile):"
 
-#: gitk:3811
+#: gitk:3855
 msgid "Apply (F5)"
 msgstr "Anwenden (F5)"
 
-#: gitk:3849
+#: gitk:3893
 msgid "Error in commit selection arguments:"
 msgstr "Fehler in den ausgewählten Versionen:"
 
-#: gitk:3347 gitk:3399 gitk:3842 gitk:3856 gitk:5060 gitk:10141 gitk:10142
+#: gitk:3946 gitk:3998 gitk:4446 gitk:4460 gitk:5721 gitk:11114 gitk:11115
 msgid "None"
 msgstr "Keine"
 
-#: gitk:3790 gitk:5580 gitk:7287 gitk:7302
+#: gitk:4394 gitk:6241 gitk:7993 gitk:8008
 msgid "Date"
 msgstr "Datum"
 
-#: gitk:3790 gitk:5580
+#: gitk:4394 gitk:6241
 msgid "CDate"
 msgstr "Eintragedatum"
 
-#: gitk:3939 gitk:3944
+#: gitk:4543 gitk:4548
 msgid "Descendant"
 msgstr "Abkömmling"
 
-#: gitk:3940
+#: gitk:4544
 msgid "Not descendant"
-msgstr "Nicht Abkömmling"
+msgstr "Kein Abkömmling"
 
-#: gitk:3947 gitk:3952
+#: gitk:4551 gitk:4556
 msgid "Ancestor"
 msgstr "Vorgänger"
 
-#: gitk:3948
+#: gitk:4552
 msgid "Not ancestor"
-msgstr "Nicht Vorgänger"
+msgstr "Kein Vorgänger"
 
-#: gitk:4187
+#: gitk:4842
 msgid "Local changes checked in to index but not committed"
 msgstr "Lokale Ã„nderungen bereitgestellt, aber nicht eingetragen"
 
-#: gitk:4220
+#: gitk:4878
 msgid "Local uncommitted changes, not checked in to index"
 msgstr "Lokale Ã„nderungen, nicht bereitgestellt"
 
-#: gitk:6673
+#: gitk:6559
+msgid "many"
+msgstr "viele"
+
+#: gitk:6743
 msgid "Tags:"
 msgstr "Markierungen:"
 
-#: gitk:6066 gitk:6072 gitk:7280
+#: gitk:6760 gitk:6766 gitk:7986
 msgid "Parent"
 msgstr "Eltern"
 
-#: gitk:6077
+#: gitk:6771
 msgid "Child"
 msgstr "Kind"
 
-#: gitk:6086
+#: gitk:6780
 msgid "Branch"
 msgstr "Zweig"
 
-#: gitk:6089
+#: gitk:6783
 msgid "Follows"
 msgstr "Folgt auf"
 
-#: gitk:6092
+#: gitk:6786
 msgid "Precedes"
 msgstr "Vorgänger von"
 
-#: gitk:7209
+#: gitk:7279
 #, tcl-format
 msgid "Error getting diffs: %s"
 msgstr "Fehler beim Laden des Vergleichs: %s"
 
-#: gitk:7748
+#: gitk:7819
 msgid "Goto:"
 msgstr "Gehe zu:"
 
-#: gitk:7115
+#: gitk:7821
 msgid "SHA1 ID:"
 msgstr "SHA1-Hashwert:"
 
-#: gitk:7134
+#: gitk:7840
 #, tcl-format
 msgid "Short SHA1 id %s is ambiguous"
 msgstr "Kurzer SHA1-Hashwert Â»%s« ist mehrdeutig"
 
-#: gitk:7146
+#: gitk:7852
 #, tcl-format
 msgid "SHA1 id %s is not known"
-msgstr "SHA1-Hashwert Â»%s« unbekannt"
+msgstr "SHA1-Hashwert Â»%s« ist unbekannt"
 
-#: gitk:7148
+#: gitk:7854
 #, tcl-format
 msgid "Tag/Head %s is not known"
 msgstr "Markierung/Zweig Â»%s« ist unbekannt"
 
-#: gitk:7290
+#: gitk:7996
 msgid "Children"
 msgstr "Kinder"
 
-#: gitk:7347
+#: gitk:8053
 #, tcl-format
 msgid "Reset %s branch to here"
 msgstr "Zweig Â»%s« hierher zurücksetzen"
 
-#: gitk:7349
+#: gitk:8055
 msgid "Detached head: can't reset"
 msgstr "Zweigspitze ist abgetrennt: Zurücksetzen nicht möglich"
 
-#: gitk:7381
+#: gitk:8164 gitk:8170
+msgid "Skipping merge commit "
+msgstr "Ãœberspringe Zusammenführungs-Version "
+
+#: gitk:8179 gitk:8184
+msgid "Error getting patch ID for "
+msgstr "Fehler beim Holen der Patch-ID für "
+
+#: gitk:8180 gitk:8185
+msgid " - stopping\n"
+msgstr " - Abbruch.\n"
+
+#: gitk:8190 gitk:8193 gitk:8201 gitk:8211 gitk:8220
+msgid "Commit "
+msgstr "Version "
+
+#: gitk:8194
+msgid ""
+" is the same patch as\n"
+"       "
+msgstr ""
+" ist das gleiche Patch wie\n"
+"       "
+
+#: gitk:8202
+msgid ""
+" differs from\n"
+"       "
+msgstr ""
+" ist unterschiedlich von\n"
+"       "
+
+#: gitk:8204
+msgid "- stopping\n"
+msgstr "- Abbruch.\n"
+
+#: gitk:8212 gitk:8221
+#, tcl-format
+msgid " has %s children - stopping\n"
+msgstr " hat %s Kinder. Abbruch\n"
+
+#: gitk:8252
 msgid "Top"
 msgstr "Oben"
 
-#: gitk:7382
+#: gitk:8253
 msgid "From"
 msgstr "Von"
 
-#: gitk:7387
+#: gitk:8258
 msgid "To"
 msgstr "bis"
 
-#: gitk:7410
+#: gitk:8282
 msgid "Generate patch"
 msgstr "Patch erstellen"
 
-#: gitk:7412
+#: gitk:8284
 msgid "From:"
 msgstr "Von:"
 
-#: gitk:7421
+#: gitk:8293
 msgid "To:"
 msgstr "bis:"
 
-#: gitk:7430
+#: gitk:8302
 msgid "Reverse"
 msgstr "Umgekehrt"
 
-#: gitk:7432 gitk:7607
+#: gitk:8304 gitk:8489
 msgid "Output file:"
 msgstr "Ausgabedatei:"
 
-#: gitk:7438
+#: gitk:8310
 msgid "Generate"
 msgstr "Erzeugen"
 
-#: gitk:7474
+#: gitk:8348
 msgid "Error creating patch:"
-msgstr "Fehler beim Patch erzeugen:"
+msgstr "Fehler beim Erzeugen des Patches:"
 
-#: gitk:7496 gitk:7595 gitk:7649
+#: gitk:8371 gitk:8477 gitk:8534
 msgid "ID:"
 msgstr "ID:"
 
-#: gitk:7505
+#: gitk:8380
 msgid "Tag name:"
 msgstr "Markierungsname:"
 
-#: gitk:7509 gitk:7659
+#: gitk:8384 gitk:8543
 msgid "Create"
 msgstr "Erstellen"
 
-#: gitk:7524
+#: gitk:8401
 msgid "No tag name specified"
 msgstr "Kein Markierungsname angegeben"
 
-#: gitk:7528
+#: gitk:8405
 #, tcl-format
 msgid "Tag \"%s\" already exists"
 msgstr "Markierung Â»%s« existiert bereits."
 
-#: gitk:7534
+#: gitk:8411
 msgid "Error creating tag:"
-msgstr "Fehler bei Markierung erstellen:"
+msgstr "Fehler beim Erstellen der Markierung:"
 
-#: gitk:7604
+#: gitk:8486
 msgid "Command:"
 msgstr "Kommando:"
 
-#: gitk:7612
+#: gitk:8494
 msgid "Write"
 msgstr "Schreiben"
 
-#: gitk:7628
+#: gitk:8512
 msgid "Error writing commit:"
 msgstr "Fehler beim Schreiben der Version:"
 
-#: gitk:7654
+#: gitk:8539
 msgid "Name:"
 msgstr "Name:"
 
-#: gitk:7674
+#: gitk:8562
 msgid "Please specify a name for the new branch"
 msgstr "Bitte geben Sie einen Namen für den neuen Zweig an."
 
-#: gitk:8328
+#: gitk:8567
 #, tcl-format
 msgid "Branch '%s' already exists. Overwrite?"
 msgstr "Zweig Â»%s« existiert bereits. Soll er Ã¼berschrieben werden?"
 
-#: gitk:8394
+#: gitk:8633
 #, tcl-format
 msgid "Commit %s is already included in branch %s -- really re-apply it?"
 msgstr ""
 "Version Â»%s« ist bereits im Zweig Â»%s« enthalten -- trotzdem erneut "
 "eintragen?"
 
-#: gitk:7718
+#: gitk:8638
 msgid "Cherry-picking"
 msgstr "Version pflücken"
 
-#: gitk:8408
+#: gitk:8647
 #, tcl-format
 msgid ""
 "Cherry-pick failed because of local changes to file '%s'.\n"
@@ -822,45 +888,45 @@ msgid ""
 msgstr ""
 "Pflücken fehlgeschlagen, da noch lokale Ã„nderungen in Datei Â»%s«\n"
 "vorliegen. Bitte diese Ã„nderungen eintragen, zurücksetzen oder\n"
-"zwischenspeichern (»git stash») und dann erneut versuchen."
+"zwischenspeichern (»git stash«) und dann erneut versuchen."
 
-#: gitk:8414
+#: gitk:8653
 msgid ""
 "Cherry-pick failed because of merge conflict.\n"
 "Do you wish to run git citool to resolve it?"
 msgstr ""
 "Pflücken fehlgeschlagen, da ein Zusammenführungs-Konflikt aufgetreten\n"
-"ist. Soll das Â»git citool« (Zusammenführungs-Werkzeug) aufgerufen\n"
+"ist. Soll das Zusammenführungs-Werkzeug (»git citool«) aufgerufen\n"
 "werden, um diesen Konflikt aufzulösen?"
 
-#: gitk:8430
+#: gitk:8669
 msgid "No changes committed"
 msgstr "Keine Ã„nderungen eingetragen"
 
-#: gitk:7745
+#: gitk:8695
 msgid "Confirm reset"
 msgstr "Zurücksetzen bestätigen"
 
-#: gitk:7747
+#: gitk:8697
 #, tcl-format
 msgid "Reset branch %s to %s?"
 msgstr "Zweig Â»%s« auf Â»%s« zurücksetzen?"
 
-#: gitk:7751
+#: gitk:8701
 msgid "Reset type:"
 msgstr "Art des Zurücksetzens:"
 
-#: gitk:7755
+#: gitk:8705
 msgid "Soft: Leave working tree and index untouched"
 msgstr "Harmlos: Arbeitskopie und Bereitstellung unverändert"
 
-#: gitk:7758
+#: gitk:8708
 msgid "Mixed: Leave working tree untouched, reset index"
 msgstr ""
 "Gemischt: Arbeitskopie unverändert,\n"
 "Bereitstellung zurückgesetzt"
 
-#: gitk:7761
+#: gitk:8711
 msgid ""
 "Hard: Reset working tree and index\n"
 "(discard ALL local changes)"
@@ -868,21 +934,21 @@ msgstr ""
 "Hart: Arbeitskopie und Bereitstellung\n"
 "(Alle lokalen Ã„nderungen werden gelöscht)"
 
-#: gitk:7777
+#: gitk:8728
 msgid "Resetting"
 msgstr "Zurücksetzen"
 
-#: gitk:7834
+#: gitk:8785
 msgid "Checking out"
 msgstr "Umstellen"
 
-#: gitk:7885
+#: gitk:8838
 msgid "Cannot delete the currently checked-out branch"
 msgstr ""
 "Der Zweig, auf den die Arbeitskopie momentan umgestellt ist, kann nicht "
 "gelöscht werden."
 
-#: gitk:7891
+#: gitk:8844
 #, tcl-format
 msgid ""
 "The commits on branch %s aren't on any other branch.\n"
@@ -891,174 +957,174 @@ msgstr ""
 "Die Versionen auf Zweig Â»%s« existieren auf keinem anderen Zweig.\n"
 "Zweig Â»%s« trotzdem löschen?"
 
-#: gitk:7922
+#: gitk:8875
 #, tcl-format
 msgid "Tags and heads: %s"
 msgstr "Markierungen und Zweige: %s"
 
-#: gitk:7936
+#: gitk:8890
 msgid "Filter"
 msgstr "Filtern"
 
-#: gitk:8230
+#: gitk:9185
 msgid ""
 "Error reading commit topology information; branch and preceding/following "
 "tag information will be incomplete."
 msgstr ""
-"Fehler beim Lesen der Strukturinformationen; Zweige und Vorgänger/Nachfolger "
-"Informationen werden unvollständig sein."
+"Fehler beim Lesen der Strukturinformationen; Zweige und Informationen zu "
+"Vorgänger/Nachfolger werden unvollständig sein."
 
-#: gitk:9216
+#: gitk:10171
 msgid "Tag"
 msgstr "Markierung"
 
-#: gitk:9216
+#: gitk:10171
 msgid "Id"
 msgstr "Id"
 
-#: gitk:9262
+#: gitk:10219
 msgid "Gitk font chooser"
-msgstr "Gitk Schriften wählen"
+msgstr "Gitk-Schriften wählen"
 
-#: gitk:9279
+#: gitk:10236
 msgid "B"
 msgstr "F"
 
-#: gitk:9282
+#: gitk:10239
 msgid "I"
 msgstr "K"
 
-#: gitk:9375
+#: gitk:10334
 msgid "Gitk preferences"
-msgstr "Gitk Einstellungen"
+msgstr "Gitk-Einstellungen"
 
-#: gitk:9376
+#: gitk:10336
 msgid "Commit list display options"
-msgstr "Anzeige Versionsliste"
+msgstr "Anzeige der Versionsliste"
 
-#: gitk:9379
+#: gitk:10339
 msgid "Maximum graph width (lines)"
 msgstr "Maximale Graphenbreite (Zeilen)"
 
-#: gitk:9383
+#: gitk:10343
 #, tcl-format
 msgid "Maximum graph width (% of pane)"
 msgstr "Maximale Graphenbreite (% des Fensters)"
 
-#: gitk:9388
+#: gitk:10347
 msgid "Show local changes"
 msgstr "Lokale Ã„nderungen anzeigen"
 
-#: gitk:9393
+#: gitk:10350
 msgid "Auto-select SHA1"
-msgstr "SHA1-Hashwert automatisch markieren"
+msgstr "SHA1-Hashwert automatisch auswählen"
 
-#: gitk:9398
+#: gitk:10354
 msgid "Diff display options"
-msgstr "Anzeige Vergleich"
+msgstr "Anzeige des Vergleichs"
 
-#: gitk:9400
+#: gitk:10356
 msgid "Tab spacing"
 msgstr "Tabulatorbreite"
 
-#: gitk:9404
+#: gitk:10359
 msgid "Display nearby tags"
-msgstr "Naheliegende Ãœberschriften anzeigen"
+msgstr "Naheliegende Markierungen anzeigen"
 
-#: gitk:9409
+#: gitk:10362
 msgid "Limit diffs to listed paths"
 msgstr "Vergleich nur für angezeigte Pfade"
 
-#: gitk:9414
+#: gitk:10365
 msgid "Support per-file encodings"
 msgstr "Zeichenkodierung pro Datei ermitteln"
 
-#: gitk:9421
+#: gitk:10371 gitk:10436
 msgid "External diff tool"
-msgstr "Externes Vergleich-(Diff-)Programm"
+msgstr "Externes Diff-Programm"
 
-#: gitk:9423
+#: gitk:10373
 msgid "Choose..."
-msgstr "Wählen..."
+msgstr "Wählen ..."
 
-#: gitk:9428
+#: gitk:10378
 msgid "Colors: press to choose"
 msgstr "Farben: Klicken zum Wählen"
 
-#: gitk:9431
+#: gitk:10381
 msgid "Background"
 msgstr "Hintergrund"
 
-#: gitk:10153 gitk:10183
+#: gitk:10382 gitk:10412
 msgid "background"
 msgstr "Hintergrund"
 
-#: gitk:10156
+#: gitk:10385
 msgid "Foreground"
 msgstr "Vordergrund"
 
-#: gitk:10157
+#: gitk:10386
 msgid "foreground"
 msgstr "Vordergrund"
 
-#: gitk:10160
+#: gitk:10389
 msgid "Diff: old lines"
 msgstr "Vergleich: Alte Zeilen"
 
-#: gitk:10161
+#: gitk:10390
 msgid "diff old lines"
 msgstr "Vergleich - Alte Zeilen"
 
-#: gitk:10165
+#: gitk:10394
 msgid "Diff: new lines"
 msgstr "Vergleich: Neue Zeilen"
 
-#: gitk:10166
+#: gitk:10395
 msgid "diff new lines"
 msgstr "Vergleich - Neue Zeilen"
 
-#: gitk:10170
+#: gitk:10399
 msgid "Diff: hunk header"
 msgstr "Vergleich: Ã„nderungstitel"
 
-#: gitk:10172
+#: gitk:10401
 msgid "diff hunk header"
 msgstr "Vergleich - Ã„nderungstitel"
 
-#: gitk:10176
+#: gitk:10405
 msgid "Marked line bg"
-msgstr "Markierte Zeile Hintergrund"
+msgstr "Hintergrund für markierte Zeile"
 
-#: gitk:10178
+#: gitk:10407
 msgid "marked line background"
-msgstr "markierte Zeile Hintergrund"
+msgstr "Hintergrund für markierte Zeile"
 
-#: gitk:10182
+#: gitk:10411
 msgid "Select bg"
-msgstr "Hintergrundfarbe Auswählen"
+msgstr "Hintergrundfarbe auswählen"
 
-#: gitk:9459
+#: gitk:10415
 msgid "Fonts: press to choose"
 msgstr "Schriftart: Klicken zum Wählen"
 
-#: gitk:9461
+#: gitk:10417
 msgid "Main font"
 msgstr "Programmschriftart"
 
-#: gitk:9462
+#: gitk:10418
 msgid "Diff display font"
-msgstr "Vergleich"
+msgstr "Schriftart für Vergleich"
 
-#: gitk:9463
+#: gitk:10419
 msgid "User interface font"
 msgstr "Beschriftungen"
 
-#: gitk:9488
+#: gitk:10446
 #, tcl-format
 msgid "Gitk: choose color for %s"
 msgstr "Gitk: Farbe wählen für %s"
 
-#: gitk:9934
+#: gitk:10893
 msgid ""
 "Sorry, gitk cannot run with this version of Tcl/Tk.\n"
 " Gitk requires at least Tcl/Tk 8.4."
@@ -1066,24 +1132,24 @@ msgstr ""
 "Gitk läuft nicht mit dieser Version von Tcl/Tk.\n"
 "Gitk benötigt mindestens Tcl/Tk 8.4."
 
-#: gitk:10047
+#: gitk:11020
 msgid "Cannot find a git repository here."
 msgstr "Kein Git-Projektarchiv gefunden."
 
-#: gitk:10051
+#: gitk:11024
 #, tcl-format
 msgid "Cannot find the git directory \"%s\"."
 msgstr "Git-Verzeichnis Â»%s« wurde nicht gefunden."
 
-#: gitk:10098
+#: gitk:11071
 #, tcl-format
 msgid "Ambiguous argument '%s': both revision and filename"
 msgstr "Mehrdeutige Angabe Â»%s«: Sowohl Version als auch Dateiname existiert."
 
-#: gitk:10110
+#: gitk:11083
 msgid "Bad arguments to gitk:"
 msgstr "Falsche Kommandozeilen-Parameter für gitk:"
 
-#: gitk:10170
+#: gitk:11167
 msgid "Command line"
 msgstr "Kommandozeile"
index ccda890c0ef1b2d1fb1c451d3f9a10d97817c8f6..9056d1e090b314cfa617ccd8aa03047b3aea23b4 100644 (file)
@@ -377,7 +377,7 @@ named without a .git extension (e.g. /pub/git/project instead of
 
        DocumentRoot /var/www/gitweb
 
-       AliasMatch ^(/.*?)(\.git)(/.*)? /pub/git$1$3
+       AliasMatch ^(/.*?)(\.git)(/.*)?$ /pub/git$1$3
        <Directory /var/www/gitweb>
                Options ExecCGI
                AddHandler cgi-script cgi
@@ -402,6 +402,14 @@ http://git.example.com/project
 
 will provide human-friendly gitweb access.
 
+This solution is not 100% bulletproof, in the sense that if some project
+has a named ref (branch, tag) starting with 'git/', then paths such as
+
+http://git.example.com/project/command/abranch..git/abranch
+
+will fail with a 404 error.
+
+
 
 Originally written by:
   Kay Sievers <kay.sievers@vrfy.org>
index e4ea395e029446920f570d888d93ba9ae249f18c..8cc8ee0dfd5c047b2523f63346bf9b30094c1386 100644 (file)
@@ -1750,7 +1750,7 @@ static int delete_remote_branch(char *pattern, int force)
        return 0;
 }
 
-void run_request_queue(void)
+static void run_request_queue(void)
 {
 #ifdef USE_CURL_MULTI
        is_running_queue = 1;
diff --git a/http.c b/http.c
index 95b2137cfbb1eef355c392e7634e1c761de27379..b0499482455e256a3c2c9b6498b21c32d328c5c9 100644 (file)
--- a/http.c
+++ b/http.c
@@ -20,7 +20,7 @@ char curl_errorstr[CURL_ERROR_SIZE];
 
 static int curl_ssl_verify = -1;
 static const char *ssl_cert;
-#if LIBCURL_VERSION_NUM >= 0x070902
+#if LIBCURL_VERSION_NUM >= 0x070903
 static const char *ssl_key;
 #endif
 #if LIBCURL_VERSION_NUM >= 0x070908
@@ -126,7 +126,7 @@ static int http_options(const char *var, const char *value, void *cb)
        }
        if (!strcmp("http.sslcert", var))
                return git_config_string(&ssl_cert, var, value);
-#if LIBCURL_VERSION_NUM >= 0x070902
+#if LIBCURL_VERSION_NUM >= 0x070903
        if (!strcmp("http.sslkey", var))
                return git_config_string(&ssl_key, var, value);
 #endif
@@ -196,7 +196,7 @@ static CURL *get_curl_handle(void)
 
        if (ssl_cert != NULL)
                curl_easy_setopt(result, CURLOPT_SSLCERT, ssl_cert);
-#if LIBCURL_VERSION_NUM >= 0x070902
+#if LIBCURL_VERSION_NUM >= 0x070903
        if (ssl_key != NULL)
                curl_easy_setopt(result, CURLOPT_SSLKEY, ssl_key);
 #endif
@@ -313,7 +313,7 @@ void http_init(struct remote *remote)
                curl_ssl_verify = 0;
 
        set_from_env(&ssl_cert, "GIT_SSL_CERT");
-#if LIBCURL_VERSION_NUM >= 0x070902
+#if LIBCURL_VERSION_NUM >= 0x070903
        set_from_env(&ssl_key, "GIT_SSL_KEY");
 #endif
 #if LIBCURL_VERSION_NUM >= 0x070908
index e4c83b9d5b989671c1accc573235479ad77a5ab7..3847fd151df6e9f41fdb0b95573882a7d9ac992a 100644 (file)
@@ -238,7 +238,7 @@ static const char *Flags[] = {
 #ifndef NO_OPENSSL
 static void ssl_socket_perror(const char *func)
 {
-       fprintf(stderr, "%s: %s\n", func, ERR_error_string(ERR_get_error(), 0));
+       fprintf(stderr, "%s: %s\n", func, ERR_error_string(ERR_get_error(), NULL));
 }
 #endif
 
index 6e93ee6af64593937ee9b078e599e81d40b74303..c72cbd406a7880361f262f43daff62a9f453628d 100644 (file)
@@ -293,8 +293,8 @@ static void *unpack_entry_data(unsigned long offset, unsigned long size)
 
 static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_base)
 {
-       unsigned char *p, c;
-       unsigned long size;
+       unsigned char *p;
+       unsigned long size, c;
        off_t base_offset;
        unsigned shift;
        void *data;
@@ -312,7 +312,7 @@ static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_
                p = fill(1);
                c = *p;
                use(1);
-               size += (c & 0x7fUL) << shift;
+               size += (c & 0x7f) << shift;
                shift += 7;
        }
        obj->size = size;
@@ -469,7 +469,7 @@ static void sha1_object(const void *data, unsigned long size,
                                die("invalid %s", typename(type));
                        if (fsck_object(obj, 1, fsck_error_function))
                                die("Error in object");
-                       if (fsck_walk(obj, mark_link, 0))
+                       if (fsck_walk(obj, mark_link, NULL))
                                die("Not all child objects of %s are reachable", sha1_to_hex(obj->sha1));
 
                        if (obj->type == OBJ_TREE) {
index 31d6f0a2ee63e8c3cad1053f9281a0ce9917fb32..9168958e863e50f0d1bd1446b3314cb3dd2e772f 100644 (file)
@@ -231,7 +231,7 @@ static int read_merge_config(const char *var, const char *value, void *cb)
 
        if (!strcmp(var, "merge.default")) {
                if (value)
-                       default_ll_merge = strdup(value);
+                       default_ll_merge = xstrdup(value);
                return 0;
        }
 
@@ -265,7 +265,7 @@ static int read_merge_config(const char *var, const char *value, void *cb)
        if (!strcmp("name", ep)) {
                if (!value)
                        return error("%s: lacks value", var);
-               fn->description = strdup(value);
+               fn->description = xstrdup(value);
                return 0;
        }
 
@@ -288,14 +288,14 @@ static int read_merge_config(const char *var, const char *value, void *cb)
                 * file named by %A, and signal that it has done with zero exit
                 * status.
                 */
-               fn->cmdline = strdup(value);
+               fn->cmdline = xstrdup(value);
                return 0;
        }
 
        if (!strcmp("recursive", ep)) {
                if (!value)
                        return error("%s: lacks value", var);
-               fn->recursive = strdup(value);
+               fn->recursive = xstrdup(value);
                return 0;
        }
 
index 59d63eb67e57ab55bdca6493fa8b28b0c870ff21..6f73c17d74bee326a40505b29bba762bade2451e 100644 (file)
@@ -321,7 +321,8 @@ void show_log(struct rev_info *opt)
        }
 
        /*
-        * If use_terminator is set, add a newline at the end of the entry.
+        * If use_terminator is set, we already handled any record termination
+        * at the end of the last record.
         * Otherwise, add a diffopt.line_termination character before all
         * entries but the first.  (IOW, as a separator between entries)
         */
index bb1f2fb711a588d2af0d61decbd4b3eb2f2aebbe..f167c005bf9039f44d21ef5f32ab27db7784d642 100644 (file)
--- a/mailmap.c
+++ b/mailmap.c
@@ -103,7 +103,7 @@ static char *parse_name_and_email(char *buffer, char **name,
                char **email, int allow_empty_email)
 {
        char *left, *right, *nstart, *nend;
-       *name = *email = 0;
+       *name = *email = NULL;
 
        if ((left = strchr(buffer, '<')) == NULL)
                return NULL;
@@ -136,7 +136,7 @@ static int read_single_mailmap(struct string_list *map, const char *filename, ch
        if (f == NULL)
                return 1;
        while (fgets(buffer, sizeof(buffer), f) != NULL) {
-               char *name1 = 0, *email1 = 0, *name2 = 0, *email2 = 0;
+               char *name1 = NULL, *email1 = NULL, *name2 = NULL, *email2 = NULL;
                if (buffer[0] == '#') {
                        static const char abbrev[] = "# repo-abbrev:";
                        int abblen = sizeof(abbrev) - 1;
@@ -200,7 +200,7 @@ int map_user(struct string_list *map,
        if (!p) {
                /* email passed in might not be wrapped in <>, but end with a \0 */
                p = memchr(email, '\0', maxlen_email);
-               if (p == 0)
+               if (!p)
                        return 0;
        }
        if (p - email + 1 < sizeof(buf))
index f5df9b961b2999e4824b900d61d28c254b2ef858..c703445a9cdf66f2933c1ffce636bfe3c11a048c 100644 (file)
@@ -38,7 +38,7 @@ static struct tree *shift_tree_object(struct tree *one, struct tree *two)
  * A virtual commit has (const char *)commit->util set to the name.
  */
 
-struct commit *make_virtual_commit(struct tree *tree, const char *comment)
+static struct commit *make_virtual_commit(struct tree *tree, const char *comment)
 {
        struct commit *commit = xcalloc(1, sizeof(struct commit));
        commit->tree = tree;
index 79de18b37eb1aa96d2f25963b7f7cc2a08977846..f7ce523a615b121b8a0825e459c1b75f24253c85 100644 (file)
@@ -464,7 +464,7 @@ int parse_options(int argc, const char **argv, const char *prefix,
 static int usage_argh(const struct option *opts)
 {
        const char *s;
-       int literal = opts->flags & PARSE_OPT_LITERAL_ARGHELP;
+       int literal = (opts->flags & PARSE_OPT_LITERAL_ARGHELP) || !opts->argh;
        if (opts->flags & PARSE_OPT_OPTARG)
                if (opts->long_name)
                        s = literal ? "[=%s]" : "[=<%s>]";
@@ -472,13 +472,13 @@ static int usage_argh(const struct option *opts)
                        s = literal ? "[%s]" : "[<%s>]";
        else
                s = literal ? " %s" : " <%s>";
-       return fprintf(stderr, s, opts->argh);
+       return fprintf(stderr, s, opts->argh ? opts->argh : "...");
 }
 
 #define USAGE_OPTS_WIDTH 24
 #define USAGE_GAP         2
 
-int usage_with_options_internal(const char * const *usagestr,
+static int usage_with_options_internal(const char * const *usagestr,
                                const struct option *opts, int full)
 {
        if (!usagestr)
@@ -524,40 +524,8 @@ int usage_with_options_internal(const char * const *usagestr,
                if (opts->type == OPTION_NUMBER)
                        pos += fprintf(stderr, "-NUM");
 
-               switch (opts->type) {
-               case OPTION_ARGUMENT:
-                       break;
-               case OPTION_INTEGER:
-                       if (opts->flags & PARSE_OPT_OPTARG)
-                               if (opts->long_name)
-                                       pos += fprintf(stderr, "[=<n>]");
-                               else
-                                       pos += fprintf(stderr, "[<n>]");
-                       else
-                               pos += fprintf(stderr, " <n>");
-                       break;
-               case OPTION_CALLBACK:
-                       if (opts->flags & PARSE_OPT_NOARG)
-                               break;
-                       /* FALLTHROUGH */
-               case OPTION_FILENAME:
-                       /* FALLTHROUGH */
-               case OPTION_STRING:
-                       if (opts->argh)
-                               pos += usage_argh(opts);
-                       else {
-                               if (opts->flags & PARSE_OPT_OPTARG)
-                                       if (opts->long_name)
-                                               pos += fprintf(stderr, "[=...]");
-                                       else
-                                               pos += fprintf(stderr, "[...]");
-                               else
-                                       pos += fprintf(stderr, " ...");
-                       }
-                       break;
-               default: /* OPTION_{BIT,BOOLEAN,NUMBER,SET_INT,SET_PTR} */
-                       break;
-               }
+               if (!(opts->flags & PARSE_OPT_NOARG))
+                       pos += usage_argh(opts);
 
                if (pos <= USAGE_OPTS_WIDTH)
                        pad = USAGE_OPTS_WIDTH - pos;
index 5653dbab87a7d27b10e1513c14ec6d0ec3464325..aba30671dccd9e90686363a766df3eb25d4a8e20 100644 (file)
@@ -67,7 +67,7 @@ typedef int parse_opt_cb(const struct option *, const char *arg, int unset);
  * `flags`::
  *   mask of parse_opt_option_flags.
  *   PARSE_OPT_OPTARG: says that the argument is optional (not for BOOLEANs)
- *   PARSE_OPT_NOARG: says that this option takes no argument, for CALLBACKs
+ *   PARSE_OPT_NOARG: says that this option takes no argument
  *   PARSE_OPT_NONEG: says that this option cannot be negated
  *   PARSE_OPT_HIDDEN: this option is skipped in the default usage, and
  *                     shown only in the full usage.
@@ -104,14 +104,20 @@ struct option {
 };
 
 #define OPT_END()                   { OPTION_END }
-#define OPT_ARGUMENT(l, h)          { OPTION_ARGUMENT, 0, (l), NULL, NULL, (h) }
+#define OPT_ARGUMENT(l, h)          { OPTION_ARGUMENT, 0, (l), NULL, NULL, \
+                                     (h), PARSE_OPT_NOARG}
 #define OPT_GROUP(h)                { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
-#define OPT_BIT(s, l, v, h, b)      { OPTION_BIT, (s), (l), (v), NULL, (h), 0, NULL, (b) }
-#define OPT_NEGBIT(s, l, v, h, b)   { OPTION_NEGBIT, (s), (l), (v), NULL, (h), 0, NULL, (b) }
-#define OPT_BOOLEAN(s, l, v, h)     { OPTION_BOOLEAN, (s), (l), (v), NULL, (h) }
-#define OPT_SET_INT(s, l, v, h, i)  { OPTION_SET_INT, (s), (l), (v), NULL, (h), 0, NULL, (i) }
-#define OPT_SET_PTR(s, l, v, h, p)  { OPTION_SET_PTR, (s), (l), (v), NULL, (h), 0, NULL, (p) }
-#define OPT_INTEGER(s, l, v, h)     { OPTION_INTEGER, (s), (l), (v), NULL, (h) }
+#define OPT_BIT(s, l, v, h, b)      { OPTION_BIT, (s), (l), (v), NULL, (h), \
+                                     PARSE_OPT_NOARG, NULL, (b) }
+#define OPT_NEGBIT(s, l, v, h, b)   { OPTION_NEGBIT, (s), (l), (v), NULL, \
+                                     (h), PARSE_OPT_NOARG, NULL, (b) }
+#define OPT_BOOLEAN(s, l, v, h)     { OPTION_BOOLEAN, (s), (l), (v), NULL, \
+                                     (h), PARSE_OPT_NOARG }
+#define OPT_SET_INT(s, l, v, h, i)  { OPTION_SET_INT, (s), (l), (v), NULL, \
+                                     (h), PARSE_OPT_NOARG, NULL, (i) }
+#define OPT_SET_PTR(s, l, v, h, p)  { OPTION_SET_PTR, (s), (l), (v), NULL, \
+                                     (h), PARSE_OPT_NOARG, NULL, (p) }
+#define OPT_INTEGER(s, l, v, h)     { OPTION_INTEGER, (s), (l), (v), "n", (h) }
 #define OPT_STRING(s, l, v, a, h)   { OPTION_STRING,  (s), (l), (v), (a), (h) }
 #define OPT_DATE(s, l, v, h) \
        { OPTION_CALLBACK, (s), (l), (v), "time",(h), 0, \
index ed9db81fa82c812c9ffa07f5a40540dbb15da0d3..ef748ce96d246bb17c6e64b51b882d535d7f7774 100644 (file)
@@ -44,7 +44,7 @@ void *patch_delta(const void *src_buf, unsigned long src_size,
                        if (cmd & 0x01) cp_off = *data++;
                        if (cmd & 0x02) cp_off |= (*data++ << 8);
                        if (cmd & 0x04) cp_off |= (*data++ << 16);
-                       if (cmd & 0x08) cp_off |= (*data++ << 24);
+                       if (cmd & 0x08) cp_off |= ((unsigned) *data++ << 24);
                        if (cmd & 0x10) cp_size = *data++;
                        if (cmd & 0x20) cp_size |= (*data++ << 8);
                        if (cmd & 0x40) cp_size |= (*data++ << 16);
diff --git a/quote.c b/quote.c
index 7a49fcf69671646a0d3ba6de6478cfc6767c31fe..848d174cc56be32483ba6c73f9b06bc398ed6437 100644 (file)
--- a/quote.c
+++ b/quote.c
@@ -272,8 +272,8 @@ void write_name_quoted(const char *name, FILE *fp, int terminator)
        fputc(terminator, fp);
 }
 
-extern void write_name_quotedpfx(const char *pfx, size_t pfxlen,
-                                 const char *name, FILE *fp, int terminator)
+void write_name_quotedpfx(const char *pfx, size_t pfxlen,
+                         const char *name, FILE *fp, int terminator)
 {
        int needquote = 0;
 
index 08a59644c03b9c61bfad8383e521ac813e0c4f05..733ba57494715e00427350af4175fe67c390ec34 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -106,6 +106,12 @@ static void add_url_alias(struct remote *remote, const char *url)
        add_url(remote, alias_url(url));
 }
 
+static void add_pushurl(struct remote *remote, const char *pushurl)
+{
+       ALLOC_GROW(remote->pushurl, remote->pushurl_nr + 1, remote->pushurl_alloc);
+       remote->pushurl[remote->pushurl_nr++] = pushurl;
+}
+
 static struct remote *make_remote(const char *name, int len)
 {
        struct remote *ret;
@@ -301,7 +307,7 @@ static void read_branches_file(struct remote *remote)
                strbuf_addstr(&branch, "HEAD:");
        }
        add_url_alias(remote, p);
-       add_fetch_refspec(remote, strbuf_detach(&branch, 0));
+       add_fetch_refspec(remote, strbuf_detach(&branch, NULL));
        /*
         * Cogito compatible push: push current HEAD to remote #branch
         * (master if missing)
@@ -312,7 +318,7 @@ static void read_branches_file(struct remote *remote)
                strbuf_addf(&branch, ":refs/heads/%s", frag);
        else
                strbuf_addstr(&branch, ":refs/heads/master");
-       add_push_refspec(remote, strbuf_detach(&branch, 0));
+       add_push_refspec(remote, strbuf_detach(&branch, NULL));
        remote->fetch_tags = 1; /* always auto-follow */
 }
 
@@ -379,6 +385,11 @@ static int handle_config(const char *key, const char *value, void *cb)
                if (git_config_string(&v, key, value))
                        return -1;
                add_url(remote, v);
+       } else if (!strcmp(subkey, ".pushurl")) {
+               const char *v;
+               if (git_config_string(&v, key, value))
+                       return -1;
+               add_pushurl(remote, v);
        } else if (!strcmp(subkey, ".push")) {
                const char *v;
                if (git_config_string(&v, key, value))
@@ -424,6 +435,9 @@ static void alias_all_urls(void)
                for (j = 0; j < remotes[i]->url_nr; j++) {
                        remotes[i]->url[j] = alias_url(remotes[i]->url[j]);
                }
+               for (j = 0; j < remotes[i]->pushurl_nr; j++) {
+                       remotes[i]->pushurl[j] = alias_url(remotes[i]->pushurl[j]);
+               }
        }
 }
 
@@ -1105,7 +1119,7 @@ int match_refs(struct ref *src, struct ref **dst,
        int send_all = flags & MATCH_REFS_ALL;
        int send_mirror = flags & MATCH_REFS_MIRROR;
        int errs;
-       static const char *default_refspec[] = { ":", 0 };
+       static const char *default_refspec[] = { ":", NULL };
        struct ref **dst_tail = tail_ref(dst);
 
        if (!nr_refspec) {
index 257a55538f3ff2d6330b84436a40d6ef972025a0..5db842087da081abbad96c8f9eed5829140714d2 100644 (file)
--- a/remote.h
+++ b/remote.h
@@ -15,6 +15,10 @@ struct remote {
        int url_nr;
        int url_alloc;
 
+       const char **pushurl;
+       int pushurl_nr;
+       int pushurl_alloc;
+
        const char **push_refspec;
        struct refspec *push;
        int push_refspec_nr;
index bf584483675ef55b2ed9b8d8586b92d5432759a5..a31434bdc8ed19674d3c4863e009af0c40d75e73 100644 (file)
@@ -1077,6 +1077,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
                revs->show_all = 1;
        } else if (!strcmp(arg, "--remove-empty")) {
                revs->remove_empty_trees = 1;
+       } else if (!strcmp(arg, "--merges")) {
+               revs->merges_only = 1;
        } else if (!strcmp(arg, "--no-merges")) {
                revs->no_merges = 1;
        } else if (!strcmp(arg, "--boundary")) {
@@ -1676,6 +1678,8 @@ enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
                return commit_ignore;
        if (revs->no_merges && commit->parents && commit->parents->next)
                return commit_ignore;
+       if (revs->merges_only && !(commit->parents && commit->parents->next))
+               return commit_ignore;
        if (!commit_match(commit, revs))
                return commit_ignore;
        if (revs->prune && revs->dense) {
index 227164cf7096d3b0642714b18ee345738684da79..fb74492714b9276d02992dbe1101efff2cbdb5e6 100644 (file)
@@ -36,6 +36,7 @@ struct rev_info {
        unsigned int    dense:1,
                        prune:1,
                        no_merges:1,
+                       merges_only:1,
                        no_walk:1,
                        show_all:1,
                        remove_empty_trees:1,
index e73cd4fc0ba2daac14f604f1973d1b0658212b26..8f5fe62d545ace21c338cd554c76bac5d5acb431 100644 (file)
@@ -1162,8 +1162,7 @@ unsigned long unpack_object_header_buffer(const unsigned char *buf,
                unsigned long len, enum object_type *type, unsigned long *sizep)
 {
        unsigned shift;
-       unsigned char c;
-       unsigned long size;
+       unsigned long size, c;
        unsigned long used = 0;
 
        c = buf[used++];
index a88496030b7053a543173c299bd9f54b923db2ec..f03d11702b3f6212ca7305df60f2f9ea6ca49e35 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -260,7 +260,7 @@ size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f)
        res = fread(sb->buf + sb->len, 1, size, f);
        if (res > 0)
                strbuf_setlen(sb, sb->len + res);
-       else if (res < 0 && oldalloc == 0)
+       else if (oldalloc == 0)
                strbuf_release(sb);
        return res;
 }
index 9aaeabd972ffd3009fb62b9884516cc876bbb35f..e51e505a9fb902ec7d4cedfa32052f03a04e612e 100755 (executable)
@@ -17,11 +17,11 @@ test_expect_success setup '
 
 '
 
-test_expect_code 1 'cherry-pick an empty commit' '
-
-       git checkout master &&
-       git cherry-pick empty-branch
-
+test_expect_success 'cherry-pick an empty commit' '
+       git checkout master && {
+               git cherry-pick empty-branch
+               test "$?" = 1
+       }
 '
 
 test_expect_success 'index lockfile was removed' '
index 6ce8256a17bb7c775eed301b3af8a88497a12c09..85eb0fbf96a65ad958422da02ca4975fe687da95 100755 (executable)
@@ -221,6 +221,19 @@ test_expect_success POSIXPERM 'git add (add.ignore-errors = false)' '
        test_must_fail git add --verbose . &&
        ! ( git ls-files foo1 | grep foo1 )
 '
+rm -f foo2
+
+test_expect_success POSIXPERM '--no-ignore-errors overrides config' '
+       git config add.ignore-errors 1 &&
+       git reset --hard &&
+       date >foo1 &&
+       date >foo2 &&
+       chmod 0 foo2 &&
+       test_must_fail git add --verbose --no-ignore-errors . &&
+       ! ( git ls-files foo1 | grep foo1 ) &&
+       git config add.ignore-errors 0
+'
+rm -f foo2
 
 test_expect_success BSLASHPSPEC "git add 'fo\\[ou\\]bar' ignores foobar" '
        git reset --hard &&
index 42072d724ef67c51e6a9adcf9bf8e3ca1757e053..11502b750997aba0ecfb6aa5b07c9aad1c45d592 100755 (executable)
@@ -9,32 +9,36 @@ test_description='Rename interaction with pathspec.
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/diff-lib.sh ;# test-lib chdir's into trash
 
-test_expect_success \
-    'prepare reference tree' \
-    'mkdir path0 path1 &&
-     cp "$TEST_DIRECTORY"/../COPYING path0/COPYING &&
-     git update-index --add path0/COPYING &&
-    tree=$(git write-tree) &&
-    echo $tree'
-
-test_expect_success \
-    'prepare work tree' \
-    'cp path0/COPYING path1/COPYING &&
-     git update-index --add --remove path0/COPYING path1/COPYING'
+test_expect_success 'prepare reference tree' '
+       mkdir path0 path1 &&
+       cp "$TEST_DIRECTORY"/../COPYING path0/COPYING &&
+       git update-index --add path0/COPYING &&
+       tree=$(git write-tree) &&
+       echo $tree
+'
+
+test_expect_success 'prepare work tree' '
+       cp path0/COPYING path1/COPYING &&
+       git update-index --add --remove path0/COPYING path1/COPYING
+'
 
 # In the tree, there is only path0/COPYING.  In the cache, path0 and
 # path1 both have COPYING and the latter is a copy of path0/COPYING.
 # Comparing the full tree with cache should tell us so.
 
-git diff-index -C --find-copies-harder $tree >current
-
 cat >expected <<\EOF
 :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 C100  path0/COPYING   path1/COPYING
 EOF
 
-test_expect_success \
-    'validate the result (#1)' \
-    'compare_diff_raw current expected'
+test_expect_success 'copy detection' '
+       git diff-index -C --find-copies-harder $tree >current &&
+       compare_diff_raw current expected
+'
+
+test_expect_success 'copy detection, cached' '
+       git diff-index -C --find-copies-harder --cached $tree >current &&
+       compare_diff_raw current expected
+'
 
 # In the tree, there is only path0/COPYING.  In the cache, path0 and
 # path1 both have COPYING and the latter is a copy of path0/COPYING.
@@ -42,49 +46,45 @@ test_expect_success \
 # path1/COPYING suddenly appearing from nowhere, not detected as
 # a copy from path0/COPYING.
 
-git diff-index -C $tree path1 >current
-
 cat >expected <<\EOF
 :000000 100644 0000000000000000000000000000000000000000 6ff87c4664981e4397625791c8ea3bbb5f2279a3 A     path1/COPYING
 EOF
 
-test_expect_success \
-    'validate the result (#2)' \
-    'compare_diff_raw current expected'
-
-test_expect_success \
-    'tweak work tree' \
-    'rm -f path0/COPYING &&
-     git update-index --remove path0/COPYING'
+test_expect_success 'copy, limited to a subtree' '
+       git diff-index -C --find-copies-harder $tree path1 >current &&
+       compare_diff_raw current expected
+'
 
+test_expect_success 'tweak work tree' '
+       rm -f path0/COPYING &&
+       git update-index --remove path0/COPYING
+'
 # In the tree, there is only path0/COPYING.  In the cache, path0 does
 # not have COPYING anymore and path1 has COPYING which is a copy of
 # path0/COPYING.  Showing the full tree with cache should tell us about
 # the rename.
 
-git diff-index -C $tree >current
-
 cat >expected <<\EOF
 :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 R100  path0/COPYING   path1/COPYING
 EOF
 
-test_expect_success \
-    'validate the result (#3)' \
-    'compare_diff_raw current expected'
+test_expect_success 'rename detection' '
+       git diff-index -C --find-copies-harder $tree >current &&
+       compare_diff_raw current expected
+'
 
 # In the tree, there is only path0/COPYING.  In the cache, path0 does
 # not have COPYING anymore and path1 has COPYING which is a copy of
 # path0/COPYING.  When we say we care only about path1, we should just
 # see path1/COPYING appearing from nowhere.
 
-git diff-index -C $tree path1 >current
-
 cat >expected <<\EOF
 :000000 100644 0000000000000000000000000000000000000000 6ff87c4664981e4397625791c8ea3bbb5f2279a3 A     path1/COPYING
 EOF
 
-test_expect_success \
-    'validate the result (#4)' \
-    'compare_diff_raw current expected'
+test_expect_success 'rename, limited to a subtree' '
+       git diff-index -C --find-copies-harder $tree path1 >current &&
+       compare_diff_raw current expected
+'
 
 test_done
diff --git a/t/t4037-diff-r-t-dirs.sh b/t/t4037-diff-r-t-dirs.sh
new file mode 100755 (executable)
index 0000000..f5ce3b2
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+test_description='diff -r -t shows directory additions and deletions'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+       mkdir dc dr dt &&
+       >dc/1 &&
+       >dr/2 &&
+       >dt/3 &&
+       >fc &&
+       >fr &&
+       >ft &&
+       git add . &&
+       test_tick &&
+       git commit -m initial &&
+
+       rm -fr dt dr ft fr &&
+       mkdir da ft &&
+       for p in dc/1 da/4 dt ft/5 fc
+       do
+               echo hello >$p || exit
+       done &&
+       git add -u &&
+       git add . &&
+       test_tick &&
+       git commit -m second
+'
+
+cat >expect <<\EOF
+A      da
+A      da/4
+M      dc
+M      dc/1
+D      dr
+D      dr/2
+A      dt
+D      dt
+D      dt/3
+M      fc
+D      fr
+D      ft
+A      ft
+A      ft/5
+EOF
+
+test_expect_success verify '
+       git diff-tree -r -t --name-status HEAD^ HEAD >actual &&
+       test_cmp expect actual
+'
+
+test_done
index abb41b07ef1985d53c2186617e6b2fcf7e7fe033..5f84b18fa5f0f199905bc7fc045672b70035a708 100755 (executable)
@@ -94,6 +94,10 @@ test_expect_success 'git archive with --output' \
     'git archive --output=b4.tar HEAD &&
     test_cmp b.tar b4.tar'
 
+test_expect_success 'git archive --remote' \
+    'git archive --remote=. HEAD >b5.tar &&
+    test_cmp b.tar b5.tar'
+
 test_expect_success \
     'validate file modification time' \
     'mkdir extract &&
index e70246b3fb5f0040a65db953b0adee7ada2d51ed..852ccb5d7d649a71eeab25eadce6940b9c2a6f63 100755 (executable)
@@ -135,7 +135,8 @@ EOF
 
 cat > test/expect << EOF
 * remote origin
-  URL: $(pwd)/one
+  Fetch URL: $(pwd)/one
+  Push  URL: $(pwd)/one
   HEAD branch: master
   Remote branches:
     master new (next fetch will store in remotes/origin)
@@ -151,7 +152,8 @@ cat > test/expect << EOF
     master pushes to master   (local out of date)
     master pushes to upstream (create)
 * remote two
-  URL: ../two
+  Fetch URL: ../two
+  Push  URL: ../three
   HEAD branch (remote HEAD is ambiguous, may be one of the following):
     another
     master
@@ -173,6 +175,7 @@ test_expect_success 'show' '
         git branch --track rebase origin/master &&
         git branch -d -r origin/master &&
         git config --add remote.two.url ../two &&
+        git config --add remote.two.pushurl ../three &&
         git config branch.rebase.rebase true &&
         git config branch.octopus.merge "topic-a topic-b topic-c" &&
         (cd ../one &&
@@ -191,7 +194,8 @@ test_expect_success 'show' '
 
 cat > test/expect << EOF
 * remote origin
-  URL: $(pwd)/one
+  Fetch URL: $(pwd)/one
+  Push  URL: $(pwd)/one
   HEAD branch: (not queried)
   Remote branches: (status not queried)
     master
index 89649e7a9b2dc138bb9618d4e5770e76f62dc7e0..2d2633f3f8784565faf5db84c6efe12d9c405013 100755 (executable)
@@ -419,6 +419,19 @@ test_expect_success 'push with config remote.*.push = HEAD' '
 git config --remove-section remote.there
 git config --remove-section branch.master
 
+test_expect_success 'push with config remote.*.pushurl' '
+
+       mk_test heads/master &&
+       git checkout master &&
+       git config remote.there.url test2repo &&
+       git config remote.there.pushurl testrepo &&
+       git push there &&
+       check_push_result $the_commit heads/master
+'
+
+# clean up the cruft left with the previous one
+git config --remove-section remote.there
+
 test_expect_success 'push with dry-run' '
 
        mk_test heads/master &&
index 725771fac167ea5aac8cf65b916c96918b0f5e0d..c5a2e66a09b9a871fb97142a58de51097a685ae0 100755 (executable)
@@ -92,20 +92,34 @@ test_expect_success '--rebase with rebased upstream' '
 
        git remote add -f me . &&
        git checkout copy &&
+       git tag copy-orig &&
        git reset --hard HEAD^ &&
        echo conflicting modification > file &&
        git commit -m conflict file &&
        git checkout to-rebase &&
        echo file > file2 &&
        git commit -m to-rebase file2 &&
+       git tag to-rebase-orig &&
        git pull --rebase me copy &&
        test "conflicting modification" = "$(cat file)" &&
        test file = $(cat file2)
 
 '
 
+test_expect_success '--rebase with rebased default upstream' '
+
+       git update-ref refs/remotes/me/copy copy-orig &&
+       git checkout --track -b to-rebase2 me/copy &&
+       git reset --hard to-rebase-orig &&
+       git pull --rebase &&
+       test "conflicting modification" = "$(cat file)" &&
+       test file = $(cat file2)
+
+'
+
 test_expect_success 'pull --rebase dies early with dirty working directory' '
 
+       git checkout to-rebase &&
        git update-ref refs/remotes/me/copy copy^ &&
        COPY=$(git rev-parse --verify me/copy) &&
        git rebase --onto $COPY copy &&
index f275af82403dc0f1de4c584074c0eb63e61a6704..7868af8f1896e621b98a2ae9b71492a68a96e584 100755 (executable)
@@ -125,6 +125,36 @@ do
 
 done
 
+cat >expected <<EOF
+file:foo mmap bar_mmap
+EOF
+
+test_expect_success 'grep -e A --and -e B' '
+       git grep -e "foo mmap" --and -e bar_mmap >actual &&
+       test_cmp expected actual
+'
+
+cat >expected <<EOF
+file:foo_mmap bar mmap
+file:foo_mmap bar mmap baz
+EOF
+
+
+test_expect_success 'grep ( -e A --or -e B ) --and -e B' '
+       git grep \( -e foo_ --or -e baz \) \
+               --and -e " mmap" >actual &&
+       test_cmp expected actual
+'
+
+cat >expected <<EOF
+file:foo mmap bar
+EOF
+
+test_expect_success 'grep -e A --and --not -e B' '
+       git grep -e "foo mmap" --and --not -e bar_mmap >actual &&
+       test_cmp expected actual
+'
+
 test_expect_success 'log grep setup' '
        echo a >>file &&
        test_tick &&
index 0773fe405bb792e82b658c7cea2d8815163ccd19..2d33d9efec3f2f601305e736e31368621acd0584 100755 (executable)
@@ -6,7 +6,7 @@
 test_description='Test updating submodules
 
 This test verifies that "git submodule update" detaches the HEAD of the
-submodule and "git submodule update --rebase" does not detach the HEAD.
+submodule and "git submodule update --rebase/--merge" does not detach the HEAD.
 '
 
 . ./test-lib.sh
@@ -76,6 +76,20 @@ test_expect_success 'submodule update --rebase staying on master' '
        )
 '
 
+test_expect_success 'submodule update --merge staying on master' '
+       (cd super/submodule &&
+         git reset --hard HEAD~1
+       ) &&
+       (cd super &&
+        (cd submodule &&
+         compare_head
+        ) &&
+        git submodule update --merge submodule &&
+        cd submodule &&
+        compare_head
+       )
+'
+
 test_expect_success 'submodule update - rebase in .git/config' '
        (cd super &&
         git config submodule.submodule.update rebase
@@ -110,6 +124,40 @@ test_expect_success 'submodule update - checkout in .git/config but --rebase giv
        )
 '
 
+test_expect_success 'submodule update - merge in .git/config' '
+       (cd super &&
+        git config submodule.submodule.update merge
+       ) &&
+       (cd super/submodule &&
+         git reset --hard HEAD~1
+       ) &&
+       (cd super &&
+        (cd submodule &&
+         compare_head
+        ) &&
+        git submodule update submodule &&
+        cd submodule &&
+        compare_head
+       )
+'
+
+test_expect_success 'submodule update - checkout in .git/config but --merge given' '
+       (cd super &&
+        git config submodule.submodule.update checkout
+       ) &&
+       (cd super/submodule &&
+         git reset --hard HEAD~1
+       ) &&
+       (cd super &&
+        (cd submodule &&
+         compare_head
+        ) &&
+        git submodule update --merge submodule &&
+        cd submodule &&
+        compare_head
+       )
+'
+
 test_expect_success 'submodule update - checkout in .git/config' '
        (cd super &&
         git config submodule.submodule.update checkout
@@ -137,4 +185,14 @@ test_expect_success 'submodule init picks up rebase' '
        )
 '
 
+test_expect_success 'submodule init picks up merge' '
+       (cd super &&
+        git config submodule.merging.url git://non-existing/git &&
+        git config submodule.merging.path does-not-matter &&
+        git config submodule.merging.update merge &&
+        git submodule init merging &&
+        test "merge" = $(git config submodule.merging.update)
+       )
+'
+
 test_done
index 9ce04fd47277e1641979eb583a95de41e2f75570..fb606a9f05bd6964c588f1ba9e5422e757d12387 100755 (executable)
@@ -148,6 +148,25 @@ test_expect_success 'Prompting works' '
                grep "^To: to@example.com$" msgtxt1
 '
 
+test_expect_success 'cccmd works' '
+       clean_fake_sendmail &&
+       cp $patches cccmd.patch &&
+       echo cccmd--cccmd@example.com >>cccmd.patch &&
+       {
+         echo "#!$SHELL_PATH"
+         echo sed -n -e s/^cccmd--//p \"\$1\"
+       } > cccmd-sed &&
+       chmod +x cccmd-sed &&
+       git send-email \
+               --from="Example <nobody@example.com>" \
+               --to=nobody@example.com \
+               --cc-cmd=./cccmd-sed \
+               --smtp-server="$(pwd)/fake.sendmail" \
+               cccmd.patch \
+               &&
+       grep ^Cc:.*cccmd@example.com msgtxt1
+'
+
 z8=zzzzzzzz
 z64=$z8$z8$z8$z8$z8$z8$z8$z8
 z512=$z64$z64$z64$z64$z64$z64$z64$z64
@@ -274,7 +293,7 @@ EOF
 test_suppression () {
        git send-email \
                --dry-run \
-               --suppress-cc=$1 \
+               --suppress-cc=$1 ${2+"--suppress-cc=$2"} \
                --from="Example <from@example.com>" \
                --to=to@example.com \
                --smtp-server relay.example.com \
@@ -282,8 +301,8 @@ test_suppression () {
        sed     -e "s/^\(Date:\).*/\1 DATE-STRING/" \
                -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
                -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
-               >actual-suppress-$1 &&
-       test_cmp expected-suppress-$1 actual-suppress-$1
+               >actual-suppress-$1${2+"-$2"} &&
+       test_cmp expected-suppress-$1${2+"-$2"} actual-suppress-$1${2+"-$2"}
 }
 
 test_expect_success 'sendemail.cc set' '
@@ -316,6 +335,34 @@ test_expect_success 'sendemail.cc unset' '
        test_suppression sob
 '
 
+cat >expected-suppress-cccmd <<\EOF
+0001-Second.patch
+(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
+(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
+(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
+(body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
+Dry-OK. Log says:
+Server: relay.example.com
+MAIL FROM:<from@example.com>
+RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<committer@example.com>
+From: Example <from@example.com>
+To: to@example.com
+Cc: A <author@example.com>, One <one@example.com>, two@example.com, C O Mitter <committer@example.com>
+Subject: [PATCH 1/1] Second.
+Date: DATE-STRING
+Message-Id: MESSAGE-ID-STRING
+X-Mailer: X-MAILER-STRING
+
+Result: OK
+EOF
+
+test_expect_success 'sendemail.cccmd' '
+       echo echo cc-cmd@example.com > cccmd &&
+       chmod +x cccmd &&
+       git config sendemail.cccmd ./cccmd &&
+       test_suppression cccmd
+'
+
 cat >expected-suppress-all <<\EOF
 0001-Second.patch
 Dry-OK. Log says:
@@ -341,13 +388,14 @@ cat >expected-suppress-body <<\EOF
 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
 (mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
 (mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
+(cc-cmd) Adding cc: cc-cmd@example.com from: './cccmd'
 Dry-OK. Log says:
 Server: relay.example.com
 MAIL FROM:<from@example.com>
-RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
+RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<cc-cmd@example.com>
 From: Example <from@example.com>
 To: to@example.com
-Cc: A <author@example.com>, One <one@example.com>, two@example.com
+Cc: A <author@example.com>, One <one@example.com>, two@example.com, cc-cmd@example.com
 Subject: [PATCH 1/1] Second.
 Date: DATE-STRING
 Message-Id: MESSAGE-ID-STRING
@@ -360,6 +408,30 @@ test_expect_success '--suppress-cc=body' '
        test_suppression body
 '
 
+cat >expected-suppress-body-cccmd <<\EOF
+0001-Second.patch
+(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
+(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
+(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
+Dry-OK. Log says:
+Server: relay.example.com
+MAIL FROM:<from@example.com>
+RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
+From: Example <from@example.com>
+To: to@example.com
+Cc: A <author@example.com>, One <one@example.com>, two@example.com
+Subject: [PATCH 1/1] Second.
+Date: DATE-STRING
+Message-Id: MESSAGE-ID-STRING
+X-Mailer: X-MAILER-STRING
+
+Result: OK
+EOF
+
+test_expect_success '--suppress-cc=body --suppress-cc=cccmd' '
+       test_suppression body cccmd
+'
+
 cat >expected-suppress-sob <<\EOF
 0001-Second.patch
 (mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
@@ -381,6 +453,7 @@ Result: OK
 EOF
 
 test_expect_success '--suppress-cc=sob' '
+       git config --unset sendemail.cccmd
        test_suppression sob
 '
 
index 64aa7e2f104eba5f9f844c40d520163a8463cc8f..570e0359e4739e178b1836887c53ddd78e3c8ec0 100755 (executable)
@@ -231,6 +231,25 @@ test_expect_success \
                               "^:refs/${remotes_git_svn}$"
         '
 
+test_expect_success 'dcommit $rev does not clobber current branch' '
+       git svn fetch -i bar &&
+       git checkout -b my-bar refs/remotes/bar &&
+       echo 1 > foo &&
+       git add foo &&
+       git commit -m "change 1" &&
+       echo 2 > foo &&
+       git add foo &&
+       git commit -m "change 2" &&
+       old_head=$(git rev-parse HEAD) &&
+       git svn dcommit -i bar HEAD^ &&
+       test $old_head = $(git rev-parse HEAD) &&
+       test refs/heads/my-bar = $(git symbolic-ref HEAD) &&
+       git log refs/remotes/bar | grep "change 1" &&
+       ! git log refs/remotes/bar | grep "change 2" &&
+       git checkout master &&
+       git branch -D my-bar
+       '
+
 test_expect_success 'able to dcommit to a subdirectory' "
        git svn fetch -i bar &&
        git checkout -b my-bar refs/remotes/bar &&
diff --git a/t/t9138-git-svn-multiple-branches.sh b/t/t9138-git-svn-multiple-branches.sh
new file mode 100755 (executable)
index 0000000..cb9a6d2
--- /dev/null
@@ -0,0 +1,122 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Marc Branchaud
+#
+
+test_description='git svn multiple branch and tag paths in the svn repo'
+. ./lib-git-svn.sh
+
+test_expect_success 'setup svnrepo' '
+       mkdir   project \
+               project/trunk \
+               project/b_one \
+               project/b_two \
+               project/tags_A \
+               project/tags_B &&
+       echo 1 > project/trunk/a.file &&
+       svn_cmd import -m "$test_description" project "$svnrepo/project" &&
+       rm -rf project &&
+       svn_cmd cp -m "Branch 1" "$svnrepo/project/trunk" \
+                                "$svnrepo/project/b_one/first" &&
+       svn_cmd cp -m "Tag 1" "$svnrepo/project/trunk" \
+                             "$svnrepo/project/tags_A/1.0" &&
+       svn_cmd co "$svnrepo/project" svn_project &&
+       ( cd svn_project &&
+               echo 2 > trunk/a.file &&
+               svn_cmd ci -m "Change 1" trunk/a.file &&
+               svn_cmd cp -m "Branch 2" "$svnrepo/project/trunk" \
+                                        "$svnrepo/project/b_one/second" &&
+               svn_cmd cp -m "Tag 2" "$svnrepo/project/trunk" \
+                                     "$svnrepo/project/tags_A/2.0" &&
+               echo 3 > trunk/a.file &&
+               svn_cmd ci -m "Change 2" trunk/a.file &&
+               svn_cmd cp -m "Branch 3" "$svnrepo/project/trunk" \
+                                        "$svnrepo/project/b_two/1" &&
+               svn_cmd cp -m "Tag 3" "$svnrepo/project/trunk" \
+                                     "$svnrepo/project/tags_A/3.0" &&
+               echo 4 > trunk/a.file &&
+               svn_cmd ci -m "Change 3" trunk/a.file &&
+               svn_cmd cp -m "Branch 4" "$svnrepo/project/trunk" \
+                                        "$svnrepo/project/b_two/2" &&
+               svn_cmd cp -m "Tag 4" "$svnrepo/project/trunk" \
+                                     "$svnrepo/project/tags_A/4.0" &&
+               svn_cmd up &&
+               echo 5 > b_one/first/a.file &&
+               svn_cmd ci -m "Change 4" b_one/first/a.file &&
+               svn_cmd cp -m "Tag 5" "$svnrepo/project/b_one/first" \
+                                     "$svnrepo/project/tags_B/v5" &&
+               echo 6 > b_one/second/a.file &&
+               svn_cmd ci -m "Change 5" b_one/second/a.file &&
+               svn_cmd cp -m "Tag 6" "$svnrepo/project/b_one/second" \
+                                     "$svnrepo/project/tags_B/v6" &&
+               echo 7 > b_two/1/a.file &&
+               svn_cmd ci -m "Change 6" b_two/1/a.file &&
+               svn_cmd cp -m "Tag 7" "$svnrepo/project/b_two/1" \
+                                     "$svnrepo/project/tags_B/v7" &&
+               echo 8 > b_two/2/a.file &&
+               svn_cmd ci -m "Change 7" b_two/2/a.file &&
+               svn_cmd cp -m "Tag 8" "$svnrepo/project/b_two/2" \
+                                     "$svnrepo/project/tags_B/v8"
+       )
+'
+
+test_expect_success 'clone multiple branch and tag paths' '
+       git svn clone -T trunk \
+                     -b b_one/* --branches b_two/* \
+                     -t tags_A/* --tags tags_B \
+                     "$svnrepo/project" git_project &&
+       ( cd git_project &&
+               git rev-parse refs/remotes/first &&
+               git rev-parse refs/remotes/second &&
+               git rev-parse refs/remotes/1 &&
+               git rev-parse refs/remotes/2 &&
+               git rev-parse refs/remotes/tags/1.0 &&
+               git rev-parse refs/remotes/tags/2.0 &&
+               git rev-parse refs/remotes/tags/3.0 &&
+               git rev-parse refs/remotes/tags/4.0 &&
+               git rev-parse refs/remotes/tags/v5 &&
+               git rev-parse refs/remotes/tags/v6 &&
+               git rev-parse refs/remotes/tags/v7 &&
+               git rev-parse refs/remotes/tags/v8
+       )
+'
+
+test_expect_success 'Multiple branch or tag paths require -d' '
+       ( cd git_project &&
+               test_must_fail git svn branch -m "No new branch" Nope &&
+               test_must_fail git svn tag -m "No new tag" Tagless &&
+               test_must_fail git rev-parse refs/remotes/Nope &&
+               test_must_fail git rev-parse refs/remotes/tags/Tagless
+       ) &&
+       ( cd svn_project &&
+               svn_cmd up &&
+               test_must_fail test -d b_one/Nope &&
+               test_must_fail test -d b_two/Nope &&
+               test_must_fail test -d tags_A/Tagless &&
+               test_must_fail test -d tags_B/Tagless
+       )
+'
+
+test_expect_success 'create new branches and tags' '
+       ( cd git_project &&
+               git svn branch -m "New branch 1" -d project/b_one New1 ) &&
+       ( cd svn_project &&
+               svn_cmd up && test -e b_one/New1/a.file ) &&
+
+       ( cd git_project &&
+               git svn branch -m "New branch 2" -d project/b_two New2 ) &&
+       ( cd svn_project &&
+               svn_cmd up && test -e b_two/New2/a.file ) &&
+
+       ( cd git_project &&
+               git svn branch -t -m "New tag 1" -d project/tags_A Tag1 ) &&
+       ( cd svn_project &&
+               svn_cmd up && test -e tags_A/Tag1/a.file ) &&
+
+       ( cd git_project &&
+               git svn tag -m "New tag 2" -d project/tags_B Tag2 ) &&
+       ( cd svn_project &&
+               svn_cmd up && test -e tags_B/Tag2/a.file )
+'
+
+test_done
diff --git a/t/t9139-git-svn-reset.sh b/t/t9139-git-svn-reset.sh
new file mode 100755 (executable)
index 0000000..0735526
--- /dev/null
@@ -0,0 +1,66 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Ben Jackson
+#
+
+test_description='git svn reset'
+. ./lib-git-svn.sh
+
+test_expect_success 'setup test repository' '
+       svn_cmd co "$svnrepo" s &&
+       (
+               cd s &&
+               mkdir vis &&
+               echo always visible > vis/vis.txt &&
+               svn_cmd add vis &&
+               svn_cmd commit -m "create visible files" &&
+               mkdir hid &&
+               echo initially hidden > hid/hid.txt &&
+               svn_cmd add hid &&
+               svn_cmd commit -m "create initially hidden files" &&
+               svn_cmd up &&
+               echo mod >> vis/vis.txt &&
+               svn_cmd commit -m "modify vis" &&
+               svn_cmd up
+       )
+'
+
+test_expect_success 'clone SVN repository with hidden directory' '
+       git svn init "$svnrepo" g &&
+       ( cd g && git svn fetch --ignore-paths="^hid" )
+'
+
+test_expect_success 'modify hidden file in SVN repo' '
+       ( cd s &&
+         echo mod hidden >> hid/hid.txt &&
+         svn_cmd commit -m "modify hid" &&
+         svn_cmd up
+       )
+'
+
+test_expect_success 'fetch fails on modified hidden file' '
+       ( cd g &&
+         git svn find-rev refs/remotes/git-svn > ../expect &&
+         ! git svn fetch 2> ../errors &&
+         git svn find-rev refs/remotes/git-svn > ../expect2 ) &&
+       fgrep "not found in commit" errors &&
+       test_cmp expect expect2
+'
+
+test_expect_success 'reset unwinds back to r1' '
+       ( cd g &&
+         git svn reset -r1 &&
+         git svn find-rev refs/remotes/git-svn > ../expect2 ) &&
+       echo 1 >expect &&
+       test_cmp expect expect2
+'
+
+test_expect_success 'refetch succeeds not ignoring any files' '
+       ( cd g &&
+         git svn fetch &&
+         git svn rebase &&
+         fgrep "mod hidden" hid/hid.txt
+       )
+'
+
+test_done
index a90bc3003d97f86fcc2210e340666106647eb74c..efa734b42e38d7f5a98393cd69ac0ffe10160ffc 100644 (file)
@@ -9,7 +9,7 @@ static int verbose = 0, dry_run = 0, quiet = 0;
 static char *string = NULL;
 static char *file = NULL;
 
-int length_callback(const struct option *opt, const char *arg, int unset)
+static int length_callback(const struct option *opt, const char *arg, int unset)
 {
        printf("Callback: \"%s\", %d\n",
                (arg ? arg : "not set"), unset);
@@ -20,7 +20,7 @@ int length_callback(const struct option *opt, const char *arg, int unset)
        return 0;
 }
 
-int number_callback(const struct option *opt, const char *arg, int unset)
+static int number_callback(const struct option *opt, const char *arg, int unset)
 {
        *(int *)opt->value = strtol(arg, NULL, 10);
        return 0;
index edd83949bf0896bedff4cab8e2b037eba574a45e..0459e54d3d89a413330f52ab34662f51924b04ea 100644 (file)
@@ -239,6 +239,12 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree
                if (!tree || type != OBJ_TREE)
                        die("corrupt tree sha %s", sha1_to_hex(sha1));
 
+               if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) {
+                       newbase[baselen + pathlen] = 0;
+                       opt->add_remove(opt, *prefix, mode, sha1, newbase);
+                       newbase[baselen + pathlen] = '/';
+               }
+
                init_tree_desc(&inner, tree, size);
                show_tree(opt, prefix, &inner, newbase, baselen + 1 + pathlen);
 
index aaacaf1015ccf1f353151982a3018ad349663d76..05d0bb1f85467a275bb78173d3a045940262abe7 100644 (file)
@@ -140,7 +140,7 @@ static int unpack_index_entry(struct cache_entry *ce, struct unpack_trees_option
        return call_unpack_fn(src, o);
 }
 
-int traverse_trees_recursive(int n, unsigned long dirmask, unsigned long df_conflicts, struct name_entry *names, struct traverse_info *info)
+static int traverse_trees_recursive(int n, unsigned long dirmask, unsigned long df_conflicts, struct name_entry *names, struct traverse_info *info)
 {
        int i;
        struct tree_desc t[MAX_UNPACK_TREES];
@@ -326,6 +326,23 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str
                        if (src[0])
                                conflicts |= 1;
                }
+
+               /* special case: "diff-index --cached" looking at a tree */
+               if (o->diff_index_cached &&
+                   n == 1 && dirmask == 1 && S_ISDIR(names->mode)) {
+                       int matches;
+                       matches = cache_tree_matches_traversal(o->src_index->cache_tree,
+                                                              names, info);
+                       /*
+                        * Everything under the name matches.  Adjust o->pos to
+                        * skip the entire hierarchy.
+                        */
+                       if (matches) {
+                               o->pos += matches;
+                               return mask;
+                       }
+               }
+
                if (traverse_trees_recursive(n, dirmask, conflicts,
                                             names, info) < 0)
                        return -1;
index 0d26f3d73e773230972db86f34a5147ada881e8b..1e0e2325f150e943dd22b16c1392c136570732bc 100644 (file)
@@ -27,6 +27,7 @@ struct unpack_trees_options {
                     aggressive:1,
                     skip_unmerged:1,
                     initial_checkout:1,
+                    diff_index_cached:1,
                     gently:1;
        const char *prefix;
        int pos;
index d556da975197a718979575864e37c2b9b9f3327a..57529ae63d49826952b29860b3d4106b60250c7b 100644 (file)
@@ -13,7 +13,8 @@ PATTERNS("html", "^[ \t]*(<[Hh][1-6][ \t].*>.*)$",
         "[^<>= \t]+|[^[:space:]]|[\x80-\xff]+"),
 PATTERNS("java",
         "!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
-        "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$",
+        "^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$",
+        /* -- */
         "[a-zA-Z_][a-zA-Z0-9_]*"
         "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
         "|[-+*/<>%&^|=!]="
@@ -25,7 +26,7 @@ PATTERNS("objc",
         /* Objective-C methods */
         "^[ \t]*([-+][ \t]*\\([ \t]*[A-Za-z_][A-Za-z_0-9* \t]*\\)[ \t]*[A-Za-z_].*)$\n"
         /* C functions */
-        "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$\n"
+        "^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$\n"
         /* Objective-C class/protocol definitions */
         "^(@(implementation|interface|protocol)[ \t].*)$",
         /* -- */
diff --git a/ws.c b/ws.c
index b1efcd9d753a29d295702b36fb1beba58fb16995..819c797cf6f7a265c01f00033fa48fdab94a0943 100644 (file)
--- a/ws.c
+++ b/ws.c
 static struct whitespace_rule {
        const char *rule_name;
        unsigned rule_bits;
+       unsigned loosens_error;
 } whitespace_rule_names[] = {
-       { "trailing-space", WS_TRAILING_SPACE },
-       { "space-before-tab", WS_SPACE_BEFORE_TAB },
-       { "indent-with-non-tab", WS_INDENT_WITH_NON_TAB },
-       { "cr-at-eol", WS_CR_AT_EOL },
+       { "trailing-space", WS_TRAILING_SPACE, 0 },
+       { "space-before-tab", WS_SPACE_BEFORE_TAB, 0 },
+       { "indent-with-non-tab", WS_INDENT_WITH_NON_TAB, 0 },
+       { "cr-at-eol", WS_CR_AT_EOL, 1 },
 };
 
 unsigned parse_whitespace_rule(const char *string)
@@ -79,7 +80,8 @@ unsigned whitespace_rule(const char *pathname)
                        unsigned all_rule = 0;
                        int i;
                        for (i = 0; i < ARRAY_SIZE(whitespace_rule_names); i++)
-                               all_rule |= whitespace_rule_names[i].rule_bits;
+                               if (!whitespace_rule_names[i].loosens_error)
+                                       all_rule |= whitespace_rule_names[i].rule_bits;
                        return all_rule;
                } else if (ATTR_FALSE(value)) {
                        /* false (-whitespace) */
index 1b6df45450c39c0f456df68485b5735950816ac8..0ca4b13c29ee6a8cebc1db4ec59f543aef299484 100644 (file)
@@ -13,7 +13,7 @@
 
 int wt_status_relative_paths = 1;
 int wt_status_use_color = -1;
-int wt_status_submodule_summary;
+static int wt_status_submodule_summary;
 static char wt_status_colors[][COLOR_MAXLEN] = {
        GIT_COLOR_NORMAL, /* WT_STATUS_HEADER */
        GIT_COLOR_GREEN,  /* WT_STATUS_UPDATED */