summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/RelNotes/1.7.6.txt16
-rw-r--r--Documentation/config.txt8
-rw-r--r--Documentation/diff-options.txt20
-rw-r--r--Documentation/git-instaweb.txt8
-rw-r--r--Documentation/git-status.txt7
-rw-r--r--Documentation/git.txt5
-rwxr-xr-xGIT-VERSION-GEN2
-rw-r--r--builtin/branch.c2
-rw-r--r--builtin/cat-file.c2
-rw-r--r--builtin/checkout.c23
-rw-r--r--builtin/commit.c7
-rw-r--r--builtin/diff.c1
-rw-r--r--builtin/fetch.c6
-rw-r--r--builtin/gc.c2
-rw-r--r--builtin/update-index.c4
-rw-r--r--combine-diff.c214
-rwxr-xr-xcontrib/completion/git-completion.bash2
-rw-r--r--diff-lib.c11
-rw-r--r--diff.c75
-rw-r--r--diff.h3
-rwxr-xr-xgit-instaweb.sh84
-rwxr-xr-xgit-svn.perl12
-rw-r--r--gitweb/INSTALL152
-rw-r--r--gitweb/README114
-rwxr-xr-xgitweb/gitweb.perl6
-rw-r--r--http.c5
-rw-r--r--refs.c8
-rw-r--r--refs.h1
-rw-r--r--remote-curl.c10
-rw-r--r--sh-i18n--envsubst.c1
-rw-r--r--t/Makefile2
-rwxr-xr-xt/t2018-checkout-branch.sh11
-rwxr-xr-xt/t3703-add-magic-pathspec.sh12
-rwxr-xr-xt/t3903-stash.sh2
-rwxr-xr-xt/t4040-whitespace-status.sh5
-rwxr-xr-xt/t4048-diff-combined-binary.sh212
-rwxr-xr-xt/t4049-diff-stat-count.sh25
-rwxr-xr-xt/t4203-mailmap.sh2
-rwxr-xr-xt/t4205-log-pretty-formats.sh2
-rwxr-xr-xt/t5506-remote-groups.sh6
-rwxr-xr-xt/t5516-fetch-push.sh10
-rwxr-xr-xt/t7508-status.sh128
-rwxr-xr-xt/t7810-grep.sh6
-rwxr-xr-xt/t9159-git-svn-no-parent-mergeinfo.sh33
-rwxr-xr-xt/t9300-fast-import.sh4
-rwxr-xr-xt/t9500-gitweb-standalone-no-errors.sh8
-rw-r--r--t/test-lib.sh21
-rw-r--r--tree-diff.c3
-rw-r--r--unpack-trees.c4
-rw-r--r--unpack-trees.h1
-rw-r--r--userdiff.c17
-rw-r--r--userdiff.h2
-rw-r--r--wt-status.c2
53 files changed, 991 insertions, 338 deletions
diff --git a/Documentation/RelNotes/1.7.6.txt b/Documentation/RelNotes/1.7.6.txt
index 6ab3252888..9ec498ea39 100644
--- a/Documentation/RelNotes/1.7.6.txt
+++ b/Documentation/RelNotes/1.7.6.txt
@@ -1,4 +1,4 @@
-Git v1.7.6 Release Notes (draft)
+Git v1.7.6 Release Notes
========================
Updates since v1.7.5
@@ -48,7 +48,7 @@ Updates since v1.7.5
easier to parse.
* Aborting "git commit --interactive" discards updates to the index
- made during the interctive session.
+ made during the interactive session.
* "git commit" learned a "--patch" option to directly jump to the
per-hunk selection UI of the interactive mode.
@@ -69,6 +69,8 @@ Updates since v1.7.5
* "git format-patch" can take an empty --subject-prefix now.
+ * "git grep" learned the "-P" option to take pcre regular expressions.
+
* "git log" and friends learned a new "--notes" option to replace the
"--show-notes" option. Unlike "--show-notes", "--notes=<ref>" does
not imply showing the default notes.
@@ -127,8 +129,8 @@ included in this release.
* "git config" used to choke with an insanely long line.
(merge ef/maint-strbuf-init later)
----
-exec >/var/tmp/1
-echo O=$(git describe master)
-O=v1.7.5.3-365-g7eacc2b
-git shortlog --no-merges ^maint ^$O master
+ * "git diff --quiet" did not work well with --diff-filter.
+ (merge jk/diff-not-so-quick later)
+
+ * "git status -z" did not default to --porcelain output format.
+ (merge bc/maint-status-z-to-use-porcelain later)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 6b93777199..c631d1cbf9 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -1196,6 +1196,14 @@ http.proxy::
environment variable (see linkgit:curl[1]). This can be overridden
on a per-remote basis; see remote.<name>.proxy
+http.cookiefile::
+ File containing previously stored cookie lines which should be used
+ in the git http session, if they match the server. The file format
+ of the file to read cookies from should be plain HTTP headers or
+ the Netscape/Mozilla cookie file format (see linkgit:curl[1]).
+ NOTE that the file specified with http.cookiefile is only used as
+ input. No cookies will be stored in the file.
+
http.sslVerify::
Whether to verify the SSL certificate when fetching or pushing
over HTTPS. Can be overridden by the 'GIT_SSL_NO_VERIFY' environment
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index c7ed946357..4235302ea4 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -48,11 +48,17 @@ endif::git-format-patch[]
--patience::
Generate a diff using the "patience diff" algorithm.
---stat[=<width>[,<name-width>]]::
+--stat[=<width>[,<name-width>[,<count>]]]::
Generate a diffstat. You can override the default
output width for 80-column terminal by `--stat=<width>`.
The width of the filename part can be controlled by
giving another width to it separated by a comma.
+ By giving a third parameter `<count>`, you can limit the
+ output to the first `<count>` lines, followed by
+ `...` if there are more.
++
+These parameters can also be set individually with `--stat-width=<width>`,
+`--stat-name-width=<name-width>` and `--stat-count=<count>`.
--numstat::
Similar to `\--stat`, but shows number of added and
@@ -224,10 +230,14 @@ endif::git-format-patch[]
ifndef::git-format-patch[]
--check::
- Warn if changes introduce trailing whitespace
- or an indent that uses a space before a tab. Exits with
- non-zero status if problems are found. Not compatible with
- --exit-code.
+ Warn if changes introduce whitespace errors. What are
+ considered whitespace errors is controlled by `core.whitespace`
+ configuration. By default, trailing whitespaces (including
+ lines that solely consist of whitespaces) and a space character
+ that is immediately followed by a tab character inside the
+ initial indent of the line are considered whitespace errors.
+ Exits with non-zero status if problems are found. Not compatible
+ with --exit-code.
endif::git-format-patch[]
--full-index::
diff --git a/Documentation/git-instaweb.txt b/Documentation/git-instaweb.txt
index 08f85ba046..ea95c90460 100644
--- a/Documentation/git-instaweb.txt
+++ b/Documentation/git-instaweb.txt
@@ -51,8 +51,8 @@ OPTIONS
start::
--start::
- Start the httpd instance and exit. This does not generate
- any of the configuration files for spawning a new instance.
+ Start the httpd instance and exit. Regenerate configuration files
+ as necessary for spawning a new instance.
stop::
--stop::
@@ -62,8 +62,8 @@ stop::
restart::
--restart::
- Restart the httpd instance and exit. This does not generate
- any of the configuration files for spawning a new instance.
+ Restart the httpd instance and exit. Regenerate configuration files
+ as necessary for spawning a new instance.
CONFIGURATION
-------------
diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt
index 38cb741f18..8ecc99d995 100644
--- a/Documentation/git-status.txt
+++ b/Documentation/git-status.txt
@@ -69,6 +69,9 @@ configuration variable documented in linkgit:git-config[1].
(and suppresses the output of submodule summaries when the config option
`status.submodulesummary` is set).
+--ignored::
+ Show ignored files as well.
+
-z::
Terminate entries with NUL, instead of LF. This implies
the `--porcelain` output format if no other format is given.
@@ -119,7 +122,8 @@ codes can be interpreted as follows:
* 'C' = copied
* 'U' = updated but unmerged
-Ignored files are not listed.
+Ignored files are not listed, unless `--ignored` option is in effect,
+in which case `XY` are `!!`.
X Y Meaning
-------------------------------------------------
@@ -142,6 +146,7 @@ Ignored files are not listed.
U U unmerged, both modified
-------------------------------------------------
? ? untracked
+ ! ! ignored
-------------------------------------------------
If -b is used the short-format status is preceded by a line
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 5c45446a4a..3c7a832343 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -44,6 +44,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.6/git.html[documentation for release 1.7.6]
+
+* release notes for
+ link:RelNotes/1.7.6.txt[1.7.6].
+
* link:v1.7.5.4/git.html[documentation for release 1.7.5.4]
* release notes for
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 7f48227494..f04e4b138d 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.5.GIT
+DEF_VER=v1.7.6
LF='
'
diff --git a/builtin/branch.c b/builtin/branch.c
index d6ab93bfbb..3142daa57a 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -19,7 +19,7 @@
static const char * const builtin_branch_usage[] = {
"git branch [options] [-r | -a] [--merged | --no-merged]",
"git branch [options] [-l] [-f] <branchname> [<start-point>]",
- "git branch [options] [-r] (-d | -D) <branchname>",
+ "git branch [options] [-r] (-d | -D) <branchname>...",
"git branch [options] (-m | -M) [<oldbranch>] <newbranch>",
NULL
};
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 94632dbdb4..07bd984084 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -187,6 +187,8 @@ static int batch_one_object(const char *obj_name, int print_contents)
if (type <= 0) {
printf("%s missing\n", obj_name);
fflush(stdout);
+ if (print_contents == BATCH)
+ free(contents);
return 0;
}
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 28cdc51b85..f152adf9ab 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -657,24 +657,25 @@ static void suggest_reattach(struct commit *commit, struct rev_info *revs)
"Warning: you are leaving %d commit behind, "
"not connected to\n"
"any of your branches:\n\n"
- "%s\n"
- "If you want to keep it by creating a new branch, "
- "this may be a good time\nto do so with:\n\n"
- " git branch new_branch_name %s\n\n",
+ "%s\n",
/* The plural version */
"Warning: you are leaving %d commits behind, "
"not connected to\n"
"any of your branches:\n\n"
- "%s\n"
- "If you want to keep them by creating a new branch, "
- "this may be a good time\nto do so with:\n\n"
- " git branch new_branch_name %s\n\n",
+ "%s\n",
/* Give ngettext() the count */
lost),
lost,
- sb.buf,
- sha1_to_hex(commit->object.sha1));
+ sb.buf);
strbuf_release(&sb);
+
+ if (advice_detached_head)
+ fprintf(stderr,
+ _(
+ "If you want to keep them by creating a new branch, "
+ "this may be a good time\nto do so with:\n\n"
+ " git branch new_branch_name %s\n\n"),
+ sha1_to_hex(commit->object.sha1));
}
/*
@@ -1071,7 +1072,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
if (strbuf_check_branch_ref(&buf, opts.new_branch))
die(_("git checkout: we do not like '%s' as a branch name."),
opts.new_branch);
- if (!get_sha1(buf.buf, rev)) {
+ if (ref_exists(buf.buf)) {
opts.branch_exists = 1;
if (!opts.new_branch_force)
die(_("git checkout: branch %s already exists"),
diff --git a/builtin/commit.c b/builtin/commit.c
index 5286432f39..e1af9b19f0 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1207,9 +1207,6 @@ int cmd_status(int argc, const char **argv, const char *prefix)
if (argc == 2 && !strcmp(argv[1], "-h"))
usage_with_options(builtin_status_usage, builtin_status_options);
- if (null_termination && status_format == STATUS_FORMAT_LONG)
- status_format = STATUS_FORMAT_PORCELAIN;
-
wt_status_prepare(&s);
gitmodules_config();
git_config(git_status_config, &s);
@@ -1217,6 +1214,10 @@ int cmd_status(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix,
builtin_status_options,
builtin_status_usage, 0);
+
+ if (null_termination && status_format == STATUS_FORMAT_LONG)
+ status_format = STATUS_FORMAT_PORCELAIN;
+
handle_untracked_files_arg(&s);
if (show_ignored_in_status)
s.show_ignored_files = 1;
diff --git a/builtin/diff.c b/builtin/diff.c
index 14bd14fce0..69cd5eed78 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -182,6 +182,7 @@ static int builtin_diff_combined(struct rev_info *revs,
hashcpy((unsigned char *)(parent + i), ent[i].item->sha1);
diff_tree_combined(parent[0], parent + 1, ents - 1,
revs->dense_combined_merges, revs);
+ free(parent);
return 0;
}
diff --git a/builtin/fetch.c b/builtin/fetch.c
index f9c41da475..93c99385a9 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -875,6 +875,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)
{
int i;
static const char **refs = NULL;
+ struct refspec *refspec;
int ref_nr = 0;
int exit_code;
@@ -915,8 +916,9 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)
sigchain_push_common(unlock_pack_on_signal);
atexit(unlock_pack);
- exit_code = do_fetch(transport,
- parse_fetch_refspec(ref_nr, refs), ref_nr);
+ refspec = parse_fetch_refspec(ref_nr, refs);
+ exit_code = do_fetch(transport, refspec, ref_nr);
+ free(refspec);
transport_disconnect(transport);
transport = NULL;
return exit_code;
diff --git a/builtin/gc.c b/builtin/gc.c
index ff5f73ba87..0498094711 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -225,7 +225,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
fprintf(stderr,
_("Auto packing the repository for optimum performance. You may also\n"
"run \"git gc\" manually. See "
- "\"git help gc\" for more information."));
+ "\"git help gc\" for more information.\n"));
} else
append_option(argv_repack,
prune_expire && !strcmp(prune_expire, "now")
diff --git a/builtin/update-index.c b/builtin/update-index.c
index f14bc90830..a6a23fa1f3 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -100,8 +100,10 @@ static int add_one_path(struct cache_entry *old, const char *path, int len, stru
ce->ce_mode = ce_mode_from_stat(old, st->st_mode);
if (index_path(ce->sha1, path, st,
- info_only ? 0 : HASH_WRITE_OBJECT))
+ info_only ? 0 : HASH_WRITE_OBJECT)) {
+ free(ce);
return -1;
+ }
option = allow_add ? ADD_CACHE_OK_TO_ADD : 0;
option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;
if (add_cache_entry(ce, option))
diff --git a/combine-diff.c b/combine-diff.c
index 655fa89d8a..be67cfcd45 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -7,6 +7,7 @@
#include "xdiff-interface.h"
#include "log-tree.h"
#include "refs.h"
+#include "userdiff.h"
static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent)
{
@@ -92,7 +93,9 @@ struct sline {
unsigned long *p_lno;
};
-static char *grab_blob(const unsigned char *sha1, unsigned int mode, unsigned long *size)
+static char *grab_blob(const unsigned char *sha1, unsigned int mode,
+ unsigned long *size, struct userdiff_driver *textconv,
+ const char *path)
{
char *blob;
enum object_type type;
@@ -105,6 +108,11 @@ static char *grab_blob(const unsigned char *sha1, unsigned int mode, unsigned lo
/* deleted blob */
*size = 0;
return xcalloc(1, 1);
+ } else if (textconv) {
+ struct diff_filespec *df = alloc_filespec(path);
+ fill_filespec(df, sha1, mode);
+ *size = fill_textconv(textconv, df, &blob);
+ free_filespec(df);
} else {
blob = read_sha1_file(sha1, &type, size);
if (type != OBJ_BLOB)
@@ -204,7 +212,9 @@ 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 result_deleted)
+ int num_parent, int result_deleted,
+ struct userdiff_driver *textconv,
+ const char *path)
{
unsigned int p_lno, lno;
unsigned long nmask = (1UL << n);
@@ -217,7 +227,7 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
if (result_deleted)
return; /* result deleted */
- parent_file.ptr = grab_blob(parent, mode, &sz);
+ parent_file.ptr = grab_blob(parent, mode, &sz, textconv, path);
parent_file.size = sz;
memset(&xpp, 0, sizeof(xpp));
xpp.flags = 0;
@@ -681,6 +691,82 @@ static void dump_quoted_path(const char *head,
puts(buf.buf);
}
+static void show_combined_header(struct combine_diff_path *elem,
+ int num_parent,
+ int dense,
+ struct rev_info *rev,
+ int mode_differs,
+ int show_file_header)
+{
+ struct diff_options *opt = &rev->diffopt;
+ int abbrev = DIFF_OPT_TST(opt, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
+ const char *a_prefix = opt->a_prefix ? opt->a_prefix : "a/";
+ const char *b_prefix = opt->b_prefix ? opt->b_prefix : "b/";
+ int use_color = DIFF_OPT_TST(opt, COLOR_DIFF);
+ const char *c_meta = diff_get_color(use_color, DIFF_METAINFO);
+ const char *c_reset = diff_get_color(use_color, DIFF_RESET);
+ const char *abb;
+ int added = 0;
+ int deleted = 0;
+ int i;
+
+ if (rev->loginfo && !rev->no_commit_id)
+ show_log(rev);
+
+ dump_quoted_path(dense ? "diff --cc " : "diff --combined ",
+ "", elem->path, c_meta, c_reset);
+ printf("%sindex ", c_meta);
+ for (i = 0; i < num_parent; i++) {
+ abb = find_unique_abbrev(elem->parent[i].sha1,
+ abbrev);
+ printf("%s%s", i ? "," : "", abb);
+ }
+ abb = find_unique_abbrev(elem->sha1, abbrev);
+ printf("..%s%s\n", abb, c_reset);
+
+ if (mode_differs) {
+ deleted = !elem->mode;
+
+ /* We say it was added if nobody had it */
+ added = !deleted;
+ for (i = 0; added && i < num_parent; i++)
+ if (elem->parent[i].status !=
+ DIFF_STATUS_ADDED)
+ added = 0;
+ if (added)
+ printf("%snew file mode %06o",
+ c_meta, elem->mode);
+ else {
+ if (deleted)
+ printf("%sdeleted file ", c_meta);
+ printf("mode ");
+ for (i = 0; i < num_parent; i++) {
+ printf("%s%06o", i ? "," : "",
+ elem->parent[i].mode);
+ }
+ if (elem->mode)
+ printf("..%06o", elem->mode);
+ }
+ printf("%s\n", c_reset);
+ }
+
+ if (!show_file_header)
+ return;
+
+ if (added)
+ dump_quoted_path("--- ", "", "/dev/null",
+ c_meta, c_reset);
+ else
+ dump_quoted_path("--- ", a_prefix, elem->path,
+ c_meta, c_reset);
+ if (deleted)
+ dump_quoted_path("+++ ", "", "/dev/null",
+ c_meta, c_reset);
+ else
+ dump_quoted_path("+++ ", b_prefix, elem->path,
+ c_meta, c_reset);
+}
+
static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
int dense, struct rev_info *rev)
{
@@ -692,17 +778,22 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
int mode_differs = 0;
int i, show_hunks;
int working_tree_file = is_null_sha1(elem->sha1);
- int abbrev = DIFF_OPT_TST(opt, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
- const char *a_prefix, *b_prefix;
mmfile_t result_file;
+ struct userdiff_driver *userdiff;
+ struct userdiff_driver *textconv = NULL;
+ int is_binary;
context = opt->context;
- a_prefix = opt->a_prefix ? opt->a_prefix : "a/";
- b_prefix = opt->b_prefix ? opt->b_prefix : "b/";
+ userdiff = userdiff_find_by_path(elem->path);
+ if (!userdiff)
+ userdiff = userdiff_find_by_name("default");
+ if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV))
+ textconv = userdiff_get_textconv(userdiff);
/* Read the result of merge first */
if (!working_tree_file)
- result = grab_blob(elem->sha1, elem->mode, &result_size);
+ result = grab_blob(elem->sha1, elem->mode, &result_size,
+ textconv, elem->path);
else {
/* Used by diff-tree to read from the working tree */
struct stat st;
@@ -725,9 +816,16 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
} else if (S_ISDIR(st.st_mode)) {
unsigned char sha1[20];
if (resolve_gitlink_ref(elem->path, "HEAD", sha1) < 0)
- result = grab_blob(elem->sha1, elem->mode, &result_size);
+ result = grab_blob(elem->sha1, elem->mode,
+ &result_size, NULL, NULL);
else
- result = grab_blob(sha1, elem->mode, &result_size);
+ result = grab_blob(sha1, elem->mode,
+ &result_size, NULL, NULL);
+ } else if (textconv) {
+ struct diff_filespec *df = alloc_filespec(elem->path);
+ fill_filespec(df, null_sha1, st.st_mode);
+ result_size = fill_textconv(textconv, df, &result);
+ free_filespec(df);
} else if (0 <= (fd = open(elem->path, O_RDONLY))) {
size_t len = xsize_t(st.st_size);
ssize_t done;
@@ -777,6 +875,38 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
close(fd);
}
+ for (i = 0; i < num_parent; i++) {
+ if (elem->parent[i].mode != elem->mode) {
+ mode_differs = 1;
+ break;
+ }
+ }
+
+ if (textconv)
+ is_binary = 0;
+ else if (userdiff->binary != -1)
+ is_binary = userdiff->binary;
+ else {
+ is_binary = buffer_is_binary(result, result_size);
+ for (i = 0; !is_binary && i < num_parent; i++) {
+ char *buf;
+ unsigned long size;
+ buf = grab_blob(elem->parent[i].sha1,
+ elem->parent[i].mode,
+ &size, NULL, NULL);
+ if (buffer_is_binary(buf, size))
+ is_binary = 1;
+ free(buf);
+ }
+ }
+ if (is_binary) {
+ show_combined_header(elem, num_parent, dense, rev,
+ mode_differs, 0);
+ printf("Binary files differ\n");
+ free(result);
+ return;
+ }
+
for (cnt = 0, cp = result; cp < result + result_size; cp++) {
if (*cp == '\n')
cnt++;
@@ -824,71 +954,15 @@ 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, result_deleted);
- if (elem->parent[i].mode != elem->mode)
- mode_differs = 1;
+ cnt, i, num_parent, result_deleted,
+ textconv, elem->path);
}
show_hunks = make_hunks(sline, cnt, num_parent, dense);
if (show_hunks || mode_differs || working_tree_file) {
- const char *abb;
- int use_color = DIFF_OPT_TST(opt, COLOR_DIFF);
- const char *c_meta = diff_get_color(use_color, DIFF_METAINFO);
- const char *c_reset = diff_get_color(use_color, DIFF_RESET);
- int added = 0;
- int deleted = 0;
-
- if (rev->loginfo && !rev->no_commit_id)
- show_log(rev);
- dump_quoted_path(dense ? "diff --cc " : "diff --combined ",
- "", elem->path, c_meta, c_reset);
- printf("%sindex ", c_meta);
- for (i = 0; i < num_parent; i++) {
- abb = find_unique_abbrev(elem->parent[i].sha1,
- abbrev);
- printf("%s%s", i ? "," : "", abb);
- }
- abb = find_unique_abbrev(elem->sha1, abbrev);
- printf("..%s%s\n", abb, c_reset);
-
- if (mode_differs) {
- deleted = !elem->mode;
-
- /* We say it was added if nobody had it */
- added = !deleted;
- for (i = 0; added && i < num_parent; i++)
- if (elem->parent[i].status !=
- DIFF_STATUS_ADDED)
- added = 0;
- if (added)
- printf("%snew file mode %06o",
- c_meta, elem->mode);
- else {
- if (deleted)
- printf("%sdeleted file ", c_meta);
- printf("mode ");
- for (i = 0; i < num_parent; i++) {
- printf("%s%06o", i ? "," : "",
- elem->parent[i].mode);
- }
- if (elem->mode)
- printf("..%06o", elem->mode);
- }
- printf("%s\n", c_reset);
- }
- if (added)
- dump_quoted_path("--- ", "", "/dev/null",
- c_meta, c_reset);
- else
- dump_quoted_path("--- ", a_prefix, elem->path,
- c_meta, c_reset);
- if (deleted)
- dump_quoted_path("+++ ", "", "/dev/null",
- c_meta, c_reset);
- else
- dump_quoted_path("+++ ", b_prefix, elem->path,
- c_meta, c_reset);
+ show_combined_header(elem, num_parent, dense, rev,
+ mode_differs, 1);
dump_sline(sline, cnt, num_parent,
DIFF_OPT_TST(opt, COLOR_DIFF), result_deleted);
}
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index b36290fa60..5a8309076d 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2058,7 +2058,7 @@ _git_config ()
color.ui
commit.status
commit.template
- core.abbrevguard
+ core.abbrev
core.askpass
core.attributesfile
core.autocrlf
diff --git a/diff-lib.c b/diff-lib.c
index 3b5f2242a5..2e09500c82 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -102,9 +102,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
int changed;
unsigned dirty_submodule = 0;
- if (DIFF_OPT_TST(&revs->diffopt, QUICK) &&
- !revs->diffopt.filter &&
- DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES))
+ if (diff_can_quit_early(&revs->diffopt))
break;
if (!ce_path_match(ce, &revs->prune_data))
@@ -435,8 +433,13 @@ static int oneway_diff(struct cache_entry **src, struct unpack_trees_options *o)
if (tree == o->df_conflict_entry)
tree = NULL;
- if (ce_path_match(idx ? idx : tree, &revs->prune_data))
+ if (ce_path_match(idx ? idx : tree, &revs->prune_data)) {
do_oneway_diff(o, idx, tree);
+ if (diff_can_quit_early(&revs->diffopt)) {
+ o->exiting_early = 1;
+ return -1;
+ }
+ }
return 0;
}
diff --git a/diff.c b/diff.c
index 8f4815bfd7..918c70ca45 100644
--- a/diff.c
+++ b/diff.c
@@ -1316,9 +1316,10 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
int i, len, add, del, adds = 0, dels = 0;
uintmax_t max_change = 0, max_len = 0;
int total_files = data->nr;
- int width, name_width;
+ int width, name_width, count;
const char *reset, *add_c, *del_c;
const char *line_prefix = "";
+ int extra_shown = 0;
struct strbuf *msg = NULL;
if (data->nr == 0)
@@ -1331,6 +1332,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
width = options->stat_width ? options->stat_width : 80;
name_width = options->stat_name_width ? options->stat_name_width : 50;
+ count = options->stat_count ? options->stat_count : data->nr;
/* Sanity: give at least 5 columns to the graph,
* but leave at least 10 columns for the name.
@@ -1347,9 +1349,14 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
add_c = diff_get_color_opt(options, DIFF_FILE_NEW);
del_c = diff_get_color_opt(options, DIFF_FILE_OLD);
- for (i = 0; i < data->nr; i++) {
+ for (i = 0; (i < count) && (i < data->nr); i++) {
struct diffstat_file *file = data->files[i];
uintmax_t change = file->added + file->deleted;
+ if (!data->files[i]->is_renamed &&
+ (change == 0)) {
+ count++; /* not shown == room for one more */
+ continue;
+ }
fill_print_name(file);
len = strlen(file->print_name);
if (max_len < len)
@@ -1360,6 +1367,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
if (max_change < change)
max_change = change;
}
+ count = i; /* min(count, data->nr) */
/* Compute the width of the graph part;
* 10 is for one blank at the beginning of the line plus
@@ -1374,13 +1382,18 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
else
width = max_change;
- for (i = 0; i < data->nr; i++) {
+ for (i = 0; i < count; i++) {
const char *prefix = "";
char *name = data->files[i]->print_name;
uintmax_t added = data->files[i]->added;
uintmax_t deleted = data->files[i]->deleted;
int name_len;
+ if (!data->files[i]->is_renamed &&
+ (added + deleted == 0)) {
+ total_files--;
+ continue;
+ }
/*
* "scale" the filename
*/
@@ -1415,11 +1428,6 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
fprintf(options->file, " Unmerged\n");
continue;
}
- else if (!data->files[i]->is_renamed &&
- (added + deleted == 0)) {
- total_files--;
- continue;
- }
/*
* scale the add/delete
@@ -1441,6 +1449,20 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
show_graph(options->file, '-', del, del_c, reset);
fprintf(options->file, "\n");
}
+ for (i = count; i < data->nr; i++) {
+ uintmax_t added = data->files[i]->added;
+ uintmax_t deleted = data->files[i]->deleted;
+ if (!data->files[i]->is_renamed &&
+ (added + deleted == 0)) {
+ total_files--;
+ continue;
+ }
+ adds += added;
+ dels += deleted;
+ if (!extra_shown)
+ fprintf(options->file, "%s ...\n", line_prefix);
+ extra_shown = 1;
+ }
fprintf(options->file, "%s", line_prefix);
fprintf(options->file,
" %d files changed, %d insertions(+), %d deletions(-)\n",
@@ -1984,19 +2006,7 @@ struct userdiff_driver *get_textconv(struct diff_filespec *one)
return NULL;
diff_filespec_load_driver(one);
- if (!one->driver->textconv)
- return NULL;
-
- if (one->driver->textconv_want_cache && !one->driver->textconv_cache) {
- struct notes_cache *c = xmalloc(sizeof(*c));
- struct strbuf name = STRBUF_INIT;
-
- strbuf_addf(&name, "textconv/%s", one->driver->name);
- notes_cache_init(c, name.buf, one->driver->textconv);
- one->driver->textconv_cache = c;
- }
-
- return one->driver;
+ return userdiff_get_textconv(one->driver);
}
static void builtin_diff(const char *name_a,
@@ -3220,6 +3230,7 @@ static int stat_opt(struct diff_options *options, const char **av)
char *end;
int width = options->stat_width;
int name_width = options->stat_name_width;
+ int count = options->stat_count;
int argcount = 1;
arg += strlen("--stat");
@@ -3247,12 +3258,24 @@ static int stat_opt(struct diff_options *options, const char **av)
name_width = strtoul(av[1], &end, 10);
argcount = 2;
}
+ } else if (!prefixcmp(arg, "-count")) {
+ arg += strlen("-count");
+ if (*arg == '=')
+ count = strtoul(arg + 1, &end, 10);
+ else if (!*arg && !av[1])
+ die("Option '--stat-count' requires a value");
+ else if (!*arg) {
+ count = strtoul(av[1], &end, 10);
+ argcount = 2;
+ }
}
break;
case '=':
width = strtoul(arg+1, &end, 10);
if (*end == ',')
name_width = strtoul(end+1, &end, 10);
+ if (*end == ',')
+ count = strtoul(end+1, &end, 10);
}
/* Important! This checks all the error cases! */
@@ -3261,6 +3284,7 @@ static int stat_opt(struct diff_options *options, const char **av)
options->output_format |= DIFF_FORMAT_DIFFSTAT;
options->stat_name_width = name_width;
options->stat_width = width;
+ options->stat_count = count;
return argcount;
}
@@ -3325,7 +3349,7 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
else if (!strcmp(arg, "-s"))
options->output_format |= DIFF_FORMAT_NO_OUTPUT;
else if (!prefixcmp(arg, "--stat"))
- /* --stat, --stat-width, or --stat-name-width */
+ /* --stat, --stat-width, --stat-name-width, or --stat-count */
return stat_opt(options, av);
/* renames options */
@@ -4456,6 +4480,13 @@ int diff_result_code(struct diff_options *opt, int status)
return result;
}
+int diff_can_quit_early(struct diff_options *opt)
+{
+ return (DIFF_OPT_TST(opt, QUICK) &&
+ !opt->filter &&
+ DIFF_OPT_TST(opt, HAS_CHANGES));
+}
+
/*
* Shall changes to this submodule be ignored?
*
diff --git a/diff.h b/diff.h
index adb40ba273..b920a20f80 100644
--- a/diff.h
+++ b/diff.h
@@ -125,6 +125,7 @@ struct diff_options {
int stat_width;
int stat_name_width;
+ int stat_count;
const char *word_regex;
enum diff_words_type word_diff;
@@ -198,6 +199,8 @@ extern void diff_tree_combined_merge(const unsigned char *sha1, int, struct rev_
void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b);
+extern int diff_can_quit_early(struct diff_options *);
+
extern void diff_addremove(struct diff_options *,
int addremove,
unsigned mode,
diff --git a/git-instaweb.sh b/git-instaweb.sh
index 8bfa8a055c..01a1b05e6b 100755
--- a/git-instaweb.sh
+++ b/git-instaweb.sh
@@ -27,6 +27,7 @@ httpd="$(git config --get instaweb.httpd)"
root="$(git config --get instaweb.gitwebdir)"
port=$(git config --get instaweb.port)
module_path="$(git config --get instaweb.modulepath)"
+action="browse"
conf="$GIT_DIR/gitweb/httpd.conf"
@@ -98,12 +99,18 @@ start_httpd () {
# here $httpd should have a meaningful value
resolve_full_httpd
+ mkdir -p "$fqgitdir/gitweb/$httpd_only"
+ conf="$fqgitdir/gitweb/$httpd_only.conf"
+
+ # generate correct config file if it doesn't exist
+ test -f "$conf" || configure_httpd
+ test -f "$fqgitdir/gitweb/gitweb_config.perl" || gitweb_conf
# don't quote $full_httpd, there can be arguments to it (-f)
case "$httpd" in
*mongoose*|*plackup*)
#These servers don't have a daemon mode so we'll have to fork it
- $full_httpd "$fqgitdir/gitweb/httpd.conf" &
+ $full_httpd "$conf" &
#Save the pid before doing anything else (we'll print it later)
pid=$!
@@ -117,7 +124,7 @@ $pid
EOF
;;
*)
- $full_httpd "$fqgitdir/gitweb/httpd.conf"
+ $full_httpd "$conf"
if test $? != 0; then
echo "Could not execute http daemon $httpd."
exit 1
@@ -148,17 +155,13 @@ while test $# != 0
do
case "$1" in
--stop|stop)
- stop_httpd
- exit 0
+ action="stop"
;;
--start|start)
- start_httpd
- exit 0
+ action="start"
;;
--restart|restart)
- stop_httpd
- start_httpd
- exit 0
+ action="restart"
;;
-l|--local)
local=true
@@ -587,33 +590,54 @@ our \$projects_list = \$projectroot;
EOF
}
-gitweb_conf
-
-resolve_full_httpd
-mkdir -p "$fqgitdir/gitweb/$httpd_only"
+configure_httpd() {
+ case "$httpd" in
+ *lighttpd*)
+ lighttpd_conf
+ ;;
+ *apache2*|*httpd*)
+ apache2_conf
+ ;;
+ webrick)
+ webrick_conf
+ ;;
+ *mongoose*)
+ mongoose_conf
+ ;;
+ *plackup*)
+ plackup_conf
+ ;;
+ *)
+ echo "Unknown httpd specified: $httpd"
+ exit 1
+ ;;
+ esac
+}
-case "$httpd" in
-*lighttpd*)
- lighttpd_conf
- ;;
-*apache2*|*httpd*)
- apache2_conf
- ;;
-webrick)
- webrick_conf
+case "$action" in
+stop)
+ stop_httpd
+ exit 0
;;
-*mongoose*)
- mongoose_conf
+start)
+ start_httpd
+ exit 0
;;
-*plackup*)
- plackup_conf
- ;;
-*)
- echo "Unknown httpd specified: $httpd"
- exit 1
+restart)
+ stop_httpd
+ start_httpd
+ exit 0
;;
esac
+gitweb_conf
+
+resolve_full_httpd
+mkdir -p "$fqgitdir/gitweb/$httpd_only"
+conf="$fqgitdir/gitweb/$httpd_only.conf"
+
+configure_httpd
+
start_httpd
url=http://127.0.0.1:$port
diff --git a/git-svn.perl b/git-svn.perl
index 7849cfc141..89f83fd27a 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -3124,8 +3124,12 @@ sub lookup_svn_merge {
next;
}
- push @merged_commit_ranges,
- "$bottom_commit^..$top_commit";
+ if (scalar(command('rev-parse', "$bottom_commit^@"))) {
+ push @merged_commit_ranges,
+ "$bottom_commit^..$top_commit";
+ } else {
+ push @merged_commit_ranges, "$top_commit";
+ }
if ( !defined $tip or $top > $tip ) {
$tip = $top;
@@ -3154,9 +3158,9 @@ sub check_cherry_pick {
my $parents = shift;
my @ranges = @_;
my %commits = map { $_ => 1 }
- _rev_list("--no-merges", $tip, "--not", $base, @$parents);
+ _rev_list("--no-merges", $tip, "--not", $base, @$parents, "--");
for my $range ( @ranges ) {
- delete @commits{_rev_list($range)};
+ delete @commits{_rev_list($range, "--")};
}
for my $commit (keys %commits) {
if (has_no_changes($commit)) {
diff --git a/gitweb/INSTALL b/gitweb/INSTALL
index 4964a679b3..c5236fee9d 100644
--- a/gitweb/INSTALL
+++ b/gitweb/INSTALL
@@ -25,11 +25,25 @@ The above example assumes that your web server is configured to run
scripts).
+Requirements
+------------
+
+ - Core git tools
+ - Perl
+ - Perl modules: CGI, Encode, Fcntl, File::Find, File::Basename.
+ - web server
+
+The following optional Perl modules are required for extra features
+ - Digest::MD5 - for gravatar support
+ - CGI::Fast and FCGI - for running gitweb as FastCGI script
+ - HTML::TagCloud - for fancy tag cloud in project list view
+ - HTTP::Date or Time::ParseDate - to support If-Modified-Since for feeds
+
+
Build time configuration
------------------------
-See also "How to configure gitweb for your local system" in README
-file for gitweb (in gitweb/README).
+See also "How to configure gitweb for your local system" section below.
- There are many configuration variables which affect building of
gitweb.cgi; see "default configuration for gitweb" section in main
@@ -73,6 +87,125 @@ file for gitweb (in gitweb/README).
substitute gitweb.min.js and gitweb.min.css for all uses of gitweb.js and
gitweb.css in the help files.
+
+How to configure gitweb for your local system
+---------------------------------------------
+
+You can specify the following configuration variables when building GIT:
+
+ * GIT_BINDIR
+ Points where to find the git executable. You should set it up to
+ the place where the git binary was installed (usually /usr/bin) if you
+ don't install git from sources together with gitweb. [Default: $(bindir)]
+ * GITWEB_SITENAME
+ Shown in the title of all generated pages, defaults to the server name
+ (SERVER_NAME CGI environment variable) if not set. [No default]
+ * GITWEB_PROJECTROOT
+ The root directory for all projects shown by gitweb. Must be set
+ correctly for gitweb to find repositories to display. See also
+ "Gitweb repositories" in the INSTALL file for gitweb. [Default: /pub/git]
+ * GITWEB_PROJECT_MAXDEPTH
+ The filesystem traversing limit for getting the project list; the number
+ is taken as depth relative to the projectroot. It is used when
+ GITWEB_LIST is a directory (or is not set; then project root is used).
+ This is meant to speed up project listing on large work trees by limiting
+ search depth. [Default: 2007]
+ * GITWEB_LIST
+ Points to a directory to scan for projects (defaults to project root
+ if not set / if empty) or to a file with explicit listing of projects
+ (together with projects' ownership). See "Generating projects list
+ using gitweb" in INSTALL file for gitweb to find out how to generate
+ such file from scan of a directory. [No default, which means use root
+ directory for projects]
+ * GITWEB_EXPORT_OK
+ Show repository only if this file exists (in repository). Only
+ effective if this variable evaluates to true. [No default / Not set]
+ * GITWEB_STRICT_EXPORT
+ Only allow viewing of repositories also shown on the overview page.
+ This for example makes GITWEB_EXPORT_OK to decide if repository is
+ available and not only if it is shown. If GITWEB_LIST points to
+ file with list of project, only those repositories listed would be
+ available for gitweb. [No default]
+ * GITWEB_HOMETEXT
+ Points to an .html file which is included on the gitweb project
+ overview page ('projects_list' view), if it exists. Relative to
+ gitweb.cgi script. [Default: indextext.html]
+ * GITWEB_SITE_HEADER
+ Filename of html text to include at top of each page. Relative to
+ gitweb.cgi script. [No default]
+ * GITWEB_SITE_FOOTER
+ Filename of html text to include at bottom of each page. Relative to
+ gitweb.cgi script. [No default]
+ * GITWEB_HOME_LINK_STR
+ String of the home link on top of all pages, leading to $home_link
+ (usually main gitweb page, which means projects list). Used as first
+ part of gitweb view "breadcrumb trail": <home> / <project> / <view>.
+ [Default: projects]
+ * GITWEB_SITENAME
+ Name of your site or organization to appear in page titles. Set it
+ to something descriptive for clearer bookmarks etc. If not set
+ (if empty) gitweb uses "$SERVER_NAME Git", or "Untitled Git" if
+ SERVER_NAME CGI environment variable is not set (e.g. if running
+ gitweb as standalone script). [No default]
+ * GITWEB_BASE_URL
+ Git base URLs used for URL to where fetch project from, i.e. full
+ URL is "$git_base_url/$project". Shown on projects summary page.
+ Repository URL for project can be also configured per repository; this
+ takes precedence over URLs composed from base URL and a project name.
+ Note that you can setup multiple base URLs (for example one for
+ git:// protocol access, another for http:// access) from the gitweb
+ config file. [No default]
+ * GITWEB_CSS
+ Points to the location where you put gitweb.css on your web server
+ (or to be more generic, the URI of gitweb stylesheet). Relative to the
+ base URI of gitweb. Note that you can setup multiple stylesheets from
+ the gitweb config file. [Default: static/gitweb.css (or
+ static/gitweb.min.css if the CSSMIN variable is defined / CSS minifier
+ is used)]
+ * GITWEB_JS
+ Points to the location where you put gitweb.js on your web server
+ (or to be more generic URI of JavaScript code used by gitweb).
+ Relative to base URI of gitweb. [Default: static/gitweb.js (or
+ static/gitweb.min.js if JSMIN build variable is defined / JavaScript
+ minifier is used)]
+ * CSSMIN, JSMIN
+ Invocation of a CSS minifier or a JavaScript minifier, respectively,
+ working as a filter (source on standard input, minified result on
+ standard output). If set, it is used to generate a minified version of
+ 'static/gitweb.css' or 'static/gitweb.js', respectively. *Note* that
+ minified files would have *.min.css and *.min.js extension, which is
+ important if you also set GITWEB_CSS and/or GITWEB_JS. [No default]
+ * GITWEB_LOGO
+ Points to the location where you put git-logo.png on your web server
+ (or to be more generic URI of logo, 72x27 size, displayed in top right
+ corner of each gitweb page, and used as logo for Atom feed). Relative
+ to base URI of gitweb. [Default: static/git-logo.png]
+ * GITWEB_FAVICON
+ Points to the location where you put git-favicon.png on your web server
+ (or to be more generic URI of favicon, assumed to be image/png type;
+ web browsers that support favicons (website icons) may display them
+ in the browser's URL bar and next to site name in bookmarks). Relative
+ to base URI of gitweb. [Default: static/git-favicon.png]
+ * GITWEB_CONFIG
+ This Perl file will be loaded using 'do' and can be used to override any
+ of the options above as well as some other options -- see the "Runtime
+ gitweb configuration" section below, and top of 'gitweb.cgi' for their
+ full list and description. If the environment variable GITWEB_CONFIG
+ is set when gitweb.cgi is executed, then the file specified in the
+ environment variable will be loaded instead of the file specified
+ when gitweb.cgi was created. [Default: gitweb_config.perl]
+ * GITWEB_CONFIG_SYSTEM
+ This Perl file will be loaded using 'do' as a fallback if GITWEB_CONFIG
+ does not exist. If the environment variable GITWEB_CONFIG_SYSTEM is set
+ when gitweb.cgi is executed, then the file specified in the environment
+ variable will be loaded instead of the file specified when gitweb.cgi was
+ created. [Default: /etc/gitweb.conf]
+ * HIGHLIGHT_BIN
+ Path to the highlight executable to use (must be the one from
+ http://www.andre-simon.de due to assumptions about parameters and output).
+ Useful if highlight is not installed on your webserver's PATH.
+ [Default: highlight]
+
Build example
~~~~~~~~~~~~~
@@ -229,21 +362,6 @@ $projects_list variable in gitweb config):
perl -- /var/www/cgi-bin/gitweb.cgi
-Requirements
-------------
-
- - Core git tools
- - Perl
- - Perl modules: CGI, Encode, Fcntl, File::Find, File::Basename.
- - web server
-
-The following optional Perl modules are required for extra features
- - Digest::MD5 - for gravatar support
- - CGI::Fast and FCGI - for running gitweb as FastCGI script
- - HTML::TagCloud - for fancy tag cloud in project list view
- - HTTP::Date or Time::ParseDate - to support If-Modified-Since for feeds
-
-
Example web server configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/gitweb/README b/gitweb/README
index a3a697bf55..a4cfcb42cd 100644
--- a/gitweb/README
+++ b/gitweb/README
@@ -7,120 +7,6 @@ The one working on:
From the git version 1.4.0 gitweb is bundled with git.
-How to configure gitweb for your local system
----------------------------------------------
-
-See also the "Build time configuration" section in the INSTALL
-file for gitweb (in gitweb/INSTALL).
-
-You can specify the following configuration variables when building GIT:
- * GIT_BINDIR
- Points where to find the git executable. You should set it up to
- the place where the git binary was installed (usually /usr/bin) if you
- don't install git from sources together with gitweb. [Default: $(bindir)]
- * GITWEB_SITENAME
- Shown in the title of all generated pages, defaults to the server name
- (SERVER_NAME CGI environment variable) if not set. [No default]
- * GITWEB_PROJECTROOT
- The root directory for all projects shown by gitweb. Must be set
- correctly for gitweb to find repositories to display. See also
- "Gitweb repositories" in the INSTALL file for gitweb. [Default: /pub/git]
- * GITWEB_PROJECT_MAXDEPTH
- The filesystem traversing limit for getting the project list; the number
- is taken as depth relative to the projectroot. It is used when
- GITWEB_LIST is a directory (or is not set; then project root is used).
- This is meant to speed up project listing on large work trees by limiting
- search depth. [Default: 2007]
- * GITWEB_LIST
- Points to a directory to scan for projects (defaults to project root
- if not set / if empty) or to a file with explicit listing of projects
- (together with projects' ownership). See "Generating projects list
- using gitweb" in INSTALL file for gitweb to find out how to generate
- such file from scan of a directory. [No default, which means use root
- directory for projects]
- * GITWEB_EXPORT_OK
- Show repository only if this file exists (in repository). Only
- effective if this variable evaluates to true. [No default / Not set]
- * GITWEB_STRICT_EXPORT
- Only allow viewing of repositories also shown on the overview page.
- This for example makes GITWEB_EXPORT_OK to decide if repository is
- available and not only if it is shown. If GITWEB_LIST points to
- file with list of project, only those repositories listed would be
- available for gitweb. [No default]
- * GITWEB_HOMETEXT
- Points to an .html file which is included on the gitweb project
- overview page ('projects_list' view), if it exists. Relative to
- gitweb.cgi script. [Default: indextext.html]
- * GITWEB_SITE_HEADER
- Filename of html text to include at top of each page. Relative to
- gitweb.cgi script. [No default]
- * GITWEB_SITE_FOOTER
- Filename of html text to include at bottom of each page. Relative to
- gitweb.cgi script. [No default]
- * GITWEB_HOME_LINK_STR
- String of the home link on top of all pages, leading to $home_link
- (usually main gitweb page, which means projects list). Used as first
- part of gitweb view "breadcrumb trail": <home> / <project> / <view>.
- [Default: projects]
- * GITWEB_SITENAME
- Name of your site or organization to appear in page titles. Set it
- to something descriptive for clearer bookmarks etc. If not set
- (if empty) gitweb uses "$SERVER_NAME Git", or "Untitled Git" if
- SERVER_NAME CGI environment variable is not set (e.g. if running
- gitweb as standalone script). [No default]
- * GITWEB_BASE_URL
- Git base URLs used for URL to where fetch project from, i.e. full
- URL is "$git_base_url/$project". Shown on projects summary page.
- Repository URL for project can be also configured per repository; this
- takes precedence over URLs composed from base URL and a project name.
- Note that you can setup multiple base URLs (for example one for
- git:// protocol access, another for http:// access) from the gitweb
- config file. [No default]
- * GITWEB_CSS
- Points to the location where you put gitweb.css on your web server
- (or to be more generic, the URI of gitweb stylesheet). Relative to the
- base URI of gitweb. Note that you can setup multiple stylesheets from
- the gitweb config file. [Default: static/gitweb.css (or
- static/gitweb.min.css if the CSSMIN variable is defined / CSS minifier
- is used)]
- * GITWEB_LOGO
- Points to the location where you put git-logo.png on your web server
- (or to be more generic URI of logo, 72x27 size, displayed in top right
- corner of each gitweb page, and used as logo for Atom feed). Relative
- to base URI of gitweb. [Default: static/git-logo.png]
- * GITWEB_FAVICON
- Points to the location where you put git-favicon.png on your web server
- (or to be more generic URI of favicon, assumed to be image/png type;
- web browsers that support favicons (website icons) may display them
- in the browser's URL bar and next to site name in bookmarks). Relative
- to base URI of gitweb. [Default: static/git-favicon.png]
- * GITWEB_JS
- Points to the location where you put gitweb.js on your web server
- (or to be more generic URI of JavaScript code used by gitweb).
- Relative to base URI of gitweb. [Default: static/gitweb.js (or
- static/gitweb.min.js if JSMIN build variable is defined / JavaScript
- minifier is used)]
- * GITWEB_CONFIG
- This Perl file will be loaded using 'do' and can be used to override any
- of the options above as well as some other options -- see the "Runtime
- gitweb configuration" section below, and top of 'gitweb.cgi' for their
- full list and description. If the environment variable GITWEB_CONFIG
- is set when gitweb.cgi is executed, then the file specified in the
- environment variable will be loaded instead of the file specified
- when gitweb.cgi was created. [Default: gitweb_config.perl]
- * GITWEB_CONFIG_SYSTEM
- This Perl file will be loaded using 'do' as a fallback if GITWEB_CONFIG
- does not exist. If the environment variable GITWEB_CONFIG_SYSTEM is set
- when gitweb.cgi is executed, then the file specified in the environment
- variable will be loaded instead of the file specified when gitweb.cgi was
- created. [Default: /etc/gitweb.conf]
- * HIGHLIGHT_BIN
- Path to the highlight executable to use (must be the one from
- http://www.andre-simon.de due to assumptions about parameters and output).
- Useful if highlight is not installed on your webserver's PATH.
- [Default: highlight]
-
-
Runtime gitweb configuration
----------------------------
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 240dd4701c..81dacf2b6a 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -328,6 +328,7 @@ our %feature = (
# Enable grep search, which will list the files in currently selected
# tree containing the given string. Enabled by default. This can be
# potentially CPU-intensive, of course.
+ # Note that you need to have 'search' feature enabled too.
# To enable system wide have in $GITWEB_CONFIG
# $feature{'grep'}{'default'} = [1];
@@ -342,6 +343,7 @@ our %feature = (
# Enable the pickaxe search, which will list the commits that modified
# a given string in a file. This can be practical and quite faster
# alternative to 'blame', but still potentially CPU-intensive.
+ # Note that you need to have 'search' feature enabled too.
# To enable system wide have in $GITWEB_CONFIG
# $feature{'pickaxe'}{'default'} = [1];
@@ -2644,7 +2646,7 @@ sub git_get_project_ctags {
close $ct;
(my $ctag = $tagfile) =~ s#.*/##;
- if ($val =~ /\d+/) {
+ if ($val =~ /^\d+$/) {
$ctags->{$ctag} = $val;
} else {
$ctags->{$ctag} = 1;
@@ -6127,7 +6129,7 @@ sub git_blob_plain {
# want to be sure not to break that by serving the image as an
# attachment (though Firefox 3 doesn't seem to care).
my $sandbox = $prevent_xss &&
- $type !~ m!^(?:text/plain|image/(?:gif|png|jpeg))$!;
+ $type !~ m!^(?:text/plain|image/(?:gif|png|jpeg))(?:[ ;]|$)!;
print $cgi->header(
-type => $type,
diff --git a/http.c b/http.c
index b2ae8de16d..a1ea3db499 100644
--- a/http.c
+++ b/http.c
@@ -41,6 +41,7 @@ static long curl_low_speed_limit = -1;
static long curl_low_speed_time = -1;
static int curl_ftp_no_epsv;
static const char *curl_http_proxy;
+static const char *curl_cookie_file;
static char *user_name, *user_pass;
static const char *user_agent;
@@ -191,6 +192,9 @@ static int http_options(const char *var, const char *value, void *cb)
if (!strcmp("http.proxy", var))
return git_config_string(&curl_http_proxy, var, value);
+ if (!strcmp("http.cookiefile", var))
+ return git_config_string(&curl_cookie_file, var, value);
+
if (!strcmp("http.postbuffer", var)) {
http_post_buffer = git_config_int(var, value);
if (http_post_buffer < LARGE_PACKET_MAX)
@@ -531,6 +535,7 @@ struct active_request_slot *get_active_slot(void)
slot->finished = NULL;
slot->callback_data = NULL;
slot->callback_func = NULL;
+ curl_easy_setopt(slot->curl, CURLOPT_COOKIEFILE, curl_cookie_file);
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, pragma_header);
curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, curl_errorstr);
curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, NULL);
diff --git a/refs.c b/refs.c
index e3c05110e5..3a8789d385 100644
--- a/refs.c
+++ b/refs.c
@@ -1451,7 +1451,7 @@ int write_ref_sha1(struct ref_lock *lock,
}
o = parse_object(sha1);
if (!o) {
- error("Trying to write ref %s with nonexistant object %s",
+ error("Trying to write ref %s with nonexistent object %s",
lock->ref_name, sha1_to_hex(sha1));
unlock_ref(lock);
return -1;
@@ -1826,6 +1826,12 @@ int update_ref(const char *action, const char *refname,
return 0;
}
+int ref_exists(char *refname)
+{
+ unsigned char sha1[20];
+ return !!resolve_ref(refname, sha1, 1, NULL);
+}
+
struct ref *find_ref_by_name(const struct ref *list, const char *name)
{
for ( ; list; list = list->next)
diff --git a/refs.h b/refs.h
index 5e7a9a59f5..5de06e57e7 100644
--- a/refs.h
+++ b/refs.h
@@ -54,6 +54,7 @@ extern void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refn
*/
extern void add_extra_ref(const char *refname, const unsigned char *sha1, int flags);
extern void clear_extra_refs(void);
+extern int ref_exists(char *);
extern int peel_ref(const char *, unsigned char *);
diff --git a/remote-curl.c b/remote-curl.c
index 17d8a9b377..b5be25ce96 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -811,19 +811,21 @@ static void parse_push(struct strbuf *buf)
strbuf_reset(buf);
if (strbuf_getline(buf, stdin, '\n') == EOF)
- return;
+ goto free_specs;
if (!*buf->buf)
break;
} while (1);
if (push(nr_spec, specs))
exit(128); /* error already reported */
- for (i = 0; i < nr_spec; i++)
- free(specs[i]);
- free(specs);
printf("\n");
fflush(stdout);
+
+ free_specs:
+ for (i = 0; i < nr_spec; i++)
+ free(specs[i]);
+ free(specs);
}
int main(int argc, const char **argv)
diff --git a/sh-i18n--envsubst.c b/sh-i18n--envsubst.c
index 2eb0ee44b8..9d2e971a27 100644
--- a/sh-i18n--envsubst.c
+++ b/sh-i18n--envsubst.c
@@ -51,7 +51,6 @@
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#include <errno.h>
-#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/t/Makefile b/t/Makefile
index 47cbeb6e68..9046ec9816 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -71,7 +71,7 @@ gitweb-test:
$(MAKE) $(TGITWEB)
valgrind:
- GIT_TEST_OPTS=--valgrind $(MAKE)
+ $(MAKE) GIT_TEST_OPTS="$(GIT_TEST_OPTS) --valgrind"
# Smoke testing targets
-include ../GIT-VERSION-FILE
diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh
index fa69016381..a42e03967b 100755
--- a/t/t2018-checkout-branch.sh
+++ b/t/t2018-checkout-branch.sh
@@ -169,4 +169,15 @@ test_expect_success 'checkout -f -B to an existing branch with mergeable changes
test_must_fail test_dirty_mergeable
'
+test_expect_success 'checkout -b <describe>' '
+ git tag -f -m "First commit" initial initial &&
+ git checkout -f change1 &&
+ name=$(git describe) &&
+ git checkout -b $name &&
+ git diff --exit-code change1 &&
+ echo "refs/heads/$name" >expect &&
+ git symbolic-ref HEAD >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t3703-add-magic-pathspec.sh b/t/t3703-add-magic-pathspec.sh
index e508246c0c..5115de7036 100755
--- a/t/t3703-add-magic-pathspec.sh
+++ b/t/t3703-add-magic-pathspec.sh
@@ -38,17 +38,17 @@ cat >expected <<EOF
add 'sub/foo'
EOF
-test_expect_success 'a file with the same (long) magic name exists' '
- : >":(icase)ha" &&
- test_must_fail git add -n ":(icase)ha" &&
- git add -n "./:(icase)ha"
-'
-
if mkdir ":" 2>/dev/null
then
test_set_prereq COLON_DIR
fi
+test_expect_success COLON_DIR 'a file with the same (long) magic name exists' '
+ : >":(icase)ha" &&
+ test_must_fail git add -n ":(icase)ha" &&
+ git add -n "./:(icase)ha"
+'
+
test_expect_success COLON_DIR 'a file with the same (short) magic name exists' '
: >":/bar" &&
test_must_fail git add -n :/bar &&
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index 5c72540642..7197aae1ed 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -536,7 +536,7 @@ test_expect_success 'stash pop - fail early if specified stash is not a stash re
git reset --hard HEAD
'
-test_expect_success 'ref with non-existant reflog' '
+test_expect_success 'ref with non-existent reflog' '
git stash clear &&
echo bar5 > file &&
echo bar6 > file2 &&
diff --git a/t/t4040-whitespace-status.sh b/t/t4040-whitespace-status.sh
index abc49348b1..3c728a3ebf 100755
--- a/t/t4040-whitespace-status.sh
+++ b/t/t4040-whitespace-status.sh
@@ -67,4 +67,9 @@ test_expect_success 'diff-files --diff-filter --quiet' '
test_must_fail git diff-files --diff-filter=M --quiet
'
+test_expect_success 'diff-tree --diff-filter --quiet' '
+ git commit -a -m "worktree state" &&
+ test_must_fail git diff-tree --diff-filter=M --quiet HEAD^ HEAD
+'
+
test_done
diff --git a/t/t4048-diff-combined-binary.sh b/t/t4048-diff-combined-binary.sh
new file mode 100755
index 0000000000..87a8949500
--- /dev/null
+++ b/t/t4048-diff-combined-binary.sh
@@ -0,0 +1,212 @@
+#!/bin/sh
+
+test_description='combined and merge diff handle binary files and textconv'
+. ./test-lib.sh
+
+test_expect_success 'setup binary merge conflict' '
+ echo oneQ1 | q_to_nul >binary &&
+ git add binary &&
+ git commit -m one &&
+ echo twoQ2 | q_to_nul >binary &&
+ git commit -a -m two &&
+ git checkout -b branch-binary HEAD^ &&
+ echo threeQ3 | q_to_nul >binary &&
+ git commit -a -m three &&
+ test_must_fail git merge master &&
+ echo resolvedQhooray | q_to_nul >binary &&
+ git commit -a -m resolved
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --git a/binary b/binary
+index 7ea6ded..9563691 100644
+Binary files a/binary and b/binary differ
+resolved
+
+diff --git a/binary b/binary
+index 6197570..9563691 100644
+Binary files a/binary and b/binary differ
+EOF
+test_expect_success 'diff -m indicates binary-ness' '
+ git show --format=%s -m >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --combined binary
+index 7ea6ded,6197570..9563691
+Binary files differ
+EOF
+test_expect_success 'diff -c indicates binary-ness' '
+ git show --format=%s -c >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --cc binary
+index 7ea6ded,6197570..9563691
+Binary files differ
+EOF
+test_expect_success 'diff --cc indicates binary-ness' '
+ git show --format=%s --cc >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'setup non-binary with binary attribute' '
+ git checkout master &&
+ test_commit one text &&
+ test_commit two text &&
+ git checkout -b branch-text HEAD^ &&
+ test_commit three text &&
+ test_must_fail git merge master &&
+ test_commit resolved text &&
+ echo text -diff >.gitattributes
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --git a/text b/text
+index 2bdf67a..2ab19ae 100644
+Binary files a/text and b/text differ
+resolved
+
+diff --git a/text b/text
+index f719efd..2ab19ae 100644
+Binary files a/text and b/text differ
+EOF
+test_expect_success 'diff -m respects binary attribute' '
+ git show --format=%s -m >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --combined text
+index 2bdf67a,f719efd..2ab19ae
+Binary files differ
+EOF
+test_expect_success 'diff -c respects binary attribute' '
+ git show --format=%s -c >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --cc text
+index 2bdf67a,f719efd..2ab19ae
+Binary files differ
+EOF
+test_expect_success 'diff --cc respects binary attribute' '
+ git show --format=%s --cc >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'setup textconv attribute' '
+ echo "text diff=upcase" >.gitattributes &&
+ git config diff.upcase.textconv "tr a-z A-Z <"
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --git a/text b/text
+index 2bdf67a..2ab19ae 100644
+--- a/text
++++ b/text
+@@ -1 +1 @@
+-THREE
++RESOLVED
+resolved
+
+diff --git a/text b/text
+index f719efd..2ab19ae 100644
+--- a/text
++++ b/text
+@@ -1 +1 @@
+-TWO
++RESOLVED
+EOF
+test_expect_success 'diff -m respects textconv attribute' '
+ git show --format=%s -m >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --combined text
+index 2bdf67a,f719efd..2ab19ae
+--- a/text
++++ b/text
+@@@ -1,1 -1,1 +1,1 @@@
+- THREE
+ -TWO
+++RESOLVED
+EOF
+test_expect_success 'diff -c respects textconv attribute' '
+ git show --format=%s -c >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+resolved
+
+diff --cc text
+index 2bdf67a,f719efd..2ab19ae
+--- a/text
++++ b/text
+@@@ -1,1 -1,1 +1,1 @@@
+- THREE
+ -TWO
+++RESOLVED
+EOF
+test_expect_success 'diff --cc respects textconv attribute' '
+ git show --format=%s --cc >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+diff --combined text
+index 2bdf67a,f719efd..2ab19ae
+--- a/text
++++ b/text
+@@@ -1,1 -1,1 +1,1 @@@
+- three
+ -two
+++resolved
+EOF
+test_expect_success 'diff-tree plumbing does not respect textconv' '
+ git diff-tree HEAD -c -p >full &&
+ tail -n +2 full >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+diff --cc text
+index 2bdf67a,f719efd..0000000
+--- a/text
++++ b/text
+@@@ -1,1 -1,1 +1,5 @@@
+++<<<<<<< HEAD
+ +THREE
+++=======
++ TWO
+++>>>>>>> MASTER
+EOF
+test_expect_success 'diff --cc respects textconv on worktree file' '
+ git reset --hard HEAD^ &&
+ test_must_fail git merge master &&
+ git diff >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t4049-diff-stat-count.sh b/t/t4049-diff-stat-count.sh
new file mode 100755
index 0000000000..641e70d14d
--- /dev/null
+++ b/t/t4049-diff-stat-count.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+# Copyright (c) 2011, Google Inc.
+
+test_description='diff --stat-count'
+. ./test-lib.sh
+
+test_expect_success setup '
+ >a &&
+ >b &&
+ >c &&
+ >d &&
+ git add a b c d &&
+ chmod +x c d &&
+ echo a >a &&
+ echo b >b &&
+ cat >expect <<-\EOF
+ a | 1 +
+ b | 1 +
+ 2 files changed, 2 insertions(+), 0 deletions(-)
+ EOF
+ git diff --stat --stat-count=2 >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh
index e818de6ddd..1f182f612c 100755
--- a/t/t4203-mailmap.sh
+++ b/t/t4203-mailmap.sh
@@ -94,7 +94,7 @@ nick1 (1):
EOF
-test_expect_success 'mailmap.file non-existant' '
+test_expect_success 'mailmap.file non-existent' '
rm internal_mailmap/.mailmap &&
rmdir internal_mailmap &&
git shortlog HEAD >actual &&
diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index cb9f2bdd29..2ae9faa8b3 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -45,7 +45,7 @@ test_expect_success 'alias user-defined tformat' '
test_cmp expected actual
'
-test_expect_success 'alias non-existant format' '
+test_expect_success 'alias non-existent format' '
git config pretty.test-alias format-that-will-never-exist &&
test_must_fail git log --pretty=test-alias
'
diff --git a/t/t5506-remote-groups.sh b/t/t5506-remote-groups.sh
index b7b7ddaa40..530b01678e 100755
--- a/t/t5506-remote-groups.sh
+++ b/t/t5506-remote-groups.sh
@@ -43,10 +43,10 @@ test_expect_success 'no group updates all' '
repo_fetched two
'
-test_expect_success 'nonexistant group produces error' '
- mark nonexistant &&
+test_expect_success 'nonexistent group produces error' '
+ mark nonexistent &&
update_repos &&
- test_must_fail git remote update nonexistant &&
+ test_must_fail git remote update nonexistent &&
! repo_fetched one &&
! repo_fetched two
'
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index d73731e644..3abb2907ea 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -367,7 +367,7 @@ test_expect_success 'push with colon-less refspec (4)' '
'
-test_expect_success 'push head with non-existant, incomplete dest' '
+test_expect_success 'push head with non-existent, incomplete dest' '
mk_test &&
git push testrepo master:branch &&
@@ -375,7 +375,7 @@ test_expect_success 'push head with non-existant, incomplete dest' '
'
-test_expect_success 'push tag with non-existant, incomplete dest' '
+test_expect_success 'push tag with non-existent, incomplete dest' '
mk_test &&
git tag -f v1.0 &&
@@ -384,14 +384,14 @@ test_expect_success 'push tag with non-existant, incomplete dest' '
'
-test_expect_success 'push sha1 with non-existant, incomplete dest' '
+test_expect_success 'push sha1 with non-existent, incomplete dest' '
mk_test &&
test_must_fail git push testrepo `git rev-parse master`:foo
'
-test_expect_success 'push ref expression with non-existant, incomplete dest' '
+test_expect_success 'push ref expression with non-existent, incomplete dest' '
mk_test &&
test_must_fail git push testrepo master^:branch
@@ -436,7 +436,7 @@ test_expect_success 'push with +HEAD' '
'
-test_expect_success 'push HEAD with non-existant, incomplete dest' '
+test_expect_success 'push HEAD with non-existent, incomplete dest' '
mk_test &&
git checkout master &&
diff --git a/t/t7508-status.sh b/t/t7508-status.sh
index cd6e2c5e87..905255adf0 100755
--- a/t/t7508-status.sh
+++ b/t/t7508-status.sh
@@ -131,6 +131,127 @@ test_expect_success 'status -s' '
'
+test_expect_success 'status with gitignore' '
+ {
+ echo ".gitignore" &&
+ echo "expect" &&
+ echo "output" &&
+ echo "untracked"
+ } >.gitignore &&
+
+ cat >expect <<-\EOF &&
+ M dir1/modified
+ A dir2/added
+ ?? dir2/modified
+ EOF
+ git status -s >output &&
+ test_cmp expect output &&
+
+ cat >expect <<-\EOF &&
+ M dir1/modified
+ A dir2/added
+ ?? dir2/modified
+ !! .gitignore
+ !! dir1/untracked
+ !! dir2/untracked
+ !! expect
+ !! output
+ !! untracked
+ EOF
+ git status -s --ignored >output &&
+ test_cmp expect output &&
+
+ cat >expect <<-\EOF &&
+ # On branch master
+ # Changes to be committed:
+ # (use "git reset HEAD <file>..." to unstage)
+ #
+ # new file: dir2/added
+ #
+ # Changes not staged for commit:
+ # (use "git add <file>..." to update what will be committed)
+ # (use "git checkout -- <file>..." to discard changes in working directory)
+ #
+ # modified: dir1/modified
+ #
+ # Untracked files:
+ # (use "git add <file>..." to include in what will be committed)
+ #
+ # dir2/modified
+ # Ignored files:
+ # (use "git add -f <file>..." to include in what will be committed)
+ #
+ # .gitignore
+ # dir1/untracked
+ # dir2/untracked
+ # expect
+ # output
+ # untracked
+ EOF
+ git status --ignored >output &&
+ test_cmp expect output
+'
+
+test_expect_success 'status with gitignore (nothing untracked)' '
+ {
+ echo ".gitignore" &&
+ echo "expect" &&
+ echo "dir2/modified" &&
+ echo "output" &&
+ echo "untracked"
+ } >.gitignore &&
+
+ cat >expect <<-\EOF &&
+ M dir1/modified
+ A dir2/added
+ EOF
+ git status -s >output &&
+ test_cmp expect output &&
+
+ cat >expect <<-\EOF &&
+ M dir1/modified
+ A dir2/added
+ !! .gitignore
+ !! dir1/untracked
+ !! dir2/modified
+ !! dir2/untracked
+ !! expect
+ !! output
+ !! untracked
+ EOF
+ git status -s --ignored >output &&
+ test_cmp expect output &&
+
+ cat >expect <<-\EOF &&
+ # On branch master
+ # Changes to be committed:
+ # (use "git reset HEAD <file>..." to unstage)
+ #
+ # new file: dir2/added
+ #
+ # Changes not staged for commit:
+ # (use "git add <file>..." to update what will be committed)
+ # (use "git checkout -- <file>..." to discard changes in working directory)
+ #
+ # modified: dir1/modified
+ #
+ # Ignored files:
+ # (use "git add -f <file>..." to include in what will be committed)
+ #
+ # .gitignore
+ # dir1/untracked
+ # dir2/modified
+ # dir2/untracked
+ # expect
+ # output
+ # untracked
+ EOF
+ git status --ignored >output &&
+ test_cmp expect output
+'
+
+rm -f .gitignore
+
cat >expect <<\EOF
## master
M dir1/modified
@@ -780,6 +901,13 @@ test_expect_success 'status -s submodule summary (clean submodule)' '
test_cmp expect output
'
+test_expect_success 'status -z implies porcelain' '
+ git status --porcelain |
+ perl -pe "s/\012/\000/g" >expect &&
+ git status -z >output &&
+ test_cmp expect output
+'
+
cat >expect <<EOF
# On branch master
# Changes to be committed:
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 1227fa69b4..a29ae45b39 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -658,9 +658,9 @@ test_expect_success LIBPCRE 'grep -P -v pattern' '
'
test_expect_success LIBPCRE 'grep -P -i pattern' '
- {
- echo "hello.c: printf(\"Hello world.\n\");"
- } >expected &&
+ cat >expected <<-EOF &&
+ hello.c: printf("Hello world.\n");
+ EOF
git grep -P -i "PRINTF\([^\d]+\)" hello.c >actual &&
test_cmp expected actual
'
diff --git a/t/t9159-git-svn-no-parent-mergeinfo.sh b/t/t9159-git-svn-no-parent-mergeinfo.sh
new file mode 100755
index 0000000000..85120b70db
--- /dev/null
+++ b/t/t9159-git-svn-no-parent-mergeinfo.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+test_description='git svn handling of root commits in merge ranges'
+. ./lib-git-svn.sh
+
+test_expect_success 'test handling of root commits in merge ranges' '
+ mkdir -p init/trunk init/branches init/tags &&
+ echo "r1" > init/trunk/file.txt &&
+ svn_cmd import -m "initial import" init "$svnrepo" &&
+ svn_cmd co "$svnrepo" tmp &&
+ (
+ cd tmp &&
+ echo "r2" > trunk/file.txt &&
+ svn_cmd commit -m "Modify file.txt on trunk" &&
+ svn_cmd cp trunk@1 branches/a &&
+ svn_cmd commit -m "Create branch a from trunk r1" &&
+ svn_cmd propset svn:mergeinfo /trunk:1-2 branches/a &&
+ svn_cmd commit -m "Fake merge of trunk r2 into branch a" &&
+ mkdir branches/b &&
+ echo "r5" > branches/b/file2.txt &&
+ svn_cmd add branches/b &&
+ svn_cmd commit -m "Create branch b from thin air" &&
+ echo "r6" > branches/b/file2.txt &&
+ svn_cmd commit -m "Modify file2.txt on branch b" &&
+ svn_cmd cp branches/b@5 branches/c &&
+ svn_cmd commit -m "Create branch c from branch b r5" &&
+ svn_cmd propset svn:mergeinfo /branches/b:5-6 branches/c &&
+ svn_cmd commit -m "Fake merge of branch b r6 into branch c"
+ ) &&
+ git svn init -s "$svnrepo" &&
+ git svn fetch
+ '
+
+test_done
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 6b1ba6c858..2a53640c5b 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -1893,7 +1893,7 @@ test_expect_success \
test_cmp marks.out marks.new'
cat >input <<EOF
-feature import-marks=nonexistant.marks
+feature import-marks=nonexistent.marks
feature export-marks=marks.new
EOF
@@ -1904,7 +1904,7 @@ test_expect_success \
cat >input <<EOF
-feature import-marks=nonexistant.marks
+feature import-marks=nonexistent.marks
feature export-marks=combined.marks
EOF
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index f5648a6694..53297156a3 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -644,6 +644,14 @@ test_expect_success \
'ctags: search projects by non existent tag' \
'gitweb_run "by_tag=non-existent"'
+test_expect_success \
+ 'ctags: malformed tag weights' \
+ 'mkdir -p .git/ctags &&
+ echo "not-a-number" > .git/ctags/nan &&
+ echo "not-a-number-2" > .git/ctags/nan2 &&
+ echo "0.1" >.git/ctags/floating-point &&
+ gitweb_run'
+
# ----------------------------------------------------------------------
# categories
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 64390d716d..df25f17929 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -446,9 +446,14 @@ test_debug () {
test_run_ () {
test_cleanup=:
+ expecting_failure=$2
eval >&3 2>&4 "$1"
eval_ret=$?
- eval >&3 2>&4 "$test_cleanup"
+
+ if test -z "$immediate" || test $eval_ret = 0 || test -n "$expecting_failure"
+ then
+ eval >&3 2>&4 "$test_cleanup"
+ fi
if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then
echo ""
fi
@@ -497,7 +502,7 @@ test_expect_failure () {
if ! test_skip "$@"
then
say >&3 "checking known breakage: $2"
- test_run_ "$2"
+ test_run_ "$2" expecting_failure
if [ "$?" = 0 -a "$eval_ret" = 0 ]
then
test_known_broken_ok_ "$1"
@@ -774,6 +779,9 @@ test_cmp() {
#
# except that the greeting and config --unset must both succeed for
# the test to pass.
+#
+# Note that under --immediate mode, no clean-up is done to help diagnose
+# what went wrong.
test_when_finished () {
test_cleanup="{ $*
@@ -884,8 +892,13 @@ then
}
make_valgrind_symlink () {
- # handle only executables
- test -x "$1" || return
+ # handle only executables, unless they are shell libraries that
+ # need to be in the exec-path. We will just use "#!" as a
+ # guess for a shell-script, since we have no idea what the user
+ # may have configured as the shell path.
+ test -x "$1" ||
+ test "#!" = "$(head -c 2 <"$1")" ||
+ return;
base=$(basename "$1")
symlink_target=$GIT_BUILD_DIR/$base
diff --git a/tree-diff.c b/tree-diff.c
index 3f4072525b..b3cc2e4753 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -142,8 +142,7 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
strbuf_add(&base, base_str, baselen);
for (;;) {
- if (DIFF_OPT_TST(opt, QUICK) &&
- DIFF_OPT_TST(opt, HAS_CHANGES))
+ if (diff_can_quit_early(opt))
break;
if (opt->pathspec.nr) {
skip_uninteresting(t1, &base, opt, &t1_match);
diff --git a/unpack-trees.c b/unpack-trees.c
index 07f8364244..3a61d821ee 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -593,7 +593,7 @@ static int unpack_nondirectories(int n, unsigned long mask,
static int unpack_failed(struct unpack_trees_options *o, const char *message)
{
discard_index(&o->result);
- if (!o->gently) {
+ if (!o->gently && !o->exiting_early) {
if (message)
return error("%s", message);
return -1;
@@ -1133,6 +1133,8 @@ return_failed:
display_error_msgs(o);
mark_all_ce_unused(o->src_index);
ret = unpack_failed(o, NULL);
+ if (o->exiting_early)
+ ret = 0;
goto done;
}
diff --git a/unpack-trees.h b/unpack-trees.h
index 64f02cb03a..7998948307 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -46,6 +46,7 @@ struct unpack_trees_options {
debug_unpack,
skip_sparse_checkout,
gently,
+ exiting_early,
show_all_errors,
dry_run;
const char *prefix;
diff --git a/userdiff.c b/userdiff.c
index e55310cd02..01d3a8b81e 100644
--- a/userdiff.c
+++ b/userdiff.c
@@ -281,3 +281,20 @@ struct userdiff_driver *userdiff_find_by_path(const char *path)
return NULL;
return userdiff_find_by_name(check.value);
}
+
+struct userdiff_driver *userdiff_get_textconv(struct userdiff_driver *driver)
+{
+ if (!driver->textconv)
+ return NULL;
+
+ if (driver->textconv_want_cache && !driver->textconv_cache) {
+ struct notes_cache *c = xmalloc(sizeof(*c));
+ struct strbuf name = STRBUF_INIT;
+
+ strbuf_addf(&name, "textconv/%s", driver->name);
+ notes_cache_init(c, name.buf, driver->textconv);
+ driver->textconv_cache = c;
+ }
+
+ return driver;
+}
diff --git a/userdiff.h b/userdiff.h
index 942d594950..4a7e78ffbc 100644
--- a/userdiff.h
+++ b/userdiff.h
@@ -23,4 +23,6 @@ int userdiff_config(const char *k, const char *v);
struct userdiff_driver *userdiff_find_by_name(const char *name);
struct userdiff_driver *userdiff_find_by_path(const char *path);
+struct userdiff_driver *userdiff_get_textconv(struct userdiff_driver *driver);
+
#endif /* USERDIFF */
diff --git a/wt-status.c b/wt-status.c
index 9f4e0ba9c1..02377729c4 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -642,7 +642,7 @@ static void wt_status_print_other(struct wt_status *s,
int i;
struct strbuf buf = STRBUF_INIT;
- if (!s->untracked.nr)
+ if (!l->nr)
return;
wt_status_print_other_header(s, what, how);