* [PATCH/RFC] diff --relative: output paths as relative to the current subdirectory
@ 2008-02-12 22:26 Junio C Hamano
2008-02-12 23:33 ` Linus Torvalds
0 siblings, 1 reply; 8+ messages in thread
From: Junio C Hamano @ 2008-02-12 22:26 UTC (permalink / raw)
To: git; +Cc: Linus Torvalds
This adds --relative option to 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 <gitster@pobox.com>
---
* I've been cooking this privately, but I am sending this out
now, as I suspect dirstat needs to be adjusted if we decide
this is a good idea.
Documentation/git-diff.txt | 5 ++
builtin-diff.c | 11 ++++-
diff.c | 100 ++++++++++++++++++++++++++++++++++-------
diff.h | 3 +
revision.c | 4 ++
t/t3404-rebase-interactive.sh | 10 +++-
6 files changed, 113 insertions(+), 20 deletions(-)
diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt
index 57c2862..012bbdc 100644
--- a/Documentation/git-diff.txt
+++ b/Documentation/git-diff.txt
@@ -78,6 +78,11 @@ OPTIONS
:git-diff: 1
include::diff-options.txt[]
+--relative::
+ When run from a subdirectory of the project, it can be
+ told to exclude changes outside the directory and show
+ pathnames relative to it with this option.
+
<path>...::
The <paths> parameters, when given, are used to limit
the diff to the named paths (you can give directory
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, ALLOW_EXTERNAL);
DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
diff --git a/diff.c b/diff.c
index 5b8afdc..db4bd55 100644
--- a/diff.c
+++ b/diff.c
@@ -1397,6 +1397,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
}
static void builtin_checkdiff(const char *name_a, const char *name_b,
+ const char *attr_path,
struct diff_filespec *one,
struct diff_filespec *two, struct diff_options *o)
{
@@ -1411,7 +1412,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
data.filename = name_b ? name_b : name_a;
data.lineno = 0;
data.color_diff = DIFF_OPT_TST(o, COLOR_DIFF);
- data.ws_rule = whitespace_rule(data.filename);
+ data.ws_rule = whitespace_rule(attr_path);
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
die("unable to read files to diff");
@@ -1831,6 +1832,9 @@ static const char *external_diff_attr(const char *name)
{
struct git_attr_check attr_diff_check;
+ if (!name)
+ return NULL;
+
setup_diff_attr_check(&attr_diff_check);
if (!git_checkattr(name, 1, &attr_diff_check)) {
const char *value = attr_diff_check.value;
@@ -1850,6 +1854,7 @@ static const char *external_diff_attr(const char *name)
static void run_diff_cmd(const char *pgm,
const char *name,
const char *other,
+ const char *attr_path,
struct diff_filespec *one,
struct diff_filespec *two,
const char *xfrm_msg,
@@ -1859,7 +1864,7 @@ static void run_diff_cmd(const char *pgm,
if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL))
pgm = NULL;
else {
- const char *cmd = external_diff_attr(name);
+ const char *cmd = external_diff_attr(attr_path);
if (cmd)
pgm = cmd;
}
@@ -1900,6 +1905,15 @@ static int similarity_index(struct diff_filepair *p)
return p->score * 100 / MAX_SCORE;
}
+static void strip_prefix(int prefix_length, const char **namep, const char **otherp)
+{
+ /* Strip the prefix but do not molest /dev/null and absolute paths */
+ if (*namep && **namep != '/')
+ *namep += prefix_length;
+ if (*otherp && **otherp != '/')
+ *otherp += prefix_length;
+}
+
static void run_diff(struct diff_filepair *p, struct diff_options *o)
{
const char *pgm = external_diff();
@@ -1909,16 +1923,21 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
struct diff_filespec *two = p->two;
const char *name;
const char *other;
+ const char *attr_path;
int complete_rewrite = 0;
+ name = p->one->path;
+ other = (strcmp(name, p->two->path) ? p->two->path : NULL);
+ attr_path = name;
+ if (o->prefix_length)
+ strip_prefix(o->prefix_length, &name, &other);
if (DIFF_PAIR_UNMERGED(p)) {
- run_diff_cmd(pgm, p->one->path, NULL, NULL, NULL, NULL, o, 0);
+ run_diff_cmd(pgm, name, NULL, attr_path,
+ NULL, NULL, NULL, o, 0);
return;
}
- name = p->one->path;
- other = (strcmp(name, p->two->path) ? p->two->path : NULL);
diff_fill_sha1_info(one);
diff_fill_sha1_info(two);
@@ -1981,15 +2000,17 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
* needs to be split into deletion and creation.
*/
struct diff_filespec *null = alloc_filespec(two->path);
- run_diff_cmd(NULL, name, other, one, null, xfrm_msg, o, 0);
+ run_diff_cmd(NULL, name, other, attr_path,
+ one, null, xfrm_msg, o, 0);
free(null);
null = alloc_filespec(one->path);
- run_diff_cmd(NULL, name, other, null, two, xfrm_msg, o, 0);
+ run_diff_cmd(NULL, name, other, attr_path,
+ null, two, xfrm_msg, o, 0);
free(null);
}
else
- run_diff_cmd(pgm, name, other, one, two, xfrm_msg, o,
- complete_rewrite);
+ run_diff_cmd(pgm, name, other, attr_path,
+ one, two, xfrm_msg, o, complete_rewrite);
strbuf_release(&msg);
}
@@ -2010,6 +2031,9 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
name = p->one->path;
other = (strcmp(name, p->two->path) ? p->two->path : NULL);
+ if (o->prefix_length)
+ strip_prefix(o->prefix_length, &name, &other);
+
diff_fill_sha1_info(p->one);
diff_fill_sha1_info(p->two);
@@ -2022,6 +2046,7 @@ static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
{
const char *name;
const char *other;
+ const char *attr_path;
if (DIFF_PAIR_UNMERGED(p)) {
/* unmerged */
@@ -2030,11 +2055,15 @@ static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
name = p->one->path;
other = (strcmp(name, p->two->path) ? p->two->path : NULL);
+ attr_path = other ? other : name;
+
+ if (o->prefix_length)
+ strip_prefix(o->prefix_length, &name, &other);
diff_fill_sha1_info(p->one);
diff_fill_sha1_info(p->two);
- builtin_checkdiff(name, other, p->one, p->two, o);
+ builtin_checkdiff(name, other, attr_path, p->one, p->two, o);
}
void diff_setup(struct diff_options *options)
@@ -2076,6 +2105,13 @@ int diff_setup_done(struct diff_options *options)
if (DIFF_OPT_TST(options, FIND_COPIES_HARDER))
options->detect_rename = DIFF_DETECT_COPY;
+ if (!DIFF_OPT_TST(options, RELATIVE_NAME))
+ options->prefix = NULL;
+ if (options->prefix)
+ options->prefix_length = strlen(options->prefix);
+ else
+ options->prefix_length = 0;
+
if (options->output_format & (DIFF_FORMAT_NAME |
DIFF_FORMAT_NAME_STATUS |
DIFF_FORMAT_CHECKDIFF |
@@ -2264,6 +2300,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
}
else if (!strcmp(arg, "--no-renames"))
options->detect_rename = 0;
+ else if (!strcmp(arg, "--relative"))
+ DIFF_OPT_SET(options, RELATIVE_NAME);
/* xdiff options */
else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space"))
@@ -2475,12 +2513,20 @@ static void diff_flush_raw(struct diff_filepair *p, struct diff_options *opt)
printf("%c%c", p->status, inter_name_termination);
}
- if (p->status == DIFF_STATUS_COPIED || p->status == DIFF_STATUS_RENAMED) {
- write_name_quoted(p->one->path, stdout, inter_name_termination);
- write_name_quoted(p->two->path, stdout, line_termination);
+ if (p->status == DIFF_STATUS_COPIED ||
+ p->status == DIFF_STATUS_RENAMED) {
+ const char *name_a, *name_b;
+ name_a = p->one->path;
+ name_b = p->two->path;
+ strip_prefix(opt->prefix_length, &name_a, &name_b);
+ write_name_quoted(name_a, stdout, inter_name_termination);
+ write_name_quoted(name_b, stdout, line_termination);
} else {
- const char *path = p->one->mode ? p->one->path : p->two->path;
- write_name_quoted(path, stdout, line_termination);
+ const char *name_a, *name_b;
+ name_a = p->one->mode ? p->one->path : p->two->path;
+ name_b = NULL;
+ strip_prefix(opt->prefix_length, &name_a, &name_b);
+ write_name_quoted(name_a, stdout, line_termination);
}
}
@@ -2677,8 +2723,13 @@ static void flush_one_pair(struct diff_filepair *p, struct diff_options *opt)
diff_flush_checkdiff(p, opt);
else if (fmt & (DIFF_FORMAT_RAW | DIFF_FORMAT_NAME_STATUS))
diff_flush_raw(p, opt);
- else if (fmt & DIFF_FORMAT_NAME)
- write_name_quoted(p->two->path, stdout, opt->line_termination);
+ else if (fmt & DIFF_FORMAT_NAME) {
+ const char *name_a, *name_b;
+ name_a = p->two->path;
+ name_b = NULL;
+ strip_prefix(opt->prefix_length, &name_a, &name_b);
+ write_name_quoted(name_a, stdout, opt->line_termination);
+ }
}
static void show_file_mode_name(const char *newdelete, struct diff_filespec *fs)
@@ -3164,6 +3215,11 @@ void diff_addremove(struct diff_options *options,
if (!path) path = "";
sprintf(concatpath, "%s%s", base, path);
+
+ if (options->prefix &&
+ strncmp(concatpath, options->prefix, options->prefix_length))
+ return;
+
one = alloc_filespec(concatpath);
two = alloc_filespec(concatpath);
@@ -3193,6 +3249,11 @@ void diff_change(struct diff_options *options,
}
if (!path) path = "";
sprintf(concatpath, "%s%s", base, path);
+
+ if (options->prefix &&
+ strncmp(concatpath, options->prefix, options->prefix_length))
+ return;
+
one = alloc_filespec(concatpath);
two = alloc_filespec(concatpath);
fill_filespec(one, old_sha1, old_mode);
@@ -3207,6 +3268,11 @@ void diff_unmerge(struct diff_options *options,
unsigned mode, const unsigned char *sha1)
{
struct diff_filespec *one, *two;
+
+ if (options->prefix &&
+ strncmp(path, options->prefix, options->prefix_length))
+ return;
+
one = alloc_filespec(path);
two = alloc_filespec(path);
fill_filespec(one, sha1, mode);
diff --git a/diff.h b/diff.h
index 073d5cb..fcd9653 100644
--- a/diff.h
+++ b/diff.h
@@ -60,6 +60,7 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
#define DIFF_OPT_EXIT_WITH_STATUS (1 << 14)
#define DIFF_OPT_REVERSE_DIFF (1 << 15)
#define DIFF_OPT_CHECK_FAILED (1 << 16)
+#define DIFF_OPT_RELATIVE_NAME (1 << 17)
#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)
@@ -82,6 +83,8 @@ struct diff_options {
int rename_limit;
int setup;
int abbrev;
+ const char *prefix;
+ int prefix_length;
const char *msg_sep;
const char *stat_sep;
long xdl_opts;
diff --git a/revision.c b/revision.c
index 6e85aaa..6d9188b 100644
--- a/revision.c
+++ b/revision.c
@@ -720,6 +720,10 @@ void init_revisions(struct rev_info *revs, const char *prefix)
revs->commit_format = CMIT_FMT_DEFAULT;
diff_setup(&revs->diffopt);
+ if (prefix) {
+ revs->diffopt.prefix = prefix;
+ revs->diffopt.prefix_length = strlen(prefix);
+ }
}
static void add_pending_commit_list(struct rev_info *revs,
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index e33ea4e..bc46c37 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -328,8 +328,14 @@ test_expect_success 'rebase a commit violating pre-commit' '
mkdir -p .git/hooks &&
PRE_COMMIT=.git/hooks/pre-commit &&
- echo "#!/bin/sh" > $PRE_COMMIT &&
- echo "test -z \"\$(git diff --cached --check)\"" >> $PRE_COMMIT &&
+ (
+ echo "#!/bin/sh"
+ echo "z=\$(git diff --cached --check)"
+ echo "test -z \"\$z\" || {"
+ echo " echo >&2 \"*** \$z ***\""
+ echo " false"
+ echo "}"
+ ) > $PRE_COMMIT &&
chmod a+x $PRE_COMMIT &&
echo "monde! " >> file1 &&
test_tick &&
--
1.5.4.1.1278.gc75be
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] diff --relative: output paths as relative to the current subdirectory
2008-02-12 22:26 [PATCH/RFC] diff --relative: output paths as relative to the current subdirectory Junio C Hamano
@ 2008-02-12 23:33 ` Linus Torvalds
2008-02-12 23:43 ` Junio C Hamano
0 siblings, 1 reply; 8+ messages in thread
From: Linus Torvalds @ 2008-02-12 23:33 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On Tue, 12 Feb 2008, Junio C Hamano wrote:
>
> This adds --relative option to diff family. When you start from
> a subdirectory,
>
> $ git diff --relative
Ack, except I think it should allow you to actually *set* what the diff is
relative to.
An example of that could be something like
git diff --relative=drivers/scsi/ a..b -- drivers/scsi/
where you aren't actually *in* that subdirectory, but for one reason or
another you're limiting the diff to just stuff in that subdirectory, and
want a diff that is relative to that one.
Hmm?
Linus
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] diff --relative: output paths as relative to the current subdirectory
2008-02-12 23:33 ` Linus Torvalds
@ 2008-02-12 23:43 ` Junio C Hamano
2008-02-12 23:53 ` Linus Torvalds
0 siblings, 1 reply; 8+ messages in thread
From: Junio C Hamano @ 2008-02-12 23:43 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
Linus Torvalds <torvalds@linux-foundation.org> writes:
> On Tue, 12 Feb 2008, Junio C Hamano wrote:
>>
>> This adds --relative option to diff family. When you start from
>> a subdirectory,
>>
>> $ git diff --relative
>
> Ack, except I think it should allow you to actually *set* what the diff is
> relative to.
>
> An example of that could be something like
>
> git diff --relative=drivers/scsi/ a..b -- drivers/scsi/
>
> where you aren't actually *in* that subdirectory, but for one reason or
> another you're limiting the diff to just stuff in that subdirectory, and
> want a diff that is relative to that one.
>
> Hmm?
Your example is shorter to type as:
(cd drivers/scsi && git diff --relative a..b --)
Do you envision a useful case where --relative=<foo> does not
cover the pathspec you give? IOW, with the "temporarily chdir
there" approach, you cannot express:
git diff --relative=block/ a..b -- drivers/scsi
but I do not think it is useful. On the other hand,
git diff --relative=drivers a..b -- drivers/scsi
does make sense but again that is:
(cd drivers && git diff --relative a..b -- scsi/)
So...
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] diff --relative: output paths as relative to the current subdirectory
2008-02-12 23:43 ` Junio C Hamano
@ 2008-02-12 23:53 ` Linus Torvalds
2008-02-13 0:09 ` Linus Torvalds
2008-02-13 0:59 ` Junio C Hamano
0 siblings, 2 replies; 8+ messages in thread
From: Linus Torvalds @ 2008-02-12 23:53 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On Tue, 12 Feb 2008, Junio C Hamano wrote:
>
> Your example is shorter to type as:
>
> (cd drivers/scsi && git diff --relative a..b --)
No it isn't. The above doesn't even work for bare repositories, or when
you want to look at a branch that has a different directory structure than
the currently-checked-out one.
Linus
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] diff --relative: output paths as relative to the current subdirectory
2008-02-12 23:53 ` Linus Torvalds
@ 2008-02-13 0:09 ` Linus Torvalds
2008-02-13 1:19 ` Junio C Hamano
2008-02-13 0:59 ` Junio C Hamano
1 sibling, 1 reply; 8+ messages in thread
From: Linus Torvalds @ 2008-02-13 0:09 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On Tue, 12 Feb 2008, Linus Torvalds wrote:
>
> No it isn't. The above doesn't even work for bare repositories, or when
> you want to look at a branch that has a different directory structure than
> the currently-checked-out one.
.. and I don't mean that as a theoretical thing. I don't personally use
bare directories directly very much (I push to them, but I seldom do any
other remote management than just repacking once in a while), but it _is_
a meaningful operation for various services like gitweb or gitk etc.
Obviously gitweb doesn't support that --relative thing right now, and
maybe it never makes sense in that context, but it's actually really
pleasant how many things *do* just "automatically work" with bare
repositories etc.
So I simply don't think that we should assume a working directory for any
basic git operation, unless that operation fundamentally needs one because
it's only defined for a system with working directories (which is fairly
rare, but obviously happens: "git reset --hard", "git pull/merge", "git
checkout" etc).
Linus
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] diff --relative: output paths as relative to the current subdirectory
2008-02-13 0:09 ` Linus Torvalds
@ 2008-02-13 1:19 ` Junio C Hamano
2008-02-13 8:33 ` Junio C Hamano
0 siblings, 1 reply; 8+ messages in thread
From: Junio C Hamano @ 2008-02-13 1:19 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
Linus Torvalds <torvalds@linux-foundation.org> writes:
> So I simply don't think that we should assume a working directory for any
> basic git operation, unless that operation fundamentally needs one because
> it's only defined for a system with working directories (which is fairly
> rare, but obviously happens: "git reset --hard", "git pull/merge", "git
> checkout" etc).
Yeah, but that begs for a larger design-level question.
Instead of treating "diff --relative=drivers/ a..b", as a
special case, shouldn't we have a more general "I may be in a
bare repository, but please pretend that my prefix were this
path" option?
$ git --prefix=drivers/ diff --relative a..b -- scsi
$ git --prefix=drivers/scsi log a..b .
Of course, if you are truly in a bare repository and if you did
an operation that wants a work tree, you would get mostly
useless results, e.g.
$ git --prefix=fs/ diff v2.6.24 -- ext3
will give you tons of whole-file removals.
I suspect that a lot of existing code assumes a non NULL prefix
automatically means we have work tree, which needs to be fixed,
if we go this route, though.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] diff --relative: output paths as relative to the current subdirectory
2008-02-13 1:19 ` Junio C Hamano
@ 2008-02-13 8:33 ` Junio C Hamano
0 siblings, 0 replies; 8+ messages in thread
From: Junio C Hamano @ 2008-02-13 8:33 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
Junio C Hamano <gitster@pobox.com> writes:
> Linus Torvalds <torvalds@linux-foundation.org> writes:
>
>> So I simply don't think that we should assume a working directory for any
>> basic git operation, unless that operation fundamentally needs one because
>> it's only defined for a system with working directories (which is fairly
>> rare, but obviously happens: "git reset --hard", "git pull/merge", "git
>> checkout" etc).
>
> Yeah, but that begs for a larger design-level question.
>
> Instead of treating "diff --relative=drivers/ a..b", as a
> special case, shouldn't we have a more general "I may be in a
> bare repository, but please pretend that my prefix were this
> path" option?
>
> $ git --prefix=drivers/ diff --relative a..b -- scsi
> $ git --prefix=drivers/scsi log a..b .
>
> Of course, if you are truly in a bare repository and if you did
> an operation that wants a work tree, you would get mostly
> useless results, e.g.
>
> $ git --prefix=fs/ diff v2.6.24 -- ext3
>
> will give you tons of whole-file removals.
>
> I suspect that a lot of existing code assumes a non NULL prefix
> automatically means we have work tree, which needs to be fixed,
> if we go this route, though.
This does not address the above issue, but simply adds the
special purpose --relative=<path>.
The earlier one had the option described only in "git-diff"
manual page, simply because I originally planned to do this only
for "git-diff" Porcelain and nothing else. But it should have
been described as a general diff option. This moves the
description where it belongs to.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/diff-options.txt | 8 ++++++++
Documentation/git-diff.txt | 5 -----
diff.c | 4 ++++
revision.c | 2 +-
4 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 8d35cbd..8dc5b00 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -170,6 +170,14 @@ endif::git-format-patch[]
Swap two inputs; that is, show differences from index or
on-disk file to tree contents.
+--relative[=<path>]::
+ When run from a subdirectory of the project, it can be
+ told to exclude changes outside the directory and show
+ pathnames relative to it with this option. When you are
+ not in a subdirectory (e.g. in a bare repository), you
+ can name which subdirectory to make the output relative
+ to by giving a <path> as an argument.
+
--text::
Treat all files as text.
diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt
index 012bbdc..57c2862 100644
--- a/Documentation/git-diff.txt
+++ b/Documentation/git-diff.txt
@@ -78,11 +78,6 @@ OPTIONS
:git-diff: 1
include::diff-options.txt[]
---relative::
- When run from a subdirectory of the project, it can be
- told to exclude changes outside the directory and show
- pathnames relative to it with this option.
-
<path>...::
The <paths> parameters, when given, are used to limit
the diff to the named paths (you can give directory
diff --git a/diff.c b/diff.c
index db4bd55..2b89b16 100644
--- a/diff.c
+++ b/diff.c
@@ -2302,6 +2302,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
options->detect_rename = 0;
else if (!strcmp(arg, "--relative"))
DIFF_OPT_SET(options, RELATIVE_NAME);
+ else if (!prefixcmp(arg, "--relative=")) {
+ DIFF_OPT_SET(options, RELATIVE_NAME);
+ options->prefix = arg + 11;
+ }
/* xdiff options */
else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space"))
diff --git a/revision.c b/revision.c
index 6d9188b..4d6f57b 100644
--- a/revision.c
+++ b/revision.c
@@ -720,7 +720,7 @@ void init_revisions(struct rev_info *revs, const char *prefix)
revs->commit_format = CMIT_FMT_DEFAULT;
diff_setup(&revs->diffopt);
- if (prefix) {
+ if (prefix && !revs->diffopt.prefix) {
revs->diffopt.prefix = prefix;
revs->diffopt.prefix_length = strlen(prefix);
}
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] diff --relative: output paths as relative to the current subdirectory
2008-02-12 23:53 ` Linus Torvalds
2008-02-13 0:09 ` Linus Torvalds
@ 2008-02-13 0:59 ` Junio C Hamano
1 sibling, 0 replies; 8+ messages in thread
From: Junio C Hamano @ 2008-02-13 0:59 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
Linus Torvalds <torvalds@linux-foundation.org> writes:
> On Tue, 12 Feb 2008, Junio C Hamano wrote:
>>
>> Your example is shorter to type as:
>>
>> (cd drivers/scsi && git diff --relative a..b --)
>
> No it isn't. The above doesn't even work for bare
> repositories,...
AHHHHH. You are right.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2008-02-13 8:34 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-12 22:26 [PATCH/RFC] diff --relative: output paths as relative to the current subdirectory Junio C Hamano
2008-02-12 23:33 ` Linus Torvalds
2008-02-12 23:43 ` Junio C Hamano
2008-02-12 23:53 ` Linus Torvalds
2008-02-13 0:09 ` Linus Torvalds
2008-02-13 1:19 ` Junio C Hamano
2008-02-13 8:33 ` Junio C Hamano
2008-02-13 0:59 ` Junio C Hamano
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).