提交 af5323e0 编写于 作者: J Junio C Hamano 提交者: Linus Torvalds

[PATCH] Add -O<orderfile> option to diff-* brothers.

A new diffcore filter diffcore-order is introduced.  This takes
a text file each of whose line is a shell glob pattern.  Patches
that match a glob pattern on an earlier line in the file are
output before patches that match a later line, and patches that
do not match any glob pattern are output last.

A typical orderfile for git project probably should look like
this:

    README
    Makefile
    Documentation
    *.h
    *.c
Signed-off-by: NJunio C Hamano <junkio@cox.net>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 2036d841
......@@ -9,7 +9,7 @@ git-diff-cache - Compares content and mode of blobs between the cache and reposi
SYNOPSIS
--------
'git-diff-cache' [-p] [-r] [-z] [-m] [-B] [-M] [-R] [-C] [-S<string>] [--pickaxe-all] [--cached] <tree-ish> [<path>...]
'git-diff-cache' [-p] [-r] [-z] [-m] [-B] [-M] [-R] [-C] [-O<orderfile>] [-S<string>] [--pickaxe-all] [--cached] <tree-ish> [<path>...]
DESCRIPTION
-----------
......@@ -52,6 +52,10 @@ OPTIONS
changeset, not just the files that contains the change
in <string>.
-O<orderfile>::
Output the patch in the order specified in the
<orderfile>, which has one shell glob pattern per line.
-R::
Output diff in reverse.
......
......@@ -9,7 +9,7 @@ git-diff-files - Compares files in the working tree and the cache
SYNOPSIS
--------
'git-diff-files' [-p] [-q] [-r] [-z] [-B] [-M] [-C] [-R] [-S<string>] [--pickaxe-all] [<pattern>...]
'git-diff-files' [-p] [-q] [-r] [-z] [-B] [-M] [-C] [-R] [-O<orderfile>] [-S<string>] [--pickaxe-all] [<pattern>...]
DESCRIPTION
-----------
......@@ -46,6 +46,10 @@ OPTIONS
changeset, not just the files that contains the change
in <string>.
-O<orderfile>::
Output the patch in the order specified in the
<orderfile>, which has one shell glob pattern per line.
-r::
This flag does not mean anything. It is there only to match
git-diff-tree. Unlike git-diff-tree, git-diff-files always looks
......
......@@ -9,7 +9,7 @@ git-diff-tree - Compares the content and mode of blobs found via two tree object
SYNOPSIS
--------
'git-diff-tree' [-p] [-r] [-z] [--stdin] [-B] [-M] [-R] [-C] [-S<string>] [--pickaxe-all] [-m] [-s] [-v] [-t] <tree-ish> <tree-ish> [<pattern>]\*
'git-diff-tree' [-p] [-r] [-z] [--stdin] [-B] [-M] [-R] [-C] [-O<orderfile>] [-S<string>] [--pickaxe-all] [-m] [-s] [-v] [-t] <tree-ish> <tree-ish> [<pattern>]\*
DESCRIPTION
-----------
......@@ -53,6 +53,10 @@ OPTIONS
changeset, not just the files that contains the change
in <string>.
-O<orderfile>::
Output the patch in the order specified in the
<orderfile>, which has one shell glob pattern per line.
-r::
recurse
......
......@@ -48,7 +48,7 @@ LIB_OBJS += strbuf.o
LIB_H += diff.h count-delta.h
LIB_OBJS += diff.o diffcore-rename.o diffcore-pickaxe.o diffcore-pathspec.o \
count-delta.o diffcore-break.o
count-delta.o diffcore-break.o diffcore-order.o
LIB_OBJS += gitenv.o
......@@ -132,6 +132,7 @@ diffcore-rename.o : $(LIB_H) diffcore.h
diffcore-pathspec.o : $(LIB_H) diffcore.h
diffcore-pickaxe.o : $(LIB_H) diffcore.h
diffcore-break.o : $(LIB_H) diffcore.h
diffcore-order.o : $(LIB_H) diffcore.h
test: all
$(MAKE) -C t/ all
......
......@@ -10,6 +10,7 @@ static int diff_score_opt = 0;
static const char *pickaxe = NULL;
static int pickaxe_opts = 0;
static int diff_break_opt = -1;
static const char *orderfile = NULL;
/* A file entry went away or appeared */
static void show_file(const char *prefix, struct cache_entry *ce, unsigned char *sha1, unsigned int mode)
......@@ -215,6 +216,10 @@ int main(int argc, const char **argv)
pickaxe = arg + 2;
continue;
}
if (!strncmp(arg, "-O", 2)) {
orderfile = arg + 2;
continue;
}
if (!strcmp(arg, "--pickaxe-all")) {
pickaxe_opts = DIFF_PICKAXE_ALL;
continue;
......@@ -249,7 +254,8 @@ int main(int argc, const char **argv)
diffcore_std(pathspec ? : NULL,
detect_rename, diff_score_opt,
pickaxe, pickaxe_opts,
diff_break_opt);
diff_break_opt,
orderfile);
diff_flush(diff_output_format, 1);
return ret;
}
......@@ -16,6 +16,7 @@ static int diff_score_opt = 0;
static const char *pickaxe = NULL;
static int pickaxe_opts = 0;
static int diff_break_opt = -1;
static const char *orderfile = NULL;
static int silent = 0;
static void show_unmerge(const char *path)
......@@ -56,6 +57,8 @@ int main(int argc, const char **argv)
diff_setup_opt |= DIFF_SETUP_REVERSE;
else if (!strncmp(argv[1], "-S", 2))
pickaxe = argv[1] + 2;
else if (!strncmp(argv[1], "-O", 2))
orderfile = argv[1] + 2;
else if (!strcmp(argv[1], "--pickaxe-all"))
pickaxe_opts = DIFF_PICKAXE_ALL;
else if (!strncmp(argv[1], "-B", 2))
......@@ -122,7 +125,8 @@ int main(int argc, const char **argv)
diffcore_std((1 < argc) ? argv + 1 : NULL,
detect_rename, diff_score_opt,
pickaxe, pickaxe_opts,
diff_break_opt);
diff_break_opt,
orderfile);
diff_flush(diff_output_format, 1);
return 0;
}
......@@ -15,6 +15,7 @@ static int diff_score_opt = 0;
static const char *pickaxe = NULL;
static int pickaxe_opts = 0;
static int diff_break_opt = -1;
static const char *orderfile = NULL;
static const char *header = NULL;
static const char *header_prefix = "";
......@@ -265,7 +266,8 @@ static int call_diff_flush(void)
diffcore_std(0,
detect_rename, diff_score_opt,
pickaxe, pickaxe_opts,
diff_break_opt);
diff_break_opt,
orderfile);
if (diff_queue_is_empty()) {
diff_flush(DIFF_FORMAT_NO_OUTPUT, 0);
return 0;
......@@ -511,6 +513,10 @@ int main(int argc, const char **argv)
pickaxe = arg + 2;
continue;
}
if (!strncmp(arg, "-O", 2)) {
orderfile = arg + 2;
continue;
}
if (!strcmp(arg, "--pickaxe-all")) {
pickaxe_opts = DIFF_PICKAXE_ALL;
continue;
......
......@@ -888,7 +888,8 @@ void diff_flush(int diff_output_style, int resolve_rename_copy)
void diffcore_std(const char **paths,
int detect_rename, int rename_score,
const char *pickaxe, int pickaxe_opts,
int break_opt)
int break_opt,
const char *orderfile)
{
if (paths && paths[0])
diffcore_pathspec(paths);
......@@ -898,6 +899,8 @@ void diffcore_std(const char **paths,
diffcore_rename(detect_rename, rename_score);
if (pickaxe)
diffcore_pickaxe(pickaxe, pickaxe_opts);
if (orderfile)
diffcore_order(orderfile);
}
void diff_addremove(int addremove, unsigned mode,
......
......@@ -43,12 +43,15 @@ extern void diffcore_pickaxe(const char *needle, int opts);
extern void diffcore_pathspec(const char **pathspec);
extern void diffcore_break(int);
extern void diffcore_order(const char *orderfile);
extern void diffcore_break(int max_score);
extern void diffcore_std(const char **paths,
int detect_rename, int rename_score,
const char *pickaxe, int pickaxe_opts,
int break_opt);
int break_opt,
const char *orderfile);
extern int diff_queue_is_empty(void);
......
/*
* Copyright (C) 2005 Junio C Hamano
*/
#include "cache.h"
#include "diff.h"
#include "diffcore.h"
#include <fnmatch.h>
static char **order;
static int order_cnt;
static void prepare_order(const char *orderfile)
{
int fd, cnt, pass;
void *map;
char *cp, *endp;
struct stat st;
if (order)
return;
fd = open(orderfile, O_RDONLY);
if (fd < 0)
return;
if (fstat(fd, &st)) {
close(fd);
return;
}
map = mmap(NULL, st.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
close(fd);
if (-1 == (int)(long)map)
return;
endp = map + st.st_size;
for (pass = 0; pass < 2; pass++) {
cnt = 0;
cp = map;
while (cp < endp) {
char *ep;
for (ep = cp; ep < endp && *ep != '\n'; ep++)
;
/* cp to ep has one line */
if (*cp == '\n' || *cp == '#')
; /* comment */
else if (pass == 0)
cnt++;
else {
if (*ep == '\n') {
*ep = 0;
order[cnt] = cp;
}
else {
order[cnt] = xmalloc(ep-cp+1);
memcpy(order[cnt], cp, ep-cp);
order[cnt][ep-cp] = 0;
}
cnt++;
}
if (ep < endp)
ep++;
cp = ep;
}
if (pass == 0) {
order_cnt = cnt;
order = xmalloc(sizeof(*order) * cnt);
}
}
}
struct pair_order {
struct diff_filepair *pair;
int orig_order;
int order;
};
static int match_order(const char *path)
{
int i;
char p[PATH_MAX];
for (i = 0; i < order_cnt; i++) {
strcpy(p, path);
while (p[0]) {
char *cp;
if (!fnmatch(order[i], p, 0))
return i;
cp = strrchr(p, '/');
if (!cp)
break;
*cp = 0;
}
}
return order_cnt;
}
static int compare_pair_order(const void *a_, const void *b_)
{
struct pair_order const *a, *b;
a = (struct pair_order const *)a_;
b = (struct pair_order const *)b_;
if (a->order != b->order)
return a->order - b->order;
return a->orig_order - b->orig_order;
}
void diffcore_order(const char *orderfile)
{
struct diff_queue_struct *q = &diff_queued_diff;
struct pair_order *o = xmalloc(sizeof(*o) * q->nr);
int i;
prepare_order(orderfile);
for (i = 0; i < q->nr; i++) {
o[i].pair = q->queue[i];
o[i].orig_order = i;
o[i].order = match_order(o[i].pair->two->path);
}
qsort(o, q->nr, sizeof(*o), compare_pair_order);
for (i = 0; i < q->nr; i++)
q->queue[i] = o[i].pair;
free(o);
return;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册