aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.mailmap3
-rw-r--r--Documentation/Makefile8
-rw-r--r--Documentation/RelNotes-1.7.0.4.txt27
-rw-r--r--Documentation/RelNotes-1.7.0.5.txt26
-rw-r--r--Documentation/blame-options.txt19
-rw-r--r--Documentation/config.txt10
-rw-r--r--Documentation/diff-options.txt4
-rw-r--r--Documentation/git-branch.txt6
-rw-r--r--Documentation/git-describe.txt3
-rw-r--r--Documentation/git-fetch.txt8
-rw-r--r--Documentation/git-http-backend.txt2
-rw-r--r--Documentation/git-imap-send.txt10
-rw-r--r--Documentation/git-merge.txt3
-rw-r--r--Documentation/git-push.txt2
-rw-r--r--Documentation/git-show-ref.txt2
-rw-r--r--Documentation/git.txt4
-rw-r--r--Documentation/merge-options.txt10
-rw-r--r--Documentation/technical/pack-protocol.txt10
-rwxr-xr-xGIT-VERSION-GEN2
-rw-r--r--Makefile8
l---------RelNotes2
-rw-r--r--branch.c2
-rw-r--r--builtin-add.c38
-rw-r--r--builtin-apply.c190
-rw-r--r--builtin-fast-export.c2
-rw-r--r--builtin-fetch.c8
-rw-r--r--builtin-log.c9
-rw-r--r--builtin-push.c2
-rw-r--r--builtin-reflog.c2
-rw-r--r--builtin-reset.c3
-rw-r--r--builtin-rev-list.c5
-rw-r--r--color.c24
-rw-r--r--color.h16
-rw-r--r--combine-diff.c14
-rw-r--r--compat/bswap.h2
-rw-r--r--compat/mingw.c20
-rw-r--r--compat/vcbuild/include/termios.h1
-rwxr-xr-xcontrib/fast-import/import-zips.py2
-rwxr-xr-xcontrib/hg-to-git/hg-to-git.py2
-rw-r--r--contrib/p4import/git-p4import.py2
-rw-r--r--daemon.c11
-rw-r--r--diff.c62
-rw-r--r--dir.c20
-rwxr-xr-xgit-difftool.perl12
-rwxr-xr-xgit-send-email.perl5
-rwxr-xr-xgit-stash.sh8
-rw-r--r--git_remote_helpers/Makefile6
-rwxr-xr-xgitweb/gitweb.perl3
-rw-r--r--http-backend.c18
-rw-r--r--imap-send.c8
-rw-r--r--refs.c11
-rwxr-xr-xt/t0050-filesystem.sh8
-rwxr-xr-xt/t1010-mktree.sh10
-rwxr-xr-xt/t2200-add-update.sh5
-rwxr-xr-xt/t2204-add-ignored.sh79
-rwxr-xr-xt/t3417-rebase-whitespace-fix.sh126
-rwxr-xr-xt/t3700-add.sh5
-rwxr-xr-xt/t4014-format-patch.sh4
-rwxr-xr-xt/t4017-diff-retval.sh23
-rwxr-xr-xt/t4026-color.sh15
-rwxr-xr-xt/t4038-diff-combined.sh8
-rwxr-xr-xt/t4104-apply-boundary.sh9
-rwxr-xr-xt/t4124-apply-ws-rule.sh170
-rwxr-xr-xt/t5505-remote.sh6
-rwxr-xr-xt/t6006-rev-list-format.sh9
-rwxr-xr-xt/t7012-skip-worktree-writing.sh12
-rwxr-xr-xt/t7800-difftool.sh9
-rwxr-xr-xt/t9350-fast-export.sh71
68 files changed, 999 insertions, 247 deletions
diff --git a/.mailmap b/.mailmap
index 88bd01e16..a8091eb5d 100644
--- a/.mailmap
+++ b/.mailmap
@@ -5,6 +5,7 @@
# same person appearing not to be so.
#
+Alex Bennée <kernel-hacker@bennee.com>
Alexander Gavrilov <angavrilov@gmail.com>
Aneesh Kumar K.V <aneesh.kumar@gmail.com>
Brian M. Carlson <sandals@crustytoothpaste.ath.cx>
@@ -15,6 +16,7 @@ Daniel Barkalow <barkalow@iabervon.org>
David D. Kilzer <ddkilzer@kilzer.net>
David Kågedal <davidk@lysator.liu.se>
David S. Miller <davem@davemloft.net>
+Deskin Miller <deskinm@umich.edu>
Dirk Süsserott <newsletter@dirk.my1.cc>
Fredrik Kuivinen <freku045@student.liu.se>
H. Peter Anvin <hpa@bonde.sc.orionmulti.com>
@@ -60,6 +62,7 @@ Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
Uwe Kleine-König <uzeisberger@io.fsforth.de>
Uwe Kleine-König <zeisberg@informatik.uni-freiburg.de>
Ville Skyttä <scop@xemacs.org>
+Vitaly "_Vi" Shukela <public_vi@tut.by>
William Pursell <bill.pursell@gmail.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
anonymous <linux@horizon.com>
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 8a8a3954d..04f69cf64 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -264,7 +264,9 @@ manpage-base-url.xsl: manpage-base-url.xsl.in
mv $@+ $@
user-manual.xml: user-manual.txt user-manual.conf
- $(QUIET_ASCIIDOC)$(ASCIIDOC) $(ASCIIDOC_EXTRA) -b docbook -d book $<
+ $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
+ $(ASCIIDOC) $(ASCIIDOC_EXTRA) -b docbook -d book -o $@+ $< && \
+ mv $@+ $@
technical/api-index.txt: technical/api-index-skel.txt \
technical/api-index.sh $(patsubst %,%.txt,$(API_DOCS))
@@ -278,7 +280,9 @@ XSLT = docbook.xsl
XSLTOPTS = --xinclude --stringparam html.stylesheet docbook-xsl.css
user-manual.html: user-manual.xml
- $(QUIET_XSLTPROC)xsltproc $(XSLTOPTS) -o $@ $(XSLT) $<
+ $(QUIET_XSLTPROC)$(RM) $@+ $@ && \
+ xsltproc $(XSLTOPTS) -o $@+ $(XSLT) $< && \
+ mv $@+ $@
git.info: user-manual.texi
$(QUIET_MAKEINFO)$(MAKEINFO) --no-split -o $@ user-manual.texi
diff --git a/Documentation/RelNotes-1.7.0.4.txt b/Documentation/RelNotes-1.7.0.4.txt
new file mode 100644
index 000000000..cf7f60e60
--- /dev/null
+++ b/Documentation/RelNotes-1.7.0.4.txt
@@ -0,0 +1,27 @@
+Git v1.7.0.4 Release Notes
+==========================
+
+Fixes since v1.7.0.3
+--------------------
+
+ * Optimized ntohl/htonl on big-endian machines were broken.
+
+ * Color values given to "color.<cmd>.<slot>" configuration can now have
+ more than one attributes (e.g. "bold ul").
+
+ * "git add -u nonexistent-path" did not complain.
+
+ * "git apply --whitespace=fix" didn't work well when an early patch in
+ a patch series adds trailing blank lines and a later one depended on
+ such a block of blank lines at the end.
+
+ * "git fast-export" didn't check error status and stop when marks file
+ cannot be opened.
+
+ * "git format-patch --ignore-if-in-upstream" gave unwarranted errors
+ when the range was empty, instead of silently finishing.
+
+ * "git remote prune" did not detect remote tracking refs that became
+ dangling correctly.
+
+And other minor fixes and documentation updates.
diff --git a/Documentation/RelNotes-1.7.0.5.txt b/Documentation/RelNotes-1.7.0.5.txt
new file mode 100644
index 000000000..3149c91b7
--- /dev/null
+++ b/Documentation/RelNotes-1.7.0.5.txt
@@ -0,0 +1,26 @@
+Git v1.7.0.5 Release Notes
+==========================
+
+Fixes since v1.7.0.4
+--------------------
+
+ * "git daemon" failed to compile on platforms without sockaddr_storage type.
+
+ * Output from "git rev-list --pretty=oneline" was unparsable when a
+ commit did not have any message, which is abnormal but possible in a
+ repository converted from foreign scm.
+
+ * "git stash show <commit-that-is-not-a-stash>" gave an error message
+ that was not so useful. Reworded the message to "<it> is not a
+ stash".
+
+ * Python scripts in contrib/ area now start with "#!/usr/bin/env python"
+ to honor user's PATH.
+
+ * "git imap-send" used to mistake any line that begins with "From " as a
+ message separator in format-patch output.
+
+ * Smart http server backend failed to report an internal server error and
+ infinitely looped instead after output pipe was closed.
+
+And other minor fixes and documentation updates.
diff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt
index 4833cac4b..d8205691c 100644
--- a/Documentation/blame-options.txt
+++ b/Documentation/blame-options.txt
@@ -79,14 +79,15 @@ of lines before or after the line given by <start>.
of the --date option at linkgit:git-log[1].
-M|<num>|::
- Detect moving lines in the file as well. When a commit
- moves a block of lines in a file (e.g. the original file
- has A and then B, and the commit changes it to B and
- then A), the traditional 'blame' algorithm typically blames
- the lines that were moved up (i.e. B) to the parent and
- assigns blame to the lines that were moved down (i.e. A)
- to the child commit. With this option, both groups of lines
- are blamed on the parent.
+ Detect moved or copied lines within a file. When a commit
+ moves or copies a block of lines (e.g. the original file
+ has A and then B, and the commit changes it to B and then
+ A), the traditional 'blame' algorithm notices only half of
+ the movement and typically blames the lines that were moved
+ up (i.e. B) to the parent and assigns blame to the lines that
+ were moved down (i.e. A) to the child commit. With this
+ option, both groups of lines are blamed on the parent by
+ running extra passes of inspection.
+
<num> is optional but it is the lower bound on the number of
alphanumeric characters that git must detect as moving
@@ -94,7 +95,7 @@ within a file for it to associate those lines with the parent
commit.
-C|<num>|::
- In addition to `-M`, detect lines copied from other
+ In addition to `-M`, detect lines moved or copied from other
files that were modified in the same commit. This is
useful when you reorganize your program and move code
around across files. When this option is given twice,
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 437b4ac5e..f6ddd35c0 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -198,11 +198,11 @@ core.quotepath::
core.autocrlf::
If true, makes git convert `CRLF` at the end of lines in text files to
- `LF` when reading from the filesystem, and convert in reverse when
- writing to the filesystem. The variable can be set to
+ `LF` when reading from the work tree, and convert in reverse when
+ writing to the work tree. The variable can be set to
'input', in which case the conversion happens only while
- reading from the filesystem but files are written out with
- `LF` at the end of lines. A file is considered
+ reading from the work tree but files are written out to the work
+ tree with `LF` at the end of lines. A file is considered
"text" (i.e. be subjected to the autocrlf mechanism) based on
the file's `crlf` attribute, or if `crlf` is unspecified,
based on the file's contents. See linkgit:gitattributes[5].
@@ -885,7 +885,7 @@ format.signoff::
gc.aggressiveWindow::
The window size parameter used in the delta compression
algorithm used by 'git gc --aggressive'. This defaults
- to 10.
+ to 250.
gc.auto::
When there are approximately more than this many loose
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 8707d0e74..a1191d647 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -94,8 +94,8 @@ Also, when `--raw` or `--numstat` has been given, do not munge
pathnames and use NULs as output field terminators.
endif::git-log[]
ifndef::git-log[]
- When `--raw` or `--numstat` has been given, do not munge
- pathnames and use NULs as output field terminators.
+ When `--raw`, `--numstat`, `--name-only` or `--name-status` has been
+ given, do not munge pathnames and use NULs as output field terminators.
endif::git-log[]
+
Without this option, each pathname output will have TAB, LF, double quotes,
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 6b6c3da2d..60fa684b1 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -63,7 +63,9 @@ way to clean up all obsolete remote-tracking branches.
OPTIONS
-------
-d::
- Delete a branch. The branch must be fully merged in HEAD.
+ Delete a branch. The branch must be fully merged in its
+ upstream branch, or in `HEAD` if no upstream was set with
+ `--track` or `--set-upstream`.
-D::
Delete a branch irrespective of its merged status.
@@ -72,6 +74,8 @@ OPTIONS
Create the branch's reflog. This activates recording of
all changes made to the branch ref, enabling use of date
based sha1 expressions such as "<branchname>@\{yesterday}".
+ Note that in non-bare repositories, reflogs are usually
+ enabled by default by the `core.logallrefupdates` config option.
-f::
--force::
diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt
index 6fc5323ee..7ef9d5157 100644
--- a/Documentation/git-describe.txt
+++ b/Documentation/git-describe.txt
@@ -105,6 +105,9 @@ The number of additional commits is the number
of commits which would be displayed by "git log v1.0.4..parent".
The hash suffix is "-g" + 7-char abbreviation for the tip commit
of parent (which was `2414721b194453f058079d897d13c4e377f92dc6`).
+The "g" prefix stands for "git" and is used to allow describing the version of
+a software depending on the SCM the software is managed with. This is useful
+in an environment where people may use different SCMs.
Doing a 'git describe' on a tag-name will just show the tag name:
diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt
index 948ea26c5..400fe7f95 100644
--- a/Documentation/git-fetch.txt
+++ b/Documentation/git-fetch.txt
@@ -8,13 +8,13 @@ git-fetch - Download objects and refs from another repository
SYNOPSIS
--------
-'git fetch' <options> <repository> <refspec>...
+'git fetch' [<options>] [<repository> [<refspec>...]]
-'git fetch' <options> <group>
+'git fetch' [<options>] <group>
-'git fetch' --multiple <options> [<repository> | <group>]...
+'git fetch' --multiple [<options>] [<repository> | <group>]...
-'git fetch' --all <options>
+'git fetch' --all [<options>]
DESCRIPTION
diff --git a/Documentation/git-http-backend.txt b/Documentation/git-http-backend.txt
index 523882065..277d9e141 100644
--- a/Documentation/git-http-backend.txt
+++ b/Documentation/git-http-backend.txt
@@ -35,7 +35,7 @@ These services can be enabled/disabled using the per-repository
configuration file:
http.getanyfile::
- This serves older Git clients which are unable to use the
+ This serves Git clients older than version 1.6.6 that are unable to use the
upload pack service. When enabled, clients are able to read
any file within the repository, including objects that are
no longer reachable from a branch but are still present.
diff --git a/Documentation/git-imap-send.txt b/Documentation/git-imap-send.txt
index 57db955bd..ad446b0e8 100644
--- a/Documentation/git-imap-send.txt
+++ b/Documentation/git-imap-send.txt
@@ -16,7 +16,9 @@ DESCRIPTION
This command uploads a mailbox generated with 'git format-patch'
into an IMAP drafts folder. This allows patches to be sent as
other email is when using mail clients that cannot read mailbox
-files directly.
+files directly. The command also works with any general mailbox
+in which emails have the fields "From", "Date", and "Subject" in
+that order.
Typical usage is something like:
@@ -118,12 +120,6 @@ Thunderbird in particular is known to be problematic. Thunderbird
users may wish to visit this web page for more information:
http://kb.mozillazine.org/Plain_text_e-mail_-_Thunderbird#Completely_plain_email
-
-BUGS
-----
-Doesn't handle lines starting with "From " in the message body.
-
-
Author
------
Derived from isync 1.0.1 by Mike McCormack.
diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index 9c9618cea..c2325ef90 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -9,7 +9,8 @@ git-merge - Join two or more development histories together
SYNOPSIS
--------
[verse]
-'git merge' [-n] [--stat] [--no-commit] [--squash] [-s <strategy>]...
+'git merge' [-n] [--stat] [--no-commit] [--squash]
+ [-s <strategy>] [-X <strategy-option>]
[--[no-]rerere-autoupdate] [-m <msg>] <commit>...
'git merge' <msg> HEAD <commit>...
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 49b6bd9d9..7a4e507c4 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -11,7 +11,7 @@ SYNOPSIS
[verse]
'git push' [--all | --mirror | --tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
[--repo=<repository>] [-f | --force] [-v | --verbose] [-u | --set-upstream]
- [<repository> <refspec>...]
+ [<repository> [<refspec>...]]
DESCRIPTION
-----------
diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt
index df17d49b8..3f9d9c6db 100644
--- a/Documentation/git-show-ref.txt
+++ b/Documentation/git-show-ref.txt
@@ -10,7 +10,7 @@ SYNOPSIS
[verse]
'git show-ref' [-q|--quiet] [--verify] [--head] [-d|--dereference]
[-s|--hash[=<n>]] [--abbrev[=<n>]] [--tags]
- [--heads] [--] <pattern>...
+ [--heads] [--] [<pattern>...]
'git show-ref' --exclude-existing[=<pattern>] < ref-list
DESCRIPTION
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 4e00b315f..fbae9956b 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -43,9 +43,11 @@ unreleased) version of git, that is available from 'master'
branch of the `git.git` repository.
Documentation for older releases are available here:
-* link:v1.7.0.3/git.html[documentation for release 1.7.0.3]
+* link:v1.7.0.5/git.html[documentation for release 1.7.0.5]
* release notes for
+ link:RelNotes-1.7.0.5.txt[1.7.0.5],
+ link:RelNotes-1.7.0.4.txt[1.7.0.4],
link:RelNotes-1.7.0.3.txt[1.7.0.3],
link:RelNotes-1.7.0.2.txt[1.7.0.2],
link:RelNotes-1.7.0.1.txt[1.7.0.1],
diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt
index 3b83dba1a..81ac82396 100644
--- a/Documentation/merge-options.txt
+++ b/Documentation/merge-options.txt
@@ -62,6 +62,11 @@ option can be used to override --squash.
is used instead ('git merge-recursive' when merging a single
head, 'git merge-octopus' otherwise).
+-X <option>::
+--strategy-option=<option>::
+ Pass merge strategy specific option through to the merge
+ strategy.
+
--summary::
--no-summary::
Synonyms to --stat and --no-stat; these are deprecated and will be
@@ -74,8 +79,3 @@ option can be used to override --squash.
-v::
--verbose::
Be verbose.
-
--X <option>::
---strategy-option=<option>::
- Pass merge strategy specific option through to the merge
- strategy.
diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt
index 9a5cdafa9..369f91d3b 100644
--- a/Documentation/technical/pack-protocol.txt
+++ b/Documentation/technical/pack-protocol.txt
@@ -36,7 +36,7 @@ Git Transport
The Git transport starts off by sending the command and repository
on the wire using the pkt-line format, followed by a NUL byte and a
-hostname paramater, terminated by a NUL byte.
+hostname parameter, terminated by a NUL byte.
0032git-upload-pack /project.git\0host=myserver.com\0
@@ -331,7 +331,7 @@ An incremental update (fetch) response might look like this:
C: 0009done\n
- S: 003aACK 74730d410fcb6603ace96f1dc55ea6196122532d\n
+ S: 0031ACK 74730d410fcb6603ace96f1dc55ea6196122532d\n
S: [PACKFILE]
----
@@ -488,7 +488,7 @@ An example client/server communication might look like this:
C: 0000
C: [PACKDATA]
- S: 000aunpack ok\n
- S: 0014ok refs/heads/debug\n
- S: 0026ng refs/heads/master non-fast-forward\n
+ S: 000eunpack ok\n
+ S: 0018ok refs/heads/debug\n
+ S: 002ang refs/heads/master non-fast-forward\n
----
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 076c18ecc..6705b1048 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.0.3
+DEF_VER=v1.7.0.5
LF='
'
diff --git a/Makefile b/Makefile
index 98372ebbf..5b8680660 100644
--- a/Makefile
+++ b/Makefile
@@ -831,6 +831,7 @@ ifeq ($(uname_S),FreeBSD)
NO_UINTMAX_T = YesPlease
NO_STRTOUMAX = YesPlease
endif
+ PYTHON_PATH = /usr/local/bin/python
endif
ifeq ($(uname_S),OpenBSD)
NO_STRCASESTR = YesPlease
@@ -886,6 +887,7 @@ ifeq ($(uname_S),IRIX)
SNPRINTF_RETURNS_BOGUS = YesPlease
SHELL_PATH = /usr/gnu/bin/bash
NEEDS_LIBGEN = YesPlease
+ NEEDS_LIBICONV = YesPlease
endif
ifeq ($(uname_S),IRIX64)
NO_SETENV=YesPlease
@@ -904,6 +906,7 @@ ifeq ($(uname_S),IRIX64)
SNPRINTF_RETURNS_BOGUS = YesPlease
SHELL_PATH=/usr/gnu/bin/bash
NEEDS_LIBGEN = YesPlease
+ NEEDS_LIBICONV = YesPlease
endif
ifeq ($(uname_S),HP-UX)
NO_IPV6=YesPlease
@@ -1557,9 +1560,8 @@ $(patsubst %.py,%,$(SCRIPT_PYTHON)): % : %.py
-e '}' \
-e 's|^import sys.*|&; \\\
import os; \\\
- sys.path[0] = os.environ.has_key("GITPYTHONLIB") and \\\
- os.environ["GITPYTHONLIB"] or \\\
- "@@INSTLIBDIR@@"|' \
+ sys.path.insert(0, os.getenv("GITPYTHONLIB",\
+ "@@INSTLIBDIR@@"));|' \
-e 's|@@INSTLIBDIR@@|'"$$INSTLIBDIR"'|g' \
$@.py >$@+ && \
chmod +x $@+ && \
diff --git a/RelNotes b/RelNotes
index 02e74966c..156a87e7f 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes-1.7.0.3.txt \ No newline at end of file
+Documentation/RelNotes-1.7.0.5.txt \ No newline at end of file
diff --git a/branch.c b/branch.c
index 9e1f63ed8..2ab42aaf4 100644
--- a/branch.c
+++ b/branch.c
@@ -198,7 +198,7 @@ void create_branch(const char *head,
log_all_ref_updates = 1;
if (forcing)
- snprintf(msg, sizeof msg, "branch: Reset from %s",
+ snprintf(msg, sizeof msg, "branch: Reset to %s",
start_name);
else if (!dont_change_ref)
snprintf(msg, sizeof msg, "branch: Created from %s",
diff --git a/builtin-add.c b/builtin-add.c
index 2705f8d05..87d298031 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -117,7 +117,19 @@ static void fill_pathspec_matches(const char **pathspec, char *seen, int specs)
}
}
-static void prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
+static char *find_used_pathspec(const char **pathspec)
+{
+ char *seen;
+ int i;
+
+ for (i = 0; pathspec[i]; i++)
+ ; /* just counting */
+ seen = xcalloc(i, 1);
+ fill_pathspec_matches(pathspec, seen, i);
+ return seen;
+}
+
+static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
{
char *seen;
int i, specs;
@@ -137,13 +149,7 @@ static void prune_directory(struct dir_struct *dir, const char **pathspec, int p
}
dir->nr = dst - dir->entries;
fill_pathspec_matches(pathspec, seen, specs);
-
- for (i = 0; i < specs; i++) {
- if (!seen[i] && pathspec[i][0] && !file_exists(pathspec[i]))
- die("pathspec '%s' did not match any files",
- pathspec[i]);
- }
- free(seen);
+ return seen;
}
static void treat_gitlinks(const char **pathspec)
@@ -359,6 +365,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
int flags;
int add_new_files;
int require_pathspec;
+ char *seen = NULL;
git_config(add_config, NULL);
@@ -418,7 +425,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
/* This picks up the paths that are not tracked */
baselen = fill_directory(&dir, pathspec);
if (pathspec)
- prune_directory(&dir, pathspec, baselen);
+ seen = prune_directory(&dir, pathspec, baselen);
}
if (refresh_only) {
@@ -426,6 +433,19 @@ int cmd_add(int argc, const char **argv, const char *prefix)
goto finish;
}
+ if (pathspec) {
+ int i;
+ if (!seen)
+ seen = find_used_pathspec(pathspec);
+ for (i = 0; pathspec[i]; i++) {
+ if (!seen[i] && pathspec[i][0]
+ && !file_exists(pathspec[i]))
+ die("pathspec '%s' did not match any files",
+ pathspec[i]);
+ }
+ free(seen);
+ }
+
exit_status |= add_files_to_cache(prefix, pathspec, flags);
if (add_new_files)
diff --git a/builtin-apply.c b/builtin-apply.c
index 3af4ae0c2..771c972c5 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -1854,33 +1854,76 @@ static int match_fragment(struct image *img,
{
int i;
char *fixed_buf, *buf, *orig, *target;
+ int preimage_limit;
- if (preimage->nr + try_lno > img->nr)
+ if (preimage->nr + try_lno <= img->nr) {
+ /*
+ * The hunk falls within the boundaries of img.
+ */
+ preimage_limit = preimage->nr;
+ if (match_end && (preimage->nr + try_lno != img->nr))
+ return 0;
+ } else if (ws_error_action == correct_ws_error &&
+ (ws_rule & WS_BLANK_AT_EOF) && match_end) {
+ /*
+ * This hunk that matches at the end extends beyond
+ * the end of img, and we are removing blank lines
+ * at the end of the file. This many lines from the
+ * beginning of the preimage must match with img, and
+ * the remainder of the preimage must be blank.
+ */
+ preimage_limit = img->nr - try_lno;
+ } else {
+ /*
+ * The hunk extends beyond the end of the img and
+ * we are not removing blanks at the end, so we
+ * should reject the hunk at this position.
+ */
return 0;
+ }
if (match_beginning && try_lno)
return 0;
- if (match_end && preimage->nr + try_lno != img->nr)
- return 0;
-
/* Quick hash check */
- for (i = 0; i < preimage->nr; i++)
+ for (i = 0; i < preimage_limit; i++)
if (preimage->line[i].hash != img->line[try_lno + i].hash)
return 0;
- /*
- * Do we have an exact match? If we were told to match
- * at the end, size must be exactly at try+fragsize,
- * otherwise try+fragsize must be still within the preimage,
- * and either case, the old piece should match the preimage
- * exactly.
- */
- if ((match_end
- ? (try + preimage->len == img->len)
- : (try + preimage->len <= img->len)) &&
- !memcmp(img->buf + try, preimage->buf, preimage->len))
- return 1;
+ if (preimage_limit == preimage->nr) {
+ /*
+ * Do we have an exact match? If we were told to match
+ * at the end, size must be exactly at try+fragsize,
+ * otherwise try+fragsize must be still within the preimage,
+ * and either case, the old piece should match the preimage
+ * exactly.
+ */
+ if ((match_end
+ ? (try + preimage->len == img->len)
+ : (try + preimage->len <= img->len)) &&
+ !memcmp(img->buf + try, preimage->buf, preimage->len))
+ return 1;
+ } else {
+ /*
+ * The preimage extends beyond the end of img, so
+ * there cannot be an exact match.
+ *
+ * There must be one non-blank context line that match
+ * a line before the end of img.
+ */
+ char *buf_end;
+
+ buf = preimage->buf;
+ buf_end = buf;
+ for (i = 0; i < preimage_limit; i++)
+ buf_end += preimage->line[i].len;
+
+ for ( ; buf < buf_end; buf++)
+ if (!isspace(*buf))
+ break;
+ if (buf == buf_end)
+ return 0;
+ }
/*
* No exact match. If we are ignoring whitespace, run a line-by-line
@@ -1891,7 +1934,10 @@ static int match_fragment(struct image *img,
size_t imgoff = 0;
size_t preoff = 0;
size_t postlen = postimage->len;
- for (i = 0; i < preimage->nr; i++) {
+ size_t extra_chars;
+ char *preimage_eof;
+ char *preimage_end;
+ for (i = 0; i < preimage_limit; i++) {
size_t prelen = preimage->line[i].len;
size_t imglen = img->line[try_lno+i].len;
@@ -1905,20 +1951,36 @@ static int match_fragment(struct image *img,
}
/*
- * Ok, the preimage matches with whitespace fuzz. Update it and
- * the common postimage lines to use the same whitespace as the
- * target. imgoff now holds the true length of the target that
- * matches the preimage, and we need to update the line lengths
- * of the preimage to match the target ones.
+ * Ok, the preimage matches with whitespace fuzz.
+ *
+ * imgoff now holds the true length of the target that
+ * matches the preimage before the end of the file.
+ *
+ * Count the number of characters in the preimage that fall
+ * beyond the end of the file and make sure that all of them
+ * are whitespace characters. (This can only happen if
+ * we are removing blank lines at the end of the file.)
*/
- fixed_buf = xmalloc(imgoff);
- memcpy(fixed_buf, img->buf + try, imgoff);
- for (i = 0; i < preimage->nr; i++)
- preimage->line[i].len = img->line[try_lno+i].len;
+ buf = preimage_eof = preimage->buf + preoff;
+ for ( ; i < preimage->nr; i++)
+ preoff += preimage->line[i].len;
+ preimage_end = preimage->buf + preoff;
+ for ( ; buf < preimage_end; buf++)
+ if (!isspace(*buf))
+ return 0;
/*
- * Update the preimage buffer and the postimage context lines.
+ * Update the preimage and the common postimage context
+ * lines to use the same whitespace as the target.
+ * If whitespace is missing in the target (i.e.
+ * if the preimage extends beyond the end of the file),
+ * use the whitespace from the preimage.
*/
+ extra_chars = preimage_end - preimage_eof;
+ fixed_buf = xmalloc(imgoff + extra_chars);
+ memcpy(fixed_buf, img->buf + try, imgoff);
+ memcpy(fixed_buf + imgoff, preimage_eof, extra_chars);
+ imgoff += extra_chars;
update_pre_post_images(preimage, postimage,
fixed_buf, imgoff, postlen);
return 1;
@@ -1932,12 +1994,16 @@ static int match_fragment(struct image *img,
* it might with whitespace fuzz. We haven't been asked to
* ignore whitespace, we were asked to correct whitespace
* errors, so let's try matching after whitespace correction.
+ *
+ * The preimage may extend beyond the end of the file,
+ * but in this loop we will only handle the part of the
+ * preimage that falls within the file.
*/
fixed_buf = xmalloc(preimage->len + 1);
buf = fixed_buf;
orig = preimage->buf;
target = img->buf + try;
- for (i = 0; i < preimage->nr; i++) {
+ for (i = 0; i < preimage_limit; i++) {
size_t fixlen; /* length after fixing the preimage */
size_t oldlen = preimage->line[i].len;
size_t tgtlen = img->line[try_lno + i].len;
@@ -1977,6 +2043,29 @@ static int match_fragment(struct image *img,
target += tgtlen;
}
+
+ /*
+ * Now handle the lines in the preimage that falls beyond the
+ * end of the file (if any). They will only match if they are
+ * empty or only contain whitespace (if WS_BLANK_AT_EOL is
+ * false).
+ */
+ for ( ; i < preimage->nr; i++) {
+ size_t fixlen; /* length after fixing the preimage */
+ size_t oldlen = preimage->line[i].len;
+ int j;
+
+ /* Try fixing the line in the preimage */
+ fixlen = ws_fix_copy(buf, orig, oldlen, ws_rule, NULL);
+
+ for (j = 0; j < fixlen; j++)
+ if (!isspace(buf[j]))
+ goto unmatch_exit;
+
+ orig += oldlen;
+ buf += fixlen;
+ }
+
/*
* Yes, the preimage is based on an older version that still
* has whitespace breakages unfixed, and fixing them makes the
@@ -2002,9 +2091,6 @@ static int find_pos(struct image *img,
unsigned long backwards, forwards, try;
int backwards_lno, forwards_lno, try_lno;
- if (preimage->nr > img->nr)
- return -1;
-
/*
* If match_beginning or match_end is specified, there is no
* point starting from a wrong line that will never match and
@@ -2015,7 +2101,12 @@ static int find_pos(struct image *img,
else if (match_end)
line = img->nr - preimage->nr;
- if (line > img->nr)
+ /*
+ * Because the comparison is unsigned, the following test
+ * will also take care of a negative line number that can
+ * result when match_end and preimage is larger than the target.
+ */
+ if ((size_t) line > img->nr)
line = img->nr;
try = 0;
@@ -2091,12 +2182,26 @@ static void update_image(struct image *img,
int i, nr;
size_t remove_count, insert_count, applied_at = 0;
char *result;
+ int preimage_limit;
+
+ /*
+ * If we are removing blank lines at the end of img,
+ * the preimage may extend beyond the end.
+ * If that is the case, we must be careful only to
+ * remove the part of the preimage that falls within
+ * the boundaries of img. Initialize preimage_limit
+ * to the number of lines in the preimage that falls
+ * within the boundaries.
+ */
+ preimage_limit = preimage->nr;
+ if (preimage_limit > img->nr - applied_pos)
+ preimage_limit = img->nr - applied_pos;
for (i = 0; i < applied_pos; i++)
applied_at += img->line[i].len;
remove_count = 0;
- for (i = 0; i < preimage->nr; i++)
+ for (i = 0; i < preimage_limit; i++)
remove_count += img->line[applied_pos + i].len;
insert_count = postimage->len;
@@ -2113,8 +2218,8 @@ static void update_image(struct image *img,
result[img->len] = '\0';
/* Adjust the line table */
- nr = img->nr + postimage->nr - preimage->nr;
- if (preimage->nr < postimage->nr) {
+ nr = img->nr + postimage->nr - preimage_limit;
+ if (preimage_limit < postimage->nr) {
/*
* NOTE: this knows that we never call remove_first_line()
* on anything other than pre/post image.
@@ -2122,10 +2227,10 @@ static void update_image(struct image *img,
img->line = xrealloc(img->line, nr * sizeof(*img->line));
img->line_allocated = img->line;
}
- if (preimage->nr != postimage->nr)
+ if (preimage_limit != postimage->nr)
memmove(img->line + applied_pos + postimage->nr,
- img->line + applied_pos + preimage->nr,
- (img->nr - (applied_pos + preimage->nr)) *
+ img->line + applied_pos + preimage_limit,
+ (img->nr - (applied_pos + preimage_limit)) *
sizeof(*img->line));
memcpy(img->line + applied_pos,
postimage->line,
@@ -2321,7 +2426,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
if (applied_pos >= 0) {
if (new_blank_lines_at_end &&
- preimage.nr + applied_pos == img->nr &&
+ preimage.nr + applied_pos >= img->nr &&
(ws_rule & WS_BLANK_AT_EOF) &&
ws_error_action != nowarn_ws_error) {
record_ws_error(WS_BLANK_AT_EOF, "+", 1, frag->linenr);
@@ -2719,11 +2824,8 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
if (stat_ret < 0) {
struct checkout costate;
/* checkout */
+ memset(&costate, 0, sizeof(costate));
costate.base_dir = "";
- costate.base_dir_len = 0;
- costate.force = 0;
- costate.quiet = 0;
- costate.not_new = 0;
costate.refresh_cache = 1;
if (checkout_entry(*ce, &costate, NULL) ||
lstat(old_name, st))
diff --git a/builtin-fast-export.c b/builtin-fast-export.c
index b0a4029c9..c6dd71a7b 100644
--- a/builtin-fast-export.c
+++ b/builtin-fast-export.c
@@ -503,7 +503,7 @@ static void export_marks(char *file)
f = fopen(file, "w");
if (!f)
- error("Unable to open marks file %s for writing.", file);
+ die_errno("Unable to open marks file %s for writing.", file);
for (i = 0; i < idnums.size; i++) {
if (deco->base && deco->base->type == 1) {
diff --git a/builtin-fetch.c b/builtin-fetch.c
index bbc425b65..007dabf62 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -13,10 +13,10 @@
#include "sigchain.h"
static const char * const builtin_fetch_usage[] = {
- "git fetch [options] [<repository> <refspec>...]",
- "git fetch [options] <group>",
- "git fetch --multiple [options] [<repository> | <group>]...",
- "git fetch --all [options]",
+ "git fetch [<options>] [<repository> [<refspec>...]]",
+ "git fetch [<options>] <group>",
+ "git fetch --multiple [<options>] [<repository> | <group>]...",
+ "git fetch --all [<options>]",
NULL
};
diff --git a/builtin-log.c b/builtin-log.c
index e0d5caa61..76962e1b0 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -1106,8 +1106,15 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
return 0;
}
- if (ignore_if_in_upstream)
+ if (ignore_if_in_upstream) {
+ /* Don't say anything if head and upstream are the same. */
+ if (rev.pending.nr == 2) {
+ struct object_array_entry *o = rev.pending.objects;
+ if (hashcmp(o[0].item->sha1, o[1].item->sha1) == 0)
+ return 0;
+ }
get_patch_ids(&rev, &ids, prefix);
+ }
if (!use_stdout)
realstdout = xfdopen(xdup(1), "w");
diff --git a/builtin-push.c b/builtin-push.c
index f7bc2b292..9fc693124 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -10,7 +10,7 @@
#include "parse-options.h"
static const char * const push_usage[] = {
- "git push [<options>] [<repository> <refspec>...]",
+ "git push [<options>] [<repository> [<refspec>...]]",
NULL,
};
diff --git a/builtin-reflog.c b/builtin-reflog.c
index 64e45bd81..bd7880dc0 100644
--- a/builtin-reflog.c
+++ b/builtin-reflog.c
@@ -13,7 +13,7 @@
*/
static const char reflog_expire_usage[] =
-"git reflog (show|expire) [--verbose] [--dry-run] [--stale-fix] [--expire=<time>] [--expire-unreachable=<time>] [--all] <refs>...";
+"git reflog expire [--verbose] [--dry-run] [--stale-fix] [--expire=<time>] [--expire-unreachable=<time>] [--all] <refs>...";
static const char reflog_delete_usage[] =
"git reflog delete [--verbose] [--dry-run] [--rewrite] [--updateref] <refs>...";
diff --git a/builtin-reset.c b/builtin-reset.c
index 0f5022eed..a174a3161 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -23,7 +23,8 @@
static const char * const git_reset_usage[] = {
"git reset [--mixed | --soft | --hard | --merge] [-q] [<commit>]",
- "git reset [--mixed] <commit> [--] <paths>...",
+ "git reset [-q] <commit> [--] <paths>...",
+ "git reset --patch [<commit>] [--] [<paths>...]",
NULL
};
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index eb8e2c205..51ceb19d8 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -133,9 +133,12 @@ static void show_commit(struct commit *commit, void *data)
*/
if (graph_show_remainder(revs->graph))
putchar('\n');
+ if (revs->commit_format == CMIT_FMT_ONELINE)
+ putchar('\n');
}
} else {
- if (buf.len)
+ if (revs->commit_format != CMIT_FMT_USERFORMAT ||
+ buf.len)
printf("%s%c", buf.buf, info->hdr_termination);
}
strbuf_release(&buf);
diff --git a/color.c b/color.c
index 62977f480..e8bcac0a7 100644
--- a/color.c
+++ b/color.c
@@ -47,7 +47,7 @@ void color_parse_mem(const char *value, int value_len, const char *var,
{
const char *ptr = value;
int len = value_len;
- int attr = -1;
+ unsigned int attr = 0;
int fg = -2;
int bg = -2;
@@ -56,7 +56,7 @@ void color_parse_mem(const char *value, int value_len, const char *var,
return;
}
- /* [fg [bg]] [attr] */
+ /* [fg [bg]] [attr]... */
while (len > 0) {
const char *word = ptr;
int val, wordlen = 0;
@@ -85,19 +85,27 @@ void color_parse_mem(const char *value, int value_len, const char *var,
goto bad;
}
val = parse_attr(word, wordlen);
- if (val < 0 || attr != -1)
+ if (0 <= val)
+ attr |= (1 << val);
+ else
goto bad;
- attr = val;
}
- if (attr >= 0 || fg >= 0 || bg >= 0) {
+ if (attr || fg >= 0 || bg >= 0) {
int sep = 0;
+ int i;
*dst++ = '\033';
*dst++ = '[';
- if (attr >= 0) {
- *dst++ = '0' + attr;
- sep++;
+
+ for (i = 0; attr; i++) {
+ unsigned bit = (1 << i);
+ if (!(attr & bit))
+ continue;
+ attr &= ~bit;
+ if (sep++)
+ *dst++ = ';';
+ *dst++ = '0' + i;
}
if (fg >= 0) {
if (sep++)
diff --git a/color.h b/color.h
index 3cb4b7fc8..bcb28cf10 100644
--- a/color.h
+++ b/color.h
@@ -1,8 +1,20 @@
#ifndef COLOR_H
#define COLOR_H
-/* "\033[1;38;5;2xx;48;5;2xxm\0" is 23 bytes */
-#define COLOR_MAXLEN 24
+/* 2 + (2 * num_attrs) + 8 + 1 + 8 + 'm' + NUL */
+/* "\033[1;2;4;5;7;38;5;2xx;48;5;2xxm\0" */
+/*
+ * The maximum length of ANSI color sequence we would generate:
+ * - leading ESC '[' 2
+ * - attr + ';' 2 * 8 (e.g. "1;")
+ * - fg color + ';' 9 (e.g. "38;5;2xx;")
+ * - fg color + ';' 9 (e.g. "48;5;2xx;")
+ * - terminating 'm' NUL 2
+ *
+ * The above overcounts attr (we only use 5 not 8) and one semicolon
+ * but it is close enough.
+ */
+#define COLOR_MAXLEN 40
/*
* IMPORTANT: Due to the way these color codes are emulated on Windows,
diff --git a/combine-diff.c b/combine-diff.c
index 61626912e..3480dae82 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -204,7 +204,7 @@ static void consume_line(void *state_, char *line, unsigned long len)
static void combine_diff(const unsigned char *parent, unsigned int mode,
mmfile_t *result_file,
struct sline *sline, unsigned int cnt, int n,
- int num_parent)
+ int num_parent, int result_deleted)
{
unsigned int p_lno, lno;
unsigned long nmask = (1UL << n);
@@ -215,7 +215,7 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
struct combine_diff_state state;
unsigned long sz;
- if (!cnt)
+ if (result_deleted)
return; /* result deleted */
parent_file.ptr = grab_blob(parent, mode, &sz);
@@ -517,7 +517,7 @@ static void show_line_to_eol(const char *line, int len, const char *reset)
}
static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
- int use_color)
+ int use_color, int result_deleted)
{
unsigned long mark = (1UL<<num_parent);
unsigned long no_pre_delete = (2UL<<num_parent);
@@ -530,7 +530,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
const char *c_plain = diff_get_color(use_color, DIFF_PLAIN);
const char *c_reset = diff_get_color(use_color, DIFF_RESET);
- if (!cnt)
+ if (result_deleted)
return; /* result deleted */
while (1) {
@@ -687,6 +687,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
{
struct diff_options *opt = &rev->diffopt;
unsigned long result_size, cnt, lno;
+ int result_deleted = 0;
char *result, *cp;
struct sline *sline; /* survived lines */
int mode_differs = 0;
@@ -767,6 +768,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
}
else {
deleted_file:
+ result_deleted = 1;
result_size = 0;
elem->mode = 0;
result = xcalloc(1, 1);
@@ -823,7 +825,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
combine_diff(elem->parent[i].sha1,
elem->parent[i].mode,
&result_file, sline,
- cnt, i, num_parent);
+ cnt, i, num_parent, result_deleted);
if (elem->parent[i].mode != elem->mode)
mode_differs = 1;
}
@@ -889,7 +891,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
dump_quoted_path("+++ ", b_prefix, elem->path,
c_meta, c_reset);
dump_sline(sline, cnt, num_parent,
- DIFF_OPT_TST(opt, COLOR_DIFF));
+ DIFF_OPT_TST(opt, COLOR_DIFF), result_deleted);
}
free(result);
diff --git a/compat/bswap.h b/compat/bswap.h
index f3b8c4418..54756dbb0 100644
--- a/compat/bswap.h
+++ b/compat/bswap.h
@@ -17,6 +17,8 @@ static inline uint32_t default_swab32(uint32_t val)
((val & 0x000000ff) << 24));
}
+#undef bswap32
+
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
#define bswap32(x) ({ \
diff --git a/compat/mingw.c b/compat/mingw.c
index ab65f77ab..59b18dc7c 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -259,8 +259,17 @@ int mingw_utime (const char *file_name, const struct utimbuf *times)
int fh, rc;
/* must have write permission */
- if ((fh = open(file_name, O_RDWR | O_BINARY)) < 0)
- return -1;
+ DWORD attrs = GetFileAttributes(file_name);
+ if (attrs != INVALID_FILE_ATTRIBUTES &&
+ (attrs & FILE_ATTRIBUTE_READONLY)) {
+ /* ignore errors here; open() will report them */
+ SetFileAttributes(file_name, attrs & ~FILE_ATTRIBUTE_READONLY);
+ }
+
+ if ((fh = open(file_name, O_RDWR | O_BINARY)) < 0) {
+ rc = -1;
+ goto revert_attrs;
+ }
time_t_to_filetime(times->modtime, &mft);
time_t_to_filetime(times->actime, &aft);
@@ -270,6 +279,13 @@ int mingw_utime (const char *file_name, const struct utimbuf *times)
} else
rc = 0;
close(fh);
+
+revert_attrs:
+ if (attrs != INVALID_FILE_ATTRIBUTES &&
+ (attrs & FILE_ATTRIBUTE_READONLY)) {
+ /* ignore errors again */
+ SetFileAttributes(file_name, attrs);
+ }
return rc;
}
diff --git a/compat/vcbuild/include/termios.h b/compat/vcbuild/include/termios.h
new file mode 100644
index 000000000..0d8552a2c
--- /dev/null
+++ b/compat/vcbuild/include/termios.h
@@ -0,0 +1 @@
+/* Intentionally empty file to support building git with MSVC */
diff --git a/contrib/fast-import/import-zips.py b/contrib/fast-import/import-zips.py
index 7051a83a5..82f5ed3dd 100755
--- a/contrib/fast-import/import-zips.py
+++ b/contrib/fast-import/import-zips.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
## zip archive frontend for git-fast-import
##
diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py
index 854cd94ba..046cb2b26 100755
--- a/contrib/hg-to-git/hg-to-git.py
+++ b/contrib/hg-to-git/hg-to-git.py
@@ -1,4 +1,4 @@
-#! /usr/bin/python
+#!/usr/bin/env python
""" hg-to-git.py - A Mercurial to GIT converter
diff --git a/contrib/p4import/git-p4import.py b/contrib/p4import/git-p4import.py
index 0f3d97b67..b6e534b65 100644
--- a/contrib/p4import/git-p4import.py
+++ b/contrib/p4import/git-p4import.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
#
# This tool is copyright (c) 2006, Sean Estabrooks.
# It is released under the Gnu Public License, version 2.
diff --git a/daemon.c b/daemon.c
index 7d9e1c03e..a90ab1050 100644
--- a/daemon.c
+++ b/daemon.c
@@ -590,14 +590,17 @@ static int execute(struct sockaddr *addr)
static int addrcmp(const struct sockaddr_storage *s1,
const struct sockaddr_storage *s2)
{
- if (s1->ss_family != s2->ss_family)
- return s1->ss_family - s2->ss_family;
- if (s1->ss_family == AF_INET)
+ const struct sockaddr *sa1 = (const struct sockaddr*) s1;
+ const struct sockaddr *sa2 = (const struct sockaddr*) s2;
+
+ if (sa1->sa_family != sa2->sa_family)
+ return sa1->sa_family - sa2->sa_family;
+ if (sa1->sa_family == AF_INET)
return memcmp(&((struct sockaddr_in *)s1)->sin_addr,
&((struct sockaddr_in *)s2)->sin_addr,
sizeof(struct in_addr));
#ifndef NO_IPV6
- if (s1->ss_family == AF_INET6)
+ if (sa1->sa_family == AF_INET6)
return memcmp(&((struct sockaddr_in6 *)s1)->sin6_addr,
&((struct sockaddr_in6 *)s2)->sin6_addr,
sizeof(struct in6_addr));
diff --git a/diff.c b/diff.c
index 0d465faa1..edec0f6b8 100644
--- a/diff.c
+++ b/diff.c
@@ -14,6 +14,7 @@
#include "userdiff.h"
#include "sigchain.h"
#include "submodule.h"
+#include "ll-merge.h"
#ifdef NO_FAST_WORKING_DIRECTORY
#define FAST_WORKING_DIRECTORY 0
@@ -948,7 +949,7 @@ struct diffstat_t {
unsigned is_unmerged:1;
unsigned is_binary:1;
unsigned is_renamed:1;
- unsigned int added, deleted;
+ uintmax_t added, deleted;
} **files;
};
@@ -1040,7 +1041,7 @@ static void fill_print_name(struct diffstat_file *file)
static void show_stats(struct diffstat_t *data, struct diff_options *options)
{
int i, len, add, del, adds = 0, dels = 0;
- int max_change = 0, max_len = 0;
+ uintmax_t max_change = 0, max_len = 0;
int total_files = data->nr;
int width, name_width;
const char *reset, *set, *add_c, *del_c;
@@ -1069,7 +1070,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
for (i = 0; i < data->nr; i++) {
struct diffstat_file *file = data->files[i];
- int change = file->added + file->deleted;
+ uintmax_t change = file->added + file->deleted;
fill_print_name(file);
len = strlen(file->print_name);
if (max_len < len)
@@ -1097,8 +1098,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
for (i = 0; i < data->nr; i++) {
const char *prefix = "";
char *name = data->files[i]->print_name;
- int added = data->files[i]->added;
- int deleted = data->files[i]->deleted;
+ uintmax_t added = data->files[i]->added;
+ uintmax_t deleted = data->files[i]->deleted;
int name_len;
/*
@@ -1119,9 +1120,11 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
if (data->files[i]->is_binary) {
show_name(options->file, prefix, name, len);
fprintf(options->file, " Bin ");
- fprintf(options->file, "%s%d%s", del_c, deleted, reset);
+ fprintf(options->file, "%s%"PRIuMAX"%s",
+ del_c, deleted, reset);
fprintf(options->file, " -> ");
- fprintf(options->file, "%s%d%s", add_c, added, reset);
+ fprintf(options->file, "%s%"PRIuMAX"%s",
+ add_c, added, reset);
fprintf(options->file, " bytes");
fprintf(options->file, "\n");
continue;
@@ -1150,7 +1153,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
del = scale_linear(del, width, max_change);
}
show_name(options->file, prefix, name, len);
- fprintf(options->file, "%5d%s", added + deleted,
+ fprintf(options->file, "%5"PRIuMAX"%s", added + deleted,
added + deleted ? " " : "");
show_graph(options->file, '+', add, add_c, reset);
show_graph(options->file, '-', del, del_c, reset);
@@ -1200,7 +1203,8 @@ static void show_numstat(struct diffstat_t *data, struct diff_options *options)
fprintf(options->file, "-\t-\t");
else
fprintf(options->file,
- "%d\t%d\t", file->added, file->deleted);
+ "%"PRIuMAX"\t%"PRIuMAX"\t",
+ file->added, file->deleted);
if (options->line_termination) {
fill_print_name(file);
if (!file->is_renamed)
@@ -1370,37 +1374,32 @@ static void free_diffstat_info(struct diffstat_t *diffstat)
struct checkdiff_t {
const char *filename;
int lineno;
+ int conflict_marker_size;
struct diff_options *o;
unsigned ws_rule;
unsigned status;
};
-static int is_conflict_marker(const char *line, unsigned long len)
+static int is_conflict_marker(const char *line, int marker_size, unsigned long len)
{
char firstchar;
int cnt;
- if (len < 8)
+ if (len < marker_size + 1)
return 0;
firstchar = line[0];
switch (firstchar) {
- case '=': case '>': case '<':
+ case '=': case '>': case '<': case '|':
break;
default:
return 0;
}
- for (cnt = 1; cnt < 7; cnt++)
+ for (cnt = 1; cnt < marker_size; cnt++)
if (line[cnt] != firstchar)
return 0;
- /* line[0] thru line[6] are same as firstchar */
- if (firstchar == '=') {
- /* divider between ours and theirs? */
- if (len != 8 || line[7] != '\n')
- return 0;
- } else if (len < 8 || !isspace(line[7])) {
- /* not divider before ours nor after theirs */
+ /* line[1] thru line[marker_size-1] are same as firstchar */
+ if (len < marker_size + 1 || !isspace(line[marker_size]))
return 0;
- }
return 1;
}
@@ -1408,6 +1407,7 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)
{
struct checkdiff_t *data = priv;
int color_diff = DIFF_OPT_TST(data->o, COLOR_DIFF);
+ int marker_size = data->conflict_marker_size;
const char *ws = diff_get_color(color_diff, DIFF_WHITESPACE);
const char *reset = diff_get_color(color_diff, DIFF_RESET);
const char *set = diff_get_color(color_diff, DIFF_FILE_NEW);
@@ -1416,7 +1416,7 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)
if (line[0] == '+') {
unsigned bad;
data->lineno++;
- if (is_conflict_marker(line + 1, len - 1)) {
+ if (is_conflict_marker(line + 1, marker_size, len - 1)) {
data->status |= 1;
fprintf(data->o->file,
"%s:%d: leftover conflict marker\n",
@@ -1860,6 +1860,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
data.lineno = 0;
data.o = o;
data.ws_rule = whitespace_rule(attr_path);
+ data.conflict_marker_size = ll_merge_marker_size(attr_path);
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
die("unable to read files to diff");
@@ -3865,6 +3866,7 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,
const char **arg = argv;
struct child_process child;
struct strbuf buf = STRBUF_INIT;
+ int err = 0;
temp = prepare_temp_file(spec->path, spec);
*arg++ = pgm;
@@ -3875,16 +3877,20 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,
child.use_shell = 1;
child.argv = argv;
child.out = -1;
- if (start_command(&child) != 0 ||
- strbuf_read(&buf, child.out, 0) < 0 ||
- finish_command(&child) != 0) {
- close(child.out);
- strbuf_release(&buf);
+ if (start_command(&child)) {
remove_tempfile();
- error("error running textconv command '%s'", pgm);
return NULL;
}
+
+ if (strbuf_read(&buf, child.out, 0) < 0)
+ err = error("error reading from textconv command '%s'", pgm);
close(child.out);
+
+ if (finish_command(&child) || err) {
+ strbuf_release(&buf);
+ remove_tempfile();
+ return NULL;
+ }
remove_tempfile();
return strbuf_detach(&buf, outsize);
diff --git a/dir.c b/dir.c
index 133c333df..cb83332a2 100644
--- a/dir.c
+++ b/dir.c
@@ -594,13 +594,29 @@ static int simplify_away(const char *path, int pathlen, const struct path_simpli
return 0;
}
-static int in_pathspec(const char *path, int len, const struct path_simplify *simplify)
+/*
+ * This function tells us whether an excluded path matches a
+ * list of "interesting" pathspecs. That is, whether a path matched
+ * by any of the pathspecs could possibly be ignored by excluding
+ * the specified path. This can happen if:
+ *
+ * 1. the path is mentioned explicitly in the pathspec
+ *
+ * 2. the path is a directory prefix of some element in the
+ * pathspec
+ */
+static int exclude_matches_pathspec(const char *path, int len,
+ const struct path_simplify *simplify)
{
if (simplify) {
for (; simplify->path; simplify++) {
if (len == simplify->len
&& !memcmp(path, simplify->path, len))
return 1;
+ if (len < simplify->len
+ && simplify->path[len] == '/'
+ && !memcmp(path, simplify->path, len))
+ return 1;
}
}
return 0;
@@ -678,7 +694,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
{
int exclude = excluded(dir, path, &dtype);
if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
- && in_pathspec(path, *len, simplify))
+ && exclude_matches_pathspec(path, *len, simplify))
dir_add_ignored(dir, path, *len);
/*
diff --git a/git-difftool.perl b/git-difftool.perl
index d975d072d..adc42de87 100755
--- a/git-difftool.perl
+++ b/git-difftool.perl
@@ -78,11 +78,13 @@ sub generate_command
next;
}
if ($arg eq '-g' || $arg eq '--gui') {
- my $tool = Git::command_oneline('config',
- 'diff.guitool');
- if (length($tool)) {
- $ENV{GIT_DIFF_TOOL} = $tool;
- }
+ eval {
+ my $tool = Git::command_oneline('config',
+ 'diff.guitool');
+ if (length($tool)) {
+ $ENV{GIT_DIFF_TOOL} = $tool;
+ }
+ };
next;
}
if ($arg eq '-y' || $arg eq '--no-prompt') {
diff --git a/git-send-email.perl b/git-send-email.perl
index e05455f74..1b99f4039 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -162,9 +162,12 @@ my $compose_filename;
# Handle interactive edition of files.
my $multiedit;
-my $editor = Git::command_oneline('var', 'GIT_EDITOR');
+my $editor;
sub do_edit {
+ if (!defined($editor)) {
+ $editor = Git::command_oneline('var', 'GIT_EDITOR');
+ }
if (defined($multiedit) && !$multiedit) {
map {
system('sh', '-c', $editor.' "$@"', $editor, $_);
diff --git a/git-stash.sh b/git-stash.sh
index aa47e541e..59db3dc38 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -210,14 +210,18 @@ list_stash () {
}
show_stash () {
+ have_stash || die 'No stash found'
+
flags=$(git rev-parse --no-revs --flags "$@")
if test -z "$flags"
then
flags=--stat
fi
- w_commit=$(git rev-parse --verify --default $ref_stash "$@") &&
- b_commit=$(git rev-parse --verify "$w_commit^") &&
+ w_commit=$(git rev-parse --quiet --verify --default $ref_stash "$@") &&
+ b_commit=$(git rev-parse --quiet --verify "$w_commit^") ||
+ die "'$*' is not a stash"
+
git diff $flags $b_commit $w_commit
}
diff --git a/git_remote_helpers/Makefile b/git_remote_helpers/Makefile
index c62dfd0f4..74b05dc91 100644
--- a/git_remote_helpers/Makefile
+++ b/git_remote_helpers/Makefile
@@ -7,7 +7,11 @@ pysetupfile:=setup.py
DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
ifndef PYTHON_PATH
- PYTHON_PATH = /usr/bin/python
+ ifeq ($(uname_S),FreeBSD)
+ PYTHON_PATH = /usr/local/bin/python
+ else
+ PYTHON_PATH = /usr/bin/python
+ endif
endif
ifndef prefix
prefix = $(HOME)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 3d80deba0..9d4c58238 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -2209,8 +2209,7 @@ sub config_to_multi {
sub git_get_project_config {
my ($key, $type) = @_;
- # do we have project
- return unless (defined $project && defined $git_dir);
+ return unless defined $git_dir;
# key sanity check
return unless ($key);
diff --git a/http-backend.c b/http-backend.c
index 345c12b79..d1e83d090 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -538,15 +538,19 @@ static void service_rpc(char *service_name)
static NORETURN void die_webcgi(const char *err, va_list params)
{
- char buffer[1000];
+ static int dead;
- http_status(500, "Internal Server Error");
- hdr_nocache();
- end_headers();
+ if (!dead) {
+ char buffer[1000];
+ dead = 1;
- vsnprintf(buffer, sizeof(buffer), err, params);
- fprintf(stderr, "fatal: %s\n", buffer);
- exit(0);
+ vsnprintf(buffer, sizeof(buffer), err, params);
+ fprintf(stderr, "fatal: %s\n", buffer);
+ http_status(500, "Internal Server Error");
+ hdr_nocache();
+ end_headers();
+ }
+ exit(0); /* we successfully reported a failure ;-) */
}
static char* getdir(void)
diff --git a/imap-send.c b/imap-send.c
index 5631930bc..379dec491 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -1306,8 +1306,14 @@ static int count_messages(struct msg_data *msg)
while (1) {
if (!prefixcmp(p, "From ")) {
+ p = strstr(p+5, "\nFrom: ");
+ if (!p) break;
+ p = strstr(p+7, "\nDate: ");
+ if (!p) break;
+ p = strstr(p+7, "\nSubject: ");
+ if (!p) break;
+ p += 10;
count++;
- p += 5;
}
p = strstr(p+5, "\nFrom ");
if (!p)
diff --git a/refs.c b/refs.c
index 63e30d74a..a7518b6f0 100644
--- a/refs.c
+++ b/refs.c
@@ -6,6 +6,7 @@
/* ISSYMREF=01 and ISPACKED=02 are public interfaces */
#define REF_KNOWS_PEELED 04
+#define REF_BROKEN 010
struct ref_list {
struct ref_list *next;
@@ -275,8 +276,10 @@ static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)
list = get_ref_dir(ref, list);
continue;
}
- if (!resolve_ref(ref, sha1, 1, &flag))
+ if (!resolve_ref(ref, sha1, 1, &flag)) {
hashclr(sha1);
+ flag |= REF_BROKEN;
+ }
list = add_ref(ref, sha1, flag, list, NULL);
}
free(ref);
@@ -539,10 +542,10 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim,
{
if (strncmp(base, entry->name, trim))
return 0;
- /* Is this a "negative ref" that represents a deleted ref? */
- if (is_null_sha1(entry->sha1))
- return 0;
+
if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) {
+ if (entry->flag & REF_BROKEN)
+ return 0; /* ignore dangling symref */
if (!has_sha1_file(entry->sha1)) {
error("%s does not point to a valid object!", entry->name);
return 0;
diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh
index 89282ccf7..41df6bcf2 100755
--- a/t/t0050-filesystem.sh
+++ b/t/t0050-filesystem.sh
@@ -108,13 +108,17 @@ $test_case 'merge (case change)' '
'
-$test_case 'add (with different case)' '
+
+
+test_expect_failure 'add (with different case)' '
git reset --hard initial &&
rm camelcase &&
echo 1 >CamelCase &&
git add CamelCase &&
- test $(git ls-files | grep -i camelcase | wc -l) = 1
+ camel=$(git ls-files | grep -i camelcase) &&
+ test $(echo "$camel" | wc -l) = 1 &&
+ test "z$(git cat-file blob :$camel)" = z1
'
diff --git a/t/t1010-mktree.sh b/t/t1010-mktree.sh
index 9956e3ad6..b946f8768 100755
--- a/t/t1010-mktree.sh
+++ b/t/t1010-mktree.sh
@@ -58,14 +58,12 @@ test_expect_success 'allow missing object with --missing' '
test_cmp tree.missing actual
'
-test_expect_failure 'mktree reads ls-tree -r output (1)' '
- git mktree <all >actual &&
- test_cmp tree actual
+test_expect_success 'mktree refuses to read ls-tree -r output (1)' '
+ test_must_fail git mktree <all >actual
'
-test_expect_failure 'mktree reads ls-tree -r output (2)' '
- git mktree <all.withsub >actual &&
- test_cmp tree.withsub actual
+test_expect_success 'mktree refuses to read ls-tree -r output (2)' '
+ test_must_fail git mktree <all.withsub >actual
'
test_done
diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh
index 912075063..2ad2819a3 100755
--- a/t/t2200-add-update.sh
+++ b/t/t2200-add-update.sh
@@ -176,4 +176,9 @@ test_expect_success 'add -u resolves unmerged paths' '
'
+test_expect_success '"add -u non-existent" should fail' '
+ test_must_fail git add -u non-existent &&
+ ! (git ls-files | grep "non-existent")
+'
+
test_done
diff --git a/t/t2204-add-ignored.sh b/t/t2204-add-ignored.sh
new file mode 100755
index 000000000..24afdabab
--- /dev/null
+++ b/t/t2204-add-ignored.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+test_description='giving ignored paths to git add'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ mkdir sub dir dir/sub &&
+ echo sub >.gitignore &&
+ echo ign >>.gitignore &&
+ for p in . sub dir dir/sub
+ do
+ >"$p/ign" &&
+ >"$p/file" || exit 1
+ done
+'
+
+for i in file dir/file dir 'd*'
+do
+ test_expect_success "no complaints for unignored $i" '
+ rm -f .git/index &&
+ git add "$i" &&
+ git ls-files "$i" >out &&
+ test -s out
+ '
+done
+
+for i in ign dir/ign dir/sub dir/sub/*ign sub/file sub sub/*
+do
+ test_expect_success "complaints for ignored $i" '
+ rm -f .git/index &&
+ test_must_fail git add "$i" 2>err &&
+ git ls-files "$i" >out &&
+ ! test -s out &&
+ grep -e "Use -f if" err &&
+ cat err
+ '
+
+ test_expect_success "complaints for ignored $i with unignored file" '
+ rm -f .git/index &&
+ test_must_fail git add "$i" file 2>err &&
+ git ls-files "$i" >out &&
+ ! test -s out &&
+ grep -e "Use -f if" err &&
+ cat err
+ '
+done
+
+for i in sub sub/*
+do
+ test_expect_success "complaints for ignored $i in dir" '
+ rm -f .git/index &&
+ (
+ cd dir &&
+ test_must_fail git add "$i" 2>err &&
+ git ls-files "$i" >out &&
+ ! test -s out &&
+ grep -e "Use -f if" err &&
+ cat err
+ )
+ '
+done
+
+for i in ign file
+do
+ test_expect_success "complaints for ignored $i in sub" '
+ rm -f .git/index &&
+ (
+ cd sub &&
+ test_must_fail git add "$i" 2>err &&
+ git ls-files "$i" >out &&
+ ! test -s out &&
+ grep -e "Use -f if" err &&
+ cat err
+ )
+ '
+done
+
+test_done
diff --git a/t/t3417-rebase-whitespace-fix.sh b/t/t3417-rebase-whitespace-fix.sh
new file mode 100755
index 000000000..220a740ee
--- /dev/null
+++ b/t/t3417-rebase-whitespace-fix.sh
@@ -0,0 +1,126 @@
+#!/bin/sh
+
+test_description='git rebase --whitespace=fix
+
+This test runs git rebase --whitespace=fix and make sure that it works.
+'
+
+. ./test-lib.sh
+
+# prepare initial revision of "file" with a blank line at the end
+cat >file <<EOF
+a
+b
+c
+
+EOF
+
+# expected contents in "file" after rebase
+cat >expect-first <<EOF
+a
+b
+c
+EOF
+
+# prepare second revision of "file"
+cat >second <<EOF
+a
+b
+c
+
+d
+e
+f
+
+
+
+
+EOF
+
+# expected contents in second revision after rebase
+cat >expect-second <<EOF
+a
+b
+c
+
+d
+e
+f
+EOF
+
+test_expect_success 'blank line at end of file; extend at end of file' '
+ git commit --allow-empty -m "Initial empty commit" &&
+ git add file && git commit -m first &&
+ mv second file &&
+ git add file && git commit -m second &&
+ git rebase --whitespace=fix HEAD^^ &&
+ git diff --exit-code HEAD^:file expect-first &&
+ test_cmp file expect-second
+'
+
+# prepare third revision of "file"
+sed -e's/Z//' >third <<EOF
+a
+b
+c
+
+d
+e
+f
+ Z
+ Z
+h
+i
+j
+k
+l
+EOF
+
+sed -e's/ //g' <third >expect-third
+
+test_expect_success 'two blanks line at end of file; extend at end of file' '
+ cp third file && git add file && git commit -m third &&
+ git rebase --whitespace=fix HEAD^^ &&
+ git diff --exit-code HEAD^:file expect-second &&
+ test_cmp file expect-third
+'
+
+test_expect_success 'same, but do not remove trailing spaces' '
+ git config core.whitespace "-blank-at-eol" &&
+ git reset --hard HEAD^ &&
+ cp third file && git add file && git commit -m third &&
+ git rebase --whitespace=fix HEAD^^
+ git diff --exit-code HEAD^:file expect-second &&
+ test_cmp file third
+'
+
+sed -e's/Z//' >beginning <<EOF
+a
+ Z
+ Z
+EOF
+
+cat >expect-beginning <<EOF
+a
+
+
+1
+2
+3
+4
+5
+EOF
+
+test_expect_success 'at beginning of file' '
+ git config core.whitespace "blank-at-eol" &&
+ cp beginning file &&
+ git commit -m beginning file &&
+ for i in 1 2 3 4 5; do
+ echo $i
+ done >> file &&
+ git commit -m more file &&
+ git rebase --whitespace=fix HEAD^^ &&
+ test_cmp file expect-beginning
+'
+
+test_done
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index 85eb0fbf9..525c9a8fd 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -255,4 +255,9 @@ test_expect_success 'git add to resolve conflicts on otherwise ignored path' '
git add track-this
'
+test_expect_success '"add non-existent" should fail' '
+ test_must_fail git add non-existent &&
+ ! (git ls-files | grep "non-existent")
+'
+
test_done
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index f2a2aaa2b..843ef7f88 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -557,4 +557,8 @@ test_expect_success 'format-patch -- <path>' '
! grep "Use .--" error
'
+test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
+ git format-patch --ignore-if-in-upstream HEAD
+'
+
test_done
diff --git a/t/t4017-diff-retval.sh b/t/t4017-diff-retval.sh
index 0391a5827..61589853d 100755
--- a/t/t4017-diff-retval.sh
+++ b/t/t4017-diff-retval.sh
@@ -120,7 +120,6 @@ test_expect_success '--check with --no-pager returns 2 for dirty difference' '
'
-
test_expect_success 'check should test not just the last line' '
echo "" >>a &&
git --no-pager diff --check
@@ -142,4 +141,26 @@ test_expect_success 'check detects leftover conflict markers' '
git reset --hard
'
+test_expect_success 'check honors conflict marker length' '
+ git reset --hard &&
+ echo ">>>>>>> boo" >>b &&
+ echo "======" >>a &&
+ git diff --check a &&
+ (
+ git diff --check b
+ test $? = 2
+ ) &&
+ git reset --hard &&
+ echo ">>>>>>>> boo" >>b &&
+ echo "========" >>a &&
+ git diff --check &&
+ echo "b conflict-marker-size=8" >.gitattributes &&
+ (
+ git diff --check b
+ test $? = 2
+ ) &&
+ git diff --check a &&
+ git reset --hard
+'
+
test_done
diff --git a/t/t4026-color.sh b/t/t4026-color.sh
index 5ade44c04..d5ccdd0cf 100755
--- a/t/t4026-color.sh
+++ b/t/t4026-color.sh
@@ -8,14 +8,13 @@ test_description='Test diff/status color escape codes'
color()
{
- git config diff.color.new "$1" &&
- test "`git config --get-color diff.color.new`" = "$2"
+ actual=$(git config --get-color no.such.slot "$1") &&
+ test "$actual" = "$2"
}
invalid_color()
{
- git config diff.color.new "$1" &&
- test -z "`git config --get-color diff.color.new 2>/dev/null`"
+ test_must_fail git config --get-color no.such.slot "$1"
}
test_expect_success 'reset' '
@@ -42,6 +41,14 @@ test_expect_success 'fg bg attr' '
color "blue red ul" "[4;34;41m"
'
+test_expect_success 'fg bg attr...' '
+ color "blue bold dim ul blink reverse" "[1;2;4;5;7;34m"
+'
+
+test_expect_success 'long color specification' '
+ color "254 255 bold dim ul blink reverse" "[1;2;4;5;7;38;5;254;48;5;255m"
+'
+
test_expect_success '256 colors' '
color "254 bold 255" "[1;38;5;254;48;5;255m"
'
diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh
index 7584efa36..40277c77a 100755
--- a/t/t4038-diff-combined.sh
+++ b/t/t4038-diff-combined.sh
@@ -81,4 +81,12 @@ test_expect_success 'check combined output (2)' '
verify_helper sidesansone
'
+test_expect_success 'diagnose truncated file' '
+ >file &&
+ git add file &&
+ git commit --amend -C HEAD &&
+ git show >out &&
+ grep "diff --cc file" out
+'
+
test_done
diff --git a/t/t4104-apply-boundary.sh b/t/t4104-apply-boundary.sh
index 0e3ce3611..c617c2a33 100755
--- a/t/t4104-apply-boundary.sh
+++ b/t/t4104-apply-boundary.sh
@@ -134,4 +134,13 @@ test_expect_success 'two lines' '
'
+test_expect_success 'apply patch with 3 context lines matching at end' '
+ { echo a; echo b; echo c; echo d; } >file &&
+ git add file &&
+ echo e >>file &&
+ git diff >patch &&
+ >file &&
+ test_must_fail git apply patch
+'
+
test_done
diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh
index ca2639759..fb9ad247b 100755
--- a/t/t4124-apply-ws-rule.sh
+++ b/t/t4124-apply-ws-rule.sh
@@ -261,4 +261,174 @@ test_expect_success 'blank but not empty at EOF' '
grep "new blank line at EOF" error
'
+test_expect_success 'applying beyond EOF requires one non-blank context line' '
+ { echo; echo; echo; echo; } >one &&
+ git add one &&
+ { echo b; } >>one &&
+ git diff -- one >patch &&
+
+ git checkout one &&
+ { echo a; echo; } >one &&
+ cp one expect &&
+ test_must_fail git apply --whitespace=fix patch &&
+ test_cmp one expect &&
+ test_must_fail git apply --ignore-space-change --whitespace=fix patch &&
+ test_cmp one expect
+'
+
+test_expect_success 'tons of blanks at EOF should not apply' '
+ for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
+ echo; echo; echo; echo;
+ done >one &&
+ git add one &&
+ echo a >>one &&
+ git diff -- one >patch &&
+
+ >one &&
+ test_must_fail git apply --whitespace=fix patch &&
+ test_must_fail git apply --ignore-space-change --whitespace=fix patch
+'
+
+test_expect_success 'missing blank line at end with --whitespace=fix' '
+ echo a >one &&
+ echo >>one &&
+ git add one &&
+ echo b >>one &&
+ cp one expect &&
+ git diff -- one >patch &&
+ echo a >one &&
+ cp one saved-one &&
+ test_must_fail git apply patch &&
+ git apply --whitespace=fix patch &&
+ test_cmp one expect &&
+ mv saved-one one &&
+ git apply --ignore-space-change --whitespace=fix patch &&
+ test_cmp one expect
+'
+
+test_expect_success 'two missing blank lines at end with --whitespace=fix' '
+ { echo a; echo; echo b; echo c; } >one &&
+ cp one no-blank-lines &&
+ { echo; echo; } >>one &&
+ git add one &&
+ echo d >>one &&
+ cp one expect &&
+ echo >>one &&
+ git diff -- one >patch &&
+ cp no-blank-lines one &&
+ test_must_fail git apply patch &&
+ git apply --whitespace=fix patch &&
+ test_cmp one expect &&
+ mv no-blank-lines one &&
+ test_must_fail git apply patch &&
+ git apply --ignore-space-change --whitespace=fix patch &&
+ test_cmp one expect
+'
+
+test_expect_success 'shrink file with tons of missing blanks at end of file' '
+ { echo a; echo b; echo c; } >one &&
+ cp one no-blank-lines &&
+ for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
+ echo; echo; echo; echo;
+ done >>one &&
+ git add one &&
+ echo a >one &&
+ cp one expect &&
+ git diff -- one >patch &&
+ cp no-blank-lines one &&
+ test_must_fail git apply patch &&
+ git apply --whitespace=fix patch &&
+ test_cmp one expect &&
+ mv no-blank-lines one &&
+ git apply --ignore-space-change --whitespace=fix patch &&
+ test_cmp one expect
+'
+
+test_expect_success 'missing blanks at EOF must only match blank lines' '
+ { echo a; echo b; } >one &&
+ git add one &&
+ { echo c; echo d; } >>one &&
+ git diff -- one >patch &&
+
+ echo a >one &&
+ test_must_fail git apply patch
+ test_must_fail git apply --whitespace=fix patch &&
+ test_must_fail git apply --ignore-space-change --whitespace=fix patch
+'
+
+sed -e's/Z//' >one <<EOF
+a
+b
+c
+ Z
+EOF
+
+test_expect_success 'missing blank line should match context line with spaces' '
+ git add one &&
+ echo d >>one &&
+ git diff -- one >patch &&
+ { echo a; echo b; echo c; } >one &&
+ cp one expect &&
+ { echo; echo d; } >>expect &&
+ git add one &&
+
+ git apply --whitespace=fix patch &&
+ test_cmp one expect
+'
+
+sed -e's/Z//' >one <<EOF
+a
+b
+c
+ Z
+EOF
+
+test_expect_success 'same, but with the --ignore-space-option' '
+ git add one &&
+ echo d >>one &&
+ cp one expect &&
+ git diff -- one >patch &&
+ { echo a; echo b; echo c; } >one &&
+ git add one &&
+
+ git checkout-index -f one &&
+ git apply --ignore-space-change --whitespace=fix patch &&
+ test_cmp one expect
+'
+
+test_expect_success 'same, but with CR-LF line endings && cr-at-eol set' '
+ git config core.whitespace cr-at-eol &&
+ printf "a\r\n" >one &&
+ printf "b\r\n" >>one &&
+ printf "c\r\n" >>one &&
+ cp one save-one &&
+ printf " \r\n" >>one
+ git add one &&
+ printf "d\r\n" >>one &&
+ cp one expect &&
+ git diff -- one >patch &&
+ mv save-one one &&
+
+ git apply --ignore-space-change --whitespace=fix patch &&
+ test_cmp one expect
+'
+
+test_expect_success 'same, but with CR-LF line endings && cr-at-eol unset' '
+ git config --unset core.whitespace &&
+ printf "a\r\n" >one &&
+ printf "b\r\n" >>one &&
+ printf "c\r\n" >>one &&
+ cp one save-one &&
+ printf " \r\n" >>one
+ git add one &&
+ cp one expect &&
+ printf "d\r\n" >>one &&
+ git diff -- one >patch &&
+ mv save-one one &&
+ echo d >>expect &&
+
+ git apply --ignore-space-change --whitespace=fix patch &&
+ test_cmp one expect
+'
+
test_done
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index a82c5ffa1..269205020 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -507,15 +507,15 @@ test_expect_success 'remote prune to cause a dangling symref' '
(
cd seven &&
git remote prune origin
- ) 2>err &&
+ ) >err 2>&1 &&
grep "has become dangling" err &&
- : And the dangling symref will not cause other annoying errors
+ : And the dangling symref will not cause other annoying errors &&
(
cd seven &&
git branch -a
) 2>err &&
- ! grep "points nowhere" err
+ ! grep "points nowhere" err &&
(
cd seven &&
test_must_fail git branch nomore origin
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index b0047d3c6..d24ca5c07 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -209,4 +209,13 @@ test_expect_success '%gd shortens ref name' '
test_cmp expect.gd-short actual.gd-short
'
+test_expect_success 'oneline with empty message' '
+ git commit -m "dummy" --allow-empty &&
+ git commit -m "dummy" --allow-empty &&
+ git filter-branch --msg-filter "sed -e s/dummy//" HEAD^^.. &&
+ git rev-list --oneline HEAD > /tmp/test.txt &&
+ test $(git rev-list --oneline HEAD | wc -l) -eq 5 &&
+ test $(git rev-list --oneline --graph HEAD | wc -l) -eq 5
+'
+
test_done
diff --git a/t/t7012-skip-worktree-writing.sh b/t/t7012-skip-worktree-writing.sh
index 8d8b1c0e2..582d0b54f 100755
--- a/t/t7012-skip-worktree-writing.sh
+++ b/t/t7012-skip-worktree-writing.sh
@@ -136,11 +136,11 @@ test_expect_success 'git-clean, dirty case' '
test_cmp expected result
'
-test_expect_failure 'git-apply adds file' false
-test_expect_failure 'git-apply updates file' false
-test_expect_failure 'git-apply removes file' false
-test_expect_failure 'git-mv to skip-worktree' false
-test_expect_failure 'git-mv from skip-worktree' false
-test_expect_failure 'git-checkout' false
+#TODO test_expect_failure 'git-apply adds file' false
+#TODO test_expect_failure 'git-apply updates file' false
+#TODO test_expect_failure 'git-apply removes file' false
+#TODO test_expect_failure 'git-mv to skip-worktree' false
+#TODO test_expect_failure 'git-mv from skip-worktree' false
+#TODO test_expect_failure 'git-checkout' false
test_done
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index 19c72f55b..1de83ef98 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -92,6 +92,15 @@ test_expect_success 'difftool honors --gui' '
restore_test_defaults
'
+test_expect_success 'difftool --gui works without configured diff.guitool' '
+ git config diff.tool test-tool &&
+
+ diff=$(git difftool --no-prompt --gui branch) &&
+ test "$diff" = "branch" &&
+
+ restore_test_defaults
+'
+
# Specify the diff tool using $GIT_DIFF_TOOL
test_expect_success 'GIT_DIFF_TOOL variable' '
git config --unset diff.tool
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index 356964e53..d43f37cca 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -150,20 +150,22 @@ test_expect_success 'setup submodule' '
git checkout -f master &&
mkdir sub &&
- cd sub &&
- git init &&
- echo test file > file &&
- git add file &&
- git commit -m sub_initial &&
- cd .. &&
+ (
+ cd sub &&
+ git init &&
+ echo test file > file &&
+ git add file &&
+ git commit -m sub_initial
+ ) &&
git submodule add "`pwd`/sub" sub &&
git commit -m initial &&
test_tick &&
- cd sub &&
- echo more data >> file &&
- git add file &&
- git commit -m sub_second &&
- cd .. &&
+ (
+ cd sub &&
+ echo more data >> file &&
+ git add file &&
+ git commit -m sub_second
+ ) &&
git add sub &&
git commit -m second
@@ -264,19 +266,20 @@ test_expect_success 'cope with tagger-less tags' '
test_expect_success 'setup for limiting exports by PATH' '
mkdir limit-by-paths &&
- cd limit-by-paths &&
- git init &&
- echo hi > there &&
- git add there &&
- git commit -m "First file" &&
- echo foo > bar &&
- git add bar &&
- git commit -m "Second file" &&
- git tag -a -m msg mytag &&
- echo morefoo >> bar &&
- git add bar &&
- git commit -m "Change to second file" &&
- cd ..
+ (
+ cd limit-by-paths &&
+ git init &&
+ echo hi > there &&
+ git add there &&
+ git commit -m "First file" &&
+ echo foo > bar &&
+ git add bar &&
+ git commit -m "Second file" &&
+ git tag -a -m msg mytag &&
+ echo morefoo >> bar &&
+ git add bar &&
+ git commit -m "Change to second file"
+ )
'
cat > limit-by-paths/expected << EOF
@@ -297,10 +300,11 @@ M 100644 :1 there
EOF
test_expect_success 'dropping tag of filtered out object' '
+(
cd limit-by-paths &&
git fast-export --tag-of-filtered-object=drop mytag -- there > output &&
- test_cmp output expected &&
- cd ..
+ test_cmp output expected
+)
'
cat >> limit-by-paths/expected << EOF
@@ -313,10 +317,11 @@ msg
EOF
test_expect_success 'rewriting tag of filtered out object' '
+(
cd limit-by-paths &&
git fast-export --tag-of-filtered-object=rewrite mytag -- there > output &&
- test_cmp output expected &&
- cd ..
+ test_cmp output expected
+)
'
cat > limit-by-paths/expected << EOF
@@ -343,13 +348,13 @@ M 100644 :2 there
EOF
test_expect_failure 'no exact-ref revisions included' '
- cd limit-by-paths &&
- git fast-export master~2..master~1 > output &&
- test_cmp output expected &&
- cd ..
+ (
+ cd limit-by-paths &&
+ git fast-export master~2..master~1 > output &&
+ test_cmp output expected
+ )
'
-
test_expect_success 'set-up a few more tags for tag export tests' '
git checkout -f master &&
HEAD_TREE=`git show -s --pretty=raw HEAD | grep tree | sed "s/tree //"` &&