@@ -195,6 +195,7 @@ test_expect_success 'multiple exclusions' '
195
195
'
196
196
197
197
test_expect_success ' t_e_i() exclude case #8' '
198
+ test_when_finished "rm -fr case8" &&
198
199
git init case8 &&
199
200
(
200
201
cd case8 &&
@@ -244,4 +245,184 @@ test_expect_success 'grep --untracked PATTERN :(exclude)*FILE' '
244
245
test_cmp expect-grep actual-grep
245
246
'
246
247
248
+ # Depending on the command, all negative pathspec needs to subtract
249
+ # either from the full tree, or from the current directory.
250
+ #
251
+ # The sample tree checked out at this point has:
252
+ # file
253
+ # sub/file
254
+ # sub/file2
255
+ # sub/sub/file
256
+ # sub/sub/sub/file
257
+ # sub2/file
258
+ #
259
+ # but there may also be some cruft that interferes with "git clean"
260
+ # and "git add" tests.
261
+
262
+ test_expect_success ' archive with all negative' '
263
+ git reset --hard &&
264
+ git clean -f &&
265
+ git -C sub archive --format=tar HEAD -- ":!sub/" >archive &&
266
+ "$TAR" tf archive >actual &&
267
+ cat >expect <<-\EOF &&
268
+ file
269
+ file2
270
+ EOF
271
+ test_cmp expect actual
272
+ '
273
+
274
+ test_expect_success ' add with all negative' '
275
+ H=$(git rev-parse HEAD) &&
276
+ git reset --hard $H &&
277
+ git clean -f &&
278
+ test_when_finished "git reset --hard $H" &&
279
+ for path in file sub/file sub/sub/file sub2/file
280
+ do
281
+ echo smudge >>"$path" || return 1
282
+ done &&
283
+ git -C sub add -- ":!sub/" &&
284
+ git diff --name-only --no-renames --cached >actual &&
285
+ cat >expect <<-\EOF &&
286
+ file
287
+ sub/file
288
+ sub2/file
289
+ EOF
290
+ test_cmp expect actual &&
291
+ git diff --name-only --no-renames >actual &&
292
+ echo sub/sub/file >expect &&
293
+ test_cmp expect actual
294
+ '
295
+
296
+ test_expect_success ' add -p with all negative' '
297
+ H=$(git rev-parse HEAD) &&
298
+ git reset --hard $H &&
299
+ git clean -f &&
300
+ test_when_finished "git reset --hard $H" &&
301
+ for path in file sub/file sub/sub/file sub2/file
302
+ do
303
+ echo smudge >>"$path" || return 1
304
+ done &&
305
+ yes | git -C sub add -p -- ":!sub/" &&
306
+ git diff --name-only --no-renames --cached >actual &&
307
+ cat >expect <<-\EOF &&
308
+ file
309
+ sub/file
310
+ sub2/file
311
+ EOF
312
+ test_cmp expect actual &&
313
+ git diff --name-only --no-renames >actual &&
314
+ echo sub/sub/file >expect &&
315
+ test_cmp expect actual
316
+ '
317
+
318
+ test_expect_success ' clean with all negative' '
319
+ H=$(git rev-parse HEAD) &&
320
+ git reset --hard $H &&
321
+ test_when_finished "git reset --hard $H && git clean -f" &&
322
+ git clean -f &&
323
+ for path in file9 sub/file9 sub/sub/file9 sub2/file9
324
+ do
325
+ echo cruft >"$path" || return 1
326
+ done &&
327
+ git -C sub clean -f -- ":!sub" &&
328
+ test_path_is_file file9 &&
329
+ test_path_is_missing sub/file9 &&
330
+ test_path_is_file sub/sub/file9 &&
331
+ test_path_is_file sub2/file9
332
+ '
333
+
334
+ test_expect_success ' commit with all negative' '
335
+ H=$(git rev-parse HEAD) &&
336
+ git reset --hard $H &&
337
+ test_when_finished "git reset --hard $H" &&
338
+ for path in file sub/file sub/sub/file sub2/file
339
+ do
340
+ echo smudge >>"$path" || return 1
341
+ done &&
342
+ git -C sub commit -m sample -- ":!sub/" &&
343
+ git diff --name-only --no-renames HEAD^ HEAD >actual &&
344
+ cat >expect <<-\EOF &&
345
+ file
346
+ sub/file
347
+ sub2/file
348
+ EOF
349
+ test_cmp expect actual &&
350
+ git diff --name-only --no-renames HEAD >actual &&
351
+ echo sub/sub/file >expect &&
352
+ test_cmp expect actual
353
+ '
354
+
355
+ test_expect_success ' reset with all negative' '
356
+ H=$(git rev-parse HEAD) &&
357
+ git reset --hard $H &&
358
+ test_when_finished "git reset --hard $H" &&
359
+ for path in file sub/file sub/sub/file sub2/file
360
+ do
361
+ echo smudge >>"$path" &&
362
+ git add "$path" || return 1
363
+ done &&
364
+ git -C sub reset --quiet -- ":!sub/" &&
365
+ git diff --name-only --no-renames --cached >actual &&
366
+ echo sub/sub/file >expect &&
367
+ test_cmp expect actual
368
+ '
369
+
370
+ test_expect_success ' grep with all negative' '
371
+ H=$(git rev-parse HEAD) &&
372
+ git reset --hard $H &&
373
+ test_when_finished "git reset --hard $H" &&
374
+ for path in file sub/file sub/sub/file sub2/file
375
+ do
376
+ echo "needle $path" >>"$path" || return 1
377
+ done &&
378
+ git -C sub grep -h needle -- ":!sub/" >actual &&
379
+ cat >expect <<-\EOF &&
380
+ needle sub/file
381
+ EOF
382
+ test_cmp expect actual
383
+ '
384
+
385
+ test_expect_success ' ls-files with all negative' '
386
+ git reset --hard &&
387
+ git -C sub ls-files -- ":!sub/" >actual &&
388
+ cat >expect <<-\EOF &&
389
+ file
390
+ file2
391
+ EOF
392
+ test_cmp expect actual
393
+ '
394
+
395
+ test_expect_success ' rm with all negative' '
396
+ git reset --hard &&
397
+ test_when_finished "git reset --hard" &&
398
+ git -C sub rm -r --cached -- ":!sub/" >actual &&
399
+ git diff --name-only --no-renames --diff-filter=D --cached >actual &&
400
+ cat >expect <<-\EOF &&
401
+ sub/file
402
+ sub/file2
403
+ EOF
404
+ test_cmp expect actual
405
+ '
406
+
407
+ test_expect_success ' stash with all negative' '
408
+ H=$(git rev-parse HEAD) &&
409
+ git reset --hard $H &&
410
+ test_when_finished "git reset --hard $H" &&
411
+ for path in file sub/file sub/sub/file sub2/file
412
+ do
413
+ echo smudge >>"$path" || return 1
414
+ done &&
415
+ git -C sub stash push -m sample -- ":!sub/" &&
416
+ git diff --name-only --no-renames HEAD >actual &&
417
+ echo sub/sub/file >expect &&
418
+ test_cmp expect actual &&
419
+ git stash show --name-only >actual &&
420
+ cat >expect <<-\EOF &&
421
+ file
422
+ sub/file
423
+ sub2/file
424
+ EOF
425
+ test_cmp expect actual
426
+ '
427
+
247
428
test_done
0 commit comments