Merge branch 'tr/test-v-and-v-subtest-only'
authorJunio C Hamano <gitster@pobox.com>
Thu, 11 Jul 2013 20:06:02 +0000 (13:06 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 11 Jul 2013 20:06:02 +0000 (13:06 -0700)
Finishing touches to a topic that is already in master for the
upcoming release.

* tr/test-v-and-v-subtest-only:
  t0000: do not use export X=Y

382 files changed:
.gitignore
.mailmap
Documentation/Makefile
Documentation/RelNotes/1.8.3.1.txt [new file with mode: 0644]
Documentation/RelNotes/1.8.3.2.txt [new file with mode: 0644]
Documentation/RelNotes/1.8.3.3.txt [new file with mode: 0644]
Documentation/RelNotes/1.8.4.txt [new file with mode: 0644]
Documentation/blame-options.txt
Documentation/config.txt
Documentation/diff-options.txt
Documentation/fetch-options.txt
Documentation/git-am.txt
Documentation/git-blame.txt
Documentation/git-check-attr.txt
Documentation/git-check-ignore.txt
Documentation/git-check-ref-format.txt
Documentation/git-checkout.txt
Documentation/git-clone.txt
Documentation/git-config.txt
Documentation/git-describe.txt
Documentation/git-diff-index.txt
Documentation/git-diff.txt
Documentation/git-fast-export.txt
Documentation/git-gc.txt
Documentation/git-index-pack.txt
Documentation/git-log.txt
Documentation/git-ls-remote.txt
Documentation/git-merge.txt
Documentation/git-name-rev.txt
Documentation/git-push.txt
Documentation/git-rebase.txt
Documentation/git-reflog.txt
Documentation/git-remote.txt
Documentation/git-rev-parse.txt
Documentation/git-stash.txt
Documentation/git-web--browse.txt
Documentation/git.txt
Documentation/gitdiffcore.txt
Documentation/gitremote-helpers.txt
Documentation/gitrepository-layout.txt
Documentation/glossary-content.txt
Documentation/line-range-format.txt [new file with mode: 0644]
Documentation/merge-options.txt
Documentation/pull-fetch-param.txt
Documentation/rev-list-options.txt
Documentation/revisions.txt
Documentation/technical/api-builtin.txt
Documentation/technical/api-parse-options.txt
Documentation/technical/pack-protocol.txt
Documentation/technical/racy-git.txt
Documentation/urls.txt
Documentation/user-manual.txt
GIT-VERSION-GEN
Makefile
RelNotes
abspath.c
advice.c
advice.h
archive-zip.c
bisect.c
branch.c
builtin.h
builtin/apply.c
builtin/blame.c
builtin/check-ignore.c
builtin/checkout.c
builtin/clone.c
builtin/commit.c
builtin/config.c
builtin/describe.c
builtin/diff.c
builtin/fast-export.c
builtin/fetch.c
builtin/fsck.c
builtin/help.c
builtin/index-pack.c
builtin/log.c
builtin/ls-files.c
builtin/merge-base.c
builtin/merge.c
builtin/name-rev.c
builtin/notes.c
builtin/pack-refs.c
builtin/prune-packed.c
builtin/prune.c
builtin/push.c
builtin/read-tree.c
builtin/reflog.c
builtin/replace.c
builtin/rev-parse.c
builtin/rm.c
builtin/show-branch.c
builtin/show-ref.c
bundle.c
cache.h
color.c
combine-diff.c
commit-slab.h [new file with mode: 0644]
commit.c
commit.h
compat/clipped-write.c [new file with mode: 0644]
compat/cygwin.c
compat/fnmatch/fnmatch.c
compat/mingw.c
compat/mingw.h
compat/nedmalloc/malloc.c.h
compat/nedmalloc/nedmalloc.c
compat/poll/poll.c
compat/regex/regexec.c
compat/terminal.c
compat/unsetenv.c
compat/win32.h
compat/win32/pthread.c
compat/win32mmap.c
config.c
config.mak.uname
configure.ac
connect.c
connected.c
connected.h
contrib/blameview/README [deleted file]
contrib/blameview/blameview.perl [deleted file]
contrib/completion/git-completion.bash
contrib/completion/git-completion.zsh
contrib/completion/git-prompt.sh
contrib/continuous/cidaemon [deleted file]
contrib/continuous/post-receive-cinotify [deleted file]
contrib/credential/osxkeychain/git-credential-osxkeychain.c
contrib/mw-to-git/.perlcriticrc [new file with mode: 0644]
contrib/mw-to-git/Makefile
contrib/mw-to-git/git-remote-mediawiki.perl
contrib/mw-to-git/t/test-gitmw-lib.sh
contrib/mw-to-git/t/test.config
contrib/patches/docbook-xsl-manpages-charmap.patch [deleted file]
contrib/remote-helpers/git-remote-bzr
contrib/remote-helpers/git-remote-hg
contrib/remote-helpers/test-bzr.sh
contrib/remote-helpers/test-hg-bidi.sh
contrib/remote-helpers/test-hg-hg-git.sh
contrib/remote-helpers/test-hg.sh
contrib/subtree/git-subtree.sh
credential-store.c
date.c
decorate.c
diff-lib.c
diff-no-index.c
diff.c
diffcore-pickaxe.c
dir.c
environment.c
fast-import.c
fetch-pack.c
fetch-pack.h
fixup-builtins [deleted file]
git-add--interactive.perl
git-am.sh
git-bisect.sh
git-compat-util.h
git-difftool.perl
git-gui/GIT-VERSION-GEN
git-gui/Makefile
git-gui/git-gui.sh
git-gui/lib/choose_repository.tcl
git-gui/lib/diff.tcl
git-gui/lib/mergetool.tcl
git-gui/lib/remote.tcl
git-gui/po/fr.po
git-mergetool--lib.sh
git-p4.py
git-pull.sh
git-rebase--am.sh
git-rebase--interactive.sh
git-rebase--merge.sh
git-rebase.sh
git-remote-testgit.sh [moved from git-remote-testgit with 57% similarity]
git-send-email.perl
git-sh-setup.sh
git-stash.sh
git-submodule.sh
git-svn.perl
git-web--browse.sh
git.c
git.rc [new file with mode: 0644]
gitweb/gitweb.perl
help.c
help.h
http-backend.c
http.c
imap-send.c
line-log.c [new file with mode: 0644]
line-log.h [new file with mode: 0644]
line-range.c [new file with mode: 0644]
line-range.h [new file with mode: 0644]
lockfile.c
log-tree.c
match-trees.c
notes-merge.c
notes-merge.h
notes-utils.c [new file with mode: 0644]
notes-utils.h [new file with mode: 0644]
notes.c
object.c
object.h
pack-refs.c [deleted file]
pack-refs.h [deleted file]
parse-options-cb.c
parse-options.h
prio-queue.c [new file with mode: 0644]
prio-queue.h [new file with mode: 0644]
read-cache.c
refs.c
refs.h
remote-testsvn.c
remote.c
revision.c
revision.h
run-command.c
sequencer.c
sha1_file.c
sha1_name.c
shallow.c
submodule.c
t/Makefile
t/README
t/lib-httpd/apache.conf
t/lib-rebase.sh
t/lib-t6000.sh
t/perf/README
t/perf/p0002-read-cache.sh [new file with mode: 0755]
t/perf/p4211-line-log.sh [new file with mode: 0755]
t/t0000-basic.sh
t/t0005-signals.sh
t/t0008-ignores.sh
t/t0009-prio-queue.sh [new file with mode: 0755]
t/t0020-crlf.sh
t/t0040-parse-options.sh
t/t0070-fundamental.sh
t/t0100-previous.sh
t/t1004-read-tree-m-u-wf.sh
t/t1507-rev-parse-upstream.sh
t/t1508-at-combinations.sh
t/t1512-rev-parse-disambiguation.sh
t/t1513-rev-parse-prefix.sh [new file with mode: 0755]
t/t2001-checkout-cache-clash.sh
t/t2004-checkout-cache-temp.sh
t/t2007-checkout-symlink.sh
t/t2012-checkout-last.sh
t/t2021-checkout-overwrite.sh
t/t2024-checkout-dwim.sh [new file with mode: 0755]
t/t2200-add-update.sh
t/t3001-ls-files-others-exclude.sh
t/t3010-ls-files-killed-modified.sh
t/t3030-merge-recursive.sh
t/t3070-wildmatch.sh
t/t3100-ls-tree-restrict.sh
t/t3200-branch.sh
t/t3210-pack-refs.sh
t/t3211-peel-ref.sh
t/t3400-rebase.sh
t/t3401-rebase-partial.sh [deleted file]
t/t3403-rebase-skip.sh
t/t3404-rebase-interactive.sh
t/t3406-rebase-message.sh
t/t3409-rebase-preserve-merges.sh
t/t3415-rebase-autosquash.sh
t/t3420-rebase-autostash.sh [new file with mode: 0755]
t/t3421-rebase-topology-linear.sh [new file with mode: 0755]
t/t3425-rebase-topology-merges.sh [new file with mode: 0755]
t/t3505-cherry-pick-empty.sh
t/t3509-cherry-pick-merge-df.sh
t/t3600-rm.sh
t/t3700-add.sh
t/t3903-stash.sh
t/t4008-diff-break-rewrite.sh
t/t4011-diff-symlink.sh
t/t4015-diff-whitespace.sh
t/t4023-diff-rename-typechange.sh
t/t4030-diff-textconv.sh
t/t4038-diff-combined.sh
t/t4111-apply-subdir.sh
t/t4114-apply-typechange.sh
t/t4115-apply-symlink.sh
t/t4122-apply-symlink-inside.sh
t/t4150-am.sh
t/t4202-log.sh
t/t4211-line-log.sh [new file with mode: 0755]
t/t4211/expect.beginning-of-file [new file with mode: 0644]
t/t4211/expect.end-of-file [new file with mode: 0644]
t/t4211/expect.move-support-f [new file with mode: 0644]
t/t4211/expect.multiple [new file with mode: 0644]
t/t4211/expect.multiple-overlapping [new file with mode: 0644]
t/t4211/expect.multiple-superset [new file with mode: 0644]
t/t4211/expect.parallel-change-f-to-main [new file with mode: 0644]
t/t4211/expect.simple-f [new file with mode: 0644]
t/t4211/expect.simple-f-to-main [new file with mode: 0644]
t/t4211/expect.simple-main [new file with mode: 0644]
t/t4211/expect.simple-main-to-end [new file with mode: 0644]
t/t4211/expect.two-ranges [new file with mode: 0644]
t/t4211/expect.vanishes-early [new file with mode: 0644]
t/t4211/history.export [new file with mode: 0644]
t/t5000-tar-tree.sh
t/t5000/pax.tar [new file with mode: 0644]
t/t5003-archive-zip.sh
t/t5004-archive-corner-cases.sh
t/t5004/empty-with-pax-header.tar [new file with mode: 0644]
t/t5150-request-pull.sh
t/t5303-pack-corruption-resilience.sh
t/t5407-post-rewrite-hook.sh
t/t5500-fetch-pack.sh
t/t5505-remote.sh
t/t5510-fetch.sh
t/t5520-pull.sh
t/t5521-pull-options.sh
t/t5528-push-default.sh
t/t5551-http-fetch.sh
t/t5601-clone.sh
t/t5702-clone-options.sh
t/t5801-remote-helpers.sh
t/t6002-rev-list-bisect.sh
t/t6003-rev-list-topo-order.sh
t/t6012-rev-list-simplify.sh
t/t6019-rev-list-ancestry-path.sh
t/t6035-merge-dir-to-symlink.sh
t/t6111-rev-list-treesame.sh [new file with mode: 0755]
t/t6120-describe.sh
t/t7001-mv.sh
t/t7011-skip-worktree-reading.sh
t/t7102-reset.sh
t/t7201-co.sh
t/t7400-submodule-basic.sh
t/t7401-submodule-summary.sh
t/t7403-submodule-sync.sh
t/t7406-submodule-update.sh
t/t7407-submodule-foreach.sh
t/t7500-commit.sh
t/t7501-commit.sh
t/t7502-commit.sh
t/t7508-status.sh
t/t7512-status-help.sh
t/t7600-merge.sh
t/t7607-merge-overwrite.sh
t/t7800-difftool.sh
t/t8003-blame-corner-cases.sh
t/t8006-blame-textconv.sh
t/t8007-cat-file-textconv.sh
t/t9001-send-email.sh
t/t9114-git-svn-dcommit-merge.sh
t/t9350-fast-export.sh
t/t9402-git-cvsserver-refs.sh
t/t9500-gitweb-standalone-no-errors.sh
t/t9802-git-p4-filetype.sh
t/t9902-completion.sh
t/t9903-bash-prompt.sh
t/test-lib-functions.sh
t/test-lib.sh
t/valgrind/analyze.sh
templates/hooks--pre-push.sample [changed mode: 0644->0755]
test-chmtime.c
test-index-version.c
test-mergesort.c
test-parse-options.c
test-prio-queue.c [new file with mode: 0644]
test-read-cache.c [new file with mode: 0644]
test-subprocess.c
thread-utils.c
transport-helper.c
transport.c
transport.h
tree-walk.h
unpack-trees.c
unpack-trees.h
upload-pack.c
wildmatch.c
wrapper.c
wt-status.c
xdiff/xdiff.h
xdiff/xdiffi.c
xdiff/xdiffi.h
xdiff/xemit.c
xdiff/xemit.h
xdiff/xutils.c
xdiff/xutils.h

index 6669bf0..efa8db0 100644 (file)
 /git-remote-ftps
 /git-remote-fd
 /git-remote-ext
+/git-remote-testgit
 /git-remote-testpy
 /git-remote-testsvn
 /git-repack
 /test-mktemp
 /test-parse-options
 /test-path-utils
+/test-prio-queue
+/test-read-cache
 /test-regex
 /test-revision-walking
 /test-run-command
 /cscope*
 *.obj
 *.lib
+*.res
 *.sln
 *.suo
 *.ncb
index 48d7acf..345cce6 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -24,6 +24,7 @@ Eric S. Raymond <esr@thyrsus.com>
 Erik Faye-Lund <kusmabite@gmail.com> <kusmabite@googlemail.com>
 Fredrik Kuivinen <freku045@student.liu.se>
 Frédéric Heitzmann <frederic.heitzmann@gmail.com>
+H. Merijn Brand <h.m.brand@xs4all.nl> H.Merijn Brand <h.m.brand@xs4all.nl>
 H. Peter Anvin <hpa@bonde.sc.orionmulti.com>
 H. Peter Anvin <hpa@tazenda.sc.orionmulti.com>
 H. Peter Anvin <hpa@trantor.hos.anvin.org>
index 62dbd9a..0cfdc36 100644 (file)
@@ -31,11 +31,11 @@ MAN7_TXT += gittutorial.txt
 MAN7_TXT += gitworkflows.txt
 
 MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
-MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
-MAN_HTML=$(patsubst %.txt,%.html,$(MAN_TXT))
+MAN_XML = $(patsubst %.txt,%.xml,$(MAN_TXT))
+MAN_HTML = $(patsubst %.txt,%.html,$(MAN_TXT))
 
 OBSOLETE_HTML = git-remote-helpers.html
-DOC_HTML=$(MAN_HTML) $(OBSOLETE_HTML)
+DOC_HTML = $(MAN_HTML) $(OBSOLETE_HTML)
 
 ARTICLES = howto-index
 ARTICLES += everyday
@@ -74,35 +74,35 @@ SP_ARTICLES += technical/api-index
 
 DOC_HTML += $(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES))
 
-DOC_MAN1=$(patsubst %.txt,%.1,$(MAN1_TXT))
-DOC_MAN5=$(patsubst %.txt,%.5,$(MAN5_TXT))
-DOC_MAN7=$(patsubst %.txt,%.7,$(MAN7_TXT))
-
-prefix?=$(HOME)
-bindir?=$(prefix)/bin
-htmldir?=$(prefix)/share/doc/git-doc
-pdfdir?=$(prefix)/share/doc/git-doc
-mandir?=$(prefix)/share/man
-man1dir=$(mandir)/man1
-man5dir=$(mandir)/man5
-man7dir=$(mandir)/man7
-# DESTDIR=
+DOC_MAN1 = $(patsubst %.txt,%.1,$(MAN1_TXT))
+DOC_MAN5 = $(patsubst %.txt,%.5,$(MAN5_TXT))
+DOC_MAN7 = $(patsubst %.txt,%.7,$(MAN7_TXT))
+
+prefix ?= $(HOME)
+bindir ?= $(prefix)/bin
+htmldir ?= $(prefix)/share/doc/git-doc
+infodir ?= $(prefix)/share/info
+pdfdir ?= $(prefix)/share/doc/git-doc
+mandir ?= $(prefix)/share/man
+man1dir = $(mandir)/man1
+man5dir = $(mandir)/man5
+man7dir = $(mandir)/man7
+# DESTDIR =
 
 ASCIIDOC = asciidoc
 ASCIIDOC_EXTRA =
 MANPAGE_XSL = manpage-normal.xsl
 XMLTO = xmlto
 XMLTO_EXTRA =
-INSTALL?=install
+INSTALL ?= install
 RM ?= rm -f
 MAN_REPO = ../../git-manpages
 HTML_REPO = ../../git-htmldocs
 
-infodir?=$(prefix)/share/info
-MAKEINFO=makeinfo
-INSTALL_INFO=install-info
-DOCBOOK2X_TEXI=docbook2x-texi
-DBLATEX=dblatex
+MAKEINFO = makeinfo
+INSTALL_INFO = install-info
+DOCBOOK2X_TEXI = docbook2x-texi
+DBLATEX = dblatex
 ifndef PERL_PATH
        PERL_PATH = /usr/bin/perl
 endif
diff --git a/Documentation/RelNotes/1.8.3.1.txt b/Documentation/RelNotes/1.8.3.1.txt
new file mode 100644 (file)
index 0000000..fc3ea18
--- /dev/null
@@ -0,0 +1,14 @@
+Git v1.8.3.1 Release Notes
+========================
+
+Fixes since v1.8.3
+------------------
+
+ * When $HOME is misconfigured to point at an unreadable directory, we
+   used to complain and die. The check has been loosened.
+
+ * Handling of negative exclude pattern for directories "!dir" was
+   broken in the update to v1.8.3.
+
+Also contains a handful of trivial code clean-ups, documentation
+updates, updates to the test suite, etc.
diff --git a/Documentation/RelNotes/1.8.3.2.txt b/Documentation/RelNotes/1.8.3.2.txt
new file mode 100644 (file)
index 0000000..26ae142
--- /dev/null
@@ -0,0 +1,59 @@
+Git v1.8.3.2 Release Notes
+==========================
+
+Fixes since v1.8.3.1
+--------------------
+
+ * Cloning with "git clone --depth N" while fetch.fsckobjects (or
+   transfer.fsckobjects) is set to true did not tell the cut-off
+   points of the shallow history to the process that validates the
+   objects and the history received, causing the validation to fail.
+
+ * "git checkout foo" DWIMs the intended "upstream" and turns it into
+   "git checkout -t -b foo remotes/origin/foo". This codepath has been
+   updated to correctly take existing remote definitions into account.
+
+ * "git fetch" into a shallow repository from a repository that does
+   not know about the shallow boundary commits (e.g. a different fork
+   from the repository the current shallow repository was cloned from)
+   did not work correctly.
+
+ * "git subtree" (in contrib/) had one codepath with loose error
+   checks to lose data at the remote side.
+
+ * "git log --ancestry-path A...B" did not work as expected, as it did
+   not pay attention to the fact that the merge base between A and B
+   was the bottom of the range being specified.
+
+ * "git diff -c -p" was not showing a deleted line from a hunk when
+   another hunk immediately begins where the earlier one ends.
+
+ * "git merge @{-1}~22" was rewritten to "git merge frotz@{1}~22"
+   incorrectly when your previous branch was "frotz" (it should be
+   rewritten to "git merge frotz~22" instead).
+
+ * "git commit --allow-empty-message -m ''" should not start an
+   editor.
+
+ * "git push --[no-]verify" was not documented.
+
+ * An entry for "file://" scheme in the enumeration of URL types Git
+   can take in the HTML documentation was made into a clickable link
+   by mistake.
+
+ * zsh prompt script that borrowed from bash prompt script did not
+   work due to slight differences in array variable notation between
+   these two shells.
+
+ * The bash prompt code (in contrib/) displayed the name of the branch
+   being rebased when "rebase -i/-m/-p" modes are in use, but not the
+   plain vanilla "rebase".
+
+ * "git push $there HEAD:branch" did not resolve HEAD early enough, so
+   it was easy to flip it around while push is still going on and push
+   out a branch that the user did not originally intended when the
+   command was started.
+
+ * "difftool --dir-diff" did not copy back changes made by the
+   end-user in the diff tool backend to the working tree in some
+   cases.
diff --git a/Documentation/RelNotes/1.8.3.3.txt b/Documentation/RelNotes/1.8.3.3.txt
new file mode 100644 (file)
index 0000000..04289e7
--- /dev/null
@@ -0,0 +1,26 @@
+Git v1.8.3.3 Release Notes
+==========================
+
+Fixes since v1.8.3.2
+--------------------
+
+ * "gitweb" forgot to clear a global variable $search_regexp upon each
+   request, mistakenly carrying over the previous search to a new one
+   when used as a persistent CGI.
+
+ * The wildmatch engine did not honor WM_CASEFOLD option correctly.
+
+ * "git log -c --follow $path" segfaulted upon hitting the commit that
+   renamed the $path being followed.
+
+ * When a reflog notation is used for implicit "current branch",
+   e.g. "git log @{u}", we did not say which branch and worse said
+   "branch ''" in the error messages.
+
+ * Mac OS X does not like to write(2) more than INT_MAX number of
+   bytes; work it around by chopping write(2) into smaller pieces.
+
+ * Newer MacOS X encourages the programs to compile and link with
+   their CommonCrypto, not with OpenSSL.
+
+Also contains various minor documentation updates.
diff --git a/Documentation/RelNotes/1.8.4.txt b/Documentation/RelNotes/1.8.4.txt
new file mode 100644 (file)
index 0000000..b85f16b
--- /dev/null
@@ -0,0 +1,334 @@
+Git v1.8.4 Release Notes
+========================
+
+Updates since v1.8.3
+--------------------
+
+Foreign interfaces, subsystems and ports.
+
+ * Git-gui has been updated to its 0.18.0 version.
+
+ * MediaWiki remote helper (in contrib/) has been updated to use the
+   credential helper interface from Git.pm.
+
+ * Update build for Cygwin 1.[57].  Torsten Bögershausen reports that
+   this is fine with Cygwin 1.7 ($gmane/225824) so let's try moving it
+   ahead.
+
+ * The credential helper to talk to keychain on OS X (in contrib/) has
+   been updated to kick in not just when talking http/https but also
+   imap(s) and smtp.
+
+ * Remote transport helper has been updated to report errors and
+   maintain ref hierarchy used to keep track of its own state better.
+
+ * With "export" remote-helper protocol, (1) a push that tries to
+   update a remote ref whose name is different from the pushing side
+   does not work yet, and (2) the helper may not know how to do
+   --dry-run; these problematic cases are disabled for now.
+
+ * git-remote-hg/bzr (in contrib/) updates.
+
+ * git-remote-mw (in contrib/) hints users to check the certificate,
+   when https:// connection failed.
+
+
+UI, Workflows & Features
+
+ * Having multiple "fixup!" on a line in the rebase instruction sheet
+   did not work very well with "git rebase -i --autosquash".
+
+ * "git log" learned the "--author-date-order" option, with which the
+   output is topologically sorted and commits in parallel histories
+   are shown intermixed together based on the author timestamp.
+
+ * Various subcommands of "git submodule" refused to run from anywhere
+   other than the top of the working tree of the superproject, but
+   they have been taught to let you run from a subdirectory.
+
+ * "git diff" learned a mode that ignores hunks whose change consists
+   only of additions and removals of blank lines, which is the same as
+   "diff -B" (ignore blank lines) of GNU diff.
+
+ * "git rm" gives a single message followed by list of paths to report
+   multiple paths that cannot be removed.
+
+ * "git rebase" can be told with ":/look for this string" syntax commits
+   to replay the changes onto and where the work to be replayed begins.
+
+ * Many tutorials teach users to set "color.ui" to "auto" as the first
+   thing after you set "user.name/email" to introduce yourselves to
+   Git.  Now the variable defaults to "auto".
+
+ * On Cygwin, "cygstart" is now recognised as a possible way to start
+   a web browser (used in "help -w" and "instaweb" among others).
+
+### * "git status" learned status.branch and status.short configuration
+###   variables to use --branch and --short options by default (override
+###   with --no-branch and --no-short options from the command line).
+
+ * "git cmd <name>", when <name> happens to be a 40-hex string,
+   directly uses the 40-hex string as an object name, even if a ref
+   "refs/<some hierarchy>/<name>" exists.  This disambiguation order
+   is unlikely to change, but we should warn about the ambiguity just
+   like we warn when more than one refs/ hierachies share the same
+   name.
+
+ * "git rebase" learned "--[no-]autostash" option to save local
+   changes instead of refusing to run (to which people's normal
+   response was to stash them and re-run).  This introduced a corner
+   case breakage to "git am --abort" but it has been fixed.
+
+ * Instead of typing four capital letters "HEAD", you can say "@" now,
+   e.g. "git log @".
+
+ * "check-ignore" (new feature since 1.8.2) has been updated to work
+   more like "check-attr" over bidi-pipes.
+
+ * "git describe" learned "--first-parent" option to limit its closest
+   tagged commit search to the first-parent chain.
+
+ * "git merge foo" that might have meant "git merge origin/foo" is
+   diagnosed with a more informative error message.
+
+ * "git log -L<line>,<range>:<filename>" has been added.  This may
+   still have leaks and rough edges, though.
+
+ * We used the approxidate() parser for "--expire=<timestamp>" options
+   of various commands, but it is better to treat --expire=all and
+   --expire=now a bit more specially than using the current timestamp.
+   "git gc" and "git reflog" have been updated with a new parsing
+   function for expiry dates.
+
+ * Updates to completion (both bash and zsh) helpers.
+
+ * The behaviour of the "--chain-reply-to" option of "git send-email"
+   have changed at 1.7.0, and we added a warning/advice message to
+   help users adjust to the new behaviour back then, but we kept it
+   around for too long.  The message has finally been removed.
+
+ * "git fetch origin master" unlike "git fetch origin" or "git fetch"
+   did not update "refs/remotes/origin/master"; this was an early
+   design decision to keep the update of remote tracking branches
+   predictable, but in practice it turns out that people find it more
+   convenient to opportunistically update them whenever we have a
+   chance, and we have been updating them when we run "git push" which
+   already breaks the original "predictability" anyway.
+
+ * The configuration variable core.checkstat was advertised in the
+   documentation but the code expected core.statinfo instead.
+   For now, we accept both core.checkstat and core.statinfo, but the
+   latter will be removed in the longer term.
+
+
+Performance, Internal Implementation, etc.
+
+ * The original way to specify remote repository using .git/branches/
+   used to have a nifty feature.  The code to support the feature was
+   still in a function but the caller was changed not to call it 5
+   years ago, breaking that feature and leaving the supporting code
+   unreachable.  The dead code has been removed.
+
+ * "git pack-refs" that races with new ref creation or deletion have
+   been susceptible to lossage of refs under right conditions, which
+   has been tightened up.
+
+ * We read loose and packed rerferences in two steps, but after
+   deciding to read a loose ref but before actually opening it to read
+   it, another process racing with us can unlink it, which would cause
+   us to barf.  The codepath has been updated to retry when such a
+   race is detected, instead of outright failing.
+
+ * Uses of the platform fnmatch(3) function (many places in the code,
+   matching pathspec, .gitignore and .gitattributes to name a few)
+   have been replaced with wildmatch, allowing "foo/**/bar" that would
+   match foo/bar, foo/a/bar, foo/a/b/bar, etc.
+
+ * Memory ownership and lifetime rules for what for-each-ref feeds to
+   its callbacks have been clarified (in short, "you do not own it, so
+   make a copy if you want to keep it").
+
+ * The revision traversal logic to improve culling of irrelevant
+   parents while traversing a mergy history has been updated.
+
+ * Some leaks in unpack-trees (used in merge, cherry-pick and other
+   codepaths) have been plugged.
+
+ * The codepath to read from marks files in fast-import/export did not
+   have to accept anything but 40-hex representation of the object
+   name.  Further, fast-export did not need full in-core object
+   representation to have parsed wen reading from them.  These
+   codepaths have been optimized by taking advantage of these access
+   patterns.
+
+ * Object lookup logic, when the object hashtable starts to become
+   crowded, has been optimized.
+
+ * When TEST_OUTPUT_DIRECTORY setting is used, it was handled somewhat
+   inconsistently between the test framework and t/Makefile, and logic
+   to summarize the results looked at a wrong place.
+
+ * "git clone" uses a lighter-weight implementation when making sure
+   that the history behind refs are complete.
+
+ * Many warnings from sparse source checker in compat/ area has been
+   squelched.
+
+ * The code to reading and updating packed-refs file has been updated,
+   correcting corner case bugs.
+
+
+Also contains various documentation updates and code clean-ups.
+
+
+Fixes since v1.8.3
+------------------
+
+Unless otherwise noted, all the fixes since v1.8.3 in the maintenance
+track are contained in this release (see release notes to them for
+details).
+
+ * The configuration variable column.ui was poorly documented.
+   (merge 5e62cc1 rr/column-doc later to maint).
+
+ * "git name-rev --refs=tags/v*" were forbidden, which was a bit
+   inconvenient (you had to give a pattern to match refs fully, like
+   --refs=refs/tags/v*).
+   (merge 98c5c4a nk/name-rev-abbreviated-refs later to maint).
+
+ * "git apply" parsed patches that add new files, generated by
+   programs other than Git, incorrectly.  This is an old breakage in
+   v1.7.11 and will need to be merged down to the maintanance tracks.
+   (merge 212eb96 tr/maint-apply-non-git-patch-parsefix later to maint).
+
+ * Older cURL wanted piece of memory we call it with to be stable, but
+   we updated the auth material after handing it to a call.
+   (merge a94cf2c bc/http-keep-memory-given-to-curl later to maint).
+
+ * "git pull" into nothing trashed "local changes" that were in the
+   index, and this avoids it.
+   (merge b4dc085 jk/pull-into-dirty-unborn later to maint).
+
+ * Many "git submodule" operations do not work on a submodule at a
+   path whose name is not in ASCII.
+   (merge bed9470 fg/submodule-non-ascii-path later to maint).
+
+ * "cherry-pick" had a small leak in an error codepath.
+   (merge 706728a fc/sequencer-plug-leak later to maint).
+
+ * Logic used by git-send-email to suppress cc mishandled names like
+   "A U. Thor" <author@example.xz>, where the human readable part
+   needs to be quoted (the user input may not have the double quotes
+   around the name, and comparison was done between quoted and
+   unquoted strings).  It also mishandled names that need RFC2047
+   quoting.
+   (merge 1495266 mt/send-email-cc-match-fix later to maint).
+
+ * Call to discard_cache/discard_index (used when we use different
+   contents of the index in-core, in many operations like commit,
+   apply, and merge) used to leak memory that held the array of index
+   entries, which has been plugged.
+   (merge a0fc4db rs/discard-index-discard-array later to maint).
+
+ * "gitweb" forgot to clear a global variable $search_regexp upon each
+   request, mistakenly carrying over the previous search to a new one
+   when used as a persistent CGI.
+   (merge ca7a5dc cm/gitweb-project-list-persistent-cgi-fix later to maint).
+
+ * The wildmatch engine did not honor WM_CASEFOLD option correctly.
+   (merge b79c0c3 ar/wildmatch-foldcase later to maint).
+
+ * "git log -c --follow $path" segfaulted upon hitting the commit that
+   renamed the $path being followed.
+   (merge 46ec510 cb/log-follow-with-combined later to maint).
+
+ * When a reflog notation is used for implicit "current branch", we
+   did not say which branch and worse said "branch ''".
+   (merge 305ebea rr/die-on-missing-upstream later to maint).
+
+ * "difftool --dir-diff" did not copy back changes made by the
+   end-user in the diff tool backend to the working tree in some
+   cases.
+   (merge 32eaf1d ks/difftool-dir-diff-copy-fix later to maint).
+
+ * "git push $there HEAD:branch" did not resolve HEAD early enough, so
+   it was easy to flip it around while push is still going on and push
+   out a branch that the user did not originally intended when the
+   command was started.
+   (merge 0f075b2 rr/push-head later to maint).
+
+ * The bash prompt code (in contrib/) displayed the name of the branch
+   being rebased when "rebase -i/-m/-p" modes are in use, but not the
+   plain vanilla "rebase".
+   (merge 1306321 fc/show-branch-in-rebase-am later to maint).
+
+ * Handling of negative exclude pattern for directories "!dir" was
+   broken in the update to v1.8.3.
+   (merge c3c327d kb/status-ignored-optim-2 later to maint).
+
+ * zsh prompt script that borrowed from bash prompt script did not
+   work due to slight differences in array variable notation between
+   these two shells.
+   (merge d0583da tg/maint-zsh-svn-remote-prompt later to maint).
+
+ * An entry for "file://" scheme in the enumeration of URL types Git
+   can take in the HTML documentation was made into a clickable link
+   by mistake.
+   (merge 4c32e36 nd/urls-doc-no-file-hyperlink-fix later to maint).
+
+ * "git push --[no-]verify" was not documented.
+   (merge 90d32d1 tr/push-no-verify-doc later to maint).
+
+ * Stop installing the git-remote-testpy script that is only used for
+   testing.
+   (merge 416fda6 fc/makefile later to maint).
+
+ * "git commit --allow-empty-message -m ''" should not start an
+   editor.
+   (merge 2520677 rs/commit-m-no-edit later to maint).
+
+ * "git merge @{-1}~22" was rewritten to "git merge frotz@{1}~22"
+   incorrectly when your previous branch was "frotz" (it should be
+   rewritten to "git merge frotz~22" instead).
+   (merge 84cf246 jc/strbuf-branchname-fix later to maint).
+
+ * "git diff -c -p" was not showing a deleted line from a hunk when
+   another hunk immediately begins where the earlier one ends.
+   (merge aac3857 mk/combine-diff-context-horizon-fix later to maint).
+
+ * "git log --ancestry-path A...B" did not work as expected, as it did
+   not pay attention to the fact that the merge base between A and B
+   was the bottom of the range being specified.
+   (merge a765499 kb/ancestry-path-threedots later to maint).
+
+ * Mac OS X does not like to write(2) more than INT_MAX number of
+   bytes; work it around by chopping write(2) into smaller pieces.
+   (merge 6c642a8 fc/macos-x-clipped-write later to maint).
+
+ * Newer MacOS X encourages the programs to compile and link with
+   their CommonCrypto, not with OpenSSL.
+   (merge be4c828 da/darwin later to maint).
+
+ * "git clone foo/bar:baz" cannot be a request to clone from a remote
+   over git-over-ssh specified in the scp style.  This case is now
+   detected and clones from a local repository at "foo/bar:baz".
+   (merge 6000334 nd/clone-local-with-colon later to maint).
+
+ * When $HOME is misconfigured to point at an unreadable directory, we
+   used to complain and die. Loosen the check.
+   (merge 4698c8f jn/config-ignore-inaccessible later to maint).
+
+ * "git subtree" (in contrib/) had one codepath with loose error
+   checks to lose data at the remote side.
+   (merge 3212d56 jk/subtree-do-not-push-if-split-fails later to maint).
+
+ * "git fetch" into a shallow repository from a repository that does
+   not know about the shallow boundary commits (e.g. a different fork
+   from the repository the current shallow repository was cloned from)
+   did not work correctly.
+   (merge 71d5f93 mh/fetch-into-shallow later to maint).
+
+ * "git checkout foo" DWIMs the intended "upstream" and turns it into
+   "git checkout -t -b foo remotes/origin/foo". This codepath has been
+   updated to correctly take existing remote definitions into account.
+   (merge 229177a jh/checkout-auto-tracking later to maint).
index b0d31df..e9f984b 100644 (file)
@@ -9,28 +9,11 @@
 --show-stats::
        Include additional statistics at the end of blame output.
 
--L <start>,<end>::
+-L <start>,<end>, -L :<regex>::
        Annotate only the given line range.  <start> and <end> can take
        one of these forms:
 
-       - number
-+
-If <start> or <end> is a number, it specifies an
-absolute line number (lines count from 1).
-+
-
-- /regex/
-+
-This form will use the first line matching the given
-POSIX regex.  If <end> is a regex, it will search
-starting at the line given by <start>.
-+
-
-- +offset or -offset
-+
-This is only valid for <end> and will specify a number
-of lines before or after the line given by <start>.
-+
+include::line-range-format.txt[]
 
 -l::
        Show long rev (Default: off).
index 6e53fc5..81856dd 100644 (file)
@@ -199,6 +199,9 @@ advice.*::
        amWorkDir::
                Advice that shows the location of the patch file when
                linkgit:git-am[1] fails to apply it.
+       rmHints::
+               In case of failure in the output of linkgit:git-rm[1],
+               show directions on how to proceed from the current state.
 --
 
 core.fileMode::
@@ -919,17 +922,21 @@ color.ui::
        as `color.diff` and `color.grep` that control the use of color
        per command family. Its scope will expand as more commands learn
        configuration to set a default for the `--color` option.  Set it
-       to `always` if you want all output not intended for machine
-       consumption to use color, to `true` or `auto` if you want such
-       output to use color when written to the terminal, or to `false` or
-       `never` if you prefer Git commands not to use color unless enabled
-       explicitly with some other configuration or the `--color` option.
+       to `false` or `never` if you prefer Git commands not to use
+       color unless enabled explicitly with some other configuration
+       or the `--color` option. Set it to `always` if you want all
+       output not intended for machine consumption to use color, to
+       `true` or `auto` (this is the default since Git 1.8.4) if you
+       want such output to use color when written to the terminal.
 
 column.ui::
        Specify whether supported commands should output in columns.
        This variable consists of a list of tokens separated by spaces
        or commas:
 +
+These options control when the feature should be enabled
+(defaults to 'never'):
++
 --
 `always`;;
        always show in columns
@@ -937,19 +944,30 @@ column.ui::
        never show in columns
 `auto`;;
        show in columns if the output is to the terminal
+--
++
+These options control layout (defaults to 'column').  Setting any
+of these implies 'always' if none of 'always', 'never', or 'auto' are
+specified.
++
+--
 `column`;;
-       fill columns before rows (default)
+       fill columns before rows
 `row`;;
        fill rows before columns
 `plain`;;
        show in one column
+--
++
+Finally, these options can be combined with a layout option (defaults
+to 'nodense'):
++
+--
 `dense`;;
        make unequal size columns to utilize more space
 `nodense`;;
        make equal size columns
 --
-+
-This option defaults to 'never'.
 
 column.branch::
        Specify whether to output branch listing in `git branch` in columns.
@@ -1826,39 +1844,59 @@ pull.twohead::
        The default merge strategy to use when pulling a single branch.
 
 push.default::
-       Defines the action `git push` should take if no refspec is given
-       on the command line, no refspec is configured in the remote, and
-       no refspec is implied by any of the options given on the command
-       line. Possible values are:
+       Defines the action `git push` should take if no refspec is
+       explicitly given.  Different values are well-suited for
+       specific workflows; for instance, in a purely central workflow
+       (i.e. the fetch source is equal to the push destination),
+       `upstream` is probably what you want.  Possible values are:
 +
 --
-* `nothing` - do not push anything.
-* `matching` - push all branches having the same name in both ends.
-  This is for those who prepare all the branches into a publishable
-  shape and then push them out with a single command.  It is not
-  appropriate for pushing into a repository shared by multiple users,
-  since locally stalled branches will attempt a non-fast forward push
-  if other users updated the branch.
-  +
-  This is currently the default, but Git 2.0 will change the default
-  to `simple`.
-* `upstream` - push the current branch to its upstream branch
-  (`tracking` is a deprecated synonym for this).
-  With this, `git push` will update the same remote ref as the one which
-  is merged by `git pull`, making `push` and `pull` symmetrical.
-  See "branch.<name>.merge" for how to configure the upstream branch.
-* `simple` - like `upstream`, but refuses to push if the upstream
-  branch's name is different from the local one. This is the safest
-  option and is well-suited for beginners. It will become the default
-  in Git 2.0.
-* `current` - push the current branch to a branch of the same name.
---
+
+* `nothing` - do not push anything (error out) unless a refspec is
+  explicitly given. This is primarily meant for people who want to
+  avoid mistakes by always being explicit.
+
+* `current` - push the current branch to update a branch with the same
+  name on the receiving end.  Works in both central and non-central
+  workflows.
+
+* `upstream` - push the current branch back to the branch whose
+  changes are usually integrated into the current branch (which is
+  called `@{upstream}`).  This mode only makes sense if you are
+  pushing to the same repository you would normally pull from
+  (i.e. central workflow).
+
+* `simple` - in centralized workflow, work like `upstream` with an
+  added safety to refuse to push if the upstream branch's name is
+  different from the local one.
++
+When pushing to a remote that is different from the remote you normally
+pull from, work as `current`.  This is the safest option and is suited
+for beginners.
++
+This mode will become the default in Git 2.0.
+
+* `matching` - push all branches having the same name on both ends.
+  This makes the repository you are pushing to remember the set of
+  branches that will be pushed out (e.g. if you always push 'maint'
+  and 'master' there and no other branches, the repository you push
+  to will have these two branches, and your local 'maint' and
+  'master' will be pushed there).
++
+To use this mode effectively, you have to make sure _all_ the
+branches you would push out are ready to be pushed out before
+running 'git push', as the whole point of this mode is to allow you
+to push all of the branches in one go.  If you usually finish work
+on only one branch and push out the result, while other branches are
+unfinished, this mode is not for you.  Also this mode is not
+suitable for pushing into a shared central repository, as other
+people may add new branches there, or update the tip of existing
+branches outside your control.
 +
-The `simple`, `current` and `upstream` modes are for those who want to
-push out a single branch after finishing work, even when the other
-branches are not yet ready to be pushed out. If you are working with
-other people to push into the same shared repository, you would want
-to use one of these.
+This is currently the default, but Git 2.0 will change the default
+to `simple`.
+
+--
 
 rebase.stat::
        Whether to show a diffstat of what changed upstream since the last
@@ -1867,6 +1905,14 @@ rebase.stat::
 rebase.autosquash::
        If set to true enable '--autosquash' option by default.
 
+rebase.autostash::
+       When set to true, automatically create a temporary stash
+       before the operation begins, and apply it after the operation
+       ends.  This means that you can run rebase on a dirty worktree.
+       However, use with care: the final stash application after a
+       successful rebase might result in non-trivial conflicts.
+       Defaults to false.
+
 receive.autogc::
        By default, git-receive-pack will run "git-gc --auto" after
        receiving data from git-push and updating refs.  You can stop
@@ -2066,6 +2112,14 @@ status.relativePaths::
        relative to the repository root (this was the default for Git
        prior to v1.5.4).
 
+status.short::
+       Set to true to enable --short by default in linkgit:git-status[1].
+       The option --no-short takes precedence over this variable.
+
+status.branch::
+       Set to true to enable --branch by default in linkgit:git-status[1].
+       The option --no-branch takes precedence over this variable.
+
 status.showUntrackedFiles::
        By default, linkgit:git-status[1] and linkgit:git-commit[1] show
        files which are not currently tracked by Git. Directories which
index 104579d..19f78a7 100644 (file)
@@ -383,14 +383,36 @@ ifndef::git-format-patch[]
        that matches other criteria, nothing is selected.
 
 -S<string>::
-       Look for differences that introduce or remove an instance of
-       <string>. Note that this is different than the string simply
-       appearing in diff output; see the 'pickaxe' entry in
-       linkgit:gitdiffcore[7] for more details.
+       Look for differences that change the number of occurrences of
+       the specified string (i.e. addition/deletion) in a file.
+       Intended for the scripter's use.
++
+It is useful when you're looking for an exact block of code (like a
+struct), and want to know the history of that block since it first
+came into being: use the feature iteratively to feed the interesting
+block in the preimage back into `-S`, and keep going until you get the
+very first version of the block.
 
 -G<regex>::
-       Look for differences whose added or removed line matches
-       the given <regex>.
+       Look for differences whose patch text contains added/removed
+       lines that match <regex>.
++
+To illustrate the difference between `-S<regex> --pickaxe-regex` and
+`-G<regex>`, consider a commit with the following diff in the same
+file:
++
+----
++    return !regexec(regexp, two->ptr, 1, &regmatch, 0);
+...
+-    hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0);
+----
++
+While `git log -G"regexec\(regexp"` will show this commit, `git log
+-S"regexec\(regexp" --pickaxe-regex` will not (because the number of
+occurrences of that string did not change).
++
+See the 'pickaxe' entry in linkgit:gitdiffcore[7] for more
+information.
 
 --pickaxe-all::
        When `-S` or `-G` finds a change, show all the changes in that
@@ -398,8 +420,8 @@ ifndef::git-format-patch[]
        in <string>.
 
 --pickaxe-regex::
-       Make the <string> not a plain string but an extended POSIX
-       regex to match.
+       Treat the <string> given to `-S` as an extended POSIX regular
+       expression to match.
 endif::git-format-patch[]
 
 -O<orderfile>::
@@ -439,6 +461,9 @@ endif::git-format-patch[]
        differences even if one line has whitespace where the other
        line has none.
 
+--ignore-blank-lines::
+       Ignore changes whose lines are all blank.
+
 --inter-hunk-context=<lines>::
        Show the context between diff hunks, up to the specified number
        of lines, thereby fusing hunks that are close to each other.
@@ -480,7 +505,7 @@ endif::git-format-patch[]
 
 --ignore-submodules[=<when>]::
        Ignore changes to submodules in the diff generation. <when> can be
-       either "none", "untracked", "dirty" or "all", which is the default
+       either "none", "untracked", "dirty" or "all", which is the default.
        Using "none" will consider the submodule modified when it either contains
        untracked or modified files or its HEAD differs from the commit recorded
        in the superproject and can be used to override any settings of the
index 9cb6496..ba1fe49 100644 (file)
@@ -61,7 +61,7 @@ endif::git-pull[]
 ifndef::git-pull[]
 -t::
 --tags::
-       This is a short-hand for giving "refs/tags/*:refs/tags/*"
+       This is a short-hand for giving `refs/tags/*:refs/tags/*`
        refspec from the command line, to ask all tags to be fetched
        and stored locally.  Because this acts as an explicit
        refspec, the default refspecs (configured with the
index 5bbe7b6..54d8461 100644 (file)
@@ -132,7 +132,7 @@ default.   You can use `--no-utf8` to override this.
 --resolvemsg=<msg>::
        When a patch failure occurs, <msg> will be printed
        to the screen before exiting.  This overrides the
-       standard message informing you to use `--resolved`
+       standard message informing you to use `--continue`
        or `--skip` to handle the failure.  This is solely
        for internal use between 'git rebase' and 'git am'.
 
@@ -176,7 +176,7 @@ aborts in the middle.  You can recover from this in one of two ways:
 
 . hand resolve the conflict in the working directory, and update
   the index file to bring it into a state that the patch should
-  have produced.  Then run the command with the '--resolved' option.
+  have produced.  Then run the command with the '--continue' option.
 
 The command refuses to process new mailboxes until the current
 operation is finished, so if you decide to start over from scratch,
index 9a05c2b..6cea7f1 100644 (file)
@@ -8,9 +8,9 @@ git-blame - Show what revision and author last modified each line of a file
 SYNOPSIS
 --------
 [verse]
-'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental] [-L n,m]
-           [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>] [--abbrev=<n>]
-           [<rev> | --contents <file> | --reverse <rev>] [--] <file>
+'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental]
+           [-L n,m | -L :fn] [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>]
+           [--abbrev=<n>] [<rev> | --contents <file> | --reverse <rev>] [--] <file>
 
 DESCRIPTION
 -----------
index 5abdbaa..a7be80d 100644 (file)
@@ -56,6 +56,11 @@ being queried and <info> can be either:
 'set';;                when the attribute is defined as true.
 <value>;;      when a value has been assigned to the attribute.
 
+Buffering happens as documented under the `GIT_FLUSH` option in
+linkgit:git[1].  The caller is responsible for avoiding deadlocks
+caused by overfilling an input buffer or reading from an empty output
+buffer.
+
 EXAMPLES
 --------
 
index 854e4d0..d2df487 100644 (file)
@@ -39,6 +39,12 @@ OPTIONS
        below).  If `--stdin` is also given, input paths are separated
        with a NUL character instead of a linefeed character.
 
+-n, --non-matching::
+       Show given paths which don't match any pattern.  This only
+       makes sense when `--verbose` is enabled, otherwise it would
+       not be possible to distinguish between paths which match a
+       pattern and those which don't.
+
 OUTPUT
 ------
 
@@ -65,6 +71,20 @@ are also used instead of colons and hard tabs:
 
 <source> <NULL> <linenum> <NULL> <pattern> <NULL> <pathname> <NULL>
 
+If `-n` or `--non-matching` are specified, non-matching pathnames will
+also be output, in which case all fields in each output record except
+for <pathname> will be empty.  This can be useful when running
+non-interactively, so that files can be incrementally streamed to
+STDIN of a long-running check-ignore process, and for each of these
+files, STDOUT will indicate whether that file matched a pattern or
+not.  (Without this option, it would be impossible to tell whether the
+absence of output for a given file meant that it didn't match any
+pattern, or that the output hadn't been generated yet.)
+
+Buffering happens as documented under the `GIT_FLUSH` option in
+linkgit:git[1].  The caller is responsible for avoiding deadlocks
+caused by overfilling an input buffer or reading from an empty output
+buffer.
 
 EXIT STATUS
 -----------
@@ -82,7 +102,7 @@ SEE ALSO
 --------
 linkgit:gitignore[5]
 linkgit:gitconfig[5]
-linkgit:git-ls-files[5]
+linkgit:git-ls-files[1]
 
 GIT
 ---
index a49be1b..fc02959 100644 (file)
@@ -54,6 +54,8 @@ Git imposes the following rules on how references are named:
 
 . They cannot contain a sequence `@{`.
 
+. They cannot be the single character `@`.
+
 . They cannot contain a `\`.
 
 These rules make it easy for shell script based tools to parse
index 23a9413..ca118ac 100644 (file)
@@ -131,9 +131,9 @@ entries; instead, unmerged entries are ignored.
        "--track" in linkgit:git-branch[1] for details.
 +
 If no '-b' option is given, the name of the new branch will be
-derived from the remote-tracking branch.  If "remotes/" or "refs/remotes/"
-is prefixed it is stripped away, and then the part up to the
-next slash (which would be the nickname of the remote) is removed.
+derived from the remote-tracking branch, by looking at the local part of
+the refspec configured for the corresponding remote, and then stripping
+the initial part up to the "*".
 This would tell us to use "hack" as the local branch when branching
 off of "origin/hack" (or "remotes/origin/hack", or even
 "refs/remotes/origin/hack").  If the given name has no slash, or the above
index a0727d7..450f158 100644 (file)
@@ -239,8 +239,8 @@ Examples
 * Clone from upstream:
 +
 ------------
-$ git clone git://git.kernel.org/pub/scm/.../linux-2.6 my2.6
-$ cd my2.6
+$ git clone git://git.kernel.org/pub/scm/.../linux.git my-linux
+$ cd my-linux
 $ make
 ------------
 
@@ -257,10 +257,10 @@ $ git show-branch
 * Clone from upstream while borrowing from an existing local directory:
 +
 ------------
-$ git clone --reference my2.6 \
-       git://git.kernel.org/pub/scm/.../linux-2.7 \
-       my2.7
-$ cd my2.7
+$ git clone --reference /git/linux.git \
+       git://git.kernel.org/pub/scm/.../linux.git \
+       my-linux
+$ cd my-linux
 ------------
 
 
@@ -271,13 +271,6 @@ $ git clone --bare -l /home/proj/.git /pub/scm/proj.git
 ------------
 
 
-* Create a repository on the kernel.org machine that borrows from Linus:
-+
-------------
-$ git clone --bare -l -s /pub/scm/.../torvalds/linux-2.6.git \
-    /pub/scm/.../me/subsys-2.6.git
-------------
-
 GIT
 ---
 Part of the linkgit:git[1] suite
index d88a6fc..fbad05e 100644 (file)
@@ -82,7 +82,7 @@ OPTIONS
 --get::
        Get the value for a given key (optionally filtered by a regex
        matching the value). Returns error code 1 if the key was not
-       found and error code 2 if multiple key values were found.
+       found and the last value if multiple key values were found.
 
 --get-all::
        Like get, but does not fail if the number of values for the key
@@ -114,6 +114,15 @@ rather than from all available files.
 +
 See also <<FILES>>.
 
+--local::
+       For writing options: write to the repository .git/config file.
+       This is the default behavior.
++
+For reading options: read only from the repository .git/config rather than
+from all available files.
++
+See also <<FILES>>.
+
 -f config-file::
 --file config-file::
        Use the given config file instead of the one specified by GIT_CONFIG.
index 28e5ec0..9439cd6 100644 (file)
@@ -88,6 +88,11 @@ OPTIONS
 --always::
        Show uniquely abbreviated commit object as fallback.
 
+--first-parent::
+       Follow only the first parent commit upon seeing a merge commit.
+       This is useful when you wish to not match tags on branches merged
+       in the history of the target commit.
+
 EXAMPLES
 --------
 
@@ -149,7 +154,9 @@ is found, its name will be output and searching will stop.
 If an exact match was not found, 'git describe' will walk back
 through the commit history to locate an ancestor commit which
 has been tagged.  The ancestor's tag will be output along with an
-abbreviation of the input committish's SHA-1.
+abbreviation of the input committish's SHA-1. If '--first-parent' was
+specified then the walk will only consider the first parent of each
+commit.
 
 If multiple tags were found during the walk then the tag which
 has the fewest commits different from the input committish will be
index c0b7c58..a86cf62 100644 (file)
@@ -3,7 +3,7 @@ git-diff-index(1)
 
 NAME
 ----
-git-diff-index - Compares content and mode of blobs between the index and repository
+git-diff-index - Compare a tree to the working tree or index
 
 
 SYNOPSIS
@@ -13,11 +13,11 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-Compares the content and mode of the blobs found via a tree
-object with the content of the current index and, optionally
-ignoring the stat state of the file on disk.  When paths are
-specified, compares only those named paths.  Otherwise all
-entries in the index are compared.
+Compares the content and mode of the blobs found in a tree object
+with the corresponding tracked files in the working tree, or with the
+corresponding paths in the index.  When <path> arguments are present,
+compares only paths matching those patterns.  Otherwise all tracked
+files are compared.
 
 OPTIONS
 -------
index a7b4620..78d6d50 100644 (file)
@@ -18,8 +18,8 @@ SYNOPSIS
 DESCRIPTION
 -----------
 Show changes between the working tree and the index or a tree, changes
-between the index and a tree, changes between two trees, or changes
-between two files on disk.
+between the index and a tree, changes between two trees, changes between
+two blob objects, or changes between two files on disk.
 
 'git diff' [--options] [--] [<path>...]::
 
@@ -56,11 +56,6 @@ directories. This behavior can be forced by --no-index.
        This is to view the changes between two arbitrary
        <commit>.
 
-'git diff' [options] <blob> <blob>::
-
-       This form is to view the differences between the raw
-       contents of two blob objects.
-
 'git diff' [--options] <commit>..<commit> [--] [<path>...]::
 
        This is synonymous to the previous form.  If <commit> on
@@ -87,6 +82,11 @@ and the range notations ("<commit>..<commit>" and
 "<commit>\...<commit>") do not mean a range as defined in the
 "SPECIFYING RANGES" section in linkgit:gitrevisions[7].
 
+'git diff' [options] <blob> <blob>::
+
+       This form is to view the differences between the raw
+       contents of two blob objects.
+
 OPTIONS
 -------
 :git-diff: 1
index efb0380..85f1f30 100644 (file)
@@ -141,7 +141,7 @@ Limitations
 -----------
 
 Since 'git fast-import' cannot tag trees, you will not be
-able to export the linux-2.6.git repository completely, as it contains
+able to export the linux.git repository completely, as it contains
 a tag referencing a tree instead of a commit.
 
 GIT
index b370b02..2402ed6 100644 (file)
@@ -62,8 +62,9 @@ automatic consolidation of packs.
 
 --prune=<date>::
        Prune loose objects older than date (default is 2 weeks ago,
-       overridable by the config variable `gc.pruneExpire`).  This
-       option is on by default.
+       overridable by the config variable `gc.pruneExpire`).
+       --prune=all prunes loose objects regardless of their age.
+       --prune is on by default.
 
 --no-prune::
        Do not prune any loose objects.
index bde8eec..7a4e055 100644 (file)
@@ -74,6 +74,9 @@ OPTIONS
 --strict::
        Die, if the pack contains broken objects or links.
 
+--check-self-contained-and-connected::
+       Die if the pack contains broken links. For internal use only.
+
 --threads=<n>::
        Specifies the number of threads to spawn when resolving
        deltas. This requires that index-pack be compiled with
index a976534..2ea79ba 100644 (file)
@@ -62,6 +62,19 @@ produced by --stat etc.
        Note that only message is considered, if also a diff is shown
        its size is not included.
 
+-L <start>,<end>:<file>, -L :<regex>:<file>::
+
+       Trace the evolution of the line range given by "<start>,<end>"
+       (or the funcname regex <regex>) within the <file>.  You may
+       not give any pathspec limiters.  This is currently limited to
+       a walk starting from a single revision, i.e., you may only
+       give zero or one positive revision arguments.
+       You can specify this option more than once.
++
+<start> and <end> can take one of these forms:
+
+include::line-range-format.txt[]
+
 <revision range>::
        Show only commits in the specified revision range.  When no
        <revision range> is specified, it defaults to `HEAD` (i.e. the
@@ -115,9 +128,9 @@ Examples
        in the "release" branch, along with the list of paths
        each commit modifies.
 
-`git log --follow builtin-rev-list.c`::
+`git log --follow builtin/rev-list.c`::
 
-       Shows the commits that changed builtin-rev-list.c, including
+       Shows the commits that changed builtin/rev-list.c, including
        those commits that occurred before the file was given its
        present name.
 
@@ -140,6 +153,11 @@ Examples
        This makes sense only when following a strict policy of merging all
        topic branches when staying on a single integration branch.
 
+git log -L '/int main/',/^}/:main.c::
+
+       Shows how the function `main()` in the file 'main.c' evolved
+       over time.
+
 `git log -3`::
        Limits the number of commits to show to 3.
 
index 774de5e..2e22915 100644 (file)
@@ -48,9 +48,9 @@ OPTIONS
        exit without talking to the remote.
 
 <repository>::
-       Location of the repository.  The shorthand defined in
-       $GIT_DIR/branches/ can be used. Use "." (dot) to list references in
-       the local repository.
+       The "remote" repository to query.  This parameter can be
+       either a URL or the name of a remote (see the GIT URLS and
+       REMOTES sections of linkgit:git-fetch[1]).
 
 <refs>...::
        When unspecified, all references, after filtering done
@@ -70,9 +70,8 @@ EXAMPLES
        $ git ls-remote http://www.kernel.org/pub/scm/git/git.git master pu rc
        5fe978a5381f1fbad26a80e682ddd2a401966740        refs/heads/master
        c781a84b5204fb294c9ccc79f8b3baceeb32c061        refs/heads/pu
-       b1d096f2926c4e37c9c0b6a7bf2119bedaa277cb        refs/heads/rc
-       $ echo http://www.kernel.org/pub/scm/git/git.git >.git/branches/public
-       $ git ls-remote --tags public v\*
+       $ git remote add korg http://www.kernel.org/pub/scm/git/git.git
+       $ git ls-remote --tags korg v\*
        d6602ec5194c87b0fc87103ca4d67251c76f233a        refs/tags/v0.99
        f25a265a342aed6041ab0cc484224d9ca54b6f41        refs/tags/v0.99.1
        c5db5456ae3b0873fc659c19fafdde22313cc441        refs/tags/v0.99.2
index 67ca99c..8c7f2f6 100644 (file)
@@ -56,8 +56,8 @@ especially if those changes were further modified after the merge
 was started), 'git merge --abort' will in some cases be unable to
 reconstruct the original (pre-merge) changes. Therefore:
 
-*Warning*: Running 'git merge' with uncommitted changes is
-discouraged: while possible, it leaves you in a state that is hard to
+*Warning*: Running 'git merge' with non-trivial uncommitted changes is
+discouraged: while possible, it may leave you in a state that is hard to
 back out of in the case of a conflict.
 
 
index ad1d146..6b0f1ba 100644 (file)
@@ -25,7 +25,8 @@ OPTIONS
        Do not use branch names, but only tags to name the commits
 
 --refs=<pattern>::
-       Only use refs whose names match a given shell pattern.
+       Only use refs whose names match a given shell pattern.  The pattern
+       can be one of branch name, tag name or fully qualified ref name.
 
 --all::
        List all commits reachable from all refs
index d514813..f7dfe48 100644 (file)
@@ -11,7 +11,7 @@ SYNOPSIS
 [verse]
 'git push' [--all | --mirror | --tags] [--follow-tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
           [--repo=<repository>] [-f | --force] [--prune] [-v | --verbose] [-u | --set-upstream]
-          [<repository> [<refspec>...]]
+          [--no-verify] [<repository> [<refspec>...]]
 
 DESCRIPTION
 -----------
@@ -136,6 +136,15 @@ already exists on the remote side.
        not an ancestor of the local ref used to overwrite it.
        This flag disables the check.  This can cause the
        remote repository to lose commits; use it with care.
+       Note that `--force` applies to all the refs that are pushed,
+       hence using it with `push.default` set to `matching` or with
+       multiple push destinations configured with `remote.*.push`
+       may overwrite refs other than the current branch (including
+       local refs that are strictly behind their remote counterpart).
+       To force a push to only one branch, use a `+` in front of the
+       refspec to push (e.g `git push origin +master` to force a push
+       to the `master` branch). See the `<refspec>...` section above
+       for details.
 
 --repo=<repository>::
        This option is only relevant if no <repository> argument is
@@ -195,6 +204,11 @@ useful if you write an alias or script around 'git push'.
        be pushed. If on-demand was not able to push all necessary
        revisions it will also be aborted and exit with non-zero status.
 
+--[no-]verify::
+       Toggle the pre-push hook (see linkgit:githooks[5]).  The
+       default is \--verify, giving the hook a chance to prevent the
+       push.  With \--no-verify, the hook is bypassed completely.
+
 
 include::urls-remotes.txt[]
 
index aca8405..6b2e1c8 100644 (file)
@@ -208,6 +208,9 @@ rebase.stat::
 rebase.autosquash::
        If set to true enable '--autosquash' option by default.
 
+rebase.autostash::
+       If set to true enable '--autostash' option by default.
+
 OPTIONS
 -------
 --onto <newbase>::
@@ -386,7 +389,9 @@ squash/fixup series.
        the same ..., automatically modify the todo list of rebase -i
        so that the commit marked for squashing comes right after the
        commit to be modified, and change the action of the moved
-       commit from `pick` to `squash` (or `fixup`).
+       commit from `pick` to `squash` (or `fixup`).  Ignores subsequent
+       "fixup! " or "squash! " after the first, in case you referred to an
+       earlier fixup/squash with `git commit --fixup/--squash`.
 +
 This option is only valid when the '--interactive' option is used.
 +
@@ -394,6 +399,13 @@ If the '--autosquash' option is enabled by default using the
 configuration variable `rebase.autosquash`, this option can be
 used to override and disable this setting.
 
+--[no-]autostash::
+       Automatically create a temporary stash before the operation
+       begins, and apply it after the operation ends.  This means
+       that you can run rebase on a dirty worktree.  However, use
+       with care: the final stash application after a successful
+       rebase might result in non-trivial conflicts.
+
 --no-ff::
        With --interactive, cherry-pick all rebased commits instead of
        fast-forwarding over the unchanged ones.  This ensures that the
index fb8697e..70791b9 100644 (file)
@@ -67,14 +67,19 @@ them.
 --expire=<time>::
        Entries older than this time are pruned.  Without the
        option it is taken from configuration `gc.reflogExpire`,
-       which in turn defaults to 90 days.
+       which in turn defaults to 90 days.  --expire=all prunes
+       entries regardless of their age; --expire=never turns off
+       pruning of reachable entries (but see --expire-unreachable).
 
 --expire-unreachable=<time>::
        Entries older than this time and not reachable from
        the current tip of the branch are pruned.  Without the
        option it is taken from configuration
        `gc.reflogExpireUnreachable`, which in turn defaults to
-       30 days.
+       30 days.  --expire-unreachable=all prunes unreachable
+       entries regardless of their age; --expire-unreachable=never
+       turns off early pruning of unreachable entries (but see
+       --expire).
 
 --all::
        Instead of listing <refs> explicitly, prune all refs.
index 581bb4c..9c3e3bf 100644 (file)
@@ -187,18 +187,25 @@ Examples
 $ git remote
 origin
 $ git branch -r
-origin/master
-$ git remote add linux-nfs git://linux-nfs.org/pub/linux/nfs-2.6.git
+  origin/HEAD -> origin/master
+  origin/master
+$ git remote add staging git://git.kernel.org/.../gregkh/staging.git
 $ git remote
-linux-nfs
 origin
-$ git fetch
-* refs/remotes/linux-nfs/master: storing branch 'master' ...
-  commit: bf81b46
+staging
+$ git fetch staging
+...
+From git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
+ * [new branch]      master     -> staging/master
+ * [new branch]      staging-linus -> staging/staging-linus
+ * [new branch]      staging-next -> staging/staging-next
 $ git branch -r
-origin/master
-linux-nfs/master
-$ git checkout -b nfs linux-nfs/master
+  origin/HEAD -> origin/master
+  origin/master
+  staging/master
+  staging/staging-linus
+  staging/staging-next
+$ git checkout -b staging staging/master
 ...
 ------------
 
index 947d62f..993903c 100644 (file)
@@ -59,6 +59,22 @@ OPTIONS
        If there is no parameter given by the user, use `<arg>`
        instead.
 
+--prefix <arg>::
+       Behave as if 'git rev-parse' was invoked from the `<arg>`
+       subdirectory of the working tree.  Any relative filenames are
+       resolved as if they are prefixed by `<arg>` and will be printed
+       in that form.
++
+This can be used to convert arguments to a command run in a subdirectory
+so that they can still be used after moving to the top-level of the
+repository.  For example:
++
+----
+prefix=$(git rev-parse --show-prefix)
+cd "$(git rev-parse --show-toplevel)"
+eval "set -- $(git rev-parse --sq --prefix "$prefix" "$@")"
+----
+
 --verify::
        Verify that exactly one parameter is provided, and that it
        can be turned into a raw 20-byte SHA-1 that can be used to
index 711ffe1..7c8b648 100644 (file)
@@ -13,10 +13,12 @@ SYNOPSIS
 'git stash' drop [-q|--quiet] [<stash>]
 'git stash' ( pop | apply ) [--index] [-q|--quiet] [<stash>]
 'git stash' branch <branchname> [<stash>]
-'git stash' [save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
-            [-u|--include-untracked] [-a|--all] [<message>]]
+'git stash' [save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
+            [-u|--include-untracked] [-a|--all] [-f|--force]
+            [<message>]]
 'git stash' clear
-'git stash' create
+'git stash' create [<message>]
+'git stash' store [-m|--message <message>] [-q|--quiet] <commit>
 
 DESCRIPTION
 -----------
@@ -43,7 +45,7 @@ is also possible).
 OPTIONS
 -------
 
-save [-p|--patch] [--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>]::
+save [-p|--patch] [--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [-f|--force] [<message>]::
 
        Save your local modifications to a new 'stash', and run `git reset
        --hard` to revert them.  The <message> part is optional and gives
@@ -70,6 +72,13 @@ linkgit:git-add[1] to learn how to operate the `--patch` mode.
 +
 The `--patch` option implies `--keep-index`.  You can use
 `--no-keep-index` to override this.
++
+In some cases, saving a stash could mean irretrievably removing some
+data - if a directory with untracked files replaces a tracked file of
+the same name, the new untracked files are not saved (except in case
+of `--include-untracked`) but the original tracked file shall be restored.
+By default, `stash save` will abort in such a case; `--force` will allow
+it to remove the untracked files.
 
 list [<options>]::
 
@@ -151,7 +160,15 @@ create::
 
        Create a stash (which is a regular commit object) and return its
        object name, without storing it anywhere in the ref namespace.
+       This is intended to be useful for scripts.  It is probably not
+       the command you want to use; see "save" above.
+
+store::
 
+       Store a given stash created via 'git stash create' (which is a
+       dangling merge commit) in the stash ref, updating the stash
+       reflog.  This is intended to be useful for scripts.  It is
+       probably not the command you want to use; see "save" above.
 
 DISCUSSION
 ----------
index ba79cb4..5aec4ec 100644 (file)
@@ -34,6 +34,7 @@ The following browsers (or commands) are currently supported:
 * dillo
 * open (this is the default under Mac OS X GUI)
 * start (this is the default under MinGW)
+* cygstart (this is the default under Cygwin)
 
 Custom commands may also be specified.
 
index 9e302b0..b738a40 100644 (file)
@@ -43,12 +43,19 @@ unreleased) version of Git, that is available from 'master'
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
+* link:v1.8.3.2/git.html[documentation for release 1.8.3.2]
+
+* release notes for
+  link:RelNotes/1.8.3.2.txt[1.8.3.2],
+  link:RelNotes/1.8.3.1.txt[1.8.3.1],
+  link:RelNotes/1.8.3.txt[1.8.3].
+
 * link:v1.8.2.3/git.html[documentation for release 1.8.2.3]
 
 * release notes for
-  link:RelNotes/1.8.2.3.txt[1.8.2.3].
-  link:RelNotes/1.8.2.2.txt[1.8.2.2].
-  link:RelNotes/1.8.2.1.txt[1.8.2.1].
+  link:RelNotes/1.8.2.3.txt[1.8.2.3],
+  link:RelNotes/1.8.2.2.txt[1.8.2.2],
+  link:RelNotes/1.8.2.1.txt[1.8.2.1],
   link:RelNotes/1.8.2.txt[1.8.2].
 
 * link:v1.8.1.6/git.html[documentation for release 1.8.1.6]
@@ -677,9 +684,7 @@ Git so take care if using Cogito etc.
        The '--git-dir' command-line option also sets this value.
 
 'GIT_WORK_TREE'::
-       Set the path to the working tree.  The value will not be
-       used in combination with repositories found automatically in
-       a .git directory (i.e. $GIT_DIR is not set).
+       Set the path to the root of the working tree.
        This can also be controlled by the '--work-tree' command line
        option and the core.worktree configuration variable.
 
@@ -811,8 +816,9 @@ for further details.
 'GIT_FLUSH'::
        If this environment variable is set to "1", then commands such
        as 'git blame' (in incremental mode), 'git rev-list', 'git log',
-       and 'git whatchanged' will force a flush of the output stream
-       after each commit-oriented record have been flushed.   If this
+       'git check-attr', 'git check-ignore', and 'git whatchanged' will
+       force a flush of the output stream after each record have been
+       flushed. If this
        variable is set to "0", the output of these commands will be done
        using completely buffered I/O.   If this environment variable is
        not set, Git will choose buffered or record-oriented flushing
@@ -832,6 +838,19 @@ for further details.
        as a file path and will try to write the trace messages
        into it.
 
+'GIT_TRACE_PACK_ACCESS'::
+       If this variable is set to a path, a file will be created at
+       the given path logging all accesses to any packs. For each
+       access, the pack file name and an offset in the pack is
+       recorded. This may be helpful for troubleshooting some
+       pack-related performance problems.
+
+'GIT_TRACE_PACKET'::
+       If this variable is set, it shows a trace of all packets
+       coming in or out of a given program. This can help with
+       debugging object negotiation or other protocol issues. Tracing
+       is turned off at a packet starting with "PACK".
+
 GIT_LITERAL_PATHSPECS::
        Setting this variable to `1` will cause Git to treat all
        pathspecs literally, rather than as glob patterns. For example,
index 568d757..c8b3e51 100644 (file)
@@ -222,26 +222,35 @@ version prefixed with '+'.
 diffcore-pickaxe: For Detecting Addition/Deletion of Specified String
 ---------------------------------------------------------------------
 
-This transformation is used to find filepairs that represent
-changes that touch a specified string, and is controlled by the
--S option and the `--pickaxe-all` option to the 'git diff-*'
-commands.
-
-When diffcore-pickaxe is in use, it checks if there are
-filepairs whose "result" side and whose "origin" side have
-different number of specified string.  Such a filepair represents
-"the string appeared in this changeset".  It also checks for the
-opposite case that loses the specified string.
-
-When `--pickaxe-all` is not in effect, diffcore-pickaxe leaves
-only such filepairs that touch the specified string in its
-output.  When `--pickaxe-all` is used, diffcore-pickaxe leaves all
-filepairs intact if there is such a filepair, or makes the
-output empty otherwise.  The latter behaviour is designed to
-make reviewing of the changes in the context of the whole
+This transformation limits the set of filepairs to those that change
+specified strings between the preimage and the postimage in a certain
+way.  -S<block of text> and -G<regular expression> options are used to
+specify different ways these strings are sought.
+
+"-S<block of text>" detects filepairs whose preimage and postimage
+have different number of occurrences of the specified block of text.
+By definition, it will not detect in-file moves.  Also, when a
+changeset moves a file wholesale without affecting the interesting
+string, diffcore-rename kicks in as usual, and `-S` omits the filepair
+(since the number of occurrences of that string didn't change in that
+rename-detected filepair).  When used with `--pickaxe-regex`, treat
+the <block of text> as an extended POSIX regular expression to match,
+instead of a literal string.
+
+"-G<regular expression>" (mnemonic: grep) detects filepairs whose
+textual diff has an added or a deleted line that matches the given
+regular expression.  This means that it will detect in-file (or what
+rename-detection considers the same file) moves, which is noise.  The
+implementation runs diff twice and greps, and this can be quite
+expensive.
+
+When `-S` or `-G` are used without `--pickaxe-all`, only filepairs
+that match their respective criterion are kept in the output.  When
+`--pickaxe-all` is used, if even one filepair matches their respective
+criterion in a changeset, the entire changeset is kept.  This behavior
+is designed to make reviewing changes in the context of the whole
 changeset easier.
 
-
 diffcore-order: For Sorting the Output Based on Filenames
 ---------------------------------------------------------
 
index da74641..0827f69 100644 (file)
@@ -159,11 +159,11 @@ Miscellaneous capabilities
        carried out.
 
 'refspec' <refspec>::
-       This modifies the 'import' capability, allowing the produced
-       fast-import stream to modify refs in a private namespace
-       instead of writing to refs/heads or refs/remotes directly.
+       For remote helpers that implement 'import' or 'export', this capability
+       allows the refs to be constrained to a private namespace, instead of
+       writing to refs/heads or refs/remotes directly.
        It is recommended that all importers providing the 'import'
-       capability use this.
+       capability use this. It's mandatory for 'export'.
 +
 A helper advertising the capability
 `refspec refs/heads/*:refs/svn/origin/branches/*`
@@ -174,8 +174,8 @@ ref.
 This capability can be advertised multiple times.  The first
 applicable refspec takes precedence.  The left-hand of refspecs
 advertised with this capability must cover all refs reported by
-the list command.  If a helper does not need a specific 'refspec'
-capability then it should advertise `refspec *:*`.
+the list command.  If no 'refspec' capability is advertised,
+there is an implied `refspec *:*`.
 
 'bidi-import'::
        This modifies the 'import' capability.
index d6f3393..aa03882 100644 (file)
@@ -211,6 +211,9 @@ shallow::
        and maintained by shallow clone mechanism.  See `--depth`
        option to linkgit:git-clone[1] and linkgit:git-fetch[1].
 
+modules::
+       Contains the git-repositories of the submodules.
+
 SEE ALSO
 --------
 linkgit:git-init[1],
index 68a18e1..db2a74d 100644 (file)
@@ -400,12 +400,13 @@ should not be combined with other pathspec.
        <<def_ref,ref>> and local ref.
 
 [[def_remote_tracking_branch]]remote-tracking branch::
-       A regular Git <<def_branch,branch>> that is used to follow changes from
-       another <<def_repository,repository>>. A remote-tracking
-       branch should not contain direct modifications or have local commits
-       made to it. A remote-tracking branch can usually be
-       identified as the right-hand-side <<def_ref,ref>> in a Pull:
-       <<def_refspec,refspec>>.
+       A <<def_ref,ref>> that is used to follow changes from another
+       <<def_repository,repository>>. It typically looks like
+       'refs/remotes/foo/bar' (indicating that it tracks a branch named
+       'bar' in a remote named 'foo'), and matches the right-hand-side of
+       a configured fetch <<def_refspec,refspec>>. A remote-tracking
+       branch should not contain direct modifications or have local
+       commits made to it.
 
 [[def_repository]]repository::
        A collection of <<def_ref,refs>> together with an
diff --git a/Documentation/line-range-format.txt b/Documentation/line-range-format.txt
new file mode 100644 (file)
index 0000000..3e7ce72
--- /dev/null
@@ -0,0 +1,25 @@
+- number
++
+If <start> or <end> is a number, it specifies an
+absolute line number (lines count from 1).
++
+
+- /regex/
++
+This form will use the first line matching the given
+POSIX regex.  If <end> is a regex, it will search
+starting at the line given by <start>.
++
+
+- +offset or -offset
++
+This is only valid for <end> and will specify a number
+of lines before or after the line given by <start>.
++
+
+- :regex
++
+If the option's argument is of the form :regex, it denotes the range
+from the first funcname line that matches <regex>, up to the next
+funcname line.
++
index 2adccf8..afba8d4 100644 (file)
@@ -8,12 +8,13 @@ failed and do not autocommit, to give the user a chance to
 inspect and further tweak the merge result before committing.
 
 --edit::
+-e::
 --no-edit::
        Invoke an editor before committing successful mechanical merge to
        further edit the auto-generated merge message, so that the user
        can explain and justify the merge. The `--no-edit` option can be
        used to accept the auto-generated message (this is generally
-       discouraged). The `--edit` option is still useful if you are
+       discouraged). The `--edit` (or `-e`) option is still useful if you are
        giving a draft message with the `-m` option from the command line
        and want to edit it in the editor.
 +
index 94a9d32..18cffc2 100644 (file)
@@ -68,6 +68,11 @@ Some short-cut notations are also supported.
 +
 * `tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`;
   it requests fetching everything up to the given tag.
-* A parameter <ref> without a colon is equivalent to
-  <ref>: when pulling/fetching, so it merges <ref> into the current
-  branch without storing the remote branch anywhere locally
+ifndef::git-pull[]
+* A parameter <ref> without a colon fetches that ref into FETCH_HEAD,
+endif::git-pull[]
+ifdef::git-pull[]
+* A parameter <ref> without a colon merges <ref> into the current
+  branch,
+endif::git-pull[]
+  and updates the remote-tracking branches (if any).
index 3bdbf5e..e157ec3 100644 (file)
@@ -271,8 +271,8 @@ See also linkgit:git-reflog[1].
 
 --boundary::
 
-       Output uninteresting commits at the boundary, which are usually
-       not shown.
+       Output excluded boundary commits. Boundary commits are
+       prefixed with `-`.
 
 --
 
@@ -342,13 +342,13 @@ In the following, we will always refer to the same example history to
 illustrate the differences between simplification settings.  We assume
 that you are filtering for a file `foo` in this commit graph:
 -----------------------------------------------------------------------
-         .-A---M---N---O---P
-        /     /   /   /   /
-       I     B   C   D   E
-        \   /   /   /   /
-         `-------------'
+         .-A---M---N---O---P---Q
+        /     /   /   /   /   /
+       I     B   C   D   E   Y
+        \   /   /   /   /   /
+         `-------------'   X
 -----------------------------------------------------------------------
-The horizontal line of history A---P is taken to be the first parent of
+The horizontal line of history A---Q is taken to be the first parent of
 each merge.  The commits are:
 
 * `I` is the initial commit, in which `foo` exists with contents
@@ -367,8 +367,11 @@ each merge.  The commits are:
   `N` and `D` to "foobarbaz"; i.e., it is not TREESAME to any parent.
 
 * `E` changes `quux` to "xyzzy", and its merge `P` combines the
-  strings to "quux xyzzy".  Despite appearing interesting, `P` is
-  TREESAME to all parents.
+  strings to "quux xyzzy".  `P` is TREESAME to `O`, but not to `E`.
+
+* `X` is an indpendent root commit that added a new file `side`, and `Y`
+  modified it. `Y` is TREESAME to `X`. Its merge `Q` added `side` to `P`, and
+  `Q` is TREESAME to `P`, but not to `Y`.
 
 'rev-list' walks backwards through history, including or excluding
 commits based on whether '\--full-history' and/or parent rewriting
@@ -410,10 +413,10 @@ parent lines.
        the example, we get
 +
 -----------------------------------------------------------------------
-       I  A  B  N  D  O
+       I  A  B  N  D  O  P  Q
 -----------------------------------------------------------------------
 +
-`P` and `M` were excluded because they are TREESAME to a parent.  `E`,
+`M` was excluded because it is TREESAME to both parents.  `E`,
 `C` and `B` were all walked, but only `B` was !TREESAME, so the others
 do not appear.
 +
@@ -431,7 +434,7 @@ Along each parent, prune away commits that are not included
 themselves.  This results in
 +
 -----------------------------------------------------------------------
-         .-A---M---N---O---P
+         .-A---M---N---O---P---Q
         /     /   /   /   /
        I     B   /   D   /
         \   /   /   /   /
@@ -441,7 +444,7 @@ themselves.  This results in
 Compare to '\--full-history' without rewriting above.  Note that `E`
 was pruned away because it is TREESAME, but the parent list of P was
 rewritten to contain `E`'s parent `I`.  The same happened for `C` and
-`N`.  Note also that `P` was included despite being TREESAME.
+`N`, and `X`, `Y` and `Q`.
 
 In addition to the above settings, you can change whether TREESAME
 affects inclusion:
@@ -471,8 +474,9 @@ history according to the following rules:
 * Set `C'` to `C`.
 +
 * Replace each parent `P` of `C'` with its simplification `P'`.  In
-  the process, drop parents that are ancestors of other parents, and
-  remove duplicates.
+  the process, drop parents that are ancestors of other parents or that are
+  root commits TREESAME to an empty tree, and remove duplicates, but take care
+  to never drop all parents that we are TREESAME to.
 +
 * If after this parent rewriting, `C'` is a root or merge commit (has
   zero or >1 parents), a boundary commit, or !TREESAME, it remains.
@@ -490,7 +494,7 @@ The effect of this is best shown by way of comparing to
          `---------'
 -----------------------------------------------------------------------
 +
-Note the major differences in `N` and `P` over '--full-history':
+Note the major differences in `N`, `P` and `Q` over '--full-history':
 +
 --
 * `N`'s parent list had `I` removed, because it is an ancestor of the
@@ -498,6 +502,10 @@ Note the major differences in `N` and `P` over '--full-history':
 +
 * `P`'s parent list similarly had `I` removed.  `P` was then
   removed completely, because it had one parent and is TREESAME.
++
+* `Q`'s parent list had `Y` simplified to `X`. `X` was then removed, because it
+  was a TREESAME root. `Q` was then removed completely, because it had one
+  parent and is TREESAME.
 --
 
 Finally, there is a fifth simplification mode available:
@@ -617,6 +625,10 @@ By default, the commits are shown in reverse chronological order.
        Show no parents before all of its children are shown, but
        otherwise show commits in the commit timestamp order.
 
+--author-date-order::
+       Show no parents before all of its children are shown, but
+       otherwise show commits in the author timestamp order.
+
 --topo-order::
        Show no parents before all of its children are shown, and
        avoid showing commits on multiple lines of history
index d477b3f..09896a3 100644 (file)
@@ -58,6 +58,9 @@ the '$GIT_DIR/refs' directory or from the '$GIT_DIR/packed-refs' file.
 While the ref name encoding is unspecified, UTF-8 is preferred as
 some output processing may assume ref names in UTF-8.
 
+'@'::
+  '@' alone is a shortcut for 'HEAD'.
+
 '<refname>@\{<date>\}', e.g. 'master@\{yesterday\}', 'HEAD@\{5 minutes ago\}'::
   A ref followed by the suffix '@' with a date specification
   enclosed in a brace
index 4a4228b..f3c1357 100644 (file)
@@ -39,7 +39,7 @@ where options is the bitwise-or of:
        on bare repositories.
        This only makes sense when `RUN_SETUP` is also set.
 
-. Add `builtin-foo.o` to `BUILTIN_OBJS` in `Makefile`.
+. Add `builtin/foo.o` to `BUILTIN_OBJS` in `Makefile`.
 
 Additionally, if `foo` is a new command, there are 3 more things to do:
 
index 32ddc1c..0be2b51 100644 (file)
@@ -41,6 +41,8 @@ The parse-options API allows:
 * Boolean long options can be 'negated' (or 'unset') by prepending
   `no-`, e.g. `--no-abbrev` instead of `--abbrev`. Conversely,
   options that begin with `no-` can be 'negated' by removing it.
+  Other long options can be unset (e.g., set string to NULL, set
+  integer to 0) by prepending `no-`.
 
 * Options and non-option arguments can clearly be separated using the `--`
   option, e.g. `-a -b --option -- --this-is-a-file` indicates that
@@ -174,6 +176,10 @@ There are some macros to easily define options:
        Introduce an option with date argument, see `approxidate()`.
        The timestamp is put into `int_var`.
 
+`OPT_EXPIRY_DATE(short, long, &int_var, description)`::
+       Introduce an option with expiry date argument, see `parse_expiry_date()`.
+       The timestamp is put into `int_var`.
+
 `OPT_CALLBACK(short, long, &var, arg_str, description, func_ptr)`::
        Introduce an option with argument.
        The argument will be fed into the function given by `func_ptr`
@@ -269,10 +275,10 @@ Examples
 --------
 
 See `test-parse-options.c` and
-`builtin-add.c`,
-`builtin-clone.c`,
-`builtin-commit.c`,
-`builtin-fetch.c`,
-`builtin-fsck.c`,
-`builtin-rm.c`
+`builtin/add.c`,
+`builtin/clone.c`,
+`builtin/commit.c`,
+`builtin/fetch.c`,
+`builtin/fsck.c`,
+`builtin/rm.c`
 for real-world examples.
index f1a51ed..b898e97 100644 (file)
@@ -228,8 +228,7 @@ obtained through ref discovery.
 The client MUST write all obj-ids which it only has shallow copies
 of (meaning that it does not have the parents of a commit) as
 'shallow' lines so that the server is aware of the limitations of
-the client's history. Clients MUST NOT mention an obj-id which
-it does not know exists on the server.
+the client's history.
 
 The client now sends the maximum commit history depth it wants for
 this transaction, which is the number of commits it wants from the
index 6dc82ca..f716d6d 100644 (file)
@@ -135,9 +135,9 @@ them, and give the same timestamp to the index file:
   $ git ls-files | git update-index --stdin
   $ touch -r .datestamp .git/index
 
-This will make all index entries racily clean.  The linux-2.6
-project, for example, there are over 20,000 files in the working
-tree.  On my Athlon 64 X2 3800+, after the above:
+This will make all index entries racily clean.  The linux project, for
+example, there are over 20,000 files in the working tree.  On my
+Athlon 64 X2 3800+, after the above:
 
   $ /usr/bin/time git diff-files
   1.68user 0.54system 0:02.22elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k
index 3ca122f..9ccb246 100644 (file)
@@ -11,6 +11,9 @@ and ftps can be used for fetching and rsync can be used for fetching
 and pushing, but these are inefficient and deprecated; do not use
 them).
 
+The native transport (i.e. git:// URL) does no authentication and
+should be used with caution on unsecured networks.
+
 The following syntaxes may be used with them:
 
 - ssh://{startsb}user@{endsb}host.xz{startsb}:port{endsb}/path/to/repo.git/
@@ -23,6 +26,12 @@ An alternative scp-like syntax may also be used with the ssh protocol:
 
 - {startsb}user@{endsb}host.xz:path/to/repo.git/
 
+This syntax is only recognized if there are no slashes before the
+first colon. This helps differentiate a local path that contains a
+colon. For example the local path `foo:bar` could be specified as an
+absolute path or `./foo:bar` to avoid being misinterpreted as an ssh
+url.
+
 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/
@@ -33,7 +42,7 @@ For local repositories, also supported by Git natively, the following
 syntaxes may be used:
 
 - /path/to/repo.git/
-- file:///path/to/repo.git/
+- \file:///path/to/repo.git/
 
 ifndef::git-clone[]
 These two syntaxes are mostly equivalent, except when cloning, when
index e831cc2..e364007 100644 (file)
@@ -57,17 +57,17 @@ download a copy of an existing repository.  If you don't already have a
 project in mind, here are some interesting examples:
 
 ------------------------------------------------
-       # Git itself (approx. 10MB download):
+       # Git itself (approx. 40MB download):
 $ git clone git://git.kernel.org/pub/scm/git/git.git
-       # the Linux kernel (approx. 150MB download):
-$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
+       # the Linux kernel (approx. 640MB download):
+$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
 ------------------------------------------------
 
 The initial clone may be time-consuming for a large project, but you
 will only need to clone once.
 
-The clone command creates a new directory named after the project (`git`
-or `linux-2.6` in the examples above).  After you cd into this
+The clone command creates a new directory named after the project
+(`git` or `linux` in the examples above).  After you cd into this
 directory, you will see that it contains a copy of the project files,
 called the <<def_working_tree,working tree>>, together with a special
 top-level directory named `.git`, which contains all the information
@@ -431,19 +431,25 @@ You can also track branches from repositories other than the one you
 cloned from, using linkgit:git-remote[1]:
 
 -------------------------------------------------
-$ git remote add linux-nfs git://linux-nfs.org/pub/nfs-2.6.git
-$ git fetch linux-nfs
-* refs/remotes/linux-nfs/master: storing branch 'master' ...
-  commit: bf81b46
+$ git remote add staging git://git.kernel.org/.../gregkh/staging.git
+$ git fetch staging
+...
+From git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
+ * [new branch]      master     -> staging/master
+ * [new branch]      staging-linus -> staging/staging-linus
+ * [new branch]      staging-next -> staging/staging-next
 -------------------------------------------------
 
 New remote-tracking branches will be stored under the shorthand name
-that you gave `git remote add`, in this case `linux-nfs`:
+that you gave `git remote add`, in this case `staging`:
 
 -------------------------------------------------
 $ git branch -r
-linux-nfs/master
-origin/master
+  origin/HEAD -> origin/master
+  origin/master
+  staging/master
+  staging/staging-linus
+  staging/staging-next
 -------------------------------------------------
 
 If you run `git fetch <remote>` later, the remote-tracking branches
@@ -455,9 +461,9 @@ a new stanza:
 -------------------------------------------------
 $ cat .git/config
 ...
-[remote "linux-nfs"]
-       url = git://linux-nfs.org/pub/nfs-2.6.git
-       fetch = +refs/heads/*:refs/remotes/linux-nfs/*
+[remote "staging"]
+       url = git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
+       fetch = +refs/heads/*:refs/remotes/staging/*
 ...
 -------------------------------------------------
 
@@ -1835,7 +1841,7 @@ Once the index is updated with the results of the conflict
 resolution, instead of creating a new commit, just run
 
 -------------------------------------------------
-$ git am --resolved
+$ git am --continue
 -------------------------------------------------
 
 and Git will create the commit for you and continue applying the
@@ -2156,7 +2162,7 @@ To set this up, first create your work tree by cloning Linus's public
 tree:
 
 -------------------------------------------------
-$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git work
+$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git work
 $ cd work
 -------------------------------------------------
 
@@ -2198,7 +2204,7 @@ make it easy to push both branches to your public tree.  (See
 -------------------------------------------------
 $ cat >> .git/config <<EOF
 [remote "mytree"]
-       url =  master.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
+       url =  master.kernel.org:/pub/scm/linux/kernel/git/aegl/linux.git
        push = release
        push = test
 EOF
@@ -4256,15 +4262,16 @@ no longer need to call `setup_pager()` directly).
 Nowadays, `git log` is a builtin, which means that it is _contained_ in the
 command `git`.  The source side of a builtin is
 
-- a function called `cmd_<bla>`, typically defined in `builtin-<bla>.c`,
-  and declared in `builtin.h`,
+- a function called `cmd_<bla>`, typically defined in `builtin/<bla.c>`
+  (note that older versions of Git used to have it in `builtin-<bla>.c`
+  instead), and declared in `builtin.h`.
 
 - an entry in the `commands[]` array in `git.c`, and
 
 - an entry in `BUILTIN_OBJECTS` in the `Makefile`.
 
 Sometimes, more than one builtin is contained in one source file.  For
-example, `cmd_whatchanged()` and `cmd_log()` both reside in `builtin-log.c`,
+example, `cmd_whatchanged()` and `cmd_log()` both reside in `builtin/log.c`,
 since they share quite a bit of code.  In that case, the commands which are
 _not_ named like the `.c` file in which they live have to be listed in
 `BUILT_INS` in the `Makefile`.
@@ -4287,10 +4294,10 @@ For the sake of clarity, let's stay with `git cat-file`, because it
 - is plumbing, and
 
 - was around even in the initial commit (it literally went only through
-  some 20 revisions as `cat-file.c`, was renamed to `builtin-cat-file.c`
+  some 20 revisions as `cat-file.c`, was renamed to `builtin/cat-file.c`
   when made a builtin, and then saw less than 10 versions).
 
-So, look into `builtin-cat-file.c`, search for `cmd_cat_file()` and look what
+So, look into `builtin/cat-file.c`, search for `cmd_cat_file()` and look what
 it does.
 
 ------------------------------------------------------------------
@@ -4366,7 +4373,7 @@ Another example: Find out what to do in order to make some script a
 builtin:
 
 -------------------------------------------------
-$ git log --no-merges --diff-filter=A builtin-*.c
+$ git log --no-merges --diff-filter=A builtin/*.c
 -------------------------------------------------
 
 You see, Git is actually the best tool to find out about the source of Git
index aa87dbf..b4d4e50 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v1.8.3-rc3
+DEF_VER=v1.8.3.GIT
 
 LF='
 '
@@ -11,7 +11,7 @@ LF='
 if test -f version
 then
        VN=$(cat version) || VN="$DEF_VER"
-elif test -d .git -o -f .git &&
+elif test -d ${GIT_DIR:-.git} -o -f .git &&
        VN=$(git describe --match "v[0-9]*" --abbrev=7 HEAD 2>/dev/null) &&
        case "$VN" in
        *$LF*) (exit 1) ;;
index 0f931a2..0600eb4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -69,6 +69,9 @@ all::
 # Define NO_MSGFMT_EXTENDED_OPTIONS if your implementation of msgfmt
 # doesn't support GNU extensions like --check and --statistics
 #
+# Define NEEDS_CLIPPED_WRITE if your write(2) cannot write more than
+# INT_MAX bytes at once (e.g. MacOS X).
+#
 # Define HAVE_PATHS_H if you have paths.h and want to use the default PATH
 # it specifies.
 #
@@ -106,7 +109,7 @@ all::
 # Define NO_FNMATCH_CASEFOLD if your fnmatch function doesn't have the
 # FNM_CASEFOLD GNU extension.
 #
-# Define USE_WILDMATCH if you want to use Git's wildmatch
+# Define NO_WILDMATCH if you do not want to use Git's wildmatch
 # implementation as fnmatch
 #
 # Define NO_GECOS_IN_PWENT if you don't have pw_gecos in struct passwd
@@ -137,6 +140,10 @@ all::
 # specify your own (or DarwinPort's) include directories and
 # library directories by defining CFLAGS and LDFLAGS appropriately.
 #
+# Define NO_APPLE_COMMON_CRYPTO if you are building on Darwin/Mac OS X
+# and do not want to use Apple's CommonCrypto library.  This allows you
+# to provide your own OpenSSL library, for example from MacPorts.
+#
 # Define BLK_SHA1 environment variable to make use of the bundled
 # optimized C SHA1 routine.
 #
@@ -290,10 +297,6 @@ all::
 #
 # Define NO_REGEX if you have no or inferior regex support in your C library.
 #
-# Define CYGWIN_V15_WIN32API if you are using Cygwin v1.7.x but are not
-# using the current w32api packages. The recommended approach, however,
-# is to update your installation if compilation errors occur.
-#
 # Define HAVE_DEV_TTY if your system can open /dev/tty to interact with the
 # user.
 #
@@ -460,6 +463,7 @@ SCRIPT_SH += git-mergetool.sh
 SCRIPT_SH += git-pull.sh
 SCRIPT_SH += git-quiltimport.sh
 SCRIPT_SH += git-rebase.sh
+SCRIPT_SH += git-remote-testgit.sh
 SCRIPT_SH += git-repack.sh
 SCRIPT_SH += git-request-pull.sh
 SCRIPT_SH += git-stash.sh
@@ -487,11 +491,18 @@ SCRIPT_PERL += git-svn.perl
 SCRIPT_PYTHON += git-remote-testpy.py
 SCRIPT_PYTHON += git-p4.py
 
+NO_INSTALL += git-remote-testgit
+NO_INSTALL += git-remote-testpy
+
 # Generated files for scripts
 SCRIPT_SH_GEN = $(patsubst %.sh,%,$(SCRIPT_SH))
 SCRIPT_PERL_GEN = $(patsubst %.perl,%,$(SCRIPT_PERL))
 SCRIPT_PYTHON_GEN = $(patsubst %.py,%,$(SCRIPT_PYTHON))
 
+SCRIPT_SH_INS = $(filter-out $(NO_INSTALL),$(SCRIPT_SH_GEN))
+SCRIPT_PERL_INS = $(filter-out $(NO_INSTALL),$(SCRIPT_PERL_GEN))
+SCRIPT_PYTHON_INS = $(filter-out $(NO_INSTALL),$(SCRIPT_PYTHON_GEN))
+
 # Individual rules to allow e.g.
 # "make -C ../.. SCRIPT_PERL=contrib/foo/bar.perl build-perl-script"
 # from subdirectories like contrib/*/
@@ -501,12 +512,12 @@ build-sh-script: $(SCRIPT_SH_GEN)
 build-python-script: $(SCRIPT_PYTHON_GEN)
 
 .PHONY: install-perl-script install-sh-script install-python-script
-install-sh-script: $(SCRIPT_SH_GEN)
-       $(INSTALL) $(SCRIPT_SH_GEN) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
-install-perl-script: $(SCRIPT_PERL_GEN)
-       $(INSTALL) $(SCRIPT_PERL_GEN) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
-install-python-script: $(SCRIPT_PYTHON_GEN)
-       $(INSTALL) $(SCRIPT_PYTHON_GEN) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
+install-sh-script: $(SCRIPT_SH_INS)
+       $(INSTALL) $^ '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
+install-perl-script: $(SCRIPT_PERL_INS)
+       $(INSTALL) $^ '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
+install-python-script: $(SCRIPT_PYTHON_INS)
+       $(INSTALL) $^ '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
 
 .PHONY: clean-perl-script clean-sh-script clean-python-script
 clean-sh-script:
@@ -516,9 +527,9 @@ clean-perl-script:
 clean-python-script:
        $(RM) $(SCRIPT_PYTHON_GEN)
 
-SCRIPTS = $(SCRIPT_SH_GEN) \
-         $(SCRIPT_PERL_GEN) \
-         $(SCRIPT_PYTHON_GEN) \
+SCRIPTS = $(SCRIPT_SH_INS) \
+         $(SCRIPT_PERL_INS) \
+         $(SCRIPT_PYTHON_INS) \
          git-instaweb
 
 ETAGS_TARGET = TAGS
@@ -558,6 +569,8 @@ TEST_PROGRAMS_NEED_X += test-mergesort
 TEST_PROGRAMS_NEED_X += test-mktemp
 TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-path-utils
+TEST_PROGRAMS_NEED_X += test-prio-queue
+TEST_PROGRAMS_NEED_X += test-read-cache
 TEST_PROGRAMS_NEED_X += test-regex
 TEST_PROGRAMS_NEED_X += test-revision-walking
 TEST_PROGRAMS_NEED_X += test-run-command
@@ -673,6 +686,8 @@ LIB_H += help.h
 LIB_H += http.h
 LIB_H += kwset.h
 LIB_H += levenshtein.h
+LIB_H += line-log.h
+LIB_H += line-range.h
 LIB_H += list-objects.h
 LIB_H += ll-merge.h
 LIB_H += log-tree.h
@@ -682,15 +697,16 @@ LIB_H += merge-recursive.h
 LIB_H += mergesort.h
 LIB_H += notes-cache.h
 LIB_H += notes-merge.h
+LIB_H += notes-utils.h
 LIB_H += notes.h
 LIB_H += object.h
-LIB_H += pack-refs.h
 LIB_H += pack-revindex.h
 LIB_H += pack.h
 LIB_H += parse-options.h
 LIB_H += patch-ids.h
 LIB_H += pathspec.h
 LIB_H += pkt-line.h
+LIB_H += prio-queue.h
 LIB_H += progress.h
 LIB_H += prompt.h
 LIB_H += quote.h
@@ -801,6 +817,8 @@ LIB_OBJS += hex.o
 LIB_OBJS += ident.o
 LIB_OBJS += kwset.o
 LIB_OBJS += levenshtein.o
+LIB_OBJS += line-log.o
+LIB_OBJS += line-range.o
 LIB_OBJS += list-objects.o
 LIB_OBJS += ll-merge.o
 LIB_OBJS += lockfile.o
@@ -815,9 +833,9 @@ LIB_OBJS += name-hash.o
 LIB_OBJS += notes.o
 LIB_OBJS += notes-cache.o
 LIB_OBJS += notes-merge.o
+LIB_OBJS += notes-utils.o
 LIB_OBJS += object.o
 LIB_OBJS += pack-check.o
-LIB_OBJS += pack-refs.o
 LIB_OBJS += pack-revindex.o
 LIB_OBJS += pack-write.o
 LIB_OBJS += pager.o
@@ -830,6 +848,7 @@ LIB_OBJS += pathspec.o
 LIB_OBJS += pkt-line.o
 LIB_OBJS += preload-index.o
 LIB_OBJS += pretty.o
+LIB_OBJS += prio-queue.o
 LIB_OBJS += progress.o
 LIB_OBJS += prompt.o
 LIB_OBJS += quote.o
@@ -1054,6 +1073,11 @@ ifeq ($(uname_S),Darwin)
                        BASIC_LDFLAGS += -L/opt/local/lib
                endif
        endif
+       ifndef NO_APPLE_COMMON_CRYPTO
+               APPLE_COMMON_CRYPTO = YesPlease
+               COMPAT_CFLAGS += -DAPPLE_COMMON_CRYPTO
+       endif
+       NO_REGEX = YesPlease
        PTHREAD_LIBS =
 endif
 
@@ -1261,7 +1285,7 @@ ifdef NO_FNMATCH_CASEFOLD
        COMPAT_OBJS += compat/fnmatch/fnmatch.o
 endif
 endif
-ifdef USE_WILDMATCH
+ifndef NO_WILDMATCH
        COMPAT_CFLAGS += -DUSE_WILDMATCH
 endif
 ifdef NO_SETENV
@@ -1387,11 +1411,17 @@ ifdef PPC_SHA1
        SHA1_HEADER = "ppc/sha1.h"
        LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o
        LIB_H += ppc/sha1.h
+else
+ifdef APPLE_COMMON_CRYPTO
+       COMPAT_CFLAGS += -DCOMMON_DIGEST_FOR_OPENSSL
+       SHA1_HEADER = <CommonCrypto/CommonDigest.h>
 else
        SHA1_HEADER = <openssl/sha.h>
        EXTLIBS += $(LIB_4_CRYPTO)
 endif
 endif
+endif
+
 ifdef NO_PERL_MAKEMAKER
        export NO_PERL_MAKEMAKER
 endif
@@ -1449,9 +1479,6 @@ ifdef NO_REGEX
        COMPAT_CFLAGS += -Icompat/regex
        COMPAT_OBJS += compat/regex/regex.o
 endif
-ifdef CYGWIN_V15_WIN32API
-       COMPAT_CFLAGS += -DCYGWIN_V15_WIN32API
-endif
 
 ifdef USE_NED_ALLOCATOR
        COMPAT_CFLAGS += -Icompat/nedmalloc
@@ -1466,6 +1493,11 @@ ifndef NO_MSGFMT_EXTENDED_OPTIONS
        MSGFMT += --check --statistics
 endif
 
+ifdef NEEDS_CLIPPED_WRITE
+       BASIC_CFLAGS += -DNEEDS_CLIPPED_WRITE
+       COMPAT_OBJS += compat/clipped-write.o
+endif
+
 ifneq (,$(XDL_FAST_HASH))
        BASIC_CFLAGS += -DXDL_FAST_HASH
 endif
@@ -1503,6 +1535,7 @@ ifndef V
        QUIET_MSGFMT   = @echo '   ' MSGFMT $@;
        QUIET_GCOV     = @echo '   ' GCOV $@;
        QUIET_SP       = @echo '   ' SP $<;
+       QUIET_RC       = @echo '   ' RC $@;
        QUIET_SUBDIR0  = +@subdir=
        QUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \
                         $(MAKE) $(PRINT_DIR) -C $$subdir
@@ -1645,7 +1678,7 @@ please_set_SHELL_PATH_to_a_more_modern_shell:
 shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell
 
 strip: $(PROGRAMS) git$X
-       $(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X
+       $(STRIP) $(STRIP_OPTS) $^
 
 ### Target-specific flags and dependencies
 
@@ -1705,9 +1738,9 @@ version.sp version.s version.o: EXTRA_CPPFLAGS = \
 
 $(BUILT_INS): git$X
        $(QUIET_BUILT_IN)$(RM) $@ && \
-       ln git$X $@ 2>/dev/null || \
-       ln -s git$X $@ 2>/dev/null || \
-       cp git$X $@
+       ln $< $@ 2>/dev/null || \
+       ln -s $< $@ 2>/dev/null || \
+       cp $< $@
 
 common-cmds.h: ./generate-cmdlist.sh command-list.txt
 
@@ -1748,6 +1781,11 @@ $(SCRIPT_LIB) : % : %.sh GIT-SCRIPT-DEFINES
        $(QUIET_GEN)$(cmd_munge_script) && \
        mv $@+ $@
 
+git.res: git.rc GIT-VERSION-FILE
+       $(QUIET_RC)$(RC) \
+         $(join -DMAJOR= -DMINOR= -DPATCH=, $(wordlist 1,3,$(subst -, ,$(subst ., ,$(GIT_VERSION))))) \
+         -DGIT_VERSION="\\\"$(GIT_VERSION)\\\"" $< -o $@
+
 ifndef NO_PERL
 $(patsubst %.perl,%,$(SCRIPT_PERL)): perl/perl.mak
 
@@ -1772,7 +1810,7 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl GIT-VERSION-FILE
            -e '        x' \
            -e '}' \
            -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
-           $@.perl >$@+ && \
+           $< >$@+ && \
        chmod +x $@+ && \
        mv $@+ $@
 
@@ -1796,8 +1834,8 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)) git-instaweb: % : unimplemented.sh
 endif # NO_PERL
 
 ifndef NO_PYTHON
-$(patsubst %.py,%,$(SCRIPT_PYTHON)): GIT-CFLAGS GIT-PREFIX GIT-PYTHON-VARS
-$(patsubst %.py,%,$(SCRIPT_PYTHON)): % : %.py
+$(SCRIPT_PYTHON_GEN): GIT-CFLAGS GIT-PREFIX GIT-PYTHON-VARS
+$(SCRIPT_PYTHON_GEN): % : %.py
        $(QUIET_GEN)$(RM) $@ $@+ && \
        INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C git_remote_helpers -s \
                --no-print-directory prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' \
@@ -1805,11 +1843,11 @@ $(patsubst %.py,%,$(SCRIPT_PYTHON)): % : %.py
        sed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \
            -e 's|\(os\.getenv("GITPYTHONLIB"\)[^)]*)|\1,"@@INSTLIBDIR@@")|' \
            -e 's|@@INSTLIBDIR@@|'"$$INSTLIBDIR"'|g' \
-           $@.py >$@+ && \
+           $< >$@+ && \
        chmod +x $@+ && \
        mv $@+ $@
 else # NO_PYTHON
-$(patsubst %.py,%,$(SCRIPT_PYTHON)): % : unimplemented.sh
+$(SCRIPT_PYTHON_GEN): % : unimplemented.sh
        $(QUIET_GEN)$(RM) $@ $@+ && \
        sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
            -e 's|@@REASON@@|NO_PYTHON=$(NO_PYTHON)|g' \
@@ -2004,6 +2042,7 @@ endif
 ifdef USE_NED_ALLOCATOR
 compat/nedmalloc/nedmalloc.sp compat/nedmalloc/nedmalloc.o: EXTRA_CPPFLAGS = \
        -DNDEBUG -DOVERRIDE_STRDUP -DREPLACE_SYSTEM_ALLOCATOR
+compat/nedmalloc/nedmalloc.sp: SPARSE_FLAGS += -Wno-non-pointer-null
 endif
 
 git-%$X: %.o GIT-LDFLAGS $(GITLIBS)
@@ -2035,13 +2074,13 @@ $(REMOTE_CURL_PRIMARY): remote-curl.o http.o http-walker.o GIT-LDFLAGS $(GITLIBS
                $(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
 
 $(LIB_FILE): $(LIB_OBJS)
-       $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS)
+       $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $^
 
 $(XDIFF_LIB): $(XDIFF_OBJS)
-       $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(XDIFF_OBJS)
+       $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $^
 
 $(VCSSVN_LIB): $(VCSSVN_OBJS)
-       $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(VCSSVN_OBJS)
+       $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $^
 
 export DEFAULT_EDITOR DEFAULT_PAGER
 
@@ -2159,6 +2198,9 @@ GIT-BUILD-OPTIONS: FORCE
        @echo NO_PERL=\''$(subst ','\'',$(subst ','\'',$(NO_PERL)))'\' >>$@
        @echo NO_PYTHON=\''$(subst ','\'',$(subst ','\'',$(NO_PYTHON)))'\' >>$@
        @echo NO_UNIX_SOCKETS=\''$(subst ','\'',$(subst ','\'',$(NO_UNIX_SOCKETS)))'\' >>$@
+ifdef TEST_OUTPUT_DIRECTORY
+       @echo TEST_OUTPUT_DIRECTORY=\''$(subst ','\'',$(subst ','\'',$(TEST_OUTPUT_DIRECTORY)))'\' >>$@
+endif
 ifdef GIT_TEST_OPTS
        @echo GIT_TEST_OPTS=\''$(subst ','\'',$(subst ','\'',$(GIT_TEST_OPTS)))'\' >>$@
 endif
@@ -2198,6 +2240,7 @@ endif
 test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(BINDIR_PROGRAMS_NO_X) $(TEST_PROGRAMS_NEED_X))
 
 all:: $(TEST_PROGRAMS) $(test_bindir_programs)
+all:: $(NO_INSTALL)
 
 bin-wrappers/%: wrap-for-bin.sh
        @mkdir -p bin-wrappers
@@ -2262,9 +2305,6 @@ check: common-cmds.h
                exit 1; \
        fi
 
-remove-dashes:
-       ./fixup-builtins $(BUILT_INS) $(PROGRAMS) $(SCRIPTS)
-
 ### Installation rules
 
 ifneq ($(filter /%,$(firstword $(template_dir))),)
@@ -2443,11 +2483,11 @@ profile-clean:
        $(RM) $(addsuffix *.gcda,$(addprefix $(PROFILE_DIR)/, $(object_dirs)))
        $(RM) $(addsuffix *.gcno,$(addprefix $(PROFILE_DIR)/, $(object_dirs)))
 
-clean: profile-clean
-       $(RM) *.o block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o xdiff/*.o vcs-svn/*.o \
+clean: profile-clean coverage-clean
+       $(RM) *.o *.res block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o xdiff/*.o vcs-svn/*.o \
                builtin/*.o $(LIB_FILE) $(XDIFF_LIB) $(VCSSVN_LIB)
        $(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X
-       $(RM) $(TEST_PROGRAMS)
+       $(RM) $(TEST_PROGRAMS) $(NO_INSTALL)
        $(RM) -r bin-wrappers $(dep_dirs)
        $(RM) -r po/build/
        $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h $(ETAGS_TARGET) tags cscope*
@@ -2524,29 +2564,34 @@ check-builtins::
 
 ### Test suite coverage testing
 #
-.PHONY: coverage coverage-clean coverage-build coverage-report
+.PHONY: coverage coverage-clean coverage-compile coverage-test coverage-report
+.PHONY: coverage-clean-results
 
 coverage:
-       $(MAKE) coverage-build
-       $(MAKE) coverage-report
+       $(MAKE) coverage-test
+       $(MAKE) coverage-untested-functions
 
 object_dirs := $(sort $(dir $(OBJECTS)))
-coverage-clean:
+coverage-clean-results:
        $(RM) $(addsuffix *.gcov,$(object_dirs))
        $(RM) $(addsuffix *.gcda,$(object_dirs))
-       $(RM) $(addsuffix *.gcno,$(object_dirs))
        $(RM) coverage-untested-functions
        $(RM) -r cover_db/
        $(RM) -r cover_db_html/
 
+coverage-clean: coverage-clean-results
+       $(RM) $(addsuffix *.gcno,$(object_dirs))
+
 COVERAGE_CFLAGS = $(CFLAGS) -O0 -ftest-coverage -fprofile-arcs
 COVERAGE_LDFLAGS = $(CFLAGS)  -O0 -lgcov
 GCOVFLAGS = --preserve-paths --branch-probabilities --all-blocks
 
-coverage-build: coverage-clean
+coverage-compile:
        $(MAKE) CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" all
+
+coverage-test: coverage-clean-results coverage-compile
        $(MAKE) CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" \
-               -j1 test
+               DEFAULT_TEST_TARGET=test -j1 test
 
 coverage-report:
        $(QUIET_GCOV)for dir in $(object_dirs); do \
index 80b7e38..fce99fb 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/1.8.3.txt
\ No newline at end of file
+Documentation/RelNotes/1.8.4.txt
\ No newline at end of file
index 40cdc46..64adbe2 100644 (file)
--- a/abspath.c
+++ b/abspath.c
@@ -216,7 +216,7 @@ const char *absolute_path(const char *path)
 const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
 {
        static char path[PATH_MAX];
-#ifndef WIN32
+#ifndef GIT_WINDOWS_NATIVE
        if (!pfx_len || is_absolute_path(arg))
                return arg;
        memcpy(path, pfx, pfx_len);
index a8deee6..2a52098 100644 (file)
--- a/advice.c
+++ b/advice.c
@@ -14,6 +14,8 @@ int advice_resolve_conflict = 1;
 int advice_implicit_identity = 1;
 int advice_detached_head = 1;
 int advice_set_upstream_failure = 1;
+int advice_object_name_warning = 1;
+int advice_rm_hints = 1;
 
 static struct {
        const char *name;
@@ -33,6 +35,8 @@ static struct {
        { "implicitidentity", &advice_implicit_identity },
        { "detachedhead", &advice_detached_head },
        { "setupstreamfailure", &advice_set_upstream_failure },
+       { "object_name_warning", &advice_object_name_warning },
+       { "rmhints", &advice_rm_hints },
 
        /* make this an alias for backward compatibility */
        { "pushnonfastforward", &advice_push_update_rejected }
index 94caa32..93a7d11 100644 (file)
--- a/advice.h
+++ b/advice.h
@@ -17,6 +17,8 @@ extern int advice_resolve_conflict;
 extern int advice_implicit_identity;
 extern int advice_detached_head;
 extern int advice_set_upstream_failure;
+extern int advice_object_name_warning;
+extern int advice_rm_hints;
 
 int git_default_advice_config(const char *var, const char *value);
 void advise(const char *advice, ...);
index b2c4fe0..4bde019 100644 (file)
@@ -232,7 +232,6 @@ static int write_zip_entry(struct archiver_args *args,
                size = 0;
                compressed_size = 0;
                buffer = NULL;
-               size = 0;
        } else if (S_ISREG(mode) || S_ISLNK(mode)) {
                enum object_type type = sha1_object_info(sha1, &size);
 
index 374d9e2..71c1958 100644 (file)
--- a/bisect.c
+++ b/bisect.c
@@ -15,7 +15,7 @@
 static struct sha1_array good_revs;
 static struct sha1_array skipped_revs;
 
-static const unsigned char *current_bad_sha1;
+static unsigned char *current_bad_sha1;
 
 static const char *argv_checkout[] = {"checkout", "-q", NULL, "--", NULL};
 static const char *argv_show_branch[] = {"show-branch", NULL, NULL};
@@ -404,7 +404,8 @@ static int register_ref(const char *refname, const unsigned char *sha1,
                        int flags, void *cb_data)
 {
        if (!strcmp(refname, "bad")) {
-               current_bad_sha1 = sha1;
+               current_bad_sha1 = xmalloc(20);
+               hashcpy(current_bad_sha1, sha1);
        } else if (!prefixcmp(refname, "good-")) {
                sha1_array_append(&good_revs, sha1);
        } else if (!prefixcmp(refname, "skip-")) {
index 97c72bf..c5c6984 100644 (file)
--- a/branch.c
+++ b/branch.c
@@ -197,6 +197,21 @@ int validate_new_branchname(const char *name, struct strbuf *ref,
        return 1;
 }
 
+static int check_tracking_branch(struct remote *remote, void *cb_data)
+{
+       char *tracking_branch = cb_data;
+       struct refspec query;
+       memset(&query, 0, sizeof(struct refspec));
+       query.dst = tracking_branch;
+       return !(remote_find_tracking(remote, &query) ||
+                prefixcmp(query.src, "refs/heads/"));
+}
+
+static int validate_remote_tracking_branch(char *ref)
+{
+       return !for_each_remote(check_tracking_branch, ref);
+}
+
 static const char upstream_not_branch[] =
 N_("Cannot setup tracking information; starting point '%s' is not a branch.");
 static const char upstream_missing[] =
@@ -259,7 +274,7 @@ void create_branch(const char *head,
        case 1:
                /* Unique completion -- good, only if it is a real branch */
                if (prefixcmp(real_ref, "refs/heads/") &&
-                   prefixcmp(real_ref, "refs/remotes/")) {
+                   validate_remote_tracking_branch(real_ref)) {
                        if (explicit_tracking)
                                die(_(upstream_not_branch), start_name);
                        else
index faef559..1ed8edb 100644 (file)
--- a/builtin.h
+++ b/builtin.h
@@ -5,13 +5,15 @@
 #include "strbuf.h"
 #include "cache.h"
 #include "commit.h"
-#include "notes.h"
 
 #define DEFAULT_MERGE_LOG_LEN 20
 
 extern const char git_usage_string[];
 extern const char git_more_info_string[];
 
+#define PRUNE_PACKED_DRY_RUN 01
+#define PRUNE_PACKED_VERBOSE 02
+
 extern void prune_packed_objects(int);
 
 struct fmt_merge_msg_opts {
@@ -23,21 +25,6 @@ struct fmt_merge_msg_opts {
 extern int fmt_merge_msg(struct strbuf *in, struct strbuf *out,
                         struct fmt_merge_msg_opts *);
 
-struct notes_rewrite_cfg {
-       struct notes_tree **trees;
-       const char *cmd;
-       int enabled;
-       combine_notes_fn combine;
-       struct string_list *refs;
-       int refs_from_env;
-       int mode_from_env;
-};
-
-struct notes_rewrite_cfg *init_copy_notes_for_rewrite(const char *cmd);
-int copy_note_for_rewrite(struct notes_rewrite_cfg *c,
-                         const unsigned char *from_obj, const unsigned char *to_obj);
-void finish_copy_notes_for_rewrite(struct notes_rewrite_cfg *c);
-
 extern int textconv_object(const char *path, unsigned mode, const unsigned char *sha1, int sha1_valid, char **buf, unsigned long *buf_size);
 
 extern int cmd_add(int argc, const char **argv, const char *prefix);
index 30eefc3..0e9b631 100644 (file)
@@ -906,7 +906,7 @@ static void parse_traditional_patch(const char *first, const char *second, struc
                        patch->old_name = name;
                } else {
                        patch->old_name = name;
-                       patch->new_name = xstrdup(name);
+                       patch->new_name = null_strdup(name);
                }
        }
        if (!name)
@@ -3525,7 +3525,7 @@ static int check_patch(struct patch *patch)
                ok_if_exists = 0;
 
        if (new_name &&
-           ((0 < patch->is_new) | (0 < patch->is_rename) | patch->is_copy)) {
+           ((0 < patch->is_new) || patch->is_rename || patch->is_copy)) {
                int err = check_to_create(new_name, ok_if_exists);
 
                if (err && threeway) {
index 57a487e..079dcd3 100644 (file)
@@ -21,6 +21,7 @@
 #include "parse-options.h"
 #include "utf8.h"
 #include "userdiff.h"
+#include "line-range.h"
 
 static char blame_usage[] = N_("git blame [options] [rev-opts] [rev] [--] file");
 
@@ -566,11 +567,16 @@ static void dup_entry(struct blame_entry *dst, struct blame_entry *src)
        dst->score = 0;
 }
 
-static const char *nth_line(struct scoreboard *sb, int lno)
+static const char *nth_line(struct scoreboard *sb, long lno)
 {
        return sb->final_buf + sb->lineno[lno];
 }
 
+static const char *nth_line_cb(void *data, long lno)
+{
+       return nth_line((struct scoreboard *)data, lno);
+}
+
 /*
  * It is known that lines between tlno to same came from parent, and e
  * has an overlap with that range.  it also is known that parent's
@@ -1931,83 +1937,6 @@ static const char *add_prefix(const char *prefix, const char *path)
        return prefix_path(prefix, prefix ? strlen(prefix) : 0, path);
 }
 
-/*
- * Parsing of (comma separated) one item in the -L option
- */
-static const char *parse_loc(const char *spec,
-                            struct scoreboard *sb, long lno,
-                            long begin, long *ret)
-{
-       char *term;
-       const char *line;
-       long num;
-       int reg_error;
-       regex_t regexp;
-       regmatch_t match[1];
-
-       /* Allow "-L <something>,+20" to mean starting at <something>
-        * for 20 lines, or "-L <something>,-5" for 5 lines ending at
-        * <something>.
-        */
-       if (1 < begin && (spec[0] == '+' || spec[0] == '-')) {
-               num = strtol(spec + 1, &term, 10);
-               if (term != spec + 1) {
-                       if (spec[0] == '-')
-                               num = 0 - num;
-                       if (0 < num)
-                               *ret = begin + num - 2;
-                       else if (!num)
-                               *ret = begin;
-                       else
-                               *ret = begin + num;
-                       return term;
-               }
-               return spec;
-       }
-       num = strtol(spec, &term, 10);
-       if (term != spec) {
-               *ret = num;
-               return term;
-       }
-       if (spec[0] != '/')
-               return spec;
-
-       /* it could be a regexp of form /.../ */
-       for (term = (char *) spec + 1; *term && *term != '/'; term++) {
-               if (*term == '\\')
-                       term++;
-       }
-       if (*term != '/')
-               return spec;
-
-       /* try [spec+1 .. term-1] as regexp */
-       *term = 0;
-       begin--; /* input is in human terms */
-       line = nth_line(sb, begin);
-
-       if (!(reg_error = regcomp(&regexp, spec + 1, REG_NEWLINE)) &&
-           !(reg_error = regexec(&regexp, line, 1, match, 0))) {
-               const char *cp = line + match[0].rm_so;
-               const char *nline;
-
-               while (begin++ < lno) {
-                       nline = nth_line(sb, begin);
-                       if (line <= cp && cp < nline)
-                               break;
-                       line = nline;
-               }
-               *ret = begin;
-               regfree(&regexp);
-               *term++ = '/';
-               return term;
-       }
-       else {
-               char errbuf[1024];
-               regerror(reg_error, &regexp, errbuf, 1024);
-               die("-L parameter '%s': %s", spec + 1, errbuf);
-       }
-}
-
 /*
  * Parsing of -L option
  */
@@ -2016,15 +1945,7 @@ static void prepare_blame_range(struct scoreboard *sb,
                                long lno,
                                long *bottom, long *top)
 {
-       const char *term;
-
-       term = parse_loc(bottomtop, sb, lno, 1, bottom);
-       if (*term == ',') {
-               term = parse_loc(term + 1, sb, lno, *bottom + 1, top);
-               if (*term)
-                       usage(blame_usage);
-       }
-       if (*term)
+       if (parse_range_arg(bottomtop, nth_line_cb, sb, lno, bottom, top, sb->path))
                usage(blame_usage);
 }
 
@@ -2574,10 +2495,6 @@ parse_done:
        bottom = top = 0;
        if (bottomtop)
                prepare_blame_range(&sb, bottomtop, lno, &bottom, &top);
-       if (bottom && top && top < bottom) {
-               long tmp;
-               tmp = top; top = bottom; bottom = tmp;
-       }
        if (bottom < 1)
                bottom = 1;
        if (top < 1)
index 854a88a..4a8fc70 100644 (file)
@@ -5,7 +5,7 @@
 #include "pathspec.h"
 #include "parse-options.h"
 
-static int quiet, verbose, stdin_paths;
+static int quiet, verbose, stdin_paths, show_non_matching;
 static const char * const check_ignore_usage[] = {
 "git check-ignore [options] pathname...",
 "git check-ignore [options] --stdin < <list-of-paths>",
@@ -22,21 +22,28 @@ static const struct option check_ignore_options[] = {
                    N_("read file names from stdin")),
        OPT_BOOLEAN('z', NULL, &null_term_line,
                    N_("input paths are terminated by a null character")),
+       OPT_BOOLEAN('n', "non-matching", &show_non_matching,
+                   N_("show non-matching input paths")),
        OPT_END()
 };
 
 static void output_exclude(const char *path, struct exclude *exclude)
 {
-       char *bang  = exclude->flags & EXC_FLAG_NEGATIVE  ? "!" : "";
-       char *slash = exclude->flags & EXC_FLAG_MUSTBEDIR ? "/" : "";
+       char *bang  = (exclude && exclude->flags & EXC_FLAG_NEGATIVE)  ? "!" : "";
+       char *slash = (exclude && exclude->flags & EXC_FLAG_MUSTBEDIR) ? "/" : "";
        if (!null_term_line) {
                if (!verbose) {
                        write_name_quoted(path, stdout, '\n');
                } else {
-                       quote_c_style(exclude->el->src, NULL, stdout, 0);
-                       printf(":%d:%s%s%s\t",
-                              exclude->srcpos,
-                              bang, exclude->pattern, slash);
+                       if (exclude) {
+                               quote_c_style(exclude->el->src, NULL, stdout, 0);
+                               printf(":%d:%s%s%s\t",
+                                      exclude->srcpos,
+                                      bang, exclude->pattern, slash);
+                       }
+                       else {
+                               printf("::\t");
+                       }
                        quote_c_style(path, NULL, stdout, 0);
                        fputc('\n', stdout);
                }
@@ -44,30 +51,26 @@ static void output_exclude(const char *path, struct exclude *exclude)
                if (!verbose) {
                        printf("%s%c", path, '\0');
                } else {
-                       printf("%s%c%d%c%s%s%s%c%s%c",
-                              exclude->el->src, '\0',
-                              exclude->srcpos, '\0',
-                              bang, exclude->pattern, slash, '\0',
-                              path, '\0');
+                       if (exclude)
+                               printf("%s%c%d%c%s%s%s%c%s%c",
+                                      exclude->el->src, '\0',
+                                      exclude->srcpos, '\0',
+                                      bang, exclude->pattern, slash, '\0',
+                                      path, '\0');
+                       else
+                               printf("%c%c%c%s%c", '\0', '\0', '\0', path, '\0');
                }
        }
 }
 
-static int check_ignore(const char *prefix, const char **pathspec)
+static int check_ignore(struct dir_struct *dir,
+                       const char *prefix, const char **pathspec)
 {
-       struct dir_struct dir;
        const char *path, *full_path;
        char *seen;
        int num_ignored = 0, dtype = DT_UNKNOWN, i;
        struct exclude *exclude;
 
-       /* read_cache() is only necessary so we can watch out for submodules. */
-       if (read_cache() < 0)
-               die(_("index file corrupt"));
-
-       memset(&dir, 0, sizeof(dir));
-       setup_standard_excludes(&dir);
-
        if (!pathspec || !*pathspec) {
                if (!quiet)
                        fprintf(stderr, "no pathspec given.\n");
@@ -86,28 +89,26 @@ static int check_ignore(const char *prefix, const char **pathspec)
                                        ? strlen(prefix) : 0, path);
                full_path = check_path_for_gitlink(full_path);
                die_if_path_beyond_symlink(full_path, prefix);
+               exclude = NULL;
                if (!seen[i]) {
-                       exclude = last_exclude_matching(&dir, full_path, &dtype);
-                       if (exclude) {
-                               if (!quiet)
-                                       output_exclude(path, exclude);
-                               num_ignored++;
-                       }
+                       exclude = last_exclude_matching(dir, full_path, &dtype);
                }
+               if (!quiet && (exclude || show_non_matching))
+                       output_exclude(path, exclude);
+               if (exclude)
+                       num_ignored++;
        }
        free(seen);
-       clear_directory(&dir);
 
        return num_ignored;
 }
 
-static int check_ignore_stdin_paths(const char *prefix)
+static int check_ignore_stdin_paths(struct dir_struct *dir, const char *prefix)
 {
        struct strbuf buf, nbuf;
-       char **pathspec = NULL;
-       size_t nr = 0, alloc = 0;
+       char *pathspec[2] = { NULL, NULL };
        int line_termination = null_term_line ? 0 : '\n';
-       int num_ignored;
+       int num_ignored = 0;
 
        strbuf_init(&buf, 0);
        strbuf_init(&nbuf, 0);
@@ -118,23 +119,19 @@ static int check_ignore_stdin_paths(const char *prefix)
                                die("line is badly quoted");
                        strbuf_swap(&buf, &nbuf);
                }
-               ALLOC_GROW(pathspec, nr + 1, alloc);
-               pathspec[nr] = xcalloc(strlen(buf.buf) + 1, sizeof(*buf.buf));
-               strcpy(pathspec[nr++], buf.buf);
+               pathspec[0] = buf.buf;
+               num_ignored += check_ignore(dir, prefix, (const char **)pathspec);
+               maybe_flush_or_die(stdout, "check-ignore to stdout");
        }
-       ALLOC_GROW(pathspec, nr + 1, alloc);
-       pathspec[nr] = NULL;
-       num_ignored = check_ignore(prefix, (const char **)pathspec);
-       maybe_flush_or_die(stdout, "attribute to stdout");
        strbuf_release(&buf);
        strbuf_release(&nbuf);
-       free(pathspec);
        return num_ignored;
 }
 
 int cmd_check_ignore(int argc, const char **argv, const char *prefix)
 {
        int num_ignored;
+       struct dir_struct dir;
 
        git_config(git_default_config, NULL);
 
@@ -156,13 +153,24 @@ int cmd_check_ignore(int argc, const char **argv, const char *prefix)
                if (verbose)
                        die(_("cannot have both --quiet and --verbose"));
        }
+       if (show_non_matching && !verbose)
+               die(_("--non-matching is only valid with --verbose"));
+
+       /* read_cache() is only necessary so we can watch out for submodules. */
+       if (read_cache() < 0)
+               die(_("index file corrupt"));
+
+       memset(&dir, 0, sizeof(dir));
+       setup_standard_excludes(&dir);
 
        if (stdin_paths) {
-               num_ignored = check_ignore_stdin_paths(prefix);
+               num_ignored = check_ignore_stdin_paths(&dir, prefix);
        } else {
-               num_ignored = check_ignore(prefix, argv);
+               num_ignored = check_ignore(&dir, prefix, argv);
                maybe_flush_or_die(stdout, "ignore to stdout");
        }
 
+       clear_directory(&dir);
+
        return !num_ignored;
 }
index 81b4419..7fe0bff 100644 (file)
@@ -587,7 +587,7 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
                                   struct branch_info *new)
 {
        struct strbuf msg = STRBUF_INIT;
-       const char *old_desc;
+       const char *old_desc, *reflog_msg;
        if (opts->new_branch) {
                if (opts->new_orphan_branch) {
                        if (opts->new_branch_log && !log_all_ref_updates) {
@@ -620,8 +620,13 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
        old_desc = old->name;
        if (!old_desc && old->commit)
                old_desc = sha1_to_hex(old->commit->object.sha1);
-       strbuf_addf(&msg, "checkout: moving from %s to %s",
-                   old_desc ? old_desc : "(invalid)", new->name);
+
+       reflog_msg = getenv("GIT_REFLOG_ACTION");
+       if (!reflog_msg)
+               strbuf_addf(&msg, "checkout: moving from %s to %s",
+                       old_desc ? old_desc : "(invalid)", new->name);
+       else
+               strbuf_insert(&msg, 0, reflog_msg, strlen(reflog_msg));
 
        if (!strcmp(new->name, "HEAD") && !new->path && !opts->force_detach) {
                /* Nothing to do. */
@@ -825,38 +830,43 @@ static int git_checkout_config(const char *var, const char *value, void *cb)
 }
 
 struct tracking_name_data {
-       const char *name;
-       char *remote;
+       /* const */ char *src_ref;
+       char *dst_ref;
+       unsigned char *dst_sha1;
        int unique;
 };
 
-static int check_tracking_name(const char *refname, const unsigned char *sha1,
-                              int flags, void *cb_data)
+static int check_tracking_name(struct remote *remote, void *cb_data)
 {
        struct tracking_name_data *cb = cb_data;
-       const char *slash;
-
-       if (prefixcmp(refname, "refs/remotes/"))
+       struct refspec query;
+       memset(&query, 0, sizeof(struct refspec));
+       query.src = cb->src_ref;
+       if (remote_find_tracking(remote, &query) ||
+           get_sha1(query.dst, cb->dst_sha1)) {
+               free(query.dst);
                return 0;
-       slash = strchr(refname + 13, '/');
-       if (!slash || strcmp(slash + 1, cb->name))
-               return 0;
-       if (cb->remote) {
+       }
+       if (cb->dst_ref) {
+               free(query.dst);
                cb->unique = 0;
                return 0;
        }
-       cb->remote = xstrdup(refname);
+       cb->dst_ref = query.dst;
        return 0;
 }
 
-static const char *unique_tracking_name(const char *name)
+static const char *unique_tracking_name(const char *name, unsigned char *sha1)
 {
-       struct tracking_name_data cb_data = { NULL, NULL, 1 };
-       cb_data.name = name;
-       for_each_ref(check_tracking_name, &cb_data);
+       struct tracking_name_data cb_data = { NULL, NULL, NULL, 1 };
+       char src_ref[PATH_MAX];
+       snprintf(src_ref, PATH_MAX, "refs/heads/%s", name);
+       cb_data.src_ref = src_ref;
+       cb_data.dst_sha1 = sha1;
+       for_each_remote(check_tracking_name, &cb_data);
        if (cb_data.unique)
-               return cb_data.remote;
-       free(cb_data.remote);
+               return cb_data.dst_ref;
+       free(cb_data.dst_ref);
        return NULL;
 }
 
@@ -919,8 +929,8 @@ static int parse_branchname_arg(int argc, const char **argv,
                if (dwim_new_local_branch_ok &&
                    !check_filename(NULL, arg) &&
                    argc == 1) {
-                       const char *remote = unique_tracking_name(arg);
-                       if (!remote || get_sha1(remote, rev))
+                       const char *remote = unique_tracking_name(arg, rev);
+                       if (!remote)
                                return argcount;
                        *new_branch = arg;
                        arg = remote;
index 035ab64..14b1323 100644 (file)
@@ -18,7 +18,6 @@
 #include "transport.h"
 #include "strbuf.h"
 #include "dir.h"
-#include "pack-refs.h"
 #include "sigchain.h"
 #include "branch.h"
 #include "remote.h"
@@ -494,13 +493,16 @@ static void write_remote_refs(const struct ref *local_refs)
 {
        const struct ref *r;
 
+       lock_packed_refs(LOCK_DIE_ON_ERROR);
+
        for (r = local_refs; r; r = r->next) {
                if (!r->peer_ref)
                        continue;
                add_packed_ref(r->peer_ref->name, r->old_sha1);
        }
 
-       pack_refs(PACK_REFS_ALL);
+       if (commit_packed_refs())
+               die_errno("unable to overwrite old ref-pack file");
 }
 
 static void write_followtags(const struct ref *refs, const char *msg)
@@ -542,12 +544,18 @@ static void update_remote_refs(const struct ref *refs,
                               const struct ref *mapped_refs,
                               const struct ref *remote_head_points_at,
                               const char *branch_top,
-                              const char *msg)
+                              const char *msg,
+                              struct transport *transport)
 {
        const struct ref *rm = mapped_refs;
 
-       if (check_everything_connected(iterate_ref_map, 0, &rm))
+       if (0 <= option_verbosity)
+               printf(_("Checking connectivity... "));
+       if (check_everything_connected_with_transport(iterate_ref_map,
+                                                     0, &rm, transport))
                die(_("remote did not send all necessary objects"));
+       if (0 <= option_verbosity)
+               printf(_("done\n"));
 
        if (refs) {
                write_remote_refs(mapped_refs);
@@ -783,6 +791,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        is_local = option_local != 0 && path && !is_bundle;
        if (is_local && option_depth)
                warning(_("--depth is ignored in local clones; use file:// instead."));
+       if (option_local > 0 && !is_local)
+               warning(_("--local is ignored"));
 
        if (argc == 2)
                dir = xstrdup(argv[1]);
@@ -889,6 +899,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
                if (option_upload_pack)
                        transport_set_option(transport, TRANS_OPT_UPLOADPACK,
                                             option_upload_pack);
+
+               if (transport->smart_options && !option_depth)
+                       transport->smart_options->check_self_contained_and_connected = 1;
        }
 
        refs = transport_get_remote_refs(transport);
@@ -950,7 +963,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
                transport_fetch_refs(transport, mapped_refs);
 
        update_remote_refs(refs, mapped_refs, remote_head_points_at,
-                          branch_top.buf, reflog_msg.buf);
+                          branch_top.buf, reflog_msg.buf, transport);
 
        update_head(our_head_points_at, remote_head, reflog_msg.buf);
 
index d2f30d9..790e5ab 100644 (file)
@@ -29,6 +29,7 @@
 #include "gpg-interface.h"
 #include "column.h"
 #include "sequencer.h"
+#include "notes-utils.h"
 
 static const char * const builtin_commit_usage[] = {
        N_("git commit [options] [--] <pathspec>..."),
@@ -107,23 +108,27 @@ static const char *cleanup_arg;
 
 static enum commit_whence whence;
 static int use_editor = 1, include_status = 1;
-static int show_ignored_in_status;
+static int show_ignored_in_status, have_option_m;
 static const char *only_include_assumed;
 static struct strbuf message = STRBUF_INIT;
 
-static enum {
+static enum status_format {
        STATUS_FORMAT_NONE = 0,
        STATUS_FORMAT_LONG,
        STATUS_FORMAT_SHORT,
-       STATUS_FORMAT_PORCELAIN
-} status_format;
+       STATUS_FORMAT_PORCELAIN,
+
+       STATUS_FORMAT_UNSPECIFIED
+} status_format = STATUS_FORMAT_UNSPECIFIED;
 
 static int opt_parse_m(const struct option *opt, const char *arg, int unset)
 {
        struct strbuf *buf = opt->value;
-       if (unset)
+       if (unset) {
+               have_option_m = 0;
                strbuf_setlen(buf, 0);
-       else {
+       } else {
+               have_option_m = 1;
                if (buf->len)
                        strbuf_addch(buf, '\n');
                strbuf_addstr(buf, arg);
@@ -457,6 +462,9 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
        case STATUS_FORMAT_PORCELAIN:
                wt_porcelain_print(s);
                break;
+       case STATUS_FORMAT_UNSPECIFIED:
+               die("BUG: finalize_deferred_config() should have been called");
+               break;
        case STATUS_FORMAT_NONE:
        case STATUS_FORMAT_LONG:
                wt_status_print(s);
@@ -958,6 +966,42 @@ static const char *read_commit_message(const char *name)
        return logmsg_reencode(commit, NULL, out_enc);
 }
 
+/*
+ * Enumerate what needs to be propagated when --porcelain
+ * is not in effect here.
+ */
+static struct status_deferred_config {
+       enum status_format status_format;
+       int show_branch;
+} status_deferred_config = {
+       STATUS_FORMAT_UNSPECIFIED,
+       -1 /* unspecified */
+};
+
+static void finalize_deferred_config(struct wt_status *s)
+{
+       int use_deferred_config = (status_format != STATUS_FORMAT_PORCELAIN &&
+                                  !s->null_termination);
+
+       if (s->null_termination) {
+               if (status_format == STATUS_FORMAT_NONE ||
+                   status_format == STATUS_FORMAT_UNSPECIFIED)
+                       status_format = STATUS_FORMAT_PORCELAIN;
+               else if (status_format == STATUS_FORMAT_LONG)
+                       die(_("--long and -z are incompatible"));
+       }
+
+       if (use_deferred_config && status_format == STATUS_FORMAT_UNSPECIFIED)
+               status_format = status_deferred_config.status_format;
+       if (status_format == STATUS_FORMAT_UNSPECIFIED)
+               status_format = STATUS_FORMAT_NONE;
+
+       if (use_deferred_config && s->show_branch < 0)
+               s->show_branch = status_deferred_config.show_branch;
+       if (s->show_branch < 0)
+               s->show_branch = 0;
+}
+
 static int parse_and_validate_options(int argc, const char *argv[],
                                      const struct option *options,
                                      const char * const usage[],
@@ -968,6 +1012,7 @@ static int parse_and_validate_options(int argc, const char *argv[],
        int f = 0;
 
        argc = parse_options(argc, argv, prefix, options, usage, 0);
+       finalize_deferred_config(s);
 
        if (force_author && !strchr(force_author, '>'))
                force_author = find_author_by_nickname(force_author);
@@ -975,7 +1020,7 @@ static int parse_and_validate_options(int argc, const char *argv[],
        if (force_author && renew_authorship)
                die(_("Using both --reset-author and --author does not make sense"));
 
-       if (logfile || message.len || use_message || fixup_message)
+       if (logfile || have_option_m || use_message || fixup_message)
                use_editor = 0;
        if (0 <= edit_flag)
                use_editor = edit_flag;
@@ -1052,12 +1097,6 @@ static int parse_and_validate_options(int argc, const char *argv[],
        if (all && argc > 0)
                die(_("Paths with -a does not make sense."));
 
-       if (s->null_termination) {
-               if (status_format == STATUS_FORMAT_NONE)
-                       status_format = STATUS_FORMAT_PORCELAIN;
-               else if (status_format == STATUS_FORMAT_LONG)
-                       die(_("--long and -z are incompatible"));
-       }
        if (status_format != STATUS_FORMAT_NONE)
                dry_run = 1;
 
@@ -1110,6 +1149,17 @@ static int git_status_config(const char *k, const char *v, void *cb)
                        s->submodule_summary = -1;
                return 0;
        }
+       if (!strcmp(k, "status.short")) {
+               if (git_config_bool(k, v))
+                       status_deferred_config.status_format = STATUS_FORMAT_SHORT;
+               else
+                       status_deferred_config.status_format = STATUS_FORMAT_NONE;
+               return 0;
+       }
+       if (!strcmp(k, "status.branch")) {
+               status_deferred_config.show_branch = git_config_bool(k, v);
+               return 0;
+       }
        if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
                s->use_color = git_config_colorbool(k, v);
                return 0;
@@ -1152,8 +1202,8 @@ int cmd_status(int argc, const char **argv, const char *prefix)
                OPT__VERBOSE(&verbose, N_("be verbose")),
                OPT_SET_INT('s', "short", &status_format,
                            N_("show status concisely"), STATUS_FORMAT_SHORT),
-               OPT_BOOLEAN('b', "branch", &s.show_branch,
-                           N_("show branch information")),
+               OPT_BOOL('b', "branch", &s.show_branch,
+                        N_("show branch information")),
                OPT_SET_INT(0, "porcelain", &status_format,
                            N_("machine-readable output"),
                            STATUS_FORMAT_PORCELAIN),
@@ -1186,13 +1236,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
                             builtin_status_options,
                             builtin_status_usage, 0);
        finalize_colopts(&s.colopts, -1);
-
-       if (s.null_termination) {
-               if (status_format == STATUS_FORMAT_NONE)
-                       status_format = STATUS_FORMAT_PORCELAIN;
-               else if (status_format == STATUS_FORMAT_LONG)
-                       die(_("--long and -z are incompatible"));
-       }
+       finalize_deferred_config(&s);
 
        handle_untracked_files_arg(&s);
        if (show_ignored_in_status)
@@ -1221,6 +1265,9 @@ int cmd_status(int argc, const char **argv, const char *prefix)
        case STATUS_FORMAT_PORCELAIN:
                wt_porcelain_print(&s);
                break;
+       case STATUS_FORMAT_UNSPECIFIED:
+               die("BUG: finalize_deferred_config() should have been called");
+               break;
        case STATUS_FORMAT_NONE:
        case STATUS_FORMAT_LONG:
                s.verbose = verbose;
@@ -1389,7 +1436,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
                OPT_BOOLEAN(0, "dry-run", &dry_run, N_("show what would be committed")),
                OPT_SET_INT(0, "short", &status_format, N_("show status concisely"),
                            STATUS_FORMAT_SHORT),
-               OPT_BOOLEAN(0, "branch", &s.show_branch, N_("show branch information")),
+               OPT_BOOL(0, "branch", &s.show_branch, N_("show branch information")),
                OPT_SET_INT(0, "porcelain", &status_format,
                            N_("machine-readable output"), STATUS_FORMAT_PORCELAIN),
                OPT_SET_INT(0, "long", &status_format,
@@ -1430,6 +1477,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
        wt_status_prepare(&s);
        gitmodules_config();
        git_config(git_commit_config, &s);
+       status_format = STATUS_FORMAT_NONE; /* Ignore status.short */
        determine_whence(&s);
        s.colopts = 0;
 
@@ -1591,7 +1639,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
                if (cfg) {
                        /* we are amending, so current_head is not NULL */
                        copy_note_for_rewrite(cfg, current_head->object.sha1, sha1);
-                       finish_copy_notes_for_rewrite(cfg);
+                       finish_copy_notes_for_rewrite(cfg, "Notes added by 'git commit --amend'");
                }
                run_rewrite_hook(current_head->object.sha1, sha1);
        }
index 33c9bf9..7759671 100644 (file)
@@ -329,6 +329,7 @@ static int get_colorbool(int print)
 {
        get_colorbool_found = -1;
        get_diff_color_found = -1;
+       get_color_ui_found = -1;
        git_config_with_options(git_get_colorbool_config, NULL,
                                given_config_file, respect_includes);
 
@@ -339,6 +340,10 @@ static int get_colorbool(int print)
                        get_colorbool_found = get_color_ui_found;
        }
 
+       if (get_colorbool_found < 0)
+               /* default value if none found in config */
+               get_colorbool_found = GIT_COLOR_AUTO;
+
        get_colorbool_found = want_color(get_colorbool_found);
 
        if (print) {
@@ -379,8 +384,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
                         */
                        die("$HOME not set");
 
-               if (access_or_warn(user_config, R_OK) &&
-                   xdg_config && !access_or_warn(xdg_config, R_OK))
+               if (access_or_warn(user_config, R_OK, 0) &&
+                   xdg_config && !access_or_warn(xdg_config, R_OK, 0))
                        given_config_file = xdg_config;
                else
                        given_config_file = user_config;
index 6636a68..4e675c3 100644 (file)
@@ -21,6 +21,7 @@ static int debug;     /* Display lots of verbose info */
 static int all;        /* Any valid ref can be used */
 static int tags;       /* Allow lightweight tags */
 static int longformat;
+static int first_parent;
 static int abbrev = -1; /* unspecified */
 static int max_candidates = 10;
 static struct hash_table names;
@@ -42,7 +43,7 @@ struct commit_name {
        unsigned prio:2; /* annotated tag = 2, tag = 1, head = 0 */
        unsigned name_checked:1;
        unsigned char sha1[20];
-       const char *path;
+       char *path;
 };
 static const char *prio_names[] = {
        "head", "lightweight", "annotated",
@@ -126,12 +127,14 @@ static void add_to_known_names(const char *path,
                        } else {
                                e->next = NULL;
                        }
+                       e->path = NULL;
                }
                e->tag = tag;
                e->prio = prio;
                e->name_checked = 0;
                hashcpy(e->sha1, sha1);
-               e->path = path;
+               free(e->path);
+               e->path = xstrdup(path);
        }
 }
 
@@ -336,6 +339,9 @@ static void describe(const char *arg, int last_one)
                                commit_list_insert_by_date(p, &list);
                        p->object.flags |= c->object.flags;
                        parents = parents->next;
+
+                       if (first_parent)
+                               break;
                }
        }
 
@@ -404,6 +410,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
                OPT_BOOLEAN(0, "all",        &all, N_("use any ref")),
                OPT_BOOLEAN(0, "tags",       &tags, N_("use any tag, even unannotated")),
                OPT_BOOLEAN(0, "long",       &longformat, N_("always use long format")),
+               OPT_BOOLEAN(0, "first-parent", &first_parent, N_("only follow first parent")),
                OPT__ABBREV(&abbrev),
                OPT_SET_INT(0, "exact-match", &max_candidates,
                            N_("only output exact matches"), 0),
index 8c2af6c..9fc273d 100644 (file)
@@ -153,7 +153,8 @@ static int builtin_diff_index(struct rev_info *revs,
 
 static int builtin_diff_tree(struct rev_info *revs,
                             int argc, const char **argv,
-                            struct object_array_entry *ent)
+                            struct object_array_entry *ent0,
+                            struct object_array_entry *ent1)
 {
        const unsigned char *(sha1[2]);
        int swap = 0;
@@ -161,13 +162,14 @@ static int builtin_diff_tree(struct rev_info *revs,
        if (argc > 1)
                usage(builtin_diff_usage);
 
-       /* We saw two trees, ent[0] and ent[1].
-        * if ent[1] is uninteresting, they are swapped
+       /*
+        * We saw two trees, ent0 and ent1.  If ent1 is uninteresting,
+        * swap them.
         */
-       if (ent[1].item->flags & UNINTERESTING)
+       if (ent1->item->flags & UNINTERESTING)
                swap = 1;
-       sha1[swap] = ent[0].item->sha1;
-       sha1[1-swap] = ent[1].item->sha1;
+       sha1[swap] = ent0->item->sha1;
+       sha1[1-swap] = ent1->item->sha1;
        diff_tree_sha1(sha1[0], sha1[1], "", &revs->diffopt);
        log_tree_diff_flush(revs);
        return 0;
@@ -251,8 +253,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
 {
        int i;
        struct rev_info rev;
-       struct object_array_entry ent[100];
-       int ents = 0, blobs = 0, paths = 0;
+       struct object_array ent = OBJECT_ARRAY_INIT;
+       int blobs = 0, paths = 0;
        const char *path = NULL;
        struct blobinfo blob[2];
        int nongit;
@@ -337,9 +339,9 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
        }
 
        for (i = 0; i < rev.pending.nr; i++) {
-               struct object_array_entry *list = rev.pending.objects+i;
-               struct object *obj = list->item;
-               const char *name = list->name;
+               struct object_array_entry *entry = &rev.pending.objects[i];
+               struct object *obj = entry->item;
+               const char *name = entry->name;
                int flags = (obj->flags & UNINTERESTING);
                if (!obj->parsed)
                        obj = parse_object(obj->sha1);
@@ -348,27 +350,21 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
                        die(_("invalid object '%s' given."), name);
                if (obj->type == OBJ_COMMIT)
                        obj = &((struct commit *)obj)->tree->object;
+
                if (obj->type == OBJ_TREE) {
-                       if (ARRAY_SIZE(ent) <= ents)
-                               die(_("more than %d trees given: '%s'"),
-                                   (int) ARRAY_SIZE(ent), name);
                        obj->flags |= flags;
-                       ent[ents].item = obj;
-                       ent[ents].name = name;
-                       ents++;
-                       continue;
-               }
-               if (obj->type == OBJ_BLOB) {
+                       add_object_array(obj, name, &ent);
+               } else if (obj->type == OBJ_BLOB) {
                        if (2 <= blobs)
                                die(_("more than two blobs given: '%s'"), name);
                        hashcpy(blob[blobs].sha1, obj->sha1);
                        blob[blobs].name = name;
-                       blob[blobs].mode = list->mode;
+                       blob[blobs].mode = entry->mode;
                        blobs++;
-                       continue;
 
+               } else {
+                       die(_("unhandled object '%s' given."), name);
                }
-               die(_("unhandled object '%s' given."), name);
        }
        if (rev.prune_data.nr) {
                if (!path)
@@ -379,7 +375,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
        /*
         * Now, do the arguments look reasonable?
         */
-       if (!ents) {
+       if (!ent.nr) {
                switch (blobs) {
                case 0:
                        result = builtin_diff_files(&rev, argc, argv);
@@ -400,23 +396,26 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
        }
        else if (blobs)
                usage(builtin_diff_usage);
-       else if (ents == 1)
+       else if (ent.nr == 1)
                result = builtin_diff_index(&rev, argc, argv);
-       else if (ents == 2)
-               result = builtin_diff_tree(&rev, argc, argv, ent);
-       else if (ent[0].item->flags & UNINTERESTING) {
+       else if (ent.nr == 2)
+               result = builtin_diff_tree(&rev, argc, argv,
+                                          &ent.objects[0], &ent.objects[1]);
+       else if (ent.objects[0].item->flags & UNINTERESTING) {
                /*
                 * diff A...B where there is at least one merge base
-                * between A and B.  We have ent[0] == merge-base,
-                * ent[ents-2] == A, and ent[ents-1] == B.  Show diff
-                * between the base and B.  Note that we pick one
-                * merge base at random if there are more than one.
+                * between A and B.  We have ent.objects[0] ==
+                * merge-base, ent.objects[ents-2] == A, and
+                * ent.objects[ents-1] == B.  Show diff between the
+                * base and B.  Note that we pick one merge base at
+                * random if there are more than one.
                 */
-               ent[1] = ent[ents-1];
-               result = builtin_diff_tree(&rev, argc, argv, ent);
+               result = builtin_diff_tree(&rev, argc, argv,
+                                          &ent.objects[0],
+                                          &ent.objects[ent.nr-1]);
        } else
                result = builtin_diff_combined(&rev, argc, argv,
-                                              ent, ents);
+                                              ent.objects, ent.nr);
        result = diff_result_code(&rev.diffopt, result);
        if (1 < rev.diffopt.skip_stat_unmatch)
                refresh_index_quietly();
index d60d675..d1d68e9 100644 (file)
@@ -613,6 +613,8 @@ static void import_marks(char *input_file)
                char *line_end, *mark_end;
                unsigned char sha1[20];
                struct object *object;
+               struct commit *commit;
+               enum object_type type;
 
                line_end = strchr(line, '\n');
                if (line[0] != ':' || !line_end)
@@ -621,23 +623,29 @@ static void import_marks(char *input_file)
 
                mark = strtoumax(line + 1, &mark_end, 10);
                if (!mark || mark_end == line + 1
-                       || *mark_end != ' ' || get_sha1(mark_end + 1, sha1))
+                       || *mark_end != ' ' || get_sha1_hex(mark_end + 1, sha1))
                        die("corrupt mark line: %s", line);
 
                if (last_idnum < mark)
                        last_idnum = mark;
 
-               object = parse_object(sha1);
-               if (!object)
+               type = sha1_object_info(sha1, NULL);
+               if (type < 0)
+                       die("object not found: %s", sha1_to_hex(sha1));
+
+               if (type != OBJ_COMMIT)
+                       /* only commits */
                        continue;
 
+               commit = lookup_commit(sha1);
+               if (!commit)
+                       die("not a commit? can't happen: %s", sha1_to_hex(sha1));
+
+               object = &commit->object;
+
                if (object->flags & SHOWN)
                        error("Object %s already has a mark", sha1_to_hex(sha1));
 
-               if (object->type != OBJ_COMMIT)
-                       /* only commits */
-                       continue;
-
                mark_object(object, mark);
 
                object->flags |= SHOWN;
index 4b6b1df..d784b2e 100644 (file)
@@ -119,7 +119,7 @@ static void add_merge_config(struct ref **head,
 
                for (rm = *head; rm; rm = rm->next) {
                        if (branch_merge_matches(branch, i, rm->name)) {
-                               rm->merge = 1;
+                               rm->fetch_head_status = FETCH_HEAD_MERGE;
                                break;
                        }
                }
@@ -140,7 +140,7 @@ static void add_merge_config(struct ref **head,
                refspec.src = branch->merge[i]->src;
                get_fetch_map(remote_refs, &refspec, tail, 1);
                for (rm = *old_tail; rm; rm = rm->next)
-                       rm->merge = 1;
+                       rm->fetch_head_status = FETCH_HEAD_MERGE;
        }
 }
 
@@ -160,6 +160,8 @@ static struct ref *get_ref_map(struct transport *transport,
        const struct ref *remote_refs = transport_get_remote_refs(transport);
 
        if (ref_count || tags == TAGS_SET) {
+               struct ref **old_tail;
+
                for (i = 0; i < ref_count; i++) {
                        get_fetch_map(remote_refs, &refs[i], &tail, 0);
                        if (refs[i].dst && refs[i].dst[0])
@@ -167,9 +169,23 @@ static struct ref *get_ref_map(struct transport *transport,
                }
                /* Merge everything on the command line, but not --tags */
                for (rm = ref_map; rm; rm = rm->next)
-                       rm->merge = 1;
+                       rm->fetch_head_status = FETCH_HEAD_MERGE;
                if (tags == TAGS_SET)
                        get_fetch_map(remote_refs, tag_refspec, &tail, 0);
+
+               /*
+                * For any refs that we happen to be fetching via command-line
+                * arguments, take the opportunity to update their configured
+                * counterparts. However, we do not want to mention these
+                * entries in FETCH_HEAD at all, as they would simply be
+                * duplicates of existing entries.
+                */
+               old_tail = tail;
+               for (i = 0; i < transport->remote->fetch_refspec_nr; i++)
+                       get_fetch_map(ref_map, &transport->remote->fetch[i],
+                                     &tail, 1);
+               for (rm = *old_tail; rm; rm = rm->next)
+                       rm->fetch_head_status = FETCH_HEAD_IGNORE;
        } else {
                /* Use the defaults */
                struct remote *remote = transport->remote;
@@ -186,7 +202,7 @@ static struct ref *get_ref_map(struct transport *transport,
                                        *autotags = 1;
                                if (!i && !has_merge && ref_map &&
                                    !remote->fetch[0].pattern)
-                                       ref_map->merge = 1;
+                                       ref_map->fetch_head_status = FETCH_HEAD_MERGE;
                        }
                        /*
                         * if the remote we're fetching from is the same
@@ -202,7 +218,7 @@ static struct ref *get_ref_map(struct transport *transport,
                        ref_map = get_remote_ref(remote_refs, "HEAD");
                        if (!ref_map)
                                die(_("Couldn't find remote ref HEAD"));
-                       ref_map->merge = 1;
+                       ref_map->fetch_head_status = FETCH_HEAD_MERGE;
                        tail = &ref_map->next;
                }
        }
@@ -389,7 +405,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
        const char *what, *kind;
        struct ref *rm;
        char *url, *filename = dry_run ? "/dev/null" : git_path("FETCH_HEAD");
-       int want_merge;
+       int want_status;
 
        fp = fopen(filename, "a");
        if (!fp)
@@ -407,19 +423,22 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
        }
 
        /*
-        * The first pass writes objects to be merged and then the
-        * second pass writes the rest, in order to allow using
-        * FETCH_HEAD as a refname to refer to the ref to be merged.
+        * We do a pass for each fetch_head_status type in their enum order, so
+        * merged entries are written before not-for-merge. That lets readers
+        * use FETCH_HEAD as a refname to refer to the ref to be merged.
         */
-       for (want_merge = 1; 0 <= want_merge; want_merge--) {
+       for (want_status = FETCH_HEAD_MERGE;
+            want_status <= FETCH_HEAD_IGNORE;
+            want_status++) {
                for (rm = ref_map; rm; rm = rm->next) {
                        struct ref *ref = NULL;
+                       const char *merge_status_marker = "";
 
                        commit = lookup_commit_reference_gently(rm->old_sha1, 1);
                        if (!commit)
-                               rm->merge = 0;
+                               rm->fetch_head_status = FETCH_HEAD_NOT_FOR_MERGE;
 
-                       if (rm->merge != want_merge)
+                       if (rm->fetch_head_status != want_status)
                                continue;
 
                        if (rm->peer_ref) {
@@ -465,16 +484,26 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
                                        strbuf_addf(&note, "%s ", kind);
                                strbuf_addf(&note, "'%s' of ", what);
                        }
-                       fprintf(fp, "%s\t%s\t%s",
-                               sha1_to_hex(rm->old_sha1),
-                               rm->merge ? "" : "not-for-merge",
-                               note.buf);
-                       for (i = 0; i < url_len; ++i)
-                               if ('\n' == url[i])
-                                       fputs("\\n", fp);
-                               else
-                                       fputc(url[i], fp);
-                       fputc('\n', fp);
+                       switch (rm->fetch_head_status) {
+                       case FETCH_HEAD_NOT_FOR_MERGE:
+                               merge_status_marker = "not-for-merge";
+                               /* fall-through */
+                       case FETCH_HEAD_MERGE:
+                               fprintf(fp, "%s\t%s\t%s",
+                                       sha1_to_hex(rm->old_sha1),
+                                       merge_status_marker,
+                                       note.buf);
+                               for (i = 0; i < url_len; ++i)
+                                       if ('\n' == url[i])
+                                               fputs("\\n", fp);
+                                       else
+                                               fputc(url[i], fp);
+                               fputc('\n', fp);
+                               break;
+                       default:
+                               /* do not write anything to FETCH_HEAD */
+                               break;
+                       }
 
                        strbuf_reset(&note);
                        if (ref) {
@@ -571,7 +600,8 @@ static int add_existing(const char *refname, const unsigned char *sha1,
 {
        struct string_list *list = (struct string_list *)cbdata;
        struct string_list_item *item = string_list_insert(list, refname);
-       item->util = (void *)sha1;
+       item->util = xmalloc(20);
+       hashcpy(item->util, sha1);
        return 0;
 }
 
@@ -590,7 +620,7 @@ static void find_non_local_tags(struct transport *transport,
                        struct ref **head,
                        struct ref ***tail)
 {
-       struct string_list existing_refs = STRING_LIST_INIT_NODUP;
+       struct string_list existing_refs = STRING_LIST_INIT_DUP;
        struct string_list remote_refs = STRING_LIST_INIT_NODUP;
        const struct ref *ref;
        struct string_list_item *item = NULL;
@@ -636,7 +666,7 @@ static void find_non_local_tags(struct transport *transport,
                item = string_list_insert(&remote_refs, ref->name);
                item->util = (void *)ref->old_sha1;
        }
-       string_list_clear(&existing_refs, 0);
+       string_list_clear(&existing_refs, 1);
 
        /*
         * We may have a final lightweight tag that needs to be
@@ -693,11 +723,11 @@ static int truncate_fetch_head(void)
 static int do_fetch(struct transport *transport,
                    struct refspec *refs, int ref_count)
 {
-       struct string_list existing_refs = STRING_LIST_INIT_NODUP;
-       struct string_list_item *peer_item = NULL;
+       struct string_list existing_refs = STRING_LIST_INIT_DUP;
        struct ref *ref_map;
        struct ref *rm;
        int autotags = (transport->remote->fetch_tags == 1);
+       int retcode = 0;
 
        for_each_ref(add_existing, &existing_refs);
 
@@ -713,9 +743,9 @@ static int do_fetch(struct transport *transport,
 
        /* if not appending, truncate FETCH_HEAD */
        if (!append && !dry_run) {
-               int errcode = truncate_fetch_head();
-               if (errcode)
-                       return errcode;
+               retcode = truncate_fetch_head();
+               if (retcode)
+                       goto cleanup;
        }
 
        ref_map = get_ref_map(transport, refs, ref_count, tags, &autotags);
@@ -724,8 +754,9 @@ static int do_fetch(struct transport *transport,
 
        for (rm = ref_map; rm; rm = rm->next) {
                if (rm->peer_ref) {
-                       peer_item = string_list_lookup(&existing_refs,
-                                                      rm->peer_ref->name);
+                       struct string_list_item *peer_item =
+                               string_list_lookup(&existing_refs,
+                                                  rm->peer_ref->name);
                        if (peer_item)
                                hashcpy(rm->peer_ref->old_sha1,
                                        peer_item->util);
@@ -736,7 +767,8 @@ static int do_fetch(struct transport *transport,
                transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, "1");
        if (fetch_refs(transport, ref_map)) {
                free_refs(ref_map);
-               return 1;
+               retcode = 1;
+               goto cleanup;
        }
        if (prune) {
                /* If --tags was specified, pretend the user gave us the canonical tags refspec */
@@ -779,7 +811,9 @@ static int do_fetch(struct transport *transport,
                free_refs(ref_map);
        }
 
-       return 0;
+ cleanup:
+       string_list_clear(&existing_refs, 1);
+       return retcode;
 }
 
 static void set_option(const char *name, const char *value)
index bb9a2cd..9909b6d 100644 (file)
@@ -112,7 +112,7 @@ static int mark_object(struct object *obj, int type, void *data)
                return 1;
        }
 
-       add_object_array(obj, (void *) parent, &pending);
+       add_object_array(obj, NULL, &pending);
        return 0;
 }
 
index 062957f..f1e236b 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * builtin-help.c
- *
  * Builtin help command
  */
 #include "cache.h"
index 79dfe47..9c1cfac 100644 (file)
@@ -77,8 +77,10 @@ static int nr_threads;
 
 static int from_stdin;
 static int strict;
+static int do_fsck_object;
 static int verbose;
 static int show_stat;
+static int check_self_contained_and_connected;
 
 static struct progress *progress;
 
@@ -187,13 +189,13 @@ static int mark_link(struct object *obj, int type, void *data)
 
 /* The content of each linked object must have been checked
    or it must be already present in the object database */
-static void check_object(struct object *obj)
+static unsigned check_object(struct object *obj)
 {
        if (!obj)
-               return;
+               return 0;
 
        if (!(obj->flags & FLAG_LINK))
-               return;
+               return 0;
 
        if (!(obj->flags & FLAG_CHECKED)) {
                unsigned long size;
@@ -201,17 +203,20 @@ static void check_object(struct object *obj)
                if (type != obj->type || type <= 0)
                        die(_("object of unexpected type"));
                obj->flags |= FLAG_CHECKED;
-               return;
+               return 1;
        }
+
+       return 0;
 }
 
-static void check_objects(void)
+static unsigned check_objects(void)
 {
-       unsigned i, max;
+       unsigned i, max, foreign_nr = 0;
 
        max = get_max_object_index();
        for (i = 0; i < max; i++)
-               check_object(get_indexed_object(i));
+               foreign_nr += check_object(get_indexed_object(i));
+       return foreign_nr;
 }
 
 
@@ -747,8 +752,7 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
                        int eaten;
                        void *buf = (void *) data;
 
-                       if (!buf)
-                               buf = new_data = get_data_from_pack(obj_entry);
+                       assert(data && "data can only be NULL for large _blobs_");
 
                        /*
                         * we do not need to free the memory here, as the
@@ -757,7 +761,8 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
                        obj = parse_object_buffer(sha1, type, size, buf, &eaten);
                        if (!obj)
                                die(_("invalid %s"), typename(type));
-                       if (fsck_object(obj, 1, fsck_error_function))
+                       if (do_fsck_object &&
+                           fsck_object(obj, 1, fsck_error_function))
                                die(_("Error in object"));
                        if (fsck_walk(obj, mark_link, NULL))
                                die(_("Not all child objects of %s are reachable"), sha1_to_hex(obj->sha1));
@@ -1491,6 +1496,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
        struct pack_idx_entry **idx_objects;
        struct pack_idx_option opts;
        unsigned char pack_sha1[20];
+       unsigned foreign_nr = 1;        /* zero is a "good" value, assume bad */
 
        if (argc == 2 && !strcmp(argv[1], "-h"))
                usage(index_pack_usage);
@@ -1512,6 +1518,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
                                fix_thin_pack = 1;
                        } else if (!strcmp(arg, "--strict")) {
                                strict = 1;
+                               do_fsck_object = 1;
+                       } else if (!strcmp(arg, "--check-self-contained-and-connected")) {
+                               strict = 1;
+                               check_self_contained_and_connected = 1;
                        } else if (!strcmp(arg, "--verify")) {
                                verify = 1;
                        } else if (!strcmp(arg, "--verify-stat")) {
@@ -1625,7 +1635,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
        conclude_pack(fix_thin_pack, curr_pack, pack_sha1);
        free(deltas);
        if (strict)
-               check_objects();
+               foreign_nr = check_objects();
 
        if (show_stat)
                show_pack_info(stat_only);
@@ -1651,5 +1661,11 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
        if (index_name == NULL)
                free((void *) curr_index);
 
+       /*
+        * Let the caller know this pack is not self contained
+        */
+       if (check_self_contained_and_connected && foreign_nr)
+               return 1;
+
        return 0;
 }
index 6e56a50..e3222ed 100644 (file)
@@ -19,6 +19,7 @@
 #include "remote.h"
 #include "string-list.h"
 #include "parse-options.h"
+#include "line-log.h"
 #include "branch.h"
 #include "streaming.h"
 #include "version.h"
@@ -42,6 +43,12 @@ static const char * const builtin_log_usage[] = {
        NULL
 };
 
+struct line_opt_callback_data {
+       struct rev_info *rev;
+       const char *prefix;
+       struct string_list args;
+};
+
 static int parse_decoration_style(const char *var, const char *value)
 {
        switch (git_config_maybe_bool(var, value)) {
@@ -76,6 +83,19 @@ static int decorate_callback(const struct option *opt, const char *arg, int unse
        return 0;
 }
 
+static int log_line_range_callback(const struct option *option, const char *arg, int unset)
+{
+       struct line_opt_callback_data *data = option->value;
+
+       if (!arg)
+               return -1;
+
+       data->rev->line_level_traverse = 1;
+       string_list_append(&data->args, arg);
+
+       return 0;
+}
+
 static void cmd_log_init_defaults(struct rev_info *rev)
 {
        if (fmt_pretty)
@@ -98,6 +118,7 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
 {
        struct userformat_want w;
        int quiet = 0, source = 0, mailmap = 0;
+       static struct line_opt_callback_data line_cb = {NULL, NULL, STRING_LIST_INIT_DUP};
 
        const struct option builtin_log_options[] = {
                OPT_BOOL(0, "quiet", &quiet, N_("suppress diff output")),
@@ -105,9 +126,15 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
                OPT_BOOL(0, "use-mailmap", &mailmap, N_("Use mail map file")),
                { OPTION_CALLBACK, 0, "decorate", NULL, NULL, N_("decorate options"),
                  PARSE_OPT_OPTARG, decorate_callback},
+               OPT_CALLBACK('L', NULL, &line_cb, "n,m:file",
+                            "Process line range n,m in file, counting from 1",
+                            log_line_range_callback),
                OPT_END()
        };
 
+       line_cb.rev = rev;
+       line_cb.prefix = prefix;
+
        mailmap = use_mailmap_config;
        argc = parse_options(argc, argv, prefix,
                             builtin_log_options, builtin_log_usage,
@@ -161,6 +188,10 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
                rev->show_decorations = 1;
                load_ref_decorations(decoration_style);
        }
+
+       if (rev->line_level_traverse)
+               line_log_init(rev, line_cb.prefix, &line_cb.args);
+
        setup_pager();
 }
 
@@ -206,7 +237,7 @@ static void log_show_early(struct rev_info *revs, struct commit_list *list)
        int i = revs->early_output;
        int show_header = 1;
 
-       sort_in_topological_order(&list, revs->lifo);
+       sort_in_topological_order(&list, revs->sort_order);
        while (list && i) {
                struct commit *commit = list->item;
                switch (simplify_commit(revs, commit)) {
index 2202072..3a410c3 100644 (file)
@@ -165,11 +165,13 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce)
        }
        write_name(ce->name, ce_namelen(ce));
        if (debug_mode) {
-               printf("  ctime: %d:%d\n", ce->ce_ctime.sec, ce->ce_ctime.nsec);
-               printf("  mtime: %d:%d\n", ce->ce_mtime.sec, ce->ce_mtime.nsec);
-               printf("  dev: %d\tino: %d\n", ce->ce_dev, ce->ce_ino);
-               printf("  uid: %d\tgid: %d\n", ce->ce_uid, ce->ce_gid);
-               printf("  size: %d\tflags: %x\n", ce->ce_size, ce->ce_flags);
+               struct stat_data *sd = &ce->ce_stat_data;
+
+               printf("  ctime: %d:%d\n", sd->sd_ctime.sec, sd->sd_ctime.nsec);
+               printf("  mtime: %d:%d\n", sd->sd_mtime.sec, sd->sd_mtime.nsec);
+               printf("  dev: %d\tino: %d\n", sd->sd_dev, sd->sd_ino);
+               printf("  uid: %d\tgid: %d\n", sd->sd_uid, sd->sd_gid);
+               printf("  size: %d\tflags: %x\n", sd->sd_size, ce->ce_flags);
        }
 }
 
@@ -219,7 +221,7 @@ static void show_files(struct dir_struct *dir)
                if (show_killed)
                        show_killed_files(dir);
        }
-       if (show_cached | show_stage) {
+       if (show_cached || show_stage) {
                for (i = 0; i < active_nr; i++) {
                        struct cache_entry *ce = active_cache[i];
                        if ((dir->flags & DIR_SHOW_IGNORED) &&
@@ -233,7 +235,7 @@ static void show_files(struct dir_struct *dir)
                                (ce_skip_worktree(ce) ? tag_skip_worktree : tag_cached), ce);
                }
        }
-       if (show_deleted | show_modified) {
+       if (show_deleted || show_modified) {
                for (i = 0; i < active_nr; i++) {
                        struct cache_entry *ce = active_cache[i];
                        struct stat st;
@@ -571,8 +573,8 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
                die("ls-files --ignored needs some exclude pattern");
 
        /* With no flags, we default to showing the cached files */
-       if (!(show_stage | show_deleted | show_others | show_unmerged |
-             show_killed | show_modified | show_resolve_undo))
+       if (!(show_stage || show_deleted || show_others || show_unmerged ||
+             show_killed || show_modified || show_resolve_undo))
                show_cached = 1;
 
        if (max_prefix)
index 1bc7991..0c4cd2f 100644 (file)
@@ -107,7 +107,7 @@ int cmd_merge_base(int argc, const char **argv, const char *prefix)
        argc = parse_options(argc, argv, prefix, options, merge_base_usage, 0);
        if (!octopus && !reduce && argc < 2)
                usage_with_options(merge_base_usage, options);
-       if (is_ancestor && (show_all | octopus | reduce))
+       if (is_ancestor && (show_all || octopus || reduce))
                die("--is-ancestor cannot be used with other options");
        if (is_ancestor)
                return handle_is_ancestor(argc, argv);
index 3e2daa3..2ebe732 100644 (file)
@@ -1054,7 +1054,8 @@ static struct commit_list *collect_parents(struct commit *head_commit,
        for (i = 0; i < argc; i++) {
                struct commit *commit = get_merge_parent(argv[i]);
                if (!commit)
-                       die(_("%s - not something we can merge"), argv[i]);
+                       help_unknown_ref(argv[i], "merge",
+                                        "not something we can merge");
                remotes = &commit_list_insert(commit, remotes)->next;
        }
        *remotes = NULL;
index 6238247..87d4854 100644 (file)
@@ -82,6 +82,20 @@ copy_data:
        }
 }
 
+static int subpath_matches(const char *path, const char *filter)
+{
+       const char *subpath = path;
+
+       while (subpath) {
+               if (!fnmatch(filter, subpath, 0))
+                       return subpath - path;
+               subpath = strchr(subpath, '/');
+               if (subpath)
+                       subpath++;
+       }
+       return -1;
+}
+
 struct name_ref_data {
        int tags_only;
        int name_only;
@@ -92,13 +106,23 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void
 {
        struct object *o = parse_object(sha1);
        struct name_ref_data *data = cb_data;
+       int can_abbreviate_output = data->tags_only && data->name_only;
        int deref = 0;
 
        if (data->tags_only && prefixcmp(path, "refs/tags/"))
                return 0;
 
-       if (data->ref_filter && fnmatch(data->ref_filter, path, 0))
-               return 0;
+       if (data->ref_filter) {
+               switch (subpath_matches(path, data->ref_filter)) {
+               case -1: /* did not match */
+                       return 0;
+               case 0:  /* matched fully */
+                       break;
+               default: /* matched subpath */
+                       can_abbreviate_output = 1;
+                       break;
+               }
+       }
 
        while (o && o->type == OBJ_TAG) {
                struct tag *t = (struct tag *) o;
@@ -110,12 +134,10 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void
        if (o && o->type == OBJ_COMMIT) {
                struct commit *commit = (struct commit *)o;
 
-               if (!prefixcmp(path, "refs/heads/"))
+               if (can_abbreviate_output)
+                       path = shorten_unambiguous_ref(path, 0);
+               else if (!prefixcmp(path, "refs/heads/"))
                        path = path + 11;
-               else if (data->tags_only
-                   && data->name_only
-                   && !prefixcmp(path, "refs/tags/"))
-                       path = path + 10;
                else if (!prefixcmp(path, "refs/"))
                        path = path + 5;
 
index 57748a6..e4100c4 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 2010 Johan Herland <johan@herland.net>
  *
  * Based on git-notes.sh by Johannes Schindelin,
- * and builtin-tag.c by Kristian Høgsberg and Carlos Rica.
+ * and builtin/tag.c by Kristian Høgsberg and Carlos Rica.
  */
 
 #include "cache.h"
@@ -18,9 +18,7 @@
 #include "parse-options.h"
 #include "string-list.h"
 #include "notes-merge.h"
-
-static void commit_notes(struct notes_tree *t, const char *msg);
-static combine_notes_fn parse_combine_notes_fn(const char *v);
+#include "notes-utils.h"
 
 static const char * const git_notes_usage[] = {
        N_("git notes [--ref <notes_ref>] [list [<object>]]"),
@@ -287,139 +285,13 @@ static int parse_reedit_arg(const struct option *opt, const char *arg, int unset
        return parse_reuse_arg(opt, arg, unset);
 }
 
-static void commit_notes(struct notes_tree *t, const char *msg)
-{
-       struct strbuf buf = STRBUF_INIT;
-       unsigned char commit_sha1[20];
-
-       if (!t)
-               t = &default_notes_tree;
-       if (!t->initialized || !t->ref || !*t->ref)
-               die(_("Cannot commit uninitialized/unreferenced notes tree"));
-       if (!t->dirty)
-               return; /* don't have to commit an unchanged tree */
-
-       /* Prepare commit message and reflog message */
-       strbuf_addstr(&buf, msg);
-       if (buf.buf[buf.len - 1] != '\n')
-               strbuf_addch(&buf, '\n'); /* Make sure msg ends with newline */
-
-       create_notes_commit(t, NULL, &buf, commit_sha1);
-       strbuf_insert(&buf, 0, "notes: ", 7); /* commit message starts at index 7 */
-       update_ref(buf.buf, t->ref, commit_sha1, NULL, 0, DIE_ON_ERR);
-
-       strbuf_release(&buf);
-}
-
-static combine_notes_fn parse_combine_notes_fn(const char *v)
-{
-       if (!strcasecmp(v, "overwrite"))
-               return combine_notes_overwrite;
-       else if (!strcasecmp(v, "ignore"))
-               return combine_notes_ignore;
-       else if (!strcasecmp(v, "concatenate"))
-               return combine_notes_concatenate;
-       else if (!strcasecmp(v, "cat_sort_uniq"))
-               return combine_notes_cat_sort_uniq;
-       else
-               return NULL;
-}
-
-static int notes_rewrite_config(const char *k, const char *v, void *cb)
-{
-       struct notes_rewrite_cfg *c = cb;
-       if (!prefixcmp(k, "notes.rewrite.") && !strcmp(k+14, c->cmd)) {
-               c->enabled = git_config_bool(k, v);
-               return 0;
-       } else if (!c->mode_from_env && !strcmp(k, "notes.rewritemode")) {
-               if (!v)
-                       config_error_nonbool(k);
-               c->combine = parse_combine_notes_fn(v);
-               if (!c->combine) {
-                       error(_("Bad notes.rewriteMode value: '%s'"), v);
-                       return 1;
-               }
-               return 0;
-       } else if (!c->refs_from_env && !strcmp(k, "notes.rewriteref")) {
-               /* note that a refs/ prefix is implied in the
-                * underlying for_each_glob_ref */
-               if (!prefixcmp(v, "refs/notes/"))
-                       string_list_add_refs_by_glob(c->refs, v);
-               else
-                       warning(_("Refusing to rewrite notes in %s"
-                               " (outside of refs/notes/)"), v);
-               return 0;
-       }
-
-       return 0;
-}
-
-
-struct notes_rewrite_cfg *init_copy_notes_for_rewrite(const char *cmd)
-{
-       struct notes_rewrite_cfg *c = xmalloc(sizeof(struct notes_rewrite_cfg));
-       const char *rewrite_mode_env = getenv(GIT_NOTES_REWRITE_MODE_ENVIRONMENT);
-       const char *rewrite_refs_env = getenv(GIT_NOTES_REWRITE_REF_ENVIRONMENT);
-       c->cmd = cmd;
-       c->enabled = 1;
-       c->combine = combine_notes_concatenate;
-       c->refs = xcalloc(1, sizeof(struct string_list));
-       c->refs->strdup_strings = 1;
-       c->refs_from_env = 0;
-       c->mode_from_env = 0;
-       if (rewrite_mode_env) {
-               c->mode_from_env = 1;
-               c->combine = parse_combine_notes_fn(rewrite_mode_env);
-               if (!c->combine)
-                       /* TRANSLATORS: The first %s is the name of the
-                          environment variable, the second %s is its value */
-                       error(_("Bad %s value: '%s'"), GIT_NOTES_REWRITE_MODE_ENVIRONMENT,
-                                       rewrite_mode_env);
-       }
-       if (rewrite_refs_env) {
-               c->refs_from_env = 1;
-               string_list_add_refs_from_colon_sep(c->refs, rewrite_refs_env);
-       }
-       git_config(notes_rewrite_config, c);
-       if (!c->enabled || !c->refs->nr) {
-               string_list_clear(c->refs, 0);
-               free(c->refs);
-               free(c);
-               return NULL;
-       }
-       c->trees = load_notes_trees(c->refs);
-       string_list_clear(c->refs, 0);
-       free(c->refs);
-       return c;
-}
-
-int copy_note_for_rewrite(struct notes_rewrite_cfg *c,
-                         const unsigned char *from_obj, const unsigned char *to_obj)
-{
-       int ret = 0;
-       int i;
-       for (i = 0; c->trees[i]; i++)
-               ret = copy_note(c->trees[i], from_obj, to_obj, 1, c->combine) || ret;
-       return ret;
-}
-
-void finish_copy_notes_for_rewrite(struct notes_rewrite_cfg *c)
-{
-       int i;
-       for (i = 0; c->trees[i]; i++) {
-               commit_notes(c->trees[i], "Notes added by 'git notes copy'");
-               free_notes(c->trees[i]);
-       }
-       free(c->trees);
-       free(c);
-}
-
 static int notes_copy_from_stdin(int force, const char *rewrite_cmd)
 {
        struct strbuf buf = STRBUF_INIT;
        struct notes_rewrite_cfg *c = NULL;
        struct notes_tree *t = NULL;
        int ret = 0;
+       const char *msg = "Notes added by 'git notes copy'";
 
        if (rewrite_cmd) {
                c = init_copy_notes_for_rewrite(rewrite_cmd);
@@ -461,10 +333,10 @@ static int notes_copy_from_stdin(int force, const char *rewrite_cmd)
        }
 
        if (!rewrite_cmd) {
-               commit_notes(t, "Notes added by 'git notes copy'");
+               commit_notes(t, msg);
                free_notes(t);
        } else {
-               finish_copy_notes_for_rewrite(c);
+               finish_copy_notes_for_rewrite(c, msg);
        }
        return ret;
 }
index b5a0f88..b20b1ec 100644 (file)
@@ -1,6 +1,6 @@
 #include "builtin.h"
 #include "parse-options.h"
-#include "pack-refs.h"
+#include "refs.h"
 
 static char const * const pack_refs_usage[] = {
        N_("git pack-refs [options]"),
index 83382c1..fa6ce42 100644 (file)
@@ -8,9 +8,6 @@ static const char * const prune_packed_usage[] = {
        NULL
 };
 
-#define DRY_RUN 01
-#define VERBOSE 02
-
 static struct progress *progress;
 
 static void prune_dir(int i, DIR *dir, char *pathname, int len, int opts)
@@ -29,7 +26,7 @@ static void prune_dir(int i, DIR *dir, char *pathname, int len, int opts)
                if (!has_sha1_pack(sha1))
                        continue;
                memcpy(pathname + len, de->d_name, 38);
-               if (opts & DRY_RUN)
+               if (opts & PRUNE_PACKED_DRY_RUN)
                        printf("rm -f %s\n", pathname);
                else
                        unlink_or_warn(pathname);
@@ -44,7 +41,7 @@ void prune_packed_objects(int opts)
        const char *dir = get_object_directory();
        int len = strlen(dir);
 
-       if (opts == VERBOSE)
+       if (opts & PRUNE_PACKED_VERBOSE)
                progress = start_progress_delay("Removing duplicate objects",
                        256, 95, 2);
 
@@ -71,10 +68,12 @@ void prune_packed_objects(int opts)
 
 int cmd_prune_packed(int argc, const char **argv, const char *prefix)
 {
-       int opts = isatty(2) ? VERBOSE : 0;
+       int opts = isatty(2) ? PRUNE_PACKED_VERBOSE : 0;
        const struct option prune_packed_options[] = {
-               OPT_BIT('n', "dry-run", &opts, N_("dry run"), DRY_RUN),
-               OPT_NEGBIT('q', "quiet", &opts, N_("be quiet"), VERBOSE),
+               OPT_BIT('n', "dry-run", &opts, N_("dry run"),
+                       PRUNE_PACKED_DRY_RUN),
+               OPT_NEGBIT('q', "quiet", &opts, N_("be quiet"),
+                          PRUNE_PACKED_VERBOSE),
                OPT_END()
        };
 
index 85843d4..6366917 100644 (file)
@@ -132,8 +132,8 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
                OPT__DRY_RUN(&show_only, N_("do not remove, show only")),
                OPT__VERBOSE(&verbose, N_("report pruned objects")),
                OPT_BOOL(0, "progress", &show_progress, N_("show progress")),
-               OPT_DATE(0, "expire", &expire,
-                        N_("expire objects older than <time>")),
+               OPT_EXPIRY_DATE(0, "expire", &expire,
+                               N_("expire objects older than <time>")),
                OPT_END()
        };
        char *s;
@@ -165,7 +165,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
        stop_progress(&progress);
        prune_object_dir(get_object_directory());
 
-       prune_packed_objects(show_only);
+       prune_packed_objects(show_only ? PRUNE_PACKED_DRY_RUN : 0);
        remove_temporary_files(get_object_directory());
        s = mkpathdup("%s/pack", get_object_directory());
        remove_temporary_files(s);
index 909c34d..a2580a9 100644 (file)
@@ -113,17 +113,20 @@ static NORETURN int die_push_simple(struct branch *branch, struct remote *remote
            remote->name, branch->name, advice_maybe);
 }
 
-static void setup_push_upstream(struct remote *remote, int simple)
+static const char message_detached_head_die[] =
+       N_("You are not currently on a branch.\n"
+          "To push the history leading to the current (detached HEAD)\n"
+          "state now, use\n"
+          "\n"
+          "    git push %s HEAD:<name-of-remote-branch>\n");
+
+static void setup_push_upstream(struct remote *remote, struct branch *branch,
+                               int triangular)
 {
        struct strbuf refspec = STRBUF_INIT;
-       struct branch *branch = branch_get(NULL);
+
        if (!branch)
-               die(_("You are not currently on a branch.\n"
-                   "To push the history leading to the current (detached HEAD)\n"
-                   "state now, use\n"
-                   "\n"
-                   "    git push %s HEAD:<name-of-remote-branch>\n"),
-                   remote->name);
+               die(_(message_detached_head_die), remote->name);
        if (!branch->merge_nr || !branch->merge || !branch->remote_name)
                die(_("The current branch %s has no upstream branch.\n"
                    "To push the current branch and set the remote as upstream, use\n"
@@ -135,18 +138,29 @@ static void setup_push_upstream(struct remote *remote, int simple)
        if (branch->merge_nr != 1)
                die(_("The current branch %s has multiple upstream branches, "
                    "refusing to push."), branch->name);
-       if (strcmp(branch->remote_name, remote->name))
+       if (triangular)
                die(_("You are pushing to remote '%s', which is not the upstream of\n"
                      "your current branch '%s', without telling me what to push\n"
                      "to update which remote branch."),
                    remote->name, branch->name);
-       if (simple && strcmp(branch->refname, branch->merge[0]->src))
-               die_push_simple(branch, remote);
+
+       if (push_default == PUSH_DEFAULT_SIMPLE) {
+               /* Additional safety */
+               if (strcmp(branch->refname, branch->merge[0]->src))
+                       die_push_simple(branch, remote);
+       }
 
        strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src);
        add_refspec(refspec.buf);
 }
 
+static void setup_push_current(struct remote *remote, struct branch *branch)
+{
+       if (!branch)
+               die(_(message_detached_head_die), remote->name);
+       add_refspec(branch->name);
+}
+
 static char warn_unspecified_push_default_msg[] =
 N_("push.default is unset; its implicit value is changing in\n"
    "Git 2.0 from 'matching' to 'simple'. To squelch this message\n"
@@ -171,8 +185,17 @@ static void warn_unspecified_push_default_configuration(void)
        warning("%s\n", _(warn_unspecified_push_default_msg));
 }
 
+static int is_workflow_triangular(struct remote *remote)
+{
+       struct remote *fetch_remote = remote_get(NULL);
+       return (fetch_remote && fetch_remote != remote);
+}
+
 static void setup_default_push_refspecs(struct remote *remote)
 {
+       struct branch *branch = branch_get(NULL);
+       int triangular = is_workflow_triangular(remote);
+
        switch (push_default) {
        default:
        case PUSH_DEFAULT_UNSPECIFIED:
@@ -184,15 +207,18 @@ static void setup_default_push_refspecs(struct remote *remote)
                break;
 
        case PUSH_DEFAULT_SIMPLE:
-               setup_push_upstream(remote, 1);
+               if (triangular)
+                       setup_push_current(remote, branch);
+               else
+                       setup_push_upstream(remote, branch, triangular);
                break;
 
        case PUSH_DEFAULT_UPSTREAM:
-               setup_push_upstream(remote, 0);
+               setup_push_upstream(remote, branch, triangular);
                break;
 
        case PUSH_DEFAULT_CURRENT:
-               add_refspec("HEAD");
+               setup_push_current(remote, branch);
                break;
 
        case PUSH_DEFAULT_NOTHING:
index 042ac1b..0f5d7fe 100644 (file)
@@ -66,7 +66,7 @@ static int exclude_per_directory_cb(const struct option *opt, const char *arg,
        return 0;
 }
 
-static void debug_stage(const char *label, struct cache_entry *ce,
+static void debug_stage(const char *label, const struct cache_entry *ce,
                        struct unpack_trees_options *o)
 {
        printf("%s ", label);
@@ -80,7 +80,8 @@ static void debug_stage(const char *label, struct cache_entry *ce,
                       sha1_to_hex(ce->sha1));
 }
 
-static int debug_merge(struct cache_entry **stages, struct unpack_trees_options *o)
+static int debug_merge(const struct cache_entry * const *stages,
+                      struct unpack_trees_options *o)
 {
        int i;
 
index 72a0af7..54184b3 100644 (file)
@@ -496,11 +496,9 @@ static int parse_expire_cfg_value(const char *var, const char *value, unsigned l
 {
        if (!value)
                return config_error_nonbool(var);
-       if (!strcmp(value, "never") || !strcmp(value, "false")) {
-               *expire = 0;
-               return 0;
-       }
-       *expire = approxidate(value);
+       if (parse_expiry_date(value, expire))
+               return error(_("%s' for '%s' is not a valid timestamp"),
+                            value, var);
        return 0;
 }
 
@@ -614,11 +612,13 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
                if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n"))
                        cb.dry_run = 1;
                else if (!prefixcmp(arg, "--expire=")) {
-                       cb.expire_total = approxidate(arg + 9);
+                       if (parse_expiry_date(arg + 9, &cb.expire_total))
+                               die(_("'%s' is not a valid timestamp"), arg);
                        explicit_expiry |= EXPIRE_TOTAL;
                }
                else if (!prefixcmp(arg, "--expire-unreachable=")) {
-                       cb.expire_unreachable = approxidate(arg + 21);
+                       if (parse_expiry_date(arg + 21, &cb.expire_unreachable))
+                               die(_("'%s' is not a valid timestamp"), arg);
                        explicit_expiry |= EXPIRE_UNREACH;
                }
                else if (!strcmp(arg, "--stale-fix"))
index 398ccd5..59d3115 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2008 Christian Couder <chriscool@tuxfamily.org>
  *
- * Based on builtin-tag.c by Kristian Høgsberg <krh@redhat.com>
+ * Based on builtin/tag.c by Kristian Høgsberg <krh@redhat.com>
  * and Carlos Rica <jasampler@gmail.com> that was itself based on
  * git-tag.sh and mktag.c by Linus Torvalds.
  */
index f267a1d..de894c7 100644 (file)
@@ -212,11 +212,17 @@ static void show_datestring(const char *flag, const char *datestr)
        show(buffer);
 }
 
-static int show_file(const char *arg)
+static int show_file(const char *arg, int output_prefix)
 {
        show_default();
        if ((filter & (DO_NONFLAGS|DO_NOREV)) == (DO_NONFLAGS|DO_NOREV)) {
-               show(arg);
+               if (output_prefix) {
+                       const char *prefix = startup_info->prefix;
+                       show(prefix_filename(prefix,
+                                            prefix ? strlen(prefix) : 0,
+                                            arg));
+               } else
+                       show(arg);
                return 1;
        }
        return 0;
@@ -470,6 +476,7 @@ N_("git rev-parse --parseopt [options] -- [<args>...]\n"
 int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 {
        int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0;
+       int output_prefix = 0;
        unsigned char sha1[20];
        const char *name = NULL;
 
@@ -503,7 +510,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
                const char *arg = argv[i];
 
                if (as_is) {
-                       if (show_file(arg) && as_is < 2)
+                       if (show_file(arg, output_prefix) && as_is < 2)
                                verify_filename(prefix, arg, 0);
                        continue;
                }
@@ -527,7 +534,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
                                as_is = 2;
                                /* Pass on the "--" if we show anything but files.. */
                                if (filter & (DO_FLAGS | DO_REVS))
-                                       show_file(arg);
+                                       show_file(arg, 0);
                                continue;
                        }
                        if (!strcmp(arg, "--default")) {
@@ -535,6 +542,13 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
                                i++;
                                continue;
                        }
+                       if (!strcmp(arg, "--prefix")) {
+                               prefix = argv[i+1];
+                               startup_info->prefix = prefix;
+                               output_prefix = 1;
+                               i++;
+                               continue;
+                       }
                        if (!strcmp(arg, "--revs-only")) {
                                filter &= ~DO_NOREV;
                                continue;
@@ -754,7 +768,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
                if (verify)
                        die_no_single_rev(quiet);
                as_is = 1;
-               if (!show_file(arg))
+               if (!show_file(arg, output_prefix))
                        continue;
                verify_filename(prefix, arg, 1);
        }
index 7b91d52..06025a2 100644 (file)
@@ -9,6 +9,7 @@
 #include "cache-tree.h"
 #include "tree-walk.h"
 #include "parse-options.h"
+#include "string-list.h"
 #include "submodule.h"
 
 static const char * const builtin_rm_usage[] = {
@@ -36,10 +37,32 @@ static int get_ours_cache_pos(const char *path, int pos)
        return -1;
 }
 
+static void print_error_files(struct string_list *files_list,
+                             const char *main_msg,
+                             const char *hints_msg,
+                             int *errs)
+{
+       if (files_list->nr) {
+               int i;
+               struct strbuf err_msg = STRBUF_INIT;
+
+               strbuf_addstr(&err_msg, main_msg);
+               for (i = 0; i < files_list->nr; i++)
+                       strbuf_addf(&err_msg,
+                                   "\n    %s",
+                                   files_list->items[i].string);
+               if (advice_rm_hints)
+                       strbuf_addstr(&err_msg, hints_msg);
+               *errs = error("%s", err_msg.buf);
+               strbuf_release(&err_msg);
+       }
+}
+
 static int check_submodules_use_gitfiles(void)
 {
        int i;
        int errs = 0;
+       struct string_list files = STRING_LIST_INIT_NODUP;
 
        for (i = 0; i < list.nr; i++) {
                const char *name = list.entry[i].name;
@@ -61,11 +84,18 @@ static int check_submodules_use_gitfiles(void)
                        continue;
 
                if (!submodule_uses_gitfile(name))
-                       errs = error(_("submodule '%s' (or one of its nested "
-                                    "submodules) uses a .git directory\n"
-                                    "(use 'rm -rf' if you really want to remove "
-                                    "it including all of its history)"), name);
+                       string_list_append(&files, name);
        }
+       print_error_files(&files,
+                         Q_("the following submodule (or one of its nested "
+                            "submodules)\n uses a .git directory:",
+                            "the following submodules (or one of its nested "
+                            "submodules)\n use a .git directory:",
+                            files.nr),
+                         _("\n(use 'rm -rf' if you really want to remove "
+                           "it including all of its history)"),
+                         &errs);
+       string_list_clear(&files, 0);
 
        return errs;
 }
@@ -81,6 +111,10 @@ static int check_local_mod(unsigned char *head, int index_only)
         */
        int i, no_head;
        int errs = 0;
+       struct string_list files_staged = STRING_LIST_INIT_NODUP;
+       struct string_list files_cached = STRING_LIST_INIT_NODUP;
+       struct string_list files_submodule = STRING_LIST_INIT_NODUP;
+       struct string_list files_local = STRING_LIST_INIT_NODUP;
 
        no_head = is_null_sha1(head);
        for (i = 0; i < list.nr; i++) {
@@ -171,29 +205,58 @@ static int check_local_mod(unsigned char *head, int index_only)
                 */
                if (local_changes && staged_changes) {
                        if (!index_only || !(ce->ce_flags & CE_INTENT_TO_ADD))
-                               errs = error(_("'%s' has staged content different "
-                                            "from both the file and the HEAD\n"
-                                            "(use -f to force removal)"), name);
+                               string_list_append(&files_staged, name);
                }
                else if (!index_only) {
                        if (staged_changes)
-                               errs = error(_("'%s' has changes staged in the index\n"
-                                            "(use --cached to keep the file, "
-                                            "or -f to force removal)"), name);
+                               string_list_append(&files_cached, name);
                        if (local_changes) {
                                if (S_ISGITLINK(ce->ce_mode) &&
-                                   !submodule_uses_gitfile(name)) {
-                                       errs = error(_("submodule '%s' (or one of its nested "
-                                                    "submodules) uses a .git directory\n"
-                                                    "(use 'rm -rf' if you really want to remove "
-                                                    "it including all of its history)"), name);
-                               } else
-                                       errs = error(_("'%s' has local modifications\n"
-                                                    "(use --cached to keep the file, "
-                                                    "or -f to force removal)"), name);
+                                   !submodule_uses_gitfile(name))
+                                       string_list_append(&files_submodule, name);
+                               else
+                                       string_list_append(&files_local, name);
                        }
                }
        }
+       print_error_files(&files_staged,
+                         Q_("the following file has staged content different "
+                            "from both the\nfile and the HEAD:",
+                            "the following files have staged content different"
+                            " from both the\nfile and the HEAD:",
+                            files_staged.nr),
+                         _("\n(use -f to force removal)"),
+                         &errs);
+       string_list_clear(&files_staged, 0);
+       print_error_files(&files_cached,
+                         Q_("the following file has changes "
+                            "staged in the index:",
+                            "the following files have changes "
+                            "staged in the index:", files_cached.nr),
+                         _("\n(use --cached to keep the file,"
+                           " or -f to force removal)"),
+                         &errs);
+       string_list_clear(&files_cached, 0);
+       print_error_files(&files_submodule,
+                         Q_("the following submodule (or one of its nested "
+                            "submodule)\nuses a .git directory:",
+                            "the following submodules (or one of its nested "
+                            "submodule)\nuse a .git directory:",
+                            files_submodule.nr),
+                         _("\n(use 'rm -rf' if you really "
+                           "want to remove it including all "
+                           "of its history)"),
+                         &errs);
+       string_list_clear(&files_submodule, 0);
+       print_error_files(&files_local,
+                         Q_("the following file has local modifications:",
+                            "the following files have local modifications:",
+                            files_local.nr),
+                         _("\n(use --cached to keep the file,"
+                           " or -f to force removal)"),
+                         &errs);
+       string_list_clear(&files_local, 0);
+
        return errs;
 }
 
index 90fc6b1..99ec4af 100644 (file)
@@ -630,7 +630,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
        int num_rev, i, extra = 0;
        int all_heads = 0, all_remotes = 0;
        int all_mask, all_revs;
-       int lifo = 1;
+       enum rev_sort_order sort_order = REV_SORT_IN_GRAPH_ORDER;
        char head[128];
        const char *head_p;
        int head_len;
@@ -665,15 +665,17 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                            N_("show possible merge bases")),
                OPT_BOOLEAN(0, "independent", &independent,
                            N_("show refs unreachable from any other ref")),
-               OPT_BOOLEAN(0, "topo-order", &lifo,
-                           N_("show commits in topological order")),
+               OPT_SET_INT(0, "topo-order", &sort_order,
+                           N_("show commits in topological order"),
+                           REV_SORT_IN_GRAPH_ORDER),
                OPT_BOOLEAN(0, "topics", &topics,
                            N_("show only commits not on the first branch")),
                OPT_SET_INT(0, "sparse", &dense,
                            N_("show merges reachable from only one tip"), 0),
-               OPT_SET_INT(0, "date-order", &lifo,
+               OPT_SET_INT(0, "date-order", &sort_order,
                            N_("show commits where no parent comes before its "
-                              "children"), 0),
+                              "children"),
+                           REV_SORT_BY_COMMIT_DATE),
                { OPTION_CALLBACK, 'g', "reflog", &reflog_base, N_("<n>[,<base>]"),
                            N_("show <n> most recent ref-log entries starting at "
                               "base"),
@@ -900,7 +902,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                exit(0);
 
        /* Sort topologically */
-       sort_in_topological_order(&seen, lifo);
+       sort_in_topological_order(&seen, sort_order);
 
        /* Give names to commits */
        if (!sha1_name && !no_name)
index 8d9b76a..4a0310d 100644 (file)
@@ -103,7 +103,7 @@ static int add_existing(const char *refname, const unsigned char *sha1, int flag
  */
 static int exclude_existing(const char *match)
 {
-       static struct string_list existing_refs = STRING_LIST_INIT_NODUP;
+       static struct string_list existing_refs = STRING_LIST_INIT_DUP;
        char buf[1024];
        int matchlen = match ? strlen(match) : 0;
 
index 4b0e5cd..3d64311 100644 (file)
--- a/bundle.c
+++ b/bundle.c
@@ -281,7 +281,7 @@ int create_bundle(struct bundle_header *header, const char *path,
                        if (!get_sha1_hex(buf.buf + 1, sha1)) {
                                struct object *object = parse_object_or_die(sha1, buf.buf);
                                object->flags |= UNINTERESTING;
-                               add_pending_object(&revs, object, xstrdup(buf.buf));
+                               add_pending_object(&revs, object, buf.buf);
                        }
                } else if (!get_sha1_hex(buf.buf, sha1)) {
                        struct object *object = parse_object_or_die(sha1, buf.buf);
diff --git a/cache.h b/cache.h
index 94ca1ac..dd0fb33 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -119,15 +119,19 @@ struct cache_time {
        unsigned int nsec;
 };
 
+struct stat_data {
+       struct cache_time sd_