path: root/builtin-diff.c
diff options
authorJunio C Hamano <>2008-02-12 22:26:02 (GMT)
committerJunio C Hamano <>2008-02-13 22:58:07 (GMT)
commitcd676a513672eeb9663c6d4de276a1c860a4b879 (patch)
treed03ba0875a0c3e5bdb8f879ccda999b42d927f56 /builtin-diff.c
parent7a2078b4b00fb1c5d7b0bf8155778f79377b8f2f (diff)
diff --relative: output paths as relative to the current subdirectory
This adds --relative option to the diff family. When you start from a subdirectory: $ git diff --relative shows only the diff that is inside your current subdirectory, and without $prefix part. People who usually live in subdirectories may like it. There are a few things I should also mention about the change: - This works not just with diff but also works with the log family of commands, but the history pruning is not affected. In other words, if you go to a subdirectory, you can say: $ git log --relative -p but it will show the log message even for commits that do not touch the current directory. You can limit it by giving pathspec yourself: $ git log --relative -p . This originally was not a conscious design choice, but we have a way to affect diff pathspec and pruning pathspec independently. IOW "git log --full-diff -p ." tells it to prune history to commits that affect the current subdirectory but show the changes with full context. I think it makes more sense to leave pruning independent from --relative than the obvious alternative of always pruning with the current subdirectory, which would break the symmetry. - Because this works also with the log family, you could format-patch a single change, limiting the effect to your subdirectory, like so: $ cd gitk-git $ git format-patch -1 --relative 911f1eb But because that is a special purpose usage, this option will never become the default, with or without repository or user preference configuration. The risk of producing a partial patch and sending it out by mistake is too great if we did so. - This is inherently incompatible with --no-index, which is a bolted-on hack that does not have much to do with git itself. I didn't bother checking and erroring out on the combined use of the options, but probably I should. Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'builtin-diff.c')
1 files changed, 10 insertions, 1 deletions
diff --git a/builtin-diff.c b/builtin-diff.c
index 8d7a569..19fa668 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -43,12 +43,17 @@ static void stuff_change(struct diff_options *opt,
tmp_u = old_sha1; old_sha1 = new_sha1; new_sha1 = tmp_u;
tmp_c = old_name; old_name = new_name; new_name = tmp_c;
+ if (opt->prefix &&
+ (strncmp(old_name, opt->prefix, opt->prefix_length) ||
+ strncmp(new_name, opt->prefix, opt->prefix_length)))
+ return;
one = alloc_filespec(old_name);
two = alloc_filespec(new_name);
fill_filespec(one, old_sha1, old_mode);
fill_filespec(two, new_sha1, new_mode);
- /* NEEDSWORK: shouldn't this part of diffopt??? */
diff_queue(&diff_queued_diff, one, two);
@@ -241,6 +246,10 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
if (diff_setup_done(&rev.diffopt) < 0)
die("diff_setup_done failed");
+ if (rev.diffopt.prefix && nongit) {
+ rev.diffopt.prefix = NULL;
+ rev.diffopt.prefix_length = 0;
+ }
DIFF_OPT_SET(&rev.diffopt, RECURSIVE);