Merge branch 'jc/withraw' into next

* jc/withraw:
  diff-* --patch-with-raw
  Retire git-log.sh (take#2)
  Retire git-log.sh
  Retire diffcore-pathspec.
  Improve the git-diff-tree -c/-cc documentation
This commit is contained in:
Junio C Hamano 2006-04-10 19:44:35 -07:00
commit 6b32ee2381
7 changed files with 96 additions and 126 deletions

View File

@ -60,7 +60,8 @@ separated with a single space are given.
-m::
By default, "git-diff-tree --stdin" does not show
differences for merge commits. With this flag, it shows
differences to that commit from all of its parents.
differences to that commit from all of its parents. See
also '-c'.
-s::
By default, "git-diff-tree --stdin" shows differences,
@ -81,19 +82,25 @@ separated with a single space are given.
git-diff-tree outputs a line with the commit ID when
applicable. This flag suppressed the commit ID output.
-c,--cc::
These flags change the way a merge commit is displayed
-c::
This flag changes the way a merge commit is displayed
(which means it is useful only when the command is given
one <tree-ish>, or '--stdin'). It shows the differences
from each of the parents to the merge result
simultaneously, instead of showing pairwise diff between
a parent and the result one at a time, which '-m' option
output does. '--cc' further compresses the output by
omiting hunks that show differences from only one
from each of the parents to the merge result simultaneously
instead of showing pairwise diff between a parent and the
result one at a time (which is what the '-m' option does).
Furthermore, it lists only files which were modified
from all parents.
-cc::
This flag changes the way a merge commit patch is displayed,
in a similar way to the '-c' option. It implies the '-c'
and '-p' options and further compresses the patch output
by omitting hunks that show differences from only one
parent, or show the same change from all but one parent
for an Octopus merge. When this optimization makes all
hunks disappear, the commit itself and the commit log
message is not shown, just like any other "empty diff" cases.
message is not shown, just like in any other "empty diff" case.
--always::
Show the commit itself and the commit log message even

View File

@ -116,7 +116,7 @@ SCRIPT_SH = \
git-add.sh git-bisect.sh git-branch.sh git-checkout.sh \
git-cherry.sh git-clean.sh git-clone.sh git-commit.sh \
git-count-objects.sh git-diff.sh git-fetch.sh \
git-format-patch.sh git-log.sh git-ls-remote.sh \
git-format-patch.sh git-ls-remote.sh \
git-merge-one-file.sh git-parse-remote.sh \
git-prune.sh git-pull.sh git-push.sh git-rebase.sh \
git-repack.sh git-request-pull.sh git-reset.sh \
@ -167,8 +167,10 @@ PROGRAMS = \
git-name-rev$X git-pack-redundant$X git-repo-config$X git-var$X \
git-describe$X git-merge-tree$X git-blame$X git-imap-send$X
BUILT_INS = git-log$X
# what 'all' will build and 'install' will install, in gitexecdir
ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(BUILT_INS) $(SCRIPTS)
# Backward compatibility -- to be removed after 1.0
PROGRAMS += git-ssh-pull$X git-ssh-push$X
@ -197,7 +199,7 @@ LIB_H = \
tree-walk.h log-tree.h
DIFF_OBJS = \
diff.o diffcore-break.o diffcore-order.o diffcore-pathspec.o \
diff.o diffcore-break.o diffcore-order.o \
diffcore-pickaxe.o diffcore-rename.o tree-diff.o combine-diff.o \
diffcore-delta.o log-tree.o
@ -461,6 +463,9 @@ git$X: git.c common-cmds.h $(GITLIBS)
$(ALL_CFLAGS) -o $@ $(filter %.c,$^) \
$(ALL_LDFLAGS) $(LIBS)
$(BUILT_INS): git$X
rm -f $@ && ln git$X $@
common-cmds.h: Documentation/git-*.txt
./generate-cmdlist.sh > $@

View File

@ -832,6 +832,7 @@ const char *diff_tree_combined_merge(const unsigned char *sha1,
diffopts = *opt;
diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
diffopts.with_raw = 0;
diffopts.recursive = 1;
/* count parents */
@ -858,6 +859,16 @@ const char *diff_tree_combined_merge(const unsigned char *sha1,
num_paths++;
}
if (num_paths) {
if (opt->with_raw) {
int saved_format = opt->output_format;
opt->output_format = DIFF_FORMAT_RAW;
for (p = paths; p; p = p->next) {
if (show_combined_diff(p, num_parent, dense,
header, opt))
header = NULL;
}
opt->output_format = saved_format;
}
for (p = paths; p; p = p->next) {
if (show_combined_diff(p, num_parent, dense,
header, opt))

View File

@ -11,15 +11,17 @@ static const char diff_stages_usage[] =
"git-diff-stages [<common diff options>] <stage1> <stage2> [<path>...]"
COMMON_DIFF_OPTIONS_HELP;
static void diff_stages(int stage1, int stage2)
static void diff_stages(int stage1, int stage2, const char **pathspec)
{
int i = 0;
while (i < active_nr) {
struct cache_entry *ce, *stages[4] = { NULL, };
struct cache_entry *one, *two;
const char *name;
int len;
int len, skip;
ce = active_cache[i];
skip = !ce_path_match(ce, pathspec);
len = ce_namelen(ce);
name = ce->name;
for (;;) {
@ -34,7 +36,8 @@ static void diff_stages(int stage1, int stage2)
}
one = stages[stage1];
two = stages[stage2];
if (!one && !two)
if (skip || (!one && !two))
continue;
if (!one)
diff_addremove(&diff_options, '+', ntohl(two->ce_mode),
@ -54,8 +57,8 @@ static void diff_stages(int stage1, int stage2)
int main(int ac, const char **av)
{
int stage1, stage2;
setup_git_directory();
const char *prefix = setup_git_directory();
const char **pathspec = NULL;
git_config(git_diff_config);
read_cache();
@ -89,12 +92,12 @@ int main(int ac, const char **av)
usage(diff_stages_usage);
av += 3; /* The rest from av[0] are for paths restriction. */
diff_options.paths = av;
pathspec = get_pathspec(prefix, av);
if (diff_setup_done(&diff_options) < 0)
usage(diff_stages_usage);
diff_stages(stage1, stage2);
diff_stages(stage1, stage2, pathspec);
diffcore_std(&diff_options);
diff_flush(&diff_options);
return 0;

86
diff.c
View File

@ -862,6 +862,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
const char *arg = av[0];
if (!strcmp(arg, "-p") || !strcmp(arg, "-u"))
options->output_format = DIFF_FORMAT_PATCH;
else if (!strcmp(arg, "--patch-with-raw")) {
options->output_format = DIFF_FORMAT_PATCH;
options->with_raw = 1;
}
else if (!strcmp(arg, "-z"))
options->line_termination = 0;
else if (!strncmp(arg, "-l", 2))
@ -1048,13 +1052,13 @@ const char *diff_unique_abbrev(const unsigned char *sha1, int len)
static void diff_flush_raw(struct diff_filepair *p,
int line_termination,
int inter_name_termination,
struct diff_options *options)
struct diff_options *options,
int output_format)
{
int two_paths;
char status[10];
int abbrev = options->abbrev;
const char *path_one, *path_two;
int output_format = options->output_format;
path_one = p->one->path;
path_two = p->two->path;
@ -1270,46 +1274,58 @@ static void diff_resolve_rename_copy(void)
diff_debug_queue("resolve-rename-copy done", q);
}
static void flush_one_pair(struct diff_filepair *p,
int diff_output_format,
struct diff_options *options)
{
int inter_name_termination = '\t';
int line_termination = options->line_termination;
if (!line_termination)
inter_name_termination = 0;
switch (p->status) {
case DIFF_STATUS_UNKNOWN:
break;
case 0:
die("internal error in diff-resolve-rename-copy");
break;
default:
switch (diff_output_format) {
case DIFF_FORMAT_PATCH:
diff_flush_patch(p, options);
break;
case DIFF_FORMAT_RAW:
case DIFF_FORMAT_NAME_STATUS:
diff_flush_raw(p, line_termination,
inter_name_termination,
options, diff_output_format);
break;
case DIFF_FORMAT_NAME:
diff_flush_name(p,
inter_name_termination,
line_termination);
break;
case DIFF_FORMAT_NO_OUTPUT:
break;
}
}
}
void diff_flush(struct diff_options *options)
{
struct diff_queue_struct *q = &diff_queued_diff;
int i;
int inter_name_termination = '\t';
int diff_output_format = options->output_format;
int line_termination = options->line_termination;
if (!line_termination)
inter_name_termination = 0;
if (options->with_raw) {
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
flush_one_pair(p, DIFF_FORMAT_RAW, options);
}
}
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
switch (p->status) {
case DIFF_STATUS_UNKNOWN:
break;
case 0:
die("internal error in diff-resolve-rename-copy");
break;
default:
switch (diff_output_format) {
case DIFF_FORMAT_PATCH:
diff_flush_patch(p, options);
break;
case DIFF_FORMAT_RAW:
case DIFF_FORMAT_NAME_STATUS:
diff_flush_raw(p, line_termination,
inter_name_termination,
options);
break;
case DIFF_FORMAT_NAME:
diff_flush_name(p,
inter_name_termination,
line_termination);
break;
case DIFF_FORMAT_NO_OUTPUT:
break;
}
}
flush_one_pair(p, diff_output_format, options);
diff_free_filepair(p);
}
free(q->queue);
@ -1375,8 +1391,6 @@ static void diffcore_apply_filter(const char *filter)
void diffcore_std(struct diff_options *options)
{
if (options->paths && options->paths[0])
diffcore_pathspec(options->paths);
if (options->break_opt != -1)
diffcore_break(options->break_opt);
if (options->detect_rename)

2
diff.h
View File

@ -20,11 +20,11 @@ typedef void (*add_remove_fn_t)(struct diff_options *options,
const char *base, const char *path);
struct diff_options {
const char **paths;
const char *filter;
const char *orderfile;
const char *pickaxe;
unsigned recursive:1,
with_raw:1,
tree_in_recursive:1,
full_index:1;
int break_opt;

View File

@ -1,70 +0,0 @@
/*
* Copyright (C) 2005 Junio C Hamano
*/
#include "cache.h"
#include "diff.h"
#include "diffcore.h"
struct path_spec {
const char *spec;
int len;
};
static int matches_pathspec(const char *name, struct path_spec *s, int cnt)
{
int i;
int namelen;
if (cnt == 0)
return 1;
namelen = strlen(name);
for (i = 0; i < cnt; i++) {
int len = s[i].len;
if (namelen < len)
continue;
if (memcmp(s[i].spec, name, len))
continue;
if (s[i].spec[len-1] == '/' ||
name[len] == 0 ||
name[len] == '/')
return 1;
if (!len)
return 1;
}
return 0;
}
void diffcore_pathspec(const char **pathspec)
{
struct diff_queue_struct *q = &diff_queued_diff;
int i, speccnt;
struct diff_queue_struct outq;
struct path_spec *spec;
outq.queue = NULL;
outq.nr = outq.alloc = 0;
for (i = 0; pathspec[i]; i++)
;
speccnt = i;
if (!speccnt)
return;
spec = xmalloc(sizeof(*spec) * speccnt);
for (i = 0; pathspec[i]; i++) {
spec[i].spec = pathspec[i];
spec[i].len = strlen(pathspec[i]);
}
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
if (matches_pathspec(p->two->path, spec, speccnt))
diff_q(&outq, p);
else
diff_free_filepair(p);
}
free(q->queue);
*q = outq;
return;
}