aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/RelNotes/2.10.5.txt17
-rw-r--r--Documentation/RelNotes/2.11.4.txt17
-rw-r--r--Documentation/RelNotes/2.12.5.txt17
-rw-r--r--Documentation/RelNotes/2.13.6.txt17
-rw-r--r--Documentation/RelNotes/2.14.2.txt11
-rw-r--r--Documentation/git-cat-file.txt2
-rw-r--r--Documentation/git-checkout.txt2
-rw-r--r--Documentation/git-for-each-ref.txt33
-rw-r--r--Documentation/git-notes.txt2
-rw-r--r--Documentation/git-shell.txt16
-rw-r--r--Documentation/git-update-index.txt2
-rw-r--r--Documentation/gitattributes.txt5
-rw-r--r--Documentation/merge-strategies.txt3
-rw-r--r--archive.c19
-rw-r--r--builtin/cat-file.c4
-rw-r--r--builtin/commit-tree.c1
-rw-r--r--builtin/describe.c9
-rw-r--r--builtin/gc.c2
-rw-r--r--builtin/name-rev.c2
-rw-r--r--builtin/rev-parse.c4
-rw-r--r--compat/poll/poll.c4
-rw-r--r--config.c24
-rw-r--r--contrib/diff-highlight/Makefile3
-rw-r--r--exec_cmd.c42
-rwxr-xr-xgit-archimport.perl4
-rwxr-xr-xgit-cvsimport.perl1
-rwxr-xr-xgit-cvsserver.perl77
-rwxr-xr-xgit-request-pull.sh2
-rwxr-xr-xgit-send-email.perl33
-rw-r--r--http-push.c2
-rw-r--r--mailinfo.c11
-rw-r--r--path.c9
-rw-r--r--pkt-line.c3
-rw-r--r--ref-filter.c10
-rw-r--r--refs.c2
-rw-r--r--refs.h8
-rw-r--r--sha1-lookup.c216
-rw-r--r--sha1-lookup.h6
-rw-r--r--sha1_file.c11
-rw-r--r--shell.c14
-rw-r--r--strbuf.c1
-rw-r--r--string-list.h6
-rw-r--r--sub-process.c7
-rw-r--r--t/README6
-rwxr-xr-xt/check-non-portable-shell.pl2
-rwxr-xr-xt/t5001-archive-attr.sh2
-rwxr-xr-xt/t5002-archive-attr-pattern.sh2
-rwxr-xr-xt/t5004-archive-corner-cases.sh4
-rwxr-xr-xt/t5150-request-pull.sh4
-rwxr-xr-xt/t5308-pack-detect-duplicates.sh11
-rwxr-xr-xt/t6002-rev-list-bisect.sh18
-rwxr-xr-xt/t6120-describe.sh6
-rwxr-xr-xt/t6300-for-each-ref.sh1
-rwxr-xr-xt/t8010-cat-file-filters.sh5
-rwxr-xr-xt/t9001-send-email.sh4
-rwxr-xr-xt/t9400-git-cvsserver-server.sh48
-rw-r--r--t/test-lib.sh1
-rw-r--r--userdiff.c2
58 files changed, 377 insertions, 420 deletions
diff --git a/Documentation/RelNotes/2.10.5.txt b/Documentation/RelNotes/2.10.5.txt
new file mode 100644
index 000000000..a498fd6fd
--- /dev/null
+++ b/Documentation/RelNotes/2.10.5.txt
@@ -0,0 +1,17 @@
+Git v2.10.5 Release Notes
+=========================
+
+Fixes since v2.10.4
+-------------------
+
+ * "git cvsserver" no longer is invoked by "git daemon" by default,
+ as it is old and largely unmaintained.
+
+ * Various Perl scripts did not use safe_pipe_capture() instead of
+ backticks, leaving them susceptible to end-user input. They have
+ been corrected.
+
+Credits go to joernchen <joernchen@phenoelit.de> for finding the
+unsafe constructs in "git cvsserver", and to Jeff King at GitHub for
+finding and fixing instances of the same issue in other scripts.
+
diff --git a/Documentation/RelNotes/2.11.4.txt b/Documentation/RelNotes/2.11.4.txt
new file mode 100644
index 000000000..ad4da8eb0
--- /dev/null
+++ b/Documentation/RelNotes/2.11.4.txt
@@ -0,0 +1,17 @@
+Git v2.11.4 Release Notes
+=========================
+
+Fixes since v2.11.3
+-------------------
+
+ * "git cvsserver" no longer is invoked by "git daemon" by default,
+ as it is old and largely unmaintained.
+
+ * Various Perl scripts did not use safe_pipe_capture() instead of
+ backticks, leaving them susceptible to end-user input. They have
+ been corrected.
+
+Credits go to joernchen <joernchen@phenoelit.de> for finding the
+unsafe constructs in "git cvsserver", and to Jeff King at GitHub for
+finding and fixing instances of the same issue in other scripts.
+
diff --git a/Documentation/RelNotes/2.12.5.txt b/Documentation/RelNotes/2.12.5.txt
new file mode 100644
index 000000000..8fa73cfce
--- /dev/null
+++ b/Documentation/RelNotes/2.12.5.txt
@@ -0,0 +1,17 @@
+Git v2.12.5 Release Notes
+=========================
+
+Fixes since v2.12.4
+-------------------
+
+ * "git cvsserver" no longer is invoked by "git daemon" by default,
+ as it is old and largely unmaintained.
+
+ * Various Perl scripts did not use safe_pipe_capture() instead of
+ backticks, leaving them susceptible to end-user input. They have
+ been corrected.
+
+Credits go to joernchen <joernchen@phenoelit.de> for finding the
+unsafe constructs in "git cvsserver", and to Jeff King at GitHub for
+finding and fixing instances of the same issue in other scripts.
+
diff --git a/Documentation/RelNotes/2.13.6.txt b/Documentation/RelNotes/2.13.6.txt
new file mode 100644
index 000000000..afcae9c80
--- /dev/null
+++ b/Documentation/RelNotes/2.13.6.txt
@@ -0,0 +1,17 @@
+Git v2.13.6 Release Notes
+=========================
+
+Fixes since v2.13.5
+-------------------
+
+ * "git cvsserver" no longer is invoked by "git daemon" by default,
+ as it is old and largely unmaintained.
+
+ * Various Perl scripts did not use safe_pipe_capture() instead of
+ backticks, leaving them susceptible to end-user input. They have
+ been corrected.
+
+Credits go to joernchen <joernchen@phenoelit.de> for finding the
+unsafe constructs in "git cvsserver", and to Jeff King at GitHub for
+finding and fixing instances of the same issue in other scripts.
+
diff --git a/Documentation/RelNotes/2.14.2.txt b/Documentation/RelNotes/2.14.2.txt
index bcfe78f59..bec9186ad 100644
--- a/Documentation/RelNotes/2.14.2.txt
+++ b/Documentation/RelNotes/2.14.2.txt
@@ -91,4 +91,15 @@ Fixes since v2.14.1
* "git archive" did not work well with pathspecs and the
export-ignore attribute.
+ * "git cvsserver" no longer is invoked by "git daemon" by default,
+ as it is old and largely unmaintained.
+
+ * Various Perl scripts did not use safe_pipe_capture() instead of
+ backticks, leaving them susceptible to end-user input. They have
+ been corrected.
+
Also contains various documentation updates and code clean-ups.
+
+Credits go to joernchen <joernchen@phenoelit.de> for finding the
+unsafe constructs in "git cvsserver", and to Jeff King at GitHub for
+finding and fixing instances of the same issue in other scripts.
diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt
index 204541c69..fb09cd69d 100644
--- a/Documentation/git-cat-file.txt
+++ b/Documentation/git-cat-file.txt
@@ -192,7 +192,7 @@ newline. The available atoms are:
The 40-hex object name of the object.
`objecttype`::
- The type of of the object (the same as `cat-file -t` reports).
+ The type of the object (the same as `cat-file -t` reports).
`objectsize`::
The size, in bytes, of the object (the same as `cat-file -s`
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index d6399c0af..bd268a8fc 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -38,7 +38,7 @@ $ git checkout -b <branch> --track <remote>/<branch>
------------
+
You could omit <branch>, in which case the command degenerates to
-"check out the current branch", which is a glorified no-op with a
+"check out the current branch", which is a glorified no-op with
rather expensive side-effects to show only the tracking information,
if exists, for the current branch.
diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt
index bb370c9c7..66b4e0a40 100644
--- a/Documentation/git-for-each-ref.txt
+++ b/Documentation/git-for-each-ref.txt
@@ -10,8 +10,9 @@ SYNOPSIS
[verse]
'git for-each-ref' [--count=<count>] [--shell|--perl|--python|--tcl]
[(--sort=<key>)...] [--format=<format>] [<pattern>...]
- [--points-at <object>] [(--merged | --no-merged) [<object>]]
- [--contains [<object>]] [--no-contains [<object>]]
+ [--points-at=<object>]
+ (--merged[=<object>] | --no-merged[=<object>])
+ [--contains[=<object>]] [--no-contains[=<object>]]
DESCRIPTION
-----------
@@ -25,19 +26,25 @@ host language allowing their direct evaluation in that language.
OPTIONS
-------
-<count>::
+<pattern>...::
+ If one or more patterns are given, only refs are shown that
+ match against at least one pattern, either using fnmatch(3) or
+ literally, in the latter case matching completely or from the
+ beginning up to a slash.
+
+--count=<count>::
By default the command shows all refs that match
`<pattern>`. This option makes it stop after showing
that many refs.
-<key>::
+--sort=<key>::
A field name to sort on. Prefix `-` to sort in
descending order of the value. When unspecified,
`refname` is used. You may use the --sort=<key> option
multiple times, in which case the last key becomes the primary
key.
-<format>::
+--format=<format>::
A string that interpolates `%(fieldname)` from a ref being shown
and the object it points at. If `fieldname`
is prefixed with an asterisk (`*`) and the ref points
@@ -50,12 +57,6 @@ OPTIONS
`xx`; for example `%00` interpolates to `\0` (NUL),
`%09` to `\t` (TAB) and `%0a` to `\n` (LF).
-<pattern>...::
- If one or more patterns are given, only refs are shown that
- match against at least one pattern, either using fnmatch(3) or
- literally, in the latter case matching completely or from the
- beginning up to a slash.
-
--shell::
--perl::
--python::
@@ -65,24 +66,24 @@ OPTIONS
the specified host language. This is meant to produce
a scriptlet that can directly be `eval`ed.
---points-at <object>::
+--points-at=<object>::
Only list refs which points at the given object.
---merged [<object>]::
+--merged[=<object>]::
Only list refs whose tips are reachable from the
specified commit (HEAD if not specified),
incompatible with `--no-merged`.
---no-merged [<object>]::
+--no-merged[=<object>]::
Only list refs whose tips are not reachable from the
specified commit (HEAD if not specified),
incompatible with `--merged`.
---contains [<object>]::
+--contains[=<object>]::
Only list refs which contain the specified commit (HEAD if not
specified).
---no-contains [<object>]::
+--no-contains[=<object>]::
Only list refs which don't contain the specified commit (HEAD
if not specified).
diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt
index be7db3048..43677297f 100644
--- a/Documentation/git-notes.txt
+++ b/Documentation/git-notes.txt
@@ -171,7 +171,7 @@ OPTIONS
object that does not have notes attached to it.
--stdin::
- Also read the object names to remove notes from from the standard
+ Also read the object names to remove notes from the standard
input (there is no reason you cannot combine this with object
names from the command line).
diff --git a/Documentation/git-shell.txt b/Documentation/git-shell.txt
index 2e30a3e42..54cf2560b 100644
--- a/Documentation/git-shell.txt
+++ b/Documentation/git-shell.txt
@@ -79,6 +79,22 @@ EOF
$ chmod +x $HOME/git-shell-commands/no-interactive-login
----------------
+To enable git-cvsserver access (which should generally have the
+`no-interactive-login` example above as a prerequisite, as creating
+the git-shell-commands directory allows interactive logins):
+
+----------------
+$ cat >$HOME/git-shell-commands/cvs <<\EOF
+if ! test $# = 1 && test "$1" = "server"
+then
+ echo >&2 "git-cvsserver only handles \"server\""
+ exit 1
+fi
+exec git cvsserver server
+EOF
+$ chmod +x $HOME/git-shell-commands/cvs
+----------------
+
SEE ALSO
--------
ssh(1),
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index 1579abf3c..a14e6aebd 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -153,7 +153,7 @@ you will need to handle the situation manually.
+
Version 4 performs a simple pathname compression that reduces index
size by 30%-50% on large repositories, which results in faster load
-time. Version 4 is relatively young (first released in in 1.8.0 in
+time. Version 4 is relatively young (first released in 1.8.0 in
October 2012). Other Git implementations such as JGit and libgit2
may not support it yet.
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index c4f2be254..4c68bc19d 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -151,7 +151,10 @@ unspecified.
This attribute sets a specific line-ending style to be used in the
working directory. It enables end-of-line conversion without any
-content checks, effectively setting the `text` attribute.
+content checks, effectively setting the `text` attribute. Note that
+setting this attribute on paths which are in the index with CRLF line
+endings may make the paths to be considered dirty. Adding the path to
+the index again will normalize the line endings in the index.
Set to string value "crlf"::
diff --git a/Documentation/merge-strategies.txt b/Documentation/merge-strategies.txt
index 2eb92b932..a09d59746 100644
--- a/Documentation/merge-strategies.txt
+++ b/Documentation/merge-strategies.txt
@@ -39,7 +39,8 @@ even look at what the other tree contains at all. It discards everything
the other tree did, declaring 'our' history contains all that happened in it.
theirs;;
- This is the opposite of 'ours'.
+ This is the opposite of 'ours'; note that, unlike 'ours', there is
+ no 'theirs' merge stragegy to confuse this merge option with.
patience;;
With this option, 'merge-recursive' spends a little extra time
diff --git a/archive.c b/archive.c
index 2ad7e6cb9..f81bd3649 100644
--- a/archive.c
+++ b/archive.c
@@ -121,11 +121,6 @@ static int check_attr_export_subst(const struct attr_check *check)
return check && ATTR_TRUE(check->items[1].value);
}
-static int should_queue_directories(const struct archiver_args *args)
-{
- return args->pathspec.has_wildcard;
-}
-
static int write_archive_entry(const unsigned char *sha1, const char *base,
int baselen, const char *filename, unsigned mode, int stage,
void *context)
@@ -147,7 +142,7 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
strbuf_addch(&path, '/');
path_without_prefix = path.buf + args->baselen;
- if (!S_ISDIR(mode) || !should_queue_directories(args)) {
+ if (!S_ISDIR(mode)) {
const struct attr_check *check;
check = get_archive_attrs(path_without_prefix);
if (check_attr_export_ignore(check))
@@ -169,14 +164,6 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
return write_entry(args, sha1, path.buf, path.len, mode);
}
-static int write_archive_entry_buf(const unsigned char *sha1, struct strbuf *base,
- const char *filename, unsigned mode, int stage,
- void *context)
-{
- return write_archive_entry(sha1, base->buf, base->len,
- filename, mode, stage, context);
-}
-
static void queue_directory(const unsigned char *sha1,
struct strbuf *base, const char *filename,
unsigned mode, int stage, struct archiver_context *c)
@@ -290,9 +277,7 @@ int write_archive_entries(struct archiver_args *args,
}
err = read_tree_recursive(args->tree, "", 0, 0, &args->pathspec,
- should_queue_directories(args) ?
- queue_or_write_archive_entry :
- write_archive_entry_buf,
+ queue_or_write_archive_entry,
&context);
if (err == READ_TREE_RECURSIVE)
err = 0;
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 96b786e48..188ddc3e5 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -96,7 +96,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
return !has_object_file(&oid);
case 'w':
- if (!path[0])
+ if (!path)
die("git cat-file --filters %s: <object> must be "
"<sha1:path>", obj_name);
@@ -106,7 +106,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
break;
case 'c':
- if (!path[0])
+ if (!path)
die("git cat-file --textconv %s: <object> must be <sha1:path>",
obj_name);
diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c
index a4a923d7c..c1de41c67 100644
--- a/builtin/commit-tree.c
+++ b/builtin/commit-tree.c
@@ -102,7 +102,6 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
if (fd && close(fd))
die_errno("git commit-tree: failed to close '%s'",
argv[i]);
- strbuf_complete_line(&buffer);
continue;
}
diff --git a/builtin/describe.c b/builtin/describe.c
index 89ea1cdd6..94ff2fba0 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -155,18 +155,21 @@ static int get_name(const char *path, const struct object_id *oid, int flag, voi
* pattern.
*/
if (patterns.nr) {
+ int found = 0;
struct string_list_item *item;
if (!is_tag)
return 0;
for_each_string_list_item(item, &patterns) {
- if (!wildmatch(item->string, path + 10, 0))
+ if (!wildmatch(item->string, path + 10, 0)) {
+ found = 1;
break;
+ }
+ }
- /* If we get here, no pattern matched. */
+ if (!found)
return 0;
- }
}
/* Is it annotated? */
diff --git a/builtin/gc.c b/builtin/gc.c
index e6b84475a..53c19be8b 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -257,7 +257,7 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
int should_exit;
if (!scan_fmt)
- scan_fmt = xstrfmt("%s %%%dc", "%"SCNuMAX, HOST_NAME_MAX);
+ scan_fmt = xstrfmt("%s %%%ds", "%"SCNuMAX, HOST_NAME_MAX);
fp = fopen(pidfile_path, "r");
memset(locking_host, 0, sizeof(locking_host));
should_exit =
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index c41ea7c2a..598da6c8b 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -253,7 +253,7 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo
struct commit *commit = (struct commit *)o;
int from_tag = starts_with(path, "refs/tags/");
- if (taggerdate == ULONG_MAX)
+ if (taggerdate == TIME_MAX)
taggerdate = ((struct commit *)o)->date;
path = name_ref_abbrev(path, can_abbreviate_output);
name_rev(commit, xstrdup(path), taggerdate, 0, 0,
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index c78b7b33d..7f965fe74 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -757,8 +757,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
continue;
}
if (!strcmp(arg, "--bisect")) {
- for_each_ref_in("refs/bisect/bad", show_reference, NULL);
- for_each_ref_in("refs/bisect/good", anti_reference, NULL);
+ for_each_fullref_in("refs/bisect/bad", show_reference, NULL, 0);
+ for_each_fullref_in("refs/bisect/good", anti_reference, NULL, 0);
continue;
}
if (opt_with_value(arg, "--branches", &arg)) {
diff --git a/compat/poll/poll.c b/compat/poll/poll.c
index b10adc780..ae03b74a6 100644
--- a/compat/poll/poll.c
+++ b/compat/poll/poll.c
@@ -438,6 +438,10 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
pfd[i].revents = happened;
rc++;
}
+ else
+ {
+ pfd[i].revents = 0;
+ }
}
return rc;
diff --git a/config.c b/config.c
index acebc85d8..c138c0ba0 100644
--- a/config.c
+++ b/config.c
@@ -2404,7 +2404,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
{
int fd = -1, in_fd = -1;
int ret;
- struct lock_file *lock = NULL;
+ static struct lock_file lock;
char *filename_buf = NULL;
char *contents = NULL;
size_t contents_sz;
@@ -2423,8 +2423,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
* The lock serves a purpose in addition to locking: the new
* contents of .git/config will be written into it.
*/
- lock = xcalloc(1, sizeof(struct lock_file));
- fd = hold_lock_file_for_update(lock, config_filename, 0);
+ fd = hold_lock_file_for_update(&lock, config_filename, 0);
if (fd < 0) {
error_errno("could not lock config file %s", config_filename);
free(store.key);
@@ -2537,8 +2536,8 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
close(in_fd);
in_fd = -1;
- if (chmod(get_lock_file_path(lock), st.st_mode & 07777) < 0) {
- error_errno("chmod on %s failed", get_lock_file_path(lock));
+ if (chmod(get_lock_file_path(&lock), st.st_mode & 07777) < 0) {
+ error_errno("chmod on %s failed", get_lock_file_path(&lock));
ret = CONFIG_NO_WRITE;
goto out_free;
}
@@ -2593,28 +2592,19 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
contents = NULL;
}
- if (commit_lock_file(lock) < 0) {
+ if (commit_lock_file(&lock) < 0) {
error_errno("could not write config file %s", config_filename);
ret = CONFIG_NO_WRITE;
- lock = NULL;
goto out_free;
}
- /*
- * lock is committed, so don't try to roll it back below.
- * NOTE: Since lockfile.c keeps a linked list of all created
- * lock_file structures, it isn't safe to free(lock). It's
- * better to just leave it hanging around.
- */
- lock = NULL;
ret = 0;
/* Invalidate the config cache */
git_config_clear();
out_free:
- if (lock)
- rollback_lock_file(lock);
+ rollback_lock_file(&lock);
free(filename_buf);
if (contents)
munmap(contents, contents_sz);
@@ -2623,7 +2613,7 @@ out_free:
return ret;
write_err_out:
- ret = write_error(get_lock_file_path(lock));
+ ret = write_error(get_lock_file_path(&lock));
goto out_free;
}
diff --git a/contrib/diff-highlight/Makefile b/contrib/diff-highlight/Makefile
index fbf5c5824..f2be7cc92 100644
--- a/contrib/diff-highlight/Makefile
+++ b/contrib/diff-highlight/Makefile
@@ -17,4 +17,7 @@ shebang.perl: FORCE
test: all
$(MAKE) -C t
+clean:
+ $(RM) diff-highlight
+
.PHONY: FORCE
diff --git a/exec_cmd.c b/exec_cmd.c
index fb94aeba9..ce192a2d6 100644
--- a/exec_cmd.c
+++ b/exec_cmd.c
@@ -5,21 +5,14 @@
#define MAX_ARGS 32
static const char *argv_exec_path;
+
+#ifdef RUNTIME_PREFIX
static const char *argv0_path;
-char *system_path(const char *path)
+static const char *system_prefix(void)
{
-#ifdef RUNTIME_PREFIX
static const char *prefix;
-#else
- static const char *prefix = PREFIX;
-#endif
- struct strbuf d = STRBUF_INIT;
-
- if (is_absolute_path(path))
- return xstrdup(path);
-#ifdef RUNTIME_PREFIX
assert(argv0_path);
assert(is_absolute_path(argv0_path));
@@ -32,10 +25,7 @@ char *system_path(const char *path)
"but prefix computation failed. "
"Using static fallback '%s'.\n", prefix);
}
-#endif
-
- strbuf_addf(&d, "%s/%s", prefix, path);
- return strbuf_detach(&d, NULL);
+ return prefix;
}
void git_extract_argv0_path(const char *argv0)
@@ -51,6 +41,30 @@ void git_extract_argv0_path(const char *argv0)
argv0_path = xstrndup(argv0, slash - argv0);
}
+#else
+
+static const char *system_prefix(void)
+{
+ return PREFIX;
+}
+
+void git_extract_argv0_path(const char *argv0)
+{
+}
+
+#endif /* RUNTIME_PREFIX */
+
+char *system_path(const char *path)
+{
+ struct strbuf d = STRBUF_INIT;
+
+ if (is_absolute_path(path))
+ return xstrdup(path);
+
+ strbuf_addf(&d, "%s/%s", system_prefix(), path);
+ return strbuf_detach(&d, NULL);
+}
+
void git_set_argv_exec_path(const char *exec_path)
{
argv_exec_path = exec_path;
diff --git a/git-archimport.perl b/git-archimport.perl
index 9cb123a07..b7c173c34 100755
--- a/git-archimport.perl
+++ b/git-archimport.perl
@@ -983,7 +983,7 @@ sub find_parents {
# check that we actually know about the branch
next unless -e "$git_dir/refs/heads/$branch";
- my $mergebase = `git-merge-base $branch $ps->{branch}`;
+ my $mergebase = safe_pipe_capture(qw(git-merge-base), $branch, $ps->{branch});
if ($?) {
# Don't die here, Arch supports one-way cherry-picking
# between branches with no common base (or any relationship
@@ -1074,7 +1074,7 @@ sub find_parents {
sub git_rev_parse {
my $name = shift;
- my $val = `git-rev-parse $name`;
+ my $val = safe_pipe_capture(qw(git-rev-parse), $name);
die "Error: git-rev-parse $name" if $?;
chomp $val;
return $val;
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index 1e4e65a45..36929921e 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -642,6 +642,7 @@ sub is_sha1 {
sub get_headref ($) {
my $name = shift;
+ $name =~ s/'/'\\''/;
my $r = `git rev-parse --verify '$name' 2>/dev/null`;
return undef unless $? == 0;
chomp $r;
diff --git a/git-cvsserver.perl b/git-cvsserver.perl
index d50c85ed7..ae1044273 100755
--- a/git-cvsserver.perl
+++ b/git-cvsserver.perl
@@ -356,7 +356,7 @@ sub req_Root
return 0;
}
- my @gitvars = `git config -l`;
+ my @gitvars = safe_pipe_capture(qw(git config -l));
if ($?) {
print "E problems executing git-config on the server -- this is not a git repository or the PATH is not set correctly.\n";
print "E \n";
@@ -841,7 +841,7 @@ sub req_Modified
# Save the file data in $state
$state->{entries}{$state->{directory}.$data}{modified_filename} = $filename;
$state->{entries}{$state->{directory}.$data}{modified_mode} = $mode;
- $state->{entries}{$state->{directory}.$data}{modified_hash} = `git hash-object $filename`;
+ $state->{entries}{$state->{directory}.$data}{modified_hash} = safe_pipe_capture('git','hash-object',$filename);
$state->{entries}{$state->{directory}.$data}{modified_hash} =~ s/\s.*$//s;
#$log->debug("req_Modified : file=$data mode=$mode size=$size");
@@ -943,7 +943,7 @@ sub req_co
# Provide list of modules, if -c was used.
if (exists $state->{opt}{c}) {
- my $showref = `git show-ref --heads`;
+ my $showref = safe_pipe_capture(qw(git show-ref --heads));
for my $line (split '\n', $showref) {
if ( $line =~ m% refs/heads/(.*)$% ) {
print "M $1\t$1\n";
@@ -1181,7 +1181,7 @@ sub req_update
# projects (heads in this case) to checkout.
#
if ($state->{module} eq '') {
- my $showref = `git show-ref --heads`;
+ my $showref = safe_pipe_capture(qw(git show-ref --heads));
print "E cvs update: Updating .\n";
for my $line (split '\n', $showref) {
if ( $line =~ m% refs/heads/(.*)$% ) {
@@ -1463,7 +1463,7 @@ sub req_update
# transmit file, format is single integer on a line by itself (file
# size) followed by the file contents
# TODO : we should copy files in blocks
- my $data = `cat $mergedFile`;
+ my $data = safe_pipe_capture('cat', $mergedFile);
$log->debug("File size : " . length($data));
print length($data) . "\n";
print $data;
@@ -1579,7 +1579,7 @@ sub req_ci
$branchRef = "refs/heads/$stickyInfo->{tag}";
}
- $parenthash = `git show-ref -s $branchRef`;
+ $parenthash = safe_pipe_capture('git', 'show-ref', '-s', $branchRef);
chomp $parenthash;
if ($parenthash !~ /^[0-9a-f]{40}$/)
{
@@ -1687,7 +1687,7 @@ sub req_ci
return;
}
- my $treehash = `git write-tree`;
+ my $treehash = safe_pipe_capture(qw(git write-tree));
chomp $treehash;
$log->debug("Treehash : $treehash, Parenthash : $parenthash");
@@ -1704,7 +1704,7 @@ sub req_ci
}
close $msg_fh;
- my $commithash = `git commit-tree $treehash -p $parenthash < $msg_filename`;
+ my $commithash = safe_pipe_capture('git', 'commit-tree', $treehash, '-p', $parenthash, '-F', $msg_filename);
chomp($commithash);
$log->info("Commit hash : $commithash");
@@ -2854,12 +2854,12 @@ sub transmitfile
die "Need filehash" unless ( defined ( $filehash ) and $filehash =~ /^[a-zA-Z0-9]{40}$/ );
- my $type = `git cat-file -t $filehash`;
+ my $type = safe_pipe_capture('git', 'cat-file', '-t', $filehash);
chomp $type;
die ( "Invalid type '$type' (expected 'blob')" ) unless ( defined ( $type ) and $type eq "blob" );
- my $size = `git cat-file -s $filehash`;
+ my $size = safe_pipe_capture('git', 'cat-file', '-s', $filehash);
chomp $size;
$log->debug("transmitfile($filehash) size=$size, type=$type");
@@ -3040,7 +3040,7 @@ sub ensureWorkTree
chdir $work->{emptyDir} or
die "Unable to chdir to $work->{emptyDir}\n";
- my $ver = `git show-ref -s refs/heads/$state->{module}`;
+ my $ver = safe_pipe_capture('git', 'show-ref', '-s', "refs/heads/$state->{module}");
chomp $ver;
if ($ver !~ /^[0-9a-f]{40}$/)
{
@@ -3287,7 +3287,7 @@ sub open_blob_or_die
die "Need filehash\n";
}
- my $type = `git cat-file -t $name`;
+ my $type = safe_pipe_capture('git', 'cat-file', '-t', $name);
chomp $type;
unless ( defined ( $type ) and $type eq "blob" )
@@ -3296,7 +3296,7 @@ sub open_blob_or_die
die ( "Invalid type '$type' (expected 'blob')" )
}
- my $size = `git cat-file -s $name`;
+ my $size = safe_pipe_capture('git', 'cat-file', '-s', $name);
chomp $size;
$log->debug("open_blob_or_die($name) size=$size, type=$type");
@@ -3406,6 +3406,22 @@ sub refHashEqual
return $out;
}
+# an alternative to `command` that allows input to be passed as an array
+# to work around shell problems with weird characters in arguments
+
+sub safe_pipe_capture {
+
+ my @output;
+
+ if (my $pid = open my $child, '-|') {
+ @output = (<$child>);
+ close $child or die join(' ',@_).": $! $?";
+ } else {
+ exec(@_) or die "$! $?"; # exec() can fail the executable can't be found
+ }
+ return wantarray ? @output : join('',@output);
+}
+
package GITCVS::log;
@@ -3797,10 +3813,10 @@ sub update
# first lets get the commit list
$ENV{GIT_DIR} = $self->{git_path};
- my $commitsha1 = `git rev-parse $self->{module}`;
+ my $commitsha1 = ::safe_pipe_capture('git', 'rev-parse', $self->{module});
chomp $commitsha1;
- my $commitinfo = `git cat-file commit $self->{module} 2>&1`;
+ my $commitinfo = ::safe_pipe_capture('git', 'cat-file', 'commit', $self->{module});
unless ( $commitinfo =~ /tree\s+[a-zA-Z0-9]{40}/ )
{
die("Invalid module '$self->{module}'");
@@ -3882,7 +3898,7 @@ sub update
# several candidate merge bases. let's assume
# that the first one is the best one.
my $base = eval {
- safe_pipe_capture('git', 'merge-base',
+ ::safe_pipe_capture('git', 'merge-base',
$lastpicked, $parent);
};
# The two branches may not be related at all,
@@ -4749,7 +4765,7 @@ sub getMetaFromCommithash
return $retVal;
}
- my($fileHash)=safe_pipe_capture("git","rev-parse","$revCommit:$filename");
+ my($fileHash) = ::safe_pipe_capture("git","rev-parse","$revCommit:$filename");
chomp $fileHash;
if(!($fileHash=~/^[0-9a-f]{40}$/))
{
@@ -4844,8 +4860,8 @@ sub lookupCommitRef
return $commitHash;
}
- $commitHash=safe_pipe_capture("git","rev-parse","--verify","--quiet",
- $self->unescapeRefName($ref));
+ $commitHash = ::safe_pipe_capture("git","rev-parse","--verify","--quiet",
+ $self->unescapeRefName($ref));
$commitHash=~s/\s*$//;
if(!($commitHash=~/^[0-9a-f]{40}$/))
{
@@ -4854,7 +4870,7 @@ sub lookupCommitRef
if( defined($commitHash) )
{
- my $type=safe_pipe_capture("git","cat-file","-t",$commitHash);
+ my $type = ::safe_pipe_capture("git","cat-file","-t",$commitHash);
if( ! ($type=~/^commit\s*$/ ) )
{
$commitHash=undef;
@@ -4907,7 +4923,7 @@ sub commitmessage
return $message;
}
- my @lines = safe_pipe_capture("git", "cat-file", "commit", $commithash);
+ my @lines = ::safe_pipe_capture("git", "cat-file", "commit", $commithash);
shift @lines while ( $lines[0] =~ /\S/ );
$message = join("",@lines);
$message .= " " if ( $message =~ /\n$/ );
@@ -5056,25 +5072,6 @@ sub in_array
return $retval;
}
-=head2 safe_pipe_capture
-
-an alternative to `command` that allows input to be passed as an array
-to work around shell problems with weird characters in arguments
-
-=cut
-sub safe_pipe_capture {
-
- my @output;
-
- if (my $pid = open my $child, '-|') {
- @output = (<$child>);
- close $child or die join(' ',@_).": $! $?";
- } else {
- exec(@_) or die "$! $?"; # exec() can fail the executable can't be found
- }
- return wantarray ? @output : join('',@output);
-}
-
=head2 mangle_dirname
create a string from a directory name that is suitable to use as
diff --git a/git-request-pull.sh b/git-request-pull.sh
index eebd33276..13c172bd9 100755
--- a/git-request-pull.sh
+++ b/git-request-pull.sh
@@ -128,7 +128,7 @@ git show -s --format='The following changes since commit %H:
%s (%ci)
-are available in the git repository at:
+are available in the Git repository at:
' $merge_base &&
echo " $url $pretty_remote" &&
git show -s --format='
diff --git a/git-send-email.perl b/git-send-email.perl
index fa6526986..2208dcc21 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -155,7 +155,6 @@ sub format_2822_time {
}
my $have_email_valid = eval { require Email::Valid; 1 };
-my $have_mail_address = eval { require Mail::Address; 1 };
my $smtp;
my $auth;
my $num_sent = 0;
@@ -490,11 +489,7 @@ my ($repoauthor, $repocommitter);
($repocommitter) = Git::ident_person(@repo, 'committer');
sub parse_address_line {
- if ($have_mail_address) {
- return map { $_->format } Mail::Address->parse($_[0]);
- } else {
- return Git::parse_mailboxes($_[0]);
- }
+ return Git::parse_mailboxes($_[0]);
}
sub split_addrs {
@@ -1089,6 +1084,26 @@ sub sanitize_address {
}
+sub strip_garbage_one_address {
+ my ($addr) = @_;
+ chomp $addr;
+ if ($addr =~ /^(("[^"]*"|[^"<]*)? *<[^>]*>).*/) {
+ # "Foo Bar" <foobar@example.com> [possibly garbage here]
+ # Foo Bar <foobar@example.com> [possibly garbage here]
+ return $1;
+ }
+ if ($addr =~ /^(<[^>]*>).*/) {
+ # <foo@example.com> [possibly garbage here]
+ # if garbage contains other addresses, they are ignored.
+ return $1;
+ }
+ if ($addr =~ /^([^"#,\s]*)/) {
+ # address without quoting: remove anything after the address
+ return $1;
+ }
+ return $addr;
+}
+
sub sanitize_address_list {
return (map { sanitize_address($_) } @_);
}
@@ -1590,10 +1605,12 @@ foreach my $t (@files) {
# Now parse the message body
while(<$fh>) {
$message .= $_;
- if (/^(Signed-off-by|Cc): ([^>]*>?)/i) {
+ if (/^(Signed-off-by|Cc): (.*)/i) {
chomp;
my ($what, $c) = ($1, $2);
- chomp $c;
+ # strip garbage for the address we'll use:
+ $c = strip_garbage_one_address($c);
+ # sanitize a bit more to decide whether to suppress the address:
my $sc = sanitize_address($c);
if ($sc eq $sender) {
next if ($suppress_cc{'self'});
diff --git a/http-push.c b/http-push.c
index c91f40a61..df969609b 100644
--- a/http-push.c
+++ b/http-push.c
@@ -1017,7 +1017,7 @@ static int get_oid_hex_from_objpath(const char *path, struct object_id *oid)
memcpy(hex, path, 2);
path += 2;
path++; /* skip '/' */
- memcpy(hex, path, GIT_SHA1_HEXSZ - 2);
+ memcpy(hex + 2, path, GIT_SHA1_HEXSZ - 2);
return get_oid_hex(hex, oid);
}
diff --git a/mailinfo.c b/mailinfo.c
index bd574cb75..70187e3eb 100644
--- a/mailinfo.c
+++ b/mailinfo.c
@@ -368,11 +368,16 @@ static struct strbuf *decode_q_segment(const struct strbuf *q_seg, int rfc2047)
while ((c = *in++) != 0) {
if (c == '=') {
- int d = *in++;
+ int ch, d = *in;
if (d == '\n' || !d)
break; /* drop trailing newline */
- strbuf_addch(out, (hexval(d) << 4) | hexval(*in++));
- continue;
+ ch = hex2chr(in);
+ if (ch >= 0) {
+ strbuf_addch(out, ch);
+ in += 2;
+ continue;
+ }
+ /* garbage -- fall through */
}
if (rfc2047 && c == '_') /* rfc2047 4.2 (2) */
c = 0x20;
diff --git a/path.c b/path.c
index e50d2befc..2fecf854f 100644
--- a/path.c
+++ b/path.c
@@ -33,11 +33,10 @@ static struct strbuf *get_pathname(void)
return sb;
}
-static char *cleanup_path(char *path)
+static const char *cleanup_path(const char *path)
{
/* Clean it up */
- if (!memcmp(path, "./", 2)) {
- path += 2;
+ if (skip_prefix(path, "./", &path)) {
while (*path == '/')
path++;
}
@@ -46,7 +45,7 @@ static char *cleanup_path(char *path)
static void strbuf_cleanup_path(struct strbuf *sb)
{
- char *path = cleanup_path(sb->buf);
+ const char *path = cleanup_path(sb->buf);
if (path > sb->buf)
strbuf_remove(sb, 0, path - sb->buf);
}
@@ -63,7 +62,7 @@ char *mksnpath(char *buf, size_t n, const char *fmt, ...)
strlcpy(buf, bad_path, n);
return buf;
}
- return cleanup_path(buf);
+ return (char *)cleanup_path(buf);
}
static int dir_prefix(const char *buf, const char *dir)
diff --git a/pkt-line.c b/pkt-line.c
index 7db911957..f364944b9 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -136,9 +136,10 @@ static void format_packet(struct strbuf *out, const char *fmt, va_list args)
static int packet_write_fmt_1(int fd, int gently,
const char *fmt, va_list args)
{
- struct strbuf buf = STRBUF_INIT;
+ static struct strbuf buf = STRBUF_INIT;
ssize_t count;
+ strbuf_reset(&buf);
format_packet(&buf, fmt, args);
count = write_in_full(fd, buf.buf, buf.len);
if (count == buf.len)
diff --git a/ref-filter.c b/ref-filter.c
index bc591f4f3..f3e53d444 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -415,8 +415,16 @@ static int parse_ref_filter_atom(const struct ref_format *format,
REALLOC_ARRAY(used_atom, used_atom_cnt);
used_atom[at].name = xmemdupz(atom, ep - atom);
used_atom[at].type = valid_atom[i].cmp_type;
- if (arg)
+ if (arg) {
arg = used_atom[at].name + (arg - atom) + 1;
+ if (!*arg) {
+ /*
+ * Treat empty sub-arguments list as NULL (i.e.,
+ * "%(atom:)" is equivalent to "%(atom)").
+ */
+ arg = NULL;
+ }
+ }
memset(&used_atom[at].u, 0, sizeof(used_atom[at].u));
if (valid_atom[i].parser)
valid_atom[i].parser(format, &used_atom[at], arg);
diff --git a/refs.c b/refs.c
index ea2b9f84f..41aec6505 100644
--- a/refs.c
+++ b/refs.c
@@ -921,6 +921,8 @@ int ref_transaction_update(struct ref_transaction *transaction,
return -1;
}
+ flags &= REF_TRANSACTION_UPDATE_ALLOWED_FLAGS;
+
flags |= (new_sha1 ? REF_HAVE_NEW : 0) | (old_sha1 ? REF_HAVE_OLD : 0);
ref_transaction_add_update(transaction, refname, flags,
diff --git a/refs.h b/refs.h
index 6daa78eb5..4d75c207e 100644
--- a/refs.h
+++ b/refs.h
@@ -355,6 +355,14 @@ int refs_pack_refs(struct ref_store *refs, unsigned int flags);
#define REF_FORCE_CREATE_REFLOG 0x40
/*
+ * Flags that can be passed in to ref_transaction_update
+ */
+#define REF_TRANSACTION_UPDATE_ALLOWED_FLAGS \
+ REF_ISPRUNING | \
+ REF_FORCE_CREATE_REFLOG | \
+ REF_NODEREF
+
+/*
* Setup reflog before using. Fill in err and return -1 on failure.
*/
int refs_create_reflog(struct ref_store *refs, const char *refname,
diff --git a/sha1-lookup.c b/sha1-lookup.c
index 5f069214d..2552b7902 100644
--- a/sha1-lookup.c
+++ b/sha1-lookup.c
@@ -99,219 +99,3 @@ int sha1_pos(const unsigned char *sha1, void *table, size_t nr,
} while (lo < hi);
return -lo-1;
}
-
-/*
- * Conventional binary search loop looks like this:
- *
- * unsigned lo, hi;
- * do {
- * unsigned mi = (lo + hi) / 2;
- * int cmp = "entry pointed at by mi" minus "target";
- * if (!cmp)
- * return (mi is the wanted one)
- * if (cmp > 0)
- * hi = mi; "mi is larger than target"
- * else
- * lo = mi+1; "mi is smaller than target"
- * } while (lo < hi);
- *
- * The invariants are:
- *
- * - When entering the loop, lo points at a slot that is never
- * above the target (it could be at the target), hi points at a
- * slot that is guaranteed to be above the target (it can never
- * be at the target).
- *
- * - We find a point 'mi' between lo and hi (mi could be the same
- * as lo, but never can be as same as hi), and check if it hits
- * the target. There are three cases:
- *
- * - if it is a hit, we are happy.
- *
- * - if it is strictly higher than the target, we set it to hi,
- * and repeat the search.
- *
- * - if it is strictly lower than the target, we update lo to
- * one slot after it, because we allow lo to be at the target.
- *
- * If the loop exits, there is no matching entry.
- *
- * When choosing 'mi', we do not have to take the "middle" but
- * anywhere in between lo and hi, as long as lo <= mi < hi is
- * satisfied. When we somehow know that the distance between the
- * target and lo is much shorter than the target and hi, we could
- * pick mi that is much closer to lo than the midway.
- *
- * Now, we can take advantage of the fact that SHA-1 is a good hash
- * function, and as long as there are enough entries in the table, we
- * can expect uniform distribution. An entry that begins with for
- * example "deadbeef..." is much likely to appear much later than in
- * the midway of the table. It can reasonably be expected to be near
- * 87% (222/256) from the top of the table.
- *
- * However, we do not want to pick "mi" too precisely. If the entry at
- * the 87% in the above example turns out to be higher than the target
- * we are looking for, we would end up narrowing the search space down
- * only by 13%, instead of 50% we would get if we did a simple binary
- * search. So we would want to hedge our bets by being less aggressive.
- *
- * The table at "table" holds at least "nr" entries of "elem_size"
- * bytes each. Each entry has the SHA-1 key at "key_offset". The
- * table is sorted by the SHA-1 key of the entries. The caller wants
- * to find the entry with "key", and knows that the entry at "lo" is
- * not higher than the entry it is looking for, and that the entry at
- * "hi" is higher than the entry it is looking for.
- */
-int sha1_entry_pos(const void *table,
- size_t elem_size,
- size_t key_offset,
- unsigned lo, unsigned hi, unsigned nr,
- const unsigned char *key)
-{
- const unsigned char *base = table;
- const unsigned char *hi_key, *lo_key;
- unsigned ofs_0;
- static int debug_lookup = -1;
-
- if (debug_lookup < 0)
- debug_lookup = !!getenv("GIT_DEBUG_LOOKUP");
-
- if (!nr || lo >= hi)
- return -1;
-
- if (nr == hi)
- hi_key = NULL;
- else
- hi_key = base + elem_size * hi + key_offset;
- lo_key = base + elem_size * lo + key_offset;
-
- ofs_0 = 0;
- do {
- int cmp;
- unsigned ofs, mi, range;
- unsigned lov, hiv, kyv;
- const unsigned char *mi_key;
-
- range = hi - lo;
- if (hi_key) {
- for (ofs = ofs_0; ofs < 20; ofs++)
- if (lo_key[ofs] != hi_key[ofs])
- break;
- ofs_0 = ofs;
- /*
- * byte 0 thru (ofs-1) are the same between
- * lo and hi; ofs is the first byte that is
- * different.
- *
- * If ofs==20, then no bytes are different,
- * meaning we have entries with duplicate
- * keys. We know that we are in a solid run
- * of this entry (because the entries are
- * sorted, and our lo and hi are the same,
- * there can be nothing but this single key
- * in between). So we can stop the search.
- * Either one of these entries is it (and
- * we do not care which), or we do not have
- * it.
- *
- * Furthermore, we know that one of our
- * endpoints must be the edge of the run of
- * duplicates. For example, given this
- * sequence:
- *
- * idx 0 1 2 3 4 5
- * key A C C C C D
- *
- * If we are searching for "B", we might
- * hit the duplicate run at lo=1, hi=3
- * (e.g., by first mi=3, then mi=0). But we
- * can never have lo > 1, because B < C.
- * That is, if our key is less than the
- * run, we know that "lo" is the edge, but
- * we can say nothing of "hi". Similarly,
- * if our key is greater than the run, we
- * know that "hi" is the edge, but we can
- * say nothing of "lo".
- *
- * Therefore if we do not find it, we also
- * know where it would go if it did exist:
- * just on the far side of the edge that we
- * know about.
- */
- if (ofs == 20) {
- mi = lo;
- mi_key = base + elem_size * mi + key_offset;
- cmp = memcmp(mi_key, key, 20);
- if (!cmp)
- return mi;
- if (cmp < 0)
- return -1 - hi;
- else
- return -1 - lo;
- }
-
- hiv = hi_key[ofs_0];
- if (ofs_0 < 19)
- hiv = (hiv << 8) | hi_key[ofs_0+1];
- } else {
- hiv = 256;
- if (ofs_0 < 19)
- hiv <<= 8;
- }
- lov = lo_key[ofs_0];
- kyv = key[ofs_0];
- if (ofs_0 < 19) {
- lov = (lov << 8) | lo_key[ofs_0+1];
- kyv = (kyv << 8) | key[ofs_0+1];
- }
- assert(lov < hiv);
-
- if (kyv < lov)
- return -1 - lo;
- if (hiv < kyv)
- return -1 - hi;
-
- /*
- * Even if we know the target is much closer to 'hi'
- * than 'lo', if we pick too precisely and overshoot
- * (e.g. when we know 'mi' is closer to 'hi' than to
- * 'lo', pick 'mi' that is higher than the target), we
- * end up narrowing the search space by a smaller
- * amount (i.e. the distance between 'mi' and 'hi')
- * than what we would have (i.e. about half of 'lo'
- * and 'hi'). Hedge our bets to pick 'mi' less
- * aggressively, i.e. make 'mi' a bit closer to the
- * middle than we would otherwise pick.
- */
- kyv = (kyv * 6 + lov + hiv) / 8;
- if (lov < hiv - 1) {
- if (kyv == lov)
- kyv++;
- else if (kyv == hiv)
- kyv--;
- }
- mi = (range - 1) * (kyv - lov) / (hiv - lov) + lo;
-
- if (debug_lookup) {
- printf("lo %u hi %u rg %u mi %u ", lo, hi, range, mi);
- printf("ofs %u lov %x, hiv %x, kyv %x\n",
- ofs_0, lov, hiv, kyv);
- }
- if (!(lo <= mi && mi < hi))
- die("assertion failure lo %u mi %u hi %u %s",
- lo, mi, hi, sha1_to_hex(key));
-
- mi_key = base + elem_size * mi + key_offset;
- cmp = memcmp(mi_key + ofs_0, key + ofs_0, 20 - ofs_0);
- if (!cmp)
- return mi;
- if (cmp > 0) {
- hi = mi;
- hi_key = mi_key;
- } else {
- lo = mi + 1;
- lo_key = mi_key + elem_size;
- }
- } while (lo < hi);
- return -lo-1;
-}
diff --git a/sha1-lookup.h b/sha1-lookup.h
index 20af28568..cf5314f40 100644
--- a/sha1-lookup.h
+++ b/sha1-lookup.h
@@ -7,10 +7,4 @@ extern int sha1_pos(const unsigned char *sha1,
void *table,
size_t nr,
sha1_access_fn fn);
-
-extern int sha1_entry_pos(const void *table,
- size_t elem_size,
- size_t key_offset,
- unsigned lo, unsigned hi, unsigned nr,
- const unsigned char *key);
#endif
diff --git a/sha1_file.c b/sha1_file.c
index 4fa4b185f..9008d6aa7 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2761,7 +2761,6 @@ off_t find_pack_entry_one(const unsigned char *sha1,
const uint32_t *level1_ofs = p->index_data;
const unsigned char *index = p->index_data;
unsigned hi, lo, stride;
- static int use_lookup = -1;
static int debug_lookup = -1;
if (debug_lookup < 0)
@@ -2791,16 +2790,6 @@ off_t find_pack_entry_one(const unsigned char *sha1,
printf("%02x%02x%02x... lo %u hi %u nr %"PRIu32"\n",
sha1[0], sha1[1], sha1[2], lo, hi, p->num_objects);
- if (use_lookup < 0)
- use_lookup = !!getenv("GIT_USE_LOOKUP");
- if (use_lookup) {
- int pos = sha1_entry_pos(index, stride, 0,
- lo, hi, p->num_objects, sha1);
- if (pos < 0)
- return 0;
- return nth_packed_object_offset(p, pos);
- }
-
while (lo < hi) {
unsigned mi = (lo + hi) / 2;
int cmp = hashcmp(index + mi * stride, sha1);
diff --git a/shell.c b/shell.c
index fe2d31459..234b2d4f1 100644
--- a/shell.c
+++ b/shell.c
@@ -25,19 +25,6 @@ static int do_generic_cmd(const char *me, char *arg)
return execv_git_cmd(my_argv);
}
-static int do_cvs_cmd(const char *me, char *arg)
-{
- const char *cvsserver_argv[3] = {
- "cvsserver", "server", NULL
- };
-
- if (!arg || strcmp(arg, "server"))
- die("git-cvsserver only handles server: %s", arg);
-
- setup_path();
- return execv_git_cmd(cvsserver_argv);
-}
-
static int is_valid_cmd_name(const char *cmd)
{
/* Test command contains no . or / characters */
@@ -134,7 +121,6 @@ static struct commands {
{ "git-receive-pack", do_generic_cmd },
{ "git-upload-pack", do_generic_cmd },
{ "git-upload-archive", do_generic_cmd },
- { "cvs", do_cvs_cmd },
{ NULL },
};
diff --git a/strbuf.c b/strbuf.c
index 89d22e3b0..323c49ceb 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -476,6 +476,7 @@ int strbuf_getwholeline(struct strbuf *sb, FILE *fp, int term)
/* Translate slopbuf to NULL, as we cannot call realloc on it */
if (!sb->alloc)
sb->buf = NULL;
+ errno = 0;
r = getdelim(&sb->buf, &sb->alloc, term, fp);
if (r > 0) {
diff --git a/string-list.h b/string-list.h
index 29bfb7ae4..79ae567cb 100644
--- a/string-list.h
+++ b/string-list.h
@@ -32,8 +32,10 @@ void string_list_clear_func(struct string_list *list, string_list_clear_func_t c
typedef int (*string_list_each_func_t)(struct string_list_item *, void *);
int for_each_string_list(struct string_list *list,
string_list_each_func_t, void *cb_data);
-#define for_each_string_list_item(item,list) \
- for (item = (list)->items; item < (list)->items + (list)->nr; ++item)
+#define for_each_string_list_item(item,list) \
+ for (item = (list)->items; \
+ item && item < (list)->items + (list)->nr; \
+ ++item)
/*
* Apply want to each item in list, retaining only the ones for which
diff --git a/sub-process.c b/sub-process.c
index fcc4832c1..80571567f 100644
--- a/sub-process.c
+++ b/sub-process.c
@@ -74,13 +74,12 @@ int subprocess_start(struct hashmap *hashmap, struct subprocess_entry *entry, co
{
int err;
struct child_process *process;
- const char *argv[] = { cmd, NULL };
entry->cmd = cmd;
process = &entry->process;
child_process_init(process);
- process->argv = argv;
+ argv_array_push(&process->args, cmd);
process->use_shell = 1;
process->in = -1;
process->out = -1;
@@ -181,8 +180,8 @@ static int handshake_capabilities(struct child_process *process,
if (supported_capabilities)
*supported_capabilities |= capabilities[i].flag;
} else {
- warning("subprocess '%s' requested unsupported capability '%s'",
- process->argv[0], p);
+ die("subprocess '%s' requested unsupported capability '%s'",
+ process->argv[0], p);
}
}
diff --git a/t/README b/t/README
index 2f9586036..4b079e449 100644
--- a/t/README
+++ b/t/README
@@ -265,12 +265,12 @@ or:
$ sh ./t9200-git-cvsexport-commit.sh --run='-3 21'
-As noted above, the test set is built going though items left to
-right, so this:
+As noted above, the test set is built by going through the items
+from left to right, so this:
$ sh ./t9200-git-cvsexport-commit.sh --run='1-4 !3'
-will run tests 1, 2, and 4. Items that comes later have higher
+will run tests 1, 2, and 4. Items that come later have higher
precedence. It means that this:
$ sh ./t9200-git-cvsexport-commit.sh --run='!3 1-4'
diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl
index b170cbc04..03dc9d285 100755
--- a/t/check-non-portable-shell.pl
+++ b/t/check-non-portable-shell.pl
@@ -17,7 +17,7 @@ sub err {
while (<>) {
chomp;
/\bsed\s+-i/ and err 'sed -i is not portable';
- /\becho\s+-n/ and err 'echo -n is not portable (please use printf)';
+ /\becho\s+-[neE]/ and err 'echo with option is not portable (please use printf)';
/^\s*declare\s+/ and err 'arrays/declare not portable';
/^\s*[^#]\s*which\s/ and err 'which is not portable (please use type)';
/\btest\s+[^=]*==/ and err '"test a == b" is not portable (please use =)';
diff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh
index 897f6f06d..e9aa97117 100755
--- a/t/t5001-archive-attr.sh
+++ b/t/t5001-archive-attr.sh
@@ -73,7 +73,7 @@ test_expect_missing archive-pathspec/ignored-by-tree
test_expect_missing archive-pathspec/ignored-by-tree.d
test_expect_missing archive-pathspec/ignored-by-tree.d/file
test_expect_exists archive-pathspec/ignored-by-worktree
-test_expect_missing archive-pathspec/excluded-by-pathspec.d failure
+test_expect_missing archive-pathspec/excluded-by-pathspec.d
test_expect_missing archive-pathspec/excluded-by-pathspec.d/file
test_expect_success 'git archive with wildcard pathspec' '
diff --git a/t/t5002-archive-attr-pattern.sh b/t/t5002-archive-attr-pattern.sh
index 6667d159a..bda6d7d7e 100755
--- a/t/t5002-archive-attr-pattern.sh
+++ b/t/t5002-archive-attr-pattern.sh
@@ -76,7 +76,7 @@ test_expect_missing archive/deep/and/slashless/ &&
test_expect_missing archive/deep/and/slashless/foo &&
test_expect_missing archive/deep/with/wildcard/ &&
test_expect_missing archive/deep/with/wildcard/foo &&
-test_expect_exists archive/one-level-lower/
+test_expect_missing archive/one-level-lower/
test_expect_missing archive/one-level-lower/two-levels-lower/ignored-only-if-dir/
test_expect_missing archive/one-level-lower/two-levels-lower/ignored-ony-if-dir/ignored-by-ignored-dir
diff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh
index f6207f42b..ced44355c 100755
--- a/t/t5004-archive-corner-cases.sh
+++ b/t/t5004-archive-corner-cases.sh
@@ -108,14 +108,14 @@ test_expect_success 'archive empty subtree with no pathspec' '
git archive --format=tar $root_tree >subtree-all.tar &&
make_dir extract &&
"$TAR" xf subtree-all.tar -C extract &&
- check_dir extract sub
+ check_dir extract
'
test_expect_success 'archive empty subtree by direct pathspec' '
git archive --format=tar $root_tree -- sub >subtree-path.tar &&
make_dir extract &&
"$TAR" xf subtree-path.tar -C extract &&
- check_dir extract sub
+ check_dir extract
'
ZIPINFO=zipinfo
diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh
index 82c33b88e..08c210f03 100755
--- a/t/t5150-request-pull.sh
+++ b/t/t5150-request-pull.sh
@@ -68,7 +68,7 @@ test_expect_success 'setup: two scripts for reading pull requests' '
cat <<-\EOT >read-request.sed &&
#!/bin/sed -nf
# Note that a request could ask for "tag $tagname"
- / in the git repository at:$/!d
+ / in the Git repository at:$/!d
n
/^$/ n
s/ tag \([^ ]*\)$/ tag--\1/
@@ -192,7 +192,7 @@ test_expect_success 'pull request format' '
SUBJECT (DATE)
- are available in the git repository at:
+ are available in the Git repository at:
URL BRANCH
diff --git a/t/t5308-pack-detect-duplicates.sh b/t/t5308-pack-detect-duplicates.sh
index 9c5a8766a..156ae9e9d 100755
--- a/t/t5308-pack-detect-duplicates.sh
+++ b/t/t5308-pack-detect-duplicates.sh
@@ -56,20 +56,11 @@ test_expect_success 'create batch-check test vectors' '
EOF
'
-test_expect_success 'lookup in duplicated pack (binary search)' '
+test_expect_success 'lookup in duplicated pack' '
git cat-file --batch-check <input >actual &&
test_cmp expect actual
'
-test_expect_success 'lookup in duplicated pack (GIT_USE_LOOKUP)' '
- (
- GIT_USE_LOOKUP=1 &&
- export GIT_USE_LOOKUP &&
- git cat-file --batch-check <input >actual
- ) &&
- test_cmp expect actual
-'
-
test_expect_success 'index-pack can reject packs with duplicates' '
clear_packs &&
create_pack dups.pack 2 &&
diff --git a/t/t6002-rev-list-bisect.sh b/t/t6002-rev-list-bisect.sh
index 534903bbd..a66140803 100755
--- a/t/t6002-rev-list-bisect.sh
+++ b/t/t6002-rev-list-bisect.sh
@@ -236,17 +236,31 @@ test_sequence "--bisect"
#
#
-test_expect_success '--bisect can default to good/bad refs' '
+test_expect_success 'set up fake --bisect refs' '
git update-ref refs/bisect/bad c3 &&
good=$(git rev-parse b1) &&
git update-ref refs/bisect/good-$good $good &&
good=$(git rev-parse c1) &&
- git update-ref refs/bisect/good-$good $good &&
+ git update-ref refs/bisect/good-$good $good
+'
+test_expect_success 'rev-list --bisect can default to good/bad refs' '
# the only thing between c3 and c1 is c2
git rev-parse c2 >expect &&
git rev-list --bisect >actual &&
test_cmp expect actual
'
+test_expect_success 'rev-parse --bisect can default to good/bad refs' '
+ git rev-parse c3 ^b1 ^c1 >expect &&
+ git rev-parse --bisect >actual &&
+
+ # output order depends on the refnames, which in turn depends on
+ # the exact sha1s. We just want to make sure we have the same set
+ # of lines in any order.
+ sort <expect >expect.sorted &&
+ sort <actual >actual.sorted &&
+ test_cmp expect.sorted actual.sorted
+'
+
test_done
diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh
index aa74eb8f0..25110ea55 100755
--- a/t/t6120-describe.sh
+++ b/t/t6120-describe.sh
@@ -182,10 +182,14 @@ check_describe "test2-lightweight-*" --tags --match="test2-*"
check_describe "test2-lightweight-*" --long --tags --match="test2-*" HEAD^
-check_describe "test1-lightweight-*" --long --tags --match="test1-*" --match="test2-*" HEAD^
+check_describe "test2-lightweight-*" --long --tags --match="test1-*" --match="test2-*" HEAD^
check_describe "test2-lightweight-*" --long --tags --match="test1-*" --no-match --match="test2-*" HEAD^
+check_describe "test1-lightweight-*" --long --tags --match="test1-*" --match="test3-*" HEAD
+
+check_describe "test1-lightweight-*" --long --tags --match="test3-*" --match="test1-*" HEAD
+
test_expect_success 'name-rev with exact tags' '
echo A >expect &&
tag_object=$(git rev-parse refs/tags/A) &&
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index 2274a4b73..edc1bd8ea 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -51,6 +51,7 @@ test_atom() {
}
test_atom head refname refs/heads/master
+test_atom head refname: refs/heads/master
test_atom head refname:short master
test_atom head refname:lstrip=1 heads/master
test_atom head refname:lstrip=2 master
diff --git a/t/t8010-cat-file-filters.sh b/t/t8010-cat-file-filters.sh
index d8242e467..0f86c1917 100755
--- a/t/t8010-cat-file-filters.sh
+++ b/t/t8010-cat-file-filters.sh
@@ -51,6 +51,11 @@ test_expect_success '--path=<path> complains without --textconv/--filters' '
grep "path.*needs.*filters" err
'
+test_expect_success '--textconv/--filters complain without path' '
+ test_must_fail git cat-file --textconv HEAD &&
+ test_must_fail git cat-file --filters HEAD
+'
+
test_expect_success 'cat-file --textconv --batch works' '
sha1=$(git rev-parse -q --verify HEAD:world.txt) &&
test_config diff.txt.textconv "tr A-Za-z N-ZA-Mn-za-m <" &&
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index d1e4e8ad1..f30980895 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -148,6 +148,8 @@ cat >expected-cc <<\EOF
!two@example.com!
!three@example.com!
!four@example.com!
+!five@example.com!
+!six@example.com!
EOF
"
@@ -161,6 +163,8 @@ test_expect_success $PREREQ 'cc trailer with various syntax' '
Cc: <two@example.com> # trailing comments are ignored
Cc: <three@example.com>, <not.four@example.com> one address per line
Cc: "Some # Body" <four@example.com> [ <also.a.comment> ]
+ Cc: five@example.com # not.six@example.com
+ Cc: six@example.com, not.seven@example.com
EOF
clean_fake_sendmail &&
git send-email -1 --to=recipient@example.com \
diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh
index 432c61d24..c30660d60 100755
--- a/t/t9400-git-cvsserver-server.sh
+++ b/t/t9400-git-cvsserver-server.sh
@@ -588,4 +588,52 @@ test_expect_success 'cvs annotate' '
test_cmp ../expect ../actual
'
+#------------
+# running via git-shell
+#------------
+
+cd "$WORKDIR"
+
+test_expect_success 'create remote-cvs helper' '
+ write_script remote-cvs <<-\EOF
+ exec git shell -c "cvs server"
+ EOF
+'
+
+test_expect_success 'cvs server does not run with vanilla git-shell' '
+ (
+ cd cvswork &&
+ CVS_SERVER=$WORKDIR/remote-cvs &&
+ export CVS_SERVER &&
+ test_must_fail cvs log merge
+ )
+'
+
+test_expect_success 'configure git shell to run cvs server' '
+ mkdir "$HOME"/git-shell-commands &&
+
+ write_script "$HOME"/git-shell-commands/cvs <<-\EOF &&
+ if ! test $# = 1 && test "$1" = "server"
+ then
+ echo >&2 "git-cvsserver only handles \"server\""
+ exit 1
+ fi
+ exec git cvsserver server
+ EOF
+
+ # Should not be used, but part of the recommended setup
+ write_script "$HOME"/git-shell-commands/no-interactive-login <<-\EOF
+ echo Interactive login forbidden
+ EOF
+'
+
+test_expect_success 'cvs server can run with recommended config' '
+ (
+ cd cvswork &&
+ CVS_SERVER=$WORKDIR/remote-cvs &&
+ export CVS_SERVER &&
+ cvs log merge
+ )
+'
+
test_done
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 51f52dcd4..5fbd8d4a9 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -99,7 +99,6 @@ unset VISUAL EMAIL LANGUAGE COLUMNS $("$PERL_PATH" -e '
my $ok = join("|", qw(
TRACE
DEBUG
- USE_LOOKUP
TEST
.*_TEST
PROVE
diff --git a/userdiff.c b/userdiff.c
index 2c1502f71..d31466722 100644
--- a/userdiff.c
+++ b/userdiff.c
@@ -38,7 +38,7 @@ IPATTERN("fortran",
"|//|\\*\\*|::|[/<>=]="),
IPATTERN("fountain", "^((\\.[^.]|(int|ext|est|int\\.?/ext|i/e)[. ]).*)$",
"[^ \t-]+"),
-PATTERNS("html", "^[ \t]*(<[Hh][1-6][ \t].*>.*)$",
+PATTERNS("html", "^[ \t]*(<[Hh][1-6]([ \t].*)?>.*)$",
"[^<>= \t]+"),
PATTERNS("java",
"!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"