Merge branch 'master' into jc/diff

* master:
  Make "--parents" logs also be incremental
  Retire diffcore-pathspec.
  Improve the git-diff-tree -c/-cc documentation
This commit is contained in:
Junio C Hamano 2006-04-10 16:44:59 -07:00
commit 6d46a23bf6
10 changed files with 45 additions and 108 deletions

View File

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

View File

@ -197,7 +197,7 @@ LIB_H = \
tree-walk.h log-tree.h tree-walk.h log-tree.h
DIFF_OBJS = \ 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-pickaxe.o diffcore-rename.o tree-diff.o combine-diff.o \
diffcore-delta.o log-tree.o diffcore-delta.o log-tree.o

View File

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

2
diff.c
View File

@ -1375,8 +1375,6 @@ static void diffcore_apply_filter(const char *filter)
void diffcore_std(struct diff_options *options) void diffcore_std(struct diff_options *options)
{ {
if (options->paths && options->paths[0])
diffcore_pathspec(options->paths);
if (options->break_opt != -1) if (options->break_opt != -1)
diffcore_break(options->break_opt); diffcore_break(options->break_opt);
if (options->detect_rename) if (options->detect_rename)

1
diff.h
View File

@ -20,7 +20,6 @@ typedef void (*add_remove_fn_t)(struct diff_options *options,
const char *base, const char *path); const char *base, const char *path);
struct diff_options { struct diff_options {
const char **paths;
const char *filter; const char *filter;
const char *orderfile; const char *orderfile;
const char *pickaxe; const char *pickaxe;

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;
}

View File

@ -59,12 +59,12 @@ enum XML_Status {
#define LOCK_TIME 600 #define LOCK_TIME 600
#define LOCK_REFRESH 30 #define LOCK_REFRESH 30
/* bits #0-4 in revision.h */ /* bits #0-6 in revision.h */
#define LOCAL (1u << 5) #define LOCAL (1u << 7)
#define REMOTE (1u << 6) #define REMOTE (1u << 8)
#define FETCHING (1u << 7) #define FETCHING (1u << 9)
#define PUSHING (1u << 8) #define PUSHING (1u << 10)
/* We allow "recursive" symbolic refs. Only within reason, though */ /* We allow "recursive" symbolic refs. Only within reason, though */
#define MAXDEPTH 5 #define MAXDEPTH 5

View File

@ -7,9 +7,9 @@
#include "tree-walk.h" #include "tree-walk.h"
#include "revision.h" #include "revision.h"
/* bits #0-5 in revision.h */ /* bits #0-6 in revision.h */
#define COUNTED (1u<<6) #define COUNTED (1u<<7)
static const char rev_list_usage[] = static const char rev_list_usage[] =
"git-rev-list [OPTION] <commit-id>... [ -- paths... ]\n" "git-rev-list [OPTION] <commit-id>... [ -- paths... ]\n"

View File

@ -340,6 +340,10 @@ static void add_parents_to_list(struct rev_info *revs, struct commit *commit, st
{ {
struct commit_list *parent = commit->parents; struct commit_list *parent = commit->parents;
if (commit->object.flags & ADDED)
return;
commit->object.flags |= ADDED;
/* /*
* If the commit is uninteresting, don't try to * If the commit is uninteresting, don't try to
* prune parents - we want the maximal uninteresting * prune parents - we want the maximal uninteresting
@ -705,13 +709,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
if (revs->prune_data) { if (revs->prune_data) {
diff_tree_setup_paths(revs->prune_data); diff_tree_setup_paths(revs->prune_data);
revs->prune_fn = try_to_simplify_commit; revs->prune_fn = try_to_simplify_commit;
/*
* If we fix up parent data, we currently cannot
* do that on-the-fly.
*/
if (revs->parents)
revs->limited = 1;
} }
return left; return left;
@ -728,10 +725,12 @@ void prepare_revision_walk(struct rev_info *revs)
revs->topo_getter); revs->topo_getter);
} }
static int rewrite_one(struct commit **pp) static int rewrite_one(struct rev_info *revs, struct commit **pp)
{ {
for (;;) { for (;;) {
struct commit *p = *pp; struct commit *p = *pp;
if (!revs->limited)
add_parents_to_list(revs, p, &revs->commits);
if (p->object.flags & (TREECHANGE | UNINTERESTING)) if (p->object.flags & (TREECHANGE | UNINTERESTING))
return 0; return 0;
if (!p->parents) if (!p->parents)
@ -740,12 +739,12 @@ static int rewrite_one(struct commit **pp)
} }
} }
static void rewrite_parents(struct commit *commit) static void rewrite_parents(struct rev_info *revs, struct commit *commit)
{ {
struct commit_list **pp = &commit->parents; struct commit_list **pp = &commit->parents;
while (*pp) { while (*pp) {
struct commit_list *parent = *pp; struct commit_list *parent = *pp;
if (rewrite_one(&parent->item) < 0) { if (rewrite_one(revs, &parent->item) < 0) {
*pp = parent->next; *pp = parent->next;
continue; continue;
} }
@ -802,7 +801,7 @@ struct commit *get_revision(struct rev_info *revs)
if (!(commit->object.flags & TREECHANGE)) if (!(commit->object.flags & TREECHANGE))
continue; continue;
if (revs->parents) if (revs->parents)
rewrite_parents(commit); rewrite_parents(revs, commit);
} }
commit->object.flags |= SHOWN; commit->object.flags |= SHOWN;
return commit; return commit;

View File

@ -7,6 +7,7 @@
#define SHOWN (1u<<3) #define SHOWN (1u<<3)
#define TMP_MARK (1u<<4) /* for isolated cases; clean after use */ #define TMP_MARK (1u<<4) /* for isolated cases; clean after use */
#define BOUNDARY (1u<<5) #define BOUNDARY (1u<<5)
#define ADDED (1u<<6) /* Parents already parsed and added? */
struct rev_info; struct rev_info;