From 750f7b668f33c9e8decbdd8141115328992d6fea Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 19 Jun 2007 14:22:46 -0700 Subject: Finally implement "git log --follow" Ok, I've really held off doing this too damn long, because I'm lazy, and I was always hoping that somebody else would do it. But no, people keep asking for it, but nobody actually did anything, so I decided I might as well bite the bullet, and instead of telling people they could add a "--follow" flag to "git log" to do what they want to do, I decided that it looks like I just have to do it for them.. The code wasn't actually that complicated, in that the diffstat for this patch literally says "70 insertions(+), 1 deletions(-)", but I will have to admit that in order to get to this fairly simple patch, you did have to know and understand the internal git diff generation machinery pretty well, and had to really be able to follow how commit generation interacts with generating patches and generating the log. So I suspect that while I was right that it wasn't that hard, I might have been expecting too much of random people - this patch does seem to be firmly in the core "Linus or Junio" territory. To make a long story short: I'm sorry for it taking so long until I just did it. I'm not going to guarantee that this works for everybody, but you really can just look at the patch, and after the appropriate appreciative noises ("Ooh, aah") over how clever I am, you can then just notice that the code itself isn't really that complicated. All the real new code is in the new "try_to_follow_renames()" function. It really isn't rocket science: we notice that the pathname we were looking at went away, so we start a full tree diff and try to see if we can instead make that pathname be a rename or a copy from some other previous pathname. And if we can, we just continue, except we show *that* particular diff, and ever after we use the _previous_ pathname. One thing to look out for: the "rename detection" is considered to be a singular event in the _linear_ "git log" output! That's what people want to do, but I just wanted to point out that this patch is *not* carrying around a "commit,pathname" kind of pair and it's *not* going to be able to notice the file coming from multiple *different* files in earlier history. IOW, if you use "git log --follow", then you get the stupid CVS/SVN kind of "files have single identities" kind of semantics, and git log will just pick the identity based on the normal move/copy heuristics _as_if_ the history could be linearized. Put another way: I think the model is broken, but given the broken model, I think this patch does just about as well as you can do. If you have merges with the same "file" having different filenames over the two branches, git will just end up picking _one_ of the pathnames at the point where the newer one goes away. It never looks at multiple pathnames in parallel. And if you understood all that, you probably didn't need it explained, and if you didn't understand the above blathering, it doesn't really mtter to you. What matters to you is that you can now do git log -p --follow builtin-rev-list.c and it will find the point where the old "rev-list.c" got renamed to "builtin-rev-list.c" and show it as such. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- tree-diff.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'tree-diff.c') diff --git a/tree-diff.c b/tree-diff.c index 852498eb49..42924e9b63 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -3,6 +3,7 @@ */ #include "cache.h" #include "diff.h" +#include "diffcore.h" #include "tree.h" static char *malloc_base(const char *base, int baselen, const char *path, int pathlen) @@ -290,6 +291,59 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, stru return 0; } +/* + * Does it look like the resulting diff might be due to a rename? + * - single entry + * - not a valid previous file + */ +static inline int diff_might_be_rename(void) +{ + return diff_queued_diff.nr == 1 && + !DIFF_FILE_VALID(diff_queued_diff.queue[0]->one); +} + +static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, const char *base, struct diff_options *opt) +{ + struct diff_options diff_opts; + const char *paths[2]; + int i; + + diff_setup(&diff_opts); + diff_opts.recursive = 1; + diff_opts.detect_rename = DIFF_DETECT_RENAME; + diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; + diff_opts.single_follow = opt->paths[0]; + paths[0] = NULL; + diff_tree_setup_paths(paths, &diff_opts); + if (diff_setup_done(&diff_opts) < 0) + die("unable to set up diff options to follow renames"); + diff_tree(t1, t2, base, &diff_opts); + diffcore_std(&diff_opts); + + /* NOTE! Ignore the first diff! That was the old one! */ + for (i = 1; i < diff_queued_diff.nr; i++) { + struct diff_filepair *p = diff_queued_diff.queue[i]; + + /* + * Found a source? Not only do we use that for the new + * diff_queued_diff, we also use that as the path in + * the future! + */ + if ((p->status == 'R' || p->status == 'C') && !strcmp(p->two->path, opt->paths[0])) { + diff_queued_diff.queue[0] = p; + opt->paths[0] = xstrdup(p->one->path); + diff_tree_setup_paths(opt->paths, opt); + break; + } + } + + /* + * Then, ignore any but the first entry! It might be the old one, + * or it might be the rename/copy we found + */ + diff_queued_diff.nr = 1; +} + int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const char *base, struct diff_options *opt) { void *tree1, *tree2; @@ -306,6 +360,11 @@ int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const cha init_tree_desc(&t1, tree1, size1); init_tree_desc(&t2, tree2, size2); retval = diff_tree(&t1, &t2, base, opt); + if (opt->follow_renames && diff_might_be_rename()) { + init_tree_desc(&t1, tree1, size1); + init_tree_desc(&t2, tree2, size2); + try_to_follow_renames(&t1, &t2, base, opt); + } free(tree1); free(tree2); return retval; -- cgit v1.3 From 9f38e1ef7e7992ca490b9b419f52fb4d11efb0e4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 21 Jun 2007 10:22:59 -0700 Subject: Fix up "git log --follow" a bit.. This fixes "git log --follow" to hopefully not leak memory any more, and also cleans it up a bit to look more like some of the other functions that use "diff_queued_diff" (by *not* using it directly as a global in the code, but by instead just taking a pointer to the diff queue and using that). As to "diff_queued_diff", I think it would be better off not as a global at all, but as being just an entry in the "struct diff_options" structure, but that's a separate issue, and there may be some subtle reason for why it's currently a global. Anyway, no real changes. Instead of having a magical first entry in the diff-queue, we now end up just keeping the diff-queue clean, and keeping our "preferred" file pairing in an internal "choice" variable. That makes it easy to switch the choice around when we find a better one. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- tree-diff.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) (limited to 'tree-diff.c') diff --git a/tree-diff.c b/tree-diff.c index 42924e9b63..26bdbdd2bf 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -305,9 +305,15 @@ static inline int diff_might_be_rename(void) static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, const char *base, struct diff_options *opt) { struct diff_options diff_opts; - const char *paths[2]; + struct diff_queue_struct *q = &diff_queued_diff; + struct diff_filepair *choice; + const char *paths[1]; int i; + /* Remove the file creation entry from the diff queue, and remember it */ + choice = q->queue[0]; + q->nr = 0; + diff_setup(&diff_opts); diff_opts.recursive = 1; diff_opts.detect_rename = DIFF_DETECT_RENAME; @@ -320,17 +326,21 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co diff_tree(t1, t2, base, &diff_opts); diffcore_std(&diff_opts); - /* NOTE! Ignore the first diff! That was the old one! */ - for (i = 1; i < diff_queued_diff.nr; i++) { - struct diff_filepair *p = diff_queued_diff.queue[i]; + /* Go through the new set of filepairing, and see if we find a more interesting one */ + for (i = 0; i < q->nr; i++) { + struct diff_filepair *p = q->queue[i]; /* * Found a source? Not only do we use that for the new - * diff_queued_diff, we also use that as the path in + * diff_queued_diff, we will also use that as the path in * the future! */ if ((p->status == 'R' || p->status == 'C') && !strcmp(p->two->path, opt->paths[0])) { - diff_queued_diff.queue[0] = p; + /* Switch the file-pairs around */ + q->queue[i] = choice; + choice = p; + + /* Update the path we use from now on.. */ opt->paths[0] = xstrdup(p->one->path); diff_tree_setup_paths(opt->paths, opt); break; @@ -338,10 +348,19 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co } /* - * Then, ignore any but the first entry! It might be the old one, - * or it might be the rename/copy we found + * Then, discard all the non-relevane file pairs... + */ + for (i = 0; i < q->nr; i++) { + struct diff_filepair *p = q->queue[i]; + diff_free_filepair(p); + } + + /* + * .. and re-instate the one we want (which might be either the + * original one, or the rename/copy we found) */ - diff_queued_diff.nr = 1; + q->queue[0] = choice; + q->nr = 1; } int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const char *base, struct diff_options *opt) -- cgit v1.3 From 6dd4b66fdecc2ffdc68758b6c4e059fcaaca512b Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 20 Oct 2007 12:31:31 -0700 Subject: Fix diffcore-break total breakage Ok, so on the kernel list, some people noticed that "git log --follow" doesn't work too well with some files in the x86 merge, because a lot of files got renamed in very special ways. In particular, there was a pattern of doing single commits with renames that looked basically like - rename "filename.h" -> "filename_64.h" - create new "filename.c" that includes "filename_32.h" or "filename_64.h" depending on whether we're 32-bit or 64-bit. which was preparatory for smushing the two trees together. Now, there's two issues here: - "filename.c" *remained*. Yes, it was a rename, but there was a new file created with the old name in the same commit. This was important, because we wanted each commit to compile properly, so that it was bisectable, so splitting the rename into one commit and the "create helper file" into another was *not* an option. So we need to break associations where the contents change too much. Fine. We have the -B flag for that. When we break things up, then the rename detection will be able to figure out whether there are better alternatives. - "git log --follow" didn't with with -B. Now, the second case was really simple: we use a different "diffopt" structure for the rename detection than the basic one (which we use for showing the diffs). So that second case is trivially fixed by a trivial one-liner that just copies the break_opt values from the "real" diffopts to the one used for rename following. So now "git log -B --follow" works fine: diff --git a/tree-diff.c b/tree-diff.c index 26bdbdd..7c261fd 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -319,6 +319,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co diff_opts.detect_rename = DIFF_DETECT_RENAME; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; diff_opts.single_follow = opt->paths[0]; + diff_opts.break_opt = opt->break_opt; paths[0] = NULL; diff_tree_setup_paths(paths, &diff_opts); if (diff_setup_done(&diff_opts) < 0) however, the end result does *not* work. Because our diffcore-break.c logic is totally bogus! In particular: - it used to do if (base_size < MINIMUM_BREAK_SIZE) return 0; /* we do not break too small filepair */ which basically says "don't bother to break small files". But that "base_size" is the *smaller* of the two sizes, which means that if some large file was rewritten into one that just includes another file, we would look at the (small) result, and decide that it's smaller than the break size, so it cannot be worth it to break it up! Even if the other side was ten times bigger and looked *nothing* like the samell file! That's clearly bogus. I replaced "base_size" with "max_size", so that we compare the *bigger* of the filepair with the break size. - It calculated a "merge_score", which was the score needed to merge it back together if nothing else wanted it. But even if it was *so* different that we would never want to merge it back, we wouldn't consider it a break! That makes no sense. So I added if (*merge_score_p > break_score) return 1; to make it clear that if we wouldn't want to merge it at the end, it was *definitely* a break. - It compared the whole "extent of damage", counting all inserts and deletes, but it based this score on the "base_size", and generated the damage score with delta_size = src_removed + literal_added; damage_score = delta_size * MAX_SCORE / base_size; but that makes no sense either, since quite often, this will result in a number that is *bigger* than MAX_SCORE! Why? Because base_size is (again) the smaller of the two files we compare, and when you start out from a small file and add a lot (or start out from a large file and remove a lot), the base_size is going to be much smaller than the damage! Again, the fix was to replace "base_size" with "max_size", at which point the damage actually becomes a sane percentage of the whole. With these changes in place, not only does "git log -B --follow" work for the case that triggered this in the first place, ie now git log -B --follow arch/x86/kernel/vmlinux_64.lds.S actually gives reasonable results. But I also wanted to verify it in general, by doing a full-history git log --stat -B -C on my kernel tree with the old code and the new code. There's some tweaking to be done, but generally, the new code generates much better results wrt breaking up files (and then finding better rename candidates). Here's a few examples of the "--stat" output: - This: include/asm-x86/Kbuild | 2 - include/asm-x86/debugreg.h | 79 +++++++++++++++++++++++++++++++++++------ include/asm-x86/debugreg_32.h | 64 --------------------------------- include/asm-x86/debugreg_64.h | 65 --------------------------------- 4 files changed, 68 insertions(+), 142 deletions(-) Becomes: include/asm-x86/Kbuild | 2 - include/asm-x86/{debugreg_64.h => debugreg.h} | 9 +++- include/asm-x86/debugreg_32.h | 64 ------------------------- 3 files changed, 7 insertions(+), 68 deletions(-) - This: include/asm-x86/bug.h | 41 +++++++++++++++++++++++++++++++++++++++-- include/asm-x86/bug_32.h | 37 ------------------------------------- include/asm-x86/bug_64.h | 34 ---------------------------------- 3 files changed, 39 insertions(+), 73 deletions(-) Becomes include/asm-x86/{bug_64.h => bug.h} | 20 +++++++++++++----- include/asm-x86/bug_32.h | 37 ----------------------------------- 2 files changed, 14 insertions(+), 43 deletions(-) Now, in some other cases, it does actually turn a rename into a real "delete+create" pair, and then the diff is usually bigger, so truth in advertizing: it doesn't always generate a nicer diff. But for what -B was meant for, I think this is a big improvement, and I suspect those cases where it generates a bigger diff are tweakable. So I think this diff fixes a real bug, but we might still want to tweak the default values and perhaps the exact rules for when a break happens. Signed-off-by: Linus Torvalds Signed-off-by: Shawn O. Pearce --- diffcore-break.c | 11 +++++++---- tree-diff.c | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'tree-diff.c') diff --git a/diffcore-break.c b/diffcore-break.c index ae8a7d03e2..c71a22621a 100644 --- a/diffcore-break.c +++ b/diffcore-break.c @@ -45,8 +45,8 @@ static int should_break(struct diff_filespec *src, * The value we return is 1 if we want the pair to be broken, * or 0 if we do not. */ - unsigned long delta_size, base_size, src_copied, literal_added, - src_removed; + unsigned long delta_size, base_size, max_size; + unsigned long src_copied, literal_added, src_removed; *merge_score_p = 0; /* assume no deletion --- "do not break" * is the default. @@ -63,7 +63,8 @@ static int should_break(struct diff_filespec *src, return 0; /* error but caught downstream */ base_size = ((src->size < dst->size) ? src->size : dst->size); - if (base_size < MINIMUM_BREAK_SIZE) + max_size = ((src->size > dst->size) ? src->size : dst->size); + if (max_size < MINIMUM_BREAK_SIZE) return 0; /* we do not break too small filepair */ if (diffcore_count_changes(src, dst, @@ -89,12 +90,14 @@ static int should_break(struct diff_filespec *src, * less than the minimum, after rename/copy runs. */ *merge_score_p = (int)(src_removed * MAX_SCORE / src->size); + if (*merge_score_p > break_score) + return 1; /* Extent of damage, which counts both inserts and * deletes. */ delta_size = src_removed + literal_added; - if (delta_size * MAX_SCORE / base_size < break_score) + if (delta_size * MAX_SCORE / max_size < break_score) return 0; /* If you removed a lot without adding new material, that is diff --git a/tree-diff.c b/tree-diff.c index 26bdbdd2bf..7c261fd7c3 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -319,6 +319,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co diff_opts.detect_rename = DIFF_DETECT_RENAME; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; diff_opts.single_follow = opt->paths[0]; + diff_opts.break_opt = opt->break_opt; paths[0] = NULL; diff_tree_setup_paths(paths, &diff_opts); if (diff_setup_done(&diff_opts) < 0) -- cgit v1.3 From 8f67f8aefb1b751073f8b36fae8be8f72eb93f4a Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sat, 10 Nov 2007 20:05:14 +0100 Subject: Make the diff_options bitfields be an unsigned with explicit masks. reverse_diff was a bit-value in disguise, it's merged in the flags now. Signed-off-by: Pierre Habouzit Signed-off-by: Junio C Hamano --- builtin-blame.c | 10 ++--- builtin-diff-files.c | 4 +- builtin-diff-index.c | 4 +- builtin-diff-tree.c | 7 +-- builtin-diff.c | 12 ++--- builtin-log.c | 24 +++++----- combine-diff.c | 10 ++--- diff-lib.c | 24 +++++----- diff.c | 123 +++++++++++++++++++++++++-------------------------- diff.h | 40 ++++++++++------- log-tree.c | 6 +-- merge-recursive.c | 2 +- patch-ids.c | 2 +- revision.c | 22 ++++----- tree-diff.c | 14 +++--- 15 files changed, 155 insertions(+), 149 deletions(-) (limited to 'tree-diff.c') diff --git a/builtin-blame.c b/builtin-blame.c index ba80bf8942..c158d319dc 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -335,7 +335,7 @@ static struct origin *find_origin(struct scoreboard *sb, * same and diff-tree is fairly efficient about this. */ diff_setup(&diff_opts); - diff_opts.recursive = 1; + DIFF_OPT_SET(&diff_opts, RECURSIVE); diff_opts.detect_rename = 0; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; paths[0] = origin->path; @@ -409,7 +409,7 @@ static struct origin *find_rename(struct scoreboard *sb, const char *paths[2]; diff_setup(&diff_opts); - diff_opts.recursive = 1; + DIFF_OPT_SET(&diff_opts, RECURSIVE); diff_opts.detect_rename = DIFF_DETECT_RENAME; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; diff_opts.single_follow = origin->path; @@ -1075,7 +1075,7 @@ static int find_copy_in_parent(struct scoreboard *sb, return 1; /* nothing remains for this target */ diff_setup(&diff_opts); - diff_opts.recursive = 1; + DIFF_OPT_SET(&diff_opts, RECURSIVE); diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; paths[0] = NULL; @@ -1093,7 +1093,7 @@ static int find_copy_in_parent(struct scoreboard *sb, if ((opt & PICKAXE_BLAME_COPY_HARDEST) || ((opt & PICKAXE_BLAME_COPY_HARDER) && (!porigin || strcmp(target->path, porigin->path)))) - diff_opts.find_copies_harder = 1; + DIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER); if (is_null_sha1(target->commit->object.sha1)) do_diff_cache(parent->tree->object.sha1, &diff_opts); @@ -1102,7 +1102,7 @@ static int find_copy_in_parent(struct scoreboard *sb, target->commit->tree->object.sha1, "", &diff_opts); - if (!diff_opts.find_copies_harder) + if (!DIFF_OPT_TST(&diff_opts, FIND_COPIES_HARDER)) diffcore_std(&diff_opts); retval = 0; diff --git a/builtin-diff-files.c b/builtin-diff-files.c index 6cb30c8e12..046b7e34b5 100644 --- a/builtin-diff-files.c +++ b/builtin-diff-files.c @@ -31,5 +31,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix) if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_RAW; result = run_diff_files_cmd(&rev, argc, argv); - return rev.diffopt.exit_with_status ? rev.diffopt.has_changes: result; + if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS)) + return DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0; + return result; } diff --git a/builtin-diff-index.c b/builtin-diff-index.c index 81e7167438..556c506bfa 100644 --- a/builtin-diff-index.c +++ b/builtin-diff-index.c @@ -44,5 +44,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix) return -1; } result = run_diff_index(&rev, cached); - return rev.diffopt.exit_with_status ? rev.diffopt.has_changes: result; + if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS)) + return DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0; + return result; } diff --git a/builtin-diff-tree.c b/builtin-diff-tree.c index 0b591c8716..2e13716eec 100644 --- a/builtin-diff-tree.c +++ b/builtin-diff-tree.c @@ -118,8 +118,8 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) } if (!read_stdin) - return opt->diffopt.exit_with_status ? - opt->diffopt.has_changes: 0; + return DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS) + && DIFF_OPT_TST(&opt->diffopt, HAS_CHANGES); if (opt->diffopt.detect_rename) opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE | @@ -134,5 +134,6 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) else diff_tree_stdin(line); } - return opt->diffopt.exit_with_status ? opt->diffopt.has_changes: 0; + return DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS) + && DIFF_OPT_TST(&opt->diffopt, HAS_CHANGES); } diff --git a/builtin-diff.c b/builtin-diff.c index f557d21929..1b615991e1 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -35,7 +35,7 @@ static void stuff_change(struct diff_options *opt, !hashcmp(old_sha1, new_sha1) && (old_mode == new_mode)) return; - if (opt->reverse_diff) { + if (DIFF_OPT_TST(opt, REVERSE_DIFF)) { unsigned tmp; const unsigned char *tmp_u; const char *tmp_c; @@ -253,13 +253,13 @@ int cmd_diff(int argc, const char **argv, const char *prefix) if (diff_setup_done(&rev.diffopt) < 0) die("diff_setup_done failed"); } - rev.diffopt.allow_external = 1; - rev.diffopt.recursive = 1; + DIFF_OPT_SET(&rev.diffopt, ALLOW_EXTERNAL); + DIFF_OPT_SET(&rev.diffopt, RECURSIVE); /* If the user asked for our exit code then don't start a * pager or we would end up reporting its exit code instead. */ - if (!rev.diffopt.exit_with_status) + if (!DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS)) setup_pager(); /* Do we have --cached and not have a pending object, then @@ -363,8 +363,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix) else result = builtin_diff_combined(&rev, argc, argv, ent, ents); - if (rev.diffopt.exit_with_status) - result = rev.diffopt.has_changes; + if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS)) + result = DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0; if (1 < rev.diffopt.skip_stat_unmatch) refresh_index_quietly(); diff --git a/builtin-log.c b/builtin-log.c index 8b2bf632c5..b69b0b42f1 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -55,13 +55,13 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix, rev->abbrev = DEFAULT_ABBREV; rev->commit_format = CMIT_FMT_DEFAULT; rev->verbose_header = 1; - rev->diffopt.recursive = 1; + DIFF_OPT_SET(&rev->diffopt, RECURSIVE); rev->show_root_diff = default_show_root; rev->subject_prefix = fmt_patch_subject_prefix; argc = setup_revisions(argc, argv, rev, "HEAD"); if (rev->diffopt.pickaxe || rev->diffopt.filter) rev->always_show_header = 0; - if (rev->diffopt.follow_renames) { + if (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) { rev->always_show_header = 0; if (rev->diffopt.nr_paths != 1) usage("git logs can only follow renames on one pathname at a time"); @@ -185,11 +185,9 @@ int cmd_show(int argc, const char **argv, const char *prefix) struct tag *t = (struct tag *)o; printf("%stag %s%s\n\n", - diff_get_color(rev.diffopt.color_diff, - DIFF_COMMIT), + diff_get_color_opt(&rev.diffopt, DIFF_COMMIT), t->tag, - diff_get_color(rev.diffopt.color_diff, - DIFF_RESET)); + diff_get_color_opt(&rev.diffopt, DIFF_RESET)); ret = show_object(o->sha1, 1); objects[i].item = (struct object *)t->tagged; i--; @@ -197,11 +195,9 @@ int cmd_show(int argc, const char **argv, const char *prefix) } case OBJ_TREE: printf("%stree %s%s\n\n", - diff_get_color(rev.diffopt.color_diff, - DIFF_COMMIT), + diff_get_color_opt(&rev.diffopt, DIFF_COMMIT), name, - diff_get_color(rev.diffopt.color_diff, - DIFF_RESET)); + diff_get_color_opt(&rev.diffopt, DIFF_RESET)); read_tree_recursive((struct tree *)o, "", 0, 0, NULL, show_tree_object); break; @@ -487,7 +483,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) rev.combine_merges = 0; rev.ignore_merges = 1; rev.diffopt.msg_sep = ""; - rev.diffopt.recursive = 1; + DIFF_OPT_SET(&rev.diffopt, RECURSIVE); rev.subject_prefix = fmt_patch_subject_prefix; rev.extra_headers = extra_headers; @@ -590,8 +586,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH; - if (!rev.diffopt.text) - rev.diffopt.binary = 1; + if (!DIFF_OPT_TST(&rev.diffopt, TEXT)) + DIFF_OPT_SET(&rev.diffopt, BINARY); if (!output_directory && !use_stdout) output_directory = prefix; @@ -747,7 +743,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix) revs.diff = 1; revs.combine_merges = 0; revs.ignore_merges = 1; - revs.diffopt.recursive = 1; + DIFF_OPT_SET(&revs.diffopt, RECURSIVE); if (add_pending_commit(head, &revs, 0)) die("Unknown commit %s", head); diff --git a/combine-diff.c b/combine-diff.c index fe5a2a1953..5a658dc0d5 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -664,7 +664,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, int mode_differs = 0; int i, show_hunks; int working_tree_file = is_null_sha1(elem->sha1); - int abbrev = opt->full_index ? 40 : DEFAULT_ABBREV; + int abbrev = DIFF_OPT_TST(opt, FULL_INDEX) ? 40 : DEFAULT_ABBREV; mmfile_t result_file; context = opt->context; @@ -784,7 +784,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, if (show_hunks || mode_differs || working_tree_file) { const char *abb; - int use_color = opt->color_diff; + int use_color = DIFF_OPT_TST(opt, COLOR_DIFF); const char *c_meta = diff_get_color(use_color, DIFF_METAINFO); const char *c_reset = diff_get_color(use_color, DIFF_RESET); int added = 0; @@ -836,7 +836,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, dump_quoted_path("+++ /dev/", "null", c_meta, c_reset); else dump_quoted_path("+++ b/", elem->path, c_meta, c_reset); - dump_sline(sline, cnt, num_parent, opt->color_diff); + dump_sline(sline, cnt, num_parent, DIFF_OPT_TST(opt, COLOR_DIFF)); } free(result); @@ -929,8 +929,8 @@ void diff_tree_combined(const unsigned char *sha1, diffopts = *opt; diffopts.output_format = DIFF_FORMAT_NO_OUTPUT; - diffopts.recursive = 1; - diffopts.allow_external = 0; + DIFF_OPT_SET(&diffopts, RECURSIVE); + DIFF_OPT_CLR(&diffopts, ALLOW_EXTERNAL); show_log_first = !!rev->loginfo && !rev->no_commit_id; needsep = 0; diff --git a/diff-lib.c b/diff-lib.c index da5571302d..290a170b05 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -121,7 +121,7 @@ static int queue_diff(struct diff_options *o, } else { struct diff_filespec *d1, *d2; - if (o->reverse_diff) { + if (DIFF_OPT_TST(o, REVERSE_DIFF)) { unsigned tmp; const char *tmp_c; tmp = mode1; mode1 = mode2; mode2 = tmp; @@ -188,8 +188,8 @@ static int handle_diff_files_args(struct rev_info *revs, else if (!strcmp(argv[1], "-n") || !strcmp(argv[1], "--no-index")) { revs->max_count = -2; - revs->diffopt.exit_with_status = 1; - revs->diffopt.no_index = 1; + DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); + DIFF_OPT_SET(&revs->diffopt, NO_INDEX); } else if (!strcmp(argv[1], "-q")) *silent = 1; @@ -207,7 +207,7 @@ static int handle_diff_files_args(struct rev_info *revs, if (!is_in_index(revs->diffopt.paths[0]) || !is_in_index(revs->diffopt.paths[1])) { revs->max_count = -2; - revs->diffopt.no_index = 1; + DIFF_OPT_SET(&revs->diffopt, NO_INDEX); } } @@ -258,7 +258,7 @@ int setup_diff_no_index(struct rev_info *revs, break; } else if (i < argc - 3 && !strcmp(argv[i], "--no-index")) { i = argc - 3; - revs->diffopt.exit_with_status = 1; + DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); break; } if (argc != i + 2 || (!is_outside_repo(argv[i + 1], nongit, prefix) && @@ -296,7 +296,7 @@ int setup_diff_no_index(struct rev_info *revs, else revs->diffopt.paths = argv + argc - 2; revs->diffopt.nr_paths = 2; - revs->diffopt.no_index = 1; + DIFF_OPT_SET(&revs->diffopt, NO_INDEX); revs->max_count = -2; if (diff_setup_done(&revs->diffopt) < 0) die("diff_setup_done failed"); @@ -310,7 +310,7 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) if (handle_diff_files_args(revs, argc, argv, &silent_on_removed)) return -1; - if (revs->diffopt.no_index) { + if (DIFF_OPT_TST(&revs->diffopt, NO_INDEX)) { if (revs->diffopt.nr_paths != 2) return error("need two files/directories with --no-index"); if (queue_diff(&revs->diffopt, revs->diffopt.paths[0], @@ -346,7 +346,8 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed) struct cache_entry *ce = active_cache[i]; int changed; - if (revs->diffopt.quiet && revs->diffopt.has_changes) + if (DIFF_OPT_TST(&revs->diffopt, QUIET) && + DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES)) break; if (!ce_path_match(ce, revs->prune_data)) @@ -442,7 +443,7 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed) continue; } changed = ce_match_stat(ce, &st, 0); - if (!changed && !revs->diffopt.find_copies_harder) + if (!changed && !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER)) continue; oldmode = ntohl(ce->ce_mode); newmode = ntohl(ce_mode_from_stat(ce, st.st_mode)); @@ -561,7 +562,7 @@ static int show_modified(struct rev_info *revs, oldmode = old->ce_mode; if (mode == oldmode && !hashcmp(sha1, old->sha1) && - !revs->diffopt.find_copies_harder) + !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER)) return 0; mode = ntohl(mode); @@ -581,7 +582,8 @@ static int diff_cache(struct rev_info *revs, struct cache_entry *ce = *ac; int same = (entries > 1) && ce_same_name(ce, ac[1]); - if (revs->diffopt.quiet && revs->diffopt.has_changes) + if (DIFF_OPT_TST(&revs->diffopt, QUIET) && + DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES)) break; if (!ce_path_match(ce, pathspec)) diff --git a/diff.c b/diff.c index a6aaaf7e5a..67cce8b72e 100644 --- a/diff.c +++ b/diff.c @@ -814,10 +814,10 @@ static void show_stats(struct diffstat_t* data, struct diff_options *options) } /* Find the longest filename and max number of changes */ - reset = diff_get_color(options->color_diff, DIFF_RESET); - set = diff_get_color(options->color_diff, DIFF_PLAIN); - add_c = diff_get_color(options->color_diff, DIFF_FILE_NEW); - del_c = diff_get_color(options->color_diff, DIFF_FILE_OLD); + reset = diff_get_color_opt(options, DIFF_RESET); + set = diff_get_color_opt(options, DIFF_PLAIN); + add_c = diff_get_color_opt(options, DIFF_FILE_NEW); + del_c = diff_get_color_opt(options, DIFF_FILE_OLD); for (i = 0; i < data->nr; i++) { struct diffstat_file *file = data->files[i]; @@ -1243,8 +1243,8 @@ static void builtin_diff(const char *name_a, mmfile_t mf1, mf2; const char *lbl[2]; char *a_one, *b_two; - const char *set = diff_get_color(o->color_diff, DIFF_METAINFO); - const char *reset = diff_get_color(o->color_diff, DIFF_RESET); + const char *set = diff_get_color_opt(o, DIFF_METAINFO); + const char *reset = diff_get_color_opt(o, DIFF_RESET); a_one = quote_two("a/", name_a + (*name_a == '/')); b_two = quote_two("b/", name_b + (*name_b == '/')); @@ -1277,7 +1277,7 @@ static void builtin_diff(const char *name_a, goto free_ab_and_return; if (complete_rewrite) { emit_rewrite_diff(name_a, name_b, one, two, - o->color_diff); + DIFF_OPT_TST(o, COLOR_DIFF)); o->found_changes = 1; goto free_ab_and_return; } @@ -1286,13 +1286,13 @@ static void builtin_diff(const char *name_a, if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0) die("unable to read files to diff"); - if (!o->text && + if (!DIFF_OPT_TST(o, TEXT) && (diff_filespec_is_binary(one) || diff_filespec_is_binary(two))) { /* Quite common confusing case */ if (mf1.size == mf2.size && !memcmp(mf1.ptr, mf2.ptr, mf1.size)) goto free_ab_and_return; - if (o->binary) + if (DIFF_OPT_TST(o, BINARY)) emit_binary_diff(&mf1, &mf2); else printf("Binary files %s and %s differ\n", @@ -1315,7 +1315,7 @@ static void builtin_diff(const char *name_a, memset(&xecfg, 0, sizeof(xecfg)); memset(&ecbdata, 0, sizeof(ecbdata)); ecbdata.label_path = lbl; - ecbdata.color_diff = o->color_diff; + ecbdata.color_diff = DIFF_OPT_TST(o, COLOR_DIFF); ecbdata.found_changesp = &o->found_changes; xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts; xecfg.ctxlen = o->context; @@ -1331,11 +1331,11 @@ static void builtin_diff(const char *name_a, ecb.outf = xdiff_outf; ecb.priv = &ecbdata; ecbdata.xm.consume = fn_out_consume; - if (o->color_diff_words) + if (DIFF_OPT_TST(o, COLOR_DIFF_WORDS)) ecbdata.diff_words = xcalloc(1, sizeof(struct diff_words_data)); xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb); - if (o->color_diff_words) + if (DIFF_OPT_TST(o, COLOR_DIFF_WORDS)) free_diff_words_data(&ecbdata); } @@ -1409,7 +1409,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b, data.xm.consume = checkdiff_consume; data.filename = name_b ? name_b : name_a; data.lineno = 0; - data.color_diff = o->color_diff; + data.color_diff = DIFF_OPT_TST(o, COLOR_DIFF); if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0) die("unable to read files to diff"); @@ -1853,7 +1853,7 @@ static void run_diff_cmd(const char *pgm, struct diff_options *o, int complete_rewrite) { - if (!o->allow_external) + if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL)) pgm = NULL; else { const char *cmd = external_diff_attr(name); @@ -1951,9 +1951,9 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o) } if (hashcmp(one->sha1, two->sha1)) { - int abbrev = o->full_index ? 40 : DEFAULT_ABBREV; + int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV; - if (o->binary) { + if (DIFF_OPT_TST(o, BINARY)) { mmfile_t mf; if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) || (!fill_mmfile(&mf, two) && diff_filespec_is_binary(two))) @@ -2045,7 +2045,10 @@ void diff_setup(struct diff_options *options) options->change = diff_change; options->add_remove = diff_addremove; - options->color_diff = diff_use_color_default; + if (diff_use_color_default) + DIFF_OPT_SET(options, COLOR_DIFF); + else + DIFF_OPT_CLR(options, COLOR_DIFF); options->detect_rename = diff_detect_rename_default; } @@ -2064,7 +2067,7 @@ int diff_setup_done(struct diff_options *options) if (count > 1) die("--name-only, --name-status, --check and -s are mutually exclusive"); - if (options->find_copies_harder) + if (DIFF_OPT_TST(options, FIND_COPIES_HARDER)) options->detect_rename = DIFF_DETECT_COPY; if (options->output_format & (DIFF_FORMAT_NAME | @@ -2088,12 +2091,12 @@ int diff_setup_done(struct diff_options *options) DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_CHECKDIFF)) - options->recursive = 1; + DIFF_OPT_SET(options, RECURSIVE); /* * Also pickaxe would not work very well if you do not say recursive */ if (options->pickaxe) - options->recursive = 1; + DIFF_OPT_SET(options, RECURSIVE); if (options->detect_rename && options->rename_limit < 0) options->rename_limit = diff_rename_limit_default; @@ -2115,9 +2118,9 @@ int diff_setup_done(struct diff_options *options) * to have found. It does not make sense not to return with * exit code in such a case either. */ - if (options->quiet) { + if (DIFF_OPT_TST(options, QUIET)) { options->output_format = DIFF_FORMAT_NO_OUTPUT; - options->exit_with_status = 1; + DIFF_OPT_SET(options, EXIT_WITH_STATUS); } /* @@ -2125,7 +2128,7 @@ int diff_setup_done(struct diff_options *options) * upon the first hit. We need to run diff as usual. */ if (options->pickaxe || options->filter) - options->quiet = 0; + DIFF_OPT_CLR(options, QUIET); return 0; } @@ -2188,15 +2191,12 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) options->output_format |= DIFF_FORMAT_PATCH; else if (!strcmp(arg, "--raw")) options->output_format |= DIFF_FORMAT_RAW; - else if (!strcmp(arg, "--patch-with-raw")) { + else if (!strcmp(arg, "--patch-with-raw")) options->output_format |= DIFF_FORMAT_PATCH | DIFF_FORMAT_RAW; - } - else if (!strcmp(arg, "--numstat")) { + else if (!strcmp(arg, "--numstat")) options->output_format |= DIFF_FORMAT_NUMSTAT; - } - else if (!strcmp(arg, "--shortstat")) { + else if (!strcmp(arg, "--shortstat")) options->output_format |= DIFF_FORMAT_SHORTSTAT; - } else if (!prefixcmp(arg, "--stat")) { char *end; int width = options->stat_width; @@ -2228,33 +2228,30 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) options->output_format |= DIFF_FORMAT_CHECKDIFF; else if (!strcmp(arg, "--summary")) options->output_format |= DIFF_FORMAT_SUMMARY; - else if (!strcmp(arg, "--patch-with-stat")) { + else if (!strcmp(arg, "--patch-with-stat")) options->output_format |= DIFF_FORMAT_PATCH | DIFF_FORMAT_DIFFSTAT; - } else if (!strcmp(arg, "-z")) options->line_termination = 0; else if (!prefixcmp(arg, "-l")) options->rename_limit = strtoul(arg+2, NULL, 10); else if (!strcmp(arg, "--full-index")) - options->full_index = 1; + DIFF_OPT_SET(options, FULL_INDEX); else if (!strcmp(arg, "--binary")) { options->output_format |= DIFF_FORMAT_PATCH; - options->binary = 1; - } - else if (!strcmp(arg, "-a") || !strcmp(arg, "--text")) { - options->text = 1; + DIFF_OPT_SET(options, BINARY); } + else if (!strcmp(arg, "-a") || !strcmp(arg, "--text")) + DIFF_OPT_SET(options, TEXT); else if (!strcmp(arg, "--name-only")) options->output_format |= DIFF_FORMAT_NAME; else if (!strcmp(arg, "--name-status")) options->output_format |= DIFF_FORMAT_NAME_STATUS; else if (!strcmp(arg, "-R")) - options->reverse_diff = 1; + DIFF_OPT_SET(options, REVERSE_DIFF); else if (!prefixcmp(arg, "-S")) options->pickaxe = arg + 2; - else if (!strcmp(arg, "-s")) { + else if (!strcmp(arg, "-s")) options->output_format |= DIFF_FORMAT_NO_OUTPUT; - } else if (!prefixcmp(arg, "-O")) options->orderfile = arg + 2; else if (!prefixcmp(arg, "--diff-filter=")) @@ -2264,28 +2261,25 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) else if (!strcmp(arg, "--pickaxe-regex")) options->pickaxe_opts = DIFF_PICKAXE_REGEX; else if (!prefixcmp(arg, "-B")) { - if ((options->break_opt = - diff_scoreopt_parse(arg)) == -1) + if ((options->break_opt = diff_scoreopt_parse(arg)) == -1) return -1; } else if (!prefixcmp(arg, "-M")) { - if ((options->rename_score = - diff_scoreopt_parse(arg)) == -1) + if ((options->rename_score = diff_scoreopt_parse(arg)) == -1) return -1; options->detect_rename = DIFF_DETECT_RENAME; } else if (!prefixcmp(arg, "-C")) { if (options->detect_rename == DIFF_DETECT_COPY) - options->find_copies_harder = 1; - if ((options->rename_score = - diff_scoreopt_parse(arg)) == -1) + DIFF_OPT_SET(options, FIND_COPIES_HARDER); + if ((options->rename_score = diff_scoreopt_parse(arg)) == -1) return -1; options->detect_rename = DIFF_DETECT_COPY; } else if (!strcmp(arg, "--find-copies-harder")) - options->find_copies_harder = 1; + DIFF_OPT_SET(options, FIND_COPIES_HARDER); else if (!strcmp(arg, "--follow")) - options->follow_renames = 1; + DIFF_OPT_SET(options, FOLLOW_RENAMES); else if (!strcmp(arg, "--abbrev")) options->abbrev = DEFAULT_ABBREV; else if (!prefixcmp(arg, "--abbrev=")) { @@ -2296,9 +2290,9 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) options->abbrev = 40; } else if (!strcmp(arg, "--color")) - options->color_diff = 1; + DIFF_OPT_SET(options, COLOR_DIFF); else if (!strcmp(arg, "--no-color")) - options->color_diff = 0; + DIFF_OPT_CLR(options, COLOR_DIFF); else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space")) options->xdl_opts |= XDF_IGNORE_WHITESPACE; else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change")) @@ -2306,17 +2300,17 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) else if (!strcmp(arg, "--ignore-space-at-eol")) options->xdl_opts |= XDF_IGNORE_WHITESPACE_AT_EOL; else if (!strcmp(arg, "--color-words")) - options->color_diff = options->color_diff_words = 1; + options->flags |= DIFF_OPT_COLOR_DIFF | DIFF_OPT_COLOR_DIFF_WORDS; else if (!strcmp(arg, "--no-renames")) options->detect_rename = 0; else if (!strcmp(arg, "--exit-code")) - options->exit_with_status = 1; + DIFF_OPT_SET(options, EXIT_WITH_STATUS); else if (!strcmp(arg, "--quiet")) - options->quiet = 1; + DIFF_OPT_SET(options, QUIET); else if (!strcmp(arg, "--ext-diff")) - options->allow_external = 1; + DIFF_OPT_SET(options, ALLOW_EXTERNAL); else if (!strcmp(arg, "--no-ext-diff")) - options->allow_external = 0; + DIFF_OPT_CLR(options, ALLOW_EXTERNAL); else return 0; return 1; @@ -3071,7 +3065,7 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt) * to determine how many paths were dirty only * due to stat info mismatch. */ - if (!diffopt->no_index) + if (!DIFF_OPT_TST(diffopt, NO_INDEX)) diffopt->skip_stat_unmatch++; diff_free_filepair(p); } @@ -3082,10 +3076,10 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt) void diffcore_std(struct diff_options *options) { - if (options->quiet) + if (DIFF_OPT_TST(options, QUIET)) return; - if (options->skip_stat_unmatch && !options->find_copies_harder) + if (options->skip_stat_unmatch && !DIFF_OPT_TST(options, FIND_COPIES_HARDER)) diffcore_skip_stat_unmatch(options); if (options->break_opt != -1) diffcore_break(options->break_opt); @@ -3100,7 +3094,10 @@ void diffcore_std(struct diff_options *options) diff_resolve_rename_copy(); diffcore_apply_filter(options->filter); - options->has_changes = !!diff_queued_diff.nr; + if (diff_queued_diff.nr) + DIFF_OPT_SET(options, HAS_CHANGES); + else + DIFF_OPT_CLR(options, HAS_CHANGES); } @@ -3124,7 +3121,7 @@ void diff_addremove(struct diff_options *options, * Before the final output happens, they are pruned after * merged into rename/copy pairs as appropriate. */ - if (options->reverse_diff) + if (DIFF_OPT_TST(options, REVERSE_DIFF)) addremove = (addremove == '+' ? '-' : addremove == '-' ? '+' : addremove); @@ -3139,7 +3136,7 @@ void diff_addremove(struct diff_options *options, fill_filespec(two, sha1, mode); diff_queue(&diff_queued_diff, one, two); - options->has_changes = 1; + DIFF_OPT_SET(options, HAS_CHANGES); } void diff_change(struct diff_options *options, @@ -3151,7 +3148,7 @@ void diff_change(struct diff_options *options, char concatpath[PATH_MAX]; struct diff_filespec *one, *two; - if (options->reverse_diff) { + if (DIFF_OPT_TST(options, REVERSE_DIFF)) { unsigned tmp; const unsigned char *tmp_c; tmp = old_mode; old_mode = new_mode; new_mode = tmp; @@ -3165,7 +3162,7 @@ void diff_change(struct diff_options *options, fill_filespec(two, new_sha1, new_mode); diff_queue(&diff_queued_diff, one, two); - options->has_changes = 1; + DIFF_OPT_SET(options, HAS_CHANGES); } void diff_unmerge(struct diff_options *options, diff --git a/diff.h b/diff.h index 4546aad219..6ff2b0e318 100644 --- a/diff.h +++ b/diff.h @@ -43,26 +43,32 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q, #define DIFF_FORMAT_CALLBACK 0x1000 +#define DIFF_OPT_RECURSIVE (1 << 0) +#define DIFF_OPT_TREE_IN_RECURSIVE (1 << 1) +#define DIFF_OPT_BINARY (1 << 2) +#define DIFF_OPT_TEXT (1 << 3) +#define DIFF_OPT_FULL_INDEX (1 << 4) +#define DIFF_OPT_SILENT_ON_REMOVE (1 << 5) +#define DIFF_OPT_FIND_COPIES_HARDER (1 << 6) +#define DIFF_OPT_FOLLOW_RENAMES (1 << 7) +#define DIFF_OPT_COLOR_DIFF (1 << 8) +#define DIFF_OPT_COLOR_DIFF_WORDS (1 << 9) +#define DIFF_OPT_HAS_CHANGES (1 << 10) +#define DIFF_OPT_QUIET (1 << 11) +#define DIFF_OPT_NO_INDEX (1 << 12) +#define DIFF_OPT_ALLOW_EXTERNAL (1 << 13) +#define DIFF_OPT_EXIT_WITH_STATUS (1 << 14) +#define DIFF_OPT_REVERSE_DIFF (1 << 15) +#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag) +#define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag) +#define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag) + struct diff_options { const char *filter; const char *orderfile; const char *pickaxe; const char *single_follow; - unsigned recursive:1, - tree_in_recursive:1, - binary:1, - text:1, - full_index:1, - silent_on_remove:1, - find_copies_harder:1, - follow_renames:1, - color_diff:1, - color_diff_words:1, - has_changes:1, - quiet:1, - no_index:1, - allow_external:1, - exit_with_status:1; + unsigned flags; int context; int break_opt; int detect_rename; @@ -71,7 +77,6 @@ struct diff_options { int output_format; int pickaxe_opts; int rename_score; - int reverse_diff; int rename_limit; int setup; int abbrev; @@ -105,6 +110,9 @@ enum color_diff { DIFF_WHITESPACE = 7, }; const char *diff_get_color(int diff_use_color, enum color_diff ix); +#define diff_get_color_opt(o, ix) \ + diff_get_color(DIFF_OPT_TST((o), COLOR_DIFF), ix) + extern const char mime_boundary_leader[]; diff --git a/log-tree.c b/log-tree.c index a34beb0b02..1f3fcf16ad 100644 --- a/log-tree.c +++ b/log-tree.c @@ -245,8 +245,7 @@ void show_log(struct rev_info *opt, const char *sep) opt->diffopt.stat_sep = buffer; } } else if (opt->commit_format != CMIT_FMT_USERFORMAT) { - fputs(diff_get_color(opt->diffopt.color_diff, DIFF_COMMIT), - stdout); + fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout); if (opt->commit_format != CMIT_FMT_ONELINE) fputs("commit ", stdout); if (commit->object.flags & BOUNDARY) @@ -266,8 +265,7 @@ void show_log(struct rev_info *opt, const char *sep) diff_unique_abbrev(parent->object.sha1, abbrev_commit)); show_decorations(commit); - printf("%s", - diff_get_color(opt->diffopt.color_diff, DIFF_RESET)); + printf("%s", diff_get_color_opt(&opt->diffopt, DIFF_RESET)); putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n'); if (opt->reflog_info) { show_reflog_message(opt->reflog_info, diff --git a/merge-recursive.c b/merge-recursive.c index 6c6f595fbc..9a1e2f269d 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -366,7 +366,7 @@ static struct path_list *get_renames(struct tree *tree, renames = xcalloc(1, sizeof(struct path_list)); diff_setup(&opts); - opts.recursive = 1; + DIFF_OPT_SET(&opts, RECURSIVE); opts.detect_rename = DIFF_DETECT_RENAME; opts.rename_limit = rename_limit; opts.output_format = DIFF_FORMAT_NO_OUTPUT; diff --git a/patch-ids.c b/patch-ids.c index a288fac992..3be5d3165e 100644 --- a/patch-ids.c +++ b/patch-ids.c @@ -121,7 +121,7 @@ int init_patch_ids(struct patch_ids *ids) { memset(ids, 0, sizeof(*ids)); diff_setup(&ids->diffopts); - ids->diffopts.recursive = 1; + DIFF_OPT_SET(&ids->diffopts, RECURSIVE); if (diff_setup_done(&ids->diffopts) < 0) return error("diff_setup_done failed"); return 0; diff --git a/revision.c b/revision.c index e76da0d448..f5b0e83ee3 100644 --- a/revision.c +++ b/revision.c @@ -250,7 +250,7 @@ static void file_add_remove(struct diff_options *options, } tree_difference = diff; if (tree_difference == REV_TREE_DIFFERENT) - options->has_changes = 1; + DIFF_OPT_SET(options, HAS_CHANGES); } static void file_change(struct diff_options *options, @@ -260,7 +260,7 @@ static void file_change(struct diff_options *options, const char *base, const char *path) { tree_difference = REV_TREE_DIFFERENT; - options->has_changes = 1; + DIFF_OPT_SET(options, HAS_CHANGES); } static int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree *t2) @@ -270,7 +270,7 @@ static int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree if (!t2) return REV_TREE_DIFFERENT; tree_difference = REV_TREE_SAME; - revs->pruning.has_changes = 0; + DIFF_OPT_CLR(&revs->pruning, HAS_CHANGES); if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "", &revs->pruning) < 0) return REV_TREE_DIFFERENT; @@ -294,7 +294,7 @@ static int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1) init_tree_desc(&empty, "", 0); tree_difference = REV_TREE_SAME; - revs->pruning.has_changes = 0; + DIFF_OPT_CLR(&revs->pruning, HAS_CHANGES); retval = diff_tree(&empty, &real, "", &revs->pruning); free(tree); @@ -662,8 +662,8 @@ void init_revisions(struct rev_info *revs, const char *prefix) revs->abbrev = DEFAULT_ABBREV; revs->ignore_merges = 1; revs->simplify_history = 1; - revs->pruning.recursive = 1; - revs->pruning.quiet = 1; + DIFF_OPT_SET(&revs->pruning, RECURSIVE); + DIFF_OPT_SET(&revs->pruning, QUIET); revs->pruning.add_remove = file_add_remove; revs->pruning.change = file_change; revs->lifo = 1; @@ -1054,13 +1054,13 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch } if (!strcmp(arg, "-r")) { revs->diff = 1; - revs->diffopt.recursive = 1; + DIFF_OPT_SET(&revs->diffopt, RECURSIVE); continue; } if (!strcmp(arg, "-t")) { revs->diff = 1; - revs->diffopt.recursive = 1; - revs->diffopt.tree_in_recursive = 1; + DIFF_OPT_SET(&revs->diffopt, RECURSIVE); + DIFF_OPT_SET(&revs->diffopt, TREE_IN_RECURSIVE); continue; } if (!strcmp(arg, "-m")) { @@ -1242,7 +1242,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch revs->diff = 1; /* Pickaxe and rename following needs diffs */ - if (revs->diffopt.pickaxe || revs->diffopt.follow_renames) + if (revs->diffopt.pickaxe || DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES)) revs->diff = 1; if (revs->topo_order) @@ -1251,7 +1251,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch if (revs->prune_data) { diff_tree_setup_paths(revs->prune_data, &revs->pruning); /* Can't prune commits with rename following: the paths change.. */ - if (!revs->diffopt.follow_renames) + if (!DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES)) revs->prune_fn = try_to_simplify_commit; if (!revs->full_diff) diff_tree_setup_paths(revs->prune_data, &revs->diffopt); diff --git a/tree-diff.c b/tree-diff.c index 7c261fd7c3..aa0a100295 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -39,7 +39,7 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const show_entry(opt, "+", t2, base, baselen); return 1; } - if (!opt->find_copies_harder && !hashcmp(sha1, sha2) && mode1 == mode2) + if (!DIFF_OPT_TST(opt, FIND_COPIES_HARDER) && !hashcmp(sha1, sha2) && mode1 == mode2) return 0; /* @@ -52,10 +52,10 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const return 0; } - if (opt->recursive && S_ISDIR(mode1)) { + if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode1)) { int retval; char *newbase = malloc_base(base, baselen, path1, pathlen1); - if (opt->tree_in_recursive) + if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) opt->change(opt, mode1, mode2, sha1, sha2, base, path1); retval = diff_tree_sha1(sha1, sha2, newbase, opt); @@ -206,7 +206,7 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree const char *path; const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode); - if (opt->recursive && S_ISDIR(mode)) { + if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode)) { enum object_type type; int pathlen = tree_entry_len(path, sha1); char *newbase = malloc_base(base, baselen, path, pathlen); @@ -257,7 +257,7 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, stru int baselen = strlen(base); for (;;) { - if (opt->quiet && opt->has_changes) + if (DIFF_OPT_TST(opt, QUIET) && DIFF_OPT_TST(opt, HAS_CHANGES)) break; if (opt->nr_paths) { skip_uninteresting(t1, base, baselen, opt); @@ -315,7 +315,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co q->nr = 0; diff_setup(&diff_opts); - diff_opts.recursive = 1; + DIFF_OPT_SET(&diff_opts, RECURSIVE); diff_opts.detect_rename = DIFF_DETECT_RENAME; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; diff_opts.single_follow = opt->paths[0]; @@ -380,7 +380,7 @@ int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const cha init_tree_desc(&t1, tree1, size1); init_tree_desc(&t2, tree2, size2); retval = diff_tree(&t1, &t2, base, opt); - if (opt->follow_renames && diff_might_be_rename()) { + if (DIFF_OPT_TST(opt, FOLLOW_RENAMES) && diff_might_be_rename()) { init_tree_desc(&t1, tree1, size1); init_tree_desc(&t2, tree2, size2); try_to_follow_renames(&t1, &t2, base, opt); -- cgit v1.3 From 03b69c7606267bc978c69cf88fcd7a8edf8175bc Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 11 Dec 2007 22:59:55 +0100 Subject: Fix small memory leaks induced by diff_tree_setup_paths Run diff_tree_release_paths in the appropriate places, and add a test to avoid NULL dereference. Better safe than sorry. Signed-off-by: Mike Hommey Signed-off-by: Junio C Hamano --- builtin-blame.c | 4 +++- builtin-reset.c | 1 + tree-diff.c | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'tree-diff.c') diff --git a/builtin-blame.c b/builtin-blame.c index eda79d0f00..5466d01f9a 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -388,6 +388,7 @@ static struct origin *find_origin(struct scoreboard *sb, } } diff_flush(&diff_opts); + diff_tree_release_paths(&diff_opts); if (porigin) { /* * Create a freestanding copy that is not part of @@ -444,6 +445,7 @@ static struct origin *find_rename(struct scoreboard *sb, } } diff_flush(&diff_opts); + diff_tree_release_paths(&diff_opts); return porigin; } @@ -1165,7 +1167,7 @@ static int find_copy_in_parent(struct scoreboard *sb, } } diff_flush(&diff_opts); - + diff_tree_release_paths(&diff_opts); return retval; } diff --git a/builtin-reset.c b/builtin-reset.c index 4c61025aae..713c2d5346 100644 --- a/builtin-reset.c +++ b/builtin-reset.c @@ -158,6 +158,7 @@ static int read_from_tree(const char *prefix, const char **argv, return 1; diffcore_std(&opt); diff_flush(&opt); + diff_tree_release_paths(&opt); if (!index_was_discarded) /* The index is still clobbered from do_diff_cache() */ diff --git a/tree-diff.c b/tree-diff.c index aa0a100295..e1e2e6c6ce 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -326,6 +326,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co die("unable to set up diff options to follow renames"); diff_tree(t1, t2, base, &diff_opts); diffcore_std(&diff_opts); + diff_tree_release_paths(&diff_opts); /* Go through the new set of filepairing, and see if we find a more interesting one */ for (i = 0; i < q->nr; i++) { @@ -342,6 +343,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co choice = p; /* Update the path we use from now on.. */ + diff_tree_release_paths(opt); opt->paths[0] = xstrdup(p->one->path); diff_tree_setup_paths(opt->paths, opt); break; -- cgit v1.3 From fd55a19eb1d49ae54008d932a65f79cd6fda45c9 Mon Sep 17 00:00:00 2001 From: Dmitry Potapov Date: Wed, 16 Jul 2008 18:54:02 +0400 Subject: Fix buffer overflow in git diff If PATH_MAX on your system is smaller than a path stored, it may cause buffer overflow and stack corruption in diff_addremove() and diff_change() functions when running git-diff Signed-off-by: Dmitry Potapov Signed-off-by: Junio C Hamano --- diff-lib.c | 8 ++++---- diff.c | 11 ++--------- diff.h | 9 ++++----- revision.c | 4 ++-- tree-diff.c | 27 ++++++++++++++++++++++----- 5 files changed, 34 insertions(+), 25 deletions(-) (limited to 'tree-diff.c') diff --git a/diff-lib.c b/diff-lib.c index b17722d66a..e7eaff9a68 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -171,7 +171,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) if (silent_on_removed) continue; diff_addremove(&revs->diffopt, '-', ce->ce_mode, - ce->sha1, ce->name, NULL); + ce->sha1, ce->name); continue; } changed = ce_match_stat(ce, &st, ce_option); @@ -184,7 +184,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) newmode = ce_mode_from_stat(ce, st.st_mode); diff_change(&revs->diffopt, oldmode, newmode, ce->sha1, (changed ? null_sha1 : ce->sha1), - ce->name, NULL); + ce->name); } diffcore_std(&revs->diffopt); @@ -208,7 +208,7 @@ static void diff_index_show_file(struct rev_info *revs, const unsigned char *sha1, unsigned int mode) { diff_addremove(&revs->diffopt, prefix[0], mode, - sha1, ce->name, NULL); + sha1, ce->name); } static int get_stat_data(struct cache_entry *ce, @@ -312,7 +312,7 @@ static int show_modified(struct oneway_unpack_data *cbdata, return 0; diff_change(&revs->diffopt, oldmode, mode, - old->sha1, sha1, old->name, NULL); + old->sha1, sha1, old->name); return 0; } diff --git a/diff.c b/diff.c index 78c4d3a35a..386de826d3 100644 --- a/diff.c +++ b/diff.c @@ -3356,9 +3356,8 @@ int diff_result_code(struct diff_options *opt, int status) void diff_addremove(struct diff_options *options, int addremove, unsigned mode, const unsigned char *sha1, - const char *base, const char *path) + const char *concatpath) { - char concatpath[PATH_MAX]; struct diff_filespec *one, *two; if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(mode)) @@ -3380,9 +3379,6 @@ void diff_addremove(struct diff_options *options, addremove = (addremove == '+' ? '-' : addremove == '-' ? '+' : addremove); - if (!path) path = ""; - sprintf(concatpath, "%s%s", base, path); - if (options->prefix && strncmp(concatpath, options->prefix, options->prefix_length)) return; @@ -3403,9 +3399,8 @@ void diff_change(struct diff_options *options, unsigned old_mode, unsigned new_mode, const unsigned char *old_sha1, const unsigned char *new_sha1, - const char *base, const char *path) + const char *concatpath) { - char concatpath[PATH_MAX]; struct diff_filespec *one, *two; if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(old_mode) @@ -3418,8 +3413,6 @@ void diff_change(struct diff_options *options, tmp = old_mode; old_mode = new_mode; new_mode = tmp; tmp_c = old_sha1; old_sha1 = new_sha1; new_sha1 = tmp_c; } - if (!path) path = ""; - sprintf(concatpath, "%s%s", base, path); if (options->prefix && strncmp(concatpath, options->prefix, options->prefix_length)) diff --git a/diff.h b/diff.h index 5dc0cb595b..50fb5ddb0b 100644 --- a/diff.h +++ b/diff.h @@ -14,12 +14,12 @@ typedef void (*change_fn_t)(struct diff_options *options, unsigned old_mode, unsigned new_mode, const unsigned char *old_sha1, const unsigned char *new_sha1, - const char *base, const char *path); + const char *fullpath); typedef void (*add_remove_fn_t)(struct diff_options *options, int addremove, unsigned mode, const unsigned char *sha1, - const char *base, const char *path); + const char *fullpath); typedef void (*diff_format_fn_t)(struct diff_queue_struct *q, struct diff_options *options, void *data); @@ -164,14 +164,13 @@ extern void diff_addremove(struct diff_options *, int addremove, unsigned mode, const unsigned char *sha1, - const char *base, - const char *path); + const char *fullpath); extern void diff_change(struct diff_options *, unsigned mode1, unsigned mode2, const unsigned char *sha1, const unsigned char *sha2, - const char *base, const char *path); + const char *fullpath); extern void diff_unmerge(struct diff_options *, const char *path, diff --git a/revision.c b/revision.c index fc66755259..8dc3ca7bf6 100644 --- a/revision.c +++ b/revision.c @@ -259,7 +259,7 @@ static int tree_difference = REV_TREE_SAME; static void file_add_remove(struct diff_options *options, int addremove, unsigned mode, const unsigned char *sha1, - const char *base, const char *path) + const char *fullpath) { int diff = REV_TREE_DIFFERENT; @@ -285,7 +285,7 @@ static void file_change(struct diff_options *options, unsigned old_mode, unsigned new_mode, const unsigned char *old_sha1, const unsigned char *new_sha1, - const char *base, const char *path) + const char *fullpath) { tree_difference = REV_TREE_DIFFERENT; DIFF_OPT_SET(options, HAS_CHANGES); diff --git a/tree-diff.c b/tree-diff.c index e1e2e6c6ce..bbb126fc46 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -15,6 +15,15 @@ static char *malloc_base(const char *base, int baselen, const char *path, int pa return newbase; } +static char *malloc_fullname(const char *base, int baselen, const char *path, int pathlen) +{ + char *fullname = xmalloc(baselen + pathlen + 1); + memcpy(fullname, base, baselen); + memcpy(fullname + baselen, path, pathlen); + fullname[baselen + pathlen] = 0; + return fullname; +} + static void show_entry(struct diff_options *opt, const char *prefix, struct tree_desc *desc, const char *base, int baselen); @@ -24,6 +33,7 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const const char *path1, *path2; const unsigned char *sha1, *sha2; int cmp, pathlen1, pathlen2; + char *fullname; sha1 = tree_entry_extract(t1, &path1, &mode1); sha2 = tree_entry_extract(t2, &path2, &mode2); @@ -55,15 +65,20 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode1)) { int retval; char *newbase = malloc_base(base, baselen, path1, pathlen1); - if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) + if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) { + newbase[baselen + pathlen1] = 0; opt->change(opt, mode1, mode2, - sha1, sha2, base, path1); + sha1, sha2, newbase); + newbase[baselen + pathlen1] = '/'; + } retval = diff_tree_sha1(sha1, sha2, newbase, opt); free(newbase); return retval; } - opt->change(opt, mode1, mode2, sha1, sha2, base, path1); + fullname = malloc_fullname(base, baselen, path1, pathlen1); + opt->change(opt, mode1, mode2, sha1, sha2, fullname); + free(fullname); return 0; } @@ -205,10 +220,10 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree unsigned mode; const char *path; const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode); + int pathlen = tree_entry_len(path, sha1); if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode)) { enum object_type type; - int pathlen = tree_entry_len(path, sha1); char *newbase = malloc_base(base, baselen, path, pathlen); struct tree_desc inner; void *tree; @@ -224,7 +239,9 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree free(tree); free(newbase); } else { - opt->add_remove(opt, prefix[0], mode, sha1, base, path); + char *fullname = malloc_fullname(base, baselen, path, pathlen); + opt->add_remove(opt, prefix[0], mode, sha1, fullname); + free(fullname); } } -- cgit v1.3 From 7e44c93558e7c0b12624d76cf07753d0480ed96a Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 31 Aug 2008 09:39:19 -0700 Subject: 'git foo' program identifies itself without dash in die() messages This is a mechanical conversion of all '*.c' files with: s/((?:die|error|warning)\("git)-(\S+:)/$1 $2/; The result was manually inspected and no false positive was found. Signed-off-by: Junio C Hamano --- builtin-apply.c | 6 +++--- builtin-checkout-index.c | 6 +++--- builtin-commit-tree.c | 2 +- builtin-fetch-pack.c | 2 +- builtin-grep.c | 2 +- builtin-ls-files.c | 6 +++--- builtin-rm.c | 4 ++-- builtin-show-ref.c | 6 +++--- builtin-tar-tree.c | 4 ++-- builtin-update-index.c | 16 ++++++++-------- connect.c | 4 ++-- entry.c | 20 ++++++++++---------- merge-index.c | 6 +++--- tree-diff.c | 2 +- upload-pack.c | 18 +++++++++--------- 15 files changed, 52 insertions(+), 52 deletions(-) (limited to 'tree-diff.c') diff --git a/builtin-apply.c b/builtin-apply.c index 40eeabb625..4eb263ec58 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -506,17 +506,17 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, name = orig_name; len = strlen(name); if (isnull) - die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr); + die("git apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr); another = find_name(line, NULL, p_value, TERM_TAB); if (!another || memcmp(another, name, len)) - die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr); + die("git apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr); free(another); return orig_name; } else { /* expect "/dev/null" */ if (memcmp("/dev/null", line, 9) || line[9] != '\n') - die("git-apply: bad git-diff - expected /dev/null on line %d", linenr); + die("git apply: bad git-diff - expected /dev/null on line %d", linenr); return NULL; } } diff --git a/builtin-checkout-index.c b/builtin-checkout-index.c index 71ebabf990..90f8523eb5 100644 --- a/builtin-checkout-index.c +++ b/builtin-checkout-index.c @@ -258,9 +258,9 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix) const char *p; if (all) - die("git-checkout-index: don't mix '--all' and explicit filenames"); + die("git checkout-index: don't mix '--all' and explicit filenames"); if (read_from_stdin) - die("git-checkout-index: don't mix '--stdin' and explicit filenames"); + die("git checkout-index: don't mix '--stdin' and explicit filenames"); p = prefix_path(prefix, prefix_length, arg); checkout_file(p, prefix_length); if (p < arg || p > arg + strlen(arg)) @@ -271,7 +271,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix) struct strbuf buf, nbuf; if (all) - die("git-checkout-index: don't mix '--all' and '--stdin'"); + die("git checkout-index: don't mix '--all' and '--stdin'"); strbuf_init(&buf, 0); strbuf_init(&nbuf, 0); diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c index 7a9a309be0..291c43cf70 100644 --- a/builtin-commit-tree.c +++ b/builtin-commit-tree.c @@ -118,7 +118,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix) } if (strbuf_read(&buffer, 0, 0) < 0) - die("git-commit-tree: read returned %s", strerror(errno)); + die("git commit-tree: read returned %s", strerror(errno)); if (!commit_tree(buffer.buf, tree_sha1, parents, commit_sha1)) { printf("%s\n", sha1_to_hex(commit_sha1)); diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c index 273239af3b..6b37281a95 100644 --- a/builtin-fetch-pack.c +++ b/builtin-fetch-pack.c @@ -609,7 +609,7 @@ static struct ref *do_fetch_pack(int fd[2], fprintf(stderr, "warning: no common commits\n"); if (get_pack(fd, pack_lockfile)) - die("git-fetch-pack: fetch failed."); + die("git fetch-pack: fetch failed."); all_done: return ref; diff --git a/builtin-grep.c b/builtin-grep.c index 631129ddfd..f59f95f175 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -774,7 +774,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) /* Make sure we do not get outside of paths */ for (i = 0; paths[i]; i++) if (strncmp(prefix, paths[i], opt.prefix_length)) - die("git-grep: cannot generate relative filenames containing '..'"); + die("git grep: cannot generate relative filenames containing '..'"); } } else if (prefix) { diff --git a/builtin-ls-files.c b/builtin-ls-files.c index e8d568eed7..068f424696 100644 --- a/builtin-ls-files.c +++ b/builtin-ls-files.c @@ -78,7 +78,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent) int offset = prefix_offset; if (len >= ent->len) - die("git-ls-files: internal error - directory entry not superset of prefix"); + die("git ls-files: internal error - directory entry not superset of prefix"); if (pathspec && !pathspec_match(pathspec, ps_matched, ent->name, len)) return; @@ -183,7 +183,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce) int offset = prefix_offset; if (len >= ce_namelen(ce)) - die("git-ls-files: internal error - cache entry not superset of prefix"); + die("git ls-files: internal error - cache entry not superset of prefix"); if (pathspec && !pathspec_match(pathspec, ps_matched, ce->name, len)) return; @@ -319,7 +319,7 @@ static const char *verify_pathspec(const char *prefix) } if (prefix_offset > max || memcmp(prev, prefix, prefix_offset)) - die("git-ls-files: cannot generate relative filenames containing '..'"); + die("git ls-files: cannot generate relative filenames containing '..'"); prefix_len = max; return max ? xmemdupz(prev, max) : NULL; diff --git a/builtin-rm.c b/builtin-rm.c index 0ed26bb8f1..6bd82111d2 100644 --- a/builtin-rm.c +++ b/builtin-rm.c @@ -221,7 +221,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix) printf("rm '%s'\n", path); if (remove_file_from_cache(path)) - die("git-rm: unable to remove %s", path); + die("git rm: unable to remove %s", path); } if (show_only) @@ -244,7 +244,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix) continue; } if (!removed) - die("git-rm: %s: %s", path, strerror(errno)); + die("git rm: %s: %s", path, strerror(errno)); } } diff --git a/builtin-show-ref.c b/builtin-show-ref.c index add16004f1..572b114119 100644 --- a/builtin-show-ref.c +++ b/builtin-show-ref.c @@ -62,7 +62,7 @@ match: * ref points at a nonexistent object. */ if (!has_sha1_file(sha1)) - die("git-show-ref: bad ref %s (%s)", refname, + die("git show-ref: bad ref %s (%s)", refname, sha1_to_hex(sha1)); if (quiet) @@ -82,12 +82,12 @@ match: else { obj = parse_object(sha1); if (!obj) - die("git-show-ref: bad ref %s (%s)", refname, + die("git show-ref: bad ref %s (%s)", refname, sha1_to_hex(sha1)); if (obj->type == OBJ_TAG) { obj = deref_tag(obj, refname, 0); if (!obj) - die("git-show-ref: bad tag at ref %s (%s)", refname, + die("git show-ref: bad tag at ref %s (%s)", refname, sha1_to_hex(sha1)); hex = find_unique_abbrev(obj->sha1, abbrev); printf("%s %s^{}\n", hex, refname); diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c index f4bea4a322..cb7007e25f 100644 --- a/builtin-tar-tree.c +++ b/builtin-tar-tree.c @@ -76,7 +76,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix) n = read_in_full(0, buffer, HEADERSIZE); if (n < HEADERSIZE) - die("git-get-tar-commit-id: read error"); + die("git get-tar-commit-id: read error"); if (header->typeflag[0] != 'g') return 1; if (memcmp(content, "52 comment=", 11)) @@ -84,7 +84,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix) n = write_in_full(1, content + 11, 41); if (n < 41) - die("git-get-tar-commit-id: write error"); + die("git get-tar-commit-id: write error"); return 0; } diff --git a/builtin-update-index.c b/builtin-update-index.c index 38eb53ccba..e5bb2a03cb 100644 --- a/builtin-update-index.c +++ b/builtin-update-index.c @@ -262,7 +262,7 @@ static void chmod_path(int flip, const char *path) report("chmod %cx '%s'", flip, path); return; fail: - die("git-update-index: cannot chmod %cx '%s'", flip, path); + die("git update-index: cannot chmod %cx '%s'", flip, path); } static void update_one(const char *path, const char *prefix, int prefix_length) @@ -280,7 +280,7 @@ static void update_one(const char *path, const char *prefix, int prefix_length) if (force_remove) { if (remove_file_from_cache(p)) - die("git-update-index: unable to remove %s", path); + die("git update-index: unable to remove %s", path); report("remove '%s'", path); goto free_return; } @@ -351,7 +351,7 @@ static void read_index_info(int line_termination) if (line_termination && path_name[0] == '"') { strbuf_reset(&uq); if (unquote_c_style(&uq, path_name, NULL)) { - die("git-update-index: bad quoting of path name"); + die("git update-index: bad quoting of path name"); } path_name = uq.buf; } @@ -364,7 +364,7 @@ static void read_index_info(int line_termination) if (!mode) { /* mode == 0 means there is no such path -- remove */ if (remove_file_from_cache(path_name)) - die("git-update-index: unable to remove %s", + die("git update-index: unable to remove %s", ptr); } else { @@ -374,7 +374,7 @@ static void read_index_info(int line_termination) */ ptr[-42] = ptr[-1] = 0; if (add_cacheinfo(mode, sha1, path_name, stage)) - die("git-update-index: unable to update %s", + die("git update-index: unable to update %s", path_name); } continue; @@ -626,12 +626,12 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) unsigned int mode; if (i+3 >= argc) - die("git-update-index: --cacheinfo "); + die("git update-index: --cacheinfo "); if (strtoul_ui(argv[i+1], 8, &mode) || get_sha1_hex(argv[i+2], sha1) || add_cacheinfo(mode, sha1, argv[i+3], 0)) - die("git-update-index: --cacheinfo" + die("git update-index: --cacheinfo" " cannot add %s", argv[i+3]); i += 3; continue; @@ -639,7 +639,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) if (!strcmp(path, "--chmod=-x") || !strcmp(path, "--chmod=+x")) { if (argc <= i+1) - die("git-update-index: %s ", path); + die("git update-index: %s ", path); set_executable_bit = path[8]; continue; } diff --git a/connect.c b/connect.c index 574f42fa47..dd96f8e043 100644 --- a/connect.c +++ b/connect.c @@ -97,7 +97,7 @@ int get_ack(int fd, unsigned char *result_sha1) int len = packet_read_line(fd, line, sizeof(line)); if (!len) - die("git-fetch-pack: expected ACK/NAK, got EOF"); + die("git fetch-pack: expected ACK/NAK, got EOF"); if (line[len-1] == '\n') line[--len] = 0; if (!strcmp(line, "NAK")) @@ -109,7 +109,7 @@ int get_ack(int fd, unsigned char *result_sha1) return 1; } } - die("git-fetch_pack: expected ACK/NAK, got '%s'", line); + die("git fetch_pack: expected ACK/NAK, got '%s'", line); } int path_match(const char *path, int nr, char **match) diff --git a/entry.c b/entry.c index 222aaa374b..aa2ee46a84 100644 --- a/entry.c +++ b/entry.c @@ -111,7 +111,7 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout case S_IFREG: new = read_blob_entry(ce, path, &size); if (!new) - return error("git-checkout-index: unable to read sha1 file of %s (%s)", + return error("git checkout-index: unable to read sha1 file of %s (%s)", path, sha1_to_hex(ce->sha1)); /* @@ -132,7 +132,7 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout fd = create_file(path, ce->ce_mode); if (fd < 0) { free(new); - return error("git-checkout-index: unable to create file %s (%s)", + return error("git checkout-index: unable to create file %s (%s)", path, strerror(errno)); } @@ -140,12 +140,12 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout close(fd); free(new); if (wrote != size) - return error("git-checkout-index: unable to write file %s", path); + return error("git checkout-index: unable to write file %s", path); break; case S_IFLNK: new = read_blob_entry(ce, path, &size); if (!new) - return error("git-checkout-index: unable to read sha1 file of %s (%s)", + return error("git checkout-index: unable to read sha1 file of %s (%s)", path, sha1_to_hex(ce->sha1)); if (to_tempfile || !has_symlinks) { if (to_tempfile) { @@ -155,31 +155,31 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout fd = create_file(path, 0666); if (fd < 0) { free(new); - return error("git-checkout-index: unable to create " + return error("git checkout-index: unable to create " "file %s (%s)", path, strerror(errno)); } wrote = write_in_full(fd, new, size); close(fd); free(new); if (wrote != size) - return error("git-checkout-index: unable to write file %s", + return error("git checkout-index: unable to write file %s", path); } else { wrote = symlink(new, path); free(new); if (wrote) - return error("git-checkout-index: unable to create " + return error("git checkout-index: unable to create " "symlink %s (%s)", path, strerror(errno)); } break; case S_IFGITLINK: if (to_tempfile) - return error("git-checkout-index: cannot create temporary subproject %s", path); + return error("git checkout-index: cannot create temporary subproject %s", path); if (mkdir(path, 0777) < 0) - return error("git-checkout-index: cannot create subproject directory %s", path); + return error("git checkout-index: cannot create subproject directory %s", path); break; default: - return error("git-checkout-index: unknown file mode for %s", path); + return error("git checkout-index: unknown file mode for %s", path); } if (state->refresh_cache) { diff --git a/merge-index.c b/merge-index.c index 7491c56ad2..7827e87a92 100644 --- a/merge-index.c +++ b/merge-index.c @@ -27,7 +27,7 @@ static int merge_entry(int pos, const char *path) int found; if (pos >= active_nr) - die("git-merge-index: %s not in the cache", path); + die("git merge-index: %s not in the cache", path); arguments[0] = pgm; arguments[1] = ""; arguments[2] = ""; @@ -53,7 +53,7 @@ static int merge_entry(int pos, const char *path) arguments[stage + 4] = ownbuf[stage]; } while (++pos < active_nr); if (!found) - die("git-merge-index: %s not in the cache", path); + die("git merge-index: %s not in the cache", path); run_program(); return found; } @@ -117,7 +117,7 @@ int main(int argc, char **argv) merge_all(); continue; } - die("git-merge-index: unknown option %s", arg); + die("git merge-index: unknown option %s", arg); } merge_file(arg); } diff --git a/tree-diff.c b/tree-diff.c index bbb126fc46..9f67af6c1f 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -303,7 +303,7 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, stru update_tree_entry(t2); continue; } - die("git-diff-tree: internal error"); + die("git diff-tree: internal error"); } return 0; } diff --git a/upload-pack.c b/upload-pack.c index c911e70c9a..e5adbc011e 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -157,7 +157,7 @@ static void create_pack_file(void) /* .data is just a boolean: any non-NULL value will do */ rev_list.data = create_full_pack ? &rev_list : NULL; if (start_async(&rev_list)) - die("git-upload-pack: unable to fork git-rev-list"); + die("git upload-pack: unable to fork git-rev-list"); argv[arg++] = "pack-objects"; argv[arg++] = "--stdout"; @@ -177,7 +177,7 @@ static void create_pack_file(void) pack_objects.argv = argv; if (start_command(&pack_objects)) - die("git-upload-pack: unable to fork git-pack-objects"); + die("git upload-pack: unable to fork git-pack-objects"); /* We read from pack_objects.err to capture stderr output for * progress bar, and pack_objects.out to capture the pack data. @@ -271,7 +271,7 @@ static void create_pack_file(void) } if (finish_command(&pack_objects)) { - error("git-upload-pack: git-pack-objects died with error."); + error("git upload-pack: git-pack-objects died with error."); goto fail; } if (finish_async(&rev_list)) @@ -291,7 +291,7 @@ static void create_pack_file(void) fail: send_client_data(3, abort_msg, sizeof(abort_msg)); - die("git-upload-pack: %s", abort_msg); + die("git upload-pack: %s", abort_msg); } static int got_sha1(char *hex, unsigned char *sha1) @@ -300,7 +300,7 @@ static int got_sha1(char *hex, unsigned char *sha1) int we_knew_they_have = 0; if (get_sha1_hex(hex, sha1)) - die("git-upload-pack: expected SHA1 object, got '%s'", hex); + die("git upload-pack: expected SHA1 object, got '%s'", hex); if (!has_sha1_file(sha1)) return -1; @@ -440,7 +440,7 @@ static int get_common_commits(void) packet_write(1, "NAK\n"); return -1; } - die("git-upload-pack: expected SHA1 list, got '%s'", line); + die("git upload-pack: expected SHA1 list, got '%s'", line); } } @@ -485,7 +485,7 @@ static void receive_needs(void) } if (prefixcmp(line, "want ") || get_sha1_hex(line+5, sha1_buf)) - die("git-upload-pack: protocol error, " + die("git upload-pack: protocol error, " "expected to get sha, not '%s'", line); if (strstr(line+45, "multi_ack")) multi_ack = 1; @@ -512,7 +512,7 @@ static void receive_needs(void) */ o = lookup_object(sha1_buf); if (!o || !(o->flags & OUR_REF)) - die("git-upload-pack: not our ref %s", line+5); + die("git upload-pack: not our ref %s", line+5); if (!(o->flags & WANTED)) { o->flags |= WANTED; add_object_array(o, NULL, &want_obj); @@ -577,7 +577,7 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo struct object *o = parse_object(sha1); if (!o) - die("git-upload-pack: cannot find object %s:", sha1_to_hex(sha1)); + die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1)); if (capabilities) packet_write(1, "%s %s%c%s\n", sha1_to_hex(sha1), refname, -- cgit v1.3 From f0946cb826b9b6c01976860fdd9dfd498ce0ec5e Mon Sep 17 00:00:00 2001 From: Björn Steinbrink Date: Tue, 31 Mar 2009 17:05:01 +0200 Subject: tree_entry_interesting: a pathspec only matches at directory boundary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously the code did a simple prefix match, which means that a path in a directory "frotz/" would have matched with pathspec "f". Signed-off-by: Björn Steinbrink Signed-off-by: Junio C Hamano --- t/t4010-diff-pathspec.sh | 8 ++++++++ tree-diff.c | 12 +++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'tree-diff.c') diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh index ad3d9e4845..4c4c8b1570 100755 --- a/t/t4010-diff-pathspec.sh +++ b/t/t4010-diff-pathspec.sh @@ -62,4 +62,12 @@ test_expect_success \ 'git diff-index --cached $tree -- file0/ >current && compare_diff_raw current expected' +test_expect_success 'diff-tree pathspec' ' + tree2=$(git write-tree) && + echo "$tree2" && + git diff-tree -r --name-only $tree $tree2 -- pa path1/a >current && + >expected && + test_cmp expected current +' + test_done diff --git a/tree-diff.c b/tree-diff.c index 9f67af6c1f..b05d0f4355 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -118,10 +118,16 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int continue; /* - * The base is a subdirectory of a path which - * was specified, so all of them are interesting. + * If the base is a subdirectory of a path which + * was specified, all of them are interesting. */ - return 2; + if (!matchlen || + base[matchlen] == '/' || + match[matchlen - 1] == '/') + return 2; + + /* Just a random prefix match */ + continue; } /* Does the base match? */ -- cgit v1.3 From 3ea3c215c02dc4a4e7d0881c25b2223540960797 Mon Sep 17 00:00:00 2001 From: Mike Ralphson Date: Fri, 17 Apr 2009 19:13:30 +0100 Subject: Fix typos / spelling in comments Signed-off-by: Mike Ralphson Signed-off-by: Junio C Hamano --- builtin-checkout.c | 2 +- builtin-ls-files.c | 2 +- builtin-pack-objects.c | 2 +- builtin-reflog.c | 2 +- builtin-reset.c | 2 +- compat/cygwin.c | 2 +- compat/fnmatch/fnmatch.c | 4 ++-- compat/mingw.c | 2 +- compat/regex/regex.c | 4 ++-- diffcore-rename.c | 2 +- fast-import.c | 6 +++--- fsck.h | 2 +- git.c | 2 +- graph.c | 2 +- levenshtein.c | 2 +- parse-options.h | 8 ++++---- revision.c | 2 +- strbuf.h | 2 +- tree-diff.c | 2 +- xdiff/xdiffi.c | 2 +- 20 files changed, 27 insertions(+), 27 deletions(-) (limited to 'tree-diff.c') diff --git a/builtin-checkout.c b/builtin-checkout.c index ee1edd406f..383598c9bf 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -178,7 +178,7 @@ static int checkout_merged(int pos, struct checkout *state) /* * NEEDSWORK: * There is absolutely no reason to write this as a blob object - * and create a phoney cache entry just to leak. This hack is + * and create a phony cache entry just to leak. This hack is * primarily to get to the write_entry() machinery that massages * the contents to work-tree format and writes out which only * allows it for a cache entry. The code in write_entry() needs diff --git a/builtin-ls-files.c b/builtin-ls-files.c index 88e2697aeb..da2daf45ac 100644 --- a/builtin-ls-files.c +++ b/builtin-ls-files.c @@ -512,7 +512,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix) pathspec = get_pathspec(prefix, argv); - /* be nice with submodule patsh ending in a slash */ + /* be nice with submodule paths ending in a slash */ read_cache(); if (pathspec) strip_trailing_slash_from_submodules(); diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 419f29aa1a..9742b45c4d 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -293,7 +293,7 @@ static unsigned long write_object(struct sha1file *f, die("unable to read %s", sha1_to_hex(entry->idx.sha1)); /* * make sure no cached delta data remains from a - * previous attempt before a pack split occured. + * previous attempt before a pack split occurred. */ free(entry->delta_data); entry->delta_data = NULL; diff --git a/builtin-reflog.c b/builtin-reflog.c index 249ad2a311..ff8b4f615b 100644 --- a/builtin-reflog.c +++ b/builtin-reflog.c @@ -243,7 +243,7 @@ static void mark_reachable(struct commit *commit, unsigned long expire_limit) * We need to compute if commit on either side of an reflog * entry is reachable from the tip of the ref for all entries. * Mark commits that are reachable from the tip down to the - * time threashold first; we know a commit marked thusly is + * time threshold first; we know a commit marked thusly is * reachable from the tip without running in_merge_bases() * at all. */ diff --git a/builtin-reset.c b/builtin-reset.c index c0cb915c26..7e7ebabaa8 100644 --- a/builtin-reset.c +++ b/builtin-reset.c @@ -228,7 +228,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) } /* * Otherwise, argv[i] could be either or and - * has to be unambigous. + * has to be unambiguous. */ else if (!get_sha1(argv[i], sha1)) { /* diff --git a/compat/cygwin.c b/compat/cygwin.c index ebac148392..119287412d 100644 --- a/compat/cygwin.c +++ b/compat/cygwin.c @@ -92,7 +92,7 @@ static int cygwin_stat(const char *path, struct stat *buf) * Reading this option is not always possible immediately as git_dir may be * not be set yet. So until it is set, use cygwin lstat/stat functions. * However, if core.filemode is set, we must use the Cygwin posix - * stat/lstat as the Windows stat fuctions do not determine posix filemode. + * stat/lstat as the Windows stat functions do not determine posix filemode. * * Note that git_cygwin_config() does NOT call git_default_config() and this * is deliberate. Many commands read from config to establish initial diff --git a/compat/fnmatch/fnmatch.c b/compat/fnmatch/fnmatch.c index 1f4ead5f98..03157a4ab5 100644 --- a/compat/fnmatch/fnmatch.c +++ b/compat/fnmatch/fnmatch.c @@ -39,7 +39,7 @@ # include #endif -/* For platform which support the ISO C amendement 1 functionality we +/* For platform which support the ISO C amendment 1 functionality we support user defined character classes. */ #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) /* Solaris 2.5 has a bug: must be included before . */ @@ -90,7 +90,7 @@ # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) /* The GNU C library provides support for user-defined character classes - and the functions from ISO C amendement 1. */ + and the functions from ISO C amendment 1. */ # ifdef CHARCLASS_NAME_MAX # define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX # else diff --git a/compat/mingw.c b/compat/mingw.c index 1a17cf6cce..2a047019e8 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -396,7 +396,7 @@ repeat: * its own input data to become available. But since * the process (pack-objects) is itself CPU intensive, * it will happily pick up the time slice that we are - * relinguishing here. + * relinquishing here. */ Sleep(0); goto repeat; diff --git a/compat/regex/regex.c b/compat/regex/regex.c index 87b33e4669..5ea007567d 100644 --- a/compat/regex/regex.c +++ b/compat/regex/regex.c @@ -1043,7 +1043,7 @@ regex_compile (pattern, size, syntax, bufp) they can be reliably used as array indices. */ register unsigned char c, c1; - /* A random tempory spot in PATTERN. */ + /* A random temporary spot in PATTERN. */ const char *p1; /* Points to the end of the buffer, where we should append. */ @@ -1796,7 +1796,7 @@ regex_compile (pattern, size, syntax, bufp) we're all done, the pattern will look like: set_number_at set_number_at - succeed_n + succeed_n jump_n (The upper bound and `jump_n' are omitted if diff --git a/diffcore-rename.c b/diffcore-rename.c index 0b0d6b8c8c..63ac998bfa 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -267,7 +267,7 @@ static int find_identical_files(struct file_similarity *src, int score; struct diff_filespec *source = p->filespec; - /* False hash collission? */ + /* False hash collision? */ if (hashcmp(source->sha1, target->sha1)) continue; /* Non-regular files? If so, the modes must match! */ diff --git a/fast-import.c b/fast-import.c index 23c496d683..53617a10d2 100644 --- a/fast-import.c +++ b/fast-import.c @@ -76,7 +76,7 @@ Format of STDIN stream: delim lf; # note: declen indicates the length of binary_data in bytes. - # declen does not include the lf preceeding the binary data. + # declen does not include the lf preceding the binary data. # exact_data ::= 'data' sp declen lf binary_data; @@ -134,7 +134,7 @@ Format of STDIN stream: # # In case it is not clear, the '#' that starts the comment # must be the first character on that the line (an lf have - # preceeded it). + # preceded it). # comment ::= '#' not_lf* lf; not_lf ::= # Any byte that is not ASCII newline (LF); @@ -953,7 +953,7 @@ static void end_packfile(void) close(pack_data->pack_fd); idx_name = keep_pack(create_index()); - /* Register the packfile with core git's machinary. */ + /* Register the packfile with core git's machinery. */ new_p = add_packed_git(idx_name, strlen(idx_name), 1); if (!new_p) die("core git rejected index %s", idx_name); diff --git a/fsck.h b/fsck.h index 990ee02335..008456b675 100644 --- a/fsck.h +++ b/fsck.h @@ -23,7 +23,7 @@ int fsck_error_function(struct object *obj, int type, const char *fmt, ...); * the return value is: * -1 error in processing the object * <0 return value of the callback, which lead to an abort - * >0 return value of the first sigaled error >0 (in the case of no other errors) + * >0 return value of the first signaled error >0 (in the case of no other errors) * 0 everything OK */ int fsck_walk(struct object *obj, fsck_walk_func walk, void *data); diff --git a/git.c b/git.c index bfb6508ad0..cc5aaa76f1 100644 --- a/git.c +++ b/git.c @@ -497,7 +497,7 @@ int main(int argc, const char **argv) /* * We use PATH to find git commands, but we prepend some higher - * precidence paths: the "--exec-path" option, the GIT_EXEC_PATH + * precedence paths: the "--exec-path" option, the GIT_EXEC_PATH * environment, and the $(gitexecdir) from the Makefile at build * time. */ diff --git a/graph.c b/graph.c index b7879f8c66..06fbeb6c24 100644 --- a/graph.c +++ b/graph.c @@ -35,7 +35,7 @@ static void graph_padding_line(struct git_graph *graph, struct strbuf *sb); * newline. A new graph line will not be printed after the final newline. * If the strbuf is empty, no output will be printed. * - * Since the first line will not include the graph ouput, the caller is + * Since the first line will not include the graph output, the caller is * responsible for printing this line's graph (perhaps via * graph_show_commit() or graph_show_oneline()) before calling * graph_show_strbuf(). diff --git a/levenshtein.c b/levenshtein.c index a32f4cdc45..fc281597fd 100644 --- a/levenshtein.c +++ b/levenshtein.c @@ -27,7 +27,7 @@ * * It does so by calculating the costs of the path ending in characters * i (in string1) and j (in string2), respectively, given that the last - * operation is a substition, a swap, a deletion, or an insertion. + * operation is a substitution, a swap, a deletion, or an insertion. * * This implementation allows the costs to be weighted: * diff --git a/parse-options.h b/parse-options.h index f8ef1db128..b54eec128b 100644 --- a/parse-options.h +++ b/parse-options.h @@ -52,7 +52,7 @@ typedef int parse_opt_cb(const struct option *, const char *arg, int unset); * * `argh`:: * token to explain the kind of argument this option wants. Keep it - * homogenous across the repository. + * homogeneous across the repository. * * `help`:: * the short help associated to what the option does. @@ -61,7 +61,7 @@ typedef int parse_opt_cb(const struct option *, const char *arg, int unset); * * `flags`:: * mask of parse_opt_option_flags. - * PARSE_OPT_OPTARG: says that the argument is optionnal (not for BOOLEANs) + * PARSE_OPT_OPTARG: says that the argument is optional (not for BOOLEANs) * PARSE_OPT_NOARG: says that this option takes no argument, for CALLBACKs * PARSE_OPT_NONEG: says that this option cannot be negated * PARSE_OPT_HIDDEN this option is skipped in the default usage, showed in @@ -105,7 +105,7 @@ struct option { { OPTION_CALLBACK, (s), (l), (v), (a), (h), 0, (f) } /* parse_options() will filter out the processed options and leave the - * non-option argments in argv[]. + * non-option arguments in argv[]. * Returns the number of arguments left in argv[]. */ extern int parse_options(int argc, const char **argv, @@ -115,7 +115,7 @@ extern int parse_options(int argc, const char **argv, extern NORETURN void usage_with_options(const char * const *usagestr, const struct option *options); -/*----- incremantal advanced APIs -----*/ +/*----- incremental advanced APIs -----*/ enum { PARSE_OPT_HELP = -1, diff --git a/revision.c b/revision.c index bd0ea34af0..18b7ebbbd5 100644 --- a/revision.c +++ b/revision.c @@ -209,7 +209,7 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object } /* - * Tree object? Either mark it uniniteresting, or add it + * Tree object? Either mark it uninteresting, or add it * to the list of objects to look at later.. */ if (object->type == OBJ_TREE) { diff --git a/strbuf.h b/strbuf.h index 9ee908a3ec..eaa8704d5f 100644 --- a/strbuf.h +++ b/strbuf.h @@ -11,7 +11,7 @@ * build complex strings/buffers whose final size isn't easily known. * * It is NOT legal to copy the ->buf pointer away. - * `strbuf_detach' is the operation that detachs a buffer from its shell + * `strbuf_detach' is the operation that detaches a buffer from its shell * while keeping the shell valid wrt its invariants. * * 2. the ->buf member is a byte array that has at least ->len + 1 bytes diff --git a/tree-diff.c b/tree-diff.c index b05d0f4355..edd83949bf 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -374,7 +374,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co } /* - * Then, discard all the non-relevane file pairs... + * Then, discard all the non-relevant file pairs... */ for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c index 02184d9cde..1ebab687f7 100644 --- a/xdiff/xdiffi.c +++ b/xdiff/xdiffi.c @@ -456,7 +456,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { /* * Record the end-of-group position in case we are matched * with a group of changes in the other file (that is, the - * change record before the enf-of-group index in the other + * change record before the end-of-group index in the other * file is set). */ ixref = rchgo[ixo - 1] ? ix: nrec; -- cgit v1.3 From df533f34a31890a43baaf00d03c0a7fa51886bc5 Mon Sep 17 00:00:00 2001 From: Nick Edelen Date: Sat, 13 Jun 2009 17:06:09 -0700 Subject: diff-tree -r -t: include added/removed directories in the output We used to include only the modified and typechanged directories in the ouptut, but for consistency's sake, we should also include added and removed ones as well. This makes the output more consistent, but it may break existing scripts that expect to see the current output which has long been the established behaviour. Signed-off-by: Nick Edelen Signed-off-by: Junio C Hamano --- t/t4037-diff-r-t-dirs.sh | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ tree-diff.c | 6 ++++++ 2 files changed, 59 insertions(+) create mode 100755 t/t4037-diff-r-t-dirs.sh (limited to 'tree-diff.c') diff --git a/t/t4037-diff-r-t-dirs.sh b/t/t4037-diff-r-t-dirs.sh new file mode 100755 index 0000000000..f5ce3b29a2 --- /dev/null +++ b/t/t4037-diff-r-t-dirs.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +test_description='diff -r -t shows directory additions and deletions' + +. ./test-lib.sh + +test_expect_success setup ' + mkdir dc dr dt && + >dc/1 && + >dr/2 && + >dt/3 && + >fc && + >fr && + >ft && + git add . && + test_tick && + git commit -m initial && + + rm -fr dt dr ft fr && + mkdir da ft && + for p in dc/1 da/4 dt ft/5 fc + do + echo hello >$p || exit + done && + git add -u && + git add . && + test_tick && + git commit -m second +' + +cat >expect <<\EOF +A da +A da/4 +M dc +M dc/1 +D dr +D dr/2 +A dt +D dt +D dt/3 +M fc +D fr +D ft +A ft +A ft/5 +EOF + +test_expect_success verify ' + git diff-tree -r -t --name-status HEAD^ HEAD >actual && + test_cmp expect actual +' + +test_done diff --git a/tree-diff.c b/tree-diff.c index 9f67af6c1f..c83a8da392 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -233,6 +233,12 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree if (!tree || type != OBJ_TREE) die("corrupt tree sha %s", sha1_to_hex(sha1)); + if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) { + newbase[baselen + pathlen] = 0; + opt->add_remove(opt, *prefix, mode, sha1, newbase); + newbase[baselen + pathlen] = '/'; + } + init_tree_desc(&inner, tree, size); show_tree(opt, prefix, &inner, newbase, baselen + 1 + pathlen); -- cgit v1.3