From: Harrison McCullough Date: Mon, 05 Jan 2026 22:56:37 GMT Subject: Unexpected behavior in git diff --relative= Message-ID: What did you do before the bug happened? (Steps to reproduce your issue) - Create a "foo.txt" file - Commit the "foo.txt" - Modify the "foo.txt" file - Create a "foo/bar.txt" file - Commit the "foo/bar.txt" - Modify the "foo/bar.txt" file - Run `git diff --name-only --relative=foo` What did you expect to happen? (Expected behavior) I would expect to only see modified files inside the "foo/" directory. For example, I would expect this to be the output: ``` $ git diff --name-only --relative=foo bar.txt ``` What happened instead? (Actual behavior) Both the "foo/bar.txt" _and_ the "foo.txt" files were listed--but the "foo.txt" file had the "foo" prefix stripped, appearing as just ".txt". ``` $ git diff --name-only --relative=foo .txt bar.txt ``` What's different between what you expected and what actually happened? Using the `--relative=` flag to `git diff` appears to simply remove the prefix from each file, regardless of whether that is a full path prefix or just part of the file name. Anything else you want to add: This is the relevant part of the man page for `git-diff`: > 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 as an argument. > --no-relative can be used to countermand both diff.relative config option and > previous --relative. When I read this for the first time, I imagined that the behavior would be as follows: - `git diff`: include all changes, display file names beginning from repository root - `git diff .`: include all changes in the current directory and "below", display file names beginning from repository root - `git diff --relative=. .`: include all changes in the current directory and "below", display file names beginning from the current directory - E.g. if the repository root is `/home/bob/repo/` and the current directory is `/home/bob/repo/foo/bar/`, then a modified file `/home/bob/repo/foo/bar/baz/qux.txt` would be displayed as `baz/qux.txt` - `git diff --relative=.. ..`: include all changes in the parent directory and "below", display file names beginning from the parent directory - E.g. if the repository root is `/home/bob/repo/` and the current directory is `/home/bob/repo/foo/bar/`, then a modified file `/home/bob/repo/foo/bar/baz/qux.txt` would be displayed as `bar/baz/qux.txt` I understand that my initial assumption may not be the intended behavior. However, I don't think that stripping a prefix of a file name just because the file name matched the argument to `--relative` makes much sense. If that _is_ the desired behavior, I think that `--strip-prefix` or something similar would be a better name. The name "relative", to me, makes it sound like it is logically connected to the directory structure. In addition, the description of the `--relative` flag claims that "it can be told to exclude changes outside the directory ...". This implies that the argument should be a directory. In practice, the argument _can_ be a directory, but that isn't verified. If this flag is working exactly as intended, then perhaps a clarifying comment can be added to the documentation to explicitly state that the argument is matched against the full file path, starting at the repository root, and is removed from the beginning of the path (and the file is included in the output) if it matches--regardless of whether the match matches a full directory path or just the first portion of a file name. I will note that if you want to make sure that the argument to the `--relative` flag only matches against entire directories, not file name prefixes, you can simply append a trailing slash to the end. In the case of the example I provided above, I can run the following and get reasonable behavior: ``` $ git diff --name-only --relative=foo/ bar.txt ``` [System Info] git version: git version 2.46.2 cpu: arm64 no commit associated with this build sizeof-long: 8 sizeof-size_t: 8 shell-path: /bin/sh feature: fsmonitor--daemon libcurl: 8.4.0 zlib: 1.2.12 uname: Darwin 24.6.0 Darwin Kernel Version 24.6.0: Mon Jul 14 11:30:55 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T6031 arm64 compiler info: clang: 15.0.0 (clang-1500.3.9.4) libc info: no libc information available $SHELL (typically, interactive shell): /opt/homebrew/bin/bash [Enabled Hooks] -Harrison McCullough