diff: add config option relative

The `diff.relative` boolean option set to `true` shows only changes in
the current directory/value specified by the `path` argument of the
`relative` option and shows pathnames relative to the aforementioned
directory.

Teach `--no-relative` to override earlier `--relative`

Add for git-format-patch(1) options documentation `--relative` and
`--no-relative`

Signed-off-by: Laurent Arnoud <laurent@spkdev.net>
Acked-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Laurent Arnoud 2020-05-22 12:46:18 +02:00 committed by Junio C Hamano
parent efcab5b7a3
commit c28ded83fc
5 changed files with 108 additions and 7 deletions

View File

@ -105,6 +105,10 @@ diff.mnemonicPrefix::
diff.noprefix:: diff.noprefix::
If set, 'git diff' does not show any source or destination prefix. If set, 'git diff' does not show any source or destination prefix.


diff.relative::
If set to 'true', 'git diff' does not show changes outside of the directory
and show pathnames relative to the current directory.

diff.orderFile:: diff.orderFile::
File indicating how to order files within a diff. File indicating how to order files within a diff.
See the '-O' option to linkgit:git-diff[1] for details. See the '-O' option to linkgit:git-diff[1] for details.

View File

@ -643,15 +643,18 @@ ifndef::git-format-patch[]
-R:: -R::
Swap two inputs; that is, show differences from index or Swap two inputs; that is, show differences from index or
on-disk file to tree contents. on-disk file to tree contents.
endif::git-format-patch[]


--relative[=<path>]:: --relative[=<path>]::
--no-relative::
When run from a subdirectory of the project, it can be When run from a subdirectory of the project, it can be
told to exclude changes outside the directory and show told to exclude changes outside the directory and show
pathnames relative to it with this option. When you are pathnames relative to it with this option. When you are
not in a subdirectory (e.g. in a bare repository), you not in a subdirectory (e.g. in a bare repository), you
can name which subdirectory to make the output relative can name which subdirectory to make the output relative
to by giving a <path> as an argument. to by giving a <path> as an argument.
endif::git-format-patch[] `--no-relative` can be used to countermand both `diff.relative` config
option and previous `--relative`.


-a:: -a::
--text:: --text::

11
diff.c
View File

@ -48,6 +48,7 @@ static const char *diff_order_file_cfg;
int diff_auto_refresh_index = 1; int diff_auto_refresh_index = 1;
static int diff_mnemonic_prefix; static int diff_mnemonic_prefix;
static int diff_no_prefix; static int diff_no_prefix;
static int diff_relative;
static int diff_stat_graph_width; static int diff_stat_graph_width;
static int diff_dirstat_permille_default = 30; static int diff_dirstat_permille_default = 30;
static struct diff_options default_diff_options; static struct diff_options default_diff_options;
@ -386,6 +387,10 @@ int git_diff_ui_config(const char *var, const char *value, void *cb)
diff_no_prefix = git_config_bool(var, value); diff_no_prefix = git_config_bool(var, value);
return 0; return 0;
} }
if (!strcmp(var, "diff.relative")) {
diff_relative = git_config_bool(var, value);
return 0;
}
if (!strcmp(var, "diff.statgraphwidth")) { if (!strcmp(var, "diff.statgraphwidth")) {
diff_stat_graph_width = git_config_int(var, value); diff_stat_graph_width = git_config_int(var, value);
return 0; return 0;
@ -4538,6 +4543,7 @@ void repo_diff_setup(struct repository *r, struct diff_options *options)
options->interhunkcontext = diff_interhunk_context_default; options->interhunkcontext = diff_interhunk_context_default;
options->ws_error_highlight = ws_error_highlight_default; options->ws_error_highlight = ws_error_highlight_default;
options->flags.rename_empty = 1; options->flags.rename_empty = 1;
options->flags.relative_name = diff_relative;
options->objfind = NULL; options->objfind = NULL;


/* pathchange left =NULL by default */ /* pathchange left =NULL by default */
@ -5195,8 +5201,7 @@ static int diff_opt_relative(const struct option *opt,
{ {
struct diff_options *options = opt->value; struct diff_options *options = opt->value;


BUG_ON_OPT_NEG(unset); options->flags.relative_name = !unset;
options->flags.relative_name = 1;
if (arg) if (arg)
options->prefix = arg; options->prefix = arg;
return 0; return 0;
@ -5492,7 +5497,7 @@ static void prep_parse_options(struct diff_options *options)
OPT_GROUP(N_("Other diff options")), OPT_GROUP(N_("Other diff options")),
OPT_CALLBACK_F(0, "relative", options, N_("<prefix>"), OPT_CALLBACK_F(0, "relative", options, N_("<prefix>"),
N_("when run from subdir, exclude changes outside and show relative paths"), N_("when run from subdir, exclude changes outside and show relative paths"),
PARSE_OPT_NONEG | PARSE_OPT_OPTARG, PARSE_OPT_OPTARG,
diff_opt_relative), diff_opt_relative),
OPT_BOOL('a', "text", &options->flags.text, OPT_BOOL('a', "text", &options->flags.text,
N_("treat all files as text")), N_("treat all files as text")),

View File

@ -1602,6 +1602,19 @@ test_expect_success 'format patch ignores color.ui' '
test_cmp expect actual test_cmp expect actual
' '


test_expect_success 'format patch respects diff.relative' '
rm -rf subdir &&
mkdir subdir &&
echo other content >subdir/file2 &&
git add subdir/file2 &&
git commit -F msg &&
test_unconfig diff.relative &&
git format-patch --relative=subdir --stdout -1 >expect &&
test_config diff.relative true &&
git -C subdir format-patch --stdout -1 >actual &&
test_cmp expect actual
'

test_expect_success 'cover letter with invalid --cover-from-description and config' ' test_expect_success 'cover letter with invalid --cover-from-description and config' '
test_config branch.rebuild-1.description "config subject test_config branch.rebuild-1.description "config subject



View File

@ -8,7 +8,8 @@ test_expect_success 'setup' '
echo content >file1 && echo content >file1 &&
mkdir subdir && mkdir subdir &&
echo other content >subdir/file2 && echo other content >subdir/file2 &&
blob=$(git hash-object subdir/file2) && blob_file1=$(git hash-object file1) &&
blob_file2=$(git hash-object subdir/file2) &&
git add . && git add . &&
git commit -m one git commit -m one
' '
@ -18,7 +19,7 @@ check_diff () {
shift shift
expect=$1 expect=$1
shift shift
short_blob=$(git rev-parse --short $blob) short_blob=$(git rev-parse --short $blob_file2)
cat >expected <<-EOF cat >expected <<-EOF
diff --git a/$expect b/$expect diff --git a/$expect b/$expect
new file mode 100644 new file mode 100644
@ -70,7 +71,7 @@ check_raw () {
expect=$1 expect=$1
shift shift
cat >expected <<-EOF cat >expected <<-EOF
:000000 100644 $ZERO_OID $blob A $expect :000000 100644 $ZERO_OID $blob_file2 A $expect
EOF EOF
test_expect_success "--raw $*" " test_expect_success "--raw $*" "
git -C '$dir' diff --no-abbrev --raw $* HEAD^ >actual && git -C '$dir' diff --no-abbrev --raw $* HEAD^ >actual &&
@ -86,4 +87,79 @@ do
check_$type . dir/file2 --relative=sub check_$type . dir/file2 --relative=sub
done done


check_diff_relative_option () {
dir=$1
shift
expect=$1
shift
relative_opt=$1
shift
test_expect_success "config diff.relative $relative_opt -p $*" "
short_blob=\$(git rev-parse --short $blob_file2) &&
cat >expected <<-EOF &&
diff --git a/$expect b/$expect
new file mode 100644
index 0000000..\$short_blob
--- /dev/null
+++ b/$expect
@@ -0,0 +1 @@
+other content
EOF
test_config -C $dir diff.relative $relative_opt &&
git -C '$dir' diff -p $* HEAD^ >actual &&
test_cmp expected actual
"
}

check_diff_no_relative_option () {
dir=$1
shift
expect=$1
shift
relative_opt=$1
shift
test_expect_success "config diff.relative $relative_opt -p $*" "
short_blob_file1=\$(git rev-parse --short $blob_file1) &&
short_blob_file2=\$(git rev-parse --short $blob_file2) &&
cat >expected <<-EOF &&
diff --git a/file1 b/file1
new file mode 100644
index 0000000..\$short_blob_file1
--- /dev/null
+++ b/file1
@@ -0,0 +1 @@
+content
diff --git a/$expect b/$expect
new file mode 100644
index 0000000..\$short_blob_file2
--- /dev/null
+++ b/$expect
@@ -0,0 +1 @@
+other content
EOF
test_config -C $dir diff.relative $relative_opt &&
git -C '$dir' diff -p $* HEAD^ >actual &&
test_cmp expected actual
"
}

check_diff_no_relative_option . subdir/file2 false
check_diff_no_relative_option . subdir/file2 true --no-relative
check_diff_no_relative_option . subdir/file2 false --no-relative
check_diff_no_relative_option subdir subdir/file2 false
check_diff_no_relative_option subdir subdir/file2 true --no-relative
check_diff_no_relative_option subdir subdir/file2 false --no-relative

check_diff_relative_option . file2 false --relative=subdir/
check_diff_relative_option . file2 false --relative=subdir
check_diff_relative_option . file2 true --relative=subdir/
check_diff_relative_option . file2 true --relative=subdir
check_diff_relative_option subdir file2 false --relative
check_diff_relative_option subdir file2 true --relative
check_diff_relative_option subdir file2 true
check_diff_relative_option subdir file2 false --no-relative --relative
check_diff_relative_option subdir file2 true --no-relative --relative
check_diff_relative_option . file2 false --no-relative --relative=subdir
check_diff_relative_option . file2 true --no-relative --relative=subdir

test_done test_done