Merge branch 'ml/cygwin-mingw-headers'
authorJunio C Hamano <gitster@pobox.com>
Tue, 20 Nov 2012 18:44:29 +0000 (10:44 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 20 Nov 2012 18:44:29 +0000 (10:44 -0800)
Make git compile on cygwin with newer header files.

* ml/cygwin-mingw-headers:
USE CGYWIN_V15_WIN32API as macro to select api for cygwin
Update cygwin.c for new mingw-64 win32 api headers

80 files changed:
Documentation/Makefile
Documentation/RelNotes/1.8.0.1.txt [new file with mode: 0644]
Documentation/RelNotes/1.8.1.txt [new file with mode: 0644]
Documentation/SubmittingPatches
Documentation/git-bisect-lk2009.txt
Documentation/git-commit.txt
Documentation/git-cvsimport.txt
Documentation/git-fetch-pack.txt
Documentation/git-format-patch.txt
Documentation/git-notes.txt
Documentation/git-rm.txt
Documentation/git-symbolic-ref.txt
Documentation/howto/maintain-git.txt
Documentation/howto/rebase-from-internal-branch.txt
Documentation/howto/rebuild-from-update-hook.txt
Documentation/howto/recover-corrupted-blob-object.txt
Documentation/howto/revert-a-faulty-merge.txt
Documentation/howto/revert-branch-rebase.txt
Documentation/howto/separating-topic-branches.txt
Documentation/howto/setup-git-server-over-http.txt
Documentation/howto/update-hook-example.txt
Documentation/howto/use-git-daemon.txt
Documentation/howto/using-signed-tag-in-pull-request.txt
Documentation/technical/api-strbuf.txt
Documentation/technical/api-string-list.txt
Documentation/technical/index-format.txt
Documentation/technical/pack-format.txt
Documentation/technical/pack-protocol.txt
Documentation/technical/send-pack-pipeline.txt
Documentation/technical/shallow.txt
Documentation/technical/trivial-merge.txt
Documentation/user-manual.txt
Makefile
RelNotes
builtin/blame.c
builtin/checkout.c
builtin/config.c
builtin/diff-index.c
builtin/diff.c
builtin/mailinfo.c
builtin/replace.c
builtin/symbolic-ref.c
builtin/update-index.c
commit.h
diffcore-pickaxe.c
git-cvsimport.perl
git-p4.py
git-parse-remote.sh
git-submodule.sh
gitweb/gitweb.perl
log-tree.c
notes.c
notes.h
pretty.c
remote-curl.c
remote.c
revision.c
revision.h
sequencer.c
sha1_file.c
strbuf.c
strbuf.h
string-list.c
string-list.h
t/lib-httpd/apache.conf
t/t1300-repo-config.sh
t/t1401-symbolic-ref.sh
t/t4014-format-patch.sh
t/t4030-diff-textconv.sh
t/t5551-http-fetch.sh
t/t6050-replace.sh
t/t7403-submodule-sync.sh
t/t9502-gitweb-standalone-parse-output.sh
t/t9604-cvsimport-timestamps.sh [new file with mode: 0755]
t/t9604/cvsroot/.gitattributes [new file with mode: 0644]
t/t9604/cvsroot/CVSROOT/.gitignore [new file with mode: 0644]
t/t9604/cvsroot/module/a,v [new file with mode: 0644]
t/t9810-git-p4-rcs.sh
utf8.c
utf8.h
index 267dfe135ddef1d5e6cc452d6fdcd8b22b9e36a2..361550422a6e180f5614305985cfd12aa964ffe0 100644 (file)
@@ -24,8 +24,30 @@ SP_ARTICLES = user-manual
 SP_ARTICLES += howto/revert-branch-rebase
 SP_ARTICLES += howto/using-merge-subtree
 SP_ARTICLES += howto/using-signed-tag-in-pull-request
+SP_ARTICLES += howto/use-git-daemon
+SP_ARTICLES += howto/update-hook-example
+SP_ARTICLES += howto/setup-git-server-over-http
+SP_ARTICLES += howto/separating-topic-branches
+SP_ARTICLES += howto/revert-a-faulty-merge
+SP_ARTICLES += howto/recover-corrupted-blob-object
+SP_ARTICLES += howto/rebuild-from-update-hook
+SP_ARTICLES += howto/rebuild-from-update-hook
+SP_ARTICLES += howto/rebase-from-internal-branch
+SP_ARTICLES += howto/maintain-git
 API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technical/api-index.txt, $(wildcard technical/api-*.txt)))
 SP_ARTICLES += $(API_DOCS)
+
+TECH_DOCS = technical/index-format
+TECH_DOCS += technical/pack-format
+TECH_DOCS += technical/pack-heuristics
+TECH_DOCS += technical/pack-protocol
+TECH_DOCS += technical/protocol-capabilities
+TECH_DOCS += technical/protocol-common
+TECH_DOCS += technical/racy-git
+TECH_DOCS += technical/send-pack-pipeline
+TECH_DOCS += technical/shallow
+TECH_DOCS += technical/trivial-merge
+SP_ARTICLES += $(TECH_DOCS)
 SP_ARTICLES += technical/api-index
 
 DOC_HTML += $(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES))
@@ -231,7 +253,7 @@ clean:
        $(RM) *.texi *.texi+ *.texi++ git.info gitman.info
        $(RM) *.pdf
        $(RM) howto-index.txt howto/*.html doc.dep
-       $(RM) technical/api-*.html technical/api-index.txt
+       $(RM) technical/*.html technical/api-index.txt
        $(RM) $(cmds_txt) *.made
        $(RM) manpage-base-url.xsl
 
@@ -264,7 +286,7 @@ technical/api-index.txt: technical/api-index-skel.txt \
        $(QUIET_GEN)cd technical && '$(SHELL_PATH_SQ)' ./api-index.sh
 
 technical/%.html: ASCIIDOC_EXTRA += -a git-relative-html-prefix=../
-$(patsubst %,%.html,$(API_DOCS) technical/api-index): %.html : %.txt
+$(patsubst %,%.html,$(API_DOCS) technical/api-index $(TECH_DOCS)): %.html : %.txt
        $(QUIET_ASCIIDOC)$(ASCIIDOC) -b xhtml11 -f asciidoc.conf \
                $(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) $*.txt
 
diff --git a/Documentation/RelNotes/1.8.0.1.txt b/Documentation/RelNotes/1.8.0.1.txt
new file mode 100644 (file)
index 0000000..cda8b3e
--- /dev/null
@@ -0,0 +1,52 @@
+Git v1.8.0.1 Release Notes
+==========================
+
+Fixes since v1.8.0
+------------------
+
+ * The configuration parser had an unnecessary hardcoded limit on
+   variable names that was not checked consistently.
+
+ * The "say" function in the test scaffolding incorrectly allowed
+   "echo" to interpret "\a" as if it were a C-string asking for a
+   BEL output.
+
+ * "git mergetool" feeds /dev/null as a common ancestor when dealing
+   with an add/add conflict, but p4merge backend cannot handle
+   it. Work it around by passing a temporary empty file.
+
+ * "git log -F -E --grep='<ere>'" failed to use the given <ere>
+   pattern as extended regular expression, and instead looked for the
+   string literally.
+
+ * "git grep -e pattern <tree>" asked the attribute system to read
+   "<tree>:.gitattributes" file in the working tree, which was
+   nonsense.
+
+ * A symbolic ref refs/heads/SYM was not correctly removed with "git
+   branch -d SYM"; the command removed the ref pointed by SYM
+   instead.
+
+ * Earlier we fixed documentation to hyphenate "remote-tracking branch"
+   to clarify that these are not a remote entity, but unhyphenated
+   spelling snuck in to a few places since then.
+
+ * "git pull --rebase" run while the HEAD is detached tried to find
+   the upstream branch of the detached HEAD (which by definition
+   does not exist) and emitted unnecessary error messages.
+
+ * The refs/replace hierarchy was not mentioned in the
+   repository-layout docs.
+
+ * Sometimes curl_multi_timeout() function suggested a wrong timeout
+   value when there is no file descriptors to wait on and the http
+   transport ended up sleeping for minutes in select(2) system call.
+   A workaround has been added for this.
+
+ * Various rfc2047 quoting issues around a non-ASCII name on the
+   From: line in the output from format-patch have been corrected.
+
+ * "git diff -G<pattern>" did not honor textconv filter when looking
+   for changes.
+
+Also contains other minor fixes and documentation updates.
diff --git a/Documentation/RelNotes/1.8.1.txt b/Documentation/RelNotes/1.8.1.txt
new file mode 100644 (file)
index 0000000..107e5f3
--- /dev/null
@@ -0,0 +1,151 @@
+Git v1.8.1 Release Notes
+========================
+
+Backward compatibility notes
+----------------------------
+
+In the next major release (not *this* one), we will change the
+behavior of the "git push" command.
+
+When "git push [$there]" does not say what to push, we have used the
+traditional "matching" semantics so far (all your branches were sent
+to the remote as long as there already are branches of the same name
+over there).  We will use the "simple" semantics that pushes the
+current branch to the branch with the same name, only when the current
+branch is set to integrate with that remote branch.  There is a user
+preference configuration variable "push.default" to change this, and
+"git push" will warn about the upcoming change until you set this
+variable in this release.
+
+"git branch --set-upstream" is deprecated and may be removed in a
+relatively distant future.  "git branch [-u|--set-upstream-to]" has
+been introduced with a saner order of arguments.
+
+
+Updates since v1.8.0
+--------------------
+
+UI, Workflows & Features
+
+ * We used to have a workaround for a bug in ancient "less" that
+   causes it to exit without any output when the terminal is resized.
+   The bug has been fixed in "less" version 406 (June 2007), and the
+   workaround has been removed in this release.
+
+ * A new configuration variable "diff.context" can be used to
+   give the default number of context lines in the patch output, to
+   override the hardcoded default of 3 lines.
+
+ * "git format-patch" leraned the "--notes=<ref>" option to give
+   notes for the commit after the three-dash lines in its output.
+
+ * "git log --grep=<pcre>" learned to honor the "grep.patterntype"
+   configuration set to "perl".
+
+ * "git rm $submodule" used to punt on removing a submodule working
+   tree to avoid losing the repository embedded in it.  Because
+   recent git uses a mechanism to separate the submodule repository
+   from the submodule working tree, "git rm" learned to detect this
+   case and removes the submodule working tree when it is safe.
+
+ * "git submodule add" learned to add a new submodule at the same
+   path as the path where an unrelated submodule was bound to in an
+   existing revision via the "--name" option.
+
+ * "git submodule sync" learned the "--recursive" option.
+
+ * "git symbolic-ref" learned the "-d $symref" option to delete the
+   named symbolic ref, which is more intuitive way to spell it than
+   "update-ref -d --no-deref".
+
+
+Foreign Interface
+
+ * "git cvsimport" can be told to record timezones (other than GMT)
+   per-author via its author info file.
+
+ * The remote helper interface to interact with subversion
+   repositories (one of the GSoC 2012 projects) has been merged.
+
+
+Performance, Internal Implementation, etc.
+
+ * The logic to generate the initial advertisement from
+   "upload-pack" (what is invoked by "git fetch" on the other side
+   of the connection) to list what refs are available in the
+   repository has been optimized.
+
+ * The logic to find set of attributes that match a given path has
+   been optimized.
+
+
+Also contains minor documentation updates and code clean-ups.
+
+
+Fixes since v1.8.0
+------------------
+
+Unless otherwise noted, all the fixes since v1.8.0 in the maintenance
+track are contained in this release (see release notes to them for
+details).
+
+ * The configuration parser had an unnecessary hardcoded limit on
+   variable names that was not checked consistently.
+   (merge 0971e99 bw/config-lift-variable-name-length-limit later to maint).
+
+ * The "say" function in the test scaffolding incorrectly allowed
+   "echo" to interpret "\a" as if it were a C-string asking for a
+   BEL output.
+   (merge 7bc0911 jc/test-say-color-avoid-echo-escape later to maint).
+
+ * "git mergetool" feeds /dev/null as a common ancestor when dealing
+   with an add/add conflict, but p4merge backend cannot handle
+   it. Work it around by passing a temporary empty file.
+   (merge 3facc60 da/mergetools-p4 later to maint).
+
+ * "git log -F -E --grep='<ere>'" failed to use the given <ere>
+   pattern as extended regular expression, and instead looked for the
+   string literally.
+   (merge 727b6fc jc/grep-pcre-loose-ends~1 later to maint).
+
+ * "git grep -e pattern <tree>" asked the attribute system to read
+   "<tree>:.gitattributes" file in the working tree, which was
+   nonsense.
+   (merge 55c6168 nd/grep-true-path later to maint).
+
+ * A symbolic ref refs/heads/SYM was not correctly removed with "git
+   branch -d SYM"; the command removed the ref pointed by SYM
+   instead.
+   (merge 13baa9f rs/branch-del-symref later to maint).
+
+ * Update "remote tracking branch" in the documentation to
+   "remote-tracking branch".
+   (merge a6d3bde mm/maint-doc-remote-tracking later to maint).
+
+ * "git pull --rebase" run while the HEAD is detached tried to find
+   the upstream branch of the detached HEAD (which by definition
+   does not exist) and emitted unnecessary error messages.
+   (merge e980765 ph/pull-rebase-detached later to maint).
+
+ * The refs/replace hierarchy was not mentioned in the
+   repository-layout docs.
+   (merge 11fbe18 po/maint-refs-replace-docs later to maint).
+
+ * Various rfc2047 quoting issues around a non-ASCII name on the
+   From: line in the output from format-patch has been corrected.
+   (merge 25dc8da js/format-2047 later to maint).
+
+ * Sometimes curl_multi_timeout() function suggested a wrong timeout
+   value when there is no file descriptors to wait on and the http
+   transport ended up sleeping for minutes in select(2) system call.
+   A workaround has been added for this.
+   (merge 7202b81 sz/maint-curl-multi-timeout later to maint).
+
+ * For a fetch refspec (or the result of applying wildcard on one),
+   we always want the RHS to map to something inside "refs/"
+   hierarchy, but the logic to check it was not exactly right.
+   (merge 5c08c1f jc/maint-fetch-tighten-refname-check later to maint).
+
+ * "git diff -G<pattern>" did not honor textconv filter when looking
+   for changes.
+   (merge b1c2f57 jk/maint-diff-grep-textconv later to maint).
index 0dbf2c9843dd3eed014d788892c8719036287308..3d8b2fe4d18875f8505b91850dd33ec79b122076 100644 (file)
@@ -179,7 +179,8 @@ message starts, you can put a "From: " line to name that person.
 
 You often want to add additional explanation about the patch,
 other than the commit message itself.  Place such "cover letter"
-material between the three dash lines and the diffstat.
+material between the three dash lines and the diffstat. Git-notes
+can also be inserted using the `--notes` option.
 
 Do not attach the patch as a MIME attachment, compressed or not.
 Do not let your e-mail client send quoted-printable.  Do not let
index 8a2ba3790417d80f6e71e45bc07b1f3cbea41329..ec4497e09867d200554ead3c1aadc898252044cc 100644 (file)
@@ -257,7 +257,7 @@ Date:   Sat May 3 11:59:44 2008 -0700
 
     Linux 2.6.26-rc1
 
-:100644 100644 5cf8258195331a4dbdddff08b8d68642638eea57 4492984efc09ab72ff6219a7bc21fb6a957c4cd5 M      Makefile
+:100644 100644 5cf82581... 4492984e... M      Makefile
 -------------
 
 At this point we can see what the commit does, check it out (if it's
@@ -331,7 +331,7 @@ Date:   Sat May 3 11:59:44 2008 -0700
 
     Linux 2.6.26-rc1
 
-:100644 100644 5cf8258195331a4dbdddff08b8d68642638eea57 4492984efc09ab72ff6219a7bc21fb6a957c4cd5 M      Makefile
+:100644 100644 5cf82581... 4492984e... M      Makefile
 bisect run success
 -------------
 
index 0295890621117ae3981485eec5872d3dcfb23af6..7bdb039d5ee9c6ed6c19c70173c733860de2d5b7 100644 (file)
@@ -188,6 +188,11 @@ OPTIONS
        commit log message unmodified.  This option lets you
        further edit the message taken from these sources.
 
+--no-edit::
+       Use the selected commit message without launching an editor.
+       For example, `git commit --amend --no-edit` amends a commit
+       without changing its commit message.
+
 --amend::
        Used to amend the tip of the current branch. Prepare the tree
        object you would want to replace the latest commit as usual
@@ -197,10 +202,6 @@ OPTIONS
        current tip -- if it was a merge, it will have the parents of
        the current tip as parents -- so the current top commit is
        discarded.
-
---no-post-rewrite::
-       Bypass the post-rewrite hook.
-
 +
 --
 It is a rough equivalent for:
@@ -217,6 +218,9 @@ You should understand the implications of rewriting history if you
 amend a commit that has already been published.  (See the "RECOVERING
 FROM UPSTREAM REBASE" section in linkgit:git-rebase[1].)
 
+--no-post-rewrite::
+       Bypass the post-rewrite hook.
+
 -i::
 --include::
        Before making a commit out of staged contents so far,
index 6695ab3b4b93aa7c5829f89ceff936de48e9bc78..98d9881d7e891e4728c09f6536c3506b3688d145 100644 (file)
@@ -137,17 +137,19 @@ This option can be used several times to provide several detection regexes.
 -A <author-conv-file>::
        CVS by default uses the Unix username when writing its
        commit logs. Using this option and an author-conv-file
-       in this format
+       maps the name recorded in CVS to author name, e-mail and
+       optional timezone:
 +
 ---------
        exon=Andreas Ericsson <ae@op5.se>
-       spawn=Simon Pawn <spawn@frog-pond.org>
+       spawn=Simon Pawn <spawn@frog-pond.org> America/Chicago
 
 ---------
 +
 'git cvsimport' will make it appear as those authors had
 their GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL set properly
-all along.
+all along.  If a timezone is specified, GIT_AUTHOR_DATE will
+have the corresponding offset applied.
 +
 For convenience, this data is saved to `$GIT_DIR/cvs-authors`
 each time the '-A' option is provided and read from that same
index 474fa307a093ed126ab4f2216103a042d4bb0930..8c751202d75ec5f3e62b7c386bb168f13e63e295 100644 (file)
@@ -9,7 +9,10 @@ git-fetch-pack - Receive missing objects from another repository
 SYNOPSIS
 --------
 [verse]
-'git fetch-pack' [--all] [--quiet|-q] [--keep|-k] [--thin] [--include-tag] [--upload-pack=<git-upload-pack>] [--depth=<n>] [--no-progress] [-v] [<host>:]<directory> [<refs>...]
+'git fetch-pack' [--all] [--quiet|-q] [--keep|-k] [--thin] [--include-tag]
+                               [--upload-pack=<git-upload-pack>]
+                               [--depth=<n>] [--no-progress]
+                               [-v] [<host>:]<directory> [<refs>...]
 
 DESCRIPTION
 -----------
index 6d43f56279fe7a0d42510035e33424df0bc584f1..259dce49945089de03ad2c0ac8ae8e56cfdc04e0 100644 (file)
@@ -20,7 +20,7 @@ SYNOPSIS
                   [--ignore-if-in-upstream]
                   [--subject-prefix=Subject-Prefix]
                   [--to=<email>] [--cc=<email>]
-                  [--cover-letter] [--quiet]
+                  [--cover-letter] [--quiet] [--notes[=<ref>]]
                   [<common diff options>]
                   [ <since> | <revision range> ]
 
@@ -191,6 +191,18 @@ will want to ensure that threading is disabled for `git send-email`.
        containing the shortlog and the overall diffstat.  You can
        fill in a description in the file before sending it out.
 
+--notes[=<ref>]::
+       Append the notes (see linkgit:git-notes[1]) for the commit
+       after the three-dash line.
++
+The expected use case of this is to write supporting explanation for
+the commit that does not belong to the commit log message proper,
+and include it with the patch submission. While one can simply write
+these explanations after `format-patch` has run but before sending,
+keeping them as git notes allows them to be maintained between versions
+of the patch series (but see the discussion of the `notes.rewrite`
+configuration options in linkgit:git-notes[1] to use this workflow).
+
 --[no]-signature=<signature>::
        Add a signature to each message produced. Per RFC 3676 the signature
        is separated from the body by a line with '-- ' on it. If the
index b95aafae2d7540d86d1b804871ef26dfbc41664e..46ef0466beed0b297f986a652e4da1efedf2681c 100644 (file)
@@ -39,6 +39,10 @@ message stored in the commit object, the notes are indented like the
 message, after an unindented line saying "Notes (<refname>):" (or
 "Notes:" for `refs/notes/commits`).
 
+Notes can also be added to patches prepared with `git format-patch` by
+using the `--notes` option. Such notes are added as a patch commentary
+after a three dash separator line.
+
 To change which notes are shown by 'git log', see the
 "notes.displayRef" configuration in linkgit:git-log[1].
 
index 882cb1171bb361cd527cd71b8b06639237582dba..262436b7b14a3ace7f63a88b79d85baf9b26ba04 100644 (file)
@@ -107,21 +107,6 @@ as well as modifications of existing paths.
 Typically you would first remove all tracked files from the working
 tree using this command:
 
-Submodules
-~~~~~~~~~~
-Only submodules using a gitfile (which means they were cloned
-with a git version 1.7.8 or newer) will be removed from the work
-tree, as their repository lives inside the .git directory of the
-superproject. If a submodule (or one of those nested inside it)
-still uses a .git directory, `git rm` will fail - no matter if forced
-or not - to protect the submodule's history.
-
-A submodule is considered up-to-date when the HEAD is the same as
-recorded in the index, no tracked files are modified and no untracked
-files that aren't ignored are present in the submodules work tree.
-Ignored files are deemed expendable and won't stop a submodule's work
-tree from being removed.
-
 ----------------
 git ls-files -z | xargs -0 rm -f
 ----------------
@@ -149,6 +134,21 @@ use the following command:
 git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
 ----------------
 
+Submodules
+~~~~~~~~~~
+Only submodules using a gitfile (which means they were cloned
+with a git version 1.7.8 or newer) will be removed from the work
+tree, as their repository lives inside the .git directory of the
+superproject. If a submodule (or one of those nested inside it)
+still uses a .git directory, `git rm` will fail - no matter if forced
+or not - to protect the submodule's history.
+
+A submodule is considered up-to-date when the HEAD is the same as
+recorded in the index, no tracked files are modified and no untracked
+files that aren't ignored are present in the submodules work tree.
+Ignored files are deemed expendable and won't stop a submodule's work
+tree from being removed.
+
 EXAMPLES
 --------
 `git rm Documentation/\*.txt`::
index 981d3a8fc12cde403cd2d29c86a63b56ca3028b3..ef68ad2b7112d5749fd7ee090befe248ceb27204 100644 (file)
@@ -3,13 +3,14 @@ git-symbolic-ref(1)
 
 NAME
 ----
-git-symbolic-ref - Read and modify symbolic refs
+git-symbolic-ref - Read, modify and delete symbolic refs
 
 SYNOPSIS
 --------
 [verse]
 'git symbolic-ref' [-m <reason>] <name> <ref>
 'git symbolic-ref' [-q] [--short] <name>
+'git symbolic-ref' --delete [-q] <name>
 
 DESCRIPTION
 -----------
@@ -21,6 +22,9 @@ argument to see which branch your working tree is on.
 Given two arguments, creates or updates a symbolic ref <name> to
 point at the given branch <ref>.
 
+Given `--delete` and an additional argument, deletes the given
+symbolic ref.
+
 A symbolic ref is a regular file that stores a string that
 begins with `ref: refs/`.  For example, your `.git/HEAD` is
 a regular file whose contents is `ref: refs/heads/master`.
@@ -28,6 +32,10 @@ a regular file whose contents is `ref: refs/heads/master`.
 OPTIONS
 -------
 
+-d::
+--delete::
+       Delete the symbolic ref <name>.
+
 -q::
 --quiet::
        Do not issue an error message if the <name> is not a
index 8823a37067811037487a9f0496736bfafdc8b7ad..ea6e4a52c91ced6a86f85408971ee16686ba8baa 100644 (file)
@@ -5,6 +5,10 @@ Abstract: Imagine that git development is racing along as usual, when our friend
  neighborhood maintainer is struck down by a wayward bus. Out of the
  hordes of suckers (loyal developers), you have been tricked (chosen) to
  step up as the new maintainer. This howto will show you "how to" do it.
+Content-type: text/asciidoc
+
+How to maintain Git
+===================
 
 The maintainer's git time is spent on three activities.
 
index 74a1c0c4ba3a03ba02cbbabcf0ee6cff22e4b099..4627ee47f2ce86761344e0a57aed2cada94b6b9c 100644 (file)
@@ -8,7 +8,12 @@ Abstract: In this article, JC talks about how he rebases the
  the "master" branch, and how "rebase" works.  Also discussed
  is how this applies to individual developers who sends patches
  upstream.
+Content-type: text/asciidoc
 
+How to rebase from an internal branch
+=====================================
+
+--------------------------------------
 Petr Baudis <pasky@suse.cz> writes:
 
 > Dear diary, on Sun, Aug 14, 2005 at 09:57:13AM CEST, I got a letter
@@ -19,6 +24,7 @@ Petr Baudis <pasky@suse.cz> writes:
 >> > branch to the real branches.
 >>
 > Actually, wouldn't this be also precisely for what StGIT is intended to?
+--------------------------------------
 
 Exactly my feeling.  I was sort of waiting for Catalin to speak
 up.  With its basing philosophical ancestry on quilt, this is
@@ -156,8 +162,3 @@ you continue on starting from the new "master" head, which is
 the #1' commit.
 
 -jc
-
--
-To unsubscribe from this list: send the line "unsubscribe git" in
-the body of a message to majordomo@vger.kernel.org
-More majordomo info at  http://vger.kernel.org/majordomo-info.html
index 48c67568d3418b2d6608f362f4b76e02ec450abc..00c1b45b7963ea38c87dca95a94e8ccfc273f7b1 100644 (file)
@@ -5,6 +5,10 @@ Date: Fri, 26 Aug 2005 18:19:10 -0700
 Abstract: In this how-to article, JC talks about how he
  uses the post-update hook to automate git documentation page
  shown at http://www.kernel.org/pub/software/scm/git/docs/.
+Content-type: text/asciidoc
+
+How to rebuild from update hook
+===============================
 
 The pages under http://www.kernel.org/pub/software/scm/git/docs/
 are built from Documentation/ directory of the git.git project
index 323b513ed0e0ce8b749672f589a375073a050b97..748473532061c7f7f28e27eeeab38f7a58fafaed 100644 (file)
@@ -3,11 +3,17 @@ From: Linus Torvalds <torvalds@linux-foundation.org>
 Subject: corrupt object on git-gc
 Abstract: Some tricks to reconstruct blob objects in order to fix
  a corrupted repository.
+Content-type: text/asciidoc
 
+How to recover a corrupted blob object
+======================================
+
+-----------------------------------------------------------
 On Fri, 9 Nov 2007, Yossi Leybovich wrote:
 >
 > Did not help still the repository look for this object?
 > Any one know how can I track this object and understand which file is it
+-----------------------------------------------------------
 
 So exactly *because* the SHA1 hash is cryptographically secure, the hash
 itself doesn't actually tell you anything, in order to fix a corrupt
@@ -31,19 +37,23 @@ original object, so right now the corrupt object is useless, but it's very
 interesting for the future, in the hope that you can re-create a
 non-corrupt version.
 
+-----------------------------------------------------------
 So:
 
 > ib]$ mv .git/objects/4b/9458b3786228369c63936db65827de3cc06200 ../
+-----------------------------------------------------------
 
 This is the right thing to do, although it's usually best to save it under
 it's full SHA1 name (you just dropped the "4b" from the result ;).
 
 Let's see what that tells us:
 
+-----------------------------------------------------------
 > ib]$ git-fsck --full
 > broken link from    tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
 >              to    blob 4b9458b3786228369c63936db65827de3cc06200
 > missing blob 4b9458b3786228369c63936db65827de3cc06200
+-----------------------------------------------------------
 
 Ok, I removed the "dangling commit" messages, because they are just
 messages about the fact that you probably have rebased etc, so they're not
index 6fd711996a775d1da8ab2051db98896a601c8971..8a685483f419cb75eca4f51c93bac378900fe227 100644 (file)
@@ -7,6 +7,10 @@ Abstract: Sometimes a branch that was already merged to the mainline
  after the offending branch is fixed.
 Message-ID: <7vocz8a6zk.fsf@gitster.siamese.dyndns.org>
 References: <alpine.LFD.2.00.0812181949450.14014@localhost.localdomain>
+Content-type: text/asciidoc
+
+How to revert a faulty merge
+============================
 
 Alan <alan@clueserver.org> said:
 
index 093c656048a81e6cdc46d1aecf80fbffd97c94ea..a59ced8d046eeece06c2b621c21efb088932bf3a 100644 (file)
@@ -8,8 +8,8 @@ Date: Mon, 29 Aug 2005 21:39:02 -0700
 Content-type: text/asciidoc
 Message-ID: <7voe7g3uop.fsf@assigned-by-dhcp.cox.net>
 
-Reverting an existing commit
-============================
+How to revert an existing commit
+================================
 
 One of the changes I pulled into the 'master' branch turns out to
 break building GIT with GCC 2.95.  While they were well intentioned
index 6d3eb8ed00e1779efce8abe201d37c8cff07ec29..bd1027433bb7c54cf16cb1bcdedac0d4ee669e4e 100644 (file)
@@ -1,6 +1,10 @@
 From: Junio C Hamano <gitster@pobox.com>
 Subject: Separating topic branches
 Abstract: In this article, JC describes how to separate topic branches.
+Content-type: text/asciidoc
+
+How to separate topic branches
+==============================
 
 This text was originally a footnote to a discussion about the
 behaviour of the git diff commands.
index 622ee5c8dd7c384794a21baa6093d85a47f89a54..a695f01f0e41aca5285c54d70196386ced64e1cb 100644 (file)
@@ -1,6 +1,10 @@
 From: Rutger Nijlunsing <rutger@nospam.com>
 Subject: Setting up a git repository which can be pushed into and pulled from over HTTP(S).
 Date: Thu, 10 Aug 2006 22:00:26 +0200
+Content-type: text/asciidoc
+
+How to setup git server over http
+=================================
 
 Since Apache is one of those packages people like to compile
 themselves while others prefer the bureaucrat's dream Debian, it is
index b7f8d416d65ca1cf17d6348e858a13f6ed72c7fe..a5193b1e5c45e3d9a78de7604f104a8a80c3bdd8 100644 (file)
@@ -5,6 +5,10 @@ Message-ID: <7vfypumlu3.fsf@assigned-by-dhcp.cox.net>
 Abstract: An example hooks/update script is presented to
  implement repository maintenance policies, such as who can push
  into which branch and who can make a tag.
+Content-type: text/asciidoc
+
+How to use the update hook
+==========================
 
 When your developer runs git-push into the repository,
 git-receive-pack is run (either locally or over ssh) as that
@@ -32,8 +36,7 @@ like this as your hooks/update script.
 [jc: editorial note.  This is a much improved version by Carl
 since I posted the original outline]
 
--- >8 -- beginning of script -- >8 --
-
+----------------------------------------------------
 #!/bin/bash
 
 umask 002
@@ -111,12 +114,12 @@ then
 
       info "Found matching head pattern: '$head_pattern'"
       for user_pattern in $user_patterns; do
-       info "Checking user: '$username' against pattern: '$user_pattern'"
-       matchlen=$(expr "$username" : "$user_pattern")
-       if test "$matchlen" = "${#username}"
-       then
-         grant "Allowing user: '$username' with pattern: '$user_pattern'"
-       fi
+        info "Checking user: '$username' against pattern: '$user_pattern'"
+        matchlen=$(expr "$username" : "$user_pattern")
+        if test "$matchlen" = "${#username}"
+        then
+          grant "Allowing user: '$username' with pattern: '$user_pattern'"
+        fi
       done
       deny "The user is not in the access list for this branch"
     done
@@ -149,13 +152,13 @@ then
 
       info "Found matching head pattern: '$head_pattern'"
       for group_pattern in $group_patterns; do
-       for groupname in $groups; do
-         info "Checking group: '$groupname' against pattern: '$group_pattern'"
-         matchlen=$(expr "$groupname" : "$group_pattern")
-         if test "$matchlen" = "${#groupname}"
-         then
-           grant "Allowing group: '$groupname' with pattern: '$group_pattern'"
-         fi
+        for groupname in $groups; do
+          info "Checking group: '$groupname' against pattern: '$group_pattern'"
+          matchlen=$(expr "$groupname" : "$group_pattern")
+          if test "$matchlen" = "${#groupname}"
+          then
+            grant "Allowing group: '$groupname' with pattern: '$group_pattern'"
+          fi
         done
       done
       deny "None of the user's groups are in the access list for this branch"
@@ -169,24 +172,21 @@ then
 fi
 
 deny >/dev/null "There are no more rules to check.  Denying access"
-
--- >8 -- end of script -- >8 --
+----------------------------------------------------
 
 This uses two files, $GIT_DIR/info/allowed-users and
 allowed-groups, to describe which heads can be pushed into by
 whom.  The format of each file would look like this:
 
-        refs/heads/master      junio
-       +refs/heads/pu          junio
-        refs/heads/cogito$     pasky
-        refs/heads/bw/.*       linus
-        refs/heads/tmp/.*      .*
-        refs/tags/v[0-9].*     junio
+    refs/heads/master   junio
+    +refs/heads/pu      junio
+    refs/heads/cogito$  pasky
+    refs/heads/bw/.*    linus
+    refs/heads/tmp/.*   .*
+    refs/tags/v[0-9].*  junio
 
 With this, Linus can push or create "bw/penguin" or "bw/zebra"
 or "bw/panda" branches, Pasky can do only "cogito", and JC can
 do master and pu branches and make versioned tags.  And anybody
 can do tmp/blah branches. The '+' sign at the pu record means
 that JC can make non-fast-forward pushes on it.
-
-------------
index 4e2f75cb6167633c97ec1981d2b6659368cc0170..23cdf35435414c5f5127ca50a32cf7c970803c1f 100644 (file)
@@ -1,4 +1,7 @@
+Content-type: text/asciidoc
+
 How to use git-daemon
+=====================
 
 Git can be run in inetd mode and in stand alone mode. But all you want is
 let a coworker pull from you, and therefore need to set up a git server
index 98c0033a55f25e8c157a580dbdadc941b33dfda0..00f693bde86fce09dc44621fe7aed5181f26ebee 100644 (file)
@@ -7,8 +7,8 @@ Abstract: Beginning v1.7.9, a contributor can push a signed tag to her
  later validate it.
 Content-type: text/asciidoc
 
-Using signed tag in pull requests
-=================================
+How to use a signed tag in pull requests
+========================================
 
 A typical distributed workflow using Git is for a contributor to fork a
 project, build on it, publish the result to her public repository, and ask
index 95a8bf3846b30650f3ee089a4fbadfcc5a42da20..84686b5c69348ef67819818b7223c77f501965d0 100644 (file)
@@ -279,6 +279,22 @@ same behaviour as well.
        Strip whitespace from a buffer. The second parameter controls if
        comments are considered contents to be removed or not.
 
+`strbuf_split_buf`::
+`strbuf_split_str`::
+`strbuf_split_max`::
+`strbuf_split`::
+
+       Split a string or strbuf into a list of strbufs at a specified
+       terminator character.  The returned substrings include the
+       terminator characters.  Some of these functions take a `max`
+       parameter, which, if positive, limits the output to that
+       number of substrings.
+
+`strbuf_list_free`::
+
+       Free a list of strbufs (for example, the return values of the
+       `strbuf_split()` functions).
+
 `launch_editor`::
 
        Launch the user preferred editor to edit a file and fill the buffer
index 94d7a2bd999ce5e8603f6d6639ba34d224c2bee5..7386bcab3ec30a06f4663c953fa46e78ed26c07b 100644 (file)
@@ -38,7 +38,8 @@ member (you need this if you add things later) and you should set the
   `unsorted_string_list_delete_item`.
 
 . Can remove items not matching a criterion from a sorted or unsorted
-  list using `filter_string_list`.
+  list using `filter_string_list`, or remove empty strings using
+  `string_list_remove_empty_items`.
 
 . Finally it should free the list using `string_list_clear`.
 
@@ -75,6 +76,12 @@ Functions
        to be deleted.  Preserve the order of the items that are
        retained.
 
+`string_list_remove_empty_items`::
+
+       Remove any empty strings from the list.  If free_util is true,
+       call free() on the util members of any items that have to be
+       deleted.  Preserve the order of the items that are retained.
+
 `string_list_longest_prefix`::
 
        Return the longest string within a string_list that is a
index 9d25b30178e30458deded19a77f66e7dd0df1227..57d6f915b143765b9e58b3793f14795ddab71200 100644 (file)
@@ -1,7 +1,7 @@
 GIT index format
 ================
 
-= The git index file has the following format
+== The git index file has the following format
 
   All binary numbers are in network byte order. Version 2 is described
   here unless stated otherwise.
index 1803e64e465fa4f8f0fe520fc0fd95d0c9def5bd..a7871fb865d9c41f26011d6fd06c531538c2379e 100644 (file)
@@ -1,7 +1,7 @@
 GIT pack format
 ===============
 
-= pack-*.pack files have the following format:
+== pack-*.pack files have the following format:
 
    - A header appears at the beginning and consists of the following:
 
@@ -34,7 +34,7 @@ GIT pack format
 
   - The trailer records 20-byte SHA1 checksum of all of the above.
 
-= Original (version 1) pack-*.idx files have the following format:
+== Original (version 1) pack-*.idx files have the following format:
 
   - The header consists of 256 4-byte network byte order
     integers.  N-th entry of this table records the number of
@@ -123,8 +123,8 @@ Pack file entry: <+
 
 
 
-= Version 2 pack-*.idx files support packs larger than 4 GiB, and
-  have some other reorganizations.  They have the format:
+== Version 2 pack-*.idx files support packs larger than 4 GiB, and
+   have some other reorganizations.  They have the format:
 
   - A 4-byte magic number '\377tOc' which is an unreasonable
     fanout[0] value.
index d51e20f3526e2681b8c05c296b91dd90a4d3e322..f1a51edf47f94f45ce916f7800924e6f135800e2 100644 (file)
@@ -117,7 +117,7 @@ A few things to remember here:
 - The repository path is always quoted with single quotes.
 
 Fetching Data From a Server
-===========================
+---------------------------
 
 When one Git repository wants to get data that a second repository
 has, the first can 'fetch' from the second.  This operation determines
@@ -134,7 +134,8 @@ with the object name that each reference currently points to.
 
    $ echo -e -n "0039git-upload-pack /schacon/gitbook.git\0host=example.com\0" |
       nc -v example.com 9418
-   00887217a7c7e582c46cec22a130adf4b9d7d950fba0 HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress include-tag
+   00887217a7c7e582c46cec22a130adf4b9d7d950fba0 HEAD\0multi_ack thin-pack
+               side-band side-band-64k ofs-delta shallow no-progress include-tag
    00441d3fcd5ced445d1abc402225c0b8a1299641f497 refs/heads/integration
    003f7217a7c7e582c46cec22a130adf4b9d7d950fba0 refs/heads/master
    003cb88d2441cac0977faf98efc80305012112238d9d refs/tags/v0.9
@@ -421,7 +422,7 @@ entire packfile without multiplexing.
 
 
 Pushing Data To a Server
-========================
+------------------------
 
 Pushing data to a server will invoke the 'receive-pack' process on the
 server, which will allow the client to tell it which references it should
index 681efe42190fa28f8e6bc8f1eb569bfcf160ed4b..9b5a0bc186674d8bce4e32bbbff24a203020b943 100644 (file)
@@ -1,5 +1,5 @@
-git-send-pack
-=============
+Git-send-pack internals
+=======================
 
 Overall operation
 -----------------
index 559263af485f139d6c33d982bed9342aa4110e50..0502a5471e699aac572abd5ab82c71a03f07e9f1 100644 (file)
@@ -1,6 +1,12 @@
-Def.: Shallow commits do have parents, but not in the shallow
+Shallow commits
+===============
+
+.Definition
+*********************************************************
+Shallow commits do have parents, but not in the shallow
 repo, and therefore grafts are introduced pretending that
 these commits have no parents.
+*********************************************************
 
 The basic idea is to write the SHA1s of shallow commits into
 $GIT_DIR/shallow, and handle its contents like the contents
index 24c84100b0790be22330464e01ea876e5d30fc9a..c79d4a7c476da2c57c117529150de77646ed116e 100644 (file)
@@ -74,24 +74,24 @@ For multiple ancestors, a '+' means that this case applies even if
 only one ancestor or remote fits; a '^' means all of the ancestors
 must be the same.
 
-case  ancest    head    remote    result
-----------------------------------------
-1     (empty)+  (empty) (empty)   (empty)
-2ALT  (empty)+  *empty* remote    remote
-2     (empty)^  (empty) remote    no merge
-3ALT  (empty)+  head    *empty*   head
-3     (empty)^  head    (empty)   no merge
-4     (empty)^  head    remote    no merge
-5ALT  *         head    head      head
-6     ancest+   (empty) (empty)   no merge
-8     ancest^   (empty) ancest    no merge
-7     ancest+   (empty) remote    no merge
-10    ancest^   ancest  (empty)   no merge
-9     ancest+   head    (empty)   no merge
-16    anc1/anc2 anc1    anc2      no merge
-13    ancest+   head    ancest    head
-14    ancest+   ancest  remote    remote
-11    ancest+   head    remote    no merge
+ case  ancest    head    remote    result
+ ----------------------------------------
+ 1     (empty)+  (empty) (empty)   (empty)
+ 2ALT  (empty)+  *empty* remote    remote
+ 2     (empty)^  (empty) remote    no merge
+ 3ALT  (empty)+  head    *empty*   head
+ 3     (empty)^  head    (empty)   no merge
+ 4     (empty)^  head    remote    no merge
+ 5ALT  *         head    head      head
+ 6     ancest+   (empty) (empty)   no merge
+ 8     ancest^   (empty) ancest    no merge
+ 7     ancest+   (empty) remote    no merge
+ 10    ancest^   ancest  (empty)   no merge
+ 9     ancest+   head    (empty)   no merge
+ 16    anc1/anc2 anc1    anc2      no merge
+ 13    ancest+   head    ancest    head
+ 14    ancest+   ancest  remote    remote
+ 11    ancest+   head    remote    no merge
 
 Only #2ALT and #3ALT use *empty*, because these are the only cases
 where there can be conflicts that didn't exist before. Note that we
index 85651b57ae466496e98e9c2507072f9fa8125c4d..1b377dc20736320fb442255c88310d62078b21e0 100644 (file)
@@ -1787,6 +1787,13 @@ $ git format-patch origin
 will produce a numbered series of files in the current directory, one
 for each patch in the current branch but not in origin/HEAD.
 
+`git format-patch` can include an initial "cover letter". You can insert
+commentary on individual patches after the three dash line which
+`format-patch` places after the commit message but before the patch
+itself.  If you use `git notes` to track your cover letter material,
+`git format-patch --notes` will include the commit's notes in a similar
+manner.
+
 You can then import these into your mail client and send them by
 hand.  However, if you have a lot to send at once, you may prefer to
 use the linkgit:git-send-email[1] script to automate the process.
index 4d47af5d6b24aa51589b9c3d7a3e9eb5c4a39711..9bc5e403650d171f1b5e5a6868fdd66009739b7d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1386,6 +1386,10 @@ ifeq ($(uname_S),NONSTOP_KERNEL)
        MKDIR_WO_TRAILING_SLASH = YesPlease
        # RFE 10-120912-4693 submitted to HP NonStop development.
        NO_SETITIMER = UnfortunatelyYes
+       SANE_TOOL_PATH=/usr/coreutils/bin:/usr/local/bin
+       SHELL_PATH=/usr/local/bin/bash
+       # as of H06.25/J06.14, we might better use this
+       #SHELL_PATH=/usr/coreutils/bin/bash
 endif
 ifneq (,$(findstring MINGW,$(uname_S)))
        pathsep = ;
index 2484b38bbbae654684f65a874653487439f0df2f..28607146f3fec3b69cf5edacf2727e37ca2c89de 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/1.8.0.txt
\ No newline at end of file
+Documentation/RelNotes/1.8.1.txt
\ No newline at end of file
index c27ef21c2326afd29a68146d23c734c7ea708556..cfae5699051312943d90212fc9cbfda2aafb2288 100644 (file)
@@ -1425,7 +1425,7 @@ static void get_commit_info(struct commit *commit,
                            int detailed)
 {
        int len;
-       const char *subject;
+       const char *subject, *encoding;
        char *reencoded, *message;
        static char author_name[1024];
        static char author_mail[1024];
@@ -1446,7 +1446,8 @@ static void get_commit_info(struct commit *commit,
                        die("Cannot read commit %s",
                            sha1_to_hex(commit->object.sha1));
        }
-       reencoded = reencode_commit_message(commit, NULL);
+       encoding = get_log_output_encoding();
+       reencoded = logmsg_reencode(commit, encoding);
        message   = reencoded ? reencoded : commit->buffer;
        ret->author = author_name;
        ret->author_mail = author_mail;
index 781295b2c9abf033481bc135ca1d2330ca489937..a9c1b5a95fea0a805819f995da2d2f1ba194433d 100644 (file)
@@ -951,6 +951,9 @@ static int switch_unborn_to_new_branch(const struct checkout_opts *opts)
        strbuf_addf(&branch_ref, "refs/heads/%s", opts->new_branch);
        status = create_symref("HEAD", branch_ref.buf, "checkout -b");
        strbuf_release(&branch_ref);
+       if (!opts->quiet)
+               fprintf(stderr, _("Switched to a new branch '%s'\n"),
+                       opts->new_branch);
        return status;
 }
 
index e1c33e0691796601ac869278c155194d33ee8332..505bbc7dddc2d080fcaa9acf93ed5c1379fbe75f 100644 (file)
@@ -129,7 +129,8 @@ static int show_config(const char *key_, const char *value_, void *cb)
                else
                        sprintf(value, "%d", v);
        } else if (types == TYPE_PATH) {
-               git_config_pathname(&vptr, key_, value_);
+               if (git_config_pathname(&vptr, key_, value_) < 0)
+                       return -1;
                must_free_vptr = 1;
        } else if (value_) {
                vptr = value_;
index 2eb32bd9da8cfa4d7b1b99f9d22ffa5b3d6202e5..1c737f79216fda2e5395422d8aee2e4f5d6482a4 100644 (file)
@@ -41,9 +41,13 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
        if (rev.pending.nr != 1 ||
            rev.max_count != -1 || rev.min_age != -1 || rev.max_age != -1)
                usage(diff_cache_usage);
-       if (!cached)
+       if (!cached) {
                setup_work_tree();
-       if (read_cache() < 0) {
+               if (read_cache_preload(rev.diffopt.pathspec.raw) < 0) {
+                       perror("read_cache_preload");
+                       return -1;
+               }
+       } else if (read_cache() < 0) {
                perror("read_cache");
                return -1;
        }
index 9c70e408096fc92ed1c5056425f1014313908a75..8c2af6cb43ca62f253e07903a8e3cce1080e335b 100644 (file)
@@ -130,8 +130,6 @@ static int builtin_diff_index(struct rev_info *revs,
                        usage(builtin_diff_usage);
                argv++; argc--;
        }
-       if (!cached)
-               setup_work_tree();
        /*
         * Make sure there is one revision (i.e. pending object),
         * and there is no revision filtering parameters.
@@ -140,8 +138,14 @@ static int builtin_diff_index(struct rev_info *revs,
            revs->max_count != -1 || revs->min_age != -1 ||
            revs->max_age != -1)
                usage(builtin_diff_usage);
-       if (read_cache_preload(revs->diffopt.pathspec.raw) < 0) {
-               perror("read_cache_preload");
+       if (!cached) {
+               setup_work_tree();
+               if (read_cache_preload(revs->diffopt.pathspec.raw) < 0) {
+                       perror("read_cache_preload");
+                       return -1;
+               }
+       } else if (read_cache() < 0) {
+               perror("read_cache");
                return -1;
        }
        return run_diff_index(revs, cached);
index da231400b327b86a18a054075f6aee4749846932..24a772d8e1b7355a58088d784fdc18cd54302b7d 100644 (file)
@@ -483,7 +483,8 @@ static void convert_to_utf8(struct strbuf *line, const char *charset)
 
        if (!charset || !*charset)
                return;
-       if (!strcasecmp(metainfo_charset, charset))
+
+       if (same_encoding(metainfo_charset, charset))
                return;
        out = reencode_string(line->buf, metainfo_charset, charset);
        if (!out)
index e3aaf70203d4f5b6f099ed538d3366fb0a7747ce..398ccd5eaa243045c5d21af1e37462846665568a 100644 (file)
@@ -46,24 +46,27 @@ typedef int (*each_replace_name_fn)(const char *name, const char *ref,
 
 static int for_each_replace_name(const char **argv, each_replace_name_fn fn)
 {
-       const char **p;
+       const char **p, *full_hex;
        char ref[PATH_MAX];
        int had_error = 0;
        unsigned char sha1[20];
 
        for (p = argv; *p; p++) {
-               if (snprintf(ref, sizeof(ref), "refs/replace/%s", *p)
-                                       >= sizeof(ref)) {
-                       error("replace ref name too long: %.*s...", 50, *p);
+               if (get_sha1(*p, sha1)) {
+                       error("Failed to resolve '%s' as a valid ref.", *p);
                        had_error = 1;
                        continue;
                }
+               full_hex = sha1_to_hex(sha1);
+               snprintf(ref, sizeof(ref), "refs/replace/%s", full_hex);
+               /* read_ref() may reuse the buffer */
+               full_hex = ref + strlen("refs/replace/");
                if (read_ref(ref, sha1)) {
-                       error("replace ref '%s' not found.", *p);
+                       error("replace ref '%s' not found.", full_hex);
                        had_error = 1;
                        continue;
                }
-               if (fn(*p, ref, sha1))
+               if (fn(full_hex, ref, sha1))
                        had_error = 1;
        }
        return had_error;
index 9e92828b3ab02fb93c568eab03f0db9d398e8fa2..f48195942123692c95ad8e5585f853ad54a3dbe4 100644 (file)
@@ -5,12 +5,11 @@
 
 static const char * const git_symbolic_ref_usage[] = {
        N_("git symbolic-ref [options] name [ref]"),
+       N_("git symbolic-ref -d [-q] name"),
        NULL
 };
 
-static int shorten;
-
-static void check_symref(const char *HEAD, int quiet)
+static int check_symref(const char *HEAD, int quiet, int shorten, int print)
 {
        unsigned char sha1[20];
        int flag;
@@ -22,20 +21,24 @@ static void check_symref(const char *HEAD, int quiet)
                if (!quiet)
                        die("ref %s is not a symbolic ref", HEAD);
                else
-                       exit(1);
+                       return 1;
+       }
+       if (print) {
+               if (shorten)
+                       refname = shorten_unambiguous_ref(refname, 0);
+               puts(refname);
        }
-       if (shorten)
-               refname = shorten_unambiguous_ref(refname, 0);
-       puts(refname);
+       return 0;
 }
 
 int cmd_symbolic_ref(int argc, const char **argv, const char *prefix)
 {
-       int quiet = 0;
+       int quiet = 0, delete = 0, shorten = 0, ret = 0;
        const char *msg = NULL;
        struct option options[] = {
                OPT__QUIET(&quiet,
                        N_("suppress error message for non-symbolic (detached) refs")),
+               OPT_BOOL('d', "delete", &delete, N_("delete symbolic ref")),
                OPT_BOOL(0, "short", &shorten, N_("shorten ref output")),
                OPT_STRING('m', NULL, &msg, N_("reason"), N_("reason of the update")),
                OPT_END(),
@@ -46,9 +49,19 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix)
                             git_symbolic_ref_usage, 0);
        if (msg &&!*msg)
                die("Refusing to perform update with empty message");
+
+       if (delete) {
+               if (argc != 1)
+                       usage_with_options(git_symbolic_ref_usage, options);
+               ret = check_symref(argv[0], 1, 0, 0);
+               if (ret)
+                       die("Cannot delete %s, not a symbolic ref", argv[0]);
+               return delete_ref(argv[0], NULL, REF_NODEREF);
+       }
+
        switch (argc) {
        case 1:
-               check_symref(argv[0], quiet);
+               ret = check_symref(argv[0], quiet, shorten, 1);
                break;
        case 2:
                if (!strcmp(argv[0], "HEAD") &&
@@ -59,5 +72,5 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix)
        default:
                usage_with_options(git_symbolic_ref_usage, options);
        }
-       return 0;
+       return ret;
 }
index 74986bf163d4dadb4497a90364c29ac71a801638..ada1dff846f2b77d5f71d69db57a7eca5033b943 100644 (file)
@@ -593,6 +593,7 @@ struct refresh_params {
 static int refresh(struct refresh_params *o, unsigned int flag)
 {
        setup_work_tree();
+       read_cache_preload(NULL);
        *o->has_errors |= refresh_cache(o->flags | flag);
        return 0;
 }
index c4cd046160c7594c09bf0dd146e7cd862cb3fc0f..b6ad8f3f307a46cd5a0555ab346abaa20013b13a 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -86,7 +86,7 @@ struct pretty_print_context {
        enum date_mode date_mode;
        unsigned date_mode_explicit:1;
        int need_8bit_cte;
-       int show_notes;
+       char *notes_message;
        struct reflog_walk_info *reflog_info;
        const char *output_encoding;
 };
@@ -99,8 +99,6 @@ extern int has_non_ascii(const char *text);
 struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
 extern char *logmsg_reencode(const struct commit *commit,
                             const char *output_encoding);
-extern char *reencode_commit_message(const struct commit *commit,
-                                    const char **encoding_p);
 extern void get_commit_format(const char *arg, struct rev_info *);
 extern const char *format_subject(struct strbuf *sb, const char *msg,
                                  const char *line_separator);
index ed23eb4bdda3b595ac956ba65557b1dc7d50426d..a20937635435f6672f801454c992cbeeb8d17a1a 100644 (file)
@@ -104,10 +104,10 @@ static int diff_grep(struct diff_filepair *p, struct diff_options *o,
                if (!mf2.ptr)
                        return 0; /* ignore unmerged */
                /* created "two" -- does it have what we are looking for? */
-               hit = !regexec(regexp, p->two->data, 1, &regmatch, 0);
+               hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0);
        } else if (!mf2.ptr) {
                /* removed "one" -- did it have what we are looking for? */
-               hit = !regexec(regexp, p->one->data, 1, &regmatch, 0);
+               hit = !regexec(regexp, mf1.ptr, 1, &regmatch, 0);
        } else {
                /*
                 * We have both sides; need to run textual diff and see if
index 8032f23202ff9a1e8e0fd2a6745021fb8f1fcf71..0a31ebd82020f3aca0020d357c2028d5e7b5e37b 100755 (executable)
 use Time::Local;
 use IO::Socket;
 use IO::Pipe;
-use POSIX qw(strftime dup2 ENOENT);
+use POSIX qw(strftime tzset dup2 ENOENT);
 use IPC::Open2;
 
 $SIG{'PIPE'}="IGNORE";
-$ENV{'TZ'}="UTC";
+set_timezone('UTC');
 
 our ($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,@opt_M,$opt_A,$opt_S,$opt_L, $opt_a, $opt_r, $opt_R);
-my (%conv_author_name, %conv_author_email);
+my (%conv_author_name, %conv_author_email, %conv_author_tz);
 
 sub usage(;$) {
        my $msg = shift;
@@ -59,6 +59,14 @@ ($)
                        $conv_author_name{$user} = $2;
                        $conv_author_email{$user} = $3;
                }
+               # or with an optional timezone:
+               #   spawn=Simon Pawn <spawn@frog-pond.org> America/Chicago
+               elsif (m/^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*(\S+?)\s*$/) {
+                       $user = $1;
+                       $conv_author_name{$user} = $2;
+                       $conv_author_email{$user} = $3;
+                       $conv_author_tz{$user} = $4;
+               }
                # However, we also read from CVSROOT/users format
                # to ease migration.
                elsif (/^(\w+):(['"]?)(.+?)\2\s*$/) {
@@ -84,11 +92,22 @@ ($)
          die("Failed to open $file for writing: $!");
 
        foreach (keys %conv_author_name) {
-               print $f "$_=$conv_author_name{$_} <$conv_author_email{$_}>\n";
+               print $f "$_=$conv_author_name{$_} <$conv_author_email{$_}>";
+               print $f " $conv_author_tz{$_}" if ($conv_author_tz{$_});
+               print $f "\n";
        }
        close ($f);
 }
 
+# Versions of perl before 5.10.0 may not automatically check $TZ each
+# time localtime is run (most platforms will do so only the first time).
+# We can work around this by using tzset() to update the internal
+# variable whenever we change the environment.
+sub set_timezone {
+       $ENV{TZ} = shift;
+       tzset();
+}
+
 # convert getopts specs for use by git config
 my %longmap = (
        'A:' => 'authors-file',
@@ -795,7 +814,7 @@ ()
        return $tree;
 }
 
-my ($patchset,$date,$author_name,$author_email,$branch,$ancestor,$tag,$logmsg);
+my ($patchset,$date,$author_name,$author_email,$author_tz,$branch,$ancestor,$tag,$logmsg);
 my (@old,@new,@skipped,%ignorebranch,@commit_revisions);
 
 # commits that cvsps cannot place anywhere...
@@ -844,7 +863,9 @@ sub commit {
                }
        }
 
-       my $commit_date = strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date));
+       set_timezone($author_tz);
+       my $commit_date = strftime("%s %z", localtime($date));
+       set_timezone('UTC');
        $ENV{GIT_AUTHOR_NAME} = $author_name;
        $ENV{GIT_AUTHOR_EMAIL} = $author_email;
        $ENV{GIT_AUTHOR_DATE} = $commit_date;
@@ -945,12 +966,14 @@ sub commit {
                }
                $state=3;
        } elsif ($state == 3 and s/^Author:\s+//) {
+               $author_tz = "UTC";
                s/\s+$//;
                if (/^(.*?)\s+<(.*)>/) {
                    ($author_name, $author_email) = ($1, $2);
                } elsif ($conv_author_name{$_}) {
                        $author_name = $conv_author_name{$_};
                        $author_email = $conv_author_email{$_};
+                       $author_tz = $conv_author_tz{$_} if ($conv_author_tz{$_});
                } else {
                    $author_name = $author_email = $_;
                }
index 882b1bbab53c6e184c7eadb5250c128b59c93482..7d6c928c3f2b3d90a754f855c074ea57d2ca1bbf 100755 (executable)
--- a/git-p4.py
+++ b/git-p4.py
@@ -227,7 +227,7 @@ def p4_keywords_regexp_for_type(base, type_mods):
         pattern = r"""
             \$              # Starts with a dollar, followed by...
             (%s)            # one of the keywords, followed by...
-            (:[^$]+)?       # possibly an old expansion, followed by...
+            (:[^$\n]+)?     # possibly an old expansion, followed by...
             \$              # another dollar
             """ % kwords
         return pattern
index 484b2e61ccd6df166a8d6447556ccca4236840ad..0e87e0915ee16e36385aa4182b3a4271d1308641 100644 (file)
@@ -80,7 +80,7 @@ See git-${cmd}(1) for details
 
 If you wish to set tracking information for this branch you can do so with:
 
-    git branch --set-upstream ${branch_name#refs/heads/} $remote/<branch>
+    git branch --set-upstream-to=$remote/<branch> ${branch_name#refs/heads/}
 "
        fi
        exit 1
index 819eb5674a9a7c0db3d03de76a461e3787f51193..0522c3871a55d50cdada04c92db8d4bd87120df7 100755 (executable)
@@ -11,7 +11,7 @@ USAGE="[--quiet] add [-b branch] [-f|--force] [--name <name>] [--reference <repo
    or: $dashless [--quiet] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
    or: $dashless [--quiet] foreach [--recursive] <command>
-   or: $dashless [--quiet] sync [--] [<path>...]"
+   or: $dashless [--quiet] sync [--recursive] [--] [<path>...]"
 OPTIONS_SPEC=
 . git-sh-setup
 . git-sh-i18n
@@ -1032,6 +1032,10 @@ cmd_sync()
                        GIT_QUIET=1
                        shift
                        ;;
+               --recursive)
+                       recursive=1
+                       shift
+                       ;;
                --)
                        shift
                        break
@@ -1073,7 +1077,7 @@ cmd_sync()
 
                if git config "submodule.$name.url" >/dev/null 2>/dev/null
                then
-                       say "$(eval_gettext "Synchronizing submodule url for '\$name'")"
+                       say "$(eval_gettext "Synchronizing submodule url for '\$prefix\$sm_path'")"
                        git config submodule."$name".url "$super_config_url"
 
                        if test -e "$sm_path"/.git
@@ -1083,6 +1087,12 @@ cmd_sync()
                                cd "$sm_path"
                                remote=$(get_default_remote)
                                git config remote."$remote".url "$sub_origin_url"
+
+                               if test -n "$recursive"
+                               then
+                                       prefix="$prefix$sm_path/"
+                                       eval cmd_sync
+                               fi
                        )
                        fi
                fi
index 10ed9e51a5880430f7f109ff83f950a768a7c530..e8812fa2b9145cf669193b2b148a0a8e6ee7ac09 100755 (executable)
@@ -270,16 +270,15 @@ sub evaluate_uri {
 our %highlight_ext = (
        # main extensions, defining name of syntax;
        # see files in /usr/share/highlight/langDefs/ directory
-       map { $_ => $_ }
-               qw(py c cpp rb java css php sh pl js tex bib xml awk bat ini spec tcl sql make),
+       (map { $_ => $_ } qw(py rb java css js tex bib xml awk bat ini spec tcl sql)),
        # alternate extensions, see /etc/highlight/filetypes.conf
-       'h' => 'c',
-       map { $_ => 'sh'  } qw(bash zsh ksh),
-       map { $_ => 'cpp' } qw(cxx c++ cc),
-       map { $_ => 'php' } qw(php3 php4 php5 phps),
-       map { $_ => 'pl'  } qw(perl pm), # perhaps also 'cgi'
-       map { $_ => 'make'} qw(mak mk),
-       map { $_ => 'xml' } qw(xhtml html htm),
+       (map { $_ => 'c'   } qw(c h)),
+       (map { $_ => 'sh'  } qw(sh bash zsh ksh)),
+       (map { $_ => 'cpp' } qw(cpp cxx c++ cc)),
+       (map { $_ => 'php' } qw(php php3 php4 php5 phps)),
+       (map { $_ => 'pl'  } qw(pl perl pm)), # perhaps also 'cgi'
+       (map { $_ => 'make'} qw(make mak mk)),
+       (map { $_ => 'xml' } qw(xml xhtml html htm)),
 );
 
 # You define site-wide feature defaults here; override them with
@@ -8055,6 +8054,7 @@ sub git_feed {
                $feed_type = 'history';
        }
        $title .= " $feed_type";
+       $title = esc_html($title);
        my $descr = git_get_project_description($project);
        if (defined $descr) {
                $descr = esc_html($descr);
index c894930c1863bfcf33a01b2d98c48478aa874186..4f86defe324bac8374585df5d9e8ef7b5f9a3524 100644 (file)
@@ -540,7 +540,6 @@ void show_log(struct rev_info *opt)
        struct pretty_print_context ctx = {0};
 
        opt->loginfo = NULL;
-       ctx.show_notes = opt->show_notes;
        if (!opt->verbose_header) {
                graph_show_commit(opt->graph);
 
@@ -648,6 +647,18 @@ void show_log(struct rev_info *opt)
        if (!commit->buffer)
                return;
 
+       if (opt->show_notes) {
+               int raw;
+               struct strbuf notebuf = STRBUF_INIT;
+
+               raw = (opt->commit_format == CMIT_FMT_USERFORMAT);
+               format_display_notes(commit->object.sha1, &notebuf,
+                                    get_log_output_encoding(), raw);
+               ctx.notes_message = notebuf.len
+                       ? strbuf_detach(&notebuf, NULL)
+                       : xcalloc(1, 1);
+       }
+
        /*
         * And then the pretty-printed message itself
         */
@@ -664,6 +675,16 @@ void show_log(struct rev_info *opt)
 
        if (opt->add_signoff)
                append_signoff(&msgbuf, opt->add_signoff);
+
+       if ((ctx.fmt != CMIT_FMT_USERFORMAT) &&
+           ctx.notes_message && *ctx.notes_message) {
+               if (ctx.fmt == CMIT_FMT_EMAIL) {
+                       strbuf_addstr(&msgbuf, "---\n");
+                       opt->shown_dashes = 1;
+               }
+               strbuf_addstr(&msgbuf, ctx.notes_message);
+       }
+
        if (opt->show_log_size) {
                printf("log size %i\n", (int)msgbuf.len);
                graph_show_oneline(opt->graph);
@@ -689,10 +710,12 @@ void show_log(struct rev_info *opt)
        }
 
        strbuf_release(&msgbuf);
+       free(ctx.notes_message);
 }
 
 int log_tree_diff_flush(struct rev_info *opt)
 {
+       opt->shown_dashes = 0;
        diffcore_std(&opt->diffopt);
 
        if (diff_queue_is_empty()) {
@@ -704,15 +727,16 @@ int log_tree_diff_flush(struct rev_info *opt)
        }
 
        if (opt->loginfo && !opt->no_commit_id) {
-               /* When showing a verbose header (i.e. log message),
-                * and not in --pretty=oneline format, we would want
-                * an extra newline between the end of log and the
-                * output for readability.
-                */
                show_log(opt);
                if ((opt->diffopt.output_format & ~DIFF_FORMAT_NO_OUTPUT) &&
                    opt->verbose_header &&
                    opt->commit_format != CMIT_FMT_ONELINE) {
+                       /*
+                        * When showing a verbose header (i.e. log message),
+                        * and not in --pretty=oneline format, we would want
+                        * an extra newline between the end of log and the
+                        * diff/diffstat output for readability.
+                        */
                        int pch = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_PATCH;
                        if (opt->diffopt.output_prefix) {
                                struct strbuf *msg = NULL;
@@ -720,9 +744,20 @@ int log_tree_diff_flush(struct rev_info *opt)
                                        opt->diffopt.output_prefix_data);
                                fwrite(msg->buf, msg->len, 1, stdout);
                        }
-                       if ((pch & opt->diffopt.output_format) == pch) {
+
+                       /*
+                        * We may have shown three-dashes line early
+                        * between notes and the log message, in which
+                        * case we only want a blank line after the
+                        * notes without (an extra) three-dashes line.
+                        * Otherwise, we show the three-dashes line if
+                        * we are showing the patch with diffstat, but
+                        * in that case, there is no extra blank line
+                        * after the three-dashes line.
+                        */
+                       if (!opt->shown_dashes &&
+                           (pch & opt->diffopt.output_format) == pch)
                                printf("---");
-                       }
                        putchar('\n');
                }
        }
diff --git a/notes.c b/notes.c
index bc454e1eab2b0e1d264cee7bb1f84bdb3bb14237..f63fd572d6db125559e68556a8fc152a53700644 100644 (file)
--- a/notes.c
+++ b/notes.c
@@ -848,15 +848,16 @@ int combine_notes_ignore(unsigned char *cur_sha1,
        return 0;
 }
 
-static int string_list_add_note_lines(struct string_list *sort_uniq_list,
+/*
+ * Add the lines from the named object to list, with trailing
+ * newlines removed.
+ */
+static int string_list_add_note_lines(struct string_list *list,
                                      const unsigned char *sha1)
 {
        char *data;
        unsigned long len;
        enum object_type t;
-       struct strbuf buf = STRBUF_INIT;
-       struct strbuf **lines = NULL;
-       int i, list_index;
 
        if (is_null_sha1(sha1))
                return 0;
@@ -868,24 +869,14 @@ static int string_list_add_note_lines(struct string_list *sort_uniq_list,
                return t != OBJ_BLOB || !data;
        }
 
-       strbuf_attach(&buf, data, len, len + 1);
-       lines = strbuf_split(&buf, '\n');
-
-       for (i = 0; lines[i]; i++) {
-               if (lines[i]->buf[lines[i]->len - 1] == '\n')
-                       strbuf_setlen(lines[i], lines[i]->len - 1);
-               if (!lines[i]->len)
-                       continue; /* skip empty lines */
-               list_index = string_list_find_insert_index(sort_uniq_list,
-                                                          lines[i]->buf, 0);
-               if (list_index < 0)
-                       continue; /* skip duplicate lines */
-               string_list_insert_at_index(sort_uniq_list, list_index,
-                                           lines[i]->buf);
-       }
-
-       strbuf_list_free(lines);
-       strbuf_release(&buf);
+       /*
+        * If the last line of the file is EOL-terminated, this will
+        * add an empty string to the list.  But it will be removed
+        * later, along with any empty strings that came from empty
+        * lines within the file.
+        */
+       string_list_split(list, data, '\n', -1);
+       free(data);
        return 0;
 }
 
@@ -901,7 +892,7 @@ static int string_list_join_lines_helper(struct string_list_item *item,
 int combine_notes_cat_sort_uniq(unsigned char *cur_sha1,
                const unsigned char *new_sha1)
 {
-       struct string_list sort_uniq_list = { NULL, 0, 0, 1 };
+       struct string_list sort_uniq_list = STRING_LIST_INIT_DUP;
        struct strbuf buf = STRBUF_INIT;
        int ret = 1;
 
@@ -910,6 +901,9 @@ int combine_notes_cat_sort_uniq(unsigned char *cur_sha1,
                goto out;
        if (string_list_add_note_lines(&sort_uniq_list, new_sha1))
                goto out;
+       string_list_remove_empty_items(&sort_uniq_list, 0);
+       sort_string_list(&sort_uniq_list);
+       string_list_remove_duplicates(&sort_uniq_list, 0);
 
        /* create a new blob object from sort_uniq_list */
        if (for_each_string_list(&sort_uniq_list,
@@ -949,23 +943,18 @@ void string_list_add_refs_by_glob(struct string_list *list, const char *glob)
 void string_list_add_refs_from_colon_sep(struct string_list *list,
                                         const char *globs)
 {
-       struct strbuf globbuf = STRBUF_INIT;
-       struct strbuf **split;
+       struct string_list split = STRING_LIST_INIT_NODUP;
+       char *globs_copy = xstrdup(globs);
        int i;
 
-       strbuf_addstr(&globbuf, globs);
-       split = strbuf_split(&globbuf, ':');
+       string_list_split_in_place(&split, globs_copy, ':', -1);
+       string_list_remove_empty_items(&split, 0);
 
-       for (i = 0; split[i]; i++) {
-               if (!split[i]->len)
-                       continue;
-               if (split[i]->buf[split[i]->len-1] == ':')
-                       strbuf_setlen(split[i], split[i]->len-1);
-               string_list_add_refs_by_glob(list, split[i]->buf);
-       }
+       for (i = 0; i < split.nr; i++)
+               string_list_add_refs_by_glob(list, split.items[i].string);
 
-       strbuf_list_free(split);
-       strbuf_release(&globbuf);
+       string_list_clear(&split, 0);
+       free(globs_copy);
 }
 
 static int notes_display_config(const char *k, const char *v, void *cb)
@@ -1204,10 +1193,11 @@ void free_notes(struct notes_tree *t)
  * If the given notes_tree is NULL, the internal/default notes_tree will be
  * used instead.
  *
- * 'flags' is a bitwise combination of the flags for format_display_notes.
+ * (raw != 0) gives the %N userformat; otherwise, the note message is given
+ * for human consumption.
  */
 static void format_note(struct notes_tree *t, const unsigned char *object_sha1,
-                       struct strbuf *sb, const char *output_encoding, int flags)
+                       struct strbuf *sb, const char *output_encoding, int raw)
 {
        static const char utf8[] = "utf-8";
        const unsigned char *sha1;
@@ -1231,7 +1221,7 @@ static void format_note(struct notes_tree *t, const unsigned char *object_sha1,
        }
 
        if (output_encoding && *output_encoding &&
-                       strcmp(utf8, output_encoding)) {
+           !is_encoding_utf8(output_encoding)) {
                char *reencoded = reencode_string(msg, output_encoding, utf8);
                if (reencoded) {
                        free(msg);
@@ -1244,7 +1234,7 @@ static void format_note(struct notes_tree *t, const unsigned char *object_sha1,
        if (msglen && msg[msglen - 1] == '\n')
                msglen--;
 
-       if (flags & NOTES_SHOW_HEADER) {
+       if (!raw) {
                const char *ref = t->ref;
                if (!ref || !strcmp(ref, GIT_NOTES_DEFAULT_REF)) {
                        strbuf_addstr(sb, "\nNotes:\n");
@@ -1260,7 +1250,7 @@ static void format_note(struct notes_tree *t, const unsigned char *object_sha1,
        for (msg_p = msg; msg_p < msg + msglen; msg_p += linelen + 1) {
                linelen = strchrnul(msg_p, '\n') - msg_p;
 
-               if (flags & NOTES_INDENT)
+               if (!raw)
                        strbuf_addstr(sb, "    ");
                strbuf_add(sb, msg_p, linelen);
                strbuf_addch(sb, '\n');
@@ -1270,13 +1260,13 @@ static void format_note(struct notes_tree *t, const unsigned char *object_sha1,
 }
 
 void format_display_notes(const unsigned char *object_sha1,
-                         struct strbuf *sb, const char *output_encoding, int flags)
+                         struct strbuf *sb, const char *output_encoding, int raw)
 {
        int i;
        assert(display_notes_trees);
        for (i = 0; display_notes_trees[i]; i++)
                format_note(display_notes_trees[i], object_sha1, sb,
-                           output_encoding, flags);
+                           output_encoding, raw);
 }
 
 int copy_note(struct notes_tree *t,
diff --git a/notes.h b/notes.h
index 3592b19d2d9e5c67d9f55c8ad675ded086cbce17..3324c486a1a106053621ff215f5689cf1d92af74 100644 (file)
--- a/notes.h
+++ b/notes.h
@@ -237,10 +237,6 @@ void prune_notes(struct notes_tree *t, int flags);
  */
 void free_notes(struct notes_tree *t);
 
-/* Flags controlling how notes are formatted */
-#define NOTES_SHOW_HEADER 1
-#define NOTES_INDENT 2
-
 struct string_list;
 
 struct display_notes_opt {
@@ -274,7 +270,7 @@ void init_display_notes(struct display_notes_opt *opt);
  * You *must* call init_display_notes() before using this function.
  */
 void format_display_notes(const unsigned char *object_sha1,
-                         struct strbuf *sb, const char *output_encoding, int flags);
+                         struct strbuf *sb, const char *output_encoding, int raw);
 
 /*
  * Load the notes tree from each ref listed in 'refs'.  The output is
index 413e7587b6f67326a68a7679ca5496cd1249fbcd..5bdc2e70bcd1e8fc0c7e625c3eac26397d8c96d2 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -571,7 +571,7 @@ char *logmsg_reencode(const struct commit *commit,
                return NULL;
        encoding = get_header(commit, "encoding");
        use_encoding = encoding ? encoding : utf8;
-       if (!strcmp(use_encoding, output_encoding))
+       if (same_encoding(use_encoding, output_encoding))
                if (encoding) /* we'll strip encoding header later */
                        out = xstrdup(commit->buffer);
                else
@@ -1100,9 +1100,8 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
                }
                return 0;       /* unknown %g placeholder */
        case 'N':
-               if (c->pretty_ctx->show_notes) {
-                       format_display_notes(commit->object.sha1, sb,
-                                   get_log_output_encoding(), 0);
+               if (c->pretty_ctx->notes_message) {
+                       strbuf_addstr(sb, c->pretty_ctx->notes_message);
                        return 1;
                }
                return 0;
@@ -1414,16 +1413,6 @@ void pp_remainder(const struct pretty_print_context *pp,
        }
 }
 
-char *reencode_commit_message(const struct commit *commit, const char **encoding_p)
-{
-       const char *encoding;
-
-       encoding = get_log_output_encoding();
-       if (encoding_p)
-               *encoding_p = encoding;
-       return logmsg_reencode(commit, encoding);
-}
-
 void pretty_print_commit(const struct pretty_print_context *pp,
                         const struct commit *commit,
                         struct strbuf *sb)
@@ -1440,7 +1429,8 @@ void pretty_print_commit(const struct pretty_print_context *pp,
                return;
        }
 
-       reencoded = reencode_commit_message(commit, &encoding);
+       encoding = get_log_output_encoding();
+       reencoded = logmsg_reencode(commit, encoding);
        if (reencoded) {
                msg = reencoded;
        }
@@ -1500,10 +1490,6 @@ void pretty_print_commit(const struct pretty_print_context *pp,
        if (pp->fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body)
                strbuf_addch(sb, '\n');
 
-       if (pp->show_notes)
-               format_display_notes(commit->object.sha1, sb, encoding,
-                                    NOTES_SHOW_HEADER | NOTES_INDENT);
-
        free(reencoded);
 }
 
index 278fecdd9bd00bf0df0a3d1f35777546794bc92f..d8b3600bdd0b96e364775113c63957a2936a3324 100644 (file)
@@ -400,6 +400,7 @@ static int post_rpc(struct rpc_state *rpc)
        struct curl_slist *headers = NULL;
        int use_gzip = rpc->gzip_request;
        char *gzip_body = NULL;
+       size_t gzip_size;
        int err, large_request = 0;
 
        /* Try to load the entire request, if we can fit it into the
@@ -460,24 +461,32 @@ static int post_rpc(struct rpc_state *rpc)
                        fflush(stderr);
                }
 
+       } else if (gzip_body) {
+               /*
+                * If we are looping to retry authentication, then the previous
+                * run will have set up the headers and gzip buffer already,
+                * and we just need to send it.
+                */
+               curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, gzip_body);
+               curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, gzip_size);
+
        } else if (use_gzip && 1024 < rpc->len) {
                /* The client backend isn't giving us compressed data so
                 * we can try to deflate it ourselves, this may save on.
                 * the transfer time.
                 */
-               size_t size;
                git_zstream stream;
                int ret;
 
                memset(&stream, 0, sizeof(stream));
                git_deflate_init_gzip(&stream, Z_BEST_COMPRESSION);
-               size = git_deflate_bound(&stream, rpc->len);
-               gzip_body = xmalloc(size);
+               gzip_size = git_deflate_bound(&stream, rpc->len);
+               gzip_body = xmalloc(gzip_size);
 
                stream.next_in = (unsigned char *)rpc->buf;
                stream.avail_in = rpc->len;
                stream.next_out = (unsigned char *)gzip_body;
-               stream.avail_out = size;
+               stream.avail_out = gzip_size;
 
                ret = git_deflate(&stream, Z_FINISH);
                if (ret != Z_STREAM_END)
@@ -487,16 +496,16 @@ static int post_rpc(struct rpc_state *rpc)
                if (ret != Z_OK)
                        die("cannot deflate request; zlib end error %d", ret);
 
-               size = stream.total_out;
+               gzip_size = stream.total_out;
 
                headers = curl_slist_append(headers, "Content-Encoding: gzip");
                curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, gzip_body);
-               curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, size);
+               curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, gzip_size);
 
                if (options.verbosity > 1) {
                        fprintf(stderr, "POST %s (gzip %lu to %lu bytes)\n",
                                rpc->service_name,
-                               (unsigned long)rpc->len, (unsigned long)size);
+                               (unsigned long)rpc->len, (unsigned long)gzip_size);
                        fflush(stderr);
                }
        } else {
@@ -517,7 +526,7 @@ static int post_rpc(struct rpc_state *rpc)
        curl_easy_setopt(slot->curl, CURLOPT_FILE, rpc);
 
        err = run_slot(slot);
-       if (err == HTTP_REAUTH && !large_request && !use_gzip)
+       if (err == HTTP_REAUTH && !large_request)
                goto retry;
        if (err != HTTP_OK)
                err = -1;
index 04fd9ea4bd2f99003c9c5abb7bbbad7dafca3937..5882d11a8d57f060fdee6a79b70e230c530363c3 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -1458,8 +1458,8 @@ int get_fetch_map(const struct ref *remote_refs,
 
        for (rmp = &ref_map; *rmp; ) {
                if ((*rmp)->peer_ref) {
-                       if (check_refname_format((*rmp)->peer_ref->name + 5,
-                               REFNAME_ALLOW_ONELEVEL)) {
+                       if (prefixcmp((*rmp)->peer_ref->name, "refs/") ||
+                           check_refname_format((*rmp)->peer_ref->name, 0)) {
                                struct ref *ignore = *rmp;
                                error("* Ignoring funny ref '%s' locally",
                                      (*rmp)->peer_ref->name);
index d7d621cdbf224f5a2bc1780e9602dcd3d08c1d57..95d21e6472921ab993373ef1848357379440d46e 100644 (file)
@@ -2242,7 +2242,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
                if (!buf.len)
                        strbuf_addstr(&buf, commit->buffer);
                format_display_notes(commit->object.sha1, &buf,
-                                    get_log_output_encoding(), 0);
+                                    get_log_output_encoding(), 1);
        }
 
        /* Find either in the commit object, or in the temporary */
index a95bd0b3f3026068046d469a74d1a2d85e50e314..059bfff812da8033681aa11c5a9ca9085881747e 100644 (file)
@@ -111,6 +111,7 @@ struct rev_info {
 
        /* Format info */
        unsigned int    shown_one:1,
+                       shown_dashes:1,
                        show_merge:1,
                        show_notes:1,
                        show_notes_given:1,
index be0cb8b1076dc29bee5a77fbbde155514723c6a8..22604902aa4c4dd146f562c4841c344a773a9bda 100644 (file)
@@ -60,7 +60,7 @@ static int get_message(struct commit *commit, struct commit_message *out)
 
        out->reencoded_message = NULL;
        out->message = commit->buffer;
-       if (strcmp(encoding, git_commit_encoding))
+       if (same_encoding(encoding, git_commit_encoding))
                out->reencoded_message = reencode_string(commit->buffer,
                                        git_commit_encoding, encoding);
        if (out->reencoded_message)
index 9152974642986de2307ec4ed6beda4efa49e8383..40b23297b2e1e60a3719e9c67256303e39456604 100644 (file)
@@ -7,6 +7,7 @@
  * creation etc.
  */
 #include "cache.h"
+#include "string-list.h"
 #include "delta.h"
 #include "pack.h"
 #include "blob.h"
@@ -246,7 +247,7 @@ static int git_open_noatime(const char *name);
  * SHA1, an extra slash for the first level indirection, and the
  * terminating NUL.
  */
-static int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth)
+static int link_alt_odb_entry(const char *entry, const char *relative_base, int depth)
 {
        const char *objdir = get_object_directory();
        struct alternate_object_database *ent;
@@ -258,7 +259,7 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative
                strbuf_addstr(&pathbuf, real_path(relative_base));
                strbuf_addch(&pathbuf, '/');
        }
-       strbuf_add(&pathbuf, entry, len);
+       strbuf_addstr(&pathbuf, entry);
 
        normalize_path_copy(pathbuf.buf, pathbuf.buf);
 
@@ -316,10 +317,12 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative
        return 0;
 }
 
-static void link_alt_odb_entries(const char *alt, const char *ep, int sep,
+static void link_alt_odb_entries(const char *alt, int len, int sep,
                                 const char *relative_base, int depth)
 {
-       const char *cp, *last;
+       struct string_list entries = STRING_LIST_INIT_NODUP;
+       char *alt_copy;
+       int i;
 
        if (depth > 5) {
                error("%s: ignoring alternate object stores, nesting too deep.",
@@ -327,30 +330,21 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep,
                return;
        }
 
-       last = alt;
-       while (last < ep) {
-               cp = last;
-               if (cp < ep && *cp == '#') {
-                       while (cp < ep && *cp != sep)
-                               cp++;
-                       last = cp + 1;
+       alt_copy = xmemdupz(alt, len);
+       string_list_split_in_place(&entries, alt_copy, sep, -1);
+       for (i = 0; i < entries.nr; i++) {
+               const char *entry = entries.items[i].string;
+               if (entry[0] == '\0' || entry[0] == '#')
                        continue;
+               if (!is_absolute_path(entry) && depth) {
+                       error("%s: ignoring relative alternate object store %s",
+                                       relative_base, entry);
+               } else {
+                       link_alt_odb_entry(entry, relative_base, depth);
                }
-               while (cp < ep && *cp != sep)
-                       cp++;
-               if (last != cp) {
-                       if (!is_absolute_path(last) && depth) {
-                               error("%s: ignoring relative alternate object store %s",
-                                               relative_base, last);
-                       } else {
-                               link_alt_odb_entry(last, cp - last,
-                                               relative_base, depth);
-                       }
-               }
-               while (cp < ep && *cp == sep)
-                       cp++;
-               last = cp;
        }
+       string_list_clear(&entries, 0);
+       free(alt_copy);
 }
 
 void read_info_alternates(const char * relative_base, int depth)
@@ -377,7 +371,7 @@ void read_info_alternates(const char * relative_base, int depth)
        map = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, fd, 0);
        close(fd);
 
-       link_alt_odb_entries(map, map + mapsz, '\n', relative_base, depth);
+       link_alt_odb_entries(map, mapsz, '\n', relative_base, depth);
 
        munmap(map, mapsz);
 }
@@ -391,7 +385,7 @@ void add_to_alternates_file(const char *reference)
        if (commit_lock_file(lock))
                die("could not close alternates file");
        if (alt_odb_tail)
-               link_alt_odb_entries(alt, alt + strlen(alt), '\n', NULL, 0);
+               link_alt_odb_entries(alt, strlen(alt), '\n', NULL, 0);
 }
 
 void foreach_alt_odb(alt_odb_fn fn, void *cb)
@@ -415,7 +409,7 @@ void prepare_alt_odb(void)
        if (!alt) alt = "";
 
        alt_odb_tail = &alt_odb_list;
-       link_alt_odb_entries(alt, alt + strlen(alt), PATH_SEP, NULL, 0);
+       link_alt_odb_entries(alt, strlen(alt), PATH_SEP, NULL, 0);
 
        read_info_alternates(get_object_directory(), 0);
 }
index 4b9e30cadcd1ff45e7d4f23b210b22006445da91..05d0693eba1eba4e2f21057388368c0890e668fe 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -106,35 +106,30 @@ void strbuf_ltrim(struct strbuf *sb)
        sb->buf[sb->len] = '\0';
 }
 
-struct strbuf **strbuf_split_buf(const char *str, size_t slen, int delim, int max)
+struct strbuf **strbuf_split_buf(const char *str, size_t slen,
+                                int terminator, int max)
 {
-       int alloc = 2, pos = 0;
-       const char *n, *p;
-       struct strbuf **ret;
+       struct strbuf **ret = NULL;
+       size_t nr = 0, alloc = 0;
        struct strbuf *t;
 
-       ret = xcalloc(alloc, sizeof(struct strbuf *));
-       p = n = str;
-       while (n < str + slen) {
-               int len;
-               if (max <= 0 || pos + 1 < max)
-                       n = memchr(n, delim, slen - (n - str));
-               else
-                       n = NULL;
-               if (pos + 1 >= alloc) {
-                       alloc = alloc * 2;
-                       ret = xrealloc(ret, sizeof(struct strbuf *) * alloc);
+       while (slen) {
+               int len = slen;
+               if (max <= 0 || nr + 1 < max) {
+                       const char *end = memchr(str, terminator, slen);
+                       if (end)
+                               len = end - str + 1;
                }
-               if (!n)
-                       n = str + slen - 1;
-               len = n - p + 1;
                t = xmalloc(sizeof(struct strbuf));
                strbuf_init(t, len);
-               strbuf_add(t, p, len);
-               ret[pos] = t;
-               ret[++pos] = NULL;
-               p = ++n;
+               strbuf_add(t, str, len);
+               ALLOC_GROW(ret, nr + 2, alloc);
+               ret[nr++] = t;
+               str += len;
+               slen -= len;
        }
+       ALLOC_GROW(ret, nr + 1, alloc); /* In case string was empty */
+       ret[nr] = NULL;
        return ret;
 }
 
index be941ee481a735dcc73e3821c93e8ee682478d18..aa386c6074ec0006acbd1067b561a9b2695e29f0 100644 (file)
--- a/strbuf.h
+++ b/strbuf.h
@@ -44,22 +44,56 @@ extern void strbuf_rtrim(struct strbuf *);
 extern void strbuf_ltrim(struct strbuf *);
 extern int strbuf_cmp(const struct strbuf *, const struct strbuf *);
 
+/*
+ * Split str (of length slen) at the specified terminator character.
+ * Return a null-terminated array of pointers to strbuf objects
+ * holding the substrings.  The substrings include the terminator,
+ * except for the last substring, which might be unterminated if the
+ * original string did not end with a terminator.  If max is positive,
+ * then split the string into at most max substrings (with the last
+ * substring containing everything following the (max-1)th terminator
+ * character).
+ *
+ * For lighter-weight alternatives, see string_list_split() and
+ * string_list_split_in_place().
+ */
 extern struct strbuf **strbuf_split_buf(const char *, size_t,
-                                       int delim, int max);
+                                       int terminator, int max);
+
+/*
+ * Split a NUL-terminated string at the specified terminator
+ * character.  See strbuf_split_buf() for more information.
+ */
 static inline struct strbuf **strbuf_split_str(const char *str,
-                                              int delim, int max)
+                                              int terminator, int max)
 {
-       return strbuf_split_buf(str, strlen(str), delim, max);
+       return strbuf_split_buf(str, strlen(str), terminator, max);
 }
+
+/*
+ * Split a strbuf at the specified terminator character.  See
+ * strbuf_split_buf() for more information.
+ */
 static inline struct strbuf **strbuf_split_max(const struct strbuf *sb,
-                                               int delim, int max)
+                                               int terminator, int max)
 {
-       return strbuf_split_buf(sb->buf, sb->len, delim, max);
+       return strbuf_split_buf(sb->buf, sb->len, terminator, max);
 }
-static inline struct strbuf **strbuf_split(const struct strbuf *sb, int delim)
+
+/*
+ * Split a strbuf at the specified terminator character.  See
+ * strbuf_split_buf() for more information.
+ */
+static inline struct strbuf **strbuf_split(const struct strbuf *sb,
+                                          int terminator)
 {
-       return strbuf_split_max(sb, delim, 0);
+       return strbuf_split_max(sb, terminator, 0);
 }
+
+/*
+ * Free a NULL-terminated list of strbufs (for example, the return
+ * values of the strbuf_split*() functions).
+ */
 extern void strbuf_list_free(struct strbuf **);
 
 /*----- add data in your buffer -----*/
index c54b816244f69614c67c532d20719081a4b34bd4..397e6cfa7db82bdb17f7cdbe4662a1607c0773af 100644 (file)
@@ -136,6 +136,15 @@ void filter_string_list(struct string_list *list, int free_util,
        list->nr = dst;
 }
 
+static int item_is_not_empty(struct string_list_item *item, void *unused)
+{
+       return *item->string != '\0';
+}
+
+void string_list_remove_empty_items(struct string_list *list, int free_util) {
+       filter_string_list(list, free_util, item_is_not_empty, NULL);
+}
+
 char *string_list_longest_prefix(const struct string_list *prefixes,
                                 const char *string)
 {
index 5efd07b44e020428326ff32ff258449ec347861f..c50b0d0deac086cd5a50a5c021103a5f5e76c1cd 100644 (file)
@@ -38,6 +38,13 @@ int for_each_string_list(struct string_list *list,
 void filter_string_list(struct string_list *list, int free_util,
                        string_list_each_func_t want, void *cb_data);
 
+/*
+ * Remove any empty strings from the list.  If free_util is true, call
+ * free() on the util members of any items that have to be deleted.
+ * Preserve the order of the items that are retained.
+ */
+void string_list_remove_empty_items(struct string_list *list, int free_util);
+
 /*
  * Return the longest string in prefixes that is a prefix (in the
  * sense of prefixcmp()) of string, or NULL if no such prefix exists.
index 49d5d877ceeeba3738b0939f14d059c2a75ff3ae..fe76e84b74472a431eef59a1f4936cfc69367003 100644 (file)
@@ -99,6 +99,13 @@ SSLEngine On
        Require valid-user
 </LocationMatch>
 
+<LocationMatch "^/auth-fetch/.*/git-upload-pack$">
+       AuthType Basic
+       AuthName "git-auth"
+       AuthUserFile passwd
+       Require valid-user
+</LocationMatch>
+
 <IfDefine DAV>
        LoadModule dav_module modules/mod_dav.so
        LoadModule dav_fs_module modules/mod_dav_fs.so
index e127f35db9d12dba84cbf0503628ab5d9a3fc24f..7c4c372e374b66844b83ac9343c6c71b362380e2 100755 (executable)
@@ -803,6 +803,11 @@ test_expect_success NOT_MINGW 'get --path copes with unset $HOME' '
        test_cmp expect result
 '
 
+test_expect_success 'get --path barfs on boolean variable' '
+       echo "[path]bool" >.git/config &&
+       test_must_fail git config --get --path path.bool
+'
+
 cat > expect << EOF
 [quote]
        leading = " test"
index 2c96551ed0f2d3b95d661a0ce4d3b5b5d9ec0dfb..36378b0e3f5b271388fd0935149eea406caea0d0 100755 (executable)
@@ -33,4 +33,34 @@ test_expect_success 'symbolic-ref refuses bare sha1' '
 '
 reset_to_sane
 
+test_expect_success 'symbolic-ref deletes HEAD' '
+       git symbolic-ref -d HEAD &&
+       test_path_is_file .git/refs/heads/foo &&
+       test_path_is_missing .git/HEAD
+'
+reset_to_sane
+
+test_expect_success 'symbolic-ref deletes dangling HEAD' '
+       git symbolic-ref HEAD refs/heads/missing &&
+       git symbolic-ref -d HEAD &&
+       test_path_is_missing .git/refs/heads/missing &&
+       test_path_is_missing .git/HEAD
+'
+reset_to_sane
+
+test_expect_success 'symbolic-ref fails to delete missing FOO' '
+       echo "fatal: Cannot delete FOO, not a symbolic ref" >expect &&
+       test_must_fail git symbolic-ref -d FOO >actual 2>&1 &&
+       test_cmp expect actual
+'
+reset_to_sane
+
+test_expect_success 'symbolic-ref fails to delete real ref' '
+       echo "fatal: Cannot delete refs/heads/foo, not a symbolic ref" >expect &&
+       test_must_fail git symbolic-ref -d refs/heads/foo >actual 2>&1 &&
+       test_path_is_file .git/refs/heads/foo &&
+       test_cmp expect actual
+'
+reset_to_sane
+
 test_done
index ad9f69e6074311cc3828896bd8409822344d6f62..16a4ca1d6061122cf7ed3abd68390e27794f79b0 100755 (executable)
@@ -650,8 +650,19 @@ test_expect_success 'format-patch --in-reply-to' '
 '
 
 test_expect_success 'format-patch --signoff' '
-       git format-patch -1 --signoff --stdout |
-       grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
+       git format-patch -1 --signoff --stdout >out &&
+       grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
+'
+
+test_expect_success 'format-patch --notes --signoff' '
+       git notes --ref test add -m "test message" HEAD &&
+       git format-patch -1 --signoff --stdout --notes=test >out &&
+       # Three dashes must come after S-o-b
+       ! sed "/^Signed-off-by: /q" out | grep "test message" &&
+       sed "1,/^Signed-off-by: /d" out | grep "test message" &&
+       # Notes message must come after three dashes
+       ! sed "/^---$/q" out | grep "test message" &&
+       sed "1,/^---$/d" out | grep "test message"
 '
 
 echo "fatal: --name-only does not make sense" > expect.name-only
index eebb1eed8b1e084ddc048dc20797dfcd2f37e3ea..461d27ac202cc51f1f09b7a18de8b747198700e4 100755 (executable)
@@ -84,6 +84,18 @@ test_expect_success 'status -v produces text' '
        git reset --soft HEAD@{1}
 '
 
+test_expect_success 'grep-diff (-G) operates on textconv data (add)' '
+       echo one >expect &&
+       git log --root --format=%s -G0 >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'grep-diff (-G) operates on textconv data (modification)' '
+       echo two >expect &&
+       git log --root --format=%s -G1 >actual &&
+       test_cmp expect actual
+'
+
 cat >expect.stat <<'EOF'
  file | Bin 2 -> 4 bytes
  1 file changed, 0 insertions(+), 0 deletions(-)
index 5060879d6d93d1f10a1db690bd42c19ee5ec1ae4..c5cd2e348c6fe47af7d94ef6852757c301f8097a 100755 (executable)
@@ -130,6 +130,21 @@ test_expect_success 'clone from auth-only-for-push repository' '
        test_cmp expect actual
 '
 
+test_expect_success 'clone from auth-only-for-objects repository' '
+       echo two >expect &&
+       set_askpass user@host &&
+       git clone --bare "$HTTPD_URL/auth-fetch/smart/repo.git" half-auth &&
+       expect_askpass both user@host &&
+       git --git-dir=half-auth log -1 --format=%s >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'no-op half-auth fetch does not require a password' '
+       set_askpass wrong &&
+       git --git-dir=half-auth fetch &&
+       expect_askpass none
+'
+
 test_expect_success 'disable dumb http on server' '
        git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \
                config http.getanyfile false
index 5c87f28e4ed8c8c8dc40fd561516dd8d0db791c9..decdc33c522568e98346d085acdf873c995eb762 100755 (executable)
@@ -140,6 +140,17 @@ test_expect_success '"git replace" replacing' '
      test "$HASH2" = "$(git replace)"
 '
 
+test_expect_success '"git replace" resolves sha1' '
+     SHORTHASH2=$(git rev-parse --short=8 $HASH2) &&
+     git replace -d $SHORTHASH2 &&
+     git replace $SHORTHASH2 $R &&
+     git show $HASH2 | grep "O Thor" &&
+     test_must_fail git replace $HASH2 $R &&
+     git replace -f $HASH2 $R &&
+     test_must_fail git replace -f &&
+     test "$HASH2" = "$(git replace)"
+'
+
 # This creates a side branch where the bug in H2
 # does not appear because P2 is created by applying
 # H2 and squashing H5 into it.
index 524d5c1b21a507c5ed16edc52fb9353792b83f28..94e26c47eae37062ca0d7d24d30104fb46d06743 100755 (executable)
@@ -17,18 +17,25 @@ test_expect_success setup '
        git commit -m upstream &&
        git clone . super &&
        git clone super submodule &&
+       (cd submodule &&
+        git submodule add ../submodule sub-submodule &&
+        test_tick &&
+        git commit -m "sub-submodule"
+       ) &&
        (cd super &&
         git submodule add ../submodule submodule &&
         test_tick &&
         git commit -m "submodule"
        ) &&
        git clone super super-clone &&
-       (cd super-clone && git submodule update --init) &&
+       (cd super-clone && git submodule update --init --recursive) &&
        git clone super empty-clone &&
        (cd empty-clone && git submodule init) &&
        git clone super top-only-clone &&
        git clone super relative-clone &&
-       (cd relative-clone && git submodule update --init)
+       (cd relative-clone && git submodule update --init --recursive) &&
+       git clone super recursive-clone &&
+       (cd recursive-clone && git submodule update --init --recursive)
 '
 
 test_expect_success 'change submodule' '
@@ -46,6 +53,11 @@ test_expect_success 'change submodule url' '
         git pull
        ) &&
        mv submodule moved-submodule &&
+       (cd moved-submodule &&
+        git config -f .gitmodules submodule.sub-submodule.url ../moved-submodule &&
+        test_tick &&
+        git commit -a -m moved-sub-submodule
+       ) &&
        (cd super &&
         git config -f .gitmodules submodule.submodule.url ../moved-submodule &&
         test_tick &&
@@ -61,6 +73,9 @@ test_expect_success '"git submodule sync" should update submodule URLs' '
        test -d "$(cd super-clone/submodule &&
         git config remote.origin.url
        )" &&
+       test ! -d "$(cd super-clone/submodule/sub-submodule &&
+        git config remote.origin.url
+       )" &&
        (cd super-clone/submodule &&
         git checkout master &&
         git pull
@@ -70,6 +85,25 @@ test_expect_success '"git submodule sync" should update submodule URLs' '
        )
 '
 
+test_expect_success '"git submodule sync --recursive" should update all submodule URLs' '
+       (cd super-clone &&
+        (cd submodule &&
+         git pull --no-recurse-submodules
+        ) &&
+        git submodule sync --recursive
+       ) &&
+       test -d "$(cd super-clone/submodule &&
+        git config remote.origin.url
+       )" &&
+       test -d "$(cd super-clone/submodule/sub-submodule &&
+        git config remote.origin.url
+       )" &&
+       (cd super-clone/submodule/sub-submodule &&
+        git checkout master &&
+        git pull
+       )
+'
+
 test_expect_success '"git submodule sync" should update known submodule URLs' '
        (cd empty-clone &&
         git pull &&
@@ -107,6 +141,23 @@ test_expect_success '"git submodule sync" handles origin URL of the form foo/bar
         #actual foo/submodule
         test "$(git config remote.origin.url)" = "../foo/submodule"
        )
+       (cd submodule/sub-submodule &&
+        test "$(git config remote.origin.url)" != "../../foo/submodule"
+       )
+       )
+'
+
+test_expect_success '"git submodule sync --recursive" propagates changes in origin' '
+       (cd recursive-clone &&
+        git remote set-url origin foo/bar &&
+        git submodule sync --recursive &&
+       (cd submodule &&
+        #actual foo/submodule
+        test "$(git config remote.origin.url)" = "../foo/submodule"
+       )
+       (cd submodule/sub-submodule &&
+        test "$(git config remote.origin.url)" = "../../foo/submodule"
+       )
        )
 '
 
index 731e64c3adbd4d887bfa2c96eb060aa890377cfc..3a8e7d3f5aa1dc6a4d13467babd96a293ee1bb6e 100755 (executable)
@@ -185,5 +185,20 @@ test_expect_success 'forks: project_index lists all projects (incl. forks)' '
        test_cmp expected actual
 '
 
+xss() {
+       echo >&2 "Checking $1..." &&
+       gitweb_run "$1" &&
+       if grep "$TAG" gitweb.body; then
+               echo >&2 "xss: $TAG should have been quoted in output"
+               return 1
+       fi
+       return 0
+}
+
+test_expect_success 'xss checks' '
+       TAG="<magic-xss-tag>" &&
+       xss "a=rss&p=$TAG" &&
+       xss "a=rss&p=foo.git&f=$TAG"
+'
 
 test_done
diff --git a/t/t9604-cvsimport-timestamps.sh b/t/t9604-cvsimport-timestamps.sh
new file mode 100755 (executable)
index 0000000..1fd5142
--- /dev/null
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+test_description='git cvsimport timestamps'
+. ./lib-cvs.sh
+
+setup_cvs_test_repository t9604
+
+test_expect_success 'check timestamps are UTC (TZ=CST6CDT)' '
+
+       TZ=CST6CDT git cvsimport -p"-x" -C module-1 module &&
+       git cvsimport -p"-x" -C module-1 module &&
+       (
+               cd module-1 &&
+               git log --format="%s %ai"
+       ) >actual-1 &&
+       cat >expect-1 <<-EOF &&
+       Rev 16 2006-10-29 07:00:01 +0000
+       Rev 15 2006-10-29 06:59:59 +0000
+       Rev 14 2006-04-02 08:00:01 +0000
+       Rev 13 2006-04-02 07:59:59 +0000
+       Rev 12 2005-12-01 00:00:00 +0000
+       Rev 11 2005-11-01 00:00:00 +0000
+       Rev 10 2005-10-01 00:00:00 +0000
+       Rev  9 2005-09-01 00:00:00 +0000
+       Rev  8 2005-08-01 00:00:00 +0000
+       Rev  7 2005-07-01 00:00:00 +0000
+       Rev  6 2005-06-01 00:00:00 +0000
+       Rev  5 2005-05-01 00:00:00 +0000
+       Rev  4 2005-04-01 00:00:00 +0000
+       Rev  3 2005-03-01 00:00:00 +0000
+       Rev  2 2005-02-01 00:00:00 +0000
+       Rev  1 2005-01-01 00:00:00 +0000
+       EOF
+       test_cmp actual-1 expect-1
+'
+
+test_expect_success 'check timestamps with author-specific timezones' '
+
+       cat >cvs-authors <<-EOF &&
+       user1=User One <user1@domain.org>
+       user2=User Two <user2@domain.org> CST6CDT
+       user3=User Three <user3@domain.org> EST5EDT
+       user4=User Four <user4@domain.org> MST7MDT
+       EOF
+       git cvsimport -p"-x" -A cvs-authors -C module-2 module &&
+       (
+               cd module-2 &&
+               git log --format="%s %ai %an"
+       ) >actual-2 &&
+       cat >expect-2 <<-EOF &&
+       Rev 16 2006-10-29 01:00:01 -0600 User Two
+       Rev 15 2006-10-29 01:59:59 -0500 User Two
+       Rev 14 2006-04-02 03:00:01 -0500 User Two
+       Rev 13 2006-04-02 01:59:59 -0600 User Two
+       Rev 12 2005-11-30 17:00:00 -0700 User Four
+       Rev 11 2005-10-31 19:00:00 -0500 User Three
+       Rev 10 2005-09-30 19:00:00 -0500 User Two
+       Rev  9 2005-09-01 00:00:00 +0000 User One
+       Rev  8 2005-07-31 18:00:00 -0600 User Four
+       Rev  7 2005-06-30 20:00:00 -0400 User Three
+       Rev  6 2005-05-31 19:00:00 -0500 User Two
+       Rev  5 2005-05-01 00:00:00 +0000 User One
+       Rev  4 2005-03-31 17:00:00 -0700 User Four
+       Rev  3 2005-02-28 19:00:00 -0500 User Three
+       Rev  2 2005-01-31 18:00:00 -0600 User Two
+       Rev  1 2005-01-01 00:00:00 +0000 User One
+       EOF
+       test_cmp actual-2 expect-2
+'
+
+test_done
diff --git a/t/t9604/cvsroot/.gitattributes b/t/t9604/cvsroot/.gitattributes
new file mode 100644 (file)
index 0000000..562b12e
--- /dev/null
@@ -0,0 +1 @@
+* -whitespace
diff --git a/t/t9604/cvsroot/CVSROOT/.gitignore b/t/t9604/cvsroot/CVSROOT/.gitignore
new file mode 100644 (file)
index 0000000..3bb9b34
--- /dev/null
@@ -0,0 +1,2 @@
+history
+val-tags
diff --git a/t/t9604/cvsroot/module/a,v b/t/t9604/cvsroot/module/a,v
new file mode 100644 (file)
index 0000000..80658c3
--- /dev/null
@@ -0,0 +1,264 @@
+head   1.16;
+access;
+symbols;
+locks; strict;
+comment        @# @;
+
+
+1.16
+date   2006.10.29.07.00.01;    author user2;   state Exp;
+branches;
+next   1.15;
+
+1.15
+date   2006.10.29.06.59.59;    author user2;   state Exp;
+branches;
+next   1.14;
+
+1.14
+date   2006.04.02.08.00.01;    author user2;   state Exp;
+branches;
+next   1.13;
+
+1.13
+date   2006.04.02.07.59.59;    author user2;   state Exp;
+branches;
+next   1.12;
+
+1.12
+date   2005.12.01.00.00.00;    author user4;   state Exp;
+branches;
+next   1.11;
+
+1.11
+date   2005.11.01.00.00.00;    author user3;   state Exp;
+branches;
+next   1.10;
+
+1.10
+date   2005.10.01.00.00.00;    author user2;   state Exp;
+branches;
+next   1.9;
+
+1.9
+date   2005.09.01.00.00.00;    author user1;   state Exp;
+branches;
+next   1.8;
+
+1.8
+date   2005.08.01.00.00.00;    author user4;   state Exp;
+branches;
+next   1.7;
+
+1.7
+date   2005.07.01.00.00.00;    author user3;   state Exp;
+branches;
+next   1.6;
+
+1.6
+date   2005.06.01.00.00.00;    author user2;   state Exp;
+branches;
+next   1.5;
+
+1.5
+date   2005.05.01.00.00.00;    author user1;   state Exp;
+branches;
+next   1.4;
+
+1.4
+date   2005.04.01.00.00.00;    author user4;   state Exp;
+branches;
+next   1.3;
+
+1.3
+date   2005.03.01.00.00.00;    author user3;   state Exp;
+branches;
+next   1.2;
+
+1.2
+date   2005.02.01.00.00.00;    author user2;   state Exp;
+branches;
+next   1.1;
+
+1.1
+date   2005.01.01.00.00.00;    author user1;   state Exp;
+branches;
+next   ;
+
+
+desc
+@@
+
+
+1.16
+log
+@Rev 16
+@
+text
+@Rev 16
+@
+
+
+1.15
+log
+@Rev 15
+@
+text
+@d1 1
+a1 1
+Rev 15
+@
+
+
+1.14
+log
+@Rev 14
+@
+text
+@d1 1
+a1 1
+Rev 14
+@
+
+
+1.13
+log
+@Rev 13
+@
+text
+@d1 1
+a1 1
+Rev 13
+@
+
+
+1.12
+log
+@Rev 12
+@
+text
+@d1 1
+a1 1
+Rev 12
+@
+
+
+1.11
+log
+@Rev 11
+@
+text
+@d1 1
+a1 1
+Rev 11
+@
+
+
+1.10
+log
+@Rev 10
+@
+text
+@d1 1
+a1 1
+Rev 10
+@
+
+
+1.9
+log
+@Rev  9
+@
+text
+@d1 1
+a1 1
+Rev 9
+@
+
+
+1.8
+log
+@Rev  8
+@
+text
+@d1 1
+a1 1
+Rev 8
+@
+
+
+1.7
+log
+@Rev  7
+@
+text
+@d1 1
+a1 1
+Rev 7
+@
+
+
+1.6
+log
+@Rev  6
+@
+text
+@d1 1
+a1 1
+Rev 6
+@
+
+
+1.5
+log
+@Rev  5
+@
+text
+@d1 1
+a1 1
+Rev 5
+@
+
+
+1.4
+log
+@Rev  4
+@
+text
+@d1 1
+a1 1
+Rev 4
+@
+
+
+1.3
+log
+@Rev  3
+@
+text
+@d1 1
+a1 1
+Rev 3
+@
+
+
+1.2
+log
+@Rev  2
+@
+text
+@d1 1
+a1 1
+Rev 2
+@
+
+
+1.1
+log
+@Rev  1
+@
+text
+@d1 1
+a1 1
+Rev 1
+@
index fe30ad881f67c9f1fdcb2ee40922880126ec13cc..0c2fc3ea1a28268e216a3a93ed12b09f0cf55ef2 100755 (executable)
@@ -155,6 +155,25 @@ test_expect_success 'cleanup after failure' '
        )
 '
 
+# perl $File:: bug check
+test_expect_success 'ktext expansion should not expand multi-line $File::' '
+       (
+               cd "$cli" &&
+               cat >lv.pm <<-\EOF
+               my $wanted = sub { my $f = $File::Find::name;
+                                   if ( -f && $f =~ /foo/ ) {
+               EOF
+               p4 add -t ktext lv.pm &&
+               p4 submit -d "lv.pm"
+       ) &&
+       test_when_finished cleanup_git &&
+       git p4 clone --dest="$git" //depot &&
+       (
+               cd "$git" &&
+               test_cmp "$cli/lv.pm" lv.pm
+       )
+'
+
 #
 # Do not scrub anything but +k or +ko files.  Sneak a change into
 # the cli file so that submit will get a conflict.  Make sure that
diff --git a/utf8.c b/utf8.c
index 28791a7c3174924967182d54c8b4a7f9600c87bf..5c61bbe1131e7bbdd939c8b815bd5222b872e3fb 100644 (file)
--- a/utf8.c
+++ b/utf8.c
@@ -423,6 +423,13 @@ int is_encoding_utf8(const char *name)
        return 0;
 }
 
+int same_encoding(const char *src, const char *dst)
+{
+       if (is_encoding_utf8(src) && is_encoding_utf8(dst))
+               return 1;
+       return !strcasecmp(src, dst);
+}
+
 /*
  * Given a buffer and its encoding, return it re-encoded
  * with iconv.  If the conversion fails, returns NULL.
diff --git a/utf8.h b/utf8.h
index 3c0ae7624e027a802c38c4afb9fe5b0a590e093d..93ef60042c2fad93184b573f30e771ecddc842be 100644 (file)
--- a/utf8.h
+++ b/utf8.h
@@ -7,6 +7,7 @@ int utf8_width(const char **start, size_t *remainder_p);
 int utf8_strwidth(const char *string);
 int is_utf8(const char *text);
 int is_encoding_utf8(const char *name);
+int same_encoding(const char *, const char *);
 
 int strbuf_add_wrapped_text(struct strbuf *buf,
                const char *text, int indent, int indent2, int width);