diff options
-rw-r--r-- | Makefile | 10 | ||||
-rw-r--r-- | cgit.c | 7 | ||||
-rw-r--r-- | cgit.css | 347 | ||||
-rw-r--r-- | cgit.h | 1 | ||||
-rw-r--r-- | cgitrc.5.txt | 2 | ||||
-rwxr-xr-x | filters/commit-links.sh | 7 | ||||
-rwxr-xr-x | filters/syntax-highlighting.sh | 28 | ||||
-rw-r--r-- | html.c | 4 | ||||
-rw-r--r-- | parsing.c | 2 | ||||
-rw-r--r-- | shared.c | 3 | ||||
-rwxr-xr-x | tests/setup.sh | 5 | ||||
-rwxr-xr-x | tests/t0108-patch.sh | 2 | ||||
-rw-r--r-- | ui-diff.c | 17 | ||||
-rw-r--r-- | ui-log.c | 3 | ||||
-rw-r--r-- | ui-repolist.c | 6 | ||||
-rw-r--r-- | ui-shared.c | 30 | ||||
-rw-r--r-- | ui-shared.h | 2 | ||||
-rw-r--r-- | ui-ssdiff.c | 29 | ||||
-rw-r--r-- | ui-ssdiff.h | 12 |
19 files changed, 303 insertions, 214 deletions
diff --git a/Makefile b/Makefile index f6d6968..eac24ad 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CGIT_VERSION = v0.9.0.1 +CGIT_VERSION = v0.9.0.3 CGIT_SCRIPT_NAME = cgit.cgi CGIT_SCRIPT_PATH = /var/www/htdocs/cgit CGIT_DATA_PATH = $(CGIT_SCRIPT_PATH) @@ -13,7 +13,7 @@ pdfdir = $(docdir) mandir = $(prefix)/share/man SHA1_HEADER = <openssl/sha.h> GIT_VER = 1.7.4 -GIT_URL = http://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.bz2 +GIT_URL = http://hjemli.net/git/git/snapshot/git-$(GIT_VER).tar.bz2 INSTALL = install MAN5_TXT = $(wildcard *.5.txt) MAN_TXT = $(MAN5_TXT) @@ -198,9 +198,9 @@ install-pdf: doc-pdf $(INSTALL) -m 0644 $(DOC_PDF) $(DESTDIR)$(pdfdir) uninstall: - rm -f $(CGIT_SCRIPT_PATH)/$(CGIT_SCRIPT_NAME) - rm -f $(CGIT_DATA_PATH)/cgit.css - rm -f $(CGIT_DATA_PATH)/cgit.png + rm -f $(DESTDIR)$(CGIT_SCRIPT_PATH)/$(CGIT_SCRIPT_NAME) + rm -f $(DESTDIR)$(CGIT_DATA_PATH)/cgit.css + rm -f $(DESTDIR)$(CGIT_DATA_PATH)/cgit.png uninstall-doc: uninstall-man uninstall-html uninstall-pdf diff --git a/cgit.c b/cgit.c index 9eb2535..7e3d349 100644 --- a/cgit.c +++ b/cgit.c @@ -303,6 +303,7 @@ static void querystring_cb(const char *name, const char *value) ctx.qry.period = xstrdup(value); } else if (!strcmp(name, "ss")) { ctx.qry.ssdiff = atoi(value); + ctx.qry.has_ssdiff = 1; } else if (!strcmp(name, "all")) { ctx.qry.show_all = atoi(value); } else if (!strcmp(name, "context")) { @@ -425,13 +426,17 @@ static int prepare_repo_cmd(struct cgit_context *ctx) char *tmp; unsigned char sha1[20]; int nongit = 0; + int rc; setenv("GIT_DIR", ctx->repo->path, 1); setup_git_directory_gently(&nongit); if (nongit) { + rc = errno; ctx->page.title = fmt("%s - %s", ctx->cfg.root_title, "config error"); - tmp = fmt("Not a git repository: '%s'", ctx->repo->path); + tmp = fmt("Failed to open %s: %s", + ctx->repo->name, + rc ? strerror(rc) : "Not a valid git repository"); ctx->repo = NULL; cgit_print_http_headers(ctx); cgit_print_docstart(ctx); diff --git a/cgit.css b/cgit.css index 55afa94..e06c261 100644 --- a/cgit.css +++ b/cgit.css @@ -1,4 +1,4 @@ -body, table, form { +body, div#cgit table, div#cgit form { padding: 0em; margin: 0em; } @@ -11,39 +11,40 @@ body { padding: 4px; } -a { +div#cgit a { color: blue; text-decoration: none; } -a:hover { +div#cgit a:hover { text-decoration: underline; } -table { +div#cgit table { border-collapse: collapse; } -table#header { +div#cgit table#header { width: 100%; margin-bottom: 1em; } -table#header td.logo { +div#cgit table#header td.logo { width: 96px; + vertical-align: top; } -table#header td.main { +div#cgit table#header td.main { font-size: 250%; padding-left: 10px; white-space: nowrap; } -table#header td.main a { +div#cgit table#header td.main a { color: #000; } -table#header td.form { +div#cgit table#header td.form { text-align: right; vertical-align: bottom; padding-right: 1em; @@ -51,19 +52,19 @@ table#header td.form { white-space: nowrap; } -table#header td.form form, -table#header td.form input, -table#header td.form select { +div#cgit table#header td.form form, +div#cgit table#header td.form input, +div#cgit table#header td.form select { font-size: 90%; } -table#header td.sub { +div#cgit table#header td.sub { color: #777; border-top: solid 1px #ccc; padding-left: 10px; } -table.tabs { +div#cgit table.tabs { border-bottom: solid 3px #ccc; border-collapse: collapse; margin-top: 2em; @@ -71,74 +72,74 @@ table.tabs { width: 100%; } -table.tabs td { +div#cgit table.tabs td { padding: 0px 1em; vertical-align: bottom; } -table.tabs td a { +div#cgit table.tabs td a { padding: 2px 0.75em; color: #777; font-size: 110%; } -table.tabs td a.active { +div#cgit table.tabs td a.active { color: #000; background-color: #ccc; } -table.tabs td.form { +div#cgit table.tabs td.form { text-align: right; } -table.tabs td.form form { +div#cgit table.tabs td.form form { padding-bottom: 2px; font-size: 90%; white-space: nowrap; } -table.tabs td.form input, -table.tabs td.form select { +div#cgit table.tabs td.form input, +div#cgit table.tabs td.form select { font-size: 90%; } -div.path { +div#cgit div.path { margin: 0px; padding: 5px 2em 2px 2em; color: #000; background-color: #eee; } -div.content { +div#cgit div.content { margin: 0px; padding: 2em; border-bottom: solid 3px #ccc; } -table.list { +div#cgit table.list { width: 100%; border: none; border-collapse: collapse; } -table.list tr { +div#cgit table.list tr { background: white; } -table.list tr.logheader { +div#cgit table.list tr.logheader { background: #eee; } -table.list tr:hover { +div#cgit table.list tr:hover { background: #eee; } -table.list tr.nohover:hover { +div#cgit table.list tr.nohover:hover { background: white; } -table.list th { +div#cgit table.list th { font-weight: bold; /* color: #888; border-top: dashed 1px #888; @@ -148,93 +149,93 @@ table.list th { vertical-align: baseline; } -table.list td { +div#cgit table.list td { border: none; padding: 0.1em 0.5em 0.1em 0.5em; } -table.list td.commitgraph { +div#cgit table.list td.commitgraph { font-family: monospace; white-space: pre; } -table.list td.commitgraph .column1 { +div#cgit table.list td.commitgraph .column1 { color: #a00; } -table.list td.commitgraph .column2 { +div#cgit table.list td.commitgraph .column2 { color: #0a0; } -table.list td.commitgraph .column3 { +div#cgit table.list td.commitgraph .column3 { color: #aa0; } -table.list td.commitgraph .column4 { +div#cgit table.list td.commitgraph .column4 { color: #00a; } -table.list td.commitgraph .column5 { +div#cgit table.list td.commitgraph .column5 { color: #a0a; } -table.list td.commitgraph .column6 { +div#cgit table.list td.commitgraph .column6 { color: #0aa; } -table.list td.logsubject { +div#cgit table.list td.logsubject { font-family: monospace; font-weight: bold; } -table.list td.logmsg { +div#cgit table.list td.logmsg { font-family: monospace; white-space: pre; padding: 0 0.5em; } -table.list td a { +div#cgit table.list td a { color: black; } -table.list td a.ls-dir { +div#cgit table.list td a.ls-dir { font-weight: bold; color: #00f; } -table.list td a:hover { +div#cgit table.list td a:hover { color: #00f; } -img { +div#cgit img { border: none; } -input#switch-btn { +div#cgit input#switch-btn { margin: 2px 0px 0px 0px; } -td#sidebar input.txt { +div#cgit td#sidebar input.txt { width: 100%; margin: 2px 0px 0px 0px; } -table#grid { +div#cgit table#grid { margin: 0px; } -td#content { +div#cgit td#content { vertical-align: top; padding: 1em 2em 1em 1em; border: none; } -div#summary { +div#cgit div#summary { vertical-align: top; margin-bottom: 1em; } -table#downloads { +div#cgit table#downloads { float: right; border-collapse: collapse; border: solid 1px #777; @@ -242,152 +243,152 @@ table#downloads { margin-bottom: 0.5em; } -table#downloads th { +div#cgit table#downloads th { background-color: #ccc; } -div#blob { +div#cgit div#blob { border: solid 1px black; } -div.error { +div#cgit div.error { color: red; font-weight: bold; margin: 1em 2em; } -a.ls-blob, a.ls-dir, a.ls-mod { +div#cgit a.ls-blob, div#cgit a.ls-dir, div#cgit a.ls-mod { font-family: monospace; } -td.ls-size { +div#cgit td.ls-size { text-align: right; font-family: monospace; width: 10em; } -td.ls-mode { +div#cgit td.ls-mode { font-family: monospace; width: 10em; } -table.blob { +div#cgit table.blob { margin-top: 0.5em; border-top: solid 1px black; } -table.blob td.lines { +div#cgit table.blob td.lines { margin: 0; padding: 0 0 0 0.5em; vertical-align: top; color: black; } -table.blob td.linenumbers { +div#cgit table.blob td.linenumbers { margin: 0; padding: 0 0.5em 0 0.5em; vertical-align: top; text-align: right; border-right: 1px solid gray; } -table.blob pre { +div#cgit table.blob pre { padding: 0; margin: 0; } -table.blob a.no, table.ssdiff a.no { +div#cgit table.blob a.no, div#cgit table.ssdiff a.no { color: gray; text-align: right; text-decoration: none; } -table.blob a.no a:hover { +div#cgit table.blob a.no a:hover { color: black; } -table.bin-blob { +div#cgit table.bin-blob { margin-top: 0.5em; border: solid 1px black; } -table.bin-blob th { +div#cgit table.bin-blob th { font-family: monospace; white-space: pre; border: solid 1px #777; padding: 0.5em 1em; } -table.bin-blob td { +div#cgit table.bin-blob td { font-family: monospace; white-space: pre; border-left: solid 1px #777; padding: 0em 1em; } -table.nowrap td { +div#cgit table.nowrap td { white-space: nowrap; } -table.commit-info { +div#cgit table.commit-info { border-collapse: collapse; margin-top: 1.5em; } -div.cgit-panel { +div#cgit div.cgit-panel { float: right; margin-top: 1.5em; } -div.cgit-panel table { +div#cgit div.cgit-panel table { border-collapse: collapse; border: solid 1px #aaa; background-color: #eee; } -div.cgit-panel th { +div#cgit div.cgit-panel th { text-align: center; } -div.cgit-panel td { +div#cgit div.cgit-panel td { padding: 0.25em 0.5em; } -div.cgit-panel td.label { +div#cgit div.cgit-panel td.label { padding-right: 0.5em; } -div.cgit-panel td.ctrl { +div#cgit div.cgit-panel td.ctrl { padding-left: 0.5em; } -table.commit-info th { +div#cgit table.commit-info th { text-align: left; font-weight: normal; padding: 0.1em 1em 0.1em 0.1em; vertical-align: top; } -table.commit-info td { +div#cgit table.commit-info td { font-weight: normal; padding: 0.1em 1em 0.1em 0.1em; } -div.commit-subject { +div#cgit div.commit-subject { font-weight: bold; font-size: 125%; margin: 1.5em 0em 0.5em 0em; padding: 0em; } -div.commit-msg { +div#cgit div.commit-msg { white-space: pre; font-family: monospace; } -div.notes-header { +div#cgit div.notes-header { font-weight: bold; padding-top: 1.5em; } -div.notes { +div#cgit div.notes { white-space: pre; font-family: monospace; border: solid 1px #ee9; @@ -396,22 +397,22 @@ div.notes { float: left; } -div.notes-footer { +div#cgit div.notes-footer { clear: left; } -div.diffstat-header { +div#cgit div.diffstat-header { font-weight: bold; padding-top: 1.5em; } -table.diffstat { +div#cgit table.diffstat { border-collapse: collapse; border: solid 1px #aaa; background-color: #eee; } -table.diffstat th { +div#cgit table.diffstat th { font-weight: normal; text-align: left; text-decoration: underline; @@ -419,282 +420,286 @@ table.diffstat th { font-size: 100%; } -table.diffstat td { +div#cgit table.diffstat td { padding: 0.2em 0.2em 0.1em 0.1em; font-size: 100%; border: none; } -table.diffstat td.mode { +div#cgit table.diffstat td.mode { white-space: nowrap; } -table.diffstat td span.modechange { +div#cgit table.diffstat td span.modechange { padding-left: 1em; color: red; } -table.diffstat td.add a { +div#cgit table.diffstat td.add a { color: green; } -table.diffstat td.del a { +div#cgit table.diffstat td.del a { color: red; } -table.diffstat td.upd a { +div#cgit table.diffstat td.upd a { color: blue; } -table.diffstat td.graph { +div#cgit table.diffstat td.graph { width: 500px; vertical-align: middle; } -table.diffstat td.graph table { +div#cgit table.diffstat td.graph table { border: none; } -table.diffstat td.graph td { +div#cgit table.diffstat td.graph td { padding: 0px; border: 0px; height: 7pt; } -table.diffstat td.graph td.add { +div#cgit table.diffstat td.graph td.add { background-color: #5c5; } -table.diffstat td.graph td.rem { +div#cgit table.diffstat td.graph td.rem { background-color: #c55; } -div.diffstat-summary { +div#cgit div.diffstat-summary { color: #888; padding-top: 0.5em; } -table.diff { +div#cgit table.diff { width: 100%; } -table.diff td { +div#cgit table.diff td { font-family: monospace; white-space: pre; } -table.diff td div.head { +div#cgit table.diff td div.head { font-weight: bold; margin-top: 1em; color: black; } -table.diff td div.hunk { +div#cgit table.diff td div.hunk { color: #009; } -table.diff td div.add { +div#cgit table.diff td div.add { color: green; } -table.diff td div.del { +div#cgit table.diff td div.del { color: red; } -.sha1 { +div#cgit .sha1 { font-family: monospace; font-size: 90%; } -.left { +div#cgit .left { text-align: left; } -.right { +div#cgit .right { text-align: right; } -table.list td.reposection { +div#cgit table.list td.reposection { font-style: italic; color: #888; } -a.button { +div#cgit a.button { font-size: 80%; padding: 0em 0.5em; } -a.primary { +div#cgit a.primary { font-size: 100%; } -a.secondary { +div#cgit a.secondary { font-size: 90%; } -td.toplevel-repo { +div#cgit td.toplevel-repo { } -table.list td.sublevel-repo { +div#cgit table.list td.sublevel-repo { padding-left: 1.5em; } -div.pager { +div#cgit div.pager { text-align: center; margin: 1em 0em 0em 0em; } -div.pager a { +div#cgit div.pager a { color: #777; margin: 0em 0.5em; } -span.age-mins { +div#cgit span.age-mins { font-weight: bold; color: #080; } -span.age-hours { +div#cgit span.age-hours { color: #080; } -span.age-days { +div#cgit span.age-days { color: #040; } -span.age-weeks { +div#cgit span.age-weeks { color: #444; } -span.age-months { +div#cgit span.age-months { color: #888; } -span.age-years { +div#cgit span.age-years { color: #bbb; } -div.footer { +div#cgit div.footer { margin-top: 0.5em; text-align: center; font-size: 80%; color: #ccc; } -a.branch-deco { +div#cgit a.branch-deco { + color: #000; margin: 0px 0.5em; padding: 0px 0.25em; background-color: #88ff88; border: solid 1px #007700; } -a.tag-deco { +div#cgit a.tag-deco { + color: #000; margin: 0px 0.5em; padding: 0px 0.25em; background-color: #ffff88; border: solid 1px #777700; } -a.remote-deco { +div#cgit a.remote-deco { + color: #000; margin: 0px 0.5em; padding: 0px 0.25em; background-color: #ccccff; border: solid 1px #000077; } -a.deco { +div#cgit a.deco { + color: #000; margin: 0px 0.5em; padding: 0px 0.25em; background-color: #ff8888; border: solid 1px #770000; } -div.commit-subject a.branch-deco, -div.commit-subject a.tag-deco, -div.commit-subject a.remote-deco, -div.commit-subject a.deco { +div#cgit div.commit-subject a.branch-deco, +div#cgit div.commit-subject a.tag-deco, +div#cgit div.commit-subject a.remote-deco, +div#cgit div.commit-subject a.deco { margin-left: 1em; font-size: 75%; } -table.stats { +div#cgit table.stats { border: solid 1px black; border-collapse: collapse; } -table.stats th { +div#cgit table.stats th { text-align: left; padding: 1px 0.5em; background-color: #eee; border: solid 1px black; } -table.stats td { +div#cgit table.stats td { text-align: right; padding: 1px 0.5em; border: solid 1px black; } -table.stats td.total { +div#cgit table.stats td.total { font-weight: bold; text-align: left; } -table.stats td.sum { +div#cgit table.stats td.sum { color: #c00; font-weight: bold; /* background-color: #eee; */ } -table.stats td.left { +div#cgit table.stats td.left { text-align: left; } -table.vgraph { +div#cgit table.vgraph { border-collapse: separate; border: solid 1px black; height: 200px; } -table.vgraph th { +div#cgit table.vgraph th { background-color: #eee; font-weight: bold; border: solid 1px white; padding: 1px 0.5em; } -table.vgraph td { +div#cgit table.vgraph td { vertical-align: bottom; padding: 0px 10px; } -table.vgraph div.bar { +div#cgit table.vgraph div.bar { background-color: #eee; } -table.hgraph { +div#cgit table.hgraph { border: solid 1px black; width: 800px; } -table.hgraph th { +div#cgit table.hgraph th { background-color: #eee; font-weight: bold; border: solid 1px black; padding: 1px 0.5em; } -table.hgraph td { - vertical-align: center; +div#cgit table.hgraph td { + vertical-align: middle; padding: 2px 2px; } -table.hgraph div.bar { +div#cgit table.hgraph div.bar { background-color: #eee; height: 1em; } -table.ssdiff { +div#cgit table.ssdiff { width: 100%; } -table.ssdiff td { +div#cgit table.ssdiff td { font-size: 75%; font-family: monospace; white-space: pre; @@ -703,53 +708,53 @@ table.ssdiff td { border-right: solid 1px #aaa; } -table.ssdiff td.add { +div#cgit table.ssdiff td.add { color: black; background: #cfc; min-width: 50%; } -table.ssdiff td.add_dark { +div#cgit table.ssdiff td.add_dark { color: black; background: #aca; min-width: 50%; } -table.ssdiff span.add { +div#cgit table.ssdiff span.add { background: #cfc; font-weight: bold; } -table.ssdiff td.del { +div#cgit table.ssdiff td.del { color: black; background: #fcc; min-width: 50%; } -table.ssdiff td.del_dark { +div#cgit table.ssdiff td.del_dark { color: black; background: #caa; min-width: 50%; } -table.ssdiff span.del { +div#cgit table.ssdiff span.del { background: #fcc; font-weight: bold; } -table.ssdiff td.changed { +div#cgit table.ssdiff td.changed { color: black; background: #ffc; min-width: 50%; } -table.ssdiff td.changed_dark { +div#cgit table.ssdiff td.changed_dark { color: black; background: #cca; min-width: 50%; } -table.ssdiff td.lineno { +div#cgit table.ssdiff td.lineno { color: black; background: #eee; text-align: right; @@ -757,48 +762,48 @@ table.ssdiff td.lineno { min-width: 3em; } -table.ssdiff td.hunk { - color: #black; +div#cgit table.ssdiff td.hunk { + color: black; background: #ccf; border-top: solid 1px #aaa; border-bottom: solid 1px #aaa; } -table.ssdiff td.head { +div#cgit table.ssdiff td.head { border-top: solid 1px #aaa; border-bottom: solid 1px #aaa; } -table.ssdiff td.head div.head { +div#cgit table.ssdiff td.head div.head { font-weight: bold; color: black; } -table.ssdiff td.foot { +div#cgit table.ssdiff td.foot { border-top: solid 1px #aaa; border-left: none; border-right: none; border-bottom: none; } -table.ssdiff td.space { +div#cgit table.ssdiff td.space { border: none; } -table.ssdiff td.space div { +div#cgit table.ssdiff td.space div { min-height: 3em; } /* Syntax highlighting */ -table.blob .num { color:#2928ff; } -table.blob .esc { color:#ff00ff; } -table.blob .str { color:#ff0000; } -table.blob .dstr { color:#818100; } -table.blob .slc { color:#838183; font-style:italic; } -table.blob .com { color:#838183; font-style:italic; } -table.blob .dir { color:#008200; } -table.blob .sym { color:#000000; } -table.blob .kwa { color:#000000; font-weight:bold; } -table.blob .kwb { color:#830000; } -table.blob .kwc { color:#000000; font-weight:bold; } -table.blob .kwd { color:#010181; } +div#cgit table.blob .num { color:#2928ff; } +div#cgit table.blob .esc { color:#ff00ff; } +div#cgit table.blob .str { color:#ff0000; } +div#cgit table.blob .dstr { color:#818100; } +div#cgit table.blob .slc { color:#838183; font-style:italic; } +div#cgit table.blob .com { color:#838183; font-style:italic; } +div#cgit table.blob .dir { color:#008200; } +div#cgit table.blob .sym { color:#000000; } +div#cgit table.blob .kwa { color:#000000; font-weight:bold; } +div#cgit table.blob .kwb { color:#830000; } +div#cgit table.blob .kwc { color:#000000; font-weight:bold; } +div#cgit table.blob .kwd { color:#010181; } diff --git a/cgit.h b/cgit.h index 9d0b3d0..b7c7ac9 100644 --- a/cgit.h +++ b/cgit.h @@ -138,6 +138,7 @@ struct reflist { struct cgit_query { int has_symref; int has_sha1; + int has_ssdiff; char *raw; char *repo; char *page; diff --git a/cgitrc.5.txt b/cgitrc.5.txt index c8198c1..b4ad2ac 100644 --- a/cgitrc.5.txt +++ b/cgitrc.5.txt @@ -506,7 +506,7 @@ Also, all filters are handed the following environment variables: If a setting is not defined for a repository and the corresponding global setting is also not defined (if applicable), then the corresponding -environment variable will be an empty string. +environment variable will be unset. MACRO EXPANSION diff --git a/filters/commit-links.sh b/filters/commit-links.sh index d2cd2b3..5881952 100755 --- a/filters/commit-links.sh +++ b/filters/commit-links.sh @@ -15,11 +15,14 @@ # CGIT_REPO_CLONE_URL ( = repo.clone-url setting ) # +regex='' + # This expression generates links to commits referenced by their SHA1. regex=$regex' -s|\b([0-9a-fA-F]{8,40})\b|<a href="./?id=\1">\1</a>|g' +s|\b([0-9a-fA-F]{7,40})\b|<a href="./?id=\1">\1</a>|g' + # This expression generates links to a fictional bugtracker. regex=$regex' -s| #([0-9]+)\b|<a href="http://bugs.example.com/?bug=\1">#\1</a>|g' +s|#([0-9]+)\b|<a href="http://bugs.example.com/?bug=\1">#\1</a>|g' sed -re "$regex" diff --git a/filters/syntax-highlighting.sh b/filters/syntax-highlighting.sh index 6283ce9..5fcc9c9 100755 --- a/filters/syntax-highlighting.sh +++ b/filters/syntax-highlighting.sh @@ -42,4 +42,32 @@ EXTENSION="${BASENAME##*.}" # map Makefile and Makefile.* to .mk [ "${BASENAME%%.*}" == "Makefile" ] && EXTENSION=mk +# highlight versions 2 and 3 have different commandline options. Specifically, +# the -X option that is used for version 2 is replaced by the -O xhtml option +# for version 3. +# +# Version 2 can be found (for example) on EPEL 5, while version 3 can be +# found (for example) on EPEL 6. +# +# This is for version 2 exec highlight --force -f -I -X -S $EXTENSION 2>/dev/null + +# This is for version 3 +# +# On CentOS 6.2 (using highlight from EPEL), when highlight doesn't know about +# an EXTENSION, it outputs a lua error and _no_ text, even when the --force +# option is used. +# +# Also see the bug reports at: +# http://sourceforge.net/tracker/?func=detail&aid=3490017&group_id=215618&atid=1034391 +# https://bugzilla.redhat.com/show_bug.cgi?id=795567 +# +# This workaround can be removed when the bug is fixed upstream and the new +# version is packaged in most distributions. +# +# The workaround is to set the extension to 'txt' (plain text) when highlight +# exits with an error (doesn't know the format). +# +#echo "test" | highlight -f -I -O xhtml -S $EXTENSION &>/dev/null +#[ ${?} -ne 0 ] && EXTENSION="txt" +#exec highlight --force -f -I -O xhtml -S $EXTENSION 2>/dev/null diff --git a/html.c b/html.c index eb1c25d..8f6e4f6 100644 --- a/html.c +++ b/html.c @@ -162,7 +162,7 @@ void html_url_path(const char *txt) { const char *t = txt; while(t && *t){ - int c = *t; + unsigned char c = *t; const char *e = url_escape_table[c]; if (e && c!='+' && c!='&') { html_raw(txt, t - txt); @@ -179,7 +179,7 @@ void html_url_arg(const char *txt) { const char *t = txt; while(t && *t){ - int c = *t; + unsigned char c = *t; const char *e = url_escape_table[c]; if (c == ' ') e = "+"; diff --git a/parsing.c b/parsing.c index 151c0fe..602e3de 100644 --- a/parsing.c +++ b/parsing.c @@ -125,7 +125,7 @@ const char *reencode(char **txt, const char *src_enc, const char *dst_enc) struct commitinfo *cgit_parse_commit(struct commit *commit) { struct commitinfo *ret; - char *p = commit->buffer, *t = commit->buffer; + char *p = commit->buffer, *t; ret = xmalloc(sizeof(*ret)); ret->commit = commit; diff --git a/shared.c b/shared.c index 0add2e5..cb52380 100644 --- a/shared.c +++ b/shared.c @@ -8,7 +8,6 @@ #include "cgit.h" #include <stdio.h> -#include <linux/limits.h> struct cgit_repolist cgit_repolist; struct cgit_context ctx; @@ -394,7 +393,7 @@ void cgit_prepare_repo_env(struct cgit_repo * repo) p = env_vars; q = p + env_var_count; for (; p < q; p++) - if (setenv(p->name, p->value, 1)) + if (p->value && setenv(p->name, p->value, 1)) fprintf(stderr, warn, p->name, p->value); } diff --git a/tests/setup.sh b/tests/setup.sh index 1e06107..e3c6c17 100755 --- a/tests/setup.sh +++ b/tests/setup.sh @@ -15,13 +15,14 @@ # run_test 'repo index' 'cgit_url "/" | tidy -e' # run_test 'repo summary' 'cgit_url "/foo" | tidy -e' +unset CDPATH mkrepo() { name=$1 count=$2 dir=$PWD test -d "$name" && return - printf "Creating testrepo %s\n" $name + printf "Creating testrepo %s\n" "$name" mkdir -p "$name" cd "$name" git init @@ -40,7 +41,7 @@ mkrepo() { git commit -m "add a+b" git branch "1+2" fi - cd $dir + cd "$dir" } setup_repos() diff --git a/tests/t0108-patch.sh b/tests/t0108-patch.sh index e608104..6ee70b3 100755 --- a/tests/t0108-patch.sh +++ b/tests/t0108-patch.sh @@ -25,7 +25,7 @@ run_test 'find `cgit` signature' ' ' run_test 'find initial commit' ' - root=$(git --git-dir=$PWD/trash/repos/foo/.git rev-list HEAD | tail -1) + root=$(git --git-dir="$PWD/trash/repos/foo/.git" rev-list HEAD | tail -1) ' run_test 'generate patch for initial commit' ' diff --git a/ui-diff.c b/ui-diff.c index 868ceec..c6bad63 100644 --- a/ui-diff.c +++ b/ui-diff.c @@ -97,10 +97,12 @@ static void print_fileinfo(struct fileinfo *info) htmlf("</td><td class='%s'>", class); cgit_diff_link(info->new_path, NULL, NULL, ctx.qry.head, ctx.qry.sha1, ctx.qry.sha2, info->new_path, 0); - if (info->status == DIFF_STATUS_COPIED || info->status == DIFF_STATUS_RENAMED) - htmlf(" (%s from %s)", - info->status == DIFF_STATUS_COPIED ? "copied" : "renamed", - info->old_path); + if (info->status == DIFF_STATUS_COPIED || info->status == DIFF_STATUS_RENAMED) { + htmlf(" (%s from ", + info->status == DIFF_STATUS_COPIED ? "copied" : "renamed"); + html_txt(info->old_path); + html(")"); + } html("</td><td class='right'>"); if (info->binary) { htmlf("bin</td><td class='graph'>%ld -> %ld bytes", @@ -339,9 +341,7 @@ void cgit_print_diff_ctrls() html("<td class='label'>mode:</td>"); html("<td class='ctrl'>"); html("<select name='ss' onchange='this.form.submit();'>"); - curr = ctx.qry.ssdiff; - if (!curr && ctx.cfg.ssdiff) - curr = 1; + curr = ctx.qry.has_ssdiff ? ctx.qry.ssdiff : ctx.cfg.ssdiff; html_intoption(0, "unified", curr); html_intoption(1, "ssdiff", curr); html("</select></td></tr>"); @@ -393,8 +393,7 @@ void cgit_print_diff(const char *new_rev, const char *old_rev, } } - if ((ctx.qry.ssdiff && !ctx.cfg.ssdiff) || (!ctx.qry.ssdiff && ctx.cfg.ssdiff)) - use_ssdiff = 1; + use_ssdiff = ctx.qry.has_ssdiff ? ctx.qry.ssdiff : ctx.cfg.ssdiff; if (show_ctrls) cgit_print_diff_ctrls(); diff --git a/ui-log.c b/ui-log.c index 4a295bd..6b12ca2 100644 --- a/ui-log.c +++ b/ui-log.c @@ -76,6 +76,8 @@ void show_commit_decorations(struct commit *commit) cgit_tag_link(buf, NULL, "tag-deco", ctx.qry.head, buf); } else if (!prefixcmp(deco->name, "refs/remotes/")) { + if (!ctx.repo->enable_remote_branches) + goto next; strncpy(buf, deco->name + 13, sizeof(buf) - 1); cgit_log_link(buf, NULL, "remote-deco", NULL, sha1_to_hex(commit->object.sha1), @@ -88,6 +90,7 @@ void show_commit_decorations(struct commit *commit) sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0); } +next: deco = deco->next; } } diff --git a/ui-repolist.c b/ui-repolist.c index 25c36ce..a09a689 100644 --- a/ui-repolist.c +++ b/ui-repolist.c @@ -118,13 +118,13 @@ void print_header(int columns) } -void print_pager(int items, int pagelen, char *search) +void print_pager(int items, int pagelen, char *search, char *sort) { int i; html("<div class='pager'>"); for(i = 0; i * pagelen < items; i++) cgit_index_link(fmt("[%d]", i+1), fmt("Page %d", i+1), NULL, - search, i * pagelen); + search, sort, i * pagelen); html("</div>"); } @@ -291,7 +291,7 @@ void cgit_print_repolist() if (!hits) cgit_print_error("No repositories found"); else if (hits > ctx.cfg.max_repo_count) - print_pager(hits, ctx.cfg.max_repo_count, ctx.qry.search); + print_pager(hits, ctx.cfg.max_repo_count, ctx.qry.search, ctx.qry.sort); cgit_print_docend(); } diff --git a/ui-shared.c b/ui-shared.c index b736fca..43166af 100644 --- a/ui-shared.c +++ b/ui-shared.c @@ -133,7 +133,7 @@ char *cgit_currurl() return fmt("%s/", ctx.cfg.virtual_root); } -static void site_url(const char *page, const char *search, int ofs) +static void site_url(const char *page, const char *search, const char *sort, int ofs) { char *delim = "?"; @@ -154,6 +154,12 @@ static void site_url(const char *page, const char *search, int ofs) html_attr(search); delim = "&"; } + if (sort) { + html(delim); + html("s="); + html_attr(sort); + delim = "&"; + } if (ofs) { html(delim); htmlf("ofs=%d", ofs); @@ -161,7 +167,7 @@ static void site_url(const char *page, const char *search, int ofs) } static void site_link(const char *page, const char *name, const char *title, - const char *class, const char *search, int ofs) + const char *class, const char *search, const char *sort, int ofs) { html("<a"); if (title) { @@ -175,16 +181,16 @@ static void site_link(const char *page, const char *name, const char *title, html("'"); } html(" href='"); - site_url(page, search, ofs); + site_url(page, search, sort, ofs); html("'>"); html_txt(name); html("</a>"); } void cgit_index_link(const char *name, const char *title, const char *class, - const char *pattern, int ofs) + const char *pattern, const char *sort, int ofs) { - site_link(NULL, name, title, class, pattern, ofs); + site_link(NULL, name, title, class, pattern, sort, ofs); } static char *repolink(const char *title, const char *class, const char *page, @@ -288,7 +294,7 @@ void cgit_log_link(const char *name, const char *title, const char *class, char *delim; delim = repolink(title, class, "log", head, path); - if (rev && strcmp(rev, ctx.qry.head)) { + if (rev && ctx.qry.head && strcmp(rev, ctx.qry.head)) { html(delim); html("id="); html_url_arg(rev); @@ -332,7 +338,7 @@ void cgit_commit_link(char *name, const char *title, const char *class, char *delim; delim = repolink(title, class, "commit", head, path); - if (rev && strcmp(rev, ctx.qry.head)) { + if (rev && ctx.qry.head && strcmp(rev, ctx.qry.head)) { html(delim); html("id="); html_url_arg(rev); @@ -428,7 +434,7 @@ void cgit_self_link(char *name, const char *title, const char *class, struct cgit_context *ctx) { if (!strcmp(ctx->qry.page, "repolist")) - return cgit_index_link(name, title, class, ctx->qry.search, + return cgit_index_link(name, title, class, ctx->qry.search, ctx->qry.sort, ctx->qry.ofs); else if (!strcmp(ctx->qry.page, "summary")) return cgit_summary_link(name, title, class, ctx->qry.head); @@ -669,7 +675,7 @@ void cgit_print_docstart(struct cgit_context *ctx) html_attr(ctx->cfg.favicon); html("'/>\n"); } - if (host && ctx->repo) { + if (host && ctx->repo && ctx->qry.head) { html("<link rel='alternate' title='Atom feed' href='"); html(cgit_httpscheme()); html_attr(cgit_hosturl()); @@ -838,7 +844,7 @@ static void print_header(struct cgit_context *ctx) html("<td class='main'>"); if (ctx->repo) { - cgit_index_link("index", NULL, NULL, NULL, 0); + cgit_index_link("index", NULL, NULL, NULL, NULL, 0); html(" : "); cgit_summary_link(ctx->repo->name, ctx->repo->name, NULL, NULL); html("</td><td class='form'>"); @@ -914,10 +920,10 @@ void cgit_print_pageheader(struct cgit_context *ctx) html("<input type='submit' value='search'/>\n"); html("</form>\n"); } else { - site_link(NULL, "index", NULL, hc(ctx, "repolist"), NULL, 0); + site_link(NULL, "index", NULL, hc(ctx, "repolist"), NULL, NULL, 0); if (ctx->cfg.root_readme) site_link("about", "about", NULL, hc(ctx, "about"), - NULL, 0); + NULL, NULL, 0); html("</td><td class='form'>"); html("<form method='get' action='"); html_attr(cgit_rooturl()); diff --git a/ui-shared.h b/ui-shared.h index e80b975..87a7dac 100644 --- a/ui-shared.h +++ b/ui-shared.h @@ -11,7 +11,7 @@ extern char *cgit_pageurl(const char *reponame, const char *pagename, const char *query); extern void cgit_index_link(const char *name, const char *title, - const char *class, const char *pattern, int ofs); + const char *class, const char *pattern, const char *sort, int ofs); extern void cgit_summary_link(const char *name, const char *title, const char *class, const char *head); extern void cgit_tag_link(const char *name, const char *title, diff --git a/ui-ssdiff.c b/ui-ssdiff.c index 2481585..0cff4b8 100644 --- a/ui-ssdiff.c +++ b/ui-ssdiff.c @@ -2,10 +2,12 @@ #include "html.h" #include "ui-shared.h" #include "ui-diff.h" +#include "ui-ssdiff.h" extern int use_ssdiff; static int current_old_line, current_new_line; +static int **L = NULL; struct deferred_lines { int line_no; @@ -16,16 +18,40 @@ struct deferred_lines { static struct deferred_lines *deferred_old, *deferred_old_last; static struct deferred_lines *deferred_new, *deferred_new_last; +static void create_or_reset_lcs_table() +{ + int i; + + if (L != NULL) { + memset(*L, 0, sizeof(int) * MAX_SSDIFF_SIZE); + return; + } + + // xcalloc will die if we ran out of memory; + // not very helpful for debugging + L = (int**)xcalloc(MAX_SSDIFF_M, sizeof(int *)); + *L = (int*)xcalloc(MAX_SSDIFF_SIZE, sizeof(int)); + + for (i = 1; i < MAX_SSDIFF_M; i++) { + L[i] = *L + i * MAX_SSDIFF_N; + } +} + static char *longest_common_subsequence(char *A, char *B) { int i, j, ri; int m = strlen(A); int n = strlen(B); - int L[m + 1][n + 1]; int tmp1, tmp2; int lcs_length; char *result; + // We bail if the lines are too long + if (m >= MAX_SSDIFF_M || n >= MAX_SSDIFF_N) + return NULL; + + create_or_reset_lcs_table(); + for (i = m; i >= 0; i--) { for (j = n; j >= 0; j--) { if (A[i] == '\0' || B[j] == '\0') { @@ -59,6 +85,7 @@ static char *longest_common_subsequence(char *A, char *B) j += 1; } } + return result; } diff --git a/ui-ssdiff.h b/ui-ssdiff.h index 64b4b12..88627e2 100644 --- a/ui-ssdiff.h +++ b/ui-ssdiff.h @@ -1,6 +1,18 @@ #ifndef UI_SSDIFF_H #define UI_SSDIFF_H +/* + * ssdiff line limits + */ +#ifndef MAX_SSDIFF_M +#define MAX_SSDIFF_M 128 +#endif + +#ifndef MAX_SSDIFF_N +#define MAX_SSDIFF_N 128 +#endif +#define MAX_SSDIFF_SIZE ((MAX_SSDIFF_M) * (MAX_SSDIFF_N)) + extern void cgit_ssdiff_print_deferred_lines(); extern void cgit_ssdiff_line_cb(char *line, int len); |