Merge branch 'rr/test-make-sure-we-have-git' into maint
authorJunio C Hamano <gitster@pobox.com>
Wed, 17 Oct 2012 17:27:21 +0000 (10:27 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 17 Oct 2012 17:27:21 +0000 (10:27 -0700)
* rr/test-make-sure-we-have-git:
t/test-lib: make sure Git has already been built

84 files changed:
Documentation/Makefile
Documentation/RelNotes/1.7.12.1.txt
Documentation/RelNotes/1.7.12.2.txt [new file with mode: 0644]
Documentation/RelNotes/1.7.12.3.txt [new file with mode: 0644]
Documentation/fetch-options.txt
Documentation/git-add.txt
Documentation/git-blame.txt
Documentation/git-branch.txt
Documentation/git-clean.txt
Documentation/git-clone.txt
Documentation/git-commit.txt
Documentation/git-fast-import.txt
Documentation/git-filter-branch.txt
Documentation/git-for-each-ref.txt
Documentation/git-format-patch.txt
Documentation/git-log.txt
Documentation/git-ls-remote.txt
Documentation/git-remote.txt
Documentation/git-shortlog.txt
Documentation/git-submodule.txt
Documentation/git.txt
Documentation/gitattributes.txt
Documentation/gitcore-tutorial.txt
Documentation/gitignore.txt
Documentation/gittutorial.txt
Documentation/merge-strategies.txt
Documentation/pretty-formats.txt
Documentation/pretty-options.txt
Documentation/rev-list-options.txt
Documentation/technical/api-argv-array.txt
Documentation/technical/pack-protocol.txt
Documentation/user-manual.txt
GIT-VERSION-GEN
RelNotes
argv-array.c
argv-array.h
attr.c
builtin/blame.c
builtin/clone.c
builtin/commit.c
builtin/config.c
builtin/fetch.c
builtin/grep.c
builtin/ls-remote.c
builtin/mailinfo.c
builtin/receive-pack.c
builtin/remote.c
config.c
contrib/completion/git-completion.bash
contrib/completion/git-prompt.sh
contrib/hooks/post-receive-email
diff.c
dir.c
git-compat-util.h
git-submodule.sh
gitweb/gitweb.perl
grep.c
grep.h
http.c
ll-merge.c
po/de.po
po/sv.po
po/zh_CN.po
remote-curl.c
revision.c
run-command.c
submodule.c
submodule.h
t/t5100-mailinfo.sh
t/t5100/info0017 [new file with mode: 0644]
t/t5100/msg0017 [new file with mode: 0644]
t/t5100/patch0017 [new file with mode: 0644]
t/t5100/sample.mbox
t/t5504-fetch-receive-strict.sh
t/t5505-remote.sh
t/t5514-fetch-multiple.sh
t/t5540-http-push.sh
t/t5551-http-fetch.sh
t/t5709-clone-refspec.sh [new file with mode: 0755]
t/t6037-merge-ours-theirs.sh
t/t7400-submodule-basic.sh
t/t7810-grep.sh
t/t8004-blame-with-conflicts.sh
wrapper.c
index cf5916fe8b79e39eb57f97b36e82697694f41d7a..267dfe135ddef1d5e6cc452d6fdcd8b22b9e36a2 100644 (file)
@@ -44,9 +44,10 @@ man5dir=$(mandir)/man5
 man7dir=$(mandir)/man7
 # DESTDIR=
 
-ASCIIDOC=asciidoc
+ASCIIDOC = asciidoc
 ASCIIDOC_EXTRA =
 MANPAGE_XSL = manpage-normal.xsl
+XMLTO = xmlto
 XMLTO_EXTRA =
 INSTALL?=install
 RM ?= rm -f
@@ -245,7 +246,7 @@ manpage-base-url.xsl: manpage-base-url.xsl.in
 
 %.1 %.5 %.7 : %.xml manpage-base-url.xsl
        $(QUIET_XMLTO)$(RM) $@ && \
-       xmlto -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
+       $(XMLTO) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
 
 %.xml : %.txt
        $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
index 671e3d2eb52160bbac4be214577750f0bc90d105..b8f04af19f9691d046acc914acff78bbfd81f39f 100644 (file)
@@ -85,6 +85,12 @@ Fixes since v1.7.12
    rely on being able to parse "ls-files -s | while read a b c..."
    started to fail.  Protect them from such a misconfiguration.
 
+ * The attribute system may be asked for a path that itself or its
+   leading directories no longer exists in the working tree, and it is
+   fine if we cannot open .gitattribute file in such a case.  Failure
+   to open per-directory .gitattributes with error status other than
+   ENOENT and ENOTDIR should be diagnosed, but it wasn't.
+
  * After "gitk" showed the contents of a tag, neither "Reread
    references" nor "Reload" did not update what is shown as the
    contents of it, when the user overwrote the tag with "git tag -f".
@@ -92,6 +98,9 @@ Fixes since v1.7.12
  * "ciabot" script (in contrib/) has been updated with extensive
    documentation.
 
+ * "git-jump" script (in contrib/) did not work well when
+   diff.noprefix or diff.mnemonicprefix is in effect.
+
  * Older parts of the documentation described as if having a regular
    file in .git/refs/ hierarchy were the only way to have branches and
    tags, which is not true for quite some time.
@@ -121,3 +130,5 @@ Fixes since v1.7.12
    branch name is a parameter to the option, but the heading for the
    option description was "-B::", not "-B branch::", making the
    documentation misleading.
+
+Also contains numerous documentation updates.
diff --git a/Documentation/RelNotes/1.7.12.2.txt b/Documentation/RelNotes/1.7.12.2.txt
new file mode 100644 (file)
index 0000000..6925574
--- /dev/null
@@ -0,0 +1,40 @@
+Git 1.7.12.2 Release Notes
+==========================
+
+Fixes since v1.7.12.1
+---------------------
+
+ * When "git am" is fed an input that has multiple "Content-type: ..."
+   header, it did not grok charset= attribute correctly.
+
+ * Even during a conflicted merge, "git blame $path" always meant to
+   blame uncommitted changes to the "working tree" version; make it
+   more useful by showing cleanly merged parts as coming from the other
+   branch that is being merged.
+
+ * "git blame MAKEFILE" run in a history that has "Makefile" but not
+   "MAKEFILE" should say "No such file MAKEFILE in HEAD", but got
+   confused on a case insensitive filesystem and failed to do so.
+
+ * "git fetch --all", when passed "--no-tags", did not honor the
+   "--no-tags" option while fetching from individual remotes (the same
+   issue existed with "--tags", but combination "--all --tags" makes
+   much less sense than "--all --no-tags").
+
+ * "git log/diff/format-patch --stat" showed the "N line(s) added"
+   comment in user's locale and caused careless submitters to send
+   patches with such a line in them to projects whose project language
+   is not their language, mildly irritating others. Localization to
+   the line has been disabled for now.
+
+ * "git log --all-match --grep=A --grep=B" ought to show commits that
+   mention both A and B, but when these three options are used with
+   --author or --committer, it showed commits that mention either A or
+   B (or both) instead.
+
+ * The subcommand to remove the definition of a remote in "git remote"
+   was named "rm" even though all other subcommands were spelled out.
+   Introduce "git remote remove" to remove confusion, and keep "rm" as
+   a backward compatible synonym.
+
+Also contains a handful of documentation updates.
diff --git a/Documentation/RelNotes/1.7.12.3.txt b/Documentation/RelNotes/1.7.12.3.txt
new file mode 100644 (file)
index 0000000..ecda427
--- /dev/null
@@ -0,0 +1,34 @@
+Git 1.7.12.3 Release Notes
+==========================
+
+Fixes since v1.7.12.2
+---------------------
+
+ * "git am" mishandled a patch attached as application/octet-stream
+   (e.g. not text/*); Content-Transfer-Encoding (e.g. base64) was not
+   honored correctly.
+
+ * It was unclear in the documentation for "git blame" that it is
+   unnecessary for users to use the "--follow" option.
+
+ * A repository created with "git clone --single" had its fetch
+   refspecs set up just like a clone without "--single", leading the
+   subsequent "git fetch" to slurp all the other branches, defeating
+   the whole point of specifying "only this branch".
+
+ * "git fetch" over http had an old workaround for an unlikely server
+   misconfiguration; it turns out that this hurts debuggability of the
+   configuration in general, and has been reverted.
+
+ * "git fetch" over http advertised that it supports "deflate", which
+   is much less common, and did not advertise the more common "gzip" on
+   its Accept-Encoding header.
+
+ * "git receive-pack" (the counterpart to "git push") did not give
+   progress output while processing objects it received to the puser
+   when run over the smart-http protocol.
+
+ * "git status" honored the ignore=dirty settings in .gitmodules but
+   "git commit" didn't.
+
+Also contains a handful of documentation updates.
index 39d326abc63af01d7cffe3d6f0c3df9279bc667e..b4d6476ac898db8ff99ab3639efce08050ef71c4 100644 (file)
@@ -10,7 +10,8 @@
 --depth=<depth>::
        Deepen the history of a 'shallow' repository created by
        `git clone` with `--depth=<depth>` option (see linkgit:git-clone[1])
-       by the specified number of commits.
+       to the specified number of commits from the tip of each remote
+       branch history. Tags for the deepened commits are not fetched.
 
 ifndef::git-pull[]
 --dry-run::
index 9c1d3957223355e00eea917d4a7dff6d50343f32..fd9e36b99f5506964ac8352b82bb7af05551a523 100644 (file)
@@ -155,7 +155,7 @@ Configuration
 The optional configuration variable `core.excludesfile` indicates a path to a
 file containing patterns of file names to exclude from git-add, similar to
 $GIT_DIR/info/exclude.  Patterns in the exclude file are used in addition to
-those in info/exclude.  See linkgit:gitrepository-layout[5].
+those in info/exclude.  See linkgit:gitignore[5].
 
 
 EXAMPLES
index 7ee923629ecc0dbf12a845f18d02c317b6266066..e44173f66afa9e1e1656e7b388fd707c417a1d28 100644 (file)
@@ -20,6 +20,12 @@ last modified the line. Optionally, start annotating from the given revision.
 
 The command can also limit the range of lines annotated.
 
+The origin of lines is automatically followed across whole-file
+renames (currently there is no option to turn the rename-following
+off). To follow lines moved from one file to another, or to follow
+lines that were copied and pasted from another file, etc., see the
+`-C` and `-M` options.
+
 The report does not tell you anything about lines which have been deleted or
 replaced; you need to use a tool such as 'git diff' or the "pickaxe"
 interface briefly mentioned in the following paragraph.
index 47235bea0403bf25fa73529a37a7c5f87d0d7eb9..4f441311c27766da6e1dfa4b1cfe8f228842626a 100644 (file)
@@ -129,11 +129,13 @@ This option is only applicable in non-verbose mode.
        use `git branch --list <pattern>` to list matching branches.
 
 -v::
+-vv::
 --verbose::
        When in list mode,
        show sha1 and commit subject line for each head, along with
        relationship to upstream branch (if any). If given twice, print
-       the name of the upstream branch, as well.
+       the name of the upstream branch, as well (see also `git remote
+       show <remote>`).
 
 -q::
 --quiet::
index 79fb9841441d02cd635dcdd2aecef42d38c6b59d..9f42c0d0e63e8d23bfbf4b582a6a9a60280cca47 100644 (file)
@@ -63,6 +63,10 @@ OPTIONS
        Remove only files ignored by git.  This may be useful to rebuild
        everything from scratch, but keep manually created files.
 
+SEE ALSO
+--------
+linkgit:gitignore[5]
+
 GIT
 ---
 Part of the linkgit:git[1] suite
index c1ddd4c2cc78e078a0849fc8fb82f8de0aa7fc9b..6d98ef3d2ab8c8e63e026dbd7e242d3c3bc3c79a 100644 (file)
@@ -29,7 +29,8 @@ currently active branch.
 After the clone, a plain `git fetch` without arguments will update
 all the remote-tracking branches, and a `git pull` without
 arguments will in addition merge the remote master branch into the
-current master branch, if any.
+current master branch, if any (this is untrue when "--single-branch"
+is given; see below).
 
 This default configuration is achieved by creating references to
 the remote branch heads under `refs/remotes/origin` and
@@ -152,9 +153,10 @@ objects from the source repository into a pack in the cloned repository.
 -b <name>::
        Instead of pointing the newly created HEAD to the branch pointed
        to by the cloned repository's HEAD, point to `<name>` branch
-       instead. `--branch` can also take tags and treat them like
-       detached HEAD. In a non-bare repository, this is the branch
-       that will be checked out.
+       instead. In a non-bare repository, this is the branch that will
+       be checked out.
+       `--branch` can also take tags and detaches the HEAD at that commit
+       in the resulting repository.
 
 --upload-pack <upload-pack>::
 -u <upload-pack>::
@@ -193,6 +195,11 @@ objects from the source repository into a pack in the cloned repository.
        clone with the `--depth` option, this is the default, unless
        `--no-single-branch` is given to fetch the histories near the
        tips of all branches.
+       Further fetches into the resulting repository will only update the
+       remote tracking branch for the branch this option was used for the
+       initial cloning.  If the HEAD at the remote did not point at any
+       branch when `--single-branch` clone was made, no remote tracking
+       branch is created.
 
 --recursive::
 --recurse-submodules::
index 4622297ec98cddc2e1f2e4417b9eeec11a3c91b1..9594ac8e9de9645be71b1528dcb94705f1695283 100644 (file)
@@ -389,8 +389,10 @@ DISCUSSION
 Though not required, it's a good idea to begin the commit message
 with a single short (less than 50 character) line summarizing the
 change, followed by a blank line and then a more thorough description.
-Tools that turn commits into email, for example, use the first line
-on the Subject: line and the rest of the commit in the body.
+The text up to the first blank line in a commit message is treated
+as the commit title, and that title is used throughout git.
+For example, linkgit:git-format-patch[1] turns a commit into email, and it uses
+the title on the Subject line and the rest of the commit in the body.
 
 include::i18n.txt[]
 
index 2620d28b4b38ed3f57ee426e27a2115db8160343..6603a7ab733f4c59dd8725ada536b44bf5e8d12a 100644 (file)
@@ -39,6 +39,10 @@ OPTIONS
        See ``Date Formats'' below for details about which formats
        are supported, and their syntax.
 
+-- done::
+       Terminate with error if there is no 'done' command at the
+       end of the stream.
+
 --force::
        Force updating modified existing branches, even if doing
        so would cause commits to be lost (as the new commit does
@@ -1047,7 +1051,9 @@ done::
        Error out if the stream ends without a 'done' command.
        Without this feature, errors causing the frontend to end
        abruptly at a convenient point in the stream can go
-       undetected.
+       undetected.  This may occur, for example, if an import
+       front end dies in mid-operation without emitting SIGTERM
+       or SIGKILL at its subordinate git fast-import instance.
 
 `option`
 ~~~~~~~~
index 15e7ac80c087eee7d0bf10af5653f421bcbee0dc..e2301f5c0106a35e5fa14d63944abeea2cb09e9b 100644 (file)
@@ -304,6 +304,11 @@ committed a merge between P1 and P2, it will be propagated properly
 and all children of the merge will become merge commits with P1,P2
 as their parents instead of the merge commit.
 
+*NOTE* the changes introduced by the commits, and which are not reverted
+by subsequent commits, will still be in the rewritten branch. If you want
+to throw out _changes_ together with the commits, you should use the
+interactive mode of 'git rebase'.
+
 You can rewrite the commit log messages using `--msg-filter`.  For
 example, 'git svn-id' strings in a repository created by 'git svn' can
 be removed this way:
@@ -314,11 +319,6 @@ git filter-branch --msg-filter '
 '
 -------------------------------------------------------
 
-To restrict rewriting to only part of the history, specify a revision
-range in addition to the new branch name.  The new branch name will
-point to the top-most revision that a 'git rev-list' of this range
-will print.
-
 If you need to add 'Acked-by' lines to, say, the last 10 commits (none
 of which is a merge), use this command:
 
@@ -329,11 +329,10 @@ git filter-branch --msg-filter '
 ' HEAD~10..HEAD
 --------------------------------------------------------
 
-*NOTE* the changes introduced by the commits, and which are not reverted
-by subsequent commits, will still be in the rewritten branch. If you want
-to throw out _changes_ together with the commits, you should use the
-interactive mode of 'git rebase'.
-
+To restrict rewriting to only part of the history, specify a revision
+range in addition to the new branch name.  The new branch name will
+point to the top-most revision that a 'git rev-list' of this range
+will print.
 
 Consider this history:
 
index c872b883ba25144457eccb9967bc68003a3332ea..db55a4e0bbc524c20f08e6862daaa97dd1785b71 100644 (file)
@@ -102,9 +102,10 @@ Fields that have name-email-date tuple as its value (`author`,
 and `date` to extract the named component.
 
 The complete message in a commit and tag object is `contents`.
-Its first line is `contents:subject`, the remaining lines
-are `contents:body` and the optional GPG signature
-is `contents:signature`.
+Its first line is `contents:subject`, where subject is the concatenation
+of all lines of the commit message up to the first blank line.  The next
+line is 'contents:body', where body is all of the lines after the first
+blank line.  Finally, the optional GPG signature is `contents:signature`.
 
 For sorting purposes, fields with numeric values sort in numeric
 order (`objectsize`, `authordate`, `committerdate`, `taggerdate`).
index 04c7346e3e8ba12465e71ad1197ed6a109a473b1..6d43f56279fe7a0d42510035e33424df0bc584f1 100644 (file)
@@ -58,10 +58,13 @@ output, unless the `--stdout` option is specified.
 If `-o` is specified, output files are created in <dir>.  Otherwise
 they are created in the current working directory.
 
-By default, the subject of a single patch is "[PATCH] First Line" and
-the subject when multiple patches are output is "[PATCH n/m] First
-Line". To force 1/1 to be added for a single patch, use `-n`.  To omit
-patch numbers from the subject, use `-N`.
+By default, the subject of a single patch is "[PATCH] " followed by
+the concatenation of lines from the commit message up to the first blank
+line (see the DISCUSSION section of linkgit:git-commit[1]).
+
+When multiple patches are output, the subject prefix will instead be
+"[PATCH n/m] ".  To force 1/1 to be added for a single patch, use `-n`.
+To omit patch numbers from the subject, use `-N`.
 
 If given `--thread`, `git-format-patch` will generate `In-Reply-To` and
 `References` headers to make the second and subsequent patch mails appear
index 1f906208f9514180fe9f20293ab28ce8180b5357..585dac40baabbee291f43a6e7c59c36340286e43 100644 (file)
@@ -24,10 +24,6 @@ each commit introduces are shown.
 OPTIONS
 -------
 
--<n>::
-       Limits the number of commits to show.
-       Note that this is a commit limiting option, see below.
-
 <since>..<until>::
        Show only commits between the named two commits.  When
        either <since> or <until> is omitted, it defaults to
@@ -137,6 +133,8 @@ Examples
        This makes sense only when following a strict policy of merging all
        topic branches when staying on a single integration branch.
 
+`git log -3`::
+       Limits the number of commits to show to 3.
 
 Discussion
 ----------
index 7a9b86a58a1c00c08803e9ef40bb6a17146125a9..774de5e9d9fc2d4d88e4f820be177ea6c0a09360 100644 (file)
@@ -42,6 +42,11 @@ OPTIONS
        it successfully talked with the remote repository, whether it
        found any matching refs.
 
+--get-url::
+       Expand the URL of the given remote repository taking into account any
+       "url.<base>.insteadOf" config setting (See linkgit:git-config[1]) and
+       exit without talking to the remote.
+
 <repository>::
        Location of the repository.  The shorthand defined in
        $GIT_DIR/branches/ can be used. Use "." (dot) to list references in
index a308f4c79f1a879e124486ef6cffbb2e9f8e606c..e8c396b5f92903777ce5905cf52e2ef879850739 100644 (file)
@@ -12,7 +12,7 @@ SYNOPSIS
 'git remote' [-v | --verbose]
 'git remote add' [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--mirror=<fetch|push>] <name> <url>
 'git remote rename' <old> <new>
-'git remote rm' <name>
+'git remote remove' <name>
 'git remote set-head' <name> (-a | -d | <branch>)
 'git remote set-branches' [--add] <name> <branch>...
 'git remote set-url' [--push] <name> <newurl> [<oldurl>]
@@ -85,6 +85,7 @@ In case <old> and <new> are the same, and <old> is a file under
 `$GIT_DIR/remotes` or `$GIT_DIR/branches`, the remote is converted to
 the configuration file format.
 
+'remove'::
 'rm'::
 
 Remove the remote named <name>. All remote-tracking branches and
index 01d8417316e23bc74f2c86df9004091710437ba7..afeb4cdf16df91f63197d390fdbf1540eff66837 100644 (file)
@@ -14,8 +14,7 @@ git log --pretty=short | 'git shortlog' [-h] [-n] [-s] [-e] [-w]
 DESCRIPTION
 -----------
 Summarizes 'git log' output in a format suitable for inclusion
-in release announcements. Each commit will be grouped by author and
-the first line of the commit message will be shown.
+in release announcements. Each commit will be grouped by author and title.
 
 Additionally, "[PATCH]" will be stripped from the commit description.
 
index 2de7bf090094cd4a5c2d6697493040b445077bf7..b4683bba1bc0ea6561a2378c663cf431776a3f7a 100644 (file)
@@ -112,7 +112,6 @@ status::
        initialized, `+` if the currently checked out submodule commit
        does not match the SHA-1 found in the index of the containing
        repository and `U` if the submodule has merge conflicts.
-       This command is the default command for 'git submodule'.
 +
 If `--recursive` is specified, this command will recurse into nested
 submodules, and show their status as well.
index 34d8a1bbdfe974f1ba83028f3875bca5b439f418..d1d227a32d1b110239fc4a789839dd2dadc12d80 100644 (file)
@@ -43,9 +43,12 @@ unreleased) version of git, that is available from 'master'
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
-* link:v1.7.12/git.html[documentation for release 1.7.12]
+* link:v1.7.12.3/git.html[documentation for release 1.7.12.3]
 
 * release notes for
+  link:RelNotes/1.7.12.3.txt[1.7.12.3],
+  link:RelNotes/1.7.12.2.txt[1.7.12.2],
+  link:RelNotes/1.7.12.1.txt[1.7.12.1],
   link:RelNotes/1.7.12.txt[1.7.12].
 
 * link:v1.7.11.7/git.html[documentation for release 1.7.11.7]
index e16f3e175bd8915d139961c649be209b0afc535f..52ab93d2c286d1f91fde8f14eaf6c3742443dcf2 100644 (file)
@@ -66,6 +66,11 @@ is from the path in question, the lower its precedence). Finally
 global and system-wide files are considered (they have the lowest
 precedence).
 
+When the `.gitattributes` file is missing from the work tree, the
+path in the index is used as a fall-back.  During checkout process,
+`.gitattributes` in the index is used and then the file in the
+working tree is used as a fall-back.
+
 If you wish to affect only a single repository (i.e., to assign
 attributes to files that are particular to
 one user's workflow for that repository), then
@@ -927,7 +932,7 @@ file at the toplevel (i.e. not in any subdirectory).  The built-in
 macro attribute "binary" is equivalent to:
 
 ------------
-[attr]binary -diff -text
+[attr]binary -diff -merge -text
 ------------
 
 
index 9d893369a00b6a924876fb234c1082db2021abf3..5325c5a7d5cab3f74c3866319a60d35e4299da2e 100644 (file)
@@ -956,12 +956,11 @@ $ git show-branch --topo-order --more=1 master mybranch
 ------------------------------------------------
 
 The first two lines indicate that it is showing the two branches
-and the first line of the commit log message from their
-top-of-the-tree commits, you are currently on `master` branch
-(notice the asterisk `*` character), and the first column for
-the later output lines is used to show commits contained in the
+with the titles of their top-of-the-tree commits, you are currently on
+`master` branch (notice the asterisk `*` character), and the first
+column for the later output lines is used to show commits contained in the
 `master` branch, and the second column for the `mybranch`
-branch. Three commits are shown along with their log messages.
+branch. Three commits are shown along with their titles.
 All of them have non blank characters in the first column (`*`
 shows an ordinary commit on the current branch, `-` is a merge commit), which
 means they are now part of the `master` branch. Only the "Some
index c1f692a71e54e01f813d84f83eaff4a9514a27b3..96639e02bd143f73a9eab1dde7fbe175414ee785 100644 (file)
@@ -41,18 +41,24 @@ precedence, the last matching pattern decides the outcome):
    variable 'core.excludesfile'.
 
 Which file to place a pattern in depends on how the pattern is meant to
-be used. Patterns which should be version-controlled and distributed to
-other repositories via clone (i.e., files that all developers will want
-to ignore) should go into a `.gitignore` file. Patterns which are
-specific to a particular repository but which do not need to be shared
-with other related repositories (e.g., auxiliary files that live inside
-the repository but are specific to one user's workflow) should go into
-the `$GIT_DIR/info/exclude` file.  Patterns which a user wants git to
-ignore in all situations (e.g., backup or temporary files generated by
-the user's editor of choice) generally go into a file specified by
-`core.excludesfile` in the user's `~/.gitconfig`. Its default value is
-$XDG_CONFIG_HOME/git/ignore. If $XDG_CONFIG_HOME is either not set or empty,
-$HOME/.config/git/ignore is used instead.
+be used.
+
+ * Patterns which should be version-controlled and distributed to
+   other repositories via clone (i.e., files that all developers will want
+   to ignore) should go into a `.gitignore` file.
+
+ * Patterns which are
+   specific to a particular repository but which do not need to be shared
+   with other related repositories (e.g., auxiliary files that live inside
+   the repository but are specific to one user's workflow) should go into
+   the `$GIT_DIR/info/exclude` file.
+
+ * Patterns which a user wants git to
+   ignore in all situations (e.g., backup or temporary files generated by
+   the user's editor of choice) generally go into a file specified by
+   `core.excludesfile` in the user's `~/.gitconfig`. Its default value is
+   $XDG_CONFIG_HOME/git/ignore. If $XDG_CONFIG_HOME is either not set or
+   empty, $HOME/.config/git/ignore is used instead.
 
 The underlying git plumbing tools, such as
 'git ls-files' and 'git read-tree', read
index dee050567e65301066629c566613b84c6c065169..f1cb6f3be67fbb03583a35601791f0db839fbe1b 100644 (file)
@@ -139,9 +139,11 @@ them to the index, and commit, all in one step.
 A note on commit messages: Though not required, it's a good idea to
 begin the commit message with a single short (less than 50 character)
 line summarizing the change, followed by a blank line and then a more
-thorough description.  Tools that turn commits into email, for
-example, use the first line on the Subject: line and the rest of the
-commit in the body.
+thorough description. The text up to the first blank line in a commit
+message is treated as the commit title, and that title is used
+throughout git.  For example, linkgit:git-format-patch[1] turns a
+commit into email, and it uses the title on the Subject line and the
+rest of the commit in the body.
 
 Git tracks content not files
 ----------------------------
index 595a3cf1a7118ba29a1d57d7fc17d233d89cd3d0..66db80296f505a9bd830c746f82bb54e3f49f313 100644 (file)
@@ -32,13 +32,14 @@ ours;;
        This option forces conflicting hunks to be auto-resolved cleanly by
        favoring 'our' version.  Changes from the other tree that do not
        conflict with our side are reflected to the merge result.
+       For a binary file, the entire contents are taken from our side.
 +
 This should not be confused with the 'ours' merge strategy, which does not
 even look at what the other tree contains at all.  It discards everything
 the other tree did, declaring 'our' history contains all that happened in it.
 
 theirs;;
-       This is opposite of 'ours'.
+       This is the opposite of 'ours'.
 
 patience;;
        With this option, 'merge-recursive' spends a little extra time
index e3d8a83b23aff51c8dd4281f18de8661514b62b1..d9eddedc72a5e6362d68df1b126b76804b9676e1 100644 (file)
@@ -130,6 +130,9 @@ The placeholders are:
 - '%b': body
 - '%B': raw body (unwrapped subject and body)
 - '%N': commit notes
+- '%GG': raw verification message from GPG for a signed commit
+- '%G?': show either "G" for Good or "B" for Bad for a signed commit
+- '%GS': show the name of the signer for a signed commit
 - '%gD': reflog selector, e.g., `refs/stash@{1}`
 - '%gd': shortened reflog selector, e.g., `stash@{1}`
 - '%gn': reflog identity name
index 2a3dc8664f16957a05bc4d81824d7995517ac89c..5e499421a43526e133c7bd3be134da803b35c00d 100644 (file)
@@ -66,3 +66,7 @@ being displayed. Examples: "--notes=foo" will show only notes from
 --[no-]standard-notes::
        These options are deprecated. Use the above --notes/--no-notes
        options instead.
+
+--show-signature::
+       Check the validity of a signed commit object by passing the signature
+       to `gpg --verify` and show the output.
index 5436eba6e761716cfeaee2683566137736497791..1fc2a18404bd34a2e1ac9f5fe21d64c1827f13a6 100644 (file)
@@ -3,12 +3,20 @@ Commit Limiting
 
 Besides specifying a range of commits that should be listed using the
 special notations explained in the description, additional commit
-limiting may be applied. Note that they are applied before commit
-ordering and formatting options, such as '--reverse'.
+limiting may be applied.
+
+Using more options generally further limits the output (e.g.
+`--since=<date1>` limits to commits newer than `<date1>`, and using it
+with `--grep=<pattern>` further limits to commits whose log message
+has a line that matches `<pattern>`), unless otherwise noted.
+
+Note that these are applied before commit
+ordering and formatting options, such as `--reverse`.
 
 --
 
--n 'number'::
+-<number>::
+-n <number>::
 --max-count=<number>::
 
        Limit the number of commits to output.
@@ -38,16 +46,22 @@ endif::git-rev-list[]
 --committer=<pattern>::
 
        Limit the commits output to ones with author/committer
-       header lines that match the specified pattern (regular expression).
+       header lines that match the specified pattern (regular
+       expression).  With more than one `--author=<pattern>`,
+       commits whose author matches any of the given patterns are
+       chosen (similarly for multiple `--committer=<pattern>`).
 
 --grep=<pattern>::
 
        Limit the commits output to ones with log message that
-       matches the specified pattern (regular expression).
+       matches the specified pattern (regular expression).  With
+       more than one `--grep=<pattern>`, commits whose message
+       matches any of the given patterns are chosen (but see
+       `--all-match`).
 
 --all-match::
        Limit the commits output to ones that match all given --grep,
-       --author and --committer instead of ones that match at least one.
+       instead of ones that match at least one.
 
 -i::
 --regexp-ignore-case::
index 1b7d8f140c27d76cfa460c0839c44c6742110df7..1a797812fb426189b03a814498dd7019c96607b4 100644 (file)
@@ -46,6 +46,10 @@ Functions
        Format a string and push it onto the end of the array. This is a
        convenience wrapper combining `strbuf_addf` and `argv_array_push`.
 
+`argv_array_pop`::
+       Remove the final element from the array. If there are no
+       elements in the array, do nothing.
+
 `argv_array_clear`::
        Free all memory associated with the array and return it to the
        initial, empty state.
index 49cdc571cd7e276df2913b0ccf9d1e2320b31c9d..d51e20f3526e2681b8c05c296b91dd90a4d3e322 100644 (file)
@@ -259,8 +259,10 @@ a positive depth, this step is skipped.
 ----
 
 If the client has requested a positive depth, the server will compute
-the set of commits which are no deeper than the desired depth, starting
-at the client's wants. The server writes 'shallow' lines for each
+the set of commits which are no deeper than the desired depth. The set
+of commits start at the client's wants.
+
+The server writes 'shallow' lines for each
 commit whose parents will not be sent as a result. The server writes
 an 'unshallow' line for each commit which the client has indicated is
 shallow, but is no longer shallow at the currently requested depth
index 03d95dc290cecd2223116be90b591f75d40ced2b..85651b57ae466496e98e9c2507072f9fa8125c4d 100644 (file)
@@ -1136,9 +1136,12 @@ Creating good commit messages
 Though not required, it's a good idea to begin the commit message
 with a single short (less than 50 character) line summarizing the
 change, followed by a blank line and then a more thorough
-description.  Tools that turn commits into email, for example, use
-the first line on the Subject line and the rest of the commit in the
-body.
+description.  The text up to the first blank line in a commit
+message is treated as the commit title, and that title is used
+throughout git.  For example, linkgit:git-format-patch[1] turns a
+commit into email, and it uses the title on the Subject line and the
+rest of the commit in the body.
+
 
 [[ignoring-files]]
 Ignoring files
index b27a2ff687183607854ed630519b30e4136d0b6c..ecdbf905a32288937e1a3eec65aa7f925ea30446 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.12
+DEF_VER=v1.7.12.3
 
 LF='
 '
index 53d76d1a47e0750b0d8b14287ff3d923ca55b438..9cd9140a6b6e8ee15dc2b237795b1117b0140842 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/1.7.12.1.txt
\ No newline at end of file
+Documentation/RelNotes/1.7.12.3.txt
\ No newline at end of file
index 0b5f8898a10f16df8a6273f8960f05b670ba94bc..256741d2262b237c56b6730bea9d52c9b39b7ee3 100644 (file)
@@ -49,12 +49,21 @@ void argv_array_pushl(struct argv_array *array, ...)
        va_end(ap);
 }
 
+void argv_array_pop(struct argv_array *array)
+{
+       if (!array->argc)
+               return;
+       free((char *)array->argv[array->argc - 1]);
+       array->argv[array->argc - 1] = NULL;
+       array->argc--;
+}
+
 void argv_array_clear(struct argv_array *array)
 {
        if (array->argv != empty_argv) {
                int i;
                for (i = 0; i < array->argc; i++)
-                       free((char **)array->argv[i]);
+                       free((char *)array->argv[i]);
                free(array->argv);
        }
        argv_array_init(array);
index b93a69c36cb8d391c1d7de93f75b3d54c00e60ca..f4b98660f8a98e2cecdf70285d1d76205b3f4be7 100644 (file)
@@ -16,6 +16,7 @@ void argv_array_push(struct argv_array *, const char *);
 __attribute__((format (printf,2,3)))
 void argv_array_pushf(struct argv_array *, const char *fmt, ...);
 void argv_array_pushl(struct argv_array *, ...);
+void argv_array_pop(struct argv_array *);
 void argv_array_clear(struct argv_array *);
 
 #endif /* ARGV_ARRAY_H */
diff --git a/attr.c b/attr.c
index b52efb55a036be10618d531d66697d7f7220c524..887a9ae46b7044489845abf2072339271caf2d4a 100644 (file)
--- a/attr.c
+++ b/attr.c
@@ -306,7 +306,7 @@ static void free_attr_elem(struct attr_stack *e)
 }
 
 static const char *builtin_attr[] = {
-       "[attr]binary -diff -text",
+       "[attr]binary -diff -merge -text",
        NULL,
 };
 
@@ -352,8 +352,11 @@ static struct attr_stack *read_attr_from_file(const char *path, int macro_ok)
        char buf[2048];
        int lineno = 0;
 
-       if (!fp)
+       if (!fp) {
+               if (errno != ENOENT && errno != ENOTDIR)
+                       warn_on_inaccessible(path);
                return NULL;
+       }
        res = xcalloc(1, sizeof(*res));
        while (fgets(buf, sizeof(buf), fp))
                handle_attr_line(res, buf, path, ++lineno, macro_ok);
index ed5d01b36a309a53619c2615aed2382b2aebf056..409eb423959b17453cf9607c406b260f12cf98fc 100644 (file)
@@ -2069,6 +2069,55 @@ static int git_blame_config(const char *var, const char *value, void *cb)
        return git_default_config(var, value, cb);
 }
 
+static void verify_working_tree_path(struct commit *work_tree, const char *path)
+{
+       struct commit_list *parents;
+
+       for (parents = work_tree->parents; parents; parents = parents->next) {
+               const unsigned char *commit_sha1 = parents->item->object.sha1;
+               unsigned char blob_sha1[20];
+               unsigned mode;
+
+               if (!get_tree_entry(commit_sha1, path, blob_sha1, &mode) &&
+                   sha1_object_info(blob_sha1, NULL) == OBJ_BLOB)
+                       return;
+       }
+       die("no such path '%s' in HEAD", path);
+}
+
+static struct commit_list **append_parent(struct commit_list **tail, const unsigned char *sha1)
+{
+       struct commit *parent;
+
+       parent = lookup_commit_reference(sha1);
+       if (!parent)
+               die("no such commit %s", sha1_to_hex(sha1));
+       return &commit_list_insert(parent, tail)->next;
+}
+
+static void append_merge_parents(struct commit_list **tail)
+{
+       int merge_head;
+       const char *merge_head_file = git_path("MERGE_HEAD");
+       struct strbuf line = STRBUF_INIT;
+
+       merge_head = open(merge_head_file, O_RDONLY);
+       if (merge_head < 0) {
+               if (errno == ENOENT)
+                       return;
+               die("cannot open '%s' for reading", merge_head_file);
+       }
+
+       while (!strbuf_getwholeline_fd(&line, merge_head, '\n')) {
+               unsigned char sha1[20];
+               if (line.len < 40 || get_sha1_hex(line.buf, sha1))
+                       die("unknown line in '%s': %s", merge_head_file, line.buf);
+               tail = append_parent(tail, sha1);
+       }
+       close(merge_head);
+       strbuf_release(&line);
+}
+
 /*
  * Prepare a dummy commit that represents the work tree (or staged) item.
  * Note that annotating work tree item never works in the reverse.
@@ -2079,6 +2128,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
 {
        struct commit *commit;
        struct origin *origin;
+       struct commit_list **parent_tail, *parent;
        unsigned char head_sha1[20];
        struct strbuf buf = STRBUF_INIT;
        const char *ident;
@@ -2086,20 +2136,38 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
        int size, len;
        struct cache_entry *ce;
        unsigned mode;
-
-       if (get_sha1("HEAD", head_sha1))
-               die("No such ref: HEAD");
+       struct strbuf msg = STRBUF_INIT;
 
        time(&now);
        commit = xcalloc(1, sizeof(*commit));
-       commit->parents = xcalloc(1, sizeof(*commit->parents));
-       commit->parents->item = lookup_commit_reference(head_sha1);
        commit->object.parsed = 1;
        commit->date = now;
        commit->object.type = OBJ_COMMIT;
+       parent_tail = &commit->parents;
+
+       if (!resolve_ref_unsafe("HEAD", head_sha1, 1, NULL))
+               die("no such ref: HEAD");
+
+       parent_tail = append_parent(parent_tail, head_sha1);
+       append_merge_parents(parent_tail);
+       verify_working_tree_path(commit, path);
 
        origin = make_origin(commit, path);
 
+       ident = fmt_ident("Not Committed Yet", "not.committed.yet", NULL, 0);
+       strbuf_addstr(&msg, "tree 0000000000000000000000000000000000000000\n");
+       for (parent = commit->parents; parent; parent = parent->next)
+               strbuf_addf(&msg, "parent %s\n",
+                           sha1_to_hex(parent->item->object.sha1));
+       strbuf_addf(&msg,
+                   "author %s\n"
+                   "committer %s\n\n"
+                   "Version of %s from %s\n",
+                   ident, ident, path,
+                   (!contents_from ? path :
+                    (!strcmp(contents_from, "-") ? "standard input" : contents_from)));
+       commit->buffer = strbuf_detach(&msg, NULL);
+
        if (!contents_from || strcmp("-", contents_from)) {
                struct stat st;
                const char *read_from;
@@ -2136,7 +2204,6 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
        }
        else {
                /* Reading from stdin */
-               contents_from = "standard input";
                mode = 0;
                if (strbuf_read(&buf, 0, 0) < 0)
                        die_errno("failed to read from stdin");
@@ -2181,16 +2248,6 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
         */
        cache_tree_invalidate_path(active_cache_tree, path);
 
-       commit->buffer = xmalloc(400);
-       ident = fmt_ident("Not Committed Yet", "not.committed.yet", NULL, 0);
-       snprintf(commit->buffer, 400,
-               "tree 0000000000000000000000000000000000000000\n"
-               "parent %s\n"
-               "author %s\n"
-               "committer %s\n\n"
-               "Version of %s from %s\n",
-               sha1_to_hex(head_sha1),
-               ident, ident, path, contents_from ? contents_from : path);
        return commit;
 }
 
index e314b0b6d2133b09307dc09fa256577e6cdba03a..0d663e34f78431280eb7f79d581262a7c28820d3 100644 (file)
@@ -610,6 +610,54 @@ static void write_config(struct string_list *config)
        }
 }
 
+static void write_refspec_config(const char* src_ref_prefix,
+               const struct ref* our_head_points_at,
+               const struct ref* remote_head_points_at, struct strbuf* branch_top)
+{
+       struct strbuf key = STRBUF_INIT;
+       struct strbuf value = STRBUF_INIT;
+
+       if (option_mirror || !option_bare) {
+               if (option_single_branch && !option_mirror) {
+                       if (option_branch) {
+                               if (strstr(our_head_points_at->name, "refs/tags/"))
+                                       strbuf_addf(&value, "+%s:%s", our_head_points_at->name,
+                                               our_head_points_at->name);
+                               else
+                                       strbuf_addf(&value, "+%s:%s%s", our_head_points_at->name,
+                                               branch_top->buf, option_branch);
+                       } else if (remote_head_points_at) {
+                               strbuf_addf(&value, "+%s:%s%s", remote_head_points_at->name,
+                                               branch_top->buf,
+                                               skip_prefix(remote_head_points_at->name, "refs/heads/"));
+                       }
+                       /*
+                        * otherwise, the next "git fetch" will
+                        * simply fetch from HEAD without updating
+                        * any remote tracking branch, which is what
+                        * we want.
+                        */
+               } else {
+                       strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top->buf);
+               }
+               /* Configure the remote */
+               if (value.len) {
+                       strbuf_addf(&key, "remote.%s.fetch", option_origin);
+                       git_config_set_multivar(key.buf, value.buf, "^$", 0);
+                       strbuf_reset(&key);
+
+                       if (option_mirror) {
+                               strbuf_addf(&key, "remote.%s.mirror", option_origin);
+                               git_config_set(key.buf, "true");
+                               strbuf_reset(&key);
+                       }
+               }
+       }
+
+       strbuf_release(&key);
+       strbuf_release(&value);
+}
+
 int cmd_clone(int argc, const char **argv, const char *prefix)
 {
        int is_bundle = 0, is_local;
@@ -755,20 +803,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        }
 
        strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
-
-       if (option_mirror || !option_bare) {
-               /* Configure the remote */
-               strbuf_addf(&key, "remote.%s.fetch", option_origin);
-               git_config_set_multivar(key.buf, value.buf, "^$", 0);
-               strbuf_reset(&key);
-
-               if (option_mirror) {
-                       strbuf_addf(&key, "remote.%s.mirror", option_origin);
-                       git_config_set(key.buf, "true");
-                       strbuf_reset(&key);
-               }
-       }
-
        strbuf_addf(&key, "remote.%s.url", option_origin);
        git_config_set(key.buf, repo);
        strbuf_reset(&key);
@@ -853,6 +887,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
                                              "refs/heads/master");
        }
 
+       write_refspec_config(src_ref_prefix, our_head_points_at,
+                       remote_head_points_at, &branch_top);
+
        if (is_local)
                clone_local(path, git_dir);
        else if (refs && complete_refs_before_fetch)
index 62028e7b44b206e9722eef750be8c067aae31b32..7a83cae6ff9d0168c3d9be4241e3cd94f1128a23 100644 (file)
@@ -1452,6 +1452,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
                usage_with_options(builtin_commit_usage, builtin_commit_options);
 
        wt_status_prepare(&s);
+       gitmodules_config();
        git_config(git_commit_config, &s);
        determine_whence(&s);
        s.colopts = 0;
index ada6e1211462558f307dce6142b7b65d641c8e02..442ccc2497c4e2e889d9de55359e36a1db07c1a4 100644 (file)
@@ -400,8 +400,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
                         */
                        die("$HOME not set");
 
-               if (access(user_config, R_OK) &&
-                   xdg_config && !access(xdg_config, R_OK))
+               if (access_or_warn(user_config, R_OK) &&
+                   xdg_config && !access_or_warn(xdg_config, R_OK))
                        given_config_file = xdg_config;
                else
                        given_config_file = user_config;
index bb9a0743ff565f3002eb0fede8e35b7f01a73b75..f483352fe57c200415463078d834bd0712c22705 100644 (file)
@@ -14,6 +14,7 @@
 #include "transport.h"
 #include "submodule.h"
 #include "connected.h"
+#include "argv-array.h"
 
 static const char * const builtin_fetch_usage[] = {
        "git fetch [<options>] [<repository> [<refspec>...]]",
@@ -841,38 +842,39 @@ static int add_remote_or_group(const char *name, struct string_list *list)
        return 1;
 }
 
-static void add_options_to_argv(int *argc, const char **argv)
+static void add_options_to_argv(struct argv_array *argv)
 {
        if (dry_run)
-               argv[(*argc)++] = "--dry-run";
+               argv_array_push(argv, "--dry-run");
        if (prune)
-               argv[(*argc)++] = "--prune";
+               argv_array_push(argv, "--prune");
        if (update_head_ok)
-               argv[(*argc)++] = "--update-head-ok";
+               argv_array_push(argv, "--update-head-ok");
        if (force)
-               argv[(*argc)++] = "--force";
+               argv_array_push(argv, "--force");
        if (keep)
-               argv[(*argc)++] = "--keep";
+               argv_array_push(argv, "--keep");
        if (recurse_submodules == RECURSE_SUBMODULES_ON)
-               argv[(*argc)++] = "--recurse-submodules";
+               argv_array_push(argv, "--recurse-submodules");
        else if (recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)
-               argv[(*argc)++] = "--recurse-submodules=on-demand";
+               argv_array_push(argv, "--recurse-submodules=on-demand");
+       if (tags == TAGS_SET)
+               argv_array_push(argv, "--tags");
+       else if (tags == TAGS_UNSET)
+               argv_array_push(argv, "--no-tags");
        if (verbosity >= 2)
-               argv[(*argc)++] = "-v";
+               argv_array_push(argv, "-v");
        if (verbosity >= 1)
-               argv[(*argc)++] = "-v";
+               argv_array_push(argv, "-v");
        else if (verbosity < 0)
-               argv[(*argc)++] = "-q";
+               argv_array_push(argv, "-q");
 
 }
 
 static int fetch_multiple(struct string_list *list)
 {
        int i, result = 0;
-       const char *argv[12] = { "fetch", "--append" };
-       int argc = 2;
-
-       add_options_to_argv(&argc, argv);
+       struct argv_array argv = ARGV_ARRAY_INIT;
 
        if (!append && !dry_run) {
                int errcode = truncate_fetch_head();
@@ -880,18 +882,22 @@ static int fetch_multiple(struct string_list *list)
                        return errcode;
        }
 
+       argv_array_pushl(&argv, "fetch", "--append", NULL);
+       add_options_to_argv(&argv);
+
        for (i = 0; i < list->nr; i++) {
                const char *name = list->items[i].string;
-               argv[argc] = name;
-               argv[argc + 1] = NULL;
+               argv_array_push(&argv, name);
                if (verbosity >= 0)
                        printf(_("Fetching %s\n"), name);
-               if (run_command_v_opt(argv, RUN_GIT_CMD)) {
+               if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {
                        error(_("Could not fetch %s"), name);
                        result = 1;
                }
+               argv_array_pop(&argv);
        }
 
+       argv_array_clear(&argv);
        return result;
 }
 
@@ -1007,13 +1013,14 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
        }
 
        if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF)) {
-               const char *options[10];
-               int num_options = 0;
-               add_options_to_argv(&num_options, options);
-               result = fetch_populated_submodules(num_options, options,
+               struct argv_array options = ARGV_ARRAY_INIT;
+
+               add_options_to_argv(&options);
+               result = fetch_populated_submodules(&options,
                                                    submodule_prefix,
                                                    recurse_submodules,
                                                    verbosity < 0);
+               argv_array_clear(&options);
        }
 
        /* All names were strdup()ed or strndup()ed */
index 29adb0ac9399002b07942711863fa3b353926468..0654e0b0f693f9cdd4ba2d7f84c110f7ef8b11b4 100644 (file)
@@ -209,6 +209,7 @@ static void start_threads(struct grep_opt *opt)
                int err;
                struct grep_opt *o = grep_opt_dup(opt);
                o->output = strbuf_out;
+               o->debug = 0;
                compile_grep_patterns(o);
                err = pthread_create(&threads[i], NULL, run, o);
 
@@ -772,6 +773,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
                           "indicate hit with exit status without output"),
                OPT_BOOLEAN(0, "all-match", &opt.all_match,
                        "show only matches from files that match all patterns"),
+               { OPTION_SET_INT, 0, "debug", &opt.debug, NULL,
+                 "show parse tree for grep expression",
+                 PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1 },
                OPT_GROUP(""),
                { OPTION_STRING, 'O', "open-files-in-pager", &show_in_pager,
                        "pager", "show matching files in the pager",
index 41c88a98a2de1ce817351243f9aa9e2811604097..25e83cfe9de3dc3cee19f03f82b56396eb6b65de 100644 (file)
@@ -5,7 +5,7 @@
 
 static const char ls_remote_usage[] =
 "git ls-remote [--heads] [--tags]  [-u <exec> | --upload-pack <exec>]\n"
-"                     [-q|--quiet] [--exit-code] [<repository> [<refs>...]]";
+"                     [-q|--quiet] [--exit-code] [--get-url] [<repository> [<refs>...]]";
 
 /*
  * Is there one among the list of patterns that match the tail part
index eaf9e157a3897c2442756911b906ff9d3ee2be90..fe128572f7780c4544d8023be2989f5e037b5bef 100644 (file)
@@ -19,9 +19,6 @@ static struct strbuf email = STRBUF_INIT;
 static enum  {
        TE_DONTCARE, TE_QP, TE_BASE64
 } transfer_encoding;
-static enum  {
-       TYPE_TEXT, TYPE_OTHER
-} message_type;
 
 static struct strbuf charset = STRBUF_INIT;
 static int patch_lines;
@@ -160,10 +157,9 @@ static int slurp_attr(const char *line, const char *name, struct strbuf *attr)
        const char *ends, *ap = strcasestr(line, name);
        size_t sz;
 
-       if (!ap) {
-               strbuf_setlen(attr, 0);
+       strbuf_setlen(attr, 0);
+       if (!ap)
                return 0;
-       }
        ap += strlen(name);
        if (*ap == '"') {
                ap++;
@@ -185,8 +181,6 @@ static void handle_content_type(struct strbuf *line)
        struct strbuf *boundary = xmalloc(sizeof(struct strbuf));
        strbuf_init(boundary, line->len);
 
-       if (!strcasestr(line->buf, "text/"))
-                message_type = TYPE_OTHER;
        if (slurp_attr(line->buf, "boundary=", boundary)) {
                strbuf_insert(boundary, 0, "--", 2);
                if (++content_top > &content[MAX_BOUNDARIES]) {
@@ -232,7 +226,9 @@ static void cleanup_subject(struct strbuf *subject)
                case 'r': case 'R':
                        if (subject->len <= at + 3)
                                break;
-                       if (!memcmp(subject->buf + at + 1, "e:", 2)) {
+                       if ((subject->buf[at + 1] == 'e' ||
+                            subject->buf[at + 1] == 'E') &&
+                           subject->buf[at + 2] == ':') {
                                strbuf_remove(subject, at, 3);
                                continue;
                        }
@@ -680,7 +676,6 @@ static int handle_boundary(void)
        /* set some defaults */
        transfer_encoding = TE_DONTCARE;
        strbuf_reset(&charset);
-       message_type = TYPE_TEXT;
 
        /* slurp in this section's info */
        while (read_one_header_line(&line, fin))
@@ -894,11 +889,6 @@ static void handle_body(void)
                        strbuf_insert(&line, 0, prev.buf, prev.len);
                        strbuf_reset(&prev);
 
-                       /* binary data most likely doesn't have newlines */
-                       if (message_type != TYPE_TEXT) {
-                               handle_filter(&line);
-                               break;
-                       }
                        /*
                         * This is a decoded line that may contain
                         * multiple new lines.  Pass only one chunk
index 2cb854feb4b3a701201ef683c6644aaa852d50b5..165a633204bed5ffc279e3af703a3d275e3e3822 100644 (file)
@@ -701,7 +701,7 @@ static void execute_commands(struct command *commands, const char *unpacker_erro
 
        if (unpacker_error) {
                for (cmd = commands; cmd; cmd = cmd->next)
-                       cmd->error_string = "n/a (unpacker error)";
+                       cmd->error_string = "unpacker error";
                return;
        }
 
@@ -801,7 +801,7 @@ static const char *parse_pack_header(struct pack_header *hdr)
 
 static const char *pack_lockfile;
 
-static const char *unpack(void)
+static const char *unpack(int err_fd)
 {
        struct pack_header hdr;
        const char *hdr_err;
@@ -821,6 +821,7 @@ static const char *unpack(void)
 
        if (ntohl(hdr.hdr_entries) < unpack_limit) {
                int code, i = 0;
+               struct child_process child;
                const char *unpacker[5];
                unpacker[i++] = "unpack-objects";
                if (quiet)
@@ -829,7 +830,12 @@ static const char *unpack(void)
                        unpacker[i++] = "--strict";
                unpacker[i++] = hdr_arg;
                unpacker[i++] = NULL;
-               code = run_command_v_opt(unpacker, RUN_GIT_CMD);
+               memset(&child, 0, sizeof(child));
+               child.argv = unpacker;
+               child.no_stdout = 1;
+               child.err = err_fd;
+               child.git_cmd = 1;
+               code = run_command(&child);
                if (!code)
                        return NULL;
                return "unpack-objects abnormal exit";
@@ -854,6 +860,7 @@ static const char *unpack(void)
                memset(&ip, 0, sizeof(ip));
                ip.argv = keeper;
                ip.out = -1;
+               ip.err = err_fd;
                ip.git_cmd = 1;
                status = start_command(&ip);
                if (status) {
@@ -870,6 +877,26 @@ static const char *unpack(void)
        }
 }
 
+static const char *unpack_with_sideband(void)
+{
+       struct async muxer;
+       const char *ret;
+
+       if (!use_sideband)
+               return unpack(0);
+
+       memset(&muxer, 0, sizeof(muxer));
+       muxer.proc = copy_to_sideband;
+       muxer.in = -1;
+       if (start_async(&muxer))
+               return NULL;
+
+       ret = unpack(muxer.in);
+
+       finish_async(&muxer);
+       return ret;
+}
+
 static void report(struct command *commands, const char *unpack_status)
 {
        struct command *cmd;
@@ -967,7 +994,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
                const char *unpack_status = NULL;
 
                if (!delete_only(commands))
-                       unpack_status = unpack();
+                       unpack_status = unpack_with_sideband();
                execute_commands(commands, unpack_status);
                if (pack_lockfile)
                        unlink_or_warn(pack_lockfile);
index 920262d76ec9bdc40a8ad7703cf1eb972a40eb9e..357d59d66792308c4c4d767523767c6d078d7341 100644 (file)
@@ -11,7 +11,7 @@ static const char * const builtin_remote_usage[] = {
        "git remote [-v | --verbose]",
        "git remote add [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--mirror=<fetch|push>] <name> <url>",
        "git remote rename <old> <new>",
-       "git remote rm <name>",
+       "git remote remove <name>",
        "git remote set-head <name> (-a | -d | <branch>)",
        "git remote [-v | --verbose] show [-n] <name>",
        "git remote prune [-n | --dry-run] <name>",
@@ -34,7 +34,7 @@ static const char * const builtin_remote_rename_usage[] = {
 };
 
 static const char * const builtin_remote_rm_usage[] = {
-       "git remote rm <name>",
+       "git remote remove <name>",
        NULL
 };
 
@@ -1580,7 +1580,7 @@ int cmd_remote(int argc, const char **argv, const char *prefix)
                result = add(argc, argv);
        else if (!strcmp(argv[0], "rename"))
                result = mv(argc, argv);
-       else if (!strcmp(argv[0], "rm"))
+       else if (!strcmp(argv[0], "rm") || !strcmp(argv[0], "remove"))
                result = rm(argc, argv);
        else if (!strcmp(argv[0], "set-head"))
                result = set_head(argc, argv);
index 2b706ea2053714fdcec8997d978ce5688d072941..08e47e2e48a5bd310025752ee5ecdce81721b34d 100644 (file)
--- a/config.c
+++ b/config.c
@@ -60,7 +60,7 @@ static int handle_path_include(const char *path, struct config_include_data *inc
                path = buf.buf;
        }
 
-       if (!access(path, R_OK)) {
+       if (!access_or_warn(path, R_OK)) {
                if (++inc->depth > MAX_INCLUDE_DEPTH)
                        die(include_depth_advice, MAX_INCLUDE_DEPTH, path,
                            cf && cf->name ? cf->name : "the command line");
@@ -939,23 +939,23 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config)
 
        home_config_paths(&user_config, &xdg_config, "config");
 
-       if (git_config_system() && !access(git_etc_gitconfig(), R_OK)) {
+       if (git_config_system() && !access_or_warn(git_etc_gitconfig(), R_OK)) {
                ret += git_config_from_file(fn, git_etc_gitconfig(),
                                            data);
                found += 1;
        }
 
-       if (xdg_config && !access(xdg_config, R_OK)) {
+       if (xdg_config && !access_or_warn(xdg_config, R_OK)) {
                ret += git_config_from_file(fn, xdg_config, data);
                found += 1;
        }
 
-       if (user_config && !access(user_config, R_OK)) {
+       if (user_config && !access_or_warn(user_config, R_OK)) {
                ret += git_config_from_file(fn, user_config, data);
                found += 1;
        }
 
-       if (repo_config && !access(repo_config, R_OK)) {
+       if (repo_config && !access_or_warn(repo_config, R_OK)) {
                ret += git_config_from_file(fn, repo_config, data);
                found += 1;
        }
index d743e56d18951da435d8ffe282c06450f2dfac39..5b255cba69661a2f4d5b6cfa9dbc6a171c5f91ee 100644 (file)
@@ -2033,7 +2033,7 @@ _git_config ()
 
 _git_remote ()
 {
-       local subcommands="add rename rm set-head set-branches set-url show prune update"
+       local subcommands="add rename remove set-head set-branches set-url show prune update"
        local subcommand="$(__git_find_on_cmdline "$subcommands")"
        if [ -z "$subcommand" ]; then
                __gitcomp "$subcommands"
@@ -2041,7 +2041,7 @@ _git_remote ()
        fi
 
        case "$subcommand" in
-       rename|rm|set-url|show|prune)
+       rename|remove|set-url|show|prune)
                __gitcomp_nl "$(__git_remotes)"
                ;;
        set-head|set-branches)
index 29b1ec9eb1797e0f2c3c9f7067222432150ba85f..bf20491ec33e467f6b9591d94a2e27bc9e3d93e9 100644 (file)
 #
 # If you would like to see the difference between HEAD and its upstream,
 # set GIT_PS1_SHOWUPSTREAM="auto".  A "<" indicates you are behind, ">"
-# indicates you are ahead, and "<>" indicates you have diverged.  You
-# can further control behaviour by setting GIT_PS1_SHOWUPSTREAM to a
-# space-separated list of values:
+# indicates you are ahead, "<>" indicates you have diverged and "="
+# indicates that there is no difference. You can further control
+# behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated list
+# of values:
 #
 #     verbose       show number of commits ahead/behind (+/-) upstream
 #     legacy        don't use the '--count' option available in recent
index 01af9df15e180288723caadf42b500fe78a8c694..b2171a092eafef4cf1e5e1abfa37695a0c111927 100755 (executable)
@@ -403,7 +403,7 @@ generate_update_branch_email()
                        echo "            \\"
                        echo "             O -- O -- O ($oldrev)"
                        echo ""
-                       echo "The removed revisions are not necessarilly gone - if another reference"
+                       echo "The removed revisions are not necessarily gone - if another reference"
                        echo "still refers to them they will stay in the repository."
                        rewind_only=1
                else
diff --git a/diff.c b/diff.c
index e6846ca7507aa8a423c5e1f89390fa37723248ff..32142dba64e0a6e926101c38b6efd95d21e0dc82 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -1398,11 +1398,11 @@ int print_stat_summary(FILE *fp, int files, int insertions, int deletions)
 
        if (!files) {
                assert(insertions == 0 && deletions == 0);
-               return fprintf(fp, "%s\n", _(" 0 files changed"));
+               return fprintf(fp, "%s\n", " 0 files changed");
        }
 
        strbuf_addf(&sb,
-                   Q_(" %d file changed", " %d files changed", files),
+                   (files == 1) ? " %d file changed" : " %d files changed",
                    files);
 
        /*
@@ -1419,8 +1419,7 @@ int print_stat_summary(FILE *fp, int files, int insertions, int deletions)
                 * do not translate it.
                 */
                strbuf_addf(&sb,
-                           Q_(", %d insertion(+)", ", %d insertions(+)",
-                              insertions),
+                           (insertions == 1) ? ", %d insertion(+)" : ", %d insertions(+)",
                            insertions);
        }
 
@@ -1430,8 +1429,7 @@ int print_stat_summary(FILE *fp, int files, int insertions, int deletions)
                 * do not translate it.
                 */
                strbuf_addf(&sb,
-                           Q_(", %d deletion(-)", ", %d deletions(-)",
-                              deletions),
+                           (deletions == 1) ? ", %d deletion(-)" : ", %d deletions(-)",
                            deletions);
        }
        strbuf_addch(&sb, '\n');
diff --git a/dir.c b/dir.c
index 240bf0c49c9654b7cef56959786613e17113c3a0..486833986ed4b4e7d05d2086d53b15ec63905dd0 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -397,6 +397,8 @@ int add_excludes_from_file_to_list(const char *fname,
 
        fd = open(fname, O_RDONLY);
        if (fd < 0 || fstat(fd, &st) < 0) {
+               if (errno != ENOENT)
+                       warn_on_inaccessible(fname);
                if (0 <= fd)
                        close(fd);
                if (!check_index ||
@@ -1311,9 +1313,9 @@ void setup_standard_excludes(struct dir_struct *dir)
                home_config_paths(NULL, &xdg_path, "ignore");
                excludes_file = xdg_path;
        }
-       if (!access(path, R_OK))
+       if (!access_or_warn(path, R_OK))
                add_excludes_from_file(dir, path);
-       if (excludes_file && !access(excludes_file, R_OK))
+       if (excludes_file && !access_or_warn(excludes_file, R_OK))
                add_excludes_from_file(dir, excludes_file);
 }
 
index 35b095e8ae989ae02228f814528b43d5bd026aab..000042d79352b4a7bb789d60e5324af92f29871a 100644 (file)
@@ -604,6 +604,12 @@ int rmdir_or_warn(const char *path);
  */
 int remove_or_warn(unsigned int mode, const char *path);
 
+/* Call access(2), but warn for any error besides ENOENT. */
+int access_or_warn(const char *path, int mode);
+
+/* Warn on an inaccessible file that ought to be accessible */
+void warn_on_inaccessible(const char *path);
+
 /* Get the passwd entry for the UID of the current process. */
 struct passwd *xgetpwuid_self(void);
 
index 3e2045e52daf43cc351af23af0fd770fb1a5044f..ab6b1107b6090494f192f361471ed5748ffa7dc1 100755 (executable)
@@ -1107,7 +1107,15 @@ do
 done
 
 # No command word defaults to "status"
-test -n "$command" || command=status
+if test -z "$command"
+then
+    if test $# = 0
+    then
+       command=status
+    else
+       usage
+    fi
+fi
 
 # "-b branch" is accepted only by "add"
 if test -n "$branch" && test "$command" != add
index 7f8c1878d407e07c3ac4ac16d840557a18176d29..10ed9e51a5880430f7f109ff83f950a768a7c530 100755 (executable)
@@ -8028,7 +8028,7 @@ sub git_feed {
                %latest_commit = %{$commitlist[0]};
                my $latest_epoch = $latest_commit{'committer_epoch'};
                exit_if_unmodified_since($latest_epoch);
-               %latest_date = parse_date($latest_epoch, $latest_commit{'comitter_tz'});
+               %latest_date = parse_date($latest_epoch, $latest_commit{'committer_tz'});
        }
        print $cgi->header(
                -type => $content_type,
diff --git a/grep.c b/grep.c
index 04e3ec6c6e90e8bd96495c7b40bcb014384b07d8..898be6ebfaf2a4247ee3a64993253237b4dcc706 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -3,6 +3,10 @@
 #include "userdiff.h"
 #include "xdiff-interface.h"
 
+static int grep_source_load(struct grep_source *gs);
+static int grep_source_is_binary(struct grep_source *gs);
+
+
 static struct grep_pat *create_grep_pat(const char *pat, size_t patlen,
                                        const char *origin, int no,
                                        enum grep_pat_token t,
@@ -332,6 +336,87 @@ static struct grep_expr *compile_pattern_expr(struct grep_pat **list)
        return compile_pattern_or(list);
 }
 
+static void indent(int in)
+{
+       while (in-- > 0)
+               fputc(' ', stderr);
+}
+
+static void dump_grep_pat(struct grep_pat *p)
+{
+       switch (p->token) {
+       case GREP_AND: fprintf(stderr, "*and*"); break;
+       case GREP_OPEN_PAREN: fprintf(stderr, "*(*"); break;
+       case GREP_CLOSE_PAREN: fprintf(stderr, "*)*"); break;
+       case GREP_NOT: fprintf(stderr, "*not*"); break;
+       case GREP_OR: fprintf(stderr, "*or*"); break;
+
+       case GREP_PATTERN: fprintf(stderr, "pattern"); break;
+       case GREP_PATTERN_HEAD: fprintf(stderr, "pattern_head"); break;
+       case GREP_PATTERN_BODY: fprintf(stderr, "pattern_body"); break;
+       }
+
+       switch (p->token) {
+       default: break;
+       case GREP_PATTERN_HEAD:
+               fprintf(stderr, "<head %d>", p->field); break;
+       case GREP_PATTERN_BODY:
+               fprintf(stderr, "<body>"); break;
+       }
+       switch (p->token) {
+       default: break;
+       case GREP_PATTERN_HEAD:
+       case GREP_PATTERN_BODY:
+       case GREP_PATTERN:
+               fprintf(stderr, "%.*s", (int)p->patternlen, p->pattern);
+               break;
+       }
+       fputc('\n', stderr);
+}
+
+static void dump_grep_expression_1(struct grep_expr *x, int in)
+{
+       indent(in);
+       switch (x->node) {
+       case GREP_NODE_TRUE:
+               fprintf(stderr, "true\n");
+               break;
+       case GREP_NODE_ATOM:
+               dump_grep_pat(x->u.atom);
+               break;
+       case GREP_NODE_NOT:
+               fprintf(stderr, "(not\n");
+               dump_grep_expression_1(x->u.unary, in+1);
+               indent(in);
+               fprintf(stderr, ")\n");
+               break;
+       case GREP_NODE_AND:
+               fprintf(stderr, "(and\n");
+               dump_grep_expression_1(x->u.binary.left, in+1);
+               dump_grep_expression_1(x->u.binary.right, in+1);
+               indent(in);
+               fprintf(stderr, ")\n");
+               break;
+       case GREP_NODE_OR:
+               fprintf(stderr, "(or\n");
+               dump_grep_expression_1(x->u.binary.left, in+1);
+               dump_grep_expression_1(x->u.binary.right, in+1);
+               indent(in);
+               fprintf(stderr, ")\n");
+               break;
+       }
+}
+
+static void dump_grep_expression(struct grep_opt *opt)
+{
+       struct grep_expr *x = opt->pattern_expression;
+
+       if (opt->all_match)
+               fprintf(stderr, "[all-match]\n");
+       dump_grep_expression_1(x, 0);
+       fflush(NULL);
+}
+
 static struct grep_expr *grep_true_expr(void)
 {
        struct grep_expr *z = xcalloc(1, sizeof(*z));
@@ -395,7 +480,23 @@ static struct grep_expr *prep_header_patterns(struct grep_opt *opt)
        return header_expr;
 }
 
-void compile_grep_patterns(struct grep_opt *opt)
+static struct grep_expr *grep_splice_or(struct grep_expr *x, struct grep_expr *y)
+{
+       struct grep_expr *z = x;
+
+       while (x) {
+               assert(x->node == GREP_NODE_OR);
+               if (x->u.binary.right &&
+                   x->u.binary.right->node == GREP_NODE_TRUE) {
+                       x->u.binary.right = y;
+                       break;
+               }
+               x = x->u.binary.right;
+       }
+       return z;
+}
+
+static void compile_grep_patterns_real(struct grep_opt *opt)
 {
        struct grep_pat *p;
        struct grep_expr *header_expr = prep_header_patterns(opt);
@@ -415,7 +516,7 @@ void compile_grep_patterns(struct grep_opt *opt)
 
        if (opt->all_match || header_expr)
                opt->extended = 1;
-       else if (!opt->extended)
+       else if (!opt->extended && !opt->debug)
                return;
 
        p = opt->pattern_list;
@@ -429,12 +530,22 @@ void compile_grep_patterns(struct grep_opt *opt)
 
        if (!opt->pattern_expression)
                opt->pattern_expression = header_expr;
+       else if (opt->all_match)
+               opt->pattern_expression = grep_splice_or(header_expr,
+                                                        opt->pattern_expression);
        else
                opt->pattern_expression = grep_or_expr(opt->pattern_expression,
                                                       header_expr);
        opt->all_match = 1;
 }
 
+void compile_grep_patterns(struct grep_opt *opt)
+{
+       compile_grep_patterns_real(opt);
+       if (opt->debug)
+               dump_grep_expression(opt);
+}
+
 static void free_pattern_expr(struct grep_expr *x)
 {
        switch (x->node) {
@@ -1358,7 +1469,7 @@ static int grep_source_load_file(struct grep_source *gs)
        return 0;
 }
 
-int grep_source_load(struct grep_source *gs)
+static int grep_source_load(struct grep_source *gs)
 {
        if (gs->buf)
                return 0;
@@ -1386,7 +1497,7 @@ void grep_source_load_driver(struct grep_source *gs)
        grep_attr_unlock();
 }
 
-int grep_source_is_binary(struct grep_source *gs)
+static int grep_source_is_binary(struct grep_source *gs)
 {
        grep_source_load_driver(gs);
        if (gs->driver->binary != -1)
diff --git a/grep.h b/grep.h
index ed7de6bec8e604a7b3dcb9f9a19053696b7c3fdf..d66b19712c18cb93bf789c37ed36ad787fa89a92 100644 (file)
--- a/grep.h
+++ b/grep.h
@@ -90,6 +90,7 @@ struct grep_opt {
        int word_regexp;
        int fixed;
        int all_match;
+       int debug;
 #define GREP_BINARY_DEFAULT    0
 #define GREP_BINARY_NOMATCH    1
 #define GREP_BINARY_TEXT       2
@@ -148,11 +149,10 @@ struct grep_source {
 
 void grep_source_init(struct grep_source *gs, enum grep_source_type type,
                      const char *name, const void *identifier);
-int grep_source_load(struct grep_source *gs);
 void grep_source_clear_data(struct grep_source *gs);
 void grep_source_clear(struct grep_source *gs);
 void grep_source_load_driver(struct grep_source *gs);
-int grep_source_is_binary(struct grep_source *gs);
+
 
 int grep_source(struct grep_opt *opt, struct grep_source *gs);
 
diff --git a/http.c b/http.c
index 9bac1d89fdb639f6991bfe9f683ccf7bd5ada4cb..345c171c5fd572e65e34ea421a334141a5438979 100644 (file)
--- a/http.c
+++ b/http.c
@@ -818,6 +818,7 @@ static int http_request(const char *url, void *result, int target, int options)
 
        curl_easy_setopt(slot->curl, CURLOPT_URL, url);
        curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);
+       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip");
 
        if (start_active_slot(slot)) {
                run_active_slot(slot);
index f3f7692158666ffd2ab6f65f4040462e4a7d2d00..acea33bf1babfe541c319081f14625ac779bb582 100644 (file)
@@ -35,7 +35,7 @@ struct ll_merge_driver {
  */
 static int ll_binary_merge(const struct ll_merge_driver *drv_unused,
                           mmbuffer_t *result,
-                          const char *path_unused,
+                          const char *path,
                           mmfile_t *orig, const char *orig_name,
                           mmfile_t *src1, const char *name1,
                           mmfile_t *src2, const char *name2,
@@ -46,16 +46,34 @@ static int ll_binary_merge(const struct ll_merge_driver *drv_unused,
        assert(opts);
 
        /*
-        * The tentative merge result is "ours" for the final round,
-        * or common ancestor for an internal merge.  Still return
-        * "conflicted merge" status.
+        * The tentative merge result is the or common ancestor for an internal merge.
         */
-       stolen = opts->virtual_ancestor ? orig : src1;
+       if (opts->virtual_ancestor) {
+               stolen = orig;
+       } else {
+               switch (opts->variant) {
+               default:
+                       warning("Cannot merge binary files: %s (%s vs. %s)",
+                               path, name1, name2);
+                       /* fallthru */
+               case XDL_MERGE_FAVOR_OURS:
+                       stolen = src1;
+                       break;
+               case XDL_MERGE_FAVOR_THEIRS:
+                       stolen = src2;
+                       break;
+               }
+       }
 
        result->ptr = stolen->ptr;
        result->size = stolen->size;
        stolen->ptr = NULL;
-       return 1;
+
+       /*
+        * With -Xtheirs or -Xours, we have cleanly merged;
+        * otherwise we got a conflict.
+        */
+       return (opts->variant ? 0 : 1);
 }
 
 static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
@@ -73,8 +91,6 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
        if (buffer_is_binary(orig->ptr, orig->size) ||
            buffer_is_binary(src1->ptr, src1->size) ||
            buffer_is_binary(src2->ptr, src2->size)) {
-               warning("Cannot merge binary files: %s (%s vs. %s)",
-                       path, name1, name2);
                return ll_binary_merge(drv_unused, result,
                                       path,
                                       orig, orig_name,
index 2739bc0a3137ed506b2d7289c9bf46b81bdb5933..9e9f2da47c00681f0d9d93cbbcce5f9526cf1c3f 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -55,7 +55,7 @@ msgstr "Konnte '%s' nicht öffnen"
 
 #: bundle.c:140
 msgid "Repository lacks these prerequisite commits:"
-msgstr "Dem Projektarchiv fehlen folgende vorrausgesetzte Versionen:"
+msgstr "Dem Projektarchiv fehlen folgende vorausgesetzte Versionen:"
 
 #: bundle.c:164 sequencer.c:550 sequencer.c:982 builtin/log.c:290
 #: builtin/log.c:726 builtin/log.c:1316 builtin/log.c:1535 builtin/merge.c:347
@@ -1758,7 +1758,7 @@ msgstr "Anzahl"
 #: builtin/apply.c:4291
 msgid "remove <num> leading slashes from traditional diff paths"
 msgstr ""
-"entfernt <Anzahl> vorrangestellte Schrägstriche von herkömmlichen "
+"entfernt <Anzahl> vorangestellte Schrägstriche von herkömmlichen "
 "Differenzpfaden"
 
 #: builtin/apply.c:4294
@@ -2065,7 +2065,7 @@ msgstr "Konnte einige Referenzen nicht lesen"
 #: builtin/branch.c:613
 msgid "cannot rename the current branch while not on any."
 msgstr ""
-"Kann aktuellen Zweig nicht umbennen, solange du dich auf keinem befindest."
+"Kann aktuellen Zweig nicht umbenennen, solange du dich auf keinem befindest."
 
 #: builtin/branch.c:623
 #, c-format
@@ -2353,7 +2353,7 @@ msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
 msgstr ""
-"git checkout: --ours/--theirs, --force and --merge sind inkompatibel wenn\n"
+"git checkout: --ours/--theirs, --force und --merge sind inkompatibel wenn\n"
 "du aus der Bereitstellung auscheckst."
 
 #: builtin/checkout.c:1093
@@ -3666,7 +3666,7 @@ msgstr "Konnte %s nicht nach %s verschieben"
 #: builtin/init-db.c:363
 #, c-format
 msgid "Could not create git link %s"
-msgstr "Konnte git-Verknüfung %s nicht erstellen"
+msgstr "Konnte git-Verknüpfung %s nicht erstellen"
 
 #.
 #. * TRANSLATORS: The first '%s' is either "Reinitialized
@@ -3778,11 +3778,11 @@ msgstr "unechte Einreicher-Informationen %s"
 
 #: builtin/log.c:1205
 msgid "-n and -k are mutually exclusive."
-msgstr "-n und -k schliessen sich gegenseitig aus"
+msgstr "-n und -k schließen sich gegenseitig aus"
 
 #: builtin/log.c:1207
 msgid "--subject-prefix and -k are mutually exclusive."
-msgstr "--subject-prefix und -k schliessen sich gegenseitig aus"
+msgstr "--subject-prefix und -k schließen sich gegenseitig aus"
 
 #: builtin/log.c:1215
 msgid "--name-only does not make sense"
@@ -5750,14 +5750,14 @@ msgid ""
 "and run me again.  I am stopping in case you still have something\n"
 "valuable there."
 msgstr ""
-"Es scheint so, als gäbe es das Verzeichnis $state_dir_base bereits, und\n"
-"es wäre verwunderlich, wenn ein Neuaufbau bereits im Gange ist. Wenn das\n"
-"der Fall ist, probiere bitte\n"
+"Es sieht so aus, als ob es das Verzeichnis $state_dir_base bereits gibt\n"
+"und es könnte ein anderer Neuaufbau im Gange sein. Wenn das der Fall ist,\n"
+"probiere bitte\n"
 "\t$cmd_live_rebase\n"
 "Wenn das nicht der Fall ist, probiere bitte\n"
 "\t$cmd_clear_stale_rebase\n"
-"und führe dieses Kommando nochmal aus. Es wird angehalten, falls bereits\n"
-"etwas Nützliches vorhanden ist."
+"und führe dieses Kommando nochmal aus. Es wird angehalten, falls noch\n"
+"etwas Schützenswertes vorhanden ist."
 
 #: git-rebase.sh:395
 #, sh-format
index b327a0e8bc71c8fc57d2a64865f1a69dfe68d8e8..141b8d51820116d3770718f0e17cb531a3f5695e 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -8,7 +8,7 @@ msgstr ""
 "Project-Id-Version: git 1.7.12\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
 "POT-Creation-Date: 2012-08-06 23:47+0800\n"
-"PO-Revision-Date: 2012-08-14 09:58+0100\n"
+"PO-Revision-Date: 2012-10-02 08:15+0100\n"
 "Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
 "Language: sv\n"
@@ -3381,7 +3381,7 @@ msgstr "misslyckades tillämpa delta"
 
 #: builtin/index-pack.c:986
 msgid "Receiving objects"
-msgstr "Tar bort objekt"
+msgstr "Tar emot objekt"
 
 #: builtin/index-pack.c:986
 msgid "Indexing objects"
index bc04236e476dfd5b9683ada57e4c6515c837e2c7..354bf4dac89537fbf78a14c3c14ce9dc5b64c8f9 100644 (file)
@@ -350,7 +350,7 @@ msgstr[0] ""
 "您指的是这个么?"
 msgstr[1] ""
 "\n"
-"您指的是这些其中一个么?"
+"您指的是这其中的某一个么?"
 
 #: merge-recursive.c:190
 #, c-format
@@ -661,10 +661,10 @@ msgid_plural ""
 "and have %d and %d different commits each, respectively.\n"
 msgstr[0] ""
 "您的分支和 '%s' 出现了偏离,\n"
-"å¹¶ä¸\94å\90\84è\87ªå\88\86å\88«æ\9c\89 %d å\92\8c %d å¤\84ä¸\8då\90\8cç\9a\84æ\8f\90交ã\80\82\n"
+"并且分别有 %d 和 %d 处不同的提交。\n"
 msgstr[1] ""
 "您的分支和 '%s' 出现了偏离,\n"
-"å¹¶ä¸\94å\90\84è\87ªå\88\86å\88«æ\9c\89 %d å\92\8c %d å¤\84ä¸\8då\90\8cç\9a\84æ\8f\90交ã\80\82\n"
+"并且分别有 %d 和 %d 处不同的提交。\n"
 
 #: sequencer.c:121 builtin/merge.c:865 builtin/merge.c:978
 #: builtin/merge.c:1088 builtin/merge.c:1098
@@ -864,7 +864,7 @@ msgstr "错误收尾 %s。"
 
 #: sequencer.c:779 sequencer.c:913
 msgid "no cherry-pick or revert in progress"
-msgstr "没æ\9c\89æ\8b£é\80\89æ\88\96è¿\98å\8e\9fæ\93\8dä½\9cå\9c¨进行"
+msgstr "æ\8b£é\80\89æ\88\96è¿\98å\8e\9fæ\93\8dä½\9cå¹¶æ\9cª进行"
 
 #: sequencer.c:781
 msgid "cannot resolve HEAD"
@@ -886,7 +886,7 @@ msgstr "不能读取 %s:%s"
 
 #: sequencer.c:809
 msgid "unexpected end of file"
-msgstr "æ\9cªé¢\84æ\9c\9f的文件结束"
+msgstr "æ\84\8få¤\96的文件结束"
 
 #: sequencer.c:815
 #, c-format
@@ -928,7 +928,7 @@ msgstr "上游分支 '%s' 没有存储为一个远程跟踪分支"
 #: wrapper.c:413
 #, c-format
 msgid "unable to look up current user in the passwd file: %s"
-msgstr "无法在 passwd 文件中查询到当前用户:%s"
+msgstr "无法在 passwd 文件中查询到用户:%s"
 
 #: wrapper.c:414
 msgid "no such user"
@@ -1106,7 +1106,7 @@ msgstr "bug:未处理的差异状态 %c"
 
 #: wt-status.c:785
 msgid "You have unmerged paths."
-msgstr "您有路径尚未合并。"
+msgstr "您有尚未合并的路径。"
 
 #  译者:注意保持前导空格
 #: wt-status.c:788 wt-status.c:912
@@ -1191,7 +1191,7 @@ msgstr "  (使用 \"git commit --amend\" 修补当前提交)"
 #: wt-status.c:898
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
-msgstr "  (执行 \"git rebase --continue\" 一旦您满意您的修改)"
+msgstr "  (当您对您的修改满意后执行 \"git rebase --continue\")"
 
 #: wt-status.c:908
 msgid "You are currently cherry-picking."
@@ -1349,11 +1349,11 @@ msgstr "不能读取索引"
 #: builtin/add.c:286
 #, c-format
 msgid "Could not open '%s' for writing."
-msgstr "不能为写入打开 '%s'。"
+msgstr "不能打开 '%s' 以写入。"
 
 #: builtin/add.c:290
 msgid "Could not write patch"
-msgstr "不能补丁"
+msgstr "不能生成补丁"
 
 #: builtin/add.c:295
 #, c-format
@@ -1371,7 +1371,7 @@ msgstr "不能应用 '%s'"
 
 #: builtin/add.c:312
 msgid "The following paths are ignored by one of your .gitignore files:\n"
-msgstr "下列路径被您的一个 .gitignore 文件所忽略:\n"
+msgstr "下列路径根据您的一个 .gitignore 文件而被忽略:\n"
 
 #: builtin/add.c:352
 #, c-format
@@ -1445,7 +1445,7 @@ msgstr "不能在补丁的第 %d 行找到文件名"
 #: builtin/apply.c:946
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d"
-msgstr "git apply:错误的 git-diff - 期望 /dev/null,但在第 %2$d 行得到 %1$s"
+msgstr "git apply:错误的 git-diff - 应为 /dev/null,但在第 %2$d 行得到 %1$s"
 
 #: builtin/apply.c:950
 #, c-format
@@ -1460,7 +1460,7 @@ msgstr "git apply:错误的 git-diff - 第 %d 行上旧文件名不一致"
 #: builtin/apply.c:958
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null on line %d"
-msgstr "git apply:错误的 git-diff - 期望 /dev/null 于第 %d 行"
+msgstr "git apply:错误的 git-diff - 第 %d 行处应为 /dev/null"
 
 #: builtin/apply.c:1403
 #, c-format
@@ -1494,7 +1494,7 @@ msgstr "删除的文件仍有内容"
 #: builtin/apply.c:1665
 #, c-format
 msgid "corrupt patch at line %d"
-msgstr "补丁损坏位于第 %d 行"
+msgstr "补丁在第 %d 行损坏"
 
 #: builtin/apply.c:1701
 #, c-format
@@ -1580,7 +1580,7 @@ msgstr "二进制补丁未应用到 '%s'"
 #: builtin/apply.c:2918
 #, c-format
 msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
-msgstr "到 '%s' 的二进制补丁产生了不正确的结果(预期 %s,得到 %s)"
+msgstr "到 '%s' 的二进制补丁产生了不正确的结果(应为 %s,却为 %s)"
 
 #: builtin/apply.c:2939
 #, c-format
@@ -1629,7 +1629,7 @@ msgstr "%s:错误类型"
 #: builtin/apply.c:3402
 #, c-format
 msgid "%s has type %o, expected %o"
-msgstr "%s 的类型是 %o,预期是 %o"
+msgstr "%s 的类型是 %o,应为 %o"
 
 #: builtin/apply.c:3503
 #, c-format
@@ -1715,8 +1715,8 @@ msgstr "内部错误"
 #, c-format
 msgid "Applying patch %%s with %d reject..."
 msgid_plural "Applying patch %%s with %d rejects..."
-msgstr[0] "应用补丁 %%s 时 %d 个被拒绝..."
-msgstr[1] "应用补丁 %%s 时 %d 个被拒绝..."
+msgstr[0] "应用 %%s 个补丁,其中 %d 个被拒绝..."
+msgstr[1] "应用 %%s 个补丁,其中 %d 个被拒绝..."
 
 #: builtin/apply.c:3980
 #, c-format
@@ -1791,7 +1791,7 @@ msgstr "应用补丁而不修改工作区"
 
 #: builtin/apply.c:4310
 msgid "also apply the patch (use with --stat/--summary/--check)"
-msgstr "è¿\98åº\94ç\94¨æ­¤è¡¥ä¸\81ï¼\88使ç\94¨ --stat/--summary/--check å\8f\82æ\95°)"
+msgstr "è¿\98åº\94ç\94¨æ­¤è¡¥ä¸\81ï¼\88ä¸\8e --stat/--summary/--check é\80\89项å\90\8cæ\97¶ä½¿ç\94¨)"
 
 #: builtin/apply.c:4312
 msgid "attempt three-way merge if a patch does not apply"
@@ -1843,7 +1843,7 @@ msgstr "冗长输出"
 
 #: builtin/apply.c:4339
 msgid "tolerate incorrectly detected missing new-line at the end of file"
-msgstr "宽容不正确的文件末尾换行符"
+msgstr "å\85\81许不正确的文件末尾换行符"
 
 #: builtin/apply.c:4342
 msgid "do not trust the line counts in the hunk headers"
@@ -1895,7 +1895,7 @@ msgstr "不能创建归档文件 '%s'"
 
 #: builtin/archive.c:20
 msgid "could not redirect output"
-msgstr "不能输出重定向"
+msgstr "不能重定向输出"
 
 #: builtin/archive.c:37
 msgid "git archive: Remote with no URL"
@@ -1903,7 +1903,7 @@ msgstr "git archive:未提供远程URL"
 
 #: builtin/archive.c:58
 msgid "git archive: expected ACK/NAK, got EOF"
-msgstr "git archive:期待ACK/NACK,却得到EOF"
+msgstr "git archive:应为ACK/NACK,却得到EOF"
 
 #: builtin/archive.c:63
 #, c-format
@@ -1921,7 +1921,7 @@ msgstr "git archive:协议错误"
 
 #: builtin/archive.c:71
 msgid "git archive: expected a flush"
-msgstr "git archive:预期一个刷新"
+msgstr "git archive:应为刷新"
 
 #  译者:保持原换行格式,在输出时 %s 的替代内容会让字符串变长
 #: builtin/branch.c:144
index 3ec474fc631eb3b433b3cadbd74aed4b83cba724..a2696082fb8881d74de7a2f9c473fb03f82d81ec 100644 (file)
@@ -95,7 +95,7 @@ static struct discovery* discover_refs(const char *service)
        struct strbuf buffer = STRBUF_INIT;
        struct discovery *last = last_discovery;
        char *refs_url;
-       int http_ret, is_http = 0, proto_git_candidate = 1;
+       int http_ret, is_http = 0;
 
        if (last && !strcmp(service, last->service))
                return last;
@@ -113,19 +113,6 @@ static struct discovery* discover_refs(const char *service)
        refs_url = strbuf_detach(&buffer, NULL);
 
        http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);
-
-       /* try again with "plain" url (no ? or & appended) */
-       if (http_ret != HTTP_OK && http_ret != HTTP_NOAUTH) {
-               free(refs_url);
-               strbuf_reset(&buffer);
-
-               proto_git_candidate = 0;
-               strbuf_addf(&buffer, "%sinfo/refs", url);
-               refs_url = strbuf_detach(&buffer, NULL);
-
-               http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);
-       }
-
        switch (http_ret) {
        case HTTP_OK:
                break;
@@ -144,8 +131,7 @@ static struct discovery* discover_refs(const char *service)
        last->buf_alloc = strbuf_detach(&buffer, &last->len);
        last->buf = last->buf_alloc;
 
-       if (is_http && proto_git_candidate
-               && 5 <= last->len && last->buf[4] == '#') {
+       if (is_http && 5 <= last->len && last->buf[4] == '#') {
                /* smart HTTP response; validate that the service
                 * pkt-line matches our request.
                 */
@@ -393,7 +379,7 @@ static int probe_rpc(struct rpc_state *rpc)
        curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
        curl_easy_setopt(slot->curl, CURLOPT_POST, 1);
        curl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);
-       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "");
+       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, NULL);
        curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, "0000");
        curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, 4);
        curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);
@@ -449,7 +435,7 @@ static int post_rpc(struct rpc_state *rpc)
        curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
        curl_easy_setopt(slot->curl, CURLOPT_POST, 1);
        curl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);
-       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "");
+       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip");
 
        headers = curl_slist_append(headers, rpc->hdr_content_type);
        headers = curl_slist_append(headers, rpc->hdr_accept);
index dc3fecf903aa0ce4927b9ebe5b95f99cc9c1018d..ae12e11fb74dcc51bfddd2acf94601b2bfba7811 100644 (file)
@@ -1598,6 +1598,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
        } else if ((argcount = parse_long_opt("grep", argv, &optarg))) {
                add_message_grep(revs, optarg);
                return argcount;
+       } else if (!strcmp(arg, "--grep-debug")) {
+               revs->grep_filter.debug = 1;
        } else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) {
                revs->grep_filter.regflags |= REG_EXTENDED;
        } else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) {
index f9922b9ecc8e4956e19d7143bb6cb6ef4d97abf8..1101ef72378a502b1681a8e1bc306f38027974ae 100644 (file)
@@ -53,13 +53,14 @@ static void mark_child_for_cleanup(pid_t pid)
 
 static void clear_child_for_cleanup(pid_t pid)
 {
-       struct child_to_clean **last, *p;
+       struct child_to_clean **pp;
 
-       last = &children_to_clean;
-       for (p = children_to_clean; p; p = p->next) {
-               if (p->pid == pid) {
-                       *last = p->next;
-                       free(p);
+       for (pp = &children_to_clean; *pp; pp = &(*pp)->next) {
+               struct child_to_clean *clean_me = *pp;
+
+               if (clean_me->pid == pid) {
+                       *pp = clean_me->next;
+                       free(clean_me);
                        return;
                }
        }
index 19dc6a6c0d5cf7d9a4c80c61e160290b4462665d..51d48c21217d12c9b654310ba192606a695a8584 100644 (file)
@@ -588,13 +588,13 @@ static void calculate_changed_submodule_paths(void)
        initialized_fetch_ref_tips = 0;
 }
 
-int fetch_populated_submodules(int num_options, const char **options,
+int fetch_populated_submodules(const struct argv_array *options,
                               const char *prefix, int command_line_option,
                               int quiet)
 {
-       int i, result = 0, argc = 0, default_argc;
+       int i, result = 0;
        struct child_process cp;
-       const char **argv;
+       struct argv_array argv = ARGV_ARRAY_INIT;
        struct string_list_item *name_for_path;
        const char *work_tree = get_git_work_tree();
        if (!work_tree)
@@ -604,17 +604,13 @@ int fetch_populated_submodules(int num_options, const char **options,
                if (read_cache() < 0)
                        die("index file corrupt");
 
-       /* 6: "fetch" (options) --recurse-submodules-default default "--submodule-prefix" prefix NULL */
-       argv = xcalloc(num_options + 6, sizeof(const char *));
-       argv[argc++] = "fetch";
-       for (i = 0; i < num_options; i++)
-               argv[argc++] = options[i];
-       argv[argc++] = "--recurse-submodules-default";
-       default_argc = argc++;
-       argv[argc++] = "--submodule-prefix";
+       argv_array_push(&argv, "fetch");
+       for (i = 0; i < options->argc; i++)
+               argv_array_push(&argv, options->argv[i]);
+       argv_array_push(&argv, "--recurse-submodules-default");
+       /* default value, "--submodule-prefix" and its value are added later */
 
        memset(&cp, 0, sizeof(cp));
-       cp.argv = argv;
        cp.env = local_repo_env;
        cp.git_cmd = 1;
        cp.no_stdin = 1;
@@ -674,16 +670,21 @@ int fetch_populated_submodules(int num_options, const char **options,
                        if (!quiet)
                                printf("Fetching submodule %s%s\n", prefix, ce->name);
                        cp.dir = submodule_path.buf;
-                       argv[default_argc] = default_argv;
-                       argv[argc] = submodule_prefix.buf;
+                       argv_array_push(&argv, default_argv);
+                       argv_array_push(&argv, "--submodule-prefix");
+                       argv_array_push(&argv, submodule_prefix.buf);
+                       cp.argv = argv.argv;
                        if (run_command(&cp))
                                result = 1;
+                       argv_array_pop(&argv);
+                       argv_array_pop(&argv);
+                       argv_array_pop(&argv);
                }
                strbuf_release(&submodule_path);
                strbuf_release(&submodule_git_dir);
                strbuf_release(&submodule_prefix);
        }
-       free(argv);
+       argv_array_clear(&argv);
 out:
        string_list_clear(&changed_submodule_paths, 1);
        return result;
index e105b0ebe6c06a03af7f82bdfbc9beb66377544f..594b50d51066be35d2f9dc9aa795f3ecdf131573 100644 (file)
@@ -2,6 +2,7 @@
 #define SUBMODULE_H
 
 struct diff_options;
+struct argv_array;
 
 enum {
        RECURSE_SUBMODULES_ON_DEMAND = -1,
@@ -23,7 +24,7 @@ void show_submodule_summary(FILE *f, const char *path,
                const char *del, const char *add, const char *reset);
 void set_config_fetch_recurse_submodules(int value);
 void check_for_new_submodule_commits(unsigned char new_sha1[20]);
-int fetch_populated_submodules(int num_options, const char **options,
+int fetch_populated_submodules(const struct argv_array *options,
                               const char *prefix, int command_line_option,
                               int quiet);
 unsigned is_submodule_modified(const char *path, int ignore_untracked);
index 81904d9ec8d341399b534c5d576262439d0e1ad6..3e64a7a65da86410dd0236975bef9bd0013a6405 100755 (executable)
@@ -11,7 +11,7 @@ test_expect_success 'split sample box' \
        'git mailsplit -o. "$TEST_DIRECTORY"/t5100/sample.mbox >last &&
        last=`cat last` &&
        echo total is $last &&
-       test `cat last` = 16'
+       test `cat last` = 17'
 
 check_mailinfo () {
        mail=$1 opt=$2
diff --git a/t/t5100/info0017 b/t/t5100/info0017
new file mode 100644 (file)
index 0000000..d2bc89f
--- /dev/null
@@ -0,0 +1,5 @@
+Author: A U Thor
+Email: a.u.thor@example.com
+Subject: A E I O U
+Date: Mon, 17 Sep 2012 14:23:44 -0700
+
diff --git a/t/t5100/msg0017 b/t/t5100/msg0017
new file mode 100644 (file)
index 0000000..2ee0900
--- /dev/null
@@ -0,0 +1,2 @@
+New content here
+
diff --git a/t/t5100/patch0017 b/t/t5100/patch0017
new file mode 100644 (file)
index 0000000..35cf84c
--- /dev/null
@@ -0,0 +1,6 @@
+diff --git a/foo b/foo
+index e69de29..d95f3ad 100644
+--- a/foo
++++ b/foo
+@@ -0,0 +1 @@
++New content
index 34a09a0fc1c0ca9d1e68ed8bbf56e592c54e7227..8b2ae064c36b969ca20324154cea66bf26739de6 100644 (file)
@@ -683,3 +683,19 @@ index e69de29..d95f3ad 100644
 @@ -0,0 +1 @@
 +content
 
+From nobody Mon Sep 17 00:00:00 2001
+From: A U Thor <a.u.thor@example.com>
+Subject: A E I O U
+Date: Mon, 17 Sep 2012 14:23:44 -0700
+MIME-Version: 1.0
+Content-Type: text/plain; charset="iso-2022-jp"
+Content-type: text/plain; charset="UTF-8"
+
+New content here
+
+diff --git a/foo b/foo
+index e69de29..d95f3ad 100644
+--- a/foo
++++ b/foo
+@@ -0,0 +1 @@
++New content
index 35ec294d9a56d5fc6b22ee2a39166325352bd639..69ee13c8bebbdb1303378288597420cdf70b7b88 100755 (executable)
@@ -89,7 +89,7 @@ test_expect_success 'push with !receive.fsckobjects' '
 
 cat >exp <<EOF
 To dst
-!      refs/heads/master:refs/heads/test       [remote rejected] (n/a (unpacker error))
+!      refs/heads/master:refs/heads/test       [remote rejected] (unpacker error)
 EOF
 
 test_expect_success 'push with receive.fsckobjects' '
index e8af615e6dcdf365416ef9f71825c17a0d601186..c03ffdde1036f37d35db0d8147af20ffdd79bbb1 100755 (executable)
@@ -125,7 +125,7 @@ EOF
        } &&
        git tag footag &&
        git config --add remote.oops.fetch "+refs/*:refs/*" &&
-       git remote rm oops 2>actual1 &&
+       git remote remove oops 2>actual1 &&
        git branch foobranch &&
        git config --add remote.oops.fetch "+refs/*:refs/*" &&
        git remote rm oops 2>actual2 &&
@@ -672,7 +672,7 @@ test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' '
        git clone one five &&
        origin_url=$(pwd)/one &&
        (cd five &&
-        git remote rm origin &&
+        git remote remove origin &&
         mkdir -p .git/remotes &&
         cat ../remotes_origin > .git/remotes/origin &&
         git remote rename origin origin &&
index 227dd56137c469311209ebda43cb89f9734c6e68..0f8140957f8080f4a9f3283a1cfef7f3798ae454 100755 (executable)
@@ -151,4 +151,34 @@ test_expect_success 'git fetch --multiple (ignoring skipFetchAll)' '
         test_cmp ../expect output)
 '
 
+test_expect_success 'git fetch --all --no-tags' '
+       >expect &&
+       git clone one test5 &&
+       git clone test5 test6 &&
+       (cd test5 && git tag test-tag) &&
+       (
+               cd test6 &&
+               git fetch --all --no-tags &&
+               git tag >output
+       ) &&
+       test_cmp expect test6/output
+'
+
+test_expect_success 'git fetch --all --tags' '
+       echo test-tag >expect &&
+       git clone one test7 &&
+       git clone test7 test8 &&
+       (
+               cd test7 &&
+               test_commit test-tag &&
+               git reset --hard HEAD^
+       ) &&
+       (
+               cd test8 &&
+               git fetch --all --tags &&
+               git tag >output
+       ) &&
+       test_cmp expect test8/output
+'
+
 test_done
index f141f2d1da3ca8186ccc7a742bddd06f2e7f8970..01d0d95b4d6476f691f650cc413fa7156caee88b 100755 (executable)
@@ -109,7 +109,7 @@ test_expect_success 'http-push fetches packed objects' '
        # By reset, we force git to retrieve the packed object
        (cd "$ROOT_PATH"/test_repo_clone_packed &&
         git reset --hard HEAD^ &&
-        git remote rm origin &&
+        git remote remove origin &&
         git reflog expire --expire=0 --all &&
         git prune &&
         git push -f -v $HTTPD_URL/dumb/test_repo_packed.git master)
index 2db5c3564181818efdf885188d7cc597024c6f12..380c17541efd39946fe14c924b84bc212c435f17 100755 (executable)
@@ -32,13 +32,14 @@ setup_askpass_helper
 cat >exp <<EOF
 > GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1
 > Accept: */*
+> Accept-Encoding: gzip
 > Pragma: no-cache
 < HTTP/1.1 200 OK
 < Pragma: no-cache
 < Cache-Control: no-cache, max-age=0, must-revalidate
 < Content-Type: application/x-git-upload-pack-advertisement
 > POST /smart/repo.git/git-upload-pack HTTP/1.1
-> Accept-Encoding: deflate, gzip
+> Accept-Encoding: gzip
 > Content-Type: application/x-git-upload-pack-request
 > Accept: application/x-git-upload-pack-result
 > Content-Length: xxx
diff --git a/t/t5709-clone-refspec.sh b/t/t5709-clone-refspec.sh
new file mode 100755 (executable)
index 0000000..6f1ea98
--- /dev/null
@@ -0,0 +1,156 @@
+#!/bin/sh
+
+test_description='test refspec written by clone-command'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+       # Make two branches, "master" and "side"
+       echo one >file &&
+       git add file &&
+       git commit -m one &&
+       echo two >file &&
+       git commit -a -m two &&
+       git tag two &&
+       echo three >file &&
+       git commit -a -m three &&
+       git checkout -b side &&
+       echo four >file &&
+       git commit -a -m four &&
+       git checkout master &&
+
+       # default clone
+       git clone . dir_all &&
+
+       # default --single that follows HEAD=master
+       git clone --single-branch . dir_master &&
+
+       # default --single that follows HEAD=side
+       git checkout side &&
+       git clone --single-branch . dir_side &&
+
+       # explicit --single that follows side
+       git checkout master &&
+       git clone --single-branch --branch side . dir_side2 &&
+
+       # default --single with --mirror
+       git clone --single-branch --mirror . dir_mirror &&
+
+       # default --single with --branch and --mirror
+       git clone --single-branch --mirror --branch side . dir_mirror_side &&
+
+       # --single that does not know what branch to follow
+       git checkout two^ &&
+       git clone --single-branch . dir_detached &&
+
+       # explicit --single with tag
+       git clone --single-branch --branch two . dir_tag &&
+
+       # advance both "master" and "side" branches
+       git checkout side &&
+       echo five >file &&
+       git commit -a -m five &&
+       git checkout master &&
+       echo six >file &&
+       git commit -a -m six &&
+
+       # update tag
+       git tag -d two && git tag two
+'
+
+test_expect_success 'by default all branches will be kept updated' '
+       (
+               cd dir_all && git fetch &&
+               git for-each-ref refs/remotes/origin |
+               sed -e "/HEAD$/d" \
+                   -e "s|/remotes/origin/|/heads/|" >../actual
+       ) &&
+       # follow both master and side
+       git for-each-ref refs/heads >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success 'by default no tags will be kept updated' '
+       (
+               cd dir_all && git fetch &&
+               git for-each-ref refs/tags >../actual
+       ) &&
+       git for-each-ref refs/tags >expect &&
+       test_must_fail test_cmp expect actual
+'
+
+test_expect_success '--single-branch while HEAD pointing at master' '
+       (
+               cd dir_master && git fetch &&
+               git for-each-ref refs/remotes/origin |
+               sed -e "/HEAD$/d" \
+                   -e "s|/remotes/origin/|/heads/|" >../actual
+       ) &&
+       # only follow master
+       git for-each-ref refs/heads/master >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success '--single-branch while HEAD pointing at side' '
+       (
+               cd dir_side && git fetch &&
+               git for-each-ref refs/remotes/origin |
+               sed -e "/HEAD$/d" \
+                   -e "s|/remotes/origin/|/heads/|" >../actual
+       ) &&
+       # only follow side
+       git for-each-ref refs/heads/side >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success '--single-branch with explicit --branch side' '
+       (
+               cd dir_side2 && git fetch &&
+               git for-each-ref refs/remotes/origin |
+               sed -e "/HEAD$/d" \
+                   -e "s|/remotes/origin/|/heads/|" >../actual
+       ) &&
+       # only follow side
+       git for-each-ref refs/heads/side >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success '--single-branch with explicit --branch with tag fetches updated tag' '
+       (
+               cd dir_tag && git fetch &&
+               git for-each-ref refs/tags >../actual
+       ) &&
+       git for-each-ref refs/tags >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success '--single-branch with --mirror' '
+       (
+               cd dir_mirror && git fetch &&
+               git for-each-ref refs > ../actual
+       ) &&
+       git for-each-ref refs >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success '--single-branch with explicit --branch and --mirror' '
+       (
+               cd dir_mirror_side && git fetch &&
+               git for-each-ref refs > ../actual
+       ) &&
+       git for-each-ref refs >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success '--single-branch with detached' '
+       (
+               cd dir_detached && git fetch &&
+               git for-each-ref refs/remotes/origin |
+               sed -e "/HEAD$/d" \
+                   -e "s|/remotes/origin/|/heads/|" >../actual
+       )
+       # nothing
+       >expect &&
+       test_cmp expect actual
+'
+
+test_done
index 2cf42c73f14ef5069d096fb29e67dac571227cfe..3889eca4ae8524cd62eaf45b4d7a2394e53da429 100755 (executable)
@@ -53,7 +53,19 @@ test_expect_success 'recursive favouring ours' '
        ! grep 1 file
 '
 
-test_expect_success 'pull with -X' '
+test_expect_success 'binary file with -Xours/-Xtheirs' '
+       echo file binary >.gitattributes &&
+
+       git reset --hard master &&
+       git merge -s recursive -X theirs side &&
+       git diff --exit-code side HEAD -- file &&
+
+       git reset --hard master &&
+       git merge -s recursive -X ours side &&
+       git diff --exit-code master HEAD -- file
+'
+
+test_expect_success 'pull passes -X to underlying merge' '
        git reset --hard master && git pull -s recursive -Xours . side &&
        git reset --hard master && git pull -s recursive -X ours . side &&
        git reset --hard master && git pull -s recursive -Xtheirs . side &&
index 56a81cd7486716897cc4f08196d0815a62461ffd..53970374913eaa6f1b5921b14b5f25043974e3a4 100755 (executable)
@@ -438,8 +438,8 @@ test_expect_success 'moving to a commit without submodule does not leave empty d
        git checkout second
 '
 
-test_expect_success 'submodule <invalid-path> warns' '
-       test_failure_with_unknown_submodule
+test_expect_success 'submodule <invalid-subcommand> fails' '
+       test_must_fail git submodule no-such-subcommand
 '
 
 test_expect_success 'add submodules without specifying an explicit path' '
index 523d04123d02cabb8703f91e9bec194c7d737f00..3021cf251c96833a815c5de707d794ba2e07774b 100755 (executable)
@@ -424,31 +424,41 @@ test_expect_success 'log grep setup' '
 
 test_expect_success 'log grep (1)' '
        git log --author=author --pretty=tformat:%s >actual &&
-       ( echo third ; echo initial ) >expect &&
+       {
+               echo third && echo initial
+       } >expect &&
        test_cmp expect actual
 '
 
 test_expect_success 'log grep (2)' '
        git log --author=" * " -F --pretty=tformat:%s >actual &&
-       ( echo second ) >expect &&
+       {
+               echo second
+       } >expect &&
        test_cmp expect actual
 '
 
 test_expect_success 'log grep (3)' '
        git log --author="^A U" --pretty=tformat:%s >actual &&
-       ( echo third ; echo initial ) >expect &&
+       {
+               echo third && echo initial
+       } >expect &&
        test_cmp expect actual
 '
 
 test_expect_success 'log grep (4)' '
        git log --author="frotz\.com>$" --pretty=tformat:%s >actual &&
-       ( echo second ) >expect &&
+       {
+               echo second
+       } >expect &&
        test_cmp expect actual
 '
 
 test_expect_success 'log grep (5)' '
        git log --author=Thor -F --pretty=tformat:%s >actual &&
-       ( echo third ; echo initial ) >expect &&
+       {
+               echo third && echo initial
+       } >expect &&
        test_cmp expect actual
 '
 
@@ -458,11 +468,19 @@ test_expect_success 'log grep (6)' '
        test_cmp expect actual
 '
 
-test_expect_success 'log --grep --author implicitly uses all-match' '
-       # grep matches initial and second but not third
-       # author matches only initial and third
-       git log --author="A U Thor" --grep=s --grep=l --format=%s >actual &&
-       echo initial >expect &&
+test_expect_success 'log with multiple --grep uses union' '
+       git log --grep=i --grep=r --format=%s >actual &&
+       {
+               echo fourth && echo third && echo initial
+       } >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success 'log --all-match with multiple --grep uses intersection' '
+       git log --all-match --grep=i --grep=r --format=%s >actual &&
+       {
+               echo third
+       } >expect &&
        test_cmp expect actual
 '
 
@@ -474,7 +492,47 @@ test_expect_success 'log with multiple --author uses union' '
        test_cmp expect actual
 '
 
-test_expect_success 'log with --grep and multiple --author uses all-match' '
+test_expect_success 'log --all-match with multiple --author still uses union' '
+       git log --all-match --author="Thor" --author="Aster" --format=%s >actual &&
+       {
+           echo third && echo second && echo initial
+       } >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success 'log --grep --author uses intersection' '
+       # grep matches only third and fourth
+       # author matches only initial and third
+       git log --author="A U Thor" --grep=r --format=%s >actual &&
+       {
+               echo third
+       } >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success 'log --grep --grep --author takes union of greps and intersects with author' '
+       # grep matches initial and second but not third
+       # author matches only initial and third
+       git log --author="A U Thor" --grep=s --grep=l --format=%s >actual &&
+       {
+               echo initial
+       } >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success 'log ---all-match -grep --author --author still takes union of authors and intersects with grep' '
+       # grep matches only initial and third
+       # author matches all but second
+       git log --all-match --author="Thor" --author="Night" --grep=i --format=%s >actual &&
+       {
+           echo third && echo initial
+       } >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success 'log --grep --author --author takes union of authors and intersects with grep' '
+       # grep matches only initial and third
+       # author matches all but second
        git log --author="Thor" --author="Night" --grep=i --format=%s >actual &&
        {
            echo third && echo initial
@@ -482,9 +540,13 @@ test_expect_success 'log with --grep and multiple --author uses all-match' '
        test_cmp expect actual
 '
 
-test_expect_success 'log with --grep and multiple --author uses all-match' '
-       git log --author="Thor" --author="Night" --grep=q --format=%s >actual &&
-       >expect &&
+test_expect_success 'log --all-match --grep --grep --author takes intersection' '
+       # grep matches only third
+       # author matches only initial and third
+       git log --all-match --author="A U Thor" --grep=i --grep=r --format=%s >actual &&
+       {
+               echo third
+       } >expect &&
        test_cmp expect actual
 '
 
index ba19ac127e630c01e009fa6eda1fac0086d7184d..9c353ab22276c052de054281dd57808d1826a355 100755 (executable)
@@ -66,7 +66,7 @@ test_expect_success \
        git blame file2
 '
 
-test_expect_success 'blame runs on conflicted file in stages 1,3' '
+test_expect_success 'blame does not crash with conflicted file in stages 1,3' '
        git blame file1
 '
 
index b5e33e49c77bdf1d19292971b63ff5221b013f33..68739aaa3b9e9e1a1bbbd43c75c9b5c244fb6c3e 100644 (file)
--- a/wrapper.c
+++ b/wrapper.c
@@ -403,6 +403,19 @@ int remove_or_warn(unsigned int mode, const char *file)
        return S_ISGITLINK(mode) ? rmdir_or_warn(file) : unlink_or_warn(file);
 }
 
+void warn_on_inaccessible(const char *path)
+{
+       warning(_("unable to access '%s': %s"), path, strerror(errno));
+}
+
+int access_or_warn(const char *path, int mode)
+{
+       int ret = access(path, mode);
+       if (ret && errno != ENOENT)
+               warn_on_inaccessible(path);
+       return ret;
+}
+
 struct passwd *xgetpwuid_self(void)
 {
        struct passwd *pw;