]> asedeno.scripts.mit.edu Git - git.git/commitdiff
Merge branch 'jk/cached-textconv'
authorJunio C Hamano <gitster@pobox.com>
Sun, 9 May 2010 05:33:08 +0000 (22:33 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 9 May 2010 05:33:08 +0000 (22:33 -0700)
* jk/cached-textconv:
  diff: avoid useless filespec population
  diff: cache textconv output
  textconv: refactor calls to run_textconv
  introduce notes-cache interface
  make commit_tree a library function

132 files changed:
.gitignore
.mailmap
Documentation/Makefile
Documentation/RelNotes-1.7.0.5.txt [new file with mode: 0644]
Documentation/RelNotes-1.7.0.6.txt [new file with mode: 0644]
Documentation/RelNotes-1.7.1.txt
Documentation/SubmittingPatches
Documentation/blame-options.txt
Documentation/config.txt
Documentation/diff-options.txt
Documentation/everyday.txt
Documentation/git-branch.txt
Documentation/git-fetch.txt
Documentation/git-imap-send.txt
Documentation/git-merge.txt
Documentation/git-push.txt
Documentation/git-rebase.txt
Documentation/git-remote-helpers.txt
Documentation/git-send-email.txt
Documentation/git-status.txt
Documentation/git.txt
Documentation/howto/revert-a-faulty-merge.txt
Documentation/merge-options.txt
Documentation/technical/api-string-list.txt
Documentation/technical/pack-protocol.txt
Documentation/urls.txt
GIT-VERSION-GEN
Makefile
branch.c
builtin/apply.c
builtin/checkout.c
builtin/clone.c
builtin/commit.c
builtin/fetch.c
builtin/fmt-merge-msg.c
builtin/grep.c
builtin/index-pack.c
builtin/log.c
builtin/ls-files.c
builtin/ls-tree.c
builtin/mailinfo.c
builtin/merge-file.c
builtin/push.c
builtin/reflog.c
builtin/rev-list.c
builtin/revert.c
builtin/tag.c
combine-diff.c
commit.h
compat/mingw.c
compat/mingw.h
compat/vcbuild/include/termios.h [new file with mode: 0644]
configure.ac
contrib/ciabot/README [new file with mode: 0644]
contrib/ciabot/ciabot.py [new file with mode: 0755]
contrib/ciabot/ciabot.sh [new file with mode: 0755]
contrib/completion/git-completion.bash
contrib/fast-import/import-zips.py
contrib/hg-to-git/hg-to-git.py
contrib/p4import/git-p4import.py
daemon.c
diff.c
git-compat-util.h
git-instaweb.sh
git-rebase--interactive.sh
git-rebase.sh
git-send-email.perl
git-stash.sh
git-submodule.sh
git.spec.in
git_remote_helpers/Makefile
gitk-git/gitk
gitk-git/po/de.po
gitk-git/po/es.po
gitk-git/po/fr.po
gitk-git/po/hu.po
gitk-git/po/it.po
gitk-git/po/ja.po
gitk-git/po/ru.po
gitk-git/po/sv.po
gitweb/INSTALL
gitweb/Makefile
gitweb/README
grep.c
http-backend.c
imap-send.c
ll-merge.c
ll-merge.h
merge-file.c
merge-recursive.c
merge-recursive.h
notes.h
pretty.c
refs.c
rerere.c
run-command.c
string-list.c
string-list.h
submodule.c
t/t0000-basic.sh
t/t1010-mktree.sh
t/t1304-default-acl.sh
t/t3301-notes.sh
t/t3404-rebase-interactive.sh
t/t3507-cherry-pick-conflict.sh [new file with mode: 0755]
t/t4017-diff-retval.sh
t/t4038-diff-combined.sh
t/t4041-diff-submodule.sh
t/t4134-apply-submodule.sh [new file with mode: 0755]
t/t5505-remote.sh
t/t5601-clone.sh
t/t6006-rev-list-format.sh
t/t6023-merge-file.sh
t/t6200-fmt-merge-msg.sh
t/t7012-skip-worktree-writing.sh
t/t7201-co.sh
t/t7506-status-submodule.sh
t/test-lib.sh
templates/Makefile
templates/hooks--commit-msg.sample
templates/hooks--post-update.sample
templates/hooks--pre-commit.sample
templates/hooks--pre-rebase.sample
templates/hooks--prepare-commit-msg.sample
templates/hooks--update.sample
templates/info--exclude
unpack-trees.c
wrapper.c
xdiff-interface.c
xdiff-interface.h
xdiff/xdiff.h
xdiff/xmerge.c

index 7b3acb766491e2e002f293cf9dd50298d0d7d83a..dbf1b90c63573b08efc894ed8c1e02de58fd53e4 100644 (file)
 /git-write-tree
 /git-core-*/?*
 /gitk-git/gitk-wish
+/gitweb/GITWEB-BUILD-OPTIONS
 /gitweb/gitweb.cgi
+/gitweb/gitweb.min.*
 /test-chmtime
 /test-ctype
 /test-date
 *.exe
 *.[aos]
 *.py[co]
-*.o.d
+.depend/
 *+
 /config.mak
 /autom4te.cache
index 88bd01e16d91f002cf3ac405e2a923884058d724..a8091eb5dfa430bf1b0537da47a31e7cf88d8622 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -5,6 +5,7 @@
 # same person appearing not to be so.
 #
 
+Alex Bennée <kernel-hacker@bennee.com>
 Alexander Gavrilov <angavrilov@gmail.com>
 Aneesh Kumar K.V <aneesh.kumar@gmail.com>
 Brian M. Carlson <sandals@crustytoothpaste.ath.cx>
@@ -15,6 +16,7 @@ Daniel Barkalow <barkalow@iabervon.org>
 David D. Kilzer <ddkilzer@kilzer.net>
 David Kågedal <davidk@lysator.liu.se>
 David S. Miller <davem@davemloft.net>
+Deskin Miller <deskinm@umich.edu>
 Dirk Süsserott <newsletter@dirk.my1.cc>
 Fredrik Kuivinen <freku045@student.liu.se>
 H. Peter Anvin <hpa@bonde.sc.orionmulti.com>
@@ -60,6 +62,7 @@ Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
 Uwe Kleine-König <uzeisberger@io.fsforth.de>
 Uwe Kleine-König <zeisberg@informatik.uni-freiburg.de>
 Ville Skyttä <scop@xemacs.org>
+Vitaly "_Vi" Shukela <public_vi@tut.by>
 William Pursell <bill.pursell@gmail.com>
 YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
 anonymous <linux@horizon.com>
index 8a8a3954dc45723f7380b59dadbb7e412198d672..04f69cf64e5d989bac3cd1c235e6a7e657c6c103 100644 (file)
@@ -264,7 +264,9 @@ manpage-base-url.xsl: manpage-base-url.xsl.in
        mv $@+ $@
 
 user-manual.xml: user-manual.txt user-manual.conf
-       $(QUIET_ASCIIDOC)$(ASCIIDOC) $(ASCIIDOC_EXTRA) -b docbook -d book $<
+       $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
+       $(ASCIIDOC) $(ASCIIDOC_EXTRA) -b docbook -d book -o $@+ $< && \
+       mv $@+ $@
 
 technical/api-index.txt: technical/api-index-skel.txt \
        technical/api-index.sh $(patsubst %,%.txt,$(API_DOCS))
@@ -278,7 +280,9 @@ XSLT = docbook.xsl
 XSLTOPTS = --xinclude --stringparam html.stylesheet docbook-xsl.css
 
 user-manual.html: user-manual.xml
-       $(QUIET_XSLTPROC)xsltproc $(XSLTOPTS) -o $@ $(XSLT) $<
+       $(QUIET_XSLTPROC)$(RM) $@+ $@ && \
+       xsltproc $(XSLTOPTS) -o $@+ $(XSLT) $< && \
+       mv $@+ $@
 
 git.info: user-manual.texi
        $(QUIET_MAKEINFO)$(MAKEINFO) --no-split -o $@ user-manual.texi
diff --git a/Documentation/RelNotes-1.7.0.5.txt b/Documentation/RelNotes-1.7.0.5.txt
new file mode 100644 (file)
index 0000000..3149c91
--- /dev/null
@@ -0,0 +1,26 @@
+Git v1.7.0.5 Release Notes
+==========================
+
+Fixes since v1.7.0.4
+--------------------
+
+ * "git daemon" failed to compile on platforms without sockaddr_storage type.
+
+ * Output from "git rev-list --pretty=oneline" was unparsable when a
+   commit did not have any message, which is abnormal but possible in a
+   repository converted from foreign scm.
+
+ * "git stash show <commit-that-is-not-a-stash>" gave an error message
+   that was not so useful.  Reworded the message to "<it> is not a
+   stash".
+
+ * Python scripts in contrib/ area now start with "#!/usr/bin/env python"
+   to honor user's PATH.
+
+ * "git imap-send" used to mistake any line that begins with "From " as a
+   message separator in format-patch output.
+
+ * Smart http server backend failed to report an internal server error and
+   infinitely looped instead after output pipe was closed.
+
+And other minor fixes and documentation updates.
diff --git a/Documentation/RelNotes-1.7.0.6.txt b/Documentation/RelNotes-1.7.0.6.txt
new file mode 100644 (file)
index 0000000..b2852b6
--- /dev/null
@@ -0,0 +1,13 @@
+Git v1.7.0.6 Release Notes
+==========================
+
+Fixes since v1.7.0.5
+--------------------
+
+ * "git diff --stat" used "int" to count the size of differences,
+   which could result in overflowing.
+
+ * "git rev-list --abbrev-commit" defaulted to 40-byte abbreviations, unlike
+   newer tools in the git toolset.
+
+And other minor fixes and documentation updates.
index 19aeef5effd16a7a7fc5409ca42bc54eb780e991..9d89fedb36b4d6fa7c8a6a8487cc47b4ca542e3a 100644 (file)
@@ -1,19 +1,30 @@
-Git v1.7.1 Release Notes (draft)
-================================
+Git v1.7.1 Release Notes
+========================
 
 Updates since v1.7.0
 --------------------
 
+ * Eric Raymond is the maintainer of updated CIAbot scripts, in contrib/.
+
+ * gitk updates.
+
  * Some commands (e.g. svn and http interfaces) that interactively ask
-   password can be told to use an external program given via GIT_ASKPASS.
+   for a password can be told to use an external program given via
+   GIT_ASKPASS.
+
+ * Conflict markers that lead the common ancestor in diff3-style output
+   now have a label, which hopefully would help third-party tools that
+   expect one.
+
+ * Comes with an updated bash-completion script.
 
  * "git am" learned "--keep-cr" option to handle inputs that are
-   mixture of changes to files with and without CRLF line endings.
+   mixture of changes to files with and without CRLF line endings.
 
  * "git cvsimport" learned -R option to leave revision mapping between
    CVS revisions and resulting git commits.
 
- * "git diff --submodule" notices and descries dirty submodules.
+ * "git diff --submodule" notices and describes dirty submodules.
 
  * "git for-each-ref" learned %(symref), %(symref:short) and %(flag)
    tokens.
@@ -34,12 +45,11 @@ Updates since v1.7.0
  * "git log -p --first-parent -m" shows one-parent diff for merge
    commits, instead of showing combined diff.
 
- * "git merge-file" learned to use custom conflict marker size and also use
-   the "union merge" behaviour.
+ * "git merge-file" learned to use custom conflict marker size and also
+   to use the "union merge" behaviour.
 
- * "git notes" command has been rewritten in C and learned quite a
-   many commands and features to help you carry notes forward across
-   rebases and amends.
+ * "git notes" command has been rewritten in C and learned many commands
+   and features to help you carry notes forward across rebases and amends.
 
  * "git request-pull" identifies the commit the request is relative to in
    a more readable way.
@@ -48,13 +58,18 @@ Updates since v1.7.0
    near the tip while preserving your local changes in a way similar
    to how "git checkout branch" does.
 
- * "git status" notices and descries dirty submodules.
+ * "git status" notices and describes dirty submodules.
 
  * "git svn" should work better when interacting with repositories
    with CRLF line endings.
 
  * "git imap-send" learned to support CRAM-MD5 authentication.
 
+ * "gitweb" installation procedure can use "minified" js/css files
+   better.
+
+ * Various documentation updates.
+
 Fixes since v1.7.0
 ------------------
 
@@ -64,8 +79,11 @@ release, unless otherwise noted.
  * "git add frotz/nitfol" did not complain when the entire frotz/ directory
    was ignored.
 
----
-exec >/var/tmp/1
-echo O=$(git describe)
-O=v1.7.0.3-310-g99f5b08
-git shortlog --no-merges ^maint $O..
+ * "git diff --stat" used "int" to count the size of differences,
+   which could result in overflowing.
+
+ * "git rev-list --pretty=oneline" didn't terminate a record with LF for
+   commits without any message.
+
+ * "git rev-list --abbrev-commit" defaulted to 40-byte abbreviations, unlike
+   newer tools in the git toolset.
index c686f8646b465860c8a096241797709366cc4dc1..abc65de9464144a7bac38756c01ab315ab6922eb 100644 (file)
@@ -520,11 +520,9 @@ Gmail
 GMail does not appear to have any way to turn off line wrapping in the web
 interface, so this will mangle any emails that you send.  You can however
 use any IMAP email client to connect to the google imap server, and forward
-the emails through that.  Just make sure to disable line wrapping in that
-email client.  Alternatively, use "git send-email" instead.
+the emails through that.
 
-Submitting properly formatted patches via Gmail is simple now that
-IMAP support is available. First, edit your ~/.gitconfig to specify your
+To submit using the IMAP interface, first, edit your ~/.gitconfig to specify your
 account settings:
 
 [imap]
@@ -538,14 +536,29 @@ account settings:
 You might need to instead use: folder = "[Google Mail]/Drafts" if you get an error
 that the "Folder doesn't exist".
 
-Next, ensure that your Gmail settings are correct. In "Settings" the
-"Use Unicode (UTF-8) encoding for outgoing messages" should be checked.
+Once your commits are ready to be sent to the mailing list, run the
+following command to send the patch emails to your Gmail Drafts
+folder.
 
-Once your commits are ready to send to the mailing list, run the following
-command to send the patch emails to your Gmail Drafts folder.
+  $ git format-patch --cover-letter -M --stdout origin/master | git imap-send
 
-       $ git format-patch -M --stdout origin/master | git imap-send
+Just make sure to disable line wrapping in the email client (GMail web
+interface will line wrap no matter what, so you need to use a real
+IMAP client).
 
-Go to your Gmail account, open the Drafts folder, find the patch email, fill
-in the To: and CC: fields and send away!
+Alternatively, you can use "git send-email" and send your patches
+through the GMail SMTP server.  edit ~/.gitconfig to specify your
+account settings:
+
+[sendemail]
+       smtpencryption = tls
+       smtpserver = smtp.gmail.com
+       smtpuser = user@gmail.com
+       smtppass = p4ssw0rd
+       smtpserverport = 587
+
+Once your commits are ready to be sent to the mailing list, run the
+following commands:
 
+  $ git format-patch --cover-letter -M origin/master -o outgoing/
+  $ git send-email outgoing/*
index 4833cac4b996e83e351b70d8f02a160d04e9a8e3..d8205691c6ff85dcbbe5f064463d4671ec10125e 100644 (file)
@@ -79,14 +79,15 @@ of lines before or after the line given by <start>.
        of the --date option at linkgit:git-log[1].
 
 -M|<num>|::
-       Detect moving lines in the file as well.  When a commit
-       moves a block of lines in a file (e.g. the original file
-       has A and then B, and the commit changes it to B and
-       then A), the traditional 'blame' algorithm typically blames
-       the lines that were moved up (i.e. B) to the parent and
-       assigns blame to the lines that were moved down (i.e. A)
-       to the child commit.  With this option, both groups of lines
-       are blamed on the parent.
+       Detect moved or copied lines within a file. When a commit
+       moves or copies a block of lines (e.g. the original file
+       has A and then B, and the commit changes it to B and then
+       A), the traditional 'blame' algorithm notices only half of
+       the movement and typically blames the lines that were moved
+       up (i.e. B) to the parent and assigns blame to the lines that
+       were moved down (i.e. A) to the child commit.  With this
+       option, both groups of lines are blamed on the parent by
+       running extra passes of inspection.
 +
 <num> is optional but it is the lower bound on the number of
 alphanumeric characters that git must detect as moving
@@ -94,7 +95,7 @@ within a file for it to associate those lines with the parent
 commit.
 
 -C|<num>|::
-       In addition to `-M`, detect lines copied from other
+       In addition to `-M`, detect lines moved or copied from other
        files that were modified in the same commit.  This is
        useful when you reorganize your program and move code
        around across files.  When this option is given twice,
index 06b2f827b414651bde25165b4f42dc4160892d7a..8f86050b05f5643240cfd760492079dbbcb73c76 100644 (file)
@@ -198,11 +198,11 @@ core.quotepath::
 
 core.autocrlf::
        If true, makes git convert `CRLF` at the end of lines in text files to
-       `LF` when reading from the filesystem, and convert in reverse when
-       writing to the filesystem.  The variable can be set to
+       `LF` when reading from the work tree, and convert in reverse when
+       writing to the work tree.  The variable can be set to
        'input', in which case the conversion happens only while
-       reading from the filesystem but files are written out with
-       `LF` at the end of lines.  A file is considered
+       reading from the work tree but files are written out to the work
+       tree with `LF` at the end of lines.  A file is considered
        "text" (i.e. be subjected to the autocrlf mechanism) based on
        the file's `crlf` attribute, or if `crlf` is unspecified,
        based on the file's contents.  See linkgit:gitattributes[5].
@@ -914,7 +914,7 @@ format.signoff::
 gc.aggressiveWindow::
        The window size parameter used in the delta compression
        algorithm used by 'git gc --aggressive'.  This defaults
-       to 10.
+       to 250.
 
 gc.auto::
        When there are approximately more than this many loose
@@ -1359,10 +1359,6 @@ notes.rewrite.<command>::
        automatically copies your notes from the original to the
        rewritten commit.  Defaults to `true`, but see
        "notes.rewriteRef" below.
-+
-This setting can be overridden with the `GIT_NOTES_REWRITE_REF`
-environment variable, which must be a colon separated list of refs or
-globs.
 
 notes.rewriteMode::
        When copying notes during a rewrite (see the
@@ -1382,6 +1378,10 @@ notes.rewriteRef::
 +
 Does not have a default value; you must configure this variable to
 enable note rewriting.
++
+This setting can be overridden with the `GIT_NOTES_REWRITE_REF`
+environment variable, which must be a colon separated list of refs or
+globs.
 
 pack.window::
        The size of the window used by linkgit:git-pack-objects[1] when no
index 60e922e6eff888f83a92d3747579ef45d993528a..c9c6c2b1cb61caa6db5e029d6bce1c76a6c075a7 100644 (file)
@@ -94,8 +94,8 @@ Also, when `--raw` or `--numstat` has been given, do not munge
 pathnames and use NULs as output field terminators.
 endif::git-log[]
 ifndef::git-log[]
-       When `--raw` or `--numstat` has been given, do not munge
-       pathnames and use NULs as output field terminators.
+       When `--raw`, `--numstat`, `--name-only` or `--name-status` has been
+       given, do not munge pathnames and use NULs as output field terminators.
 endif::git-log[]
 +
 Without this option, each pathname output will have TAB, LF, double quotes,
index 9310b650d3ca6b6cb7d69814eb9b800e8c2c85cd..e0ba8cc07549af375c89496c57c016a41b8cc699 100644 (file)
@@ -1,13 +1,8 @@
 Everyday GIT With 20 Commands Or So
 ===================================
 
-<<Basic Repository>> commands are needed by people who have a
-repository --- that is everybody, because every working tree of
-git is a repository.
-
-In addition, <<Individual Developer (Standalone)>> commands are
-essential for anybody who makes a commit, even for somebody who
-works alone.
+<<Individual Developer (Standalone)>> commands are essential for
+anybody who makes a commit, even for somebody who works alone.
 
 If you work with other people, you will need commands listed in
 the <<Individual Developer (Participant)>> section as well.
@@ -20,46 +15,6 @@ administrators who are responsible for the care and feeding
 of git repositories.
 
 
-Basic Repository[[Basic Repository]]
-------------------------------------
-
-Everybody uses these commands to maintain git repositories.
-
-  * linkgit:git-init[1] or linkgit:git-clone[1] to create a
-    new repository.
-
-  * linkgit:git-fsck[1] to check the repository for errors.
-
-  * linkgit:git-gc[1] to do common housekeeping tasks such as
-    repack and prune.
-
-Examples
-~~~~~~~~
-
-Check health and remove cruft.::
-+
-------------
-$ git fsck <1>
-$ git count-objects <2>
-$ git gc <3>
-------------
-+
-<1> running without `\--full` is usually cheap and assures the
-repository health reasonably well.
-<2> check how many loose objects there are and how much
-disk space is wasted by not repacking.
-<3> repacks the local repository and performs other housekeeping tasks.
-
-Repack a small project into single pack.::
-+
-------------
-$ git gc <1>
-------------
-+
-<1> pack all the objects reachable from the refs into one pack,
-then remove the other packs.
-
-
 Individual Developer (Standalone)[[Individual Developer (Standalone)]]
 ----------------------------------------------------------------------
 
@@ -67,6 +22,8 @@ A standalone individual developer does not exchange patches with
 other people, and works alone in a single repository, using the
 following commands.
 
+  * linkgit:git-init[1] to create a new repository.
+
   * linkgit:git-show-branch[1] to see where you are.
 
   * linkgit:git-log[1] to see what happened.
index 903a690f10e3cdb7aea15a19332bf0e8bc87814e..1940256930d92c0679b95bb0cd41f24847828bd4 100644 (file)
@@ -63,7 +63,9 @@ way to clean up all obsolete remote-tracking branches.
 OPTIONS
 -------
 -d::
-       Delete a branch. The branch must be fully merged in HEAD.
+       Delete a branch. The branch must be fully merged in its
+       upstream branch, or in `HEAD` if no upstream was set with
+       `--track` or `--set-upstream`.
 
 -D::
        Delete a branch irrespective of its merged status.
@@ -72,6 +74,8 @@ OPTIONS
        Create the branch's reflog.  This activates recording of
        all changes made to the branch ref, enabling use of date
        based sha1 expressions such as "<branchname>@\{yesterday}".
+       Note that in non-bare repositories, reflogs are usually
+       enabled by default by the `core.logallrefupdates` config option.
 
 -f::
 --force::
index 948ea26c5a2b3825e61d0c6495d03829669a7351..400fe7f956961ba0ddf09d2dcc6e539adec7ff74 100644 (file)
@@ -8,13 +8,13 @@ git-fetch - Download objects and refs from another repository
 
 SYNOPSIS
 --------
-'git fetch' <options> <repository> <refspec>...
+'git fetch' [<options>] [<repository> [<refspec>...]]
 
-'git fetch' <options> <group>
+'git fetch' [<options>] <group>
 
-'git fetch' --multiple <options> [<repository> | <group>]...
+'git fetch' --multiple [<options>] [<repository> | <group>]...
 
-'git fetch' --all <options>
+'git fetch' --all [<options>]
 
 
 DESCRIPTION
index 6cafbe2ec191b2e2b35e7855c71837fa0f231785..57aba42e6654e3d32617c3c7b17d18e8dd85852b 100644 (file)
@@ -16,7 +16,9 @@ DESCRIPTION
 This command uploads a mailbox generated with 'git format-patch'
 into an IMAP drafts folder.  This allows patches to be sent as
 other email is when using mail clients that cannot read mailbox
-files directly.
+files directly. The command also works with any general mailbox
+in which emails have the fields "From", "Date", and "Subject" in
+that order.
 
 Typical usage is something like:
 
@@ -122,12 +124,6 @@ Thunderbird in particular is known to be problematic.  Thunderbird
 users may wish to visit this web page for more information:
   http://kb.mozillazine.org/Plain_text_e-mail_-_Thunderbird#Completely_plain_email
 
-
-BUGS
-----
-Doesn't handle lines starting with "From " in the message body.
-
-
 Author
 ------
 Derived from isync 1.0.1 by Mike McCormack.
index 9c9618cead5ae73a754ce741dfd423a7bd2298ca..c2325ef90e336a37df42eb7f71f95e3581c83127 100644 (file)
@@ -9,7 +9,8 @@ git-merge - Join two or more development histories together
 SYNOPSIS
 --------
 [verse]
-'git merge' [-n] [--stat] [--no-commit] [--squash] [-s <strategy>]...
+'git merge' [-n] [--stat] [--no-commit] [--squash]
+       [-s <strategy>] [-X <strategy-option>]
        [--[no-]rerere-autoupdate] [-m <msg>] <commit>...
 'git merge' <msg> HEAD <commit>...
 
index 59dc8b197ecb4b6912c9ec29f83f21c405ef8634..48570242fb2dda31a5684e2d678d40690d3c4cab 100644 (file)
@@ -11,7 +11,7 @@ SYNOPSIS
 [verse]
 'git push' [--all | --mirror | --tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
           [--repo=<repository>] [-f | --force] [-v | --verbose] [-u | --set-upstream]
-          [<repository> <refspec>...]
+          [<repository> [<refspec>...]]
 
 DESCRIPTION
 -----------
index 823f2a4638c5b53671e294faf7a99a56d17c897a..0d07b1b2077c62f1199c5ee96790e5a7121b4f00 100644 (file)
@@ -274,9 +274,16 @@ which makes little sense.
 -f::
 --force-rebase::
        Force the rebase even if the current branch is a descendant
-       of the commit you are rebasing onto.  Normally the command will
+       of the commit you are rebasing onto.  Normally non-interactive rebase will
        exit with the message "Current branch is up to date" in such a
        situation.
+       Incompatible with the --interactive option.
++
+You may find this (or --no-ff with an interactive rebase) helpful after
+reverting a topic branch merge, as this option recreates the topic branch with
+fresh commits so it can be remerged successfully without needing to "revert
+the reversion" (see the
+link:howto/revert-a-faulty-merge.txt[revert-a-faulty-merge How-To] for details).
 
 --ignore-whitespace::
 --whitespace=<option>::
@@ -316,7 +323,19 @@ which makes little sense.
        commit to be modified, and change the action of the moved
        commit from `pick` to `squash` (or `fixup`).
 +
-This option is only valid when '--interactive' option is used.
+This option is only valid when the '--interactive' option is used.
+
+--no-ff::
+       With --interactive, cherry-pick all rebased commits instead of
+       fast-forwarding over the unchanged ones.  This ensures that the
+       entire history of the rebased branch is composed of new commits.
++
+Without --interactive, this is a synonym for --force-rebase.
++
+You may find this helpful after reverting a topic branch merge, as this option
+recreates the topic branch with fresh commits so it can be remerged
+successfully without needing to "revert the reversion" (see the
+link:howto/revert-a-faulty-merge.txt[revert-a-faulty-merge How-To] for details).
 
 include::merge-strategies.txt[]
 
index 1b5f61aa0b85ec592c6efbfa8be08fe83f576be5..3a23477ce72763b562258a25c3777dd57ac1a962 100644 (file)
@@ -3,20 +3,69 @@ git-remote-helpers(1)
 
 NAME
 ----
-git-remote-helpers - Helper programs for interoperation with remote git
+git-remote-helpers - Helper programs to interact with remote repositories
 
 SYNOPSIS
 --------
-'git remote-<transport>' <remote>
+'git remote-<transport>' <repository> [<URL>]
 
 DESCRIPTION
 -----------
 
-These programs are normally not used directly by end users, but are
-invoked by various git programs that interact with remote repositories
-when the repository they would operate on will be accessed using
-transport code not linked into the main git binary. Various particular
-helper programs will behave as documented here.
+Remote helper programs are normally not used directly by end users,
+but they are invoked by git when it needs to interact with remote
+repositories git does not support natively.  A given helper will
+implement a subset of the capabilities documented here. When git
+needs to interact with a repository using a remote helper, it spawns
+the helper as an independent process, sends commands to the helper's
+standard input, and expects results from the helper's standard
+output. Because a remote helper runs as an independent process from
+git, there is no need to re-link git to add a new helper, nor any
+need to link the helper with the implementation of git.
+
+Every helper must support the "capabilities" command, which git will
+use to determine what other commands the helper will accept.  Other
+commands generally concern facilities like discovering and updating
+remote refs, transporting objects between the object database and
+the remote repository, and updating the local object store.
+
+Helpers supporting the 'fetch' capability can discover refs from the
+remote repository and transfer objects reachable from those refs to
+the local object store. Helpers supporting the 'push' capability can
+transfer local objects to the remote repository and update remote refs.
+
+Git comes with a "curl" family of remote helpers, that handle various
+transport protocols, such as 'git-remote-http', 'git-remote-https',
+'git-remote-ftp' and 'git-remote-ftps'. They implement the capabilities
+'fetch', 'option', and 'push'.
+
+INVOCATION
+----------
+
+Remote helper programs are invoked with one or (optionally) two
+arguments. The first argument specifies a remote repository as in git;
+it is either the name of a configured remote or a URL. The second
+argument specifies a URL; it is usually of the form
+'<transport>://<address>', but any arbitrary string is possible.
+
+When git encounters a URL of the form '<transport>://<address>', where
+'<transport>' is a protocol that it cannot handle natively, it
+automatically invokes 'git remote-<transport>' with the full URL as
+the second argument. If such a URL is encountered directly on the
+command line, the first argument is the same as the second, and if it
+is encountered in a configured remote, the first argument is the name
+of that remote.
+
+A URL of the form '<transport>::<address>' explicitly instructs git to
+invoke 'git remote-<transport>' with '<address>' as the second
+argument. If such a URL is encountered directly on the command line,
+the first argument is '<address>', and if it is encountered in a
+configured remote, the first argument is the name of that remote.
+
+Additionally, when a configured remote has 'remote.<name>.vcs' set to
+'<transport>', git explicitly invokes 'git remote-<transport>' with
+'<name>' as the first argument. If set, the second argument is
+'remote.<name>.url'; otherwise, the second argument is omitted.
 
 COMMANDS
 --------
@@ -25,8 +74,8 @@ Commands are given by the caller on the helper's standard input, one per line.
 
 'capabilities'::
        Lists the capabilities of the helper, one per line, ending
-       with a blank line. Each capability may be preceded with '*'.
-       This marks them mandatory for git version using the remote
+       with a blank line. Each capability may be preceded with '*',
+       which marks them mandatory for git version using the remote
        helper to understand (unknown mandatory capability is fatal
        error).
 
@@ -35,27 +84,27 @@ Commands are given by the caller on the helper's standard input, one per line.
        [<attr> ...]". The value may be a hex sha1 hash, "@<dest>" for
        a symref, or "?" to indicate that the helper could not get the
        value of the ref. A space-separated list of attributes follows
-       the name; unrecognized attributes are ignored. After the
-       complete list, outputs a blank line.
+       the name; unrecognized attributes are ignored. The list ends
+       with a blank line.
 +
 If 'push' is supported this may be called as 'list for-push'
 to obtain the current refs prior to sending one or more 'push'
 commands to the helper.
 
 'option' <name> <value>::
-       Set the transport helper option <name> to <value>.  Outputs a
+       Sets the transport helper option <name> to <value>.  Outputs a
        single line containing one of 'ok' (option successfully set),
        'unsupported' (option not recognized) or 'error <msg>'
-       (option <name> is supported but <value> is not correct
+       (option <name> is supported but <value> is not valid
        for it).  Options should be set before other commands,
-       and may how those commands behave.
+       and may influence the behavior of those commands.
 +
 Supported if the helper has the "option" capability.
 
 'fetch' <sha1> <name>::
        Fetches the given object, writing the necessary objects
        to the database.  Fetch commands are sent in a batch, one
-       per line, and the batch is terminated with a blank line.
+       per line, terminated with a blank line.
        Outputs a single blank line when all fetch commands in the
        same batch are complete. Only objects which were reported
        in the ref list with a sha1 may be fetched this way.
@@ -67,7 +116,7 @@ suitably updated.
 Supported if the helper has the "fetch" capability.
 
 'push' +<src>:<dst>::
-       Pushes the given <src> commit or branch locally to the
+       Pushes the given local <src> commit or branch to the
        remote branch described by <dst>.  A batch sequence of
        one or more push commands is terminated with a blank line.
 +
@@ -91,6 +140,9 @@ Supported if the helper has the "push" capability.
        by applying the refspecs from the "refspec" capability to the
        name of the ref.
 +
+Especially useful for interoperability with a foreign versioning
+system.
++
 Supported if the helper has the "import" capability.
 
 'connect' <service>::
@@ -119,16 +171,11 @@ CAPABILITIES
 ------------
 
 'fetch'::
-       This helper supports the 'fetch' command.
-
 'option'::
-       This helper supports the option command.
-
 'push'::
-       This helper supports the 'push' command.
-
 'import'::
-       This helper supports the 'import' command.
+'connect'::
+       This helper supports the corresponding command with the same name.
 
 'refspec' 'spec'::
        When using the import command, expect the source ref to have
@@ -140,9 +187,6 @@ CAPABILITIES
        all, it must cover all refs reported by the list command; if
        it is not used, it is effectively "*:*"
 
-'connect'::
-       This helper supports the 'connect' command.
-
 REF LIST ATTRIBUTES
 -------------------
 
@@ -158,19 +202,19 @@ REF LIST ATTRIBUTES
 OPTIONS
 -------
 'option verbosity' <N>::
-       Change the level of messages displayed by the helper.
-       When N is 0 the end-user has asked the process to be
-       quiet, and the helper should produce only error output.
-       N of 1 is the default level of verbosity, higher values
+       Changes the verbosity of messages displayed by the helper.
+       A value of 0 for N means that processes operate
+       quietly, and the helper produces only error output.
+       1 is the default level of verbosity, and higher values
        of N correspond to the number of -v flags passed on the
        command line.
 
 'option progress' \{'true'|'false'\}::
-       Enable (or disable) progress messages displayed by the
+       Enables (or disables) progress messages displayed by the
        transport helper during a command.
 
 'option depth' <depth>::
-       Deepen the history of a shallow repository.
+       Deepens the history of a shallow repository.
 
 'option followtags' \{'true'|'false'\}::
        If enabled the helper should automatically fetch annotated
@@ -186,11 +230,15 @@ OPTIONS
        helpers this only applies to the 'push', if supported.
 
 'option servpath <c-style-quoted-path>'::
-       Set service path (--upload-pack, --receive-pack etc.) for
-       next connect. Remote helper MAY support this option. Remote
-       helper MUST NOT rely on this option being set before
+       Sets service path (--upload-pack, --receive-pack etc.) for
+       next connect. Remote helper may support this option, but
+       must not rely on this option being set before
        connect request occurs.
 
+SEE ALSO
+--------
+linkgit:git-remote[1]
+
 Documentation
 -------------
 Documentation by Daniel Barkalow and Ilari Liusvaara
index ced35b2f532dde3580f162a0c23b642002a0e508..3dfdc7cca6cf27be47bf610da5c84a99d1df7926 100644 (file)
@@ -300,6 +300,21 @@ sendemail.confirm::
        in the previous section for the meaning of these values.
 
 
+Use gmail as the smtp server
+----------------------------
+
+Add the following section to the config file:
+
+       [sendemail]
+               smtpencryption = tls
+               smtpserver = smtp.gmail.com
+               smtpuser = yourname@gmail.com
+               smtpserverport = 587
+
+Note: the following perl modules are required
+      Net::SMTP::SSL, MIME::Base64 and Authen::SASL
+
+
 Author
 ------
 Written by Ryan Anderson <ryan@michonline.com>
index 1cab91b53455e0129e6c4940a2698620e2197624..2d4bbfcaf4cc2d2b92ad827662dc3b4b4ef355c0 100644 (file)
@@ -72,21 +72,37 @@ In short-format, the status of each path is shown as
 
 where `PATH1` is the path in the `HEAD`, and ` -> PATH2` part is
 shown only when `PATH1` corresponds to a different path in the
-index/worktree (i.e. renamed).
-
-For unmerged entries, `X` shows the status of stage #2 (i.e. ours) and `Y`
-shows the status of stage #3 (i.e. theirs).
-
-For entries that do not have conflicts, `X` shows the status of the index,
-and `Y` shows the status of the work tree.  For untracked paths, `XY` are
-`??`.
+index/worktree (i.e. the file is renamed). The 'XY' is a two-letter
+status code.
+
+The fields (including the `->`) are separated from each other by a
+single space. If a filename contains whitespace or other nonprintable
+characters, that field will be quoted in the manner of a C string
+literal: surrounded by ASCII double quote (34) characters, and with
+interior special characters backslash-escaped.
+
+For paths with merge conflicts, `X` and 'Y' show the modification
+states of each side of the merge. For paths that do not have merge
+conflicts, `X` shows the status of the index, and `Y` shows the status
+of the work tree.  For untracked paths, `XY` are `??`.  Other status
+codes can be interpreted as follows:
+
+* ' ' = unmodified
+* 'M' = modified
+* 'A' = added
+* 'D' = deleted
+* 'R' = renamed
+* 'C' = copied
+* 'U' = updated but unmerged
+
+Ignored files are not listed.
 
     X          Y     Meaning
     -------------------------------------------------
               [MD]   not updated
     M        [ MD]   updated in index
     A        [ MD]   added to index
-    D        [ MD]   deleted from index
+    D         [ M]   deleted from index
     R        [ MD]   renamed in index
     C        [ MD]   copied in index
     [MARC]           index and work tree matches
@@ -104,6 +120,15 @@ and `Y` shows the status of the work tree.  For untracked paths, `XY` are
     ?           ?    untracked
     -------------------------------------------------
 
+There is an alternate -z format recommended for machine parsing.  In
+that format, the status field is the same, but some other things
+change.  First, the '->' is omitted from rename entries and the field
+order is reversed (e.g 'from -> to' becomes 'to from'). Second, a NUL
+(ASCII 0) follows each filename, replacing space as a field separator
+and the terminating newline (but a space still separates the status
+field from the first filename).  Third, filenames containing special
+characters are not specially formatted; no quoting or
+backslash-escaping is performed.
 
 CONFIGURATION
 -------------
index 657eac831cf0650ce3c4ac6a1f6a690b282cea59..c4024d0edd9f77c49e6211c6950c6ccb775a70ff 100644 (file)
@@ -43,9 +43,16 @@ unreleased) version of git, that is available from 'master'
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
-* link:v1.7.0.4/git.html[documentation for release 1.7.0.4]
+* link:v1.7.1/git.html[documentation for release 1.7.1]
 
 * release notes for
+  link:RelNotes-1.7.1.txt[1.7.1].
+
+* link:v1.7.0.6/git.html[documentation for release 1.7.0.6]
+
+* release notes for
+  link:RelNotes-1.7.0.6.txt[1.7.0.6],
+  link:RelNotes-1.7.0.5.txt[1.7.0.5],
   link:RelNotes-1.7.0.4.txt[1.7.0.4],
   link:RelNotes-1.7.0.3.txt[1.7.0.3],
   link:RelNotes-1.7.0.2.txt[1.7.0.2],
index 3b4a390005b07c86ee320ee8ca1cf57e46458cb6..ff5c0bc27a416de16f106c15b9076082c6509e42 100644 (file)
@@ -142,6 +142,8 @@ different resolution strategies:
    revert of a merge was rebuilt from scratch (i.e. rebasing and fixing,
    as you seem to have interpreted), then re-merging the result without
    doing anything else fancy would be the right thing to do.
+   (See the ADDENDUM below for how to rebuild a branch from scratch
+   without changing its original branching-off point.)
 
 However, there are things to keep in mind when reverting a merge (and
 reverting such a revert).
@@ -177,3 +179,91 @@ the answer is: "oops, I really shouldn't have merged it, because it wasn't
 ready yet, and I really need to undo _all_ of the merge"). So then you
 really should revert the merge, but when you want to re-do the merge, you
 now need to do it by reverting the revert.
+
+ADDENDUM
+
+Sometimes you have to rewrite one of a topic branch's commits *and* you can't
+change the topic's branching-off point.  Consider the following situation:
+
+ P---o---o---M---x---x---W---x
+  \         /
+   A---B---C
+
+where commit W reverted commit M because it turned out that commit B was wrong
+and needs to be rewritten, but you need the rewritten topic to still branch
+from commit P (perhaps P is a branching-off point for yet another branch, and
+you want be able to merge the topic into both branches).
+
+The natural thing to do in this case is to checkout the A-B-C branch and use
+"rebase -i P" to change commit B.  However this does not rewrite commit A,
+because "rebase -i" by default fast-forwards over any initial commits selected
+with the "pick" command.  So you end up with this:
+
+ P---o---o---M---x---x---W---x
+  \         /
+   A---B---C   <-- old branch
+    \
+     B'---C'   <-- naively rewritten branch
+
+To merge A-B'-C' into the mainline branch you would still have to first revert
+commit W in order to pick up the changes in A, but then it's likely that the
+changes in B' will conflict with the original B changes re-introduced by the
+reversion of W.
+
+However, you can avoid these problems if you recreate the entire branch,
+including commit A:
+
+   A'---B'---C'  <-- completely rewritten branch
+  /
+ P---o---o---M---x---x---W---x
+  \         /
+   A---B---C
+
+You can merge A'-B'-C' into the mainline branch without worrying about first
+reverting W.  Mainline's history would look like this:
+
+   A'---B'---C'------------------
+  /                              \
+ P---o---o---M---x---x---W---x---M2
+  \         /
+   A---B---C
+
+But if you don't actually need to change commit A, then you need some way to
+recreate it as a new commit with the same changes in it.  The rebase commmand's
+--no-ff option provides a way to do this:
+
+    $ git rebase [-i] --no-ff P
+
+The --no-ff option creates a new branch A'-B'-C' with all-new commits (all the
+SHA IDs will be different) even if in the interactive case you only actually
+modify commit B.  You can then merge this new branch directly into the mainline
+branch and be sure you'll get all of the branch's changes.
+
+You can also use --no-ff in cases where you just add extra commits to the topic
+to fix it up.  Let's revisit the situation discussed at the start of this howto:
+
+ P---o---o---M---x---x---W---x
+  \         /
+   A---B---C----------------D---E   <-- fixed-up topic branch
+
+At this point, you can use --no-ff to recreate the topic branch:
+
+    $ git checkout E
+    $ git rebase --no-ff P
+
+yielding
+
+   A'---B'---C'------------D'---E'  <-- recreated topic branch
+  /
+ P---o---o---M---x---x---W---x
+  \         /
+   A---B---C----------------D---E
+
+You can merge the recreated branch into the mainline without reverting commit W,
+and mainline's history will look like this:
+
+   A'---B'---C'------------D'---E'
+  /                              \
+ P---o---o---M---x---x---W---x---M2
+  \         /
+   A---B---C
index 37ce9a17fc3d66c402954246c83d0ec93fe007af..722d704ff2de1abd3d77a18ca396ba96d5cab6bc 100644 (file)
@@ -62,6 +62,11 @@ option can be used to override --squash.
        is used instead ('git merge-recursive' when merging a single
        head, 'git merge-octopus' otherwise).
 
+-X <option>::
+--strategy-option=<option>::
+       Pass merge strategy specific option through to the merge
+       strategy.
+
 --summary::
 --no-summary::
        Synonyms to --stat and --no-stat; these are deprecated and will be
@@ -76,8 +81,3 @@ ifndef::git-pull[]
 --verbose::
        Be verbose.
 endif::git-pull[]
-
--X <option>::
---strategy-option=<option>::
-       Pass merge strategy specific option through to the merge
-       strategy.
index 293bb15d206e71f57e906b33ca27ee05e3429521..6d8c24bb1e68e86d70d4a68d02e3a4d5ccb94c2a 100644 (file)
@@ -104,8 +104,12 @@ write `string_list_insert(...)->util = ...;`.
 `unsorted_string_list_has_string`::
 
        It's like `string_list_has_string()` but for unsorted lists.
+
+`unsorted_string_list_lookup`::
+
+       It's like `string_list_lookup()` but for unsorted lists.
 +
-This function needs to look through all items, as opposed to its
+The above two functions need to look through all items, as opposed to their
 counterpart for sorted lists, which performs a binary search.
 
 Data structures
index 9a5cdafa9cb8c5af8a3903ae18297a23adab0fbf..369f91d3b949b23682c4deda8234f13513f15732 100644 (file)
@@ -36,7 +36,7 @@ Git Transport
 
 The Git transport starts off by sending the command and repository
 on the wire using the pkt-line format, followed by a NUL byte and a
-hostname paramater, terminated by a NUL byte.
+hostname parameter, terminated by a NUL byte.
 
    0032git-upload-pack /project.git\0host=myserver.com\0
 
@@ -331,7 +331,7 @@ An incremental update (fetch) response might look like this:
 
    C: 0009done\n
 
-   S: 003aACK 74730d410fcb6603ace96f1dc55ea6196122532d\n
+   S: 0031ACK 74730d410fcb6603ace96f1dc55ea6196122532d\n
    S: [PACKFILE]
 ----
 
@@ -488,7 +488,7 @@ An example client/server communication might look like this:
    C: 0000
    C: [PACKDATA]
 
-   S: 000aunpack ok\n
-   S: 0014ok refs/heads/debug\n
-   S: 0026ng refs/heads/master non-fast-forward\n
+   S: 000eunpack ok\n
+   S: 0018ok refs/heads/debug\n
+   S: 002ang refs/heads/master non-fast-forward\n
 ----
index 459a394dc0eb2c7ebecc7c9cf53808d791187006..1dcd1e7f1ede3382ae992a266f5437fe06f8dc75 100644 (file)
@@ -1,44 +1,57 @@
 GIT URLS[[URLS]]
 ----------------
 
-One of the following notations can be used
-to name the remote repository:
+In general, URLs contain information about the transport protocol, the
+address of the remote server, and the path to the repository.
+Depending on the transport protocol, some of this information may be
+absent.
+
+Git natively supports ssh, git, http, https, ftp, ftps, and rsync
+protocols. The following syntaxes may be used with them:
 
-- rsync://host.xz/path/to/repo.git/
-- http://host.xz{startsb}:port{endsb}/path/to/repo.git/
-- https://host.xz{startsb}:port{endsb}/path/to/repo.git/
-- git://host.xz{startsb}:port{endsb}/path/to/repo.git/
-- git://host.xz{startsb}:port{endsb}/~user/path/to/repo.git/
 - ssh://{startsb}user@{endsb}host.xz{startsb}:port{endsb}/path/to/repo.git/
-- ssh://{startsb}user@{endsb}host.xz/path/to/repo.git/
-- ssh://{startsb}user@{endsb}host.xz/~user/path/to/repo.git/
-- ssh://{startsb}user@{endsb}host.xz/~/path/to/repo.git
+- git://host.xz{startsb}:port{endsb}/path/to/repo.git/
+- http{startsb}s{endsb}://host.xz{startsb}:port{endsb}/path/to/repo.git/
+- ftp{startsb}s{endsb}://host.xz{startsb}:port{endsb}/path/to/repo.git/
+- rsync://host.xz/path/to/repo.git/
 
-SSH is the default transport protocol over the network.  You can
-optionally specify which user to log-in as, and an alternate,
-scp-like syntax is also supported.  Both syntaxes support
-username expansion, as does the native git protocol, but
-only the former supports port specification. The following
-three are identical to the last three above, respectively:
+An alternative scp-like syntax may also be used with the ssh protocol:
 
-- {startsb}user@{endsb}host.xz:/path/to/repo.git/
-- {startsb}user@{endsb}host.xz:~user/path/to/repo.git/
-- {startsb}user@{endsb}host.xz:path/to/repo.git
+- {startsb}user@{endsb}host.xz:path/to/repo.git/
 
-To sync with a local directory, you can use:
+The ssh and git protocols additionally support ~username expansion:
+
+- ssh://{startsb}user@{endsb}host.xz{startsb}:port{endsb}/~{startsb}user{endsb}/path/to/repo.git/
+- git://host.xz{startsb}:port{endsb}/~{startsb}user{endsb}/path/to/repo.git/
+- {startsb}user@{endsb}host.xz:/~{startsb}user{endsb}/path/to/repo.git/
+
+For local respositories, also supported by git natively, the following
+syntaxes may be used:
 
 - /path/to/repo.git/
 - file:///path/to/repo.git/
 
 ifndef::git-clone[]
-They are mostly equivalent, except when cloning.  See
-linkgit:git-clone[1] for details.
+These two syntaxes are mostly equivalent, except when cloning, when
+the former implies --local option. See linkgit:git-clone[1] for
+details.
 endif::git-clone[]
 
 ifdef::git-clone[]
-They are equivalent, except the former implies --local option.
+These two syntaxes are mostly equivalent, except the former implies
+--local option.
 endif::git-clone[]
 
+When git doesn't know how to handle a certain transport protocol, it
+attempts to use the 'remote-<transport>' remote helper, if one
+exists. To explicitly request a remote helper, the following syntax
+may be used:
+
+- <transport>::<address>
+
+where <address> may be a path, a server and path, or an arbitrary
+URL-like string recognized by the specific remote helper being
+invoked. See linkgit:git-remote-helpers[1] for details.
 
 If there are a large number of similarly-named remote repositories and
 you want to use a different format for them (such that the URLs you
index 3eb6d8517eeda1e51d042363f0265fc87f4e5ba0..0ad39484eceab30360e1f46c6057a873ca2c26f1 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.0.4
+DEF_VER=v1.7.1
 
 LF='
 '
index 24e92abe916a179bb85d4a67a6bdcf2d8ff575e3..4f7224a59a9c93b12a7878b0f692c1bc469d6daf 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -34,7 +34,7 @@ all::
 # Define NO_D_INO_IN_DIRENT if you don't have d_ino in your struct dirent.
 #
 # Define NO_D_TYPE_IN_DIRENT if your platform defines DT_UNKNOWN but lacks
-# d_type in struct dirent (latest Cygwin -- will be fixed soonish).
+# d_type in struct dirent (Cygwin 1.5, fixed in Cygwin 1.7).
 #
 # Define NO_C99_FORMAT if your formatted IO functions (printf/scanf et.al.)
 # do not support the 'size specifiers' introduced by C99, namely ll, hh,
@@ -109,7 +109,7 @@ all::
 # Define NO_PTHREADS if you do not have or do not want to use Pthreads.
 #
 # Define NO_PREAD if you have a problem with pread() system call (e.g.
-# cygwin.dll before v1.5.22).
+# cygwin1.dll before v1.5.22).
 #
 # Define NO_FAST_WORKING_DIRECTORY if accessing objects in pack files is
 # generally faster on your platform than accessing the working directory.
@@ -203,6 +203,9 @@ all::
 # Define JSMIN to point to JavaScript minifier that functions as
 # a filter to have gitweb.js minified.
 #
+# Define CSSMIN to point to a CSS minifier in order to generate a minified
+# version of gitweb.css
+#
 # Define DEFAULT_PAGER to a sensible pager command (defaults to "less") if
 # you want to use something different.  The value will be interpreted by the
 # shell at runtime when it is used.
@@ -279,9 +282,6 @@ lib = lib
 # DESTDIR=
 pathsep = :
 
-# JavaScript minifier invocation that can function as filter
-JSMIN =
-
 export prefix bindir sharedir sysconfdir
 
 CC = gcc
@@ -833,22 +833,24 @@ ifeq ($(uname_S),SunOS)
        BASIC_CFLAGS += -D__EXTENSIONS__ -D__sun__ -DHAVE_ALLOCA_H
 endif
 ifeq ($(uname_O),Cygwin)
-       NO_D_TYPE_IN_DIRENT = YesPlease
-       NO_D_INO_IN_DIRENT = YesPlease
-       NO_STRCASESTR = YesPlease
-       NO_MEMMEM = YesPlease
-       NO_MKSTEMPS = YesPlease
-       NO_SYMLINK_HEAD = YesPlease
+       ifeq ($(shell expr "$(uname_R)" : '1\.[1-6]\.'),4)
+               NO_D_TYPE_IN_DIRENT = YesPlease
+               NO_D_INO_IN_DIRENT = YesPlease
+               NO_STRCASESTR = YesPlease
+               NO_MEMMEM = YesPlease
+               NO_MKSTEMPS = YesPlease
+               NO_SYMLINK_HEAD = YesPlease
+               NO_IPV6 = YesPlease
+               OLD_ICONV = UnfortunatelyYes
+       endif
        NEEDS_LIBICONV = YesPlease
        NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
        NO_TRUSTABLE_FILEMODE = UnfortunatelyYes
-       OLD_ICONV = UnfortunatelyYes
        NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
        # There are conflicting reports about this.
        # On some boxes NO_MMAP is needed, and not so elsewhere.
        # Try commenting this out if you suspect MMAP is more efficient
        NO_MMAP = YesPlease
-       NO_IPV6 = YesPlease
        X = .exe
        COMPAT_OBJS += compat/cygwin.o
        UNRELIABLE_FSTAT = UnfortunatelyYes
@@ -866,6 +868,7 @@ ifeq ($(uname_S),FreeBSD)
                NO_UINTMAX_T = YesPlease
                NO_STRTOUMAX = YesPlease
        endif
+       PYTHON_PATH = /usr/local/bin/python
 endif
 ifeq ($(uname_S),OpenBSD)
        NO_STRCASESTR = YesPlease
@@ -921,7 +924,6 @@ ifeq ($(uname_S),IRIX)
        SNPRINTF_RETURNS_BOGUS = YesPlease
        SHELL_PATH = /usr/gnu/bin/bash
        NEEDS_LIBGEN = YesPlease
-       NEEDS_LIBICONV = YesPlease
 endif
 ifeq ($(uname_S),IRIX64)
        NO_SETENV=YesPlease
@@ -940,7 +942,6 @@ ifeq ($(uname_S),IRIX64)
        SNPRINTF_RETURNS_BOGUS = YesPlease
        SHELL_PATH=/usr/gnu/bin/bash
        NEEDS_LIBGEN = YesPlease
-       NEEDS_LIBICONV = YesPlease
 endif
 ifeq ($(uname_S),HP-UX)
        NO_IPV6=YesPlease
@@ -1480,7 +1481,7 @@ endif
 ifndef NO_PYTHON
        $(QUIET_SUBDIR0)git_remote_helpers $(QUIET_SUBDIR1) PYTHON_PATH='$(PYTHON_PATH_SQ)' prefix='$(prefix_SQ)' all
 endif
-       $(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1)
+       $(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1) SHELL_PATH='$(SHELL_PATH_SQ)' PERL_PATH='$(PERL_PATH_SQ)'
 
 please_set_SHELL_PATH_to_a_more_modern_shell:
        @$$(:)
@@ -1562,18 +1563,29 @@ gitweb:
        $(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) all
 
 ifdef JSMIN
-OTHER_PROGRAMS += gitweb/gitweb.cgi   gitweb/gitweb.min.js
-gitweb/gitweb.cgi: gitweb/gitweb.perl gitweb/gitweb.min.js
+GITWEB_PROGRAMS += gitweb/gitweb.min.js
+GITWEB_JS = gitweb/gitweb.min.js
 else
-OTHER_PROGRAMS += gitweb/gitweb.cgi
-gitweb/gitweb.cgi: gitweb/gitweb.perl
+GITWEB_JS = gitweb/gitweb.js
 endif
+ifdef CSSMIN
+GITWEB_PROGRAMS += gitweb/gitweb.min.css
+GITWEB_CSS = gitweb/gitweb.min.css
+else
+GITWEB_CSS = gitweb/gitweb.css
+endif
+OTHER_PROGRAMS +=  gitweb/gitweb.cgi  $(GITWEB_PROGRAMS)
+gitweb/gitweb.cgi: gitweb/gitweb.perl $(GITWEB_PROGRAMS)
        $(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) $(patsubst gitweb/%,%,$@)
 
 ifdef JSMIN
 gitweb/gitweb.min.js: gitweb/gitweb.js
        $(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) $(patsubst gitweb/%,%,$@)
 endif # JSMIN
+ifdef CSSMIN
+gitweb/gitweb.min.css: gitweb/gitweb.css
+       $(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) $(patsubst gitweb/%,%,$@)
+endif # CSSMIN
 
 
 git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css gitweb/gitweb.js
@@ -1583,11 +1595,13 @@ git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css gitweb/gitweb.
            -e 's/@@NO_CURL@@/$(NO_CURL)/g' \
            -e '/@@GITWEB_CGI@@/r gitweb/gitweb.cgi' \
            -e '/@@GITWEB_CGI@@/d' \
-           -e '/@@GITWEB_CSS@@/r gitweb/gitweb.css' \
+           -e '/@@GITWEB_CSS@@/r $(GITWEB_CSS)' \
            -e '/@@GITWEB_CSS@@/d' \
-           -e '/@@GITWEB_JS@@/r gitweb/gitweb.js' \
+           -e '/@@GITWEB_JS@@/r $(GITWEB_JS)' \
            -e '/@@GITWEB_JS@@/d' \
            -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \
+            -e 's|@@GITWEB_CSS_NAME@@|$(GITWEB_CSS)|' \
+            -e 's|@@GITWEB_JS_NAME@@|$(GITWEB_JS)|' \
            $@.sh > $@+ && \
        chmod +x $@+ && \
        mv $@+ $@
@@ -1613,9 +1627,8 @@ $(patsubst %.py,%,$(SCRIPT_PYTHON)): % : %.py
            -e '}' \
            -e 's|^import sys.*|&; \\\
                   import os; \\\
-                  sys.path[0] = os.environ.has_key("GITPYTHONLIB") and \\\
-                                os.environ["GITPYTHONLIB"] or \\\
-                                "@@INSTLIBDIR@@"|' \
+                  sys.path.insert(0, os.getenv("GITPYTHONLIB",\
+                                               "@@INSTLIBDIR@@"));|' \
            -e 's|@@INSTLIBDIR@@|'"$$INSTLIBDIR"'|g' \
            $@.py >$@+ && \
        chmod +x $@+ && \
@@ -2087,7 +2100,7 @@ clean:
        $(RM) $(htmldocs).tar.gz $(manpages).tar.gz
        $(MAKE) -C Documentation/ clean
 ifndef NO_PERL
-       $(RM) gitweb/gitweb.cgi
+       $(MAKE) -C gitweb clean
        $(MAKE) -C perl clean
 endif
 ifndef NO_PYTHON
index 9e1f63ed8dbe8b087f99292880059642d9744697..2ab42aaf4da38b4ea45ef7f0a0f6b807313d4a22 100644 (file)
--- a/branch.c
+++ b/branch.c
@@ -198,7 +198,7 @@ void create_branch(const char *head,
                log_all_ref_updates = 1;
 
        if (forcing)
-               snprintf(msg, sizeof msg, "branch: Reset from %s",
+               snprintf(msg, sizeof msg, "branch: Reset to %s",
                         start_name);
        else if (!dont_change_ref)
                snprintf(msg, sizeof msg, "branch: Created from %s",
index 7ca90472c10eed8535e76b1e0ec25c92af7cff05..660cf92538ce125a83d566f3ba2bb7f2c24f5671 100644 (file)
@@ -2824,11 +2824,8 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
                if (stat_ret < 0) {
                        struct checkout costate;
                        /* checkout */
+                       memset(&costate, 0, sizeof(costate));
                        costate.base_dir = "";
-                       costate.base_dir_len = 0;
-                       costate.force = 0;
-                       costate.quiet = 0;
-                       costate.not_new = 0;
                        costate.refresh_cache = 1;
                        if (checkout_entry(*ce, &costate, NULL) ||
                            lstat(old_name, st))
@@ -3144,11 +3141,7 @@ static void remove_file(struct patch *patch, int rmdir_empty)
                        die("unable to remove %s from index", patch->old_name);
        }
        if (!cached) {
-               if (S_ISGITLINK(patch->old_mode)) {
-                       if (rmdir(patch->old_name))
-                               warning("unable to remove submodule %s",
-                                       patch->old_name);
-               } else if (!unlink_or_warn(patch->old_name) && rmdir_empty) {
+               if (!remove_or_warn(patch->old_mode, patch->old_name) && rmdir_empty) {
                        remove_path(patch->old_name);
                }
        }
index acefaaf41a4e26e45225f6d228734c93c8f2b23c..88b1f43e05e64f0e8dcd6dd0461bbebd6fab1e25 100644 (file)
@@ -149,7 +149,7 @@ static int checkout_merged(int pos, struct checkout *state)
        read_mmblob(&ours, active_cache[pos+1]->sha1);
        read_mmblob(&theirs, active_cache[pos+2]->sha1);
 
-       status = ll_merge(&result_buf, path, &ancestor,
+       status = ll_merge(&result_buf, path, &ancestor, "base",
                          &ours, "ours", &theirs, "theirs", 0);
        free(ancestor.ptr);
        free(ours.ptr);
@@ -439,6 +439,7 @@ static int merge_working_tree(struct checkout_opts *opts,
                        ret = reset_tree(new->commit->tree, opts, 1);
                        if (ret)
                                return ret;
+                       o.ancestor = old->name;
                        o.branch1 = new->name;
                        o.branch2 = "local";
                        merge_trees(&o, new->commit->tree, work,
index 05f8fb4771b1ef07030338a6fd38dc7cb3bc1d1d..0bedde41f077f7c6e6106b144854c208ed4f6076 100644 (file)
@@ -302,6 +302,8 @@ static const struct ref *clone_local(const char *src_repo,
        transport = transport_get(remote, src_repo);
        ret = transport_get_remote_refs(transport);
        transport_disconnect(transport);
+       if (0 <= option_verbosity)
+               printf("done.\n");
        return ret;
 }
 
@@ -461,7 +463,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
                die("could not create leading directories of '%s'", git_dir);
        set_git_dir(make_absolute_path(git_dir));
 
-       init_db(option_template, (option_verbosity < 0) ? INIT_DB_QUIET : 0);
+       if (0 <= option_verbosity)
+               printf("Cloning into %s...\n", get_git_dir());
+       init_db(option_template, INIT_DB_QUIET);
 
        /*
         * At this point, the config exists, so we do not need the
index 8dd104ee0b247f5536d02d54a932acfcbaec603b..c5ab683d5b66d5ad85f53d13d6df71e29cd9234d 100644 (file)
@@ -307,7 +307,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int
         * (B) on failure, rollback the real index.
         */
        if (all || (also && pathspec && *pathspec)) {
-               int fd = hold_locked_index(&index_lock, 1);
+               fd = hold_locked_index(&index_lock, 1);
                add_files_to_cache(also ? prefix : NULL, pathspec, 0);
                refresh_cache_or_die(refresh_flags);
                if (write_cache(fd, active_cache, active_nr) ||
@@ -322,8 +322,8 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int
         *
         * (1) return the name of the real index file.
         *
-        * The caller should run hooks on the real index, and run
-        * hooks on the real index, and create commit from the_index.
+        * The caller should run hooks on the real index,
+        * and create commit from the_index.
         * We still need to refresh the index here.
         */
        if (!pathspec || !*pathspec) {
index 957be9f9269c657fb094b1b3daa4f309c1324ae0..8470850415c14cad8ceeca9f6baef46ab6feabc3 100644 (file)
 #include "transport.h"
 
 static const char * const builtin_fetch_usage[] = {
-       "git fetch [options] [<repository> <refspec>...]",
-       "git fetch [options] <group>",
-       "git fetch --multiple [options] [<repository> | <group>]...",
-       "git fetch --all [options]",
+       "git fetch [<options>] [<repository> [<refspec>...]]",
+       "git fetch [<options>] <group>",
+       "git fetch --multiple [<options>] [<repository> | <group>]...",
+       "git fetch --all [<options>]",
        NULL
 };
 
index 9d524000b5ba4d9c7566edd5756b68d728ec362b..379a03131fbd84fb2b45a6b05e62daf82b7e4947 100644 (file)
@@ -4,6 +4,7 @@
 #include "diff.h"
 #include "revision.h"
 #include "tag.h"
+#include "string-list.h"
 
 static const char * const fmt_merge_msg_usage[] = {
        "git fmt-merge-msg [--log|--no-log] [--file <file>]",
@@ -24,58 +25,21 @@ static int fmt_merge_msg_config(const char *key, const char *value, void *cb)
        return 0;
 }
 
-struct list {
-       char **list;
-       void **payload;
-       unsigned nr, alloc;
+struct src_data {
+       struct string_list branch, tag, r_branch, generic;
+       int head_status;
 };
 
-static void append_to_list(struct list *list, char *value, void *payload)
-{
-       if (list->nr == list->alloc) {
-               list->alloc += 32;
-               list->list = xrealloc(list->list, sizeof(char *) * list->alloc);
-               list->payload = xrealloc(list->payload,
-                               sizeof(char *) * list->alloc);
-       }
-       list->payload[list->nr] = payload;
-       list->list[list->nr++] = value;
-}
-
-static int find_in_list(struct list *list, char *value)
-{
-       int i;
-
-       for (i = 0; i < list->nr; i++)
-               if (!strcmp(list->list[i], value))
-                       return i;
-
-       return -1;
-}
-
-static void free_list(struct list *list)
+void init_src_data(struct src_data *data)
 {
-       int i;
-
-       if (list->alloc == 0)
-               return;
-
-       for (i = 0; i < list->nr; i++) {
-               free(list->list[i]);
-               free(list->payload[i]);
-       }
-       free(list->list);
-       free(list->payload);
-       list->nr = list->alloc = 0;
+       data->branch.strdup_strings = 1;
+       data->tag.strdup_strings = 1;
+       data->r_branch.strdup_strings = 1;
+       data->generic.strdup_strings = 1;
 }
 
-struct src_data {
-       struct list branch, tag, r_branch, generic;
-       int head_status;
-};
-
-static struct list srcs = { NULL, NULL, 0, 0};
-static struct list origins = { NULL, NULL, 0, 0};
+static struct string_list srcs = { NULL, 0, 0, 1 };
+static struct string_list origins = { NULL, 0, 0, 1 };
 
 static int handle_line(char *line)
 {
@@ -83,6 +47,7 @@ static int handle_line(char *line)
        unsigned char *sha1;
        char *src, *origin;
        struct src_data *src_data;
+       struct string_list_item *item;
        int pulling_head = 0;
 
        if (len < 43 || line[40] != '\t')
@@ -115,64 +80,62 @@ static int handle_line(char *line)
                pulling_head = 1;
        }
 
-       i = find_in_list(&srcs, src);
-       if (i < 0) {
-               i = srcs.nr;
-               append_to_list(&srcs, xstrdup(src),
-                               xcalloc(1, sizeof(struct src_data)));
+       item = unsorted_string_list_lookup(&srcs, src);
+       if (!item) {
+               item = string_list_append(src, &srcs);
+               item->util = xcalloc(1, sizeof(struct src_data));
+               init_src_data(item->util);
        }
-       src_data = srcs.payload[i];
+       src_data = item->util;
 
        if (pulling_head) {
-               origin = xstrdup(src);
+               origin = src;
                src_data->head_status |= 1;
        } else if (!prefixcmp(line, "branch ")) {
-               origin = xstrdup(line + 7);
-               append_to_list(&src_data->branch, origin, NULL);
+               origin = line + 7;
+               string_list_append(origin, &src_data->branch);
                src_data->head_status |= 2;
        } else if (!prefixcmp(line, "tag ")) {
                origin = line;
-               append_to_list(&src_data->tag, xstrdup(origin + 4), NULL);
+               string_list_append(origin + 4, &src_data->tag);
                src_data->head_status |= 2;
        } else if (!prefixcmp(line, "remote branch ")) {
-               origin = xstrdup(line + 14);
-               append_to_list(&src_data->r_branch, origin, NULL);
+               origin = line + 14;
+               string_list_append(origin, &src_data->r_branch);
                src_data->head_status |= 2;
        } else {
-               origin = xstrdup(src);
-               append_to_list(&src_data->generic, xstrdup(line), NULL);
+               origin = src;
+               string_list_append(line, &src_data->generic);
                src_data->head_status |= 2;
        }
 
        if (!strcmp(".", src) || !strcmp(src, origin)) {
                int len = strlen(origin);
-               if (origin[0] == '\'' && origin[len - 1] == '\'') {
+               if (origin[0] == '\'' && origin[len - 1] == '\'')
                        origin = xmemdupz(origin + 1, len - 2);
-               } else {
-                       origin = xstrdup(origin);
-               }
        } else {
                char *new_origin = xmalloc(strlen(origin) + strlen(src) + 5);
                sprintf(new_origin, "%s of %s", origin, src);
                origin = new_origin;
        }
-       append_to_list(&origins, origin, sha1);
+       string_list_append(origin, &origins)->util = sha1;
        return 0;
 }
 
 static void print_joined(const char *singular, const char *plural,
-               struct list *list, struct strbuf *out)
+               struct string_list *list, struct strbuf *out)
 {
        if (list->nr == 0)
                return;
        if (list->nr == 1) {
-               strbuf_addf(out, "%s%s", singular, list->list[0]);
+               strbuf_addf(out, "%s%s", singular, list->items[0].string);
        } else {
                int i;
                strbuf_addstr(out, plural);
                for (i = 0; i < list->nr - 1; i++)
-                       strbuf_addf(out, "%s%s", i > 0 ? ", " : "", list->list[i]);
-               strbuf_addf(out, " and %s", list->list[list->nr - 1]);
+                       strbuf_addf(out, "%s%s", i > 0 ? ", " : "",
+                                   list->items[i].string);
+               strbuf_addf(out, " and %s", list->items[list->nr - 1].string);
        }
 }
 
@@ -183,8 +146,9 @@ static void shortlog(const char *name, unsigned char *sha1,
        int i, count = 0;
        struct commit *commit;
        struct object *branch;
-       struct list subjects = { NULL, NULL, 0, 0 };
+       struct string_list subjects = { NULL, 0, 0, 1 };
        int flags = UNINTERESTING | TREESAME | SEEN | SHOWN | ADDED;
+       struct strbuf sb = STRBUF_INIT;
 
        branch = deref_tag(parse_object(sha1), sha1_to_hex(sha1), 40);
        if (!branch || branch->type != OBJ_COMMIT)
@@ -198,7 +162,7 @@ static void shortlog(const char *name, unsigned char *sha1,
        if (prepare_revision_walk(rev))
                die("revision walk setup failed");
        while ((commit = get_revision(rev)) != NULL) {
-               char *oneline, *bol, *eol;
+               struct pretty_print_context ctx = {0};
 
                /* ignore merges */
                if (commit->parents && commit->parents->next)
@@ -208,30 +172,14 @@ static void shortlog(const char *name, unsigned char *sha1,
                if (subjects.nr > limit)
                        continue;
 
-               bol = strstr(commit->buffer, "\n\n");
-               if (bol) {
-                       unsigned char c;
-                       do {
-                               c = *++bol;
-                       } while (isspace(c));
-                       if (!c)
-                               bol = NULL;
-               }
-
-               if (!bol) {
-                       append_to_list(&subjects, xstrdup(sha1_to_hex(
-                                                       commit->object.sha1)),
-                                       NULL);
-                       continue;
-               }
+               format_commit_message(commit, "%s", &sb, &ctx);
+               strbuf_ltrim(&sb);
 
-               eol = strchr(bol, '\n');
-               if (eol) {
-                       oneline = xmemdupz(bol, eol - bol);
-               } else {
-                       oneline = xstrdup(bol);
-               }
-               append_to_list(&subjects, oneline, NULL);
+               if (!sb.len)
+                       string_list_append(sha1_to_hex(commit->object.sha1),
+                                          &subjects);
+               else
+                       string_list_append(strbuf_detach(&sb, NULL), &subjects);
        }
 
        if (count > limit)
@@ -243,7 +191,7 @@ static void shortlog(const char *name, unsigned char *sha1,
                if (i >= limit)
                        strbuf_addf(out, "  ...\n");
                else
-                       strbuf_addf(out, "  %s\n", subjects.list[i]);
+                       strbuf_addf(out, "  %s\n", subjects.items[i].string);
 
        clear_commit_marks((struct commit *)branch, flags);
        clear_commit_marks(head, flags);
@@ -251,7 +199,7 @@ static void shortlog(const char *name, unsigned char *sha1,
        rev->commits = NULL;
        rev->pending.nr = 0;
 
-       free_list(&subjects);
+       string_list_clear(&subjects, 0);
 }
 
 int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
@@ -281,16 +229,19 @@ int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
                        die ("Error in line %d: %.*s", i, len, p);
        }
 
+       if (!srcs.nr)
+               return 0;
+
        strbuf_addstr(out, "Merge ");
        for (i = 0; i < srcs.nr; i++) {
-               struct src_data *src_data = srcs.payload[i];
+               struct src_data *src_data = srcs.items[i].util;
                const char *subsep = "";
 
                strbuf_addstr(out, sep);
                sep = "; ";
 
                if (src_data->head_status == 1) {
-                       strbuf_addstr(out, srcs.list[i]);
+                       strbuf_addstr(out, srcs.items[i].string);
                        continue;
                }
                if (src_data->head_status == 3) {
@@ -319,8 +270,8 @@ int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
                        print_joined("commit ", "commits ", &src_data->generic,
                                        out);
                }
-               if (strcmp(".", srcs.list[i]))
-                       strbuf_addf(out, " of %s", srcs.list[i]);
+               if (strcmp(".", srcs.items[i].string))
+                       strbuf_addf(out, " of %s", srcs.items[i].string);
        }
 
        if (!strcmp("master", current_branch))
@@ -339,7 +290,7 @@ int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
                rev.limited = 1;
 
                for (i = 0; i < origins.nr; i++)
-                       shortlog(origins.list[i], origins.payload[i],
+                       shortlog(origins.items[i].string, origins.items[i].util,
                                        head, &rev, limit, out);
        }
        return 0;
@@ -350,7 +301,9 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
        const char *inpath = NULL;
        struct option options[] = {
                OPT_BOOLEAN(0, "log",     &merge_summary, "populate log with the shortlog"),
-               OPT_BOOLEAN(0, "summary", &merge_summary, "alias for --log"),
+               { OPTION_BOOLEAN, 0, "summary", &merge_summary, NULL,
+                 "alias for --log (deprecated)",
+                 PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
                OPT_FILENAME('F', "file", &inpath, "file to read from"),
                OPT_END()
        };
index 9d30ddb28df16f834c9fbb3bf6ba8cc172a502b3..8e928e217041a159f4a962f0883d740aa84536d7 100644 (file)
@@ -96,6 +96,9 @@ static pthread_cond_t cond_write;
 /* Signalled when we are finished with everything. */
 static pthread_cond_t cond_result;
 
+static int print_hunk_marks_between_files;
+static int printed_something;
+
 static void add_work(enum work_type type, char *name, void *id)
 {
        grep_lock();
@@ -159,7 +162,12 @@ static void work_done(struct work_item *w)
        for(; todo[todo_done].done && todo_done != todo_start;
            todo_done = (todo_done+1) % ARRAY_SIZE(todo)) {
                w = &todo[todo_done];
-               write_or_die(1, w->out.buf, w->out.len);
+               if (w->out.len) {
+                       if (print_hunk_marks_between_files && printed_something)
+                               write_or_die(1, "--\n", 3);
+                       write_or_die(1, w->out.buf, w->out.len);
+                       printed_something = 1;
+               }
                free(w->name);
                free(w->identifier);
        }
@@ -946,8 +954,11 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
        if (online_cpus() == 1 || !grep_threads_ok(&opt))
                use_threads = 0;
 
-       if (use_threads)
+       if (use_threads) {
+               if (opt.pre_context || opt.post_context)
+                       print_hunk_marks_between_files = 1;
                start_threads(&opt);
+       }
 #else
        use_threads = 0;
 #endif
index b4cf8c53e0ebbee65a0e4bc0ac1afd1173d1b8e8..03d0cd2f47016b59994a75c11403061fcad8a165 100644 (file)
@@ -11,7 +11,7 @@
 #include "exec_cmd.h"
 
 static const char index_pack_usage[] =
-"git index-pack [-v] [-o <index-file>] [{ ---keep | --keep=<msg> }] [--strict] { <pack-file> | --stdin [--fix-thin] [<pack-file>] }";
+"git index-pack [-v] [-o <index-file>] [{ --keep | --keep=<msg> }] [--strict] { <pack-file> | --stdin [--fix-thin] [<pack-file>] }";
 
 struct object_entry
 {
index 542ecc708bdb830bcdbbd48e3fb3d21021119630..6208703c061abb868201073795cf516bf81b2602 100644 (file)
@@ -36,6 +36,7 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
 {
        int i;
        int decoration_style = 0;
+       struct userformat_want w;
 
        rev->abbrev = DEFAULT_ABBREV;
        rev->commit_format = CMIT_FMT_DEFAULT;
@@ -58,7 +59,10 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
                usage(builtin_log_usage);
        argc = setup_revisions(argc, argv, rev, opt);
 
-       if (!rev->show_notes_given && !rev->pretty_given)
+       memset(&w, 0, sizeof(w));
+       userformat_find_requirements(NULL, &w);
+
+       if (!rev->show_notes_given && (!rev->pretty_given || w.notes))
                rev->show_notes = 1;
        if (rev->show_notes)
                init_display_notes(&rev->notes_opt);
@@ -1303,8 +1307,11 @@ static int add_pending_commit(const char *arg, struct rev_info *revs, int flags)
        return -1;
 }
 
-static const char cherry_usage[] =
-"git cherry [-v] [<upstream> [<head> [<limit>]]]";
+static const char * const cherry_usage[] = {
+       "git cherry [-v] [<upstream> [<head> [<limit>]]]",
+       NULL
+};
+
 int cmd_cherry(int argc, const char **argv, const char *prefix)
 {
        struct rev_info revs;
@@ -1315,26 +1322,25 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
        const char *upstream;
        const char *head = "HEAD";
        const char *limit = NULL;
-       int verbose = 0;
+       int verbose = 0, abbrev = 0;
 
-       if (argc > 1 && !strcmp(argv[1], "-v")) {
-               verbose = 1;
-               argc--;
-               argv++;
-       }
+       struct option options[] = {
+               OPT__ABBREV(&abbrev),
+               OPT__VERBOSE(&verbose),
+               OPT_END()
+       };
 
-       if (argc > 1 && !strcmp(argv[1], "-h"))
-               usage(cherry_usage);
+       argc = parse_options(argc, argv, prefix, options, cherry_usage, 0);
 
        switch (argc) {
-       case 4:
-               limit = argv[3];
-               /* FALLTHROUGH */
        case 3:
-               head = argv[2];
+               limit = argv[2];
                /* FALLTHROUGH */
        case 2:
-               upstream = argv[1];
+               head = argv[1];
+               /* FALLTHROUGH */
+       case 1:
+               upstream = argv[0];
                break;
        default:
                current_branch = branch_get(NULL);
@@ -1344,7 +1350,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
                        fprintf(stderr, "Could not find a tracked"
                                        " remote branch, please"
                                        " specify <upstream> manually.\n");
-                       usage(cherry_usage);
+                       usage_with_options(cherry_usage, options);
                }
 
                upstream = current_branch->merge[0]->dst;
@@ -1397,12 +1403,13 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
                        pretty_print_commit(CMIT_FMT_ONELINE, commit,
                                            &buf, &ctx);
                        printf("%c %s %s\n", sign,
-                              sha1_to_hex(commit->object.sha1), buf.buf);
+                              find_unique_abbrev(commit->object.sha1, abbrev),
+                              buf.buf);
                        strbuf_release(&buf);
                }
                else {
                        printf("%c %s\n", sign,
-                              sha1_to_hex(commit->object.sha1));
+                              find_unique_abbrev(commit->object.sha1, abbrev));
                }
 
                list = list->next;
index b065061392718e4250d2c52dc3d53a0c1c7938e9..c0fbcdcf4f3447c29c4058907ea2e25fa6d225a6 100644 (file)
@@ -153,8 +153,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce)
                printf("%s%06o %s %d\t",
                       tag,
                       ce->ce_mode,
-                      abbrev ? find_unique_abbrev(ce->sha1,abbrev)
-                               : sha1_to_hex(ce->sha1),
+                      find_unique_abbrev(ce->sha1,abbrev),
                       ce_stage(ce));
        }
        write_name_quoted(ce->name + offset, stdout, line_terminator);
@@ -176,9 +175,7 @@ static int show_one_ru(struct string_list_item *item, void *cbdata)
                if (!ui->mode[i])
                        continue;
                printf("%s%06o %s %d\t", tag_resolve_undo, ui->mode[i],
-                      abbrev
-                      ? find_unique_abbrev(ui->sha1[i], abbrev)
-                      : sha1_to_hex(ui->sha1[i]),
+                      find_unique_abbrev(ui->sha1[i], abbrev),
                       i + 1);
                write_name_quoted(path + offset, stdout, line_terminator);
        }
index 4484185afc4c144bc0d88d9c3832cbeb1515841b..dc86b0d9a997f98ad43ca2897055a92b8a3eb7d0 100644 (file)
@@ -103,13 +103,11 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
                        } else
                                strcpy(size_text, "-");
                        printf("%06o %s %s %7s\t", mode, type,
-                              abbrev ? find_unique_abbrev(sha1, abbrev)
-                                     : sha1_to_hex(sha1),
+                              find_unique_abbrev(sha1, abbrev),
                               size_text);
                } else
                        printf("%06o %s %s\t", mode, type,
-                              abbrev ? find_unique_abbrev(sha1, abbrev)
-                                     : sha1_to_hex(sha1));
+                              find_unique_abbrev(sha1, abbrev));
        }
        write_name_quotedpfx(base + chomp_prefix, baselen - chomp_prefix,
                          pathname, stdout, line_termination);
index ce2ef6bede40fde8823336bc85762bd3e7cd4760..4a9729b9b388a1e589e9250d8157e723c68140de 100644 (file)
@@ -746,7 +746,8 @@ static int is_scissors_line(const struct strbuf *line)
                        continue;
                }
                if (i + 1 < len &&
-                   (!memcmp(buf + i, ">8", 2) || !memcmp(buf + i, "8<", 2))) {
+                   (!memcmp(buf + i, ">8", 2) || !memcmp(buf + i, "8<", 2) ||
+                    !memcmp(buf + i, ">%", 2) || !memcmp(buf + i, "%<", 2))) {
                        in_perforation = 1;
                        perforation += 2;
                        scissors += 2;
index 69cc683332a04ddc6959fcef3d2853ccfb2860b8..610849a6533c6fd2d3d2e8d3f8d233757174aabd 100644 (file)
@@ -77,8 +77,10 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
                                        argv[i]);
        }
 
-       ret = xdl_merge(mmfs + 1, mmfs + 0, names[0], mmfs + 2, names[2],
-                       &xmp, &result);
+       xmp.ancestor = names[1];
+       xmp.file1 = names[0];
+       xmp.file2 = names[2];
+       ret = xdl_merge(mmfs + 1, mmfs + 0, mmfs + 2, &xmp, &result);
 
        for (i = 0; i < 3; i++)
                free(mmfs[i].ptr);
index 62957ededdf72b93f088586f5d577ef8d38a7f6c..f4358b9d230f6d8d7a9a67fdfbc60279c5ec71ee 100644 (file)
@@ -10,7 +10,7 @@
 #include "parse-options.h"
 
 static const char * const push_usage[] = {
-       "git push [<options>] [<repository> <refspec>...]",
+       "git push [<options>] [<repository> [<refspec>...]]",
        NULL,
 };
 
index 64e45bd8137bef2b6cfe1f8a3da79e2ff6f8fc47..bd7880dc04830253daae932ba534f02db85f6d2a 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 static const char reflog_expire_usage[] =
-"git reflog (show|expire) [--verbose] [--dry-run] [--stale-fix] [--expire=<time>] [--expire-unreachable=<time>] [--all] <refs>...";
+"git reflog expire [--verbose] [--dry-run] [--stale-fix] [--expire=<time>] [--expire-unreachable=<time>] [--all] <refs>...";
 static const char reflog_delete_usage[] =
 "git reflog delete [--verbose] [--dry-run] [--rewrite] [--updateref] <refs>...";
 
index 5679170e82ed644d4c3eb4f71f26aa0ac9acce24..51ceb19d88918445c90eccc37f1fe5f90cedd385 100644 (file)
@@ -133,9 +133,12 @@ static void show_commit(struct commit *commit, void *data)
                                 */
                                if (graph_show_remainder(revs->graph))
                                        putchar('\n');
+                               if (revs->commit_format == CMIT_FMT_ONELINE)
+                                       putchar('\n');
                        }
                } else {
-                       if (buf.len)
+                       if (revs->commit_format != CMIT_FMT_USERFORMAT ||
+                           buf.len)
                                printf("%s%c", buf.buf, info->hdr_termination);
                }
                strbuf_release(&buf);
@@ -313,7 +316,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 
        git_config(git_default_config, NULL);
        init_revisions(&revs, prefix);
-       revs.abbrev = 0;
+       revs.abbrev = DEFAULT_ABBREV;
        revs.commit_format = CMIT_FMT_UNSPECIFIED;
        argc = setup_revisions(argc, argv, &revs, NULL);
 
index 9a3c14c329713f16d14147b81a4b8031028a4f82..7d68ef714eee5011d82952ca1829016c90827f61 100644 (file)
@@ -46,6 +46,8 @@ static const char *me;
 
 #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
 
+static char *get_encoding(const char *message);
+
 static void parse_args(int argc, const char **argv)
 {
        const char * const * usage_str =
@@ -85,33 +87,69 @@ static void parse_args(int argc, const char **argv)
                exit(1);
 }
 
-static char *get_oneline(const char *message)
+struct commit_message {
+       char *parent_label;
+       const char *label;
+       const char *subject;
+       char *reencoded_message;
+       const char *message;
+};
+
+static int get_message(const char *raw_message, struct commit_message *out)
 {
-       char *result;
-       const char *p = message, *abbrev, *eol;
+       const char *encoding;
+       const char *p, *abbrev, *eol;
+       char *q;
        int abbrev_len, oneline_len;
 
-       if (!p)
-               die ("Could not read commit message of %s",
-                               sha1_to_hex(commit->object.sha1));
+       if (!raw_message)
+               return -1;
+       encoding = get_encoding(raw_message);
+       if (!encoding)
+               encoding = "UTF-8";
+       if (!git_commit_encoding)
+               git_commit_encoding = "UTF-8";
+
+       out->reencoded_message = NULL;
+       out->message = raw_message;
+       if (strcmp(encoding, git_commit_encoding))
+               out->reencoded_message = reencode_string(raw_message,
+                                       git_commit_encoding, encoding);
+       if (out->reencoded_message)
+               out->message = out->reencoded_message;
+
+       abbrev = find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV);
+       abbrev_len = strlen(abbrev);
+
+       /* Find beginning and end of commit subject. */
+       p = out->message;
        while (*p && (*p != '\n' || p[1] != '\n'))
                p++;
-
        if (*p) {
                p += 2;
                for (eol = p + 1; *eol && *eol != '\n'; eol++)
                        ; /* do nothing */
        } else
                eol = p;
-       abbrev = find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV);
-       abbrev_len = strlen(abbrev);
        oneline_len = eol - p;
-       result = xmalloc(abbrev_len + 5 + oneline_len);
-       memcpy(result, abbrev, abbrev_len);
-       memcpy(result + abbrev_len, "... ", 4);
-       memcpy(result + abbrev_len + 4, p, oneline_len);
-       result[abbrev_len + 4 + oneline_len] = '\0';
-       return result;
+
+       out->parent_label = xmalloc(strlen("parent of ") + abbrev_len +
+                             strlen("... ") + oneline_len + 1);
+       q = out->parent_label;
+       q = mempcpy(q, "parent of ", strlen("parent of "));
+       out->label = q;
+       q = mempcpy(q, abbrev, abbrev_len);
+       q = mempcpy(q, "... ", strlen("... "));
+       out->subject = q;
+       q = mempcpy(q, p, oneline_len);
+       *q = '\0';
+       return 0;
+}
+
+static void free_message(struct commit_message *msg)
+{
+       free(msg->parent_label);
+       free(msg->reencoded_message);
 }
 
 static char *get_encoding(const char *message)
@@ -271,9 +309,9 @@ static int revert_or_cherry_pick(int argc, const char **argv)
 {
        unsigned char head[20];
        struct commit *base, *next, *parent;
+       const char *base_label, *next_label;
        int i, index_fd, clean;
-       char *oneline, *reencoded_message = NULL;
-       const char *message, *encoding;
+       struct commit_message msg = { NULL, NULL, NULL, NULL, NULL };
        char *defmsg = NULL;
        struct merge_options o;
        struct tree *result, *next_tree, *base_tree, *head_tree;
@@ -349,14 +387,14 @@ static int revert_or_cherry_pick(int argc, const char **argv)
        if (allow_ff && !hashcmp(parent->object.sha1, head))
                return fast_forward_to(commit->object.sha1, head);
 
-       if (!(message = commit->buffer))
-               die ("Cannot get commit message for %s",
-                               sha1_to_hex(commit->object.sha1));
-
        if (parent && parse_commit(parent) < 0)
                die("%s: cannot parse parent commit %s",
                    me, sha1_to_hex(parent->object.sha1));
 
+       if (get_message(commit->buffer, &msg) != 0)
+               die("Cannot get commit message for %s",
+                               sha1_to_hex(commit->object.sha1));
+
        /*
         * "commit" is an existing commit.  We would want to apply
         * the difference it introduces since its first parent "prev"
@@ -368,26 +406,15 @@ static int revert_or_cherry_pick(int argc, const char **argv)
        msg_fd = hold_lock_file_for_update(&msg_file, defmsg,
                                           LOCK_DIE_ON_ERROR);
 
-       encoding = get_encoding(message);
-       if (!encoding)
-               encoding = "UTF-8";
-       if (!git_commit_encoding)
-               git_commit_encoding = "UTF-8";
-       if ((reencoded_message = reencode_string(message,
-                                       git_commit_encoding, encoding)))
-               message = reencoded_message;
-
-       oneline = get_oneline(message);
-
        index_fd = hold_locked_index(&index_lock, 1);
 
        if (action == REVERT) {
-               char *oneline_body = strchr(oneline, ' ');
-
                base = commit;
+               base_label = msg.label;
                next = parent;
+               next_label = msg.parent_label;
                add_to_msg("Revert \"");
-               add_to_msg(oneline_body + 1);
+               add_to_msg(msg.subject);
                add_to_msg("\"\n\nThis reverts commit ");
                add_to_msg(sha1_to_hex(commit->object.sha1));
 
@@ -398,9 +425,11 @@ static int revert_or_cherry_pick(int argc, const char **argv)
                add_to_msg(".\n");
        } else {
                base = parent;
+               base_label = msg.parent_label;
                next = commit;
-               set_author_ident_env(message);
-               add_message_to_msg(message);
+               next_label = msg.label;
+               set_author_ident_env(msg.message);
+               add_message_to_msg(msg.message);
                if (no_replay) {
                        add_to_msg("(cherry picked from commit ");
                        add_to_msg(sha1_to_hex(commit->object.sha1));
@@ -410,8 +439,9 @@ static int revert_or_cherry_pick(int argc, const char **argv)
 
        read_cache();
        init_merge_options(&o);
+       o.ancestor = base ? base_label : "(empty tree)";
        o.branch1 = "HEAD";
-       o.branch2 = oneline;
+       o.branch2 = next ? next_label : "(empty tree)";
 
        head_tree = parse_tree_indirect(head);
        next_tree = next ? next->tree : empty_tree();
@@ -475,7 +505,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)
                args[i] = NULL;
                return execv_git_cmd(args);
        }
-       free(reencoded_message);
+       free_message(&msg);
        free(defmsg);
 
        return 0;
index 4ef1c4f508b0261e725c360e96f2b8cbed50e9ce..d311491e492787ae50aa172f51629abea53eec19 100644 (file)
@@ -147,11 +147,11 @@ static int delete_tag(const char *name, const char *ref,
 static int verify_tag(const char *name, const char *ref,
                                const unsigned char *sha1)
 {
-       const char *argv_verify_tag[] = {"git-verify-tag",
+       const char *argv_verify_tag[] = {"verify-tag",
                                        "-v", "SHA1_HEX", NULL};
        argv_verify_tag[2] = sha1_to_hex(sha1);
 
-       if (run_command_v_opt(argv_verify_tag, 0))
+       if (run_command_v_opt(argv_verify_tag, RUN_GIT_CMD))
                return error("could not verify the tag '%s'", name);
        return 0;
 }
index 61626912e3bca2571b41fd1256067470dc170cc1..7557136c820a10570e72f6870ecc7a45c4c7ce36 100644 (file)
@@ -204,18 +204,17 @@ static void consume_line(void *state_, char *line, unsigned long len)
 static void combine_diff(const unsigned char *parent, unsigned int mode,
                         mmfile_t *result_file,
                         struct sline *sline, unsigned int cnt, int n,
-                        int num_parent)
+                        int num_parent, int result_deleted)
 {
        unsigned int p_lno, lno;
        unsigned long nmask = (1UL << n);
        xpparam_t xpp;
        xdemitconf_t xecfg;
        mmfile_t parent_file;
-       xdemitcb_t ecb;
        struct combine_diff_state state;
        unsigned long sz;
 
-       if (!cnt)
+       if (result_deleted)
                return; /* result deleted */
 
        parent_file.ptr = grab_blob(parent, mode, &sz);
@@ -231,7 +230,7 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
        state.n = n;
 
        xdi_diff_outf(&parent_file, result_file, consume_line, &state,
-                     &xpp, &xecfg, &ecb);
+                     &xpp, &xecfg);
        free(parent_file.ptr);
 
        /* Assign line numbers for this parent.
@@ -517,7 +516,7 @@ static void show_line_to_eol(const char *line, int len, const char *reset)
 }
 
 static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
-                      int use_color)
+                      int use_color, int result_deleted)
 {
        unsigned long mark = (1UL<<num_parent);
        unsigned long no_pre_delete = (2UL<<num_parent);
@@ -530,7 +529,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
        const char *c_plain = diff_get_color(use_color, DIFF_PLAIN);
        const char *c_reset = diff_get_color(use_color, DIFF_RESET);
 
-       if (!cnt)
+       if (result_deleted)
                return; /* result deleted */
 
        while (1) {
@@ -687,6 +686,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
 {
        struct diff_options *opt = &rev->diffopt;
        unsigned long result_size, cnt, lno;
+       int result_deleted = 0;
        char *result, *cp;
        struct sline *sline; /* survived lines */
        int mode_differs = 0;
@@ -767,6 +767,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
                }
                else {
                deleted_file:
+                       result_deleted = 1;
                        result_size = 0;
                        elem->mode = 0;
                        result = xcalloc(1, 1);
@@ -823,7 +824,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
                        combine_diff(elem->parent[i].sha1,
                                     elem->parent[i].mode,
                                     &result_file, sline,
-                                    cnt, i, num_parent);
+                                    cnt, i, num_parent, result_deleted);
                if (elem->parent[i].mode != elem->mode)
                        mode_differs = 1;
        }
@@ -889,7 +890,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
                        dump_quoted_path("+++ ", b_prefix, elem->path,
                                         c_meta, c_reset);
                dump_sline(sline, cnt, num_parent,
-                          DIFF_OPT_TST(opt, COLOR_DIFF));
+                          DIFF_OPT_TST(opt, COLOR_DIFF), result_deleted);
        }
        free(result);
 
index 2b7fd89dfd047968aa3e7c927a6c20e506a976de..6ef88dcf45d6c5b2cd0f26397db2fc7b8859d581 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -74,11 +74,16 @@ struct pretty_print_context
        struct reflog_walk_info *reflog_info;
 };
 
+struct userformat_want {
+       unsigned notes:1;
+};
+
 extern int has_non_ascii(const char *text);
 struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
 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 void userformat_find_requirements(const char *fmt, struct userformat_want *w);
 extern void format_commit_message(const struct commit *commit,
                                  const char *format, struct strbuf *sb,
                                  const struct pretty_print_context *context);
index 30716903f5c3072588ddaae71f557f14d7806fde..f90a114b021d32c2ee1976bf51a82e87a81ea1cb 100644 (file)
@@ -650,6 +650,7 @@ static int env_compare(const void *a, const void *b)
 }
 
 static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env,
+                             const char *dir,
                              int prepend_cmd, int fhin, int fhout, int fherr)
 {
        STARTUPINFO si;
@@ -729,7 +730,7 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env,
 
        memset(&pi, 0, sizeof(pi));
        ret = CreateProcess(cmd, args.buf, NULL, NULL, TRUE, flags,
-               env ? envblk.buf : NULL, NULL, &si, &pi);
+               env ? envblk.buf : NULL, dir, &si, &pi);
 
        if (env)
                strbuf_release(&envblk);
@@ -746,10 +747,11 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env,
 static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env,
                           int prepend_cmd)
 {
-       return mingw_spawnve_fd(cmd, argv, env, prepend_cmd, 0, 1, 2);
+       return mingw_spawnve_fd(cmd, argv, env, NULL, prepend_cmd, 0, 1, 2);
 }
 
 pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env,
+                    const char *dir,
                     int fhin, int fhout, int fherr)
 {
        pid_t pid;
@@ -772,14 +774,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env,
                                pid = -1;
                        }
                        else {
-                               pid = mingw_spawnve_fd(iprog, argv, env, 1,
+                               pid = mingw_spawnve_fd(iprog, argv, env, dir, 1,
                                                       fhin, fhout, fherr);
                                free(iprog);
                        }
                        argv[0] = argv0;
                }
                else
-                       pid = mingw_spawnve_fd(prog, argv, env, 0,
+                       pid = mingw_spawnve_fd(prog, argv, env, dir, 0,
                                               fhin, fhout, fherr);
                free(prog);
        }
index e81e752ed2716ac9fb4a6847f97db84764694b4c..7c2ab64cb4eb7532c2495383ab0e7eefb329bcf9 100644 (file)
@@ -229,6 +229,7 @@ int mingw_utime(const char *file_name, const struct utimbuf *times);
 #define utime mingw_utime
 
 pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env,
+                    const char *dir,
                     int fhin, int fhout, int fherr);
 void mingw_execvp(const char *cmd, char *const *argv);
 #define execvp mingw_execvp
diff --git a/compat/vcbuild/include/termios.h b/compat/vcbuild/include/termios.h
new file mode 100644 (file)
index 0000000..0d8552a
--- /dev/null
@@ -0,0 +1 @@
+/* Intentionally empty file to support building git with MSVC */
index 914ae5759f6932c28ee39afec1e36d80c8e63cd9..f4d7372ef8d7b45f9810d5f8bc191c71622a71f2 100644 (file)
@@ -179,6 +179,26 @@ fi],
    AC_MSG_NOTICE([Will try -pthread then -lpthread to enable POSIX Threads.])
 ])
 
+# Define option to enable JavaScript minification
+AC_ARG_ENABLE([jsmin],
+[AS_HELP_STRING([--enable-jsmin=PATH],
+  [PATH is the name of a JavaScript minifier or the absolute path to one.])],
+[
+  JSMIN=$enableval;
+  AC_MSG_NOTICE([Setting JSMIN to '$JSMIN' to enable JavaScript minifying])
+  GIT_CONF_APPEND_LINE(JSMIN=$enableval);
+])
+
+# Define option to enable CSS minification
+AC_ARG_ENABLE([cssmin],
+[AS_HELP_STRING([--enable-cssmin=PATH],
+  [PATH is the name of a CSS minifier or the absolute path to one.])],
+[
+  CSSMIN=$enableval;
+  AC_MSG_NOTICE([Setting CSSMIN to '$CSSMIN' to enable CSS minifying])
+  GIT_CONF_APPEND_LINE(CSSMIN=$enableval);
+])
+
 ## Site configuration (override autodetection)
 ## --with-PACKAGE[=ARG] and --without-PACKAGE
 AC_MSG_NOTICE([CHECKS for site configuration])
diff --git a/contrib/ciabot/README b/contrib/ciabot/README
new file mode 100644 (file)
index 0000000..3b916ac
--- /dev/null
@@ -0,0 +1,12 @@
+These are hook scripts for the CIA notification service at <http://cia.vc/>
+
+They are maintained by Eric S. Raymond <esr@thyrsus.com>.  There is an
+upstream resource page for them at <http://www.catb.org/esr/ciabot/>,
+but they are unlikely to change rapidly.
+
+You probably want the Python version; it's faster, more capable, and
+better documented.  The shell version is maintained only as a fallback
+for use on hosting sites that don't permit Python hook scripts.
+
+You will find installation instructions for each script in its comment
+header.
diff --git a/contrib/ciabot/ciabot.py b/contrib/ciabot/ciabot.py
new file mode 100755 (executable)
index 0000000..d0627e0
--- /dev/null
@@ -0,0 +1,222 @@
+#!/usr/bin/env python
+# Copyright (c) 2010 Eric S. Raymond <esr@thyrsus.com>
+# Distributed under BSD terms.
+#
+# This script contains porcelain and porcelain byproducts.
+# It's Python because the Python standard libraries avoid portability/security
+# issues raised by callouts in the ancestral Perl and sh scripts.  It should
+# be compatible back to Python 2.1.5
+#
+# usage: ciabot.py [-V] [-n] [-p projectname]  [refname [commits...]]
+#
+# This script is meant to be run either in a post-commit hook or in an
+# update hook.  If there's nothing unusual about your hosting setup,
+# you can specify the project name with a -p option and avoid having
+# to modify this script.  Try it with -n to see the notification mail
+# dumped to stdout and verify that it looks sane. With -V it dumps its
+# version and exits.
+#
+# In post-commit, run it without arguments (other than possibly a -p
+# option). It will query for current HEAD and the latest commit ID to
+# get the information it needs.
+#
+# In update, call it with a refname followed by a list of commits:
+# You want to reverse the order git rev-list emits becxause it lists
+# from most recent to oldest.
+#
+# /path/to/ciabot.py ${refname} $(git rev-list ${oldhead}..${newhead} | tac)
+#
+# Note: this script uses mail, not XML-RPC, in order to avoid stalling
+# until timeout when the CIA XML-RPC server is down.
+#
+
+#
+# The project as known to CIA. You will either want to change this
+# or invoke the script with a -p option to set it.
+#
+project=None
+
+#
+# You may not need to change these:
+#
+import os, sys, commands, socket, urllib
+
+# Name of the repository.
+# You can hardwire this to make the script faster.
+repo = os.path.basename(os.getcwd())
+
+# Fully-qualified domain name of this host.
+# You can hardwire this to make the script faster.
+host = socket.getfqdn()
+
+# Changeset URL prefix for your repo: when the commit ID is appended
+# to this, it should point at a CGI that will display the commit
+# through gitweb or something similar. The defaults will probably
+# work if you have a typical gitweb/cgit setup.
+#
+#urlprefix="http://%(host)s/cgi-bin/gitweb.cgi?p=%(repo)s;a=commit;h="
+urlprefix="http://%(host)s/cgi-bin/cgit.cgi/%(repo)s/commit/?id="
+
+# The service used to turn your gitwebbish URL into a tinyurl so it
+# will take up less space on the IRC notification line.
+tinyifier = "http://tinyurl.com/api-create.php?url="
+
+# The template used to generate the XML messages to CIA.  You can make
+# visible changes to the IRC-bot notification lines by hacking this.
+# The default will produce a notfication line that looks like this:
+#
+# ${project}: ${author} ${repo}:${branch} * ${rev} ${files}: ${logmsg} ${url}
+#
+# By omitting $files you can collapse the files part to a single slash.
+xml = '''\
+<message>
+  <generator>
+    <name>CIA Python client for Git</name>
+    <version>%(gitver)s</version>
+    <url>%(generator)s</url>
+  </generator>
+  <source>
+    <project>%(project)s</project>
+    <branch>%(repo)s:%(branch)s</branch>
+  </source>
+  <timestamp>%(ts)s</timestamp>
+  <body>
+    <commit>
+      <author>%(author)s</author>
+      <revision>%(rev)s</revision>
+      <files>
+        %(files)s
+      </files>
+      <log>%(logmsg)s %(url)s</log>
+      <url>%(url)s</url>
+    </commit>
+  </body>
+</message>
+'''
+
+#
+# No user-serviceable parts below this line:
+#
+
+# Addresses for the e-mail. The from address is a dummy, since CIA
+# will never reply to this mail.
+fromaddr = "CIABOT-NOREPLY@" + host
+toaddr = "cia@cia.navi.cx"
+
+# Identify the generator script.
+# Should only change when the script itself gets a new home and maintainer.
+generator="http://www.catb.org/~esr/ciabot.py"
+
+def do(command):
+    return commands.getstatusoutput(command)[1]
+
+def report(refname, merged):
+    "Generate a commit notification to be reported to CIA"
+
+    # Try to tinyfy a reference to a web view for this commit.
+    try:
+        url = open(urllib.urlretrieve(tinyifier + urlprefix + merged)[0]).read()
+    except:
+        url = urlprefix + merged
+
+    branch = os.path.basename(refname)
+
+    # Compute a shortnane for the revision
+    rev = do("git describe ${merged} 2>/dev/null") or merged[:12]
+
+    # Extract the neta-information for the commit
+    rawcommit = do("git cat-file commit " + merged)
+    files=do("git diff-tree -r --name-only '"+ merged +"' | sed -e '1d' -e 's-.*-<file>&</file>-'")
+    inheader = True
+    headers = {}
+    logmsg = ""
+    for line in rawcommit.split("\n"):
+        if inheader:
+            if line:
+                fields = line.split()
+                headers[fields[0]] = " ".join(fields[1:])
+            else:
+                inheader = False
+        else:
+            logmsg = line
+            break
+    (author, ts) = headers["author"].split(">")
+
+    # This discards the part of the authors addrsss after @.
+    # Might be bnicece to ship the full email address, if not
+    # for spammers' address harvesters - getting this wrong
+    # would make the freenode #commits channel into harvester heaven.
+    author = author.replace("<", "").split("@")[0].split()[-1]
+
+    # This ignores the timezone.  Not clear what to do with it...
+    ts = ts.strip().split()[0]
+
+    context = locals()
+    context.update(globals())
+
+    out = xml % context
+
+    message = '''\
+Message-ID: <%(merged)s.%(author)s@%(project)s>
+From: %(fromaddr)s
+To: %(toaddr)s
+Content-type: text/xml
+Subject: DeliverXML
+
+%(out)s''' % locals()
+
+    return message
+
+if __name__ == "__main__":
+    import getopt
+
+    try:
+        (options, arguments) = getopt.getopt(sys.argv[1:], "np:V")
+    except getopt.GetoptError, msg:
+        print "ciabot.py: " + str(msg)
+        raise SystemExit, 1
+
+    mailit = True
+    for (switch, val) in options:
+        if switch == '-p':
+            project = val
+        elif switch == '-n':
+            mailit = False
+        elif switch == '-V':
+            print "ciabot.py: version 3.2"
+            sys.exit(0)
+
+    # Cough and die if user has not specified a project
+    if not project:
+        sys.stderr.write("ciabot.py: no project specified, bailing out.\n")
+        sys.exit(1)
+
+    # We'll need the git version number.
+    gitver = do("git --version").split()[0]
+
+    urlprefix = urlprefix % globals()
+
+    # The script wants a reference to head followed by the list of
+    # commit ID to report about.
+    if len(arguments) == 0:
+        refname = do("git symbolic-ref HEAD 2>/dev/null")
+        merges = [do("git rev-parse HEAD")]
+    else:
+        refname = arguments[0]
+        merges = arguments[1:]
+
+    if mailit:
+        import smtplib
+        server = smtplib.SMTP('localhost')
+
+    for merged in merges:
+        message = report(refname, merged)
+        if mailit:
+            server.sendmail(fromaddr, [toaddr], message)
+        else:
+            print message
+
+    if mailit:
+        server.quit()
+
+#End
diff --git a/contrib/ciabot/ciabot.sh b/contrib/ciabot/ciabot.sh
new file mode 100755 (executable)
index 0000000..eb87bba
--- /dev/null
@@ -0,0 +1,192 @@
+#!/bin/sh
+# Distributed under the terms of the GNU General Public License v2
+# Copyright (c) 2006 Fernando J. Pereda <ferdy@gentoo.org>
+# Copyright (c) 2008 Natanael Copa <natanael.copa@gmail.com>
+# Copyright (c) 2010 Eric S. Raymond <esr@thyrsus.com>
+#
+# This is a version 3.x of ciabot.sh; use -V to find the exact
+# version.  Versions 1 and 2 were shipped in 2006 and 2008 and are not
+# version-stamped.  The version 2 maintainer has passed the baton.
+#
+# Note: This script should be considered obsolete.
+# There is a faster, better-documented rewrite in Python: find it as ciabot.py
+# Use this only if your hosting site forbids Python hooks.
+#
+# Originally based on Git ciabot.pl by Petr Baudis.
+# This script contains porcelain and porcelain byproducts.
+#
+# usage: ciabot.sh [-V] [-n] [-p projectname] [refname commit]
+#
+# This script is meant to be run either in a post-commit hook or in an
+# update hook.  If there's nothing unusual about your hosting setup,
+# you can specify the project name with a -p option and avoid having
+# to modify this script.  Try it with -n first to see the notification
+# mail dumped to stdout and verify that it looks sane.  Use -V to dump
+# the version and exit.
+#
+# In post-commit, run it without arguments (other than possibly a -p
+# option). It will query for current HEAD and the latest commit ID to
+# get the information it needs.
+#
+# In update, you have to call it once per merged commit:
+#
+#       refname=$1
+#       oldhead=$2
+#       newhead=$3
+#       for merged in $(git rev-list ${oldhead}..${newhead} | tac) ; do
+#               /path/to/ciabot.bash ${refname} ${merged}
+#       done
+#
+# The reason for the tac call ids that git rev-list emits commits from
+# most recent to least - better to ship notifactions from oldest to newest.
+#
+# Note: this script uses mail, not XML-RPC, in order to avoid stalling
+# until timeout when the CIA XML-RPC server is down.
+#
+
+#
+# The project as known to CIA. You will either want to change this
+# or set the project name with a -p option.
+#
+project=
+
+#
+# You may not need to change these:
+#
+
+# Name of the repository.
+# You can hardwire this to make the script faster.
+repo="`basename ${PWD}`"
+
+# Fully qualified domain name of the repo host.
+# You can hardwire this to make the script faster.
+host=`hostname --fqdn`
+
+# Changeset URL prefix for your repo: when the commit ID is appended
+# to this, it should point at a CGI that will display the commit
+# through gitweb or something similar. The defaults will probably
+# work if you have a typical gitweb/cgit setup.
+#urlprefix="http://${host}/cgi-bin/gitweb.cgi?p=${repo};a=commit;h="
+urlprefix="http://${host}/cgi-bin/cgit.cgi/${repo}/commit/?id="
+
+#
+# You probably will not need to change the following:
+#
+
+# Identify the script. Should change only when the script itself
+# gets a new home and maintainer.
+generator="http://www.catb.org/~esr/ciabot/ciabot.sh"
+
+# Addresses for the e-mail
+from="CIABOT-NOREPLY@${host}"
+to="cia@cia.navi.cx"
+
+# SMTP client to use - may need to edit the absolute pathname for your system
+sendmail="sendmail -t -f ${from}"
+
+#
+# No user-serviceable parts below this line:
+#
+
+# Should include all places sendmail is likely to lurk.
+PATH="$PATH:/usr/sbin/"
+
+mode=mailit
+while getopts pnV opt
+do
+    case $opt in
+       p) project=$2; shift ; shift ;;
+       n) mode=dumpit; shift ;;
+       V) echo "ciabot.sh: version 3.2"; exit 0; shift ;;
+    esac
+done
+
+# Cough and die if user has not specified a project
+if [ -z "$project" ]
+then
+    echo "ciabot.sh: no project specified, bailing out." >&2
+    exit 1
+fi
+
+if [ $# -eq 0 ] ; then
+       refname=$(git symbolic-ref HEAD 2>/dev/null)
+       merged=$(git rev-parse HEAD)
+else
+       refname=$1
+       merged=$2
+fi
+
+# This tries to turn your gitwebbish URL into a tinyurl so it will take up
+# less space on the IRC notification line. Some repo sites (I'm looking at
+# you, berlios.de!) forbid wget calls for security reasons.  On these,
+# the code will fall back to the full un-tinyfied URL.
+longurl=${urlprefix}${merged}
+url=$(wget -O - -q http://tinyurl.com/api-create.php?url=${longurl} 2>/dev/null)
+if [ -z "$url" ]; then
+       url="${longurl}"
+fi
+
+refname=${refname##refs/heads/}
+
+gitver=$(git --version)
+gitver=${gitver##* }
+
+rev=$(git describe ${merged} 2>/dev/null)
+# ${merged:0:12} was the only bashism left in the 2008 version of this
+# script, according to checkbashisms.  Replace it with ${merged} here
+# because it was just a fallback anyway, and it's worth accepting a
+# longer fallback for faster execution and removing the bash
+# dependency.
+[ -z ${rev} ] && rev=${merged}
+
+# This discards the part of the author's address after @.
+# Might be nice to ship the full email address, if not
+# for spammers' address harvesters - getting this wrong
+# would make the freenode #commits channel into harvester heaven.
+rawcommit=$(git cat-file commit ${merged})
+author=$(echo "$rawcommit" | sed -n -e '/^author .*<\([^@]*\).*$/s--\1-p')
+logmessage=$(echo "$rawcommit" | sed -e '1,/^$/d' | head -n 1)
+logmessage=$(echo "$logmessage" | sed 's/\&/&amp\;/g; s/</&lt\;/g; s/>/&gt\;/g')
+ts=$(echo "$rawcommit" | sed -n -e '/^author .*> \([0-9]\+\).*$/s--\1-p')
+files=$(git diff-tree -r --name-only ${merged} | sed -e '1d' -e 's-.*-<file>&</file>-')
+
+out="
+<message>
+  <generator>
+    <name>CIA Shell client for Git</name>
+    <version>${gitver}</version>
+    <url>${generator}</url>
+  </generator>
+  <source>
+    <project>${project}</project>
+    <branch>$repo:${refname}</branch>
+  </source>
+  <timestamp>${ts}</timestamp>
+  <body>
+    <commit>
+      <author>${author}</author>
+      <revision>${rev}</revision>
+      <files>
+       ${files}
+      </files>
+      <log>${logmessage} ${url}</log>
+      <url>${url}</url>
+    </commit>
+  </body>
+</message>"
+
+if [ "$mode" = "dumpit" ]
+then
+    sendmail=cat
+fi
+
+${sendmail} << EOM
+Message-ID: <${merged}.${author}@${project}>
+From: ${from}
+To: ${to}
+Content-type: text/xml
+Subject: DeliverXML
+${out}
+EOM
+
+# vim: set tw=70 :
index 733ac39a32f6fd0b4f1546d429ac55c4ad6699b6..545bd4b38368e3c2a3958133bbeef6a19e831fff 100755 (executable)
@@ -627,10 +627,19 @@ __git_aliased_command ()
        local word cmdline=$(git --git-dir="$(__gitdir)" \
                config --get "alias.$1")
        for word in $cmdline; do
-               if [ "${word##-*}" ]; then
-                       echo $word
+               case "$word" in
+               \!gitk|gitk)
+                       echo "gitk"
                        return
-               fi
+                       ;;
+               \!*)    : shell command alias ;;
+               -*)     : option ;;
+               *=*)    : setting env ;;
+               git)    : git itself ;;
+               *)
+                       echo "$word"
+                       return
+               esac
        done
 }
 
@@ -1084,6 +1093,11 @@ _git_gc ()
        COMPREPLY=()
 }
 
+_git_gitk ()
+{
+       _gitk
+}
+
 _git_grep ()
 {
        __git_has_doubledash && return
@@ -1436,6 +1450,11 @@ _git_send_email ()
        COMPREPLY=()
 }
 
+_git_stage ()
+{
+       _git_add
+}
+
 __git_config_get_set_variables ()
 {
        local prevword word config_file= c=$COMP_CWORD
@@ -2167,6 +2186,11 @@ _git_tag ()
        esac
 }
 
+_git_whatchanged ()
+{
+       _git_log
+}
+
 _git ()
 {
        local i c=1 command __git_dir
@@ -2203,64 +2227,14 @@ _git ()
                return
        fi
 
+       local completion_func="_git_${command//-/_}"
+       declare -F $completion_func >/dev/null && $completion_func && return
+
        local expansion=$(__git_aliased_command "$command")
-       [ "$expansion" ] && command="$expansion"
-
-       case "$command" in
-       am)          _git_am ;;
-       add)         _git_add ;;
-       apply)       _git_apply ;;
-       archive)     _git_archive ;;
-       bisect)      _git_bisect ;;
-       bundle)      _git_bundle ;;
-       branch)      _git_branch ;;
-       checkout)    _git_checkout ;;
-       cherry)      _git_cherry ;;
-       cherry-pick) _git_cherry_pick ;;
-       clean)       _git_clean ;;
-       clone)       _git_clone ;;
-       commit)      _git_commit ;;
-       config)      _git_config ;;
-       describe)    _git_describe ;;
-       diff)        _git_diff ;;
-       difftool)    _git_difftool ;;
-       fetch)       _git_fetch ;;
-       format-patch) _git_format_patch ;;
-       fsck)        _git_fsck ;;
-       gc)          _git_gc ;;
-       grep)        _git_grep ;;
-       help)        _git_help ;;
-       init)        _git_init ;;
-       log)         _git_log ;;
-       ls-files)    _git_ls_files ;;
-       ls-remote)   _git_ls_remote ;;
-       ls-tree)     _git_ls_tree ;;
-       merge)       _git_merge;;
-       mergetool)   _git_mergetool;;
-       merge-base)  _git_merge_base ;;
-       mv)          _git_mv ;;
-       name-rev)    _git_name_rev ;;
-       notes)       _git_notes ;;
-       pull)        _git_pull ;;
-       push)        _git_push ;;
-       rebase)      _git_rebase ;;
-       remote)      _git_remote ;;
-       replace)     _git_replace ;;
-       reset)       _git_reset ;;
-       revert)      _git_revert ;;
-       rm)          _git_rm ;;
-       send-email)  _git_send_email ;;
-       shortlog)    _git_shortlog ;;
-       show)        _git_show ;;
-       show-branch) _git_show_branch ;;
-       stash)       _git_stash ;;
-       stage)       _git_add ;;
-       submodule)   _git_submodule ;;
-       svn)         _git_svn ;;
-       tag)         _git_tag ;;
-       whatchanged) _git_log ;;
-       *)           COMPREPLY=() ;;
-       esac
+       if [ -n "$expansion" ]; then
+               completion_func="_git_${expansion//-/_}"
+               declare -F $completion_func >/dev/null && $completion_func
+       fi
 }
 
 _gitk ()
index 7051a83a59758277dd60fe026dea730eb7b6b115..82f5ed3ddc8adb1b9b281c3912f4e67c53ef152f 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 
 ## zip archive frontend for git-fast-import
 ##
index 854cd94ba55e498a3ff6c26be3dbe5191faa19dc..046cb2b268a82358630e86bb55cf8b4e58c730fb 100755 (executable)
@@ -1,4 +1,4 @@
-#! /usr/bin/python
+#!/usr/bin/env python
 
 """ hg-to-git.py - A Mercurial to GIT converter
 
index 0f3d97b67eef3108728265e26f5d79c4526d11ac..b6e534b65b687d955a878d902b9bb46cfa2e42ce 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 #
 # This tool is copyright (c) 2006, Sean Estabrooks.
 # It is released under the Gnu Public License, version 2.
index 7d9e1c03e88d7785f4ff0d534563ba5778fbc244..a90ab10505a3694de83a0ffd8fc472518f12cf2b 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -590,14 +590,17 @@ static int execute(struct sockaddr *addr)
 static int addrcmp(const struct sockaddr_storage *s1,
     const struct sockaddr_storage *s2)
 {
-       if (s1->ss_family != s2->ss_family)
-               return s1->ss_family - s2->ss_family;
-       if (s1->ss_family == AF_INET)
+       const struct sockaddr *sa1 = (const struct sockaddr*) s1;
+       const struct sockaddr *sa2 = (const struct sockaddr*) s2;
+
+       if (sa1->sa_family != sa2->sa_family)
+               return sa1->sa_family - sa2->sa_family;
+       if (sa1->sa_family == AF_INET)
                return memcmp(&((struct sockaddr_in *)s1)->sin_addr,
                    &((struct sockaddr_in *)s2)->sin_addr,
                    sizeof(struct in_addr));
 #ifndef NO_IPV6
-       if (s1->ss_family == AF_INET6)
+       if (sa1->sa_family == AF_INET6)
                return memcmp(&((struct sockaddr_in6 *)s1)->sin6_addr,
                    &((struct sockaddr_in6 *)s2)->sin6_addr,
                    sizeof(struct in6_addr));
diff --git a/diff.c b/diff.c
index 4cb6d9a9e8e80bc834e14f15c07e67069e449a89..e49f14a92442117a8e8424bd7a750dc4fda5cab2 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -14,6 +14,7 @@
 #include "userdiff.h"
 #include "sigchain.h"
 #include "submodule.h"
+#include "ll-merge.h"
 
 #ifdef NO_FAST_WORKING_DIRECTORY
 #define FAST_WORKING_DIRECTORY 0
@@ -534,9 +535,9 @@ static void emit_rewrite_diff(const char *name_a,
        if (lc_b)
                emit_rewrite_lines(&ecbdata, '+', data_two, size_two);
        if (textconv_one)
-               free(data_one);
+               free((char *)data_one);
        if (textconv_two)
-               free(data_two);
+               free((char *)data_two);
 }
 
 struct diff_words_buffer {
@@ -682,7 +683,6 @@ static void diff_words_show(struct diff_words_data *diff_words)
 {
        xpparam_t xpp;
        xdemitconf_t xecfg;
-       xdemitcb_t ecb;
        mmfile_t minus, plus;
 
        /* special case: only removal */
@@ -704,7 +704,7 @@ static void diff_words_show(struct diff_words_data *diff_words)
        /* as only the hunk header will be parsed, we need a 0-context */
        xecfg.ctxlen = 0;
        xdi_diff_outf(&minus, &plus, fn_out_diff_words_aux, diff_words,
-                     &xpp, &xecfg, &ecb);
+                     &xpp, &xecfg);
        free(minus.ptr);
        free(plus.ptr);
        if (diff_words->current_plus != diff_words->plus.text.ptr +
@@ -935,7 +935,7 @@ struct diffstat_t {
                unsigned is_unmerged:1;
                unsigned is_binary:1;
                unsigned is_renamed:1;
-               unsigned int added, deleted;
+               uintmax_t added, deleted;
        } **files;
 };
 
@@ -1027,7 +1027,7 @@ static void fill_print_name(struct diffstat_file *file)
 static void show_stats(struct diffstat_t *data, struct diff_options *options)
 {
        int i, len, add, del, adds = 0, dels = 0;
-       int max_change = 0, max_len = 0;
+       uintmax_t max_change = 0, max_len = 0;
        int total_files = data->nr;
        int width, name_width;
        const char *reset, *set, *add_c, *del_c;
@@ -1056,7 +1056,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 
        for (i = 0; i < data->nr; i++) {
                struct diffstat_file *file = data->files[i];
-               int change = file->added + file->deleted;
+               uintmax_t change = file->added + file->deleted;
                fill_print_name(file);
                len = strlen(file->print_name);
                if (max_len < len)
@@ -1084,8 +1084,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
        for (i = 0; i < data->nr; i++) {
                const char *prefix = "";
                char *name = data->files[i]->print_name;
-               int added = data->files[i]->added;
-               int deleted = data->files[i]->deleted;
+               uintmax_t added = data->files[i]->added;
+               uintmax_t deleted = data->files[i]->deleted;
                int name_len;
 
                /*
@@ -1106,9 +1106,11 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
                if (data->files[i]->is_binary) {
                        show_name(options->file, prefix, name, len);
                        fprintf(options->file, "  Bin ");
-                       fprintf(options->file, "%s%d%s", del_c, deleted, reset);
+                       fprintf(options->file, "%s%"PRIuMAX"%s",
+                               del_c, deleted, reset);
                        fprintf(options->file, " -> ");
-                       fprintf(options->file, "%s%d%s", add_c, added, reset);
+                       fprintf(options->file, "%s%"PRIuMAX"%s",
+                               add_c, added, reset);
                        fprintf(options->file, " bytes");
                        fprintf(options->file, "\n");
                        continue;
@@ -1137,7 +1139,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
                        del = scale_linear(del, width, max_change);
                }
                show_name(options->file, prefix, name, len);
-               fprintf(options->file, "%5d%s", added + deleted,
+               fprintf(options->file, "%5"PRIuMAX"%s", added + deleted,
                                added + deleted ? " " : "");
                show_graph(options->file, '+', add, add_c, reset);
                show_graph(options->file, '-', del, del_c, reset);
@@ -1187,7 +1189,8 @@ static void show_numstat(struct diffstat_t *data, struct diff_options *options)
                        fprintf(options->file, "-\t-\t");
                else
                        fprintf(options->file,
-                               "%d\t%d\t", file->added, file->deleted);
+                               "%"PRIuMAX"\t%"PRIuMAX"\t",
+                               file->added, file->deleted);
                if (options->line_termination) {
                        fill_print_name(file);
                        if (!file->is_renamed)
@@ -1357,37 +1360,32 @@ static void free_diffstat_info(struct diffstat_t *diffstat)
 struct checkdiff_t {
        const char *filename;
        int lineno;
+       int conflict_marker_size;
        struct diff_options *o;
        unsigned ws_rule;
        unsigned status;
 };
 
-static int is_conflict_marker(const char *line, unsigned long len)
+static int is_conflict_marker(const char *line, int marker_size, unsigned long len)
 {
        char firstchar;
        int cnt;
 
-       if (len < 8)
+       if (len < marker_size + 1)
                return 0;
        firstchar = line[0];
        switch (firstchar) {
-       case '=': case '>': case '<':
+       case '=': case '>': case '<': case '|':
                break;
        default:
                return 0;
        }
-       for (cnt = 1; cnt < 7; cnt++)
+       for (cnt = 1; cnt < marker_size; cnt++)
                if (line[cnt] != firstchar)
                        return 0;
-       /* line[0] thru line[6] are same as firstchar */
-       if (firstchar == '=') {
-               /* divider between ours and theirs? */
-               if (len != 8 || line[7] != '\n')
-                       return 0;
-       } else if (len < 8 || !isspace(line[7])) {
-               /* not divider before ours nor after theirs */
+       /* line[1] thru line[marker_size-1] are same as firstchar */
+       if (len < marker_size + 1 || !isspace(line[marker_size]))
                return 0;
-       }
        return 1;
 }
 
@@ -1395,6 +1393,7 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)
 {
        struct checkdiff_t *data = priv;
        int color_diff = DIFF_OPT_TST(data->o, COLOR_DIFF);
+       int marker_size = data->conflict_marker_size;
        const char *ws = diff_get_color(color_diff, DIFF_WHITESPACE);
        const char *reset = diff_get_color(color_diff, DIFF_RESET);
        const char *set = diff_get_color(color_diff, DIFF_FILE_NEW);
@@ -1403,7 +1402,7 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)
        if (line[0] == '+') {
                unsigned bad;
                data->lineno++;
-               if (is_conflict_marker(line + 1, len - 1)) {
+               if (is_conflict_marker(line + 1, marker_size, len - 1)) {
                        data->status |= 1;
                        fprintf(data->o->file,
                                "%s:%d: leftover conflict marker\n",
@@ -1703,7 +1702,6 @@ static void builtin_diff(const char *name_a,
                const char *diffopts = getenv("GIT_DIFF_OPTS");
                xpparam_t xpp;
                xdemitconf_t xecfg;
-               xdemitcb_t ecb;
                struct emit_callback ecbdata;
                const struct userdiff_funcname *pe;
 
@@ -1763,7 +1761,7 @@ static void builtin_diff(const char *name_a,
                        }
                }
                xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
-                             &xpp, &xecfg, &ecb);
+                             &xpp, &xecfg);
                if (DIFF_OPT_TST(o, COLOR_DIFF_WORDS))
                        free_diff_words_data(&ecbdata);
                if (textconv_one)
@@ -1816,13 +1814,12 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
                /* Crazy xdl interfaces.. */
                xpparam_t xpp;
                xdemitconf_t xecfg;
-               xdemitcb_t ecb;
 
                memset(&xpp, 0, sizeof(xpp));
                memset(&xecfg, 0, sizeof(xecfg));
                xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
                xdi_diff_outf(&mf1, &mf2, diffstat_consume, diffstat,
-                             &xpp, &xecfg, &ecb);
+                             &xpp, &xecfg);
        }
 
  free_and_return:
@@ -1847,6 +1844,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
        data.lineno = 0;
        data.o = o;
        data.ws_rule = whitespace_rule(attr_path);
+       data.conflict_marker_size = ll_merge_marker_size(attr_path);
 
        if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
                die("unable to read files to diff");
@@ -1863,14 +1861,13 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
                /* Crazy xdl interfaces.. */
                xpparam_t xpp;
                xdemitconf_t xecfg;
-               xdemitcb_t ecb;
 
                memset(&xpp, 0, sizeof(xpp));
                memset(&xecfg, 0, sizeof(xecfg));
                xecfg.ctxlen = 1; /* at least one context line */
                xpp.flags = XDF_NEED_MINIMAL;
                xdi_diff_outf(&mf1, &mf2, checkdiff_consume, &data,
-                             &xpp, &xecfg, &ecb);
+                             &xpp, &xecfg);
 
                if (data.ws_rule & WS_BLANK_AT_EOF) {
                        struct emit_callback ecbdata;
@@ -3365,7 +3362,6 @@ static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1)
        for (i = 0; i < q->nr; i++) {
                xpparam_t xpp;
                xdemitconf_t xecfg;
-               xdemitcb_t ecb;
                mmfile_t mf1, mf2;
                struct diff_filepair *p = q->queue[i];
                int len1, len2;
@@ -3427,7 +3423,7 @@ static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1)
                xecfg.ctxlen = 3;
                xecfg.flags = XDL_EMIT_FUNCNAMES;
                xdi_diff_outf(&mf1, &mf2, patch_id_consume, &data,
-                             &xpp, &xecfg, &ecb);
+                             &xpp, &xecfg);
        }
 
        git_SHA1_Final(sha1, &ctx);
index a3c45373669cd8482c04d5815862ed36a153572d..6e259772895599b35d13564e62077b882f0de3a6 100644 (file)
@@ -55,7 +55,8 @@
 # else
 # define _XOPEN_SOURCE 500
 # endif
-#elif !defined(__APPLE__) && !defined(__FreeBSD__)  && !defined(__USLC__) && !defined(_M_UNIX) && !defined(sgi)
+#elif !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__USLC__) && \
+      !defined(_M_UNIX) && !defined(sgi) && !defined(__DragonFly__)
 #define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */
 #define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
 #endif
@@ -331,6 +332,7 @@ extern int git_vsnprintf(char *str, size_t maxsize,
 #ifdef __GLIBC_PREREQ
 #if __GLIBC_PREREQ(2, 1)
 #define HAVE_STRCHRNUL
+#define HAVE_MEMPCPY
 #endif
 #endif
 
@@ -344,6 +346,14 @@ static inline char *gitstrchrnul(const char *s, int c)
 }
 #endif
 
+#ifndef HAVE_MEMPCPY
+#define mempcpy gitmempcpy
+static inline void *gitmempcpy(void *dest, const void *src, size_t n)
+{
+       return (char *)memcpy(dest, src, n) + n;
+}
+#endif
+
 extern void release_pack_memory(size_t, int);
 
 extern char *xstrdup(const char *str);
@@ -469,5 +479,14 @@ void git_qsort(void *base, size_t nmemb, size_t size,
  * Always returns the return value of unlink(2).
  */
 int unlink_or_warn(const char *path);
+/*
+ * Likewise for rmdir(2).
+ */
+int rmdir_or_warn(const char *path);
+/*
+ * Calls the correct function out of {unlink,rmdir}_or_warn based on
+ * the supplied file mode.
+ */
+int remove_or_warn(unsigned int mode, const char *path);
 
 #endif
index 6a65f255cc63cc7a6d0ae0fc0ce4b65298a40e82..f6080149c22bad8b3434b874b9e4079ac508ca69 100755 (executable)
@@ -212,7 +212,7 @@ server.errorlog = "$fqgitdir/gitweb/error.log"
 # variable above and uncomment this
 #accesslog.filename = "$fqgitdir/gitweb/access.log"
 
-setenv.add-environment = ( "PATH" => "/usr/local/bin:/usr/bin:/bin" )
+setenv.add-environment = ( "PATH" => env.PATH )
 
 cgi.assign = ( ".cgi" => "" )
 
@@ -361,7 +361,7 @@ error_log   $fqgitdir/gitweb/error.log
 access_log     $fqgitdir/gitweb/access.log
 
 #cgi setup
-cgi_env                PATH=/usr/local/bin:/usr/bin:/bin,GIT_DIR=$GIT_DIR,GIT_EXEC_PATH=$GIT_EXEC_PATH
+cgi_env                PATH=$PATH,GIT_DIR=$GIT_DIR,GIT_EXEC_PATH=$GIT_EXEC_PATH
 cgi_interp     $PERL
 cgi_ext                cgi,pl
 
@@ -391,18 +391,20 @@ EOFGITWEB
 gitweb_css () {
        cat > "$1" <<\EOFGITWEB
 @@GITWEB_CSS@@
+
 EOFGITWEB
 }
 
 gitweb_js () {
        cat > "$1" <<\EOFGITWEB
 @@GITWEB_JS@@
+
 EOFGITWEB
 }
 
 gitweb_cgi "$GIT_DIR/gitweb/gitweb.cgi"
-gitweb_css "$GIT_DIR/gitweb/gitweb.css"
-gitweb_js  "$GIT_DIR/gitweb/gitweb.js"
+gitweb_css "$GIT_DIR/@@GITWEB_CSS_NAME@@"
+gitweb_js  "$GIT_DIR/@@GITWEB_JS_NAME@@"
 
 case "$httpd" in
 *lighttpd*)
index 1d116bfae2175891905d40ba4b55b331fba63372..436b7f5977c05c347debc12130f822af482c03e3 100755 (executable)
@@ -20,6 +20,7 @@ v,verbose          display a diffstat of what changed upstream
 onto=              rebase onto given branch instead of upstream
 p,preserve-merges  try to recreate merges instead of ignoring them
 s,strategy=        use the given merge strategy
+no-ff              cherry-pick all commits, even if unchanged
 m,merge            always used (no-op)
 i,interactive      always used (no-op)
  Actions:
@@ -110,6 +111,7 @@ VERBOSE=
 OK_TO_SKIP_PRE_REBASE=
 REBASE_ROOT=
 AUTOSQUASH=
+NEVER_FF=
 
 GIT_CHERRY_PICK_HELP="  After resolving the conflicts,
 mark the corrected paths with 'git add <paths>', and
@@ -232,6 +234,7 @@ do_with_author () {
 pick_one () {
        ff=--ff
        case "$1" in -n) sha1=$2; ff= ;; *) sha1=$1 ;; esac
+       case "$NEVER_FF" in '') ;; ?*) ff= ;; esac
        output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1"
        test -d "$REWRITTEN" &&
                pick_one_preserving_merges "$@" && return
@@ -562,6 +565,7 @@ do_next () {
                        git diff-tree --stat $(cat "$DOTEST"/head)..HEAD
        } &&
        {
+               test -s "$REWRITTEN_LIST" &&
                git notes copy --for-rewrite=rebase < "$REWRITTEN_LIST" ||
                true # we don't care if this copying failed
        } &&
@@ -782,6 +786,9 @@ first and then run 'git rebase --continue' again."
        -i)
                # yeah, we know
                ;;
+       --no-ff)
+               NEVER_FF=t
+               ;;
        --root)
                REBASE_ROOT=t
                ;;
@@ -823,8 +830,6 @@ first and then run 'git rebase --continue' again."
 
                if test ! -z "$1"
                then
-                       output git show-ref --verify --quiet "refs/heads/$1" ||
-                               die "Invalid branchname: $1"
                        output git checkout "$1" ||
                                die "Could not checkout $1"
                fi
@@ -967,7 +972,7 @@ EOF
                has_action "$TODO" ||
                        die_abort "Nothing to do"
 
-               test -d "$REWRITTEN" || skip_unnecessary_picks
+               test -d "$REWRITTEN" || test -n "$NEVER_FF" || skip_unnecessary_picks
 
                git update-ref ORIG_HEAD $HEAD
                output git checkout $ONTO && do_rest
index e0eb9568f3d12a068d46196d2dc896dde4d35fd3..44f5c65fdb5e81c4b660a666c2edd71aa75c5c1a 100755 (executable)
@@ -3,7 +3,7 @@
 # Copyright (c) 2005 Junio C Hamano.
 #
 
-USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
+USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
 LONG_USAGE='git-rebase replaces <branch> with a new branch of the
 same name.  When the --onto option is provided the new branch starts
 out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
@@ -353,7 +353,7 @@ do
        --root)
                rebase_root=t
                ;;
-       -f|--f|--fo|--for|--forc|force|--force-r|--force-re|--force-reb|--force-reba|--force-rebas|--force-rebase)
+       -f|--f|--fo|--for|--forc|force|--force-r|--force-re|--force-reb|--force-reba|--force-rebas|--force-rebase|--no-ff)
                force_rebase=t
                ;;
        --rerere-autoupdate|--no-rerere-autoupdate)
index d612ae8729e0a15f501214b6f27f4fc32a66e9fd..ce569a9c8f964b3cdc8920325bc817141035c2c3 100755 (executable)
@@ -64,6 +64,8 @@ git send-email [options] <file | directory | rev-list options >
     --smtp-pass             <str>  * Password for SMTP-AUTH; not necessary.
     --smtp-encryption       <str>  * tls or ssl; anything else disables.
     --smtp-ssl                     * Deprecated. Use '--smtp-encryption ssl'.
+    --smtp-domain           <str>  * The domain name sent to HELO/EHLO handshake
+    --smtp-debug            <0|1>  * Disable, enable Net::SMTP debug.
 
   Automating:
     --identity              <str>  * Use the sendemail.<id> options.
@@ -130,6 +132,8 @@ my $have_email_valid = eval { require Email::Valid; 1 };
 my $have_mail_address = eval { require Mail::Address; 1 };
 my $smtp;
 my $auth;
+my $mail_domain_default = "localhost.localdomain";
+my $mail_domain;
 
 sub unique_email_list(@);
 sub cleanup_compose_files();
@@ -162,9 +166,12 @@ my $compose_filename;
 
 # Handle interactive edition of files.
 my $multiedit;
-my $editor = Git::command_oneline('var', 'GIT_EDITOR');
+my $editor;
 
 sub do_edit {
+       if (!defined($editor)) {
+               $editor = Git::command_oneline('var', 'GIT_EDITOR');
+       }
        if (defined($multiedit) && !$multiedit) {
                map {
                        system('sh', '-c', $editor.' "$@"', $editor, $_);
@@ -187,6 +194,8 @@ my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts);
 my ($validate, $confirm);
 my (@suppress_cc);
 
+my ($debug_net_smtp) = 0;              # Net::SMTP, see send_message()
+
 my $not_set_by_user = "true but not set by the user";
 
 my %config_bool_settings = (
@@ -273,6 +282,8 @@ my $rc = GetOptions("sender|from=s" => \$sender,
                    "smtp-pass:s" => \$smtp_authpass,
                    "smtp-ssl" => sub { $smtp_encryption = 'ssl' },
                    "smtp-encryption=s" => \$smtp_encryption,
+                   "smtp-debug:i" => \$debug_net_smtp,
+                   "smtp-domain:s" => \$mail_domain,
                    "identity=s" => \$identity,
                    "annotate" => \$annotate,
                    "compose" => \$compose,
@@ -836,6 +847,62 @@ sub sanitize_address
 
 }
 
+# Returns the local Fully Qualified Domain Name (FQDN) if available.
+#
+# Tightly configured MTAa require that a caller sends a real DNS
+# domain name that corresponds the IP address in the HELO/EHLO
+# handshake. This is used to verify the connection and prevent
+# spammers from trying to hide their identity. If the DNS and IP don't
+# match, the receiveing MTA may deny the connection.
+#
+# Here is a deny example of Net::SMTP with the default "localhost.localdomain"
+#
+# Net::SMTP=GLOB(0x267ec28)>>> EHLO localhost.localdomain
+# Net::SMTP=GLOB(0x267ec28)<<< 550 EHLO argument does not match calling host
+#
+# This maildomain*() code is based on ideas in Perl library Test::Reporter
+# /usr/share/perl5/Test/Reporter/Mail/Util.pm ==> sub _maildomain ()
+
+sub maildomain_net
+{
+       my $maildomain;
+
+       if (eval { require Net::Domain; 1 }) {
+               my $domain = Net::Domain::domainname();
+               $maildomain = $domain
+                       unless $^O eq 'darwin' && $domain =~ /\.local$/;
+       }
+
+       return $maildomain;
+}
+
+sub maildomain_mta
+{
+       my $maildomain;
+
+       if (eval { require Net::SMTP; 1 }) {
+               for my $host (qw(mailhost localhost)) {
+                       my $smtp = Net::SMTP->new($host);
+                       if (defined $smtp) {
+                               my $domain = $smtp->domain;
+                               $smtp->quit;
+
+                               $maildomain = $domain
+                                       unless $^O eq 'darwin' && $domain =~ /\.local$/;
+
+                               last if $maildomain;
+                       }
+               }
+       }
+
+       return $maildomain;
+}
+
+sub maildomain
+{
+       return maildomain_net() || maildomain_mta() || $mail_domain_default;
+}
+
 # Returns 1 if the message was sent, and 0 otherwise.
 # In actuality, the whole program dies when there
 # is an error sending a message.
@@ -938,13 +1005,19 @@ X-Mailer: git-send-email $gitversion
                if ($smtp_encryption eq 'ssl') {
                        $smtp_server_port ||= 465; # ssmtp
                        require Net::SMTP::SSL;
-                       $smtp ||= Net::SMTP::SSL->new($smtp_server, Port => $smtp_server_port);
+                       $mail_domain ||= maildomain();
+                       $smtp ||= Net::SMTP::SSL->new($smtp_server,
+                                                     Hello => $mail_domain,
+                                                     Port => $smtp_server_port);
                }
                else {
                        require Net::SMTP;
+                       $mail_domain ||= maildomain();
                        $smtp ||= Net::SMTP->new((defined $smtp_server_port)
                                                 ? "$smtp_server:$smtp_server_port"
-                                                : $smtp_server);
+                                                : $smtp_server,
+                                                Hello => $mail_domain,
+                                                Debug => $debug_net_smtp);
                        if ($smtp_encryption eq 'tls' && $smtp) {
                                require Net::SMTP::SSL;
                                $smtp->command('STARTTLS');
@@ -963,7 +1036,11 @@ X-Mailer: git-send-email $gitversion
                }
 
                if (!$smtp) {
-                       die "Unable to initialize SMTP properly.  Is there something wrong with your config?";
+                       die "Unable to initialize SMTP properly. Check config and use --smtp-debug. ",
+                           "VALUES: server=$smtp_server ",
+                           "encryption=$smtp_encryption ",
+                           "maildomain=$mail_domain",
+                           defined $smtp_server_port ? "port=$smtp_server_port" : "";
                }
 
                if (defined $smtp_authuser) {
index aa47e541ee4fe55254edc3fb59ef534ba4d5be66..59db3dc38e72fda88d521171a174c08b919677a9 100755 (executable)
@@ -210,14 +210,18 @@ list_stash () {
 }
 
 show_stash () {
+       have_stash || die 'No stash found'
+
        flags=$(git rev-parse --no-revs --flags "$@")
        if test -z "$flags"
        then
                flags=--stat
        fi
 
-       w_commit=$(git rev-parse --verify --default $ref_stash "$@") &&
-       b_commit=$(git rev-parse --verify "$w_commit^") &&
+       w_commit=$(git rev-parse --quiet --verify --default $ref_stash "$@") &&
+       b_commit=$(git rev-parse --quiet --verify "$w_commit^") ||
+               die "'$*' is not a stash"
+
        git diff $flags $b_commit $w_commit
 }
 
index 2dd372a21d82a109774e80e014f9959485202b3e..3319b836b217a26b4ac55ae5ced328ffafa0a015 100755 (executable)
@@ -21,6 +21,8 @@ command=
 branch=
 reference=
 cached=
+recursive=
+init=
 files=
 nofetch=
 update=
index ee74a5eed7758f1267441d85619969a121fb3cec..9533147ff2e06282dc8d60aeb371afa715e22cc1 100644 (file)
@@ -127,6 +127,9 @@ find $RPM_BUILD_ROOT -type f -name perllocal.pod -exec rm -f {} ';'
 rm -rf $RPM_BUILD_ROOT%{_mandir}
 %endif
 
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/bash_completion.d
+install -m 644 -T contrib/completion/git-completion.bash $RPM_BUILD_ROOT%{_sysconfdir}/bash_completion.d/git
+
 %clean
 rm -rf $RPM_BUILD_ROOT
 
@@ -136,6 +139,7 @@ rm -rf $RPM_BUILD_ROOT
 %doc README COPYING Documentation/*.txt
 %{!?_without_docs: %doc Documentation/*.html Documentation/howto}
 %{!?_without_docs: %doc Documentation/technical}
+%{_sysconfdir}/bash_completion.d
 
 %files svn
 %defattr(-,root,root)
@@ -192,6 +196,9 @@ rm -rf $RPM_BUILD_ROOT
 # No files for you!
 
 %changelog
+* Fri Mar 26 2010 Ian Ward Comfort <icomfort@stanford.edu>
+- Ship bash completion support from contrib/ in the core package.
+
 * Sun Jan 31 2010 Junio C Hamano <gitster@pobox.com>
 - Do not use %define inside %{!?...} construct.
 
index c62dfd0f4ddafbc82be15519f17815bbfcd62e8b..74b05dc91e42414147d5f3dc7b4fc66fb86c0eca 100644 (file)
@@ -7,7 +7,11 @@ pysetupfile:=setup.py
 DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
 
 ifndef PYTHON_PATH
-       PYTHON_PATH = /usr/bin/python
+       ifeq ($(uname_S),FreeBSD)
+               PYTHON_PATH = /usr/local/bin/python
+       else
+               PYTHON_PATH = /usr/bin/python
+       endif
 endif
 ifndef prefix
        prefix = $(HOME)
index 1f36a3e815865fcc72b171b497f5c4e341e148ee..1b0e09a561e01c51bdc6dbced052e0c753924618 100644 (file)
@@ -1877,8 +1877,11 @@ proc setoptions {} {
     option add *Menubutton.font uifont startupFile
     option add *Label.font uifont startupFile
     option add *Message.font uifont startupFile
-    option add *Entry.font uifont startupFile
+    option add *Entry.font textfont startupFile
+    option add *Text.font textfont startupFile
     option add *Labelframe.font uifont startupFile
+    option add *Spinbox.font textfont startupFile
+    option add *Listbox.font mainfont startupFile
 }
 
 # Make a menu and submenus.
@@ -2174,7 +2177,7 @@ proc makewindow {} {
     set findstring {}
     set fstring .tf.lbar.findstring
     lappend entries $fstring
-    ${NS}::entry $fstring -width 30 -font textfont -textvariable findstring
+    ${NS}::entry $fstring -width 30 -textvariable findstring
     trace add variable findstring write find_change
     set findtype [mc "Exact"]
     set findtypemenu [makedroplist .tf.lbar.findtype \
@@ -2217,7 +2220,7 @@ proc makewindow {} {
     pack .bleft.top.search -side left -padx 5
     set sstring .bleft.top.sstring
     set searchstring ""
-    ${NS}::entry $sstring -width 20 -font textfont -textvariable searchstring
+    ${NS}::entry $sstring -width 20 -textvariable searchstring
     lappend entries $sstring
     trace add variable searchstring write incrsearch
     pack $sstring -side left -expand 1 -fill x
@@ -2229,7 +2232,7 @@ proc makewindow {} {
        -command changediffdisp -variable diffelide -value {1 0}
     ${NS}::label .bleft.mid.labeldiffcontext -text "      [mc "Lines of context"]: "
     pack .bleft.mid.diff .bleft.mid.old .bleft.mid.new -side left
-    spinbox .bleft.mid.diffcontext -width 5 -font textfont \
+    spinbox .bleft.mid.diffcontext -width 5 \
        -from 0 -increment 1 -to 10000000 \
        -validate all -validatecommand "diffcontextvalidate %P" \
        -textvariable diffcontextstring
@@ -2383,6 +2386,8 @@ proc makewindow {} {
     }
     bindall <$::BM> "canvscan mark %W %x %y"
     bindall <B$::BM-Motion> "canvscan dragto %W %x %y"
+    bind all <$M1B-Key-w> {destroy [winfo toplevel %W]}
+    bind . <$M1B-Key-w> doquit
     bindkey <Home> selfirstline
     bindkey <End> sellastline
     bind . <Key-Up> "selnextline -1"
@@ -2782,7 +2787,7 @@ proc about {} {
     message $w.m -text [mc "
 Gitk - a commit viewer for git
 
-Copyright © 2005-2009 Paul Mackerras
+Copyright \u00a9 2005-2010 Paul Mackerras
 
 Use and redistribute under the terms of the GNU General Public License"] \
            -justify center -aspect 400 -border 2 -bg white -relief groove
@@ -2814,6 +2819,7 @@ proc keys {} {
 [mc "Gitk key bindings:"]
 
 [mc "<%s-Q>            Quit" $M1T]
+[mc "<%s-W>            Close window" $M1T]
 [mc "<Home>            Move to first commit"]
 [mc "<End>             Move to last commit"]
 [mc "<Up>, p, i        Move up one commit"]
@@ -3805,10 +3811,10 @@ proc newview {ishighlight} {
        raise $top
        return
     }
+    decode_view_opts $nextviewnum $revtreeargs
     set newviewname($nextviewnum) "[mc "View"] $nextviewnum"
     set newviewopts($nextviewnum,perm) 0
     set newviewopts($nextviewnum,cmd)  $viewargscmd($curview)
-    decode_view_opts $nextviewnum $revtreeargs
     vieweditor $top $nextviewnum [mc "Gitk view definition"]
 }
 
@@ -3845,6 +3851,7 @@ set known_view_options {
     {cmd       t50= +  {}               {mc "Command to generate more commits to include:"}}
     }
 
+# Convert $newviewopts($n, ...) into args for git log.
 proc encode_view_opts {n} {
     global known_view_options newviewopts
 
@@ -3878,6 +3885,7 @@ proc encode_view_opts {n} {
     return [concat $rargs [shellsplit $newviewopts($n,args)]]
 }
 
+# Fill $newviewopts($n, ...) based on args for git log.
 proc decode_view_opts {n view_args} {
     global known_view_options newviewopts
 
@@ -3960,10 +3968,10 @@ proc editview {} {
        raise $top
        return
     }
+    decode_view_opts $curview $viewargs($curview)
     set newviewname($curview)      $viewname($curview)
     set newviewopts($curview,perm) $viewperm($curview)
     set newviewopts($curview,cmd)  $viewargscmd($curview)
-    decode_view_opts $curview $viewargs($curview)
     vieweditor $top $curview "[mc "Gitk: edit view"] $viewname($curview)"
 }
 
@@ -4037,7 +4045,7 @@ proc vieweditor {top n title} {
        } elseif {$type eq "path"} {
            ${NS}::label $top.l -text $title
            pack $top.l -in $top -side top -pady [list 3 0] -anchor w -padx 3
-           text $top.t -width 40 -height 5 -background $bgcolor -font uifont
+           text $top.t -width 40 -height 5 -background $bgcolor
            if {[info exists viewfiles($n)]} {
                foreach f $viewfiles($n) {
                    $top.t insert end $f
@@ -7501,7 +7509,7 @@ proc getblobdiffs {ids} {
     global ignorespace
     global limitdiffs vfilelimit curview
     global diffencoding targetline diffnparents
-    global git_version
+    global git_version currdiffsubmod
 
     set textconv {}
     if {[package vcompare $git_version "1.6.1"] >= 0} {
@@ -7528,6 +7536,7 @@ proc getblobdiffs {ids} {
     set diffencoding [get_path_encoding {}]
     fconfigure $bdf -blocking 0 -encoding binary -eofchar {}
     set blobdifffd($ids) $bdf
+    set currdiffsubmod ""
     filerun $bdf [list getblobdiffline $bdf $diffids]
 }
 
@@ -7598,7 +7607,7 @@ proc getblobdiffline {bdf ids} {
     global diffnexthead diffnextnote difffilestart
     global ctext_file_names ctext_file_lines
     global diffinhdr treediffs mergemax diffnparents
-    global diffencoding jump_to_here targetline diffline
+    global diffencoding jump_to_here targetline diffline currdiffsubmod
 
     set nr 0
     $ctext conf -state normal
@@ -7679,19 +7688,30 @@ proc getblobdiffline {bdf ids} {
 
        } elseif {![string compare -length 10 "Submodule " $line]} {
            # start of a new submodule
-           if {[string compare [$ctext get "end - 4c" end] "\n \n\n"]} {
+           if {[regexp -indices "\[0-9a-f\]+\\.\\." $line nameend]} {
+               set fname [string range $line 10 [expr [lindex $nameend 0] - 2]]
+           } else {
+               set fname [string range $line 10 [expr [string first "contains " $line] - 2]]
+           }
+           if {$currdiffsubmod != $fname} {
                $ctext insert end "\n";     # Add newline after commit message
            }
            set curdiffstart [$ctext index "end - 1c"]
            lappend ctext_file_names ""
-           set fname [string range $line 10 [expr [string last " " $line] - 1]]
-           lappend ctext_file_lines $fname
-           makediffhdr $fname $ids
-           $ctext insert end "\n$line\n" filesep
+           if {$currdiffsubmod != $fname} {
+               lappend ctext_file_lines $fname
+               makediffhdr $fname $ids
+               set currdiffsubmod $fname
+               $ctext insert end "\n$line\n" filesep
+           } else {
+               $ctext insert end "$line\n" filesep
+           }
        } elseif {![string compare -length 3 "  >" $line]} {
+           set $currdiffsubmod ""
            set line [encoding convertfrom $diffencoding $line]
            $ctext insert end "$line\n" dresult
        } elseif {![string compare -length 3 "  <" $line]} {
+           set $currdiffsubmod ""
            set line [encoding convertfrom $diffencoding $line]
            $ctext insert end "$line\n" d0
        } elseif {$diffinhdr} {
@@ -8527,7 +8547,7 @@ proc do_cmp_commits {a b} {
 }
 
 proc diffcommits {a b} {
-    global diffcontext diffids blobdifffd diffinhdr
+    global diffcontext diffids blobdifffd diffinhdr currdiffsubmod
 
     set tmpdir [gitknewtmpdir]
     set fna [file join $tmpdir "commit-[string range $a 0 7]"]
@@ -8548,6 +8568,7 @@ proc diffcommits {a b} {
     set diffids [list commits $a $b]
     set blobdifffd($diffids) $fd
     set diffinhdr 0
+    set currdiffsubmod ""
     filerun $fd [list getblobdiffline $fd $diffids]
 }
 
@@ -10528,7 +10549,6 @@ proc mkfontdisp {font top which} {
     set fontpref($font) [set $font]
     ${NS}::button $top.${font}but -text $which \
        -command [list choosefont $font $which]
-    if {!$use_ttk} {$top.${font}but configure  -font optionfont}
     ${NS}::label $top.$font -relief flat -font $font \
        -text $fontattr($font,family) -justify left
     grid x $top.${font}but $top.$font -sticky w
@@ -10791,15 +10811,6 @@ proc doprefs {} {
     mkfontdisp textfont $top [mc "Diff display font"]
     mkfontdisp uifont $top [mc "User interface font"]
 
-    if {!$use_ttk} {
-       foreach w {maxpctl maxwidthl showlocal autoselect tabstopl ntag
-           ldiff lattr extdifff.l extdifff.b bgbut fgbut
-           diffoldbut diffnewbut hunksepbut markbgbut selbgbut
-           want_ttk ttk_note} {
-           $top.$w configure -font optionfont
-       }
-    }
-
     ${NS}::frame $top.buts
     ${NS}::button $top.buts.ok -text [mc "OK"] -command prefsok -default active
     ${NS}::button $top.buts.can -text [mc "Cancel"] -command prefscan -default normal
@@ -10849,6 +10860,7 @@ proc setselbg {c} {
 # radiobuttons look bad.  This chooses white for selectColor if the
 # background color is light, or black if it is dark.
 proc setui {c} {
+    if {[tk windowingsystem] eq "win32"} { return }
     set bg [winfo rgb . $c]
     set selc black
     if {[lindex $bg 0] + 1.5 * [lindex $bg 1] + 0.5 * [lindex $bg 2] > 100000} {
@@ -11411,8 +11423,6 @@ namespace import ::msgcat::mc
 
 catch {source ~/.gitk}
 
-font create optionfont -family sans-serif -size -12
-
 parsefont mainfont $mainfont
 eval font create mainfont [fontflags mainfont]
 eval font create mainfontbold [fontflags mainfont 1]
@@ -11613,3 +11623,9 @@ if {[tk windowingsystem] eq "win32"} {
 }
 
 getcommits {}
+
+# Local variables:
+# mode: tcl
+# indent-tabs-mode: t
+# tab-width: 8
+# End:
index c79aa9cbc813dfe13bb39db2eacd1cc7ab49441c..bd194a3dff9fd36b2edbe64f053a975f489a159b 100644 (file)
@@ -334,14 +334,14 @@ msgid ""
 "\n"
 "Gitk - a commit viewer for git\n"
 "\n"
-"Copyright ©9 2005-2009 Paul Mackerras\n"
+"Copyright \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "Use and redistribute under the terms of the GNU General Public License"
 msgstr ""
 "\n"
 "Gitk - eine Visualisierung der Git-Historie\n"
 "\n"
-"Copyright © 2005-2009 Paul Mackerras\n"
+"Copyright \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "Benutzung und Weiterverbreitung gemäß den Bedingungen der GNU General Public License"
 
index 0e19b5eae27ed10e6cae524e9dc69cca1b1f428f..0471dd0672d837371fad32db5eddd32207e63c1f 100644 (file)
@@ -281,14 +281,14 @@ msgid ""
 "\n"
 "Gitk - a commit viewer for git\n"
 "\n"
-"Copyright © 2005-2008 Paul Mackerras\n"
+"Copyright \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "Use and redistribute under the terms of the GNU General Public License"
 msgstr ""
 "\n"
 "Gitk - un visualizador de revisiones para git\n"
 "\n"
-"Copyright © 2005-2008 Paul Mackerras\n"
+"Copyright \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "Uso y redistribución permitidos según los términos de la Licencia Pública "
 "General de GNU (GNU GPL)"
index cb0e1edc634d29f3ddf83ae39c4f9c75d7374326..5370ddc393dfa0b72220d9e572a60be606927da4 100644 (file)
@@ -334,14 +334,14 @@ msgid ""
 "\n"
 "Gitk - a commit viewer for git\n"
 "\n"
-"Copyright © 2005-2008 Paul Mackerras\n"
+"Copyright \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "Use and redistribute under the terms of the GNU General Public License"
 msgstr ""
 "\n"
 "Gitk - visualisateur de commit pour git\n"
 "\n"
-"Copyright © 2005-2008 Paul Mackerras\n"
+"Copyright \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "Utilisation et redistribution soumises aux termes de la GNU General Public "
 "License"
index 1df212e8817258da3bf870997e42e75fad09fe95..7262b610dc0489ce9bcc4512a7e02bba5c758682 100644 (file)
@@ -333,14 +333,14 @@ msgid ""
 "\n"
 "Gitk - a commit viewer for git\n"
 "\n"
-"Copyright ©9 2005-2009 Paul Mackerras\n"
+"Copyright \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "Use and redistribute under the terms of the GNU General Public License"
 msgstr ""
 "\n"
 "Gitk - commit nézegető a githez\n"
 "\n"
-"Szerzői jog ©9 2005-2009 Paul Mackerras\n"
+"Szerzői jog \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "Használd és terjeszd a GNU General Public License feltételei mellett"
 
index 4818652309d91e90fb4595b500cb687bcdedcb94..a730d63a42ad380548e454410eafcbadece85387 100644 (file)
@@ -334,14 +334,14 @@ msgid ""
 "\n"
 "Gitk - a commit viewer for git\n"
 "\n"
-"Copyright © 2005-2009 Paul Mackerras\n"
+"Copyright \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "Use and redistribute under the terms of the GNU General Public License"
 msgstr ""
 "\n"
 "Gitk - un visualizzatore di revisioni per git\n"
 "\n"
-"Copyright © 2005-2009 Paul Mackerras\n"
+"Copyright \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "Utilizzo e redistribuzione permessi sotto i termini della GNU General Public "
 "License"
index c0c92addb41c9e1e59c0f314a7b37b4470dcebbe..4f4705164c0c71b64bee4e833c0960b9344c2ad9 100644 (file)
@@ -335,14 +335,14 @@ msgid ""
 "\n"
 "Gitk - a commit viewer for git\n"
 "\n"
-"Copyright © 2005-2008 Paul Mackerras\n"
+"Copyright \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "Use and redistribute under the terms of the GNU General Public License"
 msgstr ""
 "\n"
 "Gitk - gitコミットビューア\n"
 "\n"
-"Copyright © 2005-2008 Paul Mackerras\n"
+"Copyright \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "使用および再配布は GNU General Public License に従ってください"
 
index 704eba8f9d39655099aa66864d1dd34a84bd0a9d..c3d0285b2429d92ca40297bfb2135365ba49f371 100644 (file)
@@ -313,14 +313,14 @@ msgid ""
 "\n"
 "Gitk - a commit viewer for git\n"
 "\n"
-"Copyright © 2005-2008 Paul Mackerras\n"
+"Copyright \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "Use and redistribute under the terms of the GNU General Public License"
 msgstr ""
 "\n"
 "Gitk - программа просмотра истории репозиториев Git\n"
 "\n"
-"Copyright (c) 2005-2008 Paul Mackerras\n"
+"Copyright \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "Использование и распространение согласно условиям GNU General Public License"
 
index 0f5e2fd8d79b585e1487b7ba9e2d1a36a49c7c7d..386763ade786d96b657dd0ab737b633eef44b424 100644 (file)
@@ -334,14 +334,14 @@ msgid ""
 "\n"
 "Gitk - a commit viewer for git\n"
 "\n"
-"Copyright ©9 2005-2009 Paul Mackerras\n"
+"Copyright \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "Use and redistribute under the terms of the GNU General Public License"
 msgstr ""
 "\n"
 "Gitk - en incheckningsvisare för git\n"
 "\n"
-"Copyright © 2005-2009 Paul Mackerras\n"
+"Copyright \\u00a9 2005-2010 Paul Mackerras\n"
 "\n"
 "Använd och vidareförmedla enligt villkoren i GNU General Public License"
 
index b76a0cffff783ba580294560f0ee53131776136b..cbdc1364700d79b9d8b41850790baee103f31ca1 100644 (file)
@@ -2,11 +2,11 @@ GIT web Interface (gitweb) Installation
 =======================================
 
 First you have to generate gitweb.cgi from gitweb.perl using
-"make gitweb/gitweb.cgi", then copy appropriate files (gitweb.cgi,
+"make gitweb", then copy appropriate files (gitweb.cgi, gitweb.js,
 gitweb.css, git-logo.png and git-favicon.png) to their destination.
 For example if git was (or is) installed with /usr prefix, you can do
 
-       $ make prefix=/usr gitweb/gitweb.cgi  ;# as yourself
+       $ make prefix=/usr gitweb             ;# as yourself
        # cp gitweb/git* /var/www/cgi-bin/    ;# as root
 
 Alternatively you can use autoconf generated ./configure script to
@@ -15,7 +15,7 @@ instead
 
        $ make configure                     ;# as yourself
        $ ./configure --prefix=/usr          ;# as yourself
-       $ make gitweb/gitweb.cgi             ;# as yourself
+       $ make gitweb                        ;# as yourself
        # cp gitweb/git* /var/www/cgi-bin/   ;# as root
 
 The above example assumes that your web server is configured to run
@@ -31,8 +31,7 @@ file for gitweb (in gitweb/README).
 
 - There are many configuration variables which affect building of
   gitweb.cgi; see "default configuration for gitweb" section in main
-  (top dir) Makefile, and instructions for building gitweb/gitweb.cgi
-  target.
+  (top dir) Makefile, and instructions for building gitweb target.
 
   One of the most important is where to find the git wrapper binary. Gitweb
   tries to find the git wrapper at $(bindir)/git, so you have to set $bindir
@@ -62,9 +61,15 @@ file for gitweb (in gitweb/README).
   a suggestion).
 
 - You can control where gitweb tries to find its main CSS style file,
-  its favicon and logo with the GITWEB_CSS, GITWEB_FAVICON and GITWEB_LOGO
-  build configuration variables. By default gitweb tries to find them
-  in the same directory as gitweb.cgi script.
+  its JavaScript file, its favicon and logo with the GITWEB_CSS, GITWEB_JS
+  GITWEB_FAVICON and GITWEB_LOGO build configuration variables. By default
+  gitweb tries to find them in the same directory as gitweb.cgi script.
+
+- You can optionally generate minified versions of gitweb.js and gitweb.css
+  by defining the JSMIN and CSSMIN build configuration variables. By default
+  the non-minified versions will be used. NOTE: if you enable this option,
+  substitute gitweb.min.js and gitweb.min.css for all uses of gitweb.js and
+  gitweb.css in the help files.
 
 Build example
 ~~~~~~~~~~~~~
@@ -74,13 +79,14 @@ Build example
   we want to display are under /home/local/scm, you can do
 
        make GITWEB_PROJECTROOT="/home/local/scm" \
+            GITWEB_JS="/gitweb/gitweb.js" \
             GITWEB_CSS="/gitweb/gitweb.css" \
             GITWEB_LOGO="/gitweb/git-logo.png" \
             GITWEB_FAVICON="/gitweb/git-favicon.png" \
             bindir=/usr/local/bin \
-            gitweb/gitweb.cgi
+            gitweb
 
-       cp -fv ~/git/gitweb/gitweb.{cgi,css} \
+       cp -fv ~/git/gitweb/gitweb.{cgi,js,css} \
               ~/git/gitweb/git-{favicon,logo}.png \
             /var/www/cgi-bin/gitweb/
 
index c9eb1ee6678aa180d74e3da3a74537766f0b1fe4..f2e1d92fbb965893b14adf2e9acb904bab953812 100644 (file)
@@ -6,14 +6,14 @@ all::
 # Define JSMIN to point to JavaScript minifier that functions as
 # a filter to have gitweb.js minified.
 #
+# Define CSSMIN to point to a CSS minifier in order to generate a minified
+# version of gitweb.css
+#
 
 prefix ?= $(HOME)
 bindir ?= $(prefix)/bin
 RM ?= rm -f
 
-# JavaScript minifier invocation that can function as filter
-JSMIN ?=
-
 # default configuration for gitweb
 GITWEB_CONFIG = gitweb_config.perl
 GITWEB_CONFIG_SYSTEM = /etc/gitweb.conf
@@ -29,11 +29,7 @@ GITWEB_HOMETEXT = indextext.html
 GITWEB_CSS = gitweb.css
 GITWEB_LOGO = git-logo.png
 GITWEB_FAVICON = git-favicon.png
-ifdef JSMIN
-GITWEB_JS = gitweb.min.js
-else
 GITWEB_JS = gitweb.js
-endif
 GITWEB_SITE_HEADER =
 GITWEB_SITE_FOOTER =
 
@@ -85,45 +81,54 @@ endif
 all:: gitweb.cgi
 
 ifdef JSMIN
-FILES=gitweb.cgi gitweb.min.js
-gitweb.cgi: gitweb.perl gitweb.min.js
-else # !JSMIN
-FILES=gitweb.cgi
-gitweb.cgi: gitweb.perl
-endif # JSMIN
-
-gitweb.cgi:
+GITWEB_JS = gitweb.min.js
+all:: gitweb.min.js
+gitweb.min.js: gitweb.js GITWEB-BUILD-OPTIONS
+       $(QUIET_GEN)$(JSMIN) <$< >$@
+endif
+
+ifdef CSSMIN
+GITWEB_CSS = gitweb.min.css
+all:: gitweb.min.css
+gitweb.min.css: gitweb.css GITWEB-BUILD-OPTIONS
+       $(QUIET_GEN)$(CSSMIN) <$ >$@
+endif
+
+GITWEB_REPLACE = \
+       -e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \
+       -e 's|++GIT_BINDIR++|$(bindir)|g' \
+       -e 's|++GITWEB_CONFIG++|$(GITWEB_CONFIG)|g' \
+       -e 's|++GITWEB_CONFIG_SYSTEM++|$(GITWEB_CONFIG_SYSTEM)|g' \
+       -e 's|++GITWEB_HOME_LINK_STR++|$(GITWEB_HOME_LINK_STR)|g' \
+       -e 's|++GITWEB_SITENAME++|$(GITWEB_SITENAME)|g' \
+       -e 's|++GITWEB_PROJECTROOT++|$(GITWEB_PROJECTROOT)|g' \
+       -e 's|"++GITWEB_PROJECT_MAXDEPTH++"|$(GITWEB_PROJECT_MAXDEPTH)|g' \
+       -e 's|++GITWEB_EXPORT_OK++|$(GITWEB_EXPORT_OK)|g' \
+       -e 's|++GITWEB_STRICT_EXPORT++|$(GITWEB_STRICT_EXPORT)|g' \
+       -e 's|++GITWEB_BASE_URL++|$(GITWEB_BASE_URL)|g' \
+       -e 's|++GITWEB_LIST++|$(GITWEB_LIST)|g' \
+       -e 's|++GITWEB_HOMETEXT++|$(GITWEB_HOMETEXT)|g' \
+       -e 's|++GITWEB_CSS++|$(GITWEB_CSS)|g' \
+       -e 's|++GITWEB_LOGO++|$(GITWEB_LOGO)|g' \
+       -e 's|++GITWEB_FAVICON++|$(GITWEB_FAVICON)|g' \
+       -e 's|++GITWEB_JS++|$(GITWEB_JS)|g' \
+       -e 's|++GITWEB_SITE_HEADER++|$(GITWEB_SITE_HEADER)|g' \
+       -e 's|++GITWEB_SITE_FOOTER++|$(GITWEB_SITE_FOOTER)|g'
+
+GITWEB-BUILD-OPTIONS: FORCE
+       @rm -f $@+
+       @echo "x" '$(PERL_PATH_SQ)' $(GITWEB_REPLACE) "$(JSMIN)|$(CSSMIN)" >$@+
+       @cmp -s $@+ $@ && rm -f $@+ || mv -f $@+ $@
+
+gitweb.cgi: gitweb.perl GITWEB-BUILD-OPTIONS
        $(QUIET_GEN)$(RM) $@ $@+ && \
        sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \
-           -e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \
-           -e 's|++GIT_BINDIR++|$(bindir)|g' \
-           -e 's|++GITWEB_CONFIG++|$(GITWEB_CONFIG)|g' \
-           -e 's|++GITWEB_CONFIG_SYSTEM++|$(GITWEB_CONFIG_SYSTEM)|g' \
-           -e 's|++GITWEB_HOME_LINK_STR++|$(GITWEB_HOME_LINK_STR)|g' \
-           -e 's|++GITWEB_SITENAME++|$(GITWEB_SITENAME)|g' \
-           -e 's|++GITWEB_PROJECTROOT++|$(GITWEB_PROJECTROOT)|g' \
-           -e 's|"++GITWEB_PROJECT_MAXDEPTH++"|$(GITWEB_PROJECT_MAXDEPTH)|g' \
-           -e 's|++GITWEB_EXPORT_OK++|$(GITWEB_EXPORT_OK)|g' \
-           -e 's|++GITWEB_STRICT_EXPORT++|$(GITWEB_STRICT_EXPORT)|g' \
-           -e 's|++GITWEB_BASE_URL++|$(GITWEB_BASE_URL)|g' \
-           -e 's|++GITWEB_LIST++|$(GITWEB_LIST)|g' \
-           -e 's|++GITWEB_HOMETEXT++|$(GITWEB_HOMETEXT)|g' \
-           -e 's|++GITWEB_CSS++|$(GITWEB_CSS)|g' \
-           -e 's|++GITWEB_LOGO++|$(GITWEB_LOGO)|g' \
-           -e 's|++GITWEB_FAVICON++|$(GITWEB_FAVICON)|g' \
-           -e 's|++GITWEB_JS++|$(GITWEB_JS)|g' \
-           -e 's|++GITWEB_SITE_HEADER++|$(GITWEB_SITE_HEADER)|g' \
-           -e 's|++GITWEB_SITE_FOOTER++|$(GITWEB_SITE_FOOTER)|g' \
-           $< >$@+ && \
+               $(GITWEB_REPLACE) $< >$@+ && \
        chmod +x $@+ && \
        mv $@+ $@
 
-ifdef JSMIN
-gitweb.min.js: gitweb.js
-       $(QUIET_GEN)$(JSMIN) <$< >$@
-endif # JSMIN
-
 clean:
-       $(RM) $(FILES)
+       $(RM) gitweb.cgi gitweb.min.js gitweb.min.css GITWEB-BUILD-OPTIONS
+
+.PHONY: all clean .FORCE-GIT-VERSION-FILE FORCE
 
-.PHONY: all clean .FORCE-GIT-VERSION-FILE
index ad6a04c464075c31afe3c67222f0bdeabc76f569..71742b335dd786a24699b06b17519e264724ea5b 100644 (file)
@@ -80,7 +80,8 @@ You can specify the following configuration variables when building GIT:
    Points to the location where you put gitweb.css on your web server
    (or to be more generic, the URI of gitweb stylesheet).  Relative to the
    base URI of gitweb.  Note that you can setup multiple stylesheets from
-   the gitweb config file.  [Default: gitweb.css]
+   the gitweb config file.  [Default: gitweb.css (or gitweb.min.css if the
+   CSSMIN variable is defined / CSS minifier is used)]
  * GITWEB_LOGO
    Points to the location where you put git-logo.png on your web server
    (or to be more generic URI of logo, 72x27 size, displayed in top right
diff --git a/grep.c b/grep.c
index fdc42062687fa6b8bb77c8d09ed58aee9107692d..543b1d53784c16020dea089f23c431c7f2608425 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -570,8 +570,7 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
                        if (opt->show_hunk_mark) {
                                output_color(opt, "--", 2, opt->color_sep);
                                opt->output(opt, "\n", 1);
-                       } else
-                               opt->show_hunk_mark = 1;
+                       }
                } else if (lno > opt->last_shown + 1) {
                        output_color(opt, "--", 2, opt->color_sep);
                        opt->output(opt, "\n", 1);
@@ -772,14 +771,6 @@ int grep_threads_ok(const struct grep_opt *opt)
            !opt->name_only)
                return 0;
 
-       /* If we are showing hunk marks, we should not do it for the
-        * first match. The synchronization problem we get for this
-        * constraint is not yet solved, so we disable threading in
-        * this case.
-        */
-       if (opt->pre_context || opt->post_context)
-               return 0;
-
        return 1;
 }
 
@@ -801,11 +792,14 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
        enum grep_context ctx = GREP_CONTEXT_HEAD;
        xdemitconf_t xecfg;
 
-       opt->last_shown = 0;
-
        if (!opt->output)
                opt->output = std_output;
 
+       if (opt->last_shown && (opt->pre_context || opt->post_context) &&
+           opt->output == std_output)
+               opt->show_hunk_mark = 1;
+       opt->last_shown = 0;
+
        if (buffer_is_binary(buf, size)) {
                switch (opt->binary) {
                case GREP_BINARY_DEFAULT:
index 345c12b79064f23e0ae0a15781731b9a42272d83..d1e83d0906dbc9d677630cdf74615ec3f9dfc46d 100644 (file)
@@ -538,15 +538,19 @@ static void service_rpc(char *service_name)
 
 static NORETURN void die_webcgi(const char *err, va_list params)
 {
-       char buffer[1000];
+       static int dead;
 
-       http_status(500, "Internal Server Error");
-       hdr_nocache();
-       end_headers();
+       if (!dead) {
+               char buffer[1000];
+               dead = 1;
 
-       vsnprintf(buffer, sizeof(buffer), err, params);
-       fprintf(stderr, "fatal: %s\n", buffer);
-       exit(0);
+               vsnprintf(buffer, sizeof(buffer), err, params);
+               fprintf(stderr, "fatal: %s\n", buffer);
+               http_status(500, "Internal Server Error");
+               hdr_nocache();
+               end_headers();
+       }
+       exit(0); /* we successfully reported a failure ;-) */
 }
 
 static char* getdir(void)
index 7107923a39247b5c18ad443dc2309971e44abdb4..9d0097ca02960460ff3a104f1739982fee453987 100644 (file)
@@ -1431,8 +1431,14 @@ static int count_messages(struct msg_data *msg)
 
        while (1) {
                if (!prefixcmp(p, "From ")) {
+                       p = strstr(p+5, "\nFrom: ");
+                       if (!p) break;
+                       p = strstr(p+7, "\nDate: ");
+                       if (!p) break;
+                       p = strstr(p+7, "\nSubject: ");
+                       if (!p) break;
+                       p += 10;
                        count++;
-                       p += 5;
                }
                p = strstr(p+5, "\nFrom ");
                if (!p)
index 82c7742e41f4645e7d6086bb277437a84ff4f03b..f9b3d854a921ab6fa3eed6f4dbf01af1a8657602 100644 (file)
@@ -15,7 +15,7 @@ struct ll_merge_driver;
 typedef int (*ll_merge_fn)(const struct ll_merge_driver *,
                           mmbuffer_t *result,
                           const char *path,
-                          mmfile_t *orig,
+                          mmfile_t *orig, const char *orig_name,
                           mmfile_t *src1, const char *name1,
                           mmfile_t *src2, const char *name2,
                           int flag,
@@ -36,7 +36,7 @@ struct ll_merge_driver {
 static int ll_binary_merge(const struct ll_merge_driver *drv_unused,
                           mmbuffer_t *result,
                           const char *path_unused,
-                          mmfile_t *orig,
+                          mmfile_t *orig, const char *orig_name,
                           mmfile_t *src1, const char *name1,
                           mmfile_t *src2, const char *name2,
                           int flag, int marker_size)
@@ -57,7 +57,7 @@ static int ll_binary_merge(const struct ll_merge_driver *drv_unused,
 static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
                        mmbuffer_t *result,
                        const char *path,
-                       mmfile_t *orig,
+                       mmfile_t *orig, const char *orig_name,
                        mmfile_t *src1, const char *name1,
                        mmfile_t *src2, const char *name2,
                        int flag, int marker_size)
@@ -71,7 +71,8 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
                        path, name1, name2);
                return ll_binary_merge(drv_unused, result,
                                       path,
-                                      orig, src1, name1,
+                                      orig, orig_name,
+                                      src1, name1,
                                       src2, name2,
                                       flag, marker_size);
        }
@@ -83,13 +84,16 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
                xmp.style = git_xmerge_style;
        if (marker_size > 0)
                xmp.marker_size = marker_size;
-       return xdl_merge(orig, src1, name1, src2, name2, &xmp, result);
+       xmp.ancestor = orig_name;
+       xmp.file1 = name1;
+       xmp.file2 = name2;
+       return xdl_merge(orig, src1, src2, &xmp, result);
 }
 
 static int ll_union_merge(const struct ll_merge_driver *drv_unused,
                          mmbuffer_t *result,
                          const char *path_unused,
-                         mmfile_t *orig,
+                         mmfile_t *orig, const char *orig_name,
                          mmfile_t *src1, const char *name1,
                          mmfile_t *src2, const char *name2,
                          int flag, int marker_size)
@@ -97,7 +101,7 @@ static int ll_union_merge(const struct ll_merge_driver *drv_unused,
        /* Use union favor */
        flag = (flag & 1) | (XDL_MERGE_FAVOR_UNION << 1);
        return ll_xdl_merge(drv_unused, result, path_unused,
-                           orig, src1, NULL, src2, NULL,
+                           orig, NULL, src1, NULL, src2, NULL,
                            flag, marker_size);
        return 0;
 }
@@ -128,7 +132,7 @@ static void create_temp(mmfile_t *src, char *path)
 static int ll_ext_merge(const struct ll_merge_driver *fn,
                        mmbuffer_t *result,
                        const char *path,
-                       mmfile_t *orig,
+                       mmfile_t *orig, const char *orig_name,
                        mmfile_t *src1, const char *name1,
                        mmfile_t *src2, const char *name2,
                        int flag, int marker_size)
@@ -319,7 +323,7 @@ static int git_path_check_merge(const char *path, struct git_attr_check check[2]
 
 int ll_merge(mmbuffer_t *result_buf,
             const char *path,
-            mmfile_t *ancestor,
+            mmfile_t *ancestor, const char *ancestor_label,
             mmfile_t *ours, const char *our_label,
             mmfile_t *theirs, const char *their_label,
             int flag)
@@ -341,7 +345,7 @@ int ll_merge(mmbuffer_t *result_buf,
        driver = find_ll_merge_driver(ll_driver_name);
        if (virtual_ancestor && driver->recursive)
                driver = find_ll_merge_driver(driver->recursive);
-       return driver->fn(driver, result_buf, path, ancestor,
+       return driver->fn(driver, result_buf, path, ancestor, ancestor_label,
                          ours, our_label, theirs, their_label,
                          flag, marker_size);
 }
index 57889227b1782d3792be2046fbb54bca67b779de..57754cc8ca7b378a86b168a4fd6299fa3dfba045 100644 (file)
@@ -7,7 +7,7 @@
 
 int ll_merge(mmbuffer_t *result_buf,
             const char *path,
-            mmfile_t *ancestor,
+            mmfile_t *ancestor, const char *ancestor_label,
             mmfile_t *ours, const char *our_label,
             mmfile_t *theirs, const char *their_label,
             int flag);
index fd34d76e1516b2c944778a11a5670d382f245873..c336c93c01c0bad76d6189065f0e6630d0b7f5af 100644 (file)
@@ -30,7 +30,13 @@ static void *three_way_filemerge(const char *path, mmfile_t *base, mmfile_t *our
        int merge_status;
        mmbuffer_t res;
 
-       merge_status = ll_merge(&res, path, base,
+       /*
+        * This function is only used by cmd_merge_tree, which
+        * does not respect the merge.conflictstyle option.
+        * There is no need to worry about a label for the
+        * common ancestor.
+        */
+       merge_status = ll_merge(&res, path, base, NULL,
                                our, ".our", their, ".their", 0);
        if (merge_status < 0)
                return NULL;
index 195ebf974435b0b08cd2be0f54c137218034008b..206c1036359ce7b1fc5a1f5734b2d0bc2a760d90 100644 (file)
@@ -409,7 +409,7 @@ static int remove_file(struct merge_options *o, int clean,
                        return -1;
        }
        if (update_working_directory) {
-               if (remove_path(path) && errno != ENOENT)
+               if (remove_path(path))
                        return -1;
        }
        return 0;
@@ -608,7 +608,7 @@ static int merge_3way(struct merge_options *o,
                      const char *branch2)
 {
        mmfile_t orig, src1, src2;
-       char *name1, *name2;
+       char *base_name, *name1, *name2;
        int merge_status;
        int favor;
 
@@ -628,10 +628,15 @@ static int merge_3way(struct merge_options *o,
                }
        }
 
-       if (strcmp(a->path, b->path)) {
+       if (strcmp(a->path, b->path) ||
+           (o->ancestor != NULL && strcmp(a->path, one->path) != 0)) {
+               base_name = o->ancestor == NULL ? NULL :
+                       xstrdup(mkpath("%s:%s", o->ancestor, one->path));
                name1 = xstrdup(mkpath("%s:%s", branch1, a->path));
                name2 = xstrdup(mkpath("%s:%s", branch2, b->path));
        } else {
+               base_name = o->ancestor == NULL ? NULL :
+                       xstrdup(mkpath("%s", o->ancestor));
                name1 = xstrdup(mkpath("%s", branch1));
                name2 = xstrdup(mkpath("%s", branch2));
        }
@@ -640,7 +645,7 @@ static int merge_3way(struct merge_options *o,
        read_mmblob(&src1, a->sha1);
        read_mmblob(&src2, b->sha1);
 
-       merge_status = ll_merge(result_buf, a->path, &orig,
+       merge_status = ll_merge(result_buf, a->path, &orig, base_name,
                                &src1, name1, &src2, name2,
                                (!!o->call_depth) | (favor << 1));
 
@@ -1342,6 +1347,7 @@ int merge_recursive(struct merge_options *o,
        if (!o->call_depth)
                read_cache();
 
+       o->ancestor = "merged common ancestors";
        clean = merge_trees(o, h1->tree, h2->tree, merged_common_ancestors->tree,
                            &mrtree);
 
index be8410ad1803bc10e5dbf74f39eecdfed53469b1..d1192f56d797a1664f5bfb5028d52ad679928e23 100644 (file)
@@ -4,6 +4,7 @@
 #include "string-list.h"
 
 struct merge_options {
+       const char *ancestor;
        const char *branch1;
        const char *branch2;
        enum {
diff --git a/notes.h b/notes.h
index ee65bd1a2430d4af53f03fd2cc9faa916863408c..9f59277c516f7ac78bcc66f91a7d7013b2a77f65 100644 (file)
--- a/notes.h
+++ b/notes.h
@@ -212,7 +212,7 @@ void format_note(struct notes_tree *t, const unsigned char *object_sha1,
 struct string_list;
 
 struct display_notes_opt {
-       int suppress_default_notes:1;
+       unsigned int suppress_default_notes:1;
        struct string_list *extra_notes_refs;
 };
 
index 6ba3da89b7d29ef35a6ac9215b4f3e0abe7a582f..7cb3a2af508bb5667cd74304f72b50766c749990 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -775,10 +775,13 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
                }
                return 0;       /* unknown %g placeholder */
        case 'N':
-               format_display_notes(commit->object.sha1, sb,
-                           git_log_output_encoding ? git_log_output_encoding
-                                                   : git_commit_encoding, 0);
-               return 1;
+               if (c->pretty_ctx->show_notes) {
+                       format_display_notes(commit->object.sha1, sb,
+                                   git_log_output_encoding ? git_log_output_encoding
+                                                           : git_commit_encoding, 0);
+                       return 1;
+               }
+               return 0;
        }
 
        /* For the rest we have to parse the commit header. */
@@ -855,6 +858,35 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
        return consumed + 1;
 }
 
+static size_t userformat_want_item(struct strbuf *sb, const char *placeholder,
+                                  void *context)
+{
+       struct userformat_want *w = context;
+
+       if (*placeholder == '+' || *placeholder == '-')
+               placeholder++;
+
+       switch (*placeholder) {
+       case 'N':
+               w->notes = 1;
+               break;
+       }
+       return 0;
+}
+
+void userformat_find_requirements(const char *fmt, struct userformat_want *w)
+{
+       struct strbuf dummy = STRBUF_INIT;
+
+       if (!fmt) {
+               if (!user_format)
+                       return;
+               fmt = user_format;
+       }
+       strbuf_expand(&dummy, user_format, userformat_want_item, w);
+       strbuf_release(&dummy);
+}
+
 void format_commit_message(const struct commit *commit,
                           const char *format, struct strbuf *sb,
                           const struct pretty_print_context *pretty_ctx)
diff --git a/refs.c b/refs.c
index 0f24c8d5d9fa897c0b72c529c9fd2ccbcc7bd4d9..d3db15a76cc46f6f6a31d4448816c09e6c48e543 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -1276,6 +1276,7 @@ static int log_ref_write(const char *ref_name, const unsigned char *old_sha1,
        if (log_all_ref_updates &&
            (!prefixcmp(ref_name, "refs/heads/") ||
             !prefixcmp(ref_name, "refs/remotes/") ||
+            !prefixcmp(ref_name, "refs/notes/") ||
             !strcmp(ref_name, "HEAD"))) {
                if (safe_create_leading_directories(log_file) < 0)
                        return error("unable to create directory for %s",
index a59f74f76c293efa783103eaf3d167c97b3768ea..f221bed1e97a0f1b41d1845edac270a109e3a4dd 100644 (file)
--- a/rerere.c
+++ b/rerere.c
@@ -319,7 +319,7 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu
                if (!mmfile[i].ptr && !mmfile[i].size)
                        mmfile[i].ptr = xstrdup("");
        }
-       ll_merge(&result, path, &mmfile[0],
+       ll_merge(&result, path, &mmfile[0], NULL,
                 &mmfile[1], "ours",
                 &mmfile[2], "theirs", 0);
        for (i = 0; i < 3; i++)
@@ -376,7 +376,7 @@ static int merge(const char *name, const char *path)
                ret = 1;
                goto out;
        }
-       ret = ll_merge(&result, path, &base, &cur, "", &other, "", 0);
+       ret = ll_merge(&result, path, &base, NULL, &cur, "", &other, "", 0);
        if (!ret) {
                FILE *f = fopen(path, "w");
                if (!f)
index c8d53795ec3ae9b8b0a73b3d6900c1a1f212d2c2..eb5c57562909c1e505c2a7688bad6dbeea4b96a0 100644 (file)
@@ -342,8 +342,6 @@ fail_pipe:
        else if (cmd->out > 1)
                fhout = dup(cmd->out);
 
-       if (cmd->dir)
-               die("chdir in start_command() not implemented");
        if (cmd->env)
                env = make_augmented_environ(cmd->env);
 
@@ -353,7 +351,7 @@ fail_pipe:
                cmd->argv = prepare_shell_cmd(cmd->argv);
        }
 
-       cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env,
+       cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env, cmd->dir,
                                  fhin, fhout, fherr);
        failed_errno = errno;
        if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT))
index 1ac536e638dbbc02deb2d4e4a607cc52f7f7c108..c9ad7fcd49669b0dff481d9ab857bf70d8a51bca 100644 (file)
@@ -168,12 +168,19 @@ void sort_string_list(struct string_list *list)
        qsort(list->items, list->nr, sizeof(*list->items), cmp_items);
 }
 
-int unsorted_string_list_has_string(struct string_list *list, const char *string)
+struct string_list_item *unsorted_string_list_lookup(struct string_list *list,
+                                                    const char *string)
 {
        int i;
        for (i = 0; i < list->nr; i++)
                if (!strcmp(string, list->items[i].string))
-                       return 1;
-       return 0;
+                       return list->items + i;
+       return NULL;
+}
+
+int unsorted_string_list_has_string(struct string_list *list,
+                                   const char *string)
+{
+       return unsorted_string_list_lookup(list, string) != NULL;
 }
 
index 6569cf607b18b84f39ebee613471f270e42cfbdc..63b69c8d75ee33120a65a23598ddf93e84831bdd 100644 (file)
@@ -38,5 +38,6 @@ struct string_list_item *string_list_lookup(const char *string, struct string_li
 struct string_list_item *string_list_append(const char *string, struct string_list *list);
 void sort_string_list(struct string_list *list);
 int unsorted_string_list_has_string(struct string_list *list, const char *string);
-
+struct string_list_item *unsorted_string_list_lookup(struct string_list *list,
+                                                    const char *string);
 #endif /* STRING_LIST_H */
index b3b8bc147909f81be6a387318ad0601dae50460f..676d48fb33119f393befcaf8998ad38741366525 100644 (file)
@@ -12,8 +12,15 @@ static int add_submodule_odb(const char *path)
        struct strbuf objects_directory = STRBUF_INIT;
        struct alternate_object_database *alt_odb;
        int ret = 0;
+       const char *git_dir;
 
-       strbuf_addf(&objects_directory, "%s/.git/objects/", path);
+       strbuf_addf(&objects_directory, "%s/.git", path);
+       git_dir = read_gitfile_gently(objects_directory.buf);
+       if (git_dir) {
+               strbuf_reset(&objects_directory);
+               strbuf_addstr(&objects_directory, git_dir);
+       }
+       strbuf_addstr(&objects_directory, "/objects/");
        if (!is_directory(objects_directory.buf)) {
                ret = -1;
                goto done;
@@ -132,7 +139,6 @@ void show_submodule_summary(FILE *f, const char *path,
 
 unsigned is_submodule_modified(const char *path, int ignore_untracked)
 {
-       int i;
        ssize_t len;
        struct child_process cp;
        const char *argv[] = {
@@ -141,16 +147,16 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)
                NULL,
                NULL,
        };
-       const char *env[LOCAL_REPO_ENV_SIZE + 3];
        struct strbuf buf = STRBUF_INIT;
        unsigned dirty_submodule = 0;
        const char *line, *next_line;
+       const char *git_dir;
 
-       for (i = 0; i < LOCAL_REPO_ENV_SIZE; i++)
-               env[i] = local_repo_env[i];
-
-       strbuf_addf(&buf, "%s/.git/", path);
-       if (!is_directory(buf.buf)) {
+       strbuf_addf(&buf, "%s/.git", path);
+       git_dir = read_gitfile_gently(buf.buf);
+       if (!git_dir)
+               git_dir = buf.buf;
+       if (!is_directory(git_dir)) {
                strbuf_release(&buf);
                /* The submodule is not checked out, so it is not modified */
                return 0;
@@ -158,21 +164,16 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)
        }
        strbuf_reset(&buf);
 
-       strbuf_addf(&buf, "GIT_WORK_TREE=%s", path);
-       env[i++] = strbuf_detach(&buf, NULL);
-       strbuf_addf(&buf, "GIT_DIR=%s/.git", path);
-       env[i++] = strbuf_detach(&buf, NULL);
-       env[i] = NULL;
-
        if (ignore_untracked)
                argv[2] = "-uno";
 
        memset(&cp, 0, sizeof(cp));
        cp.argv = argv;
-       cp.env = env;
+       cp.env = local_repo_env;
        cp.git_cmd = 1;
        cp.no_stdin = 1;
        cp.out = -1;
+       cp.dir = path;
        if (start_command(&cp))
                die("Could not run git status --porcelain");
 
@@ -201,8 +202,6 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)
        if (finish_command(&cp))
                die("git status --porcelain failed");
 
-       for (i = LOCAL_REPO_ENV_SIZE; env[i]; i++)
-               free((char *)env[i]);
        strbuf_release(&buf);
        return dirty_submodule;
 }
index f4ca4fc85c6b52a2ba919528284f2b668e6bd3d2..3ec9cbef2c88f65e5fb254d10cc551c6c4062c88 100755 (executable)
@@ -73,6 +73,27 @@ then
        exit 1
 fi
 
+clean=no
+test_expect_success 'tests clean up after themselves' '
+    test_when_finished clean=yes
+'
+
+cleaner=no
+test_expect_code 1 'tests clean up even after a failure' '
+    test_when_finished cleaner=yes &&
+    (exit 1)
+'
+
+if test $clean$cleaner != yesyes
+then
+       say "bug in test framework: cleanup commands do not work reliably"
+       exit 1
+fi
+
+test_expect_code 2 'failure to clean up causes the test to fail' '
+    test_when_finished "(exit 2)"
+'
+
 ################################################################
 # Basics of the basics
 
index 9956e3ad625eb1d70789538ecdb55e318669bdf9..b946f8768649dd76d8a175877c63d49244e00ffb 100755 (executable)
@@ -58,14 +58,12 @@ test_expect_success 'allow missing object with --missing' '
        test_cmp tree.missing actual
 '
 
-test_expect_failure 'mktree reads ls-tree -r output (1)' '
-       git mktree <all >actual &&
-       test_cmp tree actual
+test_expect_success 'mktree refuses to read ls-tree -r output (1)' '
+       test_must_fail git mktree <all >actual
 '
 
-test_expect_failure 'mktree reads ls-tree -r output (2)' '
-       git mktree <all.withsub >actual &&
-       test_cmp tree.withsub actual
+test_expect_success 'mktree refuses to read ls-tree -r output (2)' '
+       test_must_fail git mktree <all.withsub >actual
 '
 
 test_done
index cc30be4a655cad98eac233b5da9fc585ddb5d055..055ad00f778eda1de02a418bbc602e580acdaca1 100755 (executable)
@@ -20,34 +20,23 @@ if ! setfacl -m u:root:rwx .; then
     test_done
 fi
 
-modebits () {
-       ls -l "$1" | sed -e 's|^\(..........\).*|\1|'
-}
-
 check_perms_and_acl () {
-       actual=$(modebits "$1") &&
-       case "$actual" in
-       -r--r-----*)
-               : happy
-               ;;
-       *)
-               echo "Got permission '$actual', expected '-r--r-----'"
-               false
-               ;;
-       esac &&
+       test -r "$1" &&
        getfacl "$1" > actual &&
        grep -q "user:root:rwx" actual &&
        grep -q "user:${LOGNAME}:rwx" actual &&
-       grep -q "mask::r--" actual &&
+       egrep "mask::?r--" actual > /dev/null 2>&1 &&
        grep -q "group::---" actual || false
 }
 
 dirs_to_set="./ .git/ .git/objects/ .git/objects/pack/"
 
 test_expect_success 'Setup test repo' '
+       setfacl -m d:u::rwx,d:g::---,d:o:---,d:m:rwx $dirs_to_set &&
+       setfacl -m m:rwx               $dirs_to_set &&
        setfacl -m u:root:rwx          $dirs_to_set &&
-       setfacl -d -m u:"$LOGNAME":rwx $dirs_to_set &&
-       setfacl -d -m u:root:rwx       $dirs_to_set &&
+       setfacl -m d:u:"$LOGNAME":rwx  $dirs_to_set &&
+       setfacl -m d:u:root:rwx        $dirs_to_set &&
 
        touch file.txt &&
        git add file.txt &&
index 1d6cd45b55a2ae2e0a7d6728b04112d1c0f43446..64f32ad94dfe842746774596b88c91e873da864f 100755 (executable)
@@ -55,6 +55,15 @@ test_expect_success 'handle empty notes gracefully' '
        git notes show ; test 1 = $?
 '
 
+test_expect_success 'show non-existent notes entry with %N' '
+       for l in A B
+       do
+               echo "$l"
+       done >expect &&
+       git show -s --format='A%n%NB' >output &&
+       test_cmp expect output
+'
+
 test_expect_success 'create notes' '
        git config core.notesRef refs/notes/commits &&
        MSG=b4 git notes add &&
@@ -65,6 +74,24 @@ test_expect_success 'create notes' '
        test_must_fail git notes show HEAD^
 '
 
+test_expect_success 'show notes entry with %N' '
+       for l in A b4 B
+       do
+               echo "$l"
+       done >expect &&
+       git show -s --format='A%n%NB' >output &&
+       test_cmp expect output
+'
+
+cat >expect <<EOF
+d423f8c refs/notes/commits@{0}: notes: Notes added by 'git notes add'
+EOF
+
+test_expect_success 'create reflog entry' '
+       git reflog show refs/notes/commits >output &&
+       test_cmp expect output
+'
+
 test_expect_success 'edit existing notes' '
        MSG=b3 git notes edit &&
        test ! -f .git/NOTES_EDITMSG &&
index 19668c2c9206c5dfe63a5992bc7d011a9cdb4083..f20ea38411d0ca67709dbde0bfd1108e28c0dd71 100755 (executable)
@@ -22,12 +22,18 @@ set_fake_editor
 # | \
 # |   F - G - H                (branch1)
 # |     \
-#  \      I                    (branch2)
-#   \
-#     J - K - L - M            (no-conflict-branch)
+# |\      I                    (branch2)
+# | \
+# |   J - K - L - M            (no-conflict-branch)
+#  \
+#    N - O - P                 (no-ff-branch)
 #
 # where A, B, D and G all touch file1, and one, two, three, four all
 # touch file "conflict".
+#
+# WARNING: Modifications to the initial repository can change the SHA ID used
+# in the expect2 file for the 'stop on conflicting pick' test.
+
 
 test_expect_success 'setup' '
        test_commit A file1 &&
@@ -48,6 +54,11 @@ test_expect_success 'setup' '
        done &&
        git checkout -b no-conflict-branch A &&
        for n in J K L M
+       do
+               test_commit $n file$n
+       done &&
+       git checkout -b no-ff-branch A &&
+       for n in N O P
        do
                test_commit $n file$n
        done
@@ -113,7 +124,7 @@ cat > expect2 << EOF
 D
 =======
 G
->>>>>>> 51047de... G
+>>>>>>> 5d18e54... G
 EOF
 
 test_expect_success 'stop on conflicting pick' '
@@ -577,4 +588,30 @@ test_expect_success 'rebase -i can copy notes over a fixup' '
        test_cmp expect output
 '
 
+test_expect_success 'rebase while detaching HEAD' '
+       git symbolic-ref HEAD &&
+       grandparent=$(git rev-parse HEAD~2) &&
+       test_tick &&
+       FAKE_LINES="2 1" git rebase -i HEAD~2 HEAD^0 &&
+       test $grandparent = $(git rev-parse HEAD~2) &&
+       test_must_fail git symbolic-ref HEAD
+'
+
+test_tick # Ensure that the rebased commits get a different timestamp.
+test_expect_success 'always cherry-pick with --no-ff' '
+       git checkout no-ff-branch &&
+       git tag original-no-ff-branch &&
+       git rebase -i --no-ff A &&
+       touch empty &&
+       for p in 0 1 2
+       do
+               test ! $(git rev-parse HEAD~$p) = $(git rev-parse original-no-ff-branch~$p) &&
+               git diff HEAD~$p original-no-ff-branch~$p > out &&
+               test_cmp empty out
+       done &&
+       test $(git rev-parse HEAD~3) = $(git rev-parse original-no-ff-branch~3) &&
+       git diff HEAD~3 original-no-ff-branch~3 > out &&
+       test_cmp empty out
+'
+
 test_done
diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
new file mode 100755 (executable)
index 0000000..e25cf80
--- /dev/null
@@ -0,0 +1,198 @@
+#!/bin/sh
+
+test_description='test cherry-pick and revert with conflicts
+
+  -
+  + picked: rewrites foo to c
+  + base: rewrites foo to b
+  + initial: writes foo as a, unrelated as unrelated
+
+'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+       echo unrelated >unrelated &&
+       git add unrelated &&
+       test_commit initial foo a &&
+       test_commit base foo b &&
+       test_commit picked foo c &&
+       git config advice.detachedhead false
+
+'
+
+test_expect_success 'failed cherry-pick does not advance HEAD' '
+
+       git checkout -f initial^0 &&
+       git read-tree -u --reset HEAD &&
+       git clean -d -f -f -q -x &&
+
+       git update-index --refresh &&
+       git diff-index --exit-code HEAD &&
+
+       head=$(git rev-parse HEAD) &&
+       test_must_fail git cherry-pick picked &&
+       newhead=$(git rev-parse HEAD) &&
+
+       test "$head" = "$newhead"
+'
+
+test_expect_success 'failed cherry-pick produces dirty index' '
+
+       git checkout -f initial^0 &&
+       git read-tree -u --reset HEAD &&
+       git clean -d -f -f -q -x &&
+
+       git update-index --refresh &&
+       git diff-index --exit-code HEAD &&
+
+       test_must_fail git cherry-pick picked &&
+
+       test_must_fail git update-index --refresh -q &&
+       test_must_fail git diff-index --exit-code HEAD
+'
+
+test_expect_success 'failed cherry-pick registers participants in index' '
+
+       git read-tree -u --reset HEAD &&
+       git clean -d -f -f -q -x &&
+       {
+               git checkout base -- foo &&
+               git ls-files --stage foo &&
+               git checkout initial -- foo &&
+               git ls-files --stage foo &&
+               git checkout picked -- foo &&
+               git ls-files --stage foo
+       } > stages &&
+       sed "
+               1 s/ 0  / 1     /
+               2 s/ 0  / 2     /
+               3 s/ 0  / 3     /
+       " < stages > expected &&
+       git checkout -f initial^0 &&
+
+       git update-index --refresh &&
+       git diff-index --exit-code HEAD &&
+
+       test_must_fail git cherry-pick picked &&
+       git ls-files --stage --unmerged > actual &&
+
+       test_cmp expected actual
+'
+
+test_expect_success 'failed cherry-pick describes conflict in work tree' '
+
+       git checkout -f initial^0 &&
+       git read-tree -u --reset HEAD &&
+       git clean -d -f -f -q -x &&
+       cat <<-EOF > expected &&
+       <<<<<<< HEAD
+       a
+       =======
+       c
+       >>>>>>> objid picked
+       EOF
+
+       git update-index --refresh &&
+       git diff-index --exit-code HEAD &&
+
+       test_must_fail git cherry-pick picked &&
+
+       sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
+       test_cmp expected actual
+'
+
+test_expect_success 'diff3 -m style' '
+
+       git config merge.conflictstyle diff3 &&
+       git checkout -f initial^0 &&
+       git read-tree -u --reset HEAD &&
+       git clean -d -f -f -q -x &&
+       cat <<-EOF > expected &&
+       <<<<<<< HEAD
+       a
+       ||||||| parent of objid picked
+       b
+       =======
+       c
+       >>>>>>> objid picked
+       EOF
+
+       git update-index --refresh &&
+       git diff-index --exit-code HEAD &&
+
+       test_must_fail git cherry-pick picked &&
+
+       sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
+       test_cmp expected actual
+'
+
+test_expect_success 'revert also handles conflicts sanely' '
+
+       git config --unset merge.conflictstyle &&
+       git read-tree -u --reset HEAD &&
+       git clean -d -f -f -q -x &&
+       cat <<-EOF > expected &&
+       <<<<<<< HEAD
+       a
+       =======
+       b
+       >>>>>>> parent of objid picked
+       EOF
+       {
+               git checkout picked -- foo &&
+               git ls-files --stage foo &&
+               git checkout initial -- foo &&
+               git ls-files --stage foo &&
+               git checkout base -- foo &&
+               git ls-files --stage foo
+       } > stages &&
+       sed "
+               1 s/ 0  / 1     /
+               2 s/ 0  / 2     /
+               3 s/ 0  / 3     /
+       " < stages > expected-stages &&
+       git checkout -f initial^0 &&
+
+       git update-index --refresh &&
+       git diff-index --exit-code HEAD &&
+
+       head=$(git rev-parse HEAD) &&
+       test_must_fail git revert picked &&
+       newhead=$(git rev-parse HEAD) &&
+       git ls-files --stage --unmerged > actual-stages &&
+
+       test "$head" = "$newhead" &&
+       test_must_fail git update-index --refresh -q &&
+       test_must_fail git diff-index --exit-code HEAD &&
+       test_cmp expected-stages actual-stages &&
+       sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
+       test_cmp expected actual
+'
+
+test_expect_success 'revert conflict, diff3 -m style' '
+       git config merge.conflictstyle diff3 &&
+       git checkout -f initial^0 &&
+       git read-tree -u --reset HEAD &&
+       git clean -d -f -f -q -x &&
+       cat <<-EOF > expected &&
+       <<<<<<< HEAD
+       a
+       ||||||| objid picked
+       c
+       =======
+       b
+       >>>>>>> parent of objid picked
+       EOF
+
+       git update-index --refresh &&
+       git diff-index --exit-code HEAD &&
+
+       test_must_fail git revert picked &&
+
+       sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
+       test_cmp expected actual
+'
+
+test_done
index 0391a5827ea8ba196b7796b7df818f8ac860c387..61589853df55e063fbe6489fc9c6effc4a9f33b6 100755 (executable)
@@ -120,7 +120,6 @@ test_expect_success '--check with --no-pager returns 2 for dirty difference' '
 
 '
 
-
 test_expect_success 'check should test not just the last line' '
        echo "" >>a &&
        git --no-pager diff --check
@@ -142,4 +141,26 @@ test_expect_success 'check detects leftover conflict markers' '
        git reset --hard
 '
 
+test_expect_success 'check honors conflict marker length' '
+       git reset --hard &&
+       echo ">>>>>>> boo" >>b &&
+       echo "======" >>a &&
+       git diff --check a &&
+       (
+               git diff --check b
+               test $? = 2
+       ) &&
+       git reset --hard &&
+       echo ">>>>>>>> boo" >>b &&
+       echo "========" >>a &&
+       git diff --check &&
+       echo "b conflict-marker-size=8" >.gitattributes &&
+       (
+               git diff --check b
+               test $? = 2
+       ) &&
+       git diff --check a &&
+       git reset --hard
+'
+
 test_done
index 7584efa36b06effd9005b8ebcc6afecec07e424b..40277c77aad5f2d9533e6822da3380bb49621e59 100755 (executable)
@@ -81,4 +81,12 @@ test_expect_success 'check combined output (2)' '
        verify_helper sidesansone
 '
 
+test_expect_success 'diagnose truncated file' '
+       >file &&
+       git add file &&
+       git commit --amend -C HEAD &&
+       git show >out &&
+       grep "diff --cc file" out
+'
+
 test_done
index 11b19972ca89f20faaa35b8a2c9fcd7f97181f78..019acb926d6765bf24e1dfe4bea2a9dba28ca797 100755 (executable)
@@ -329,4 +329,19 @@ index 0000000..$head7
 EOF
 "
 
+test_expect_success 'setup .git file for sm2' '
+       (cd sm2 &&
+        REAL="$(pwd)/../.real" &&
+        mv .git "$REAL"
+        echo "gitdir: $REAL" >.git)
+'
+
+test_expect_success 'diff --submodule with .git file' '
+       git diff --submodule HEAD^ >actual &&
+       diff actual - <<-EOF
+Submodule sm1 $head6...0000000 (submodule deleted)
+Submodule sm2 0000000...$head7 (new submodule)
+EOF
+'
+
 test_done
diff --git a/t/t4134-apply-submodule.sh b/t/t4134-apply-submodule.sh
new file mode 100755 (executable)
index 0000000..1b82f93
--- /dev/null
@@ -0,0 +1,38 @@
+#!/bin/sh
+#
+# Copyright (c) 2010 Peter Collingbourne
+#
+
+test_description='git apply submodule tests'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+       cat > create-sm.patch <<EOF
+diff --git a/dir/sm b/dir/sm
+new file mode 160000
+index 0000000..0123456
+--- /dev/null
++++ b/dir/sm
+@@ -0,0 +1 @@
++Subproject commit 0123456789abcdef0123456789abcdef01234567
+EOF
+       cat > remove-sm.patch <<EOF
+diff --git a/dir/sm b/dir/sm
+deleted file mode 160000
+index 0123456..0000000
+--- a/dir/sm
++++ /dev/null
+@@ -1 +0,0 @@
+-Subproject commit 0123456789abcdef0123456789abcdef01234567
+EOF
+'
+
+test_expect_success 'removing a submodule also removes all leading subdirectories' '
+       git apply --index create-sm.patch &&
+       test -d dir/sm &&
+       git apply --index remove-sm.patch &&
+       test \! -d dir
+'
+
+test_done
index 26920502093a98d4b5721f783e006de9d999792a..230c0cd784b317856749609cf64a5067e35a6965 100755 (executable)
@@ -110,17 +110,18 @@ test_expect_success 'remove remote' '
 test_expect_success 'remove remote protects non-remote branches' '
 (
        cd test &&
-       (cat >expect1 <<EOF
+       cat >expect1 <<EOF
 Note: A non-remote branch was not removed; to delete it, use:
   git branch -d master
 EOF
-    cat >expect2 <<EOF
+       } &&
+       { cat >expect2 <<EOF
 Note: Non-remote branches were not removed; to delete them, use:
   git branch -d foobranch
   git branch -d master
 EOF
-) &&
-       git tag footag
+       } &&
+       git tag footag &&
        git config --add remote.oops.fetch "+refs/*:refs/*" &&
        git remote rm oops 2>actual1 &&
        git branch foobranch &&
@@ -534,43 +535,34 @@ test_expect_success 'show empty remote' '
 '
 
 test_expect_success 'new remote' '
-(
        git remote add someremote foo &&
        echo foo >expect &&
        git config --get-all remote.someremote.url >actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url bar' '
-(
        git remote set-url someremote bar &&
        echo bar >expect &&
        git config --get-all remote.someremote.url >actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url baz bar' '
-(
        git remote set-url someremote baz bar &&
        echo baz >expect &&
        git config --get-all remote.someremote.url >actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url zot bar' '
-(
        test_must_fail git remote set-url someremote zot bar &&
        echo baz >expect &&
        git config --get-all remote.someremote.url >actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url --push zot baz' '
-(
        test_must_fail git remote set-url --push someremote zot baz &&
        echo "YYY" >expect &&
        echo baz >>expect &&
@@ -578,11 +570,9 @@ test_expect_success 'remote set-url --push zot baz' '
        echo "YYY" >>actual &&
        git config --get-all remote.someremote.url >>actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url --push zot' '
-(
        git remote set-url --push someremote zot &&
        echo zot >expect &&
        echo "YYY" >>expect &&
@@ -591,11 +581,9 @@ test_expect_success 'remote set-url --push zot' '
        echo "YYY" >>actual &&
        git config --get-all remote.someremote.url >>actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url --push qux zot' '
-(
        git remote set-url --push someremote qux zot &&
        echo qux >expect &&
        echo "YYY" >>expect &&
@@ -604,11 +592,9 @@ test_expect_success 'remote set-url --push qux zot' '
        echo "YYY" >>actual &&
        git config --get-all remote.someremote.url >>actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url --push foo qu+x' '
-(
        git remote set-url --push someremote foo qu+x &&
        echo foo >expect &&
        echo "YYY" >>expect &&
@@ -617,11 +603,9 @@ test_expect_success 'remote set-url --push foo qu+x' '
        echo "YYY" >>actual &&
        git config --get-all remote.someremote.url >>actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url --push --add aaa' '
-(
        git remote set-url --push --add someremote aaa &&
        echo foo >expect &&
        echo aaa >>expect &&
@@ -631,11 +615,9 @@ test_expect_success 'remote set-url --push --add aaa' '
        echo "YYY" >>actual &&
        git config --get-all remote.someremote.url >>actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url --push bar aaa' '
-(
        git remote set-url --push someremote bar aaa &&
        echo foo >expect &&
        echo bar >>expect &&
@@ -645,11 +627,9 @@ test_expect_success 'remote set-url --push bar aaa' '
        echo "YYY" >>actual &&
        git config --get-all remote.someremote.url >>actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url --push --delete bar' '
-(
        git remote set-url --push --delete someremote bar &&
        echo foo >expect &&
        echo "YYY" >>expect &&
@@ -658,11 +638,9 @@ test_expect_success 'remote set-url --push --delete bar' '
        echo "YYY" >>actual &&
        git config --get-all remote.someremote.url >>actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url --push --delete foo' '
-(
        git remote set-url --push --delete someremote foo &&
        echo "YYY" >expect &&
        echo baz >>expect &&
@@ -670,11 +648,9 @@ test_expect_success 'remote set-url --push --delete foo' '
        echo "YYY" >>actual &&
        git config --get-all remote.someremote.url >>actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url --add bbb' '
-(
        git remote set-url --add someremote bbb &&
        echo "YYY" >expect &&
        echo baz >>expect &&
@@ -683,12 +659,10 @@ test_expect_success 'remote set-url --add bbb' '
        echo "YYY" >>actual &&
        git config --get-all remote.someremote.url >>actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url --delete .*' '
-(
-       test_must_fail git remote set-url --delete someremote .* &&
+       test_must_fail git remote set-url --delete someremote .\* &&
        echo "YYY" >expect &&
        echo baz >>expect &&
        echo bbb >>expect &&
@@ -696,11 +670,9 @@ test_expect_success 'remote set-url --delete .*' '
        echo "YYY" >>actual &&
        git config --get-all remote.someremote.url >>actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url --delete bbb' '
-(
        git remote set-url --delete someremote bbb &&
        echo "YYY" >expect &&
        echo baz >>expect &&
@@ -708,11 +680,9 @@ test_expect_success 'remote set-url --delete bbb' '
        echo "YYY" >>actual &&
        git config --get-all remote.someremote.url >>actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url --delete baz' '
-(
        test_must_fail git remote set-url --delete someremote baz &&
        echo "YYY" >expect &&
        echo baz >>expect &&
@@ -720,11 +690,9 @@ test_expect_success 'remote set-url --delete baz' '
        echo "YYY" >>actual &&
        git config --get-all remote.someremote.url >>actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url --add ccc' '
-(
        git remote set-url --add someremote ccc &&
        echo "YYY" >expect &&
        echo baz >>expect &&
@@ -733,11 +701,9 @@ test_expect_success 'remote set-url --add ccc' '
        echo "YYY" >>actual &&
        git config --get-all remote.someremote.url >>actual &&
        cmp expect actual
-)
 '
 
 test_expect_success 'remote set-url --delete baz' '
-(
        git remote set-url --delete someremote baz &&
        echo "YYY" >expect &&
        echo ccc >>expect &&
@@ -745,7 +711,6 @@ test_expect_success 'remote set-url --delete baz' '
        echo "YYY" >>actual &&
        git config --get-all remote.someremote.url >>actual &&
        cmp expect actual
-)
 '
 
 test_done
index 214756731baf199e6a50f9ab2380a8b4bfc0fb18..678cee502de54e5a9c18a43f114446d3392ec7f3 100755 (executable)
@@ -34,7 +34,7 @@ test_expect_success 'clone with excess parameters (2)' '
 test_expect_success 'output from clone' '
        rm -fr dst &&
        git clone -n "file://$(pwd)/src" dst >output &&
-       test $(grep Initialized output | wc -l) = 1
+       test $(grep Clon output | wc -l) = 1
 '
 
 test_expect_success 'clone does not keep pack' '
index b0047d3c6b593795561ce908ab8e10ff574d3dbc..a49b7c5722e6cb675f771c31e4eec87262388548 100755 (executable)
@@ -209,4 +209,13 @@ test_expect_success '%gd shortens ref name' '
        test_cmp expect.gd-short actual.gd-short
 '
 
+test_expect_success 'oneline with empty message' '
+       git commit -m "dummy" --allow-empty &&
+       git commit -m "dummy" --allow-empty &&
+       git filter-branch --msg-filter "sed -e s/dummy//" HEAD^^.. &&
+       git rev-list --oneline HEAD >test.txt &&
+       test $(git rev-list --oneline HEAD | wc -l) -eq 5 &&
+       test $(git rev-list --oneline --graph HEAD | wc -l) -eq 5
+'
+
 test_done
index 5034dd1352c275beca4d5dae805cad6573a89aca..d486d73994cf563063b578ec5e212331e87bf67f 100755 (executable)
@@ -181,7 +181,7 @@ et nihil mihi deerit;
 
 In loco pascuae ibi me collocavit;
 super aquam refectionis educavit me.
-|||||||
+||||||| new5.txt
 et nihil mihi deerit.
 In loco pascuae ibi me collocavit,
 super aquam refectionis educavit me;
@@ -225,7 +225,7 @@ et nihil mihi deerit;
 
 In loco pascuae ibi me collocavit;
 super aquam refectionis educavit me.
-||||||||||
+|||||||||| new5.txt
 et nihil mihi deerit.
 In loco pascuae ibi me collocavit,
 super aquam refectionis educavit me;
index 42f6fff373ba9707216279011b112c6c59af8780..42f8ece0978f38e10200a52ce8cf1952cf13ecbd 100755 (executable)
@@ -7,65 +7,69 @@ test_description='fmt-merge-msg test'
 
 . ./test-lib.sh
 
-datestamp=1151939923
-setdate () {
-       GIT_COMMITTER_DATE="$datestamp +0200"
-       GIT_AUTHOR_DATE="$datestamp +0200"
-       datestamp=`expr "$datestamp" + 1`
-       export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
-}
-
 test_expect_success setup '
        echo one >one &&
        git add one &&
-       setdate &&
+       test_tick &&
        git commit -m "Initial" &&
 
+       git clone . remote &&
+
        echo uno >one &&
        echo dos >two &&
        git add two &&
-       setdate &&
+       test_tick &&
        git commit -a -m "Second" &&
 
        git checkout -b left &&
 
-       echo $datestamp >one &&
-       setdate &&
+       echo "c1" >one &&
+       test_tick &&
        git commit -a -m "Common #1" &&
 
-       echo $datestamp >one &&
-       setdate &&
+       echo "c2" >one &&
+       test_tick &&
        git commit -a -m "Common #2" &&
 
        git branch right &&
 
-       echo $datestamp >two &&
-       setdate &&
+       echo "l3" >two &&
+       test_tick &&
        git commit -a -m "Left #3" &&
 
-       echo $datestamp >two &&
-       setdate &&
+       echo "l4" >two &&
+       test_tick &&
        git commit -a -m "Left #4" &&
 
-       echo $datestamp >two &&
-       setdate &&
+       echo "l5" >two &&
+       test_tick &&
        git commit -a -m "Left #5" &&
+       git tag tag-l5 &&
 
        git checkout right &&
 
-       echo $datestamp >three &&
+       echo "r3" >three &&
        git add three &&
-       setdate &&
+       test_tick &&
        git commit -a -m "Right #3" &&
+       git tag tag-r3 &&
 
-       echo $datestamp >three &&
-       setdate &&
+       echo "r4" >three &&
+       test_tick &&
        git commit -a -m "Right #4" &&
 
-       echo $datestamp >three &&
-       setdate &&
+       echo "r5" >three &&
+       test_tick &&
        git commit -a -m "Right #5" &&
 
+       git checkout -b long &&
+       i=0 &&
+       while test $i -lt 30
+       do
+               test_commit $i one &&
+               i=$(($i+1))
+       done &&
+
        git show-branch
 '
 
@@ -113,7 +117,7 @@ test_expect_success 'merge-msg test #3-1' '
        git config merge.log true &&
 
        git checkout master &&
-       setdate &&
+       test_tick &&
        git fetch . left &&
 
        git fmt-merge-msg <.git/FETCH_HEAD >actual &&
@@ -127,7 +131,7 @@ test_expect_success 'merge-msg test #3-2' '
        git config merge.summary true &&
 
        git checkout master &&
-       setdate &&
+       test_tick &&
        git fetch . left &&
 
        git fmt-merge-msg <.git/FETCH_HEAD >actual &&
@@ -159,7 +163,7 @@ test_expect_success 'merge-msg test #4-1' '
        git config merge.log true &&
 
        git checkout master &&
-       setdate &&
+       test_tick &&
        git fetch . left right &&
 
        git fmt-merge-msg <.git/FETCH_HEAD >actual &&
@@ -173,7 +177,7 @@ test_expect_success 'merge-msg test #4-2' '
        git config merge.summary true &&
 
        git checkout master &&
-       setdate &&
+       test_tick &&
        git fetch . left right &&
 
        git fmt-merge-msg <.git/FETCH_HEAD >actual &&
@@ -187,7 +191,7 @@ test_expect_success 'merge-msg test #5-1' '
        git config merge.log yes &&
 
        git checkout master &&
-       setdate &&
+       test_tick &&
        git fetch . left right &&
 
        git fmt-merge-msg <.git/FETCH_HEAD >actual &&
@@ -201,7 +205,7 @@ test_expect_success 'merge-msg test #5-2' '
        git config merge.summary yes &&
 
        git checkout master &&
-       setdate &&
+       test_tick &&
        git fetch . left right &&
 
        git fmt-merge-msg <.git/FETCH_HEAD >actual &&
@@ -215,7 +219,7 @@ test_expect_success 'merge-msg -F' '
        git config merge.summary yes &&
 
        git checkout master &&
-       setdate &&
+       test_tick &&
        git fetch . left right &&
 
        git fmt-merge-msg -F .git/FETCH_HEAD >actual &&
@@ -229,7 +233,7 @@ test_expect_success 'merge-msg -F in subdirectory' '
        git config merge.summary yes &&
 
        git checkout master &&
-       setdate &&
+       test_tick &&
        git fetch . left right &&
        mkdir sub &&
        cp .git/FETCH_HEAD sub/FETCH_HEAD &&
@@ -240,4 +244,128 @@ test_expect_success 'merge-msg -F in subdirectory' '
        test_cmp expected actual
 '
 
+test_expect_success 'merge-msg with nothing to merge' '
+
+       git config --unset-all merge.log
+       git config --unset-all merge.summary
+       git config merge.summary yes &&
+
+       (
+               cd remote &&
+               git checkout -b unrelated &&
+               test_tick &&
+               git fetch origin &&
+               git fmt-merge-msg <.git/FETCH_HEAD >../actual
+       ) &&
+
+       test_cmp /dev/null actual
+'
+
+cat >expected <<\EOF
+Merge tag 'tag-r3'
+
+* tag 'tag-r3':
+  Right #3
+  Common #2
+  Common #1
+EOF
+
+test_expect_success 'merge-msg tag' '
+
+       git config --unset-all merge.log
+       git config --unset-all merge.summary
+       git config merge.summary yes &&
+
+       git checkout master &&
+       test_tick &&
+       git fetch . tag tag-r3 &&
+
+       git fmt-merge-msg <.git/FETCH_HEAD >actual &&
+       test_cmp expected actual
+'
+
+cat >expected <<\EOF
+Merge tags 'tag-r3' and 'tag-l5'
+
+* tag 'tag-r3':
+  Right #3
+  Common #2
+  Common #1
+
+* tag 'tag-l5':
+  Left #5
+  Left #4
+  Left #3
+  Common #2
+  Common #1
+EOF
+
+test_expect_success 'merge-msg two tags' '
+
+       git config --unset-all merge.log
+       git config --unset-all merge.summary
+       git config merge.summary yes &&
+
+       git checkout master &&
+       test_tick &&
+       git fetch . tag tag-r3 tag tag-l5 &&
+
+       git fmt-merge-msg <.git/FETCH_HEAD >actual &&
+       test_cmp expected actual
+'
+
+cat >expected <<\EOF
+Merge branch 'left', tag 'tag-r3'
+
+* tag 'tag-r3':
+  Right #3
+  Common #2
+  Common #1
+
+* left:
+  Left #5
+  Left #4
+  Left #3
+  Common #2
+  Common #1
+EOF
+
+test_expect_success 'merge-msg tag and branch' '
+
+       git config --unset-all merge.log
+       git config --unset-all merge.summary
+       git config merge.summary yes &&
+
+       git checkout master &&
+       test_tick &&
+       git fetch . tag tag-r3 left &&
+
+       git fmt-merge-msg <.git/FETCH_HEAD >actual &&
+       test_cmp expected actual
+'
+
+cat >expected <<\EOF
+Merge branch 'long'
+
+* long: (35 commits)
+EOF
+
+test_expect_success 'merge-msg lots of commits' '
+
+       git checkout master &&
+       test_tick &&
+       git fetch . long &&
+
+       i=29 &&
+       while test $i -gt 9
+       do
+               echo "  $i" &&
+               i=$(($i-1))
+       done >>expected &&
+       echo "  ..." >>expected
+
+       git fmt-merge-msg <.git/FETCH_HEAD >actual &&
+       test_cmp expected actual
+'
+
 test_done
index 8d8b1c0e25e857945b17ed5ae4a9abc5f8987bd3..582d0b54f1f1a32459727e59932e95c4b466951f 100755 (executable)
@@ -136,11 +136,11 @@ test_expect_success 'git-clean, dirty case' '
        test_cmp expected result
 '
 
-test_expect_failure 'git-apply adds file' false
-test_expect_failure 'git-apply updates file' false
-test_expect_failure 'git-apply removes file' false
-test_expect_failure 'git-mv to skip-worktree' false
-test_expect_failure 'git-mv from skip-worktree' false
-test_expect_failure 'git-checkout' false
+#TODO test_expect_failure 'git-apply adds file' false
+#TODO test_expect_failure 'git-apply updates file' false
+#TODO test_expect_failure 'git-apply removes file' false
+#TODO test_expect_failure 'git-mv to skip-worktree' false
+#TODO test_expect_failure 'git-mv from skip-worktree' false
+#TODO test_expect_failure 'git-checkout' false
 
 test_done
index d20ed61b481539b25c054c49bd82aa6fb9b3a981..1337fa5a2209d489c43f0a34c95a89053d3fd8bf 100755 (executable)
@@ -11,10 +11,12 @@ Test switching across them.
   ! [master] Initial A one, A two
    * [renamer] Renamer R one->uno, M two
     ! [side] Side M one, D two, A three
-  ---
-    + [side] Side M one, D two, A three
-   *  [renamer] Renamer R one->uno, M two
-  +*+ [master] Initial A one, A two
+     ! [simple] Simple D one, M two
+  ----
+     + [simple] Simple D one, M two
+    +  [side] Side M one, D two, A three
+   *   [renamer] Renamer R one->uno, M two
+  +*++ [master] Initial A one, A two
 
 '
 
@@ -52,6 +54,11 @@ test_expect_success setup '
        git update-index --add --remove one two three &&
        git commit -m "Side M one, D two, A three" &&
 
+       git checkout -b simple master &&
+       rm -f one &&
+       fill a c e > two &&
+       git commit -a -m "Simple D one, M two" &&
+
        git checkout master
 '
 
@@ -166,6 +173,56 @@ test_expect_success 'checkout -m with merge conflict' '
        ! test -s current
 '
 
+test_expect_success 'format of merge conflict from checkout -m' '
+
+       git checkout -f master && git clean -f &&
+
+       fill b d > two &&
+       git checkout -m simple &&
+
+       git ls-files >current &&
+       fill same two two two >expect &&
+       test_cmp current expect &&
+
+       cat <<-EOF >expect &&
+       <<<<<<< simple
+       a
+       c
+       e
+       =======
+       b
+       d
+       >>>>>>> local
+       EOF
+       test_cmp two expect
+'
+
+test_expect_success 'checkout --merge --conflict=diff3 <branch>' '
+
+       git checkout -f master && git reset --hard && git clean -f &&
+
+       fill b d > two &&
+       git checkout --merge --conflict=diff3 simple &&
+
+       cat <<-EOF >expect &&
+       <<<<<<< simple
+       a
+       c
+       e
+       ||||||| master
+       a
+       b
+       c
+       d
+       e
+       =======
+       b
+       d
+       >>>>>>> local
+       EOF
+       test_cmp two expect
+'
+
 test_expect_success 'checkout to detach HEAD (with advice declined)' '
 
        git config advice.detachedHead false &&
@@ -481,7 +538,7 @@ test_expect_success 'checkout with --merge, in diff3 -m style' '
        (
                echo "<<<<<<< ours"
                echo ourside
-               echo "|||||||"
+               echo "||||||| base"
                echo original
                echo "======="
                echo theirside
@@ -525,7 +582,7 @@ test_expect_success 'checkout --conflict=diff3' '
        (
                echo "<<<<<<< ours"
                echo ourside
-               echo "|||||||"
+               echo "||||||| base"
                echo original
                echo "======="
                echo theirside
index aeec1f6142e622ffc7b0ef8a68fe7734c02d24d0..3d4f85d74f6f378d76bde77e581273af010ba452 100755 (executable)
@@ -157,6 +157,22 @@ test_expect_success 'status with added and untracked file in modified submodule
        EOF
 '
 
+test_expect_success 'setup .git file for sub' '
+       (cd sub &&
+        rm -f new-file
+        REAL="$(pwd)/../.real" &&
+        mv .git "$REAL"
+        echo "gitdir: $REAL" >.git) &&
+        echo .real >>.gitignore &&
+        git commit -m "added .real to .gitignore" .gitignore
+'
+
+test_expect_success 'status with added file in modified submodule with .git file' '
+       (cd sub && git reset --hard && echo >foo && git add foo) &&
+       git status >output &&
+       grep "modified:   sub (new commits, modified content)" output
+'
+
 test_expect_success 'rm submodule contents' '
        rm -rf sub/* sub/.git
 '
index c582964b0d26bedcc69b4f7cc787c4deccfab6b9..7422bba47e75e00073779e4b2d7a162862cdb426 100644 (file)
@@ -2,6 +2,18 @@
 #
 # Copyright (c) 2005 Junio C Hamano
 #
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see http://www.gnu.org/licenses/ .
 
 # if --tee was passed, write the output not only to the terminal, but
 # additionally to the file test-results/$BASENAME.out, too.
@@ -354,8 +366,10 @@ test_debug () {
 }
 
 test_run_ () {
+       test_cleanup=:
        eval >&3 2>&4 "$1"
-       eval_ret="$?"
+       eval_ret=$?
+       eval >&3 2>&4 "$test_cleanup"
        return 0
 }
 
@@ -533,6 +547,31 @@ test_cmp() {
        $GIT_TEST_CMP "$@"
 }
 
+# This function can be used to schedule some commands to be run
+# unconditionally at the end of the test to restore sanity:
+#
+#      test_expect_success 'test core.capslock' '
+#              git config core.capslock true &&
+#              test_when_finished "git config --unset core.capslock" &&
+#              hello world
+#      '
+#
+# That would be roughly equivalent to
+#
+#      test_expect_success 'test core.capslock' '
+#              git config core.capslock true &&
+#              hello world
+#              git config --unset core.capslock
+#      '
+#
+# except that the greeting and config --unset must both succeed for
+# the test to pass.
+
+test_when_finished () {
+       test_cleanup="{ $*
+               } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
+}
+
 # Most tests can use the created repository, but some may need to create more.
 # Usage: test_create_repo <directory>
 test_create_repo () {
index 408f0137a8342414eedba3a02372ea1ad6050117..d22a71a3999b3dc0e99f5e36053447b33f967bd7 100644 (file)
@@ -11,6 +11,16 @@ prefix ?= $(HOME)
 template_instdir ?= $(prefix)/share/git-core/templates
 # DESTDIR=
 
+ifndef SHELL_PATH
+       SHELL_PATH = /bin/sh
+endif
+ifndef PERL_PATH
+       PERL_PATH = perl
+endif
+
+SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
+PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
+
 # Shell quote (do not use $(call) to accommodate ancient setups);
 DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
 template_instdir_SQ = $(subst ','\'',$(template_instdir))
@@ -33,8 +43,11 @@ boilerplates.made : $(bpsrc)
                case "$$boilerplate" in \
                *--) continue;; \
                esac && \
-               cp $$boilerplate blt/$$dst && \
-               if test -x "blt/$$dst"; then rx=rx; else rx=r; fi && \
+               sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
+                   -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \
+                   -e 's|@PERL_PATH@|$(PERL_PATH_SQ)|g' $$boilerplate > \
+                       blt/$$dst && \
+               if test -x "$$boilerplate"; then rx=rx; else rx=r; fi && \
                chmod a+$$rx "blt/$$dst" || exit; \
        done && \
        date >$@
index 6ef1d29d09a10a5b6c3cbec0ac481931cd0d85fc..b58d1184a9d43a39c0d95f32453efc78581877d6 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 #
 # An example hook script to check the commit log message.
-# Called by git-commit with one argument, the name of the file
+# Called by "git commit" with one argument, the name of the file
 # that has the commit message.  The hook should exit with non-zero
 # status after issuing an appropriate message if it wants to stop the
 # commit.  The hook is allowed to edit the commit message file.
index 5323b56b81b9dd3d7f9fb86d8892241becbb5e7e..ec17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e 100755 (executable)
@@ -5,4 +5,4 @@
 #
 # To enable this hook, rename this file to "post-update".
 
-exec git-update-server-info
+exec git update-server-info
index 439eefda510ca8de9f55c63616f2113ac36c8b6b..b187c4bb1f256e19c25f80dd64f3451ced77e123 100755 (executable)
@@ -1,13 +1,13 @@
 #!/bin/sh
 #
 # An example hook script to verify what is about to be committed.
-# Called by git-commit with no arguments.  The hook should
+# Called by "git commit" with no arguments.  The hook should
 # exit with non-zero status after issuing an appropriate message if
 # it wants to stop the commit.
 #
 # To enable this hook, rename this file to "pre-commit".
 
-if git-rev-parse --verify HEAD >/dev/null 2>&1
+if git rev-parse --verify HEAD >/dev/null 2>&1
 then
        against=HEAD
 else
index be1b06e25043146f22261b55548229e6ab524b7c..053f1111c0d734c057e895cdc992188104cc4f84 100755 (executable)
@@ -2,7 +2,7 @@
 #
 # Copyright (c) 2006, 2008 Junio C Hamano
 #
-# The "pre-rebase" hook is run just before "git-rebase" starts doing
+# The "pre-rebase" hook is run just before "git rebase" starts doing
 # its job, and can prevent the command from running by exiting with
 # non-zero status.
 #
@@ -43,7 +43,7 @@ git show-ref -q "$topic" || {
 }
 
 # Is topic fully merged to master?
-not_in_master=`git-rev-list --pretty=oneline ^master "$topic"`
+not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
 if test -z "$not_in_master"
 then
        echo >&2 "$topic is fully merged to master; better remove it."
@@ -51,11 +51,11 @@ then
 fi
 
 # Is topic ever merged to next?  If so you should not be rebasing it.
-only_next_1=`git-rev-list ^master "^$topic" ${publish} | sort`
-only_next_2=`git-rev-list ^master           ${publish} | sort`
+only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
+only_next_2=`git rev-list ^master           ${publish} | sort`
 if test "$only_next_1" = "$only_next_2"
 then
-       not_in_topic=`git-rev-list "^$topic" master`
+       not_in_topic=`git rev-list "^$topic" master`
        if test -z "$not_in_topic"
        then
                echo >&2 "$topic is already up-to-date with master"
@@ -64,8 +64,8 @@ then
                exit 0
        fi
 else
-       not_in_next=`git-rev-list --pretty=oneline ^${publish} "$topic"`
-       perl -e '
+       not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
+       @PERL_PATH@ -e '
                my $topic = $ARGV[0];
                my $msg = "* $topic has commits already merged to public branch:\n";
                my (%not_in_next) = map {
@@ -157,13 +157,13 @@ B to be deleted.
 
 To compute (1):
 
-       git-rev-list ^master ^topic next
-       git-rev-list ^master        next
+       git rev-list ^master ^topic next
+       git rev-list ^master        next
 
        if these match, topic has not merged in next at all.
 
 To compute (2):
 
-       git-rev-list master..topic
+       git rev-list master..topic
 
        if this is empty, it is fully merged to "master".
index 365242499dcf0ee35c26ccb2917724d6e559be69..86b8f227ecab874a4af98bc5ba3164d370e5e4b5 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 #
 # An example hook script to prepare the commit log message.
-# Called by git-commit with the name of the file that has the
+# Called by "git commit" with the name of the file that has the
 # commit message, followed by the description of the commit
 # message's source.  The hook's purpose is to edit the commit
 # message file.  If the hook fails with a non-zero status,
 
 case "$2,$3" in
   merge,)
-    perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
+    @PERL_PATH@ -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
 
 # ,|template,)
-#   perl -i.bak -pe '
+#   @PERL_PATH@ -i.bak -pe '
 #      print "\n" . `git diff --cached --name-status -r`
 #       if /^#/ && $first++ == 0' "$1" ;;
 
index fd63b2d662dbcf98ec622a1ab754d041a559e3be..71ab04edc09be7aeefa1e8a0f609a974ffd55a9f 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 #
 # An example hook script to blocks unannotated tags from entering.
-# Called by git-receive-pack with arguments: refname sha1-old sha1-new
+# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
 #
 # To enable this hook, rename this file to "update".
 #
@@ -64,7 +64,7 @@ zero="0000000000000000000000000000000000000000"
 if [ "$newrev" = "$zero" ]; then
        newrev_type=delete
 else
-       newrev_type=$(git-cat-file -t $newrev)
+       newrev_type=$(git cat-file -t $newrev)
 fi
 
 case "$refname","$newrev_type" in
index 2c87b72dff61f8394b3f1f32e21c1d936314ec2e..a5196d1be8fb59edf8062bef36d3a602e0812139 100644 (file)
@@ -1,4 +1,4 @@
-# git-ls-files --others --exclude-from=.git/info/exclude
+# git ls-files --others --exclude-from=.git/info/exclude
 # Lines that start with '#' are comments.
 # For a project mostly in C, the following would be a good set of
 # exclude patterns (uncomment them if you want to use them):
index 75f54cac97f62ddaad736c2cd582cc6cdeaaebfa..c29a9e067ff362063d6626e8e4d1e4466d63b8af 100644 (file)
@@ -67,16 +67,8 @@ static void unlink_entry(struct cache_entry *ce)
 {
        if (has_symlink_or_noent_leading_path(ce->name, ce_namelen(ce)))
                return;
-       if (S_ISGITLINK(ce->ce_mode)) {
-               if (rmdir(ce->name)) {
-                       warning("unable to rmdir %s: %s",
-                               ce->name, strerror(errno));
-                       return;
-               }
-       }
-       else
-               if (unlink_or_warn(ce->name))
-                       return;
+       if (remove_or_warn(ce->ce_mode, ce->name))
+               return;
        schedule_dir_for_removal(ce->name, ce_namelen(ce));
 }
 
index 9c71b21242773f52ca560d7e5e5e52123674d334..10a6750795b287beabd50561402ffa8867f3e283 100644 (file)
--- a/wrapper.c
+++ b/wrapper.c
@@ -311,18 +311,30 @@ int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1)
        return open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
 }
 
-int unlink_or_warn(const char *file)
+static int warn_if_unremovable(const char *op, const char *file, int rc)
 {
-       int rc = unlink(file);
-
        if (rc < 0) {
                int err = errno;
                if (ENOENT != err) {
-                       warning("unable to unlink %s: %s",
-                               file, strerror(errno));
+                       warning("unable to %s %s: %s",
+                               op, file, strerror(errno));
                        errno = err;
                }
        }
        return rc;
 }
 
+int unlink_or_warn(const char *file)
+{
+       return warn_if_unremovable("unlink", file, unlink(file));
+}
+
+int rmdir_or_warn(const char *file)
+{
+       return warn_if_unremovable("rmdir", file, rmdir(file));
+}
+
+int remove_or_warn(unsigned int mode, const char *file)
+{
+       return S_ISGITLINK(mode) ? rmdir_or_warn(file) : unlink_or_warn(file);
+}
index ca5e3fbae8184e7114413ec65fe815e01ad6b2a8..cd2285de1cb1faa9f7c6c97dd22210f20bb046a3 100644 (file)
@@ -138,19 +138,20 @@ int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t co
 
 int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2,
                  xdiff_emit_consume_fn fn, void *consume_callback_data,
-                 xpparam_t const *xpp,
-                 xdemitconf_t const *xecfg, xdemitcb_t *xecb)
+                 xpparam_t const *xpp, xdemitconf_t const *xecfg)
 {
        int ret;
        struct xdiff_emit_state state;
+       xdemitcb_t ecb;
 
        memset(&state, 0, sizeof(state));
        state.consume = fn;
        state.consume_callback_data = consume_callback_data;
-       xecb->outf = xdiff_outf;
-       xecb->priv = &state;
+       memset(&ecb, 0, sizeof(ecb));
+       ecb.outf = xdiff_outf;
+       ecb.priv = &state;
        strbuf_init(&state.remainder, 0);
-       ret = xdi_diff(mf1, mf2, xpp, xecfg, xecb);
+       ret = xdi_diff(mf1, mf2, xpp, xecfg, &ecb);
        strbuf_release(&state.remainder);
        return ret;
 }
index abba70c16bb31fae0df999241830d0c8df8bfbb3..49d1116fc34f536ab9358313522a25564dd1f6c3 100644 (file)
@@ -9,8 +9,7 @@ typedef void (*xdiff_emit_hunk_consume_fn)(void *, long, long, long);
 int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *ecb);
 int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2,
                  xdiff_emit_consume_fn fn, void *consume_callback_data,
-                 xpparam_t const *xpp,
-                 xdemitconf_t const *xecfg, xdemitcb_t *xecb);
+                 xpparam_t const *xpp, xdemitconf_t const *xecfg);
 int xdi_diff_hunks(mmfile_t *mf1, mmfile_t *mf2,
                   xdiff_emit_hunk_consume_fn fn, void *consume_callback_data,
                   xpparam_t const *xpp, xdemitconf_t *xecfg);
index a71763ade835fd93ef291106298647408ada08e9..711048ea36dda1d814b395efa8bc69ab142425ca 100644 (file)
@@ -117,12 +117,14 @@ typedef struct s_xmparam {
        int level;
        int favor;
        int style;
+       const char *ancestor;   /* label for orig */
+       const char *file1;      /* label for mf1 */
+       const char *file2;      /* label for mf2 */
 } xmparam_t;
 
 #define DEFAULT_CONFLICT_MARKER_SIZE 7
 
-int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1,
-               mmfile_t *mf2, const char *name2,
+int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2,
                xmparam_t const *xmp, mmbuffer_t *result);
 
 #ifdef __cplusplus
index 87cafa7021468d00a11c72dfdc1df05f1ede0fea..6d6fc1bc5e01be7305ec5101f43645a1dce69bd3 100644 (file)
@@ -145,12 +145,13 @@ static int xdl_orig_copy(xdfenv_t *xe, int i, int count, int add_nl, char *dest)
 
 static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
                              xdfenv_t *xe2, const char *name2,
+                             const char *name3,
                              int size, int i, int style,
                              xdmerge_t *m, char *dest, int marker_size)
 {
        int marker1_size = (name1 ? strlen(name1) + 1 : 0);
        int marker2_size = (name2 ? strlen(name2) + 1 : 0);
-       int j;
+       int marker3_size = (name3 ? strlen(name3) + 1 : 0);
 
        if (marker_size <= 0)
                marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
@@ -162,8 +163,8 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
        if (!dest) {
                size += marker_size + 1 + marker1_size;
        } else {
-               for (j = 0; j < marker_size; j++)
-                       dest[size++] = '<';
+               memset(dest + size, '<', marker_size);
+               size += marker_size;
                if (marker1_size) {
                        dest[size] = ' ';
                        memcpy(dest + size + 1, name1, marker1_size - 1);
@@ -179,10 +180,15 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
        if (style == XDL_MERGE_DIFF3) {
                /* Shared preimage */
                if (!dest) {
-                       size += marker_size + 1;
+                       size += marker_size + 1 + marker3_size;
                } else {
-                       for (j = 0; j < marker_size; j++)
-                               dest[size++] = '|';
+                       memset(dest + size, '|', marker_size);
+                       size += marker_size;
+                       if (marker3_size) {
+                               dest[size] = ' ';
+                               memcpy(dest + size + 1, name3, marker3_size - 1);
+                               size += marker3_size;
+                       }
                        dest[size++] = '\n';
                }
                size += xdl_orig_copy(xe1, m->i0, m->chg0, 1,
@@ -192,8 +198,8 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
        if (!dest) {
                size += marker_size + 1;
        } else {
-               for (j = 0; j < marker_size; j++)
-                       dest[size++] = '=';
+               memset(dest + size, '=', marker_size);
+               size += marker_size;
                dest[size++] = '\n';
        }
 
@@ -203,8 +209,8 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
        if (!dest) {
                size += marker_size + 1 + marker2_size;
        } else {
-               for (j = 0; j < marker_size; j++)
-                       dest[size++] = '>';
+               memset(dest + size, '>', marker_size);
+               size += marker_size;
                if (marker2_size) {
                        dest[size] = ' ';
                        memcpy(dest + size + 1, name2, marker2_size - 1);
@@ -217,6 +223,7 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
 
 static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1,
                                 xdfenv_t *xe2, const char *name2,
+                                const char *ancestor_name,
                                 int favor,
                                 xdmerge_t *m, char *dest, int style,
                                 int marker_size)
@@ -229,6 +236,7 @@ static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1,
 
                if (m->mode == 0)
                        size = fill_conflict_hunk(xe1, name1, xe2, name2,
+                                                 ancestor_name,
                                                  size, i, style, m, dest,
                                                  marker_size);
                else if (m->mode & 3) {
@@ -398,11 +406,15 @@ static int xdl_simplify_non_conflicts(xdfenv_t *xe1, xdmerge_t *m,
  *
  * returns < 0 on error, == 0 for no conflicts, else number of conflicts
  */
-static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1,
-               xdfenv_t *xe2, xdchange_t *xscr2, const char *name2,
-               xmparam_t const *xmp, mmbuffer_t *result) {
+static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1,
+               xdfenv_t *xe2, xdchange_t *xscr2,
+               xmparam_t const *xmp, mmbuffer_t *result)
+{
        xdmerge_t *changes, *c;
        xpparam_t const *xpp = &xmp->xpp;
+       const char *const ancestor_name = xmp->ancestor;
+       const char *const name1 = xmp->file1;
+       const char *const name2 = xmp->file2;
        int i0, i1, i2, chg0, chg1, chg2;
        int level = xmp->level;
        int style = xmp->style;
@@ -540,6 +552,7 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1,
        if (result) {
                int marker_size = xmp->marker_size;
                int size = xdl_fill_merge_buffer(xe1, name1, xe2, name2,
+                                                ancestor_name,
                                                 favor, changes, NULL, style,
                                                 marker_size);
                result->ptr = xdl_malloc(size);
@@ -548,15 +561,16 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1,
                        return -1;
                }
                result->size = size;
-               xdl_fill_merge_buffer(xe1, name1, xe2, name2, favor, changes,
+               xdl_fill_merge_buffer(xe1, name1, xe2, name2,
+                                     ancestor_name, favor, changes,
                                      result->ptr, style, marker_size);
        }
        return xdl_cleanup_merge(changes);
 }
 
-int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1,
-               mmfile_t *mf2, const char *name2,
-               xmparam_t const *xmp, mmbuffer_t *result) {
+int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2,
+               xmparam_t const *xmp, mmbuffer_t *result)
+{
        xdchange_t *xscr1, *xscr2;
        xdfenv_t xe1, xe2;
        int status;
@@ -591,8 +605,8 @@ int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1,
                memcpy(result->ptr, mf1->ptr, mf1->size);
                result->size = mf1->size;
        } else {
-               status = xdl_do_merge(&xe1, xscr1, name1,
-                                     &xe2, xscr2, name2,
+               status = xdl_do_merge(&xe1, xscr1,
+                                     &xe2, xscr2,
                                      xmp, result);
        }
        xdl_free_script(xscr1);