Add plain patch view
The new view mimics the output from `git format-patch`, making it possible to cherry-pick directly from cgit with something like `curl $url | git am`. Inspired by a patch to `git-apply` by Mike Hommey: http://thread.gmane.org/gmane.comp.version-control.git/67611/focus=67610 Signed-off-by: Lars Hjemli <hjemli@gmail.com>
This commit is contained in:
parent
afcdd083da
commit
620bb3e5e4
2
Makefile
2
Makefile
@ -16,7 +16,7 @@ GIT_URL = http://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.bz2
|
|||||||
EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto
|
EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto
|
||||||
OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \
|
OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \
|
||||||
ui-summary.o ui-log.o ui-tree.o ui-commit.o ui-diff.o \
|
ui-summary.o ui-log.o ui-tree.o ui-commit.o ui-diff.o \
|
||||||
ui-snapshot.o ui-blob.o ui-tag.o ui-refs.o
|
ui-snapshot.o ui-blob.o ui-tag.o ui-refs.o ui-patch.o
|
||||||
|
|
||||||
|
|
||||||
ifdef NEEDS_LIBICONV
|
ifdef NEEDS_LIBICONV
|
||||||
|
5
cgit.c
5
cgit.c
@ -75,6 +75,11 @@ static void cgit_print_repo_page(struct cacheitem *item)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cgit_cmd == CMD_PATCH) {
|
||||||
|
cgit_print_patch(cgit_query_sha1, item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (cgit_cmd == CMD_BLOB) {
|
if (cgit_cmd == CMD_BLOB) {
|
||||||
cgit_print_blob(item, cgit_query_sha1, cgit_query_path);
|
cgit_print_blob(item, cgit_query_sha1, cgit_query_path);
|
||||||
return;
|
return;
|
||||||
|
2
cgit.h
2
cgit.h
@ -30,6 +30,7 @@
|
|||||||
#define CMD_SNAPSHOT 6
|
#define CMD_SNAPSHOT 6
|
||||||
#define CMD_TAG 7
|
#define CMD_TAG 7
|
||||||
#define CMD_REFS 8
|
#define CMD_REFS 8
|
||||||
|
#define CMD_PATCH 9
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dateformats used on misc. pages
|
* Dateformats used on misc. pages
|
||||||
@ -283,6 +284,7 @@ extern void cgit_print_commit(char *hex);
|
|||||||
extern void cgit_print_refs();
|
extern void cgit_print_refs();
|
||||||
extern void cgit_print_tag(char *revname);
|
extern void cgit_print_tag(char *revname);
|
||||||
extern void cgit_print_diff(const char *new_hex, const char *old_hex, const char *prefix);
|
extern void cgit_print_diff(const char *new_hex, const char *old_hex, const char *prefix);
|
||||||
|
extern void cgit_print_patch(char *hex, struct cacheitem *item);
|
||||||
extern void cgit_print_snapshot(struct cacheitem *item, const char *head,
|
extern void cgit_print_snapshot(struct cacheitem *item, const char *head,
|
||||||
const char *hex, const char *prefix,
|
const char *hex, const char *prefix,
|
||||||
const char *filename, int snapshot);
|
const char *filename, int snapshot);
|
||||||
|
2
shared.c
2
shared.c
@ -70,7 +70,7 @@ int htmlfd = 0;
|
|||||||
int cgit_get_cmd_index(const char *cmd)
|
int cgit_get_cmd_index(const char *cmd)
|
||||||
{
|
{
|
||||||
static char *cmds[] = {"log", "commit", "diff", "tree", "blob",
|
static char *cmds[] = {"log", "commit", "diff", "tree", "blob",
|
||||||
"snapshot", "tag", "refs", NULL};
|
"snapshot", "tag", "refs", "patch", NULL};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; cmds[i]; i++)
|
for(i = 0; cmds[i]; i++)
|
||||||
|
105
ui-patch.c
Normal file
105
ui-patch.c
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/* ui-patch.c: generate patch view
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Lars Hjemli
|
||||||
|
*
|
||||||
|
* Licensed under GNU General Public License v2
|
||||||
|
* (see COPYING for full license text)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cgit.h"
|
||||||
|
|
||||||
|
static void print_line(char *line, int len)
|
||||||
|
{
|
||||||
|
char c = line[len-1];
|
||||||
|
|
||||||
|
line[len-1] = '\0';
|
||||||
|
htmlf("%s\n", line);
|
||||||
|
line[len-1] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void header(unsigned char *sha1, char *path1, int mode1,
|
||||||
|
unsigned char *sha2, char *path2, int mode2)
|
||||||
|
{
|
||||||
|
char *abbrev1, *abbrev2;
|
||||||
|
int subproject;
|
||||||
|
|
||||||
|
subproject = (S_ISGITLINK(mode1) || S_ISGITLINK(mode2));
|
||||||
|
htmlf("diff --git a/%s b/%s\n", path1, path2);
|
||||||
|
|
||||||
|
if (is_null_sha1(sha1))
|
||||||
|
path1 = "dev/null";
|
||||||
|
if (is_null_sha1(sha2))
|
||||||
|
path2 = "dev/null";
|
||||||
|
|
||||||
|
if (mode1 == 0)
|
||||||
|
htmlf("new file mode %.6o\n", mode2);
|
||||||
|
|
||||||
|
if (mode2 == 0)
|
||||||
|
htmlf("deleted file mode %.6o\n", mode1);
|
||||||
|
|
||||||
|
if (!subproject) {
|
||||||
|
abbrev1 = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV));
|
||||||
|
abbrev2 = xstrdup(find_unique_abbrev(sha2, DEFAULT_ABBREV));
|
||||||
|
htmlf("index %s..%s", abbrev1, abbrev2);
|
||||||
|
free(abbrev1);
|
||||||
|
free(abbrev2);
|
||||||
|
if (mode1 != 0 && mode2 != 0) {
|
||||||
|
htmlf(" %.6o", mode1);
|
||||||
|
if (mode2 != mode1)
|
||||||
|
htmlf("..%.6o", mode2);
|
||||||
|
}
|
||||||
|
htmlf("\n--- a/%s\n", path1);
|
||||||
|
htmlf("+++ b/%s\n", path2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void filepair_cb(struct diff_filepair *pair)
|
||||||
|
{
|
||||||
|
header(pair->one->sha1, pair->one->path, pair->one->mode,
|
||||||
|
pair->two->sha1, pair->two->path, pair->two->mode);
|
||||||
|
if (S_ISGITLINK(pair->one->mode) || S_ISGITLINK(pair->two->mode)) {
|
||||||
|
if (S_ISGITLINK(pair->one->mode))
|
||||||
|
print_line(fmt("-Subproject %s", sha1_to_hex(pair->one->sha1)), 52);
|
||||||
|
if (S_ISGITLINK(pair->two->mode))
|
||||||
|
print_line(fmt("+Subproject %s", sha1_to_hex(pair->two->sha1)), 52);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cgit_diff_files(pair->one->sha1, pair->two->sha1, print_line))
|
||||||
|
html("Error running diff");
|
||||||
|
}
|
||||||
|
|
||||||
|
void cgit_print_patch(char *hex, struct cacheitem *item)
|
||||||
|
{
|
||||||
|
struct commit *commit;
|
||||||
|
struct commitinfo *info;
|
||||||
|
unsigned char sha1[20], old_sha1[20];
|
||||||
|
char *patchname;
|
||||||
|
|
||||||
|
if (!hex)
|
||||||
|
hex = cgit_query_head;
|
||||||
|
|
||||||
|
if (get_sha1(hex, sha1)) {
|
||||||
|
cgit_print_error(fmt("Bad object id: %s", hex));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
commit = lookup_commit_reference(sha1);
|
||||||
|
if (!commit) {
|
||||||
|
cgit_print_error(fmt("Bad commit reference: %s", hex));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
info = cgit_parse_commit(commit);
|
||||||
|
hashcpy(old_sha1, commit->parents->item->object.sha1);
|
||||||
|
|
||||||
|
patchname = fmt("%s.patch", sha1_to_hex(sha1));
|
||||||
|
cgit_print_snapshot_start("text/plain", patchname, item);
|
||||||
|
htmlf("From %s Mon Sep 17 00:00:00 2001\n", sha1_to_hex(sha1));
|
||||||
|
htmlf("From: %s%s\n", info->author, info->author_email);
|
||||||
|
html("Date: ");
|
||||||
|
cgit_print_date(info->author_date, "%a, %d %b %Y %H:%M:%S %z%n");
|
||||||
|
htmlf("Subject: %s\n\n%s", info->subject, info->msg);
|
||||||
|
html("---\n");
|
||||||
|
cgit_diff_tree(old_sha1, sha1, filepair_cb, NULL);
|
||||||
|
html("--\n");
|
||||||
|
htmlf("cgit %s\n", CGIT_VERSION);
|
||||||
|
cgit_free_commitinfo(info);
|
||||||
|
}
|
@ -272,6 +272,12 @@ void cgit_diff_link(char *name, char *title, char *class, char *head,
|
|||||||
html("</a>");
|
html("</a>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cgit_patch_link(char *name, char *title, char *class, char *head,
|
||||||
|
char *rev)
|
||||||
|
{
|
||||||
|
reporevlink("patch", name, title, class, head, rev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void cgit_object_link(struct object *obj)
|
void cgit_object_link(struct object *obj)
|
||||||
{
|
{
|
||||||
char *page, *arg, *url;
|
char *page, *arg, *url;
|
||||||
@ -490,6 +496,8 @@ void cgit_print_pageheader(char *title, int show_search)
|
|||||||
cgit_query_sha1);
|
cgit_query_sha1);
|
||||||
cgit_diff_link("diff", NULL, "menu", cgit_query_head,
|
cgit_diff_link("diff", NULL, "menu", cgit_query_head,
|
||||||
cgit_query_sha1, cgit_query_sha2, NULL);
|
cgit_query_sha1, cgit_query_sha2, NULL);
|
||||||
|
cgit_patch_link("patch", NULL, "menu", cgit_query_head,
|
||||||
|
cgit_query_sha1);
|
||||||
|
|
||||||
for_each_ref(print_archive_ref, &header);
|
for_each_ref(print_archive_ref, &header);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user