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>
Laurent Arnoud committed
May 22, 2020 at 12:46 UTC
c28ded83fc95be8157c851c8be179733a7d4b137
5 files changed
+108
-7
Documentation/config/diff.txt
+4
@@ -105,6 +105,10 @@ diff.mnemonicPrefix::
105
diff.noprefix::
106
If set, 'git diff' does not show any source or destination prefix.
107
108
+diff.relative::
109
+ If set to 'true', 'git diff' does not show changes outside of the directory
110
+ and show pathnames relative to the current directory.
111
+
112
diff.orderFile::
113
File indicating how to order files within a diff.
114
See the '-O' option to linkgit:git-diff[1] for details.
Documentation/diff-options.txt
+4
-1
@@ -643,15 +643,18 @@ ifndef::git-format-patch[]
643
-R::
644
Swap two inputs; that is, show differences from index or
645
on-disk file to tree contents.
646
+endif::git-format-patch[]
647
648
--relative[=<path>]::
649
+--no-relative::
650
When run from a subdirectory of the project, it can be
651
told to exclude changes outside the directory and show
652
pathnames relative to it with this option. When you are
653
not in a subdirectory (e.g. in a bare repository), you
654
can name which subdirectory to make the output relative
655
to by giving a <path> as an argument.
654
-endif::git-format-patch[]
656
+ `--no-relative` can be used to countermand both `diff.relative` config
657
+ option and previous `--relative`.
658
659
-a::
660
--text::
diff.c
+8
-3
@@ -48,6 +48,7 @@ static const char *diff_order_file_cfg;
48
int diff_auto_refresh_index = 1;
49
static int diff_mnemonic_prefix;
50
static int diff_no_prefix;
51
+static int diff_relative;
52
static int diff_stat_graph_width;
53
static int diff_dirstat_permille_default = 30;
54
static struct diff_options default_diff_options;
@@ -386,6 +387,10 @@ int git_diff_ui_config(const char *var, const char *value, void *cb)
387
diff_no_prefix = git_config_bool(var, value);
388
return 0;
389
}
390
+ if (!strcmp(var, "diff.relative")) {
391
+ diff_relative = git_config_bool(var, value);
392
+ return 0;
393
+ }
394
if (!strcmp(var, "diff.statgraphwidth")) {
395
diff_stat_graph_width = git_config_int(var, value);
396
return 0;
@@ -4538,6 +4543,7 @@ void repo_diff_setup(struct repository *r, struct diff_options *options)
4543
options->interhunkcontext = diff_interhunk_context_default;
4544
options->ws_error_highlight = ws_error_highlight_default;
4545
options->flags.rename_empty = 1;
4546
+ options->flags.relative_name = diff_relative;
4547
options->objfind = NULL;
4548
4549
/* pathchange left =NULL by default */
@@ -5195,8 +5201,7 @@ static int diff_opt_relative(const struct option *opt,
5201
{
5202
struct diff_options *options = opt->value;
5203
5198
- BUG_ON_OPT_NEG(unset);
5199
- options->flags.relative_name = 1;
5204
+ options->flags.relative_name = !unset;
5205
if (arg)
5206
options->prefix = arg;
5207
return 0;
@@ -5492,7 +5497,7 @@ static void prep_parse_options(struct diff_options *options)
5497
OPT_GROUP(N_("Other diff options")),
5498
OPT_CALLBACK_F(0, "relative", options, N_("<prefix>"),
5499
N_("when run from subdir, exclude changes outside and show relative paths"),
5495
- PARSE_OPT_NONEG | PARSE_OPT_OPTARG,
5500
+ PARSE_OPT_OPTARG,
5501
diff_opt_relative),
5502
OPT_BOOL('a', "text", &options->flags.text,
5503
N_("treat all files as text")),
t/t4014-format-patch.sh
+13
@@ -1602,6 +1602,19 @@ test_expect_success 'format patch ignores color.ui' '
1602
test_cmp expect actual
1603
'
1604
1605
+test_expect_success 'format patch respects diff.relative' '
1606
+ rm -rf subdir &&
1607
+ mkdir subdir &&
1608
+ echo other content >subdir/file2 &&
1609
+ git add subdir/file2 &&
1610
+ git commit -F msg &&
1611
+ test_unconfig diff.relative &&
1612
+ git format-patch --relative=subdir --stdout -1 >expect &&
1613
+ test_config diff.relative true &&
1614
+ git -C subdir format-patch --stdout -1 >actual &&
1615
+ test_cmp expect actual
1616
+'
1617
+
1618
test_expect_success 'cover letter with invalid --cover-from-description and config' '
1619
test_config branch.rebuild-1.description "config subject
1620
t/t4045-diff-relative.sh
+79
-3
@@ -8,7 +8,8 @@ test_expect_success 'setup' '
8
echo content >file1 &&
9
mkdir subdir &&
10
echo other content >subdir/file2 &&
11
- blob=$(git hash-object subdir/file2) &&
11
+ blob_file1=$(git hash-object file1) &&
12
+ blob_file2=$(git hash-object subdir/file2) &&
13
git add . &&
14
git commit -m one
15
'
@@ -18,7 +19,7 @@ check_diff () {
19
shift
20
expect=$1
21
shift
21
- short_blob=$(git rev-parse --short $blob)
22
+ short_blob=$(git rev-parse --short $blob_file2)
23
cat >expected <<-EOF
24
diff --git a/$expect b/$expect
25
new file mode 100644
@@ -70,7 +71,7 @@ check_raw () {
71
expect=$1
72
shift
73
cat >expected <<-EOF
73
- :000000 100644 $ZERO_OID $blob A $expect
74
+ :000000 100644 $ZERO_OID $blob_file2 A $expect
75
EOF
76
test_expect_success "--raw $*" "
77
git -C '$dir' diff --no-abbrev --raw $* HEAD^ >actual &&
@@ -86,4 +87,79 @@ do
87
check_$type . dir/file2 --relative=sub
88
done
89
90
+check_diff_relative_option () {
91
+ dir=$1
92
+ shift
93
+ expect=$1
94
+ shift
95
+ relative_opt=$1
96
+ shift
97
+ test_expect_success "config diff.relative $relative_opt -p $*" "
98
+ short_blob=\$(git rev-parse --short $blob_file2) &&
99
+ cat >expected <<-EOF &&
100
+ diff --git a/$expect b/$expect
101
+ new file mode 100644
102
+ index 0000000..\$short_blob
103
+ --- /dev/null
104
+ +++ b/$expect
105
+ @@ -0,0 +1 @@
106
+ +other content
107
+ EOF
108
+ test_config -C $dir diff.relative $relative_opt &&
109
+ git -C '$dir' diff -p $* HEAD^ >actual &&
110
+ test_cmp expected actual
111
+ "
112
+}
113
+
114
+check_diff_no_relative_option () {
115
+ dir=$1
116
+ shift
117
+ expect=$1
118
+ shift
119
+ relative_opt=$1
120
+ shift
121
+ test_expect_success "config diff.relative $relative_opt -p $*" "
122
+ short_blob_file1=\$(git rev-parse --short $blob_file1) &&
123
+ short_blob_file2=\$(git rev-parse --short $blob_file2) &&
124
+ cat >expected <<-EOF &&
125
+ diff --git a/file1 b/file1
126
+ new file mode 100644
127
+ index 0000000..\$short_blob_file1
128
+ --- /dev/null
129
+ +++ b/file1
130
+ @@ -0,0 +1 @@
131
+ +content
132
+ diff --git a/$expect b/$expect
133
+ new file mode 100644
134
+ index 0000000..\$short_blob_file2
135
+ --- /dev/null
136
+ +++ b/$expect
137
+ @@ -0,0 +1 @@
138
+ +other content
139
+ EOF
140
+ test_config -C $dir diff.relative $relative_opt &&
141
+ git -C '$dir' diff -p $* HEAD^ >actual &&
142
+ test_cmp expected actual
143
+ "
144
+}
145
+
146
+check_diff_no_relative_option . subdir/file2 false
147
+check_diff_no_relative_option . subdir/file2 true --no-relative
148
+check_diff_no_relative_option . subdir/file2 false --no-relative
149
+check_diff_no_relative_option subdir subdir/file2 false
150
+check_diff_no_relative_option subdir subdir/file2 true --no-relative
151
+check_diff_no_relative_option subdir subdir/file2 false --no-relative
152
+
153
+check_diff_relative_option . file2 false --relative=subdir/
154
+check_diff_relative_option . file2 false --relative=subdir
155
+check_diff_relative_option . file2 true --relative=subdir/
156
+check_diff_relative_option . file2 true --relative=subdir
157
+check_diff_relative_option subdir file2 false --relative
158
+check_diff_relative_option subdir file2 true --relative
159
+check_diff_relative_option subdir file2 true
160
+check_diff_relative_option subdir file2 false --no-relative --relative
161
+check_diff_relative_option subdir file2 true --no-relative --relative
162
+check_diff_relative_option . file2 false --no-relative --relative=subdir
163
+check_diff_relative_option . file2 true --no-relative --relative=subdir
164
+
165
test_done