Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package chezmoi for openSUSE:Factory checked in at 2025-11-04 18:41:30 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/chezmoi (Old) and /work/SRC/openSUSE:Factory/.chezmoi.new.1980 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "chezmoi" Tue Nov 4 18:41:30 2025 rev:86 rq:1315354 version:2.67.0 Changes: -------- --- /work/SRC/openSUSE:Factory/chezmoi/chezmoi.changes 2025-10-22 12:20:58.039307531 +0200 +++ /work/SRC/openSUSE:Factory/.chezmoi.new.1980/chezmoi.changes 2025-11-04 18:41:58.972481947 +0100 @@ -1,0 +2,17 @@ +Mon Nov 3 17:24:40 UTC 2025 - Filippo Bonazzi <[email protected]> + +- Update to version 2.67.0: + - Features + * feat: Make re-add add and remove entries in exact_ directories + - Fixes + * fix: Make all template funcs available in diff and merge args + * fix: Ignore special-use domains when extracting hostname from /etc/hosts + * fix: Fix fromIni | toIni template func round trip with quoted strings + * fix: Fix pattern in install script + - Documentation + * docs: Improve description of --create flag + * docs: Update VSCode merge tool instructions to handles spaces in paths + - Other + * Update documentation for --create option in add.md + +------------------------------------------------------------------- Old: ---- chezmoi-2.66.1.obscpio New: ---- chezmoi-2.67.0.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ chezmoi.spec ++++++ --- /var/tmp/diff_new_pack.g9bK5V/_old 2025-11-04 18:41:59.832518152 +0100 +++ /var/tmp/diff_new_pack.g9bK5V/_new 2025-11-04 18:41:59.836518320 +0100 @@ -17,7 +17,7 @@ Name: chezmoi -Version: 2.66.1 +Version: 2.67.0 Release: 0 Summary: A multi-host manager for dotfiles License: MIT ++++++ _service ++++++ --- /var/tmp/diff_new_pack.g9bK5V/_old 2025-11-04 18:41:59.884520341 +0100 +++ /var/tmp/diff_new_pack.g9bK5V/_new 2025-11-04 18:41:59.892520679 +0100 @@ -2,7 +2,7 @@ <service name="obs_scm" mode="manual"> <param name="scm">git</param> <param name="url">https://github.com/twpayne/chezmoi.git</param> - <param name="revision">v2.66.1</param> + <param name="revision">v2.67.0</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> </service> ++++++ chezmoi-2.66.1.obscpio -> chezmoi-2.67.0.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/.github/CODE_OF_CONDUCT.md new/chezmoi-2.67.0/.github/CODE_OF_CONDUCT.md --- old/chezmoi-2.66.1/.github/CODE_OF_CONDUCT.md 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/.github/CODE_OF_CONDUCT.md 2025-11-02 19:55:46.000000000 +0100 @@ -4,16 +4,5 @@ Conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/) with the following additions for LLM (Large Language Model)-generated contributions: -* You may use any tools you wish to generate content for chezmoi. - -* You must review the content for correctness and legal obligations before - contributing it. - -* If you contribute un-reviewed LLM-generated content with the admission that - you do not understand the content then you will receive a warning. - -* If you contribute un-reviewed LLM-generated content without any admission that - you used an LLM then you will immediately be banned without recourse. - -Example LLMs include, but are not limited to, ChatGPT, Claude, Gemini, GitHub -Copilot, and Llama. +* Any contribution of any LLM-generated content will be rejected and result in + an immediate ban for the contributor, without recourse. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/.github/workflows/installer.yml new/chezmoi-2.67.0/.github/workflows/installer.yml --- old/chezmoi-2.66.1/.github/workflows/installer.yml 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/.github/workflows/installer.yml 2025-11-02 19:55:46.000000000 +0100 @@ -40,7 +40,7 @@ contents: read steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 - - uses: reviewdog/action-misspell@9daa94af4357dddb6fd3775de806bc0a8e98d3e4 + - uses: reviewdog/action-misspell@d6429416b12b09b4e2768307d53bef58d172e962 with: locale: US test-install-sh: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/.github/workflows/main.yml new/chezmoi-2.67.0/.github/workflows/main.yml --- old/chezmoi-2.66.1/.github/workflows/main.yml 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/.github/workflows/main.yml 2025-11-02 19:55:46.000000000 +0100 @@ -18,12 +18,12 @@ CHOCOLATEY_VERSION: 2.5.1 # https://github.com/chocolatey/choco/releases COSIGN_VERSION: 2.6.1 # https://github.com/sigstore/cosign/releases https://github.com/goreleaser/goreleaser/issues/6195 GO_VERSION: 1.25.3 # https://go.dev/doc/devel/release - GOLANGCI_LINT_VERSION: 2.5.0 # https://github.com/golangci/golangci-lint/releases - GORELEASER_VERSION: 2.12.5 # https://github.com/goreleaser/goreleaser/releases + GOLANGCI_LINT_VERSION: 2.6.0 # https://github.com/golangci/golangci-lint/releases + GORELEASER_VERSION: 2.12.7 # https://github.com/goreleaser/goreleaser/releases PYTHON_VERSION: '3.10' # https://www.python.org/downloads/ RAGE_VERSION: 0.11.1 # https://github.com/str4d/rage/releases - SYFT_VERSION: 1.34.2 # https://github.com/anchore/syft/releases - UV_VERSION: 0.9.4 # https://github.com/astral-sh/uv/releases + SYFT_VERSION: 1.36.0 # https://github.com/anchore/syft/releases + UV_VERSION: 0.9.7 # https://github.com/astral-sh/uv/releases jobs: changes: runs-on: ubuntu-22.04 @@ -76,7 +76,7 @@ contents: read steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 - - uses: reviewdog/action-misspell@9daa94af4357dddb6fd3775de806bc0a8e98d3e4 + - uses: reviewdog/action-misspell@d6429416b12b09b4e2768307d53bef58d172e962 with: locale: US test-alpine: @@ -192,31 +192,31 @@ args: release --skip=sign --snapshot --timeout=1h - name: upload-artifact-chezmoi-darwin-amd64 if: github.event_name == 'push' || needs.changes.outputs.code == 'true' - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 with: name: chezmoi-darwin-amd64 path: dist/chezmoi-nocgo_darwin_amd64_v1/chezmoi - name: upload-artifact-chezmoi-darwin-arm64 if: github.event_name == 'push' || needs.changes.outputs.code == 'true' - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 with: name: chezmoi-darwin-arm64 path: dist/chezmoi-nocgo_darwin_arm64_v8.0/chezmoi - name: upload-artifact-chezmoi-linux-amd64 if: github.event_name == 'push' || needs.changes.outputs.code == 'true' - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 with: name: chezmoi-linux-amd64 path: dist/chezmoi-cgo-glibc_linux_amd64_v1/chezmoi - name: upload-artifact-chezmoi-linux-musl-amd64 if: github.event_name == 'push' || needs.changes.outputs.code == 'true' - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 with: name: chezmoi-linux-amd64-musl path: dist/chezmoi-cgo-musl_linux_amd64_v1/chezmoi - name: upload-artifact-chezmoi-windows-amd64.exe if: github.event_name == 'push' || needs.changes.outputs.code == 'true' - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 with: name: chezmoi-windows-amd64 path: dist/chezmoi-nocgo_windows_amd64_v1/chezmoi.exe @@ -280,7 +280,7 @@ with: cache-prefix: website-go go-version: ${{ env.GO_VERSION }} - - uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 + - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 with: enable-cache: true version: ${{ env.UV_VERSION }} @@ -473,7 +473,7 @@ with: cache-prefix: website-go go-version: ${{ env.GO_VERSION }} - - uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 + - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 with: enable-cache: true version: ${{ env.UV_VERSION }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/.golangci.yml new/chezmoi-2.67.0/.golangci.yml --- old/chezmoi-2.66.1/.golangci.yml 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/.golangci.yml 2025-11-02 19:55:46.000000000 +0100 @@ -42,6 +42,7 @@ - makezero - mirror - misspell + - modernize - nilerr - nilnesserr - nolintlint diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/assets/chezmoi.io/docs/developer-guide/contributing-changes.md new/chezmoi-2.67.0/assets/chezmoi.io/docs/developer-guide/contributing-changes.md --- old/chezmoi-2.66.1/assets/chezmoi.io/docs/developer-guide/contributing-changes.md 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/assets/chezmoi.io/docs/developer-guide/contributing-changes.md 2025-11-02 19:55:46.000000000 +0100 @@ -35,15 +35,27 @@ * The code passes [`golangci-lint`][golangci-lint]. You can ensure this by running `make lint`. -* The commit messages follow the [conventional commits specification][commits]. - chezmoi's release notes are generated directly from the commit messages. The - following criteria can be used to determine the commit type: - - * Small changes, such as fixing a typo or correcting grammar: `chore` - * Bug fixes: `fix` - * Extending an existing feature, or adding a new feature: `feat` - * Adding to, or updating, the documentation: `docs` - * Anything not covered by the above: `chore` +* The commit messages adhere to the [conventional commits specification][commits], + with the following additional requirements: + + * The first character of the commit message is uppercase, e.g: + + ```text + chore: Fix typo in test + ``` + + The purpose of this is to maintain consistency in chezmoi's release + notes, which are generated directly from the commit messages. + + * The commits do not have scopes (e.g. `chore(scope): Message` is invalid). + + The following criteria can be used to determine the commit type: + + * `fix`: bug fixes in chezmoi code + * `feat`: extending an existing feature or adding a new feature + * `docs`: adding to or updating the documentation + * `chore`: small changes, such as fixing a typo, correcting grammar + (including in documentation), or anything not covered by the above Examples can be found in the [commit history][history]. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/assets/chezmoi.io/docs/developer-guide/index.md new/chezmoi-2.67.0/assets/chezmoi.io/docs/developer-guide/index.md --- old/chezmoi-2.66.1/assets/chezmoi.io/docs/developer-guide/index.md 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/assets/chezmoi.io/docs/developer-guide/index.md 2025-11-02 19:55:46.000000000 +0100 @@ -3,10 +3,8 @@ !!! warning If you use an LLM (Large Language Model, like ChatGPT, Claude, Gemini, - GitHub Copilot, or Llama) to make a contribution then you must say so in - your contribution and you must carefully review your contribution for - correctness before sharing it. If you share un-reviewed LLM-generated - content then you will be immediately banned. See [`CODE_OF_CONDUCT.md`][coc] + GitHub Copilot, or Llama) to make any kind of contribution then you will + immediately be banned without recourse. See [`CODE_OF_CONDUCT.md`][coc] for more information. chezmoi is written in [Go][go] and development happens on [GitHub][github]. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/assets/chezmoi.io/docs/links/articles.md.yaml new/chezmoi-2.67.0/assets/chezmoi.io/docs/links/articles.md.yaml --- old/chezmoi-2.66.1/assets/chezmoi.io/docs/links/articles.md.yaml 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/assets/chezmoi.io/docs/links/articles.md.yaml 2025-11-02 19:55:46.000000000 +0100 @@ -605,3 +605,7 @@ version: 2.65.2 title: Testable Dotfiles Management With Chezmoi url: https://shunk031.me/post/testable-dotfiles-management-with-chezmoi/ +- date: '2025-11-02' + version: 2.66.1 + title: Maintaining KDE dotfiles with Chezmoi Modify Manager + url: https://www.lorenzobettini.it/2025/11/maintaining-kde-dotfiles-with-chezmoi-modify-manager/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/assets/chezmoi.io/docs/links/related-software.md new/chezmoi-2.67.0/assets/chezmoi.io/docs/links/related-software.md --- old/chezmoi-2.66.1/assets/chezmoi.io/docs/links/related-software.md 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/assets/chezmoi.io/docs/links/related-software.md 2025-11-02 19:55:46.000000000 +0100 @@ -49,13 +49,17 @@ chezmoi plugin for asdf version manager. +### [`github.com/main-branch/chezroot`](https://github.com/main-branch/chezroot) { id="main-branch/chezroot" } + +A `sudo` wrapper for chezmoi to manage root-owned files across your entire filesystem. + ### [`github.com/mass8326/zsh-chezmoi`](https://github.com/mass8326/zsh-chezmoi) { id="mass8326/zsh-chezmoi" } Add completion and aliases for chezmoi to make managing dotfiles easier to zsh. ### [`github.com/matmaer/chezmoi-mousse`](https://github.com/matmaer/chezmoi-mousse) { id="matmaer/chezmoi-mousse" } -Visual interface in the terminal for the chezmoi dotfile managar, with a wink to the mouse. +Visual interface in the terminal for the chezmoi dotfile manager, with a wink to the mouse. ### [Chezetc](https://silverrainz.me/chezetc/) { id="silverrainz.me/chezetc" } @@ -63,7 +67,7 @@ ### [`github.com/tcaxle/drapeau`](https://github.com/tcaxle/drapeau) { id="tcaxle/drapeau" } -An add-on to synchronize your colorschemes across systems and allow easy +An add-on to synchronize your color schemes across systems and allow easy colorscheme switching using chezmoi templates. ### [`github.com/VorpalBlade/chezmoi_modify_manager`](https://github.com/VorpalBlade/chezmoi_modify_manager) { id="vorpalblade/chezmoi_modify_manager" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/assets/chezmoi.io/docs/reference/commands/add.md new/chezmoi-2.67.0/assets/chezmoi.io/docs/reference/commands/add.md --- old/chezmoi-2.66.1/assets/chezmoi.io/docs/reference/commands/add.md 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/assets/chezmoi.io/docs/reference/commands/add.md 2025-11-02 19:55:46.000000000 +0100 @@ -23,6 +23,13 @@ Add files that should exist, irrespective of their contents. +Sets the `create_` source state attribute on the added file. + +A file will be created with the given contents if the file does not exist. +If the file already exists, then its contents will not be changed. +This allows for managing files with an initial state but should not be changed +by chezmoi afterwards. + ### `--encrypt` > Configuration: `add.encrypt` @@ -33,6 +40,12 @@ Set the `exact` attribute on added directories. +!!! warning + + Directories with the `exact` attributes are statefully synced between target and source directories. + When running `re-add`, any files deleted from the `exact` target directory will be removed from the source directory. + Likewise, any files added to the `exact` target directory, will be added to the source directory + ### `--follow` If the last part of a target is a symlink, add the target of the symlink diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/assets/chezmoi.io/docs/reference/commands/generate.md new/chezmoi-2.67.0/assets/chezmoi.io/docs/reference/commands/generate.md --- old/chezmoi-2.66.1/assets/chezmoi.io/docs/reference/commands/generate.md 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/assets/chezmoi.io/docs/reference/commands/generate.md 2025-11-02 19:55:46.000000000 +0100 @@ -12,6 +12,6 @@ ```sh chezmoi generate install.sh > install.sh -chezmoi git commit -m "$(chezmoi generate git-commit-message)" +chezmoi git -- commit -m "$(chezmoi generate git-commit-message)" chezmoi generate install-init-shell.sh $GITHUB_USERNAME ``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/assets/chezmoi.io/docs/user-guide/tools/merge.md new/chezmoi-2.67.0/assets/chezmoi.io/docs/user-guide/tools/merge.md --- old/chezmoi-2.66.1/assets/chezmoi.io/docs/user-guide/tools/merge.md 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/assets/chezmoi.io/docs/user-guide/tools/merge.md 2025-11-02 19:55:46.000000000 +0100 @@ -67,7 +67,7 @@ command = "bash" args = [ "-c", - "cp {{ .Target }} {{ .Target }}.base && code --new-window --wait --merge {{ .Destination }} {{ .Target }} {{ .Target }}.base {{ .Source }}", + "cp {{ .Target | quote }} {{ printf "%s.base" .Target | quote }} && code --new-window --wait --merge {{ .Destination | quote }} {{ .Target | quote }} {{ printf "%s.base" .Target | quote }} {{ .Source | quote }}", ] ``` @@ -78,7 +78,7 @@ command: "bash" args: - "-c" - - "cp {{ .Target }} {{ .Target }}.base && code --new-window --wait --merge {{ .Destination }} {{ .Target }} {{ .Target }}.base {{ .Source }}" + - "cp {{ .Target | quote }} {{ printf \"%s.base\" .Target | quote }} && code --new-window --wait --merge {{ .Destination | quote }} {{ .Target | quote }} {{ printf \"%s.base\" .Target | quote }} {{ .Source | quote }}" ``` [bcomp]: https://www.scootersoftware.com/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/assets/scripts/install-local-bin.sh new/chezmoi-2.67.0/assets/scripts/install-local-bin.sh --- old/chezmoi-2.66.1/assets/scripts/install-local-bin.sh 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/assets/scripts/install-local-bin.sh 2025-11-02 19:55:46.000000000 +0100 @@ -317,7 +317,7 @@ checksums="${2}" basename="${target##*/}" - want="$(grep "${basename}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)" + want="$(grep "${basename}\$" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)" if [ -z "${want}" ]; then log_err "hash_sha256_verify unable to find checksum for ${target} in ${checksums}" return 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/assets/scripts/install.sh new/chezmoi-2.67.0/assets/scripts/install.sh --- old/chezmoi-2.66.1/assets/scripts/install.sh 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/assets/scripts/install.sh 2025-11-02 19:55:46.000000000 +0100 @@ -316,7 +316,7 @@ checksums="${2}" basename="${target##*/}" - want="$(grep "${basename}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)" + want="$(grep "${basename}\$" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)" if [ -z "${want}" ]; then log_err "hash_sha256_verify unable to find checksum for ${target} in ${checksums}" return 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/go.mod new/chezmoi-2.67.0/go.mod --- old/chezmoi-2.66.1/go.mod 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/go.mod 2025-11-02 19:55:46.000000000 +0100 @@ -29,9 +29,9 @@ github.com/Masterminds/sprig/v3 v3.3.0 github.com/Shopify/ejson v1.5.4 github.com/alecthomas/assert/v2 v2.11.0 - github.com/aws/aws-sdk-go-v2 v1.39.3 - github.com/aws/aws-sdk-go-v2/config v1.31.13 - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.39.7 + github.com/aws/aws-sdk-go-v2 v1.39.5 + github.com/aws/aws-sdk-go-v2/config v1.31.16 + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.39.10 github.com/bmatcuk/doublestar/v4 v4.9.1 github.com/bradenhilton/mozillainstallhash v1.0.1 github.com/charmbracelet/bubbles v0.20.0 @@ -48,7 +48,7 @@ github.com/gopasspw/gopass v1.15.18 github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 github.com/itchyny/gojq v0.12.17 - github.com/klauspost/compress v1.18.0 + github.com/klauspost/compress v1.18.1 github.com/mattn/go-runewidth v0.0.19 github.com/mitchellh/copystructure v1.2.0 github.com/muesli/combinator v0.3.0 @@ -100,16 +100,16 @@ github.com/alecthomas/repr v0.5.2 // indirect github.com/andybalholm/brotli v1.2.0 // indirect github.com/atotto/clipboard v0.1.4 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.18.17 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.10 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.10 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.10 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.18.20 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.12 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.12 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.12 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.10 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.29.7 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.2 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.38.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.12 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.0 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.4 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.39.0 // indirect github.com/aws/smithy-go v1.23.1 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect @@ -125,9 +125,10 @@ github.com/charmbracelet/harmonica v0.2.0 // indirect github.com/charmbracelet/x/ansi v0.10.2 // indirect github.com/charmbracelet/x/cellbuf v0.0.13 // indirect - github.com/charmbracelet/x/exp/slice v0.0.0-20251016201629-54e687c87a08 // indirect - github.com/charmbracelet/x/term v0.2.1 // indirect - github.com/clipperhouse/uax29/v2 v2.2.0 // indirect + github.com/charmbracelet/x/exp/slice v0.0.0-20251031172406-4542a189d0fb // indirect + github.com/charmbracelet/x/term v0.2.2 // indirect + github.com/clipperhouse/stringish v0.1.1 // indirect + github.com/clipperhouse/uax29/v2 v2.3.0 // indirect github.com/cloudflare/circl v1.6.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect github.com/creack/pty/v2 v2.0.0-20231209135443-03db72c7b76c // indirect @@ -216,7 +217,7 @@ github.com/yuin/goldmark-emoji v1.0.6 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/exp v0.0.0-20251017212417-90e834f514db // indirect + golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect golang.org/x/mod v0.29.0 // indirect golang.org/x/net v0.46.0 // indirect golang.org/x/tools v0.38.0 // indirect diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/go.sum new/chezmoi-2.67.0/go.sum --- old/chezmoi-2.66.1/go.sum 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/go.sum 2025-11-02 19:55:46.000000000 +0100 @@ -91,32 +91,32 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= -github.com/aws/aws-sdk-go-v2 v1.39.3 h1:h7xSsanJ4EQJXG5iuW4UqgP7qBopLpj84mpkNx3wPjM= -github.com/aws/aws-sdk-go-v2 v1.39.3/go.mod h1:yWSxrnioGUZ4WVv9TgMrNUeLV3PFESn/v+6T/Su8gnM= -github.com/aws/aws-sdk-go-v2/config v1.31.13 h1:wcqQB3B0PgRPUF5ZE/QL1JVOyB0mbPevHFoAMpemR9k= -github.com/aws/aws-sdk-go-v2/config v1.31.13/go.mod h1:ySB5D5ybwqGbT6c3GszZ+u+3KvrlYCUQNo62+hkKOFk= -github.com/aws/aws-sdk-go-v2/credentials v1.18.17 h1:skpEwzN/+H8cdrrtT8y+rvWJGiWWv0DeNAe+4VTf+Vs= -github.com/aws/aws-sdk-go-v2/credentials v1.18.17/go.mod h1:Ed+nXsaYa5uBINovJhcAWkALvXw2ZLk36opcuiSZfJM= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.10 h1:UuGVOX48oP4vgQ36oiKmW9RuSeT8jlgQgBFQD+HUiHY= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.10/go.mod h1:vM/Ini41PzvudT4YkQyE/+WiQJiQ6jzeDyU8pQKwCac= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.10 h1:mj/bdWleWEh81DtpdHKkw41IrS+r3uw1J/VQtbwYYp8= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.10/go.mod h1:7+oEMxAZWP8gZCyjcm9VicI0M61Sx4DJtcGfKYv2yKQ= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.10 h1:wh+/mn57yhUrFtLIxyFPh2RgxgQz/u+Yrf7hiHGHqKY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.10/go.mod h1:7zirD+ryp5gitJJ2m1BBux56ai8RIRDykXZrJSp540w= +github.com/aws/aws-sdk-go-v2 v1.39.5 h1:e/SXuia3rkFtapghJROrydtQpfQaaUgd1cUvyO1mp2w= +github.com/aws/aws-sdk-go-v2 v1.39.5/go.mod h1:yWSxrnioGUZ4WVv9TgMrNUeLV3PFESn/v+6T/Su8gnM= +github.com/aws/aws-sdk-go-v2/config v1.31.16 h1:E4Tz+tJiPc7kGnXwIfCyUj6xHJNpENlY11oKpRTgsjc= +github.com/aws/aws-sdk-go-v2/config v1.31.16/go.mod h1:2S9hBElpCyGMifv14WxQ7EfPumgoeCPZUpuPX8VtW34= +github.com/aws/aws-sdk-go-v2/credentials v1.18.20 h1:KFndAnHd9NUuzikHjQ8D5CfFVO+bgELkmcGY8yAw98Q= +github.com/aws/aws-sdk-go-v2/credentials v1.18.20/go.mod h1:9mCi28a+fmBHSQ0UM79omkz6JtN+PEsvLrnG36uoUv0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.12 h1:VO3FIM2TDbm0kqp6sFNR0PbioXJb/HzCDW6NtIZpIWE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.12/go.mod h1:6C39gB8kg82tx3r72muZSrNhHia9rjGkX7ORaS2GKNE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.12 h1:p/9flfXdoAnwJnuW9xHEAFY22R3A6skYkW19JFF9F+8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.12/go.mod h1:ZTLHakoVCTtW8AaLGSwJ3LXqHD9uQKnOcv1TrpO6u2k= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.12 h1:2lTWFvRcnWFFLzHWmtddu5MTchc5Oj2OOey++99tPZ0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.12/go.mod h1:hI92pK+ho8HVcWMHKHrK3Uml4pfG7wvL86FzO0LVtQQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2 h1:xtuxji5CS0JknaXoACOunXOYOQzgfTvGAc9s2QdCJA4= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2/go.mod h1:zxwi0DIR0rcRcgdbl7E2MSOvxDyyXGBlScvBkARFaLQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.10 h1:DRND0dkCKtJzCj4Xl4OpVbXZgfttY5q712H9Zj7qc/0= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.10/go.mod h1:tGGNmJKOTernmR2+VJ0fCzQRurcPZj9ut60Zu5Fi6us= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.39.7 h1:ac9qk31MWmUlUci1tthz0iREvkjFktEeGaDF1fAgeCU= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.39.7/go.mod h1:A3WcpfEY2lhQvpnS6SJbMfljJuskxIKIVDcuYbIbXeE= -github.com/aws/aws-sdk-go-v2/service/sso v1.29.7 h1:fspVFg6qMx0svs40YgRmE7LZXh9VRZvTT35PfdQR6FM= -github.com/aws/aws-sdk-go-v2/service/sso v1.29.7/go.mod h1:BQTKL3uMECaLaUV3Zc2L4Qybv8C6BIXjuu1dOPyxTQs= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.2 h1:scVnW+NLXasGOhy7HhkdT9AGb6kjgW7fJ5xYkUaqHs0= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.2/go.mod h1:FRNCY3zTEWZXBKm2h5UBUPvCVDOecTad9KhynDyGBc0= -github.com/aws/aws-sdk-go-v2/service/sts v1.38.7 h1:VEO5dqFkMsl8QZ2yHsFDJAIZLAkEbaYDB+xdKi0Feic= -github.com/aws/aws-sdk-go-v2/service/sts v1.38.7/go.mod h1:L1xxV3zAdB+qVrVW/pBIrIAnHFWHo6FBbFe4xOGsG/o= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.12 h1:MM8imH7NZ0ovIVX7D2RxfMDv7Jt9OiUXkcQ+GqywA7M= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.12/go.mod h1:gf4OGwdNkbEsb7elw2Sy76odfhwNktWII3WgvQgQQ6w= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.39.10 h1:S5Mw93I9uFjXnHvkZ19O3Zj0UM5k4v3pYrDZxXCbqUg= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.39.10/go.mod h1:wW/JqWY6yVr88XZJq5wX22l8XNkDdhw+8eDgkN51Rlc= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.0 h1:xHXvxst78wBpJFgDW07xllOx0IAzbryrSdM4nMVQ4Dw= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.0/go.mod h1:/e8m+AO6HNPPqMyfKRtzZ9+mBF5/x1Wk8QiDva4m07I= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.4 h1:tBw2Qhf0kj4ZwtsVpDiVRU3zKLvjvjgIjHMKirxXg8M= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.4/go.mod h1:Deq4B7sRM6Awq/xyOBlxBdgW8/Z926KYNNaGMW2lrkA= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.0 h1:C+BRMnasSYFcgDw8o9H5hzehKzXyAb9GY5v/8bP9DUY= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.0/go.mod h1:4EjU+4mIx6+JqKQkruye+CaigV7alL3thVPfDd9VlMs= github.com/aws/smithy-go v1.23.1 h1:sLvcH6dfAFwGkHLZ7dGiYF7aK6mg4CgKA/iDKjLDt9M= github.com/aws/smithy-go v1.23.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= @@ -171,10 +171,10 @@ github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b h1:MnAMdlwSltxJyULnrYbkZpp4k58Co7Tah3ciKhSNo0Q= github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= -github.com/charmbracelet/x/exp/slice v0.0.0-20251016201629-54e687c87a08 h1:QgWxcPNK0kuOBW6/wQjRxvlnUou6nX4JOBcl3tZpEKk= -github.com/charmbracelet/x/exp/slice v0.0.0-20251016201629-54e687c87a08/go.mod h1:vqEfX6xzqW1pKKZUUiFOKg0OQ7bCh54Q2vR/tserrRA= -github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= -github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= +github.com/charmbracelet/x/exp/slice v0.0.0-20251031172406-4542a189d0fb h1:r8GKL5AcwENTjZfNhSFv2E5qF4t8KshHPdN2qkPe9F4= +github.com/charmbracelet/x/exp/slice v0.0.0-20251031172406-4542a189d0fb/go.mod h1:vqEfX6xzqW1pKKZUUiFOKg0OQ7bCh54Q2vR/tserrRA= +github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= +github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= @@ -183,8 +183,10 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY= -github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= +github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= +github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= +github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= +github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= @@ -416,8 +418,8 @@ github.com/kjk/lzmadec v0.0.0-20210713164611-19ac3ee91a71 h1:TYp9Fj0apeZMWentXRaFM6B0ixdFefrlgY8n8XYEz1s= github.com/kjk/lzmadec v0.0.0-20210713164611-19ac3ee91a71/go.mod h1:2zRkQCuw/eK6cqkYAeNqyBU7JKa2Gcq40BZ9GSJbmfE= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= +github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= @@ -692,8 +694,8 @@ golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20251017212417-90e834f514db h1:by6IehL4BH5k3e3SJmcoNbOobMey2SLpAF79iPOEBvw= -golang.org/x/exp v0.0.0-20251017212417-90e834f514db/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70= +golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY= +golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/chezmoi/abspath.go new/chezmoi-2.67.0/internal/chezmoi/abspath.go --- old/chezmoi-2.66.1/internal/chezmoi/abspath.go 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/chezmoi/abspath.go 2025-11-02 19:55:46.000000000 +0100 @@ -165,7 +165,7 @@ // from a string. func StringToAbsPathHookFunc() mapstructure.DecodeHookFunc { return func(from, to reflect.Type, data any) (any, error) { - if to != reflect.TypeOf(EmptyAbsPath) { + if to != reflect.TypeFor[AbsPath]() { return data, nil } s, ok := data.(string) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/chezmoi/chezmoi.go new/chezmoi-2.67.0/internal/chezmoi/chezmoi.go --- old/chezmoi-2.66.1/internal/chezmoi/chezmoi.go 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/chezmoi/chezmoi.go 2025-11-02 19:55:46.000000000 +0100 @@ -120,6 +120,20 @@ "chezmoistate.boltdb", ) +// ignoredHostnameSuffixes is a list of suffixes that are ignored when +// determining the hostname from /etc/hosts. See +// https://en.wikipedia.org/wiki/Special-use_domain_name. +var ignoredHostnameSuffixes = []string{ + ".alt", + ".example", + ".invalid", + ".internal", + ".local", + ".localhost", + ".onion", + ".test", +} + var FileModeTypeNames = map[fs.FileMode]string{ 0: "file", fs.ModeDir: "dir", @@ -283,34 +297,26 @@ if err != nil { return "", err } +LINE: for line := range bytes.Lines(contents) { line, _, _ = bytes.Cut(bytes.TrimSpace(line), []byte{'#'}) fields := whitespaceRx.Split(string(line), -1) if len(fields) < 2 { continue } - if !net.ParseIP(fields[0]).IsLoopback() { - continue - } - hostname, domainname, found := strings.Cut(fields[1], ".") - if !found { - continue - } - if hostname == "localhost" { - continue - } - if domainname == "localdomain" { + ipAddress, canonicalHostname := fields[0], fields[1] + if !net.ParseIP(ipAddress).IsLoopback() { continue } - // Docker Desktop breaks /etc/hosts. Filter out all docker.internal - // domain names. See https://github.com/twpayne/chezmoi/issues/3095. - if domainname == "docker.internal" { + if hostname, _, found := strings.Cut(canonicalHostname, "."); !found || hostname == "localhost" { continue } - if runtime.GOOS == "darwin" && domainname == "local" { - continue + for _, ignoredHostnameSuffix := range ignoredHostnameSuffixes { + if strings.HasSuffix(canonicalHostname, ignoredHostnameSuffix) { + continue LINE + } } - return fields[1], nil + return canonicalHostname, nil } return "", nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/chezmoi/chezmoi_test.go new/chezmoi-2.67.0/internal/chezmoi/chezmoi_test.go --- old/chezmoi-2.66.1/internal/chezmoi/chezmoi_test.go 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/chezmoi/chezmoi_test.go 2025-11-02 19:55:46.000000000 +0100 @@ -58,7 +58,9 @@ root: map[string]any{ "/etc/hosts": chezmoitest.JoinLines( `127.0.0.1 localhost.localdomain`, - `127.0.0.2 host.example.com host`, + `127.0.0.2 service.local`, + `127.0.0.4 multi.part.domain.example`, + `127.0.0.4 host.example.com host`, ), }, f: etcHostsFQDNHostname, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/chezmoi/entrytypeset.go new/chezmoi-2.67.0/internal/chezmoi/entrytypeset.go --- old/chezmoi-2.66.1/internal/chezmoi/entrytypeset.go 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/chezmoi/entrytypeset.go 2025-11-02 19:55:46.000000000 +0100 @@ -347,7 +347,7 @@ // EntryTypeSet from a []string. func StringSliceToEntryTypeSetHookFunc() mapstructure.DecodeHookFunc { return func(from, to reflect.Type, data any) (any, error) { - if to != reflect.TypeOf(EntryTypeSet{}) { + if to != reflect.TypeFor[EntryTypeSet]() { return data, nil } elemsAny, ok := data.([]any) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/chezmoi/externaldiffsystem.go new/chezmoi-2.67.0/internal/chezmoi/externaldiffsystem.go --- old/chezmoi-2.66.1/internal/chezmoi/externaldiffsystem.go 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/chezmoi/externaldiffsystem.go 2025-11-02 19:55:46.000000000 +0100 @@ -8,8 +8,6 @@ "os" "os/exec" "strconv" - "strings" - "text/template" "time" vfs "github.com/twpayne/go-vfs/v5" @@ -19,24 +17,26 @@ // An ExternalDiffSystem is a DiffSystem that uses an external diff tool. type ExternalDiffSystem struct { - system System - command string - args []string - destDirAbsPath AbsPath - tempDirAbsPath AbsPath - filter *EntryTypeFilter - pagerCmdFunc func() (*exec.Cmd, error) - reverse bool - scriptContents bool - textConvFunc TextConvFunc + system System + command string + args []string + destDirAbsPath AbsPath + tempDirAbsPath AbsPath + filter *EntryTypeFilter + pagerCmdFunc func() (*exec.Cmd, error) + reverse bool + scriptContents bool + templateOptions TemplateOptions + textConvFunc TextConvFunc } // ExternalDiffSystemOptions are options for NewExternalDiffSystem. type ExternalDiffSystemOptions struct { - Filter *EntryTypeFilter - Reverse bool - ScriptContents bool - TextConvFunc TextConvFunc + Filter *EntryTypeFilter + Reverse bool + ScriptContents bool + TextConvFunc TextConvFunc + TemplateOptions TemplateOptions } // NewExternalDiffSystem creates a new ExternalDiffSystem. @@ -49,15 +49,16 @@ options *ExternalDiffSystemOptions, ) *ExternalDiffSystem { return &ExternalDiffSystem{ - system: system, - command: command, - args: args, - destDirAbsPath: destDirAbsPath, - filter: options.Filter, - pagerCmdFunc: pagerCmdFunc, - reverse: options.Reverse, - scriptContents: options.ScriptContents, - textConvFunc: options.TextConvFunc, + system: system, + command: command, + args: args, + destDirAbsPath: destDirAbsPath, + filter: options.Filter, + pagerCmdFunc: pagerCmdFunc, + reverse: options.Reverse, + scriptContents: options.ScriptContents, + templateOptions: options.TemplateOptions, + textConvFunc: options.TextConvFunc, } } @@ -213,19 +214,19 @@ // to the original arg. anyTemplateArgs := false for i, arg := range s.args { - tmpl, err := template.New("diff.args[" + strconv.Itoa(i) + "]").Parse(arg) + tmpl, err := ParseTemplate("diff.args["+strconv.Itoa(i)+"]", []byte(arg), s.templateOptions) if err != nil { return err } - builder := strings.Builder{} - if err := tmpl.Execute(&builder, templateData); err != nil { + newArg, err := tmpl.ExecuteString(templateData) + if err != nil { return err } - args = append(args, builder.String()) + args = append(args, newArg) // Detect template arguments. - if arg != builder.String() { + if arg != newArg { anyTemplateArgs = true } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/chezmoi/template.go new/chezmoi-2.67.0/internal/chezmoi/template.go --- old/chezmoi-2.66.1/internal/chezmoi/template.go 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/chezmoi/template.go 2025-11-02 19:55:46.000000000 +0100 @@ -119,6 +119,15 @@ return result, nil } +// ExecuteString executes t with s. +func (t *Template) ExecuteString(data any) (string, error) { + resultBytes, err := t.Execute(data) + if err != nil { + return "", err + } + return string(resultBytes), err +} + // parseAndRemoveDirectives updates o by parsing all template directives in data // and returns data with the lines containing directives removed. The lines are // removed so that any delimiters do not break template parsing. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/cmd/autobool.go new/chezmoi-2.67.0/internal/cmd/autobool.go --- old/chezmoi-2.66.1/internal/cmd/autobool.go 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/cmd/autobool.go 2025-11-02 19:55:46.000000000 +0100 @@ -116,7 +116,7 @@ // from a bool or string. func StringOrBoolToAutoBoolHookFunc() mapstructure.DecodeHookFunc { return func(from, to reflect.Type, data any) (any, error) { - if to != reflect.TypeOf(autoBool{}) { + if to != reflect.TypeFor[autoBool]() { return data, nil } var b autoBool diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/cmd/choiceflag.go new/chezmoi-2.67.0/internal/cmd/choiceflag.go --- old/chezmoi-2.66.1/internal/cmd/choiceflag.go 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/cmd/choiceflag.go 2025-11-02 19:55:46.000000000 +0100 @@ -124,7 +124,7 @@ // So, we have to return a choiceFlag that allows all values. func StringToChoiceFlagHookFunc() mapstructure.DecodeHookFunc { return func(from, to reflect.Type, data any) (any, error) { - if to != reflect.TypeOf(choiceFlag{}) { + if to != reflect.TypeFor[choiceFlag]() { return data, nil } var cf choiceFlag diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/cmd/config.go new/chezmoi-2.67.0/internal/cmd/config.go --- old/chezmoi-2.66.1/internal/cmd/config.go 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/cmd/config.go 2025-11-02 19:55:46.000000000 +0100 @@ -1976,7 +1976,11 @@ Filter: chezmoi.NewEntryTypeFilter(c.Diff.include.Bits(), c.Diff.Exclude.Bits()), Reverse: c.Diff.Reverse, ScriptContents: c.Diff.ScriptContents, - TextConvFunc: c.TextConv.convert, + TemplateOptions: chezmoi.TemplateOptions{ + Funcs: c.templateFuncs, + Options: c.Template.Options, + }, + TextConvFunc: c.TextConv.convert, } return chezmoi.NewExternalDiffSystem(s, c.Diff.Command, c.Diff.Args, c.DestDirAbsPath, c.getDiffPagerCmd, options) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/cmd/helps.gen.go new/chezmoi-2.67.0/internal/cmd/helps.gen.go --- old/chezmoi-2.66.1/internal/cmd/helps.gen.go 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/cmd/helps.gen.go 2025-11-02 19:55:46.000000000 +0100 @@ -438,7 +438,7 @@ " | init, and executes your shell", example: "" + " chezmoi generate install.sh > install.sh\n" + - " chezmoi git commit -m \"$(chezmoi generate git-commit-message)\"\n" + + " chezmoi git -- commit -m \"$(chezmoi generate git-commit-message)\"\n" + " chezmoi generate install-init-shell.sh $GITHUB_USERNAME", }, "git": { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/cmd/mergecmd.go new/chezmoi-2.67.0/internal/cmd/mergecmd.go --- old/chezmoi-2.66.1/internal/cmd/mergecmd.go 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/cmd/mergecmd.go 2025-11-02 19:55:46.000000000 +0100 @@ -4,8 +4,6 @@ "fmt" "os" "strconv" - "strings" - "text/template" "github.com/spf13/cobra" @@ -146,19 +144,21 @@ // not equal to the original arg. anyTemplateArgs := false for i, arg := range c.Merge.Args { - var tmpl *template.Template - if tmpl, err = template.New("merge.args[" + strconv.Itoa(i) + "]").Parse(arg); err != nil { + tmpl, err := chezmoi.ParseTemplate("merge.args["+strconv.Itoa(i)+"]", []byte(arg), chezmoi.TemplateOptions{ + Funcs: c.templateFuncs, + Options: c.Template.Options, + }) + if err != nil { return err } - - builder := strings.Builder{} - if err := tmpl.Execute(&builder, templateData); err != nil { + newArg, err := tmpl.ExecuteString(templateData) + if err != nil { return err } - args = append(args, builder.String()) + args = append(args, newArg) // Detect template arguments. - if arg != builder.String() { + if newArg != arg { anyTemplateArgs = true } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/cmd/readdcmd.go new/chezmoi-2.67.0/internal/cmd/readdcmd.go --- old/chezmoi-2.66.1/internal/cmd/readdcmd.go 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/cmd/readdcmd.go 2025-11-02 19:55:46.000000000 +0100 @@ -84,6 +84,9 @@ } slices.SortFunc(targetRelPaths, chezmoi.CompareRelPaths) + // Track which files were already processed to avoid double-processing with exact directories + processedFiles := make(map[chezmoi.RelPath]bool) + TARGET_REL_PATH: for _, targetRelPath := range targetRelPaths { sourceStateFile, ok := sourceStateEntries[targetRelPath].(*chezmoi.SourceStateFile) @@ -198,6 +201,150 @@ }); err != nil { return err } + // Mark this file as processed + processedFiles[targetRelPath] = true + } + + // Process exact directories - add new files and remove deleted files + return c.processExactDirs(sourceState, sourceStateEntries, processedFiles) +} + +// processExactDirs handles exact directory synchronization during re-add. +// It adds new files found in exact target directories and removes files from +// source that no longer exist in exact target directories. +// processedFiles contains files that were already re-added in the file loop, +// outside of the exact directory logic, to avoid double-processing them. +func (c *Config) processExactDirs( + sourceState *chezmoi.SourceState, + sourceStateEntries map[chezmoi.RelPath]chezmoi.SourceStateEntry, + processedFiles map[chezmoi.RelPath]bool, +) error { + // Collect all exact directories from source state that are in scope + // An exact directory is in scope if: + // 1. It's directly in sourceStateEntries (was explicitly or implicitly targeted) + // 2. Any of its children are in sourceStateEntries (parent dir needs sync) + exactDirs := make(map[chezmoi.RelPath]*chezmoi.SourceStateDir) + + // First, collect exact directories that are directly in the entries + for targetRelPath, entry := range sourceStateEntries { + if sourceStateDir, ok := entry.(*chezmoi.SourceStateDir); ok && sourceStateDir.Attr.Exact { + exactDirs[targetRelPath] = sourceStateDir + } + } + + // Then, collect parent exact directories for any entries + for targetRelPath := range sourceStateEntries { + // Walk up the path to find parent exact directories + for parentPath := targetRelPath.Dir(); parentPath != chezmoi.DotRelPath; parentPath = parentPath.Dir() { + // Check if this parent is an exact directory in source state + parentEntry := sourceState.Get(parentPath) + if sourceStateDir, ok := parentEntry.(*chezmoi.SourceStateDir); ok && sourceStateDir.Attr.Exact { + // Only add if not already present + if _, exists := exactDirs[parentPath]; !exists { + exactDirs[parentPath] = sourceStateDir + } + } + } + } + + // Process each exact directory + for targetRelPath := range exactDirs { + targetDirAbsPath := c.DestDirAbsPath.Join(targetRelPath) + + // Read the target directory contents + dirEntries, err := c.destSystem.ReadDir(targetDirAbsPath) + if err != nil { + // If directory doesn't exist in target, skip it + continue + } + + // Build sets of files in source and target + sourceFiles := make(map[string]chezmoi.SourceStateEntry) + targetFiles := make(map[string]fs.DirEntry) + + // Collect files from source state that are in this exact directory + // Only consider actual files, not removes or other entry types + for entryRelPath, entry := range sourceStateEntries { + // Check if this entry is a direct child of the exact directory + if entryRelPath.Dir() == targetRelPath { + // Only count actual files in source, not remove entries + if _, ok := entry.(*chezmoi.SourceStateFile); ok { + sourceFiles[entryRelPath.Base()] = entry + } + } + } + + // Collect files from target directory + for _, dirEntry := range dirEntries { + name := dirEntry.Name() + if name == "." || name == ".." { + continue + } + targetFiles[name] = dirEntry + } + + // Find new files (in target but not in source) and add them + destAbsPathInfos := make(map[chezmoi.AbsPath]fs.FileInfo) + for name, dirEntry := range targetFiles { + entryRelPath := targetRelPath.JoinString(name) + + // Skip files that were already processed in the file re-add loop + if processedFiles[entryRelPath] { + continue + } + + if _, inSource := sourceFiles[name]; !inSource { + // Check if ignored + if sourceState.Ignore(entryRelPath) { + continue + } + + // Skip subdirectories that are themselves exact directories + // They will be processed separately in their own exact directory processing + if dirEntry.IsDir() { + childEntry := sourceState.Get(entryRelPath) + if childDir, ok := childEntry.(*chezmoi.SourceStateDir); ok && childDir.Attr.Exact { + continue + } + } + + // This is a new file - add it + // Get full FileInfo (DirEntry only has partial info) + destAbsPath := targetDirAbsPath.JoinString(name) + fileInfo, err := dirEntry.Info() + if err != nil { + return err + } + destAbsPathInfos[destAbsPath] = fileInfo + } + } + + // Add new files if any were found + if len(destAbsPathInfos) > 0 { + if err := sourceState.Add(c.sourceSystem, c.persistentState, c.destSystem, destAbsPathInfos, &chezmoi.AddOptions{ + Filter: c.reAdd.filter, + PreAddFunc: c.defaultPreAddFunc, + }); err != nil { + return err + } + } + + // Find deleted files (in source but not in target) and remove them + for name, sourceEntry := range sourceFiles { + if _, inTarget := targetFiles[name]; !inTarget { + // Check if ignored + entryRelPath := targetRelPath.JoinString(name) + if sourceState.Ignore(entryRelPath) { + continue + } + + // This file was deleted from target - remove it from source + sourceAbsPath := c.SourceDirAbsPath.Join(sourceEntry.SourceRelPath().RelPath()) + if err := c.sourceSystem.RemoveAll(sourceAbsPath); err != nil { + return err + } + } + } } return nil diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/cmd/templatefuncs.go new/chezmoi-2.67.0/internal/cmd/templatefuncs.go --- old/chezmoi-2.66.1/internal/cmd/templatefuncs.go 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/cmd/templatefuncs.go 2025-11-02 19:55:46.000000000 +0100 @@ -173,7 +173,9 @@ } func (c *Config) fromIniTemplateFunc(s string) map[string]any { - return iniFileToMap(mustValue(ini.Load([]byte(s)))) + return iniFileToMap(mustValue(ini.LoadSources(ini.LoadOptions{ + UnescapeValueDoubleQuotes: true, + }, []byte(s)))) } // fromJsonTemplateFunc parses s as JSON and returns the result. In contrast to diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/cmd/testdata/scripts/applyexact.txtar new/chezmoi-2.67.0/internal/cmd/testdata/scripts/applyexact.txtar --- old/chezmoi-2.66.1/internal/cmd/testdata/scripts/applyexact.txtar 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/cmd/testdata/scripts/applyexact.txtar 2025-11-02 19:55:46.000000000 +0100 @@ -10,6 +10,13 @@ ! exists $HOME/.dir/file2 ! exists $HOME/.dir/subdir/file +# test that chezmoi apply creates entries in exact directories +cp golden/file3 $CHEZMOISOURCEDIR/exact_dot_dir +exec chezmoi apply --force +cmp $HOME/.dir/file3 golden/file3 + +-- golden/file3 -- +# contents of .dir/file2 -- home/user/.dir/file1 -- # contents of .dir/file1 -- home/user/.dir/file2 -- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/cmd/testdata/scripts/issue4727.txtar new/chezmoi-2.67.0/internal/cmd/testdata/scripts/issue4727.txtar --- old/chezmoi-2.66.1/internal/cmd/testdata/scripts/issue4727.txtar 1970-01-01 01:00:00.000000000 +0100 +++ new/chezmoi-2.67.0/internal/cmd/testdata/scripts/issue4727.txtar 2025-11-02 19:55:46.000000000 +0100 @@ -0,0 +1,6 @@ +# test that fromIni | toIni does not mangle strings +exec chezmoi execute-template '{{ "a = \"\\\"\"" | fromIni | toIni | fromIni | toIni }}' +cmp stdout golden/stdout + +-- golden/stdout -- +a = "\"" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/cmd/testdata/scripts/re-add.txtar new/chezmoi-2.67.0/internal/cmd/testdata/scripts/re-add.txtar --- old/chezmoi-2.66.1/internal/cmd/testdata/scripts/re-add.txtar 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/cmd/testdata/scripts/re-add.txtar 2025-11-02 19:55:46.000000000 +0100 @@ -22,10 +22,12 @@ grep -count=2 '# edited' $CHEZMOISOURCEDIR/dot_dir/file grep -count=1 '# edited' $CHEZMOISOURCEDIR/dot_dir/exact_subdir/file -# test that chezmoi re-add --recursive=false does not recurse into subdirectories +# test that chezmoi re-add --recursive=false does not recurse into subdirectories AND still syncs exact directories +# Even with --recursive=false, exact directory sync happens because subdir is exact exec chezmoi re-add --recursive=false ~/.dir/subdir -grep -count=1 '# edited' $CHEZMOISOURCEDIR/dot_dir/exact_subdir/file +grep -count=2 '# edited' $CHEZMOISOURCEDIR/dot_dir/exact_subdir/file # test that chezmoi re-add is recursive by default +edit $HOME/.dir/subdir/file exec chezmoi re-add ~/.dir/subdir -grep -count=2 '# edited' $CHEZMOISOURCEDIR/dot_dir/exact_subdir/file +grep -count=3 '# edited' $CHEZMOISOURCEDIR/dot_dir/exact_subdir/file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/cmd/testdata/scripts/readd-exact.txtar new/chezmoi-2.67.0/internal/cmd/testdata/scripts/readd-exact.txtar --- old/chezmoi-2.66.1/internal/cmd/testdata/scripts/readd-exact.txtar 1970-01-01 01:00:00.000000000 +0100 +++ new/chezmoi-2.67.0/internal/cmd/testdata/scripts/readd-exact.txtar 2025-11-02 19:55:46.000000000 +0100 @@ -0,0 +1,95 @@ +# test that chezmoi re-add adds new files in exact_ directories +exec chezmoi add --exact $HOME${/}test-dir +exists $CHEZMOISOURCEDIR/exact_test-dir/test1 +cmp $CHEZMOISOURCEDIR/exact_test-dir/test1 golden/test1 + +# verify no diff after initial add +exec chezmoi diff +! stdout . + +# add a new file to the exact directory in target +cp golden/test2 $HOME/test-dir/test2 +exec chezmoi re-add +exists $CHEZMOISOURCEDIR/exact_test-dir/test2 +cmp $CHEZMOISOURCEDIR/exact_test-dir/test2 golden/test2 + +# verify no diff after adding new file +exec chezmoi diff +! stdout . + +# test that chezmoi re-add removes deleted files from exact_ directories +rm $HOME/test-dir/test1 +exec chezmoi re-add +! exists $CHEZMOISOURCEDIR/exact_test-dir/test1 + +# verify no diff after removing file +exec chezmoi diff +! stdout . + +# test that chezmoi re-add with explicit exact directory target works +cp golden/test3 $HOME/test-dir/test3 +exec chezmoi re-add $HOME/test-dir +exists $CHEZMOISOURCEDIR/exact_test-dir/test3 +cmp $CHEZMOISOURCEDIR/exact_test-dir/test3 golden/test3 + +# verify no diff after adding file with explicit target +exec chezmoi diff +! stdout . + +# test nested exact directory with --recursive=false +exec chezmoi add $HOME/outer-dir +exec chezmoi add --exact $HOME/outer-dir/exact-inner +exists $CHEZMOISOURCEDIR/outer-dir/exact_exact-inner/inner1 + +# add a new file to the nested exact directory in target +cp golden/inner2 $HOME/outer-dir/exact-inner/inner2 + +# re-add with --recursive=false should NOT process nested exact directory, and thereforce should not add new file inner2. +exec chezmoi re-add --recursive=false $HOME/outer-dir +! exists $CHEZMOISOURCEDIR/outer-dir/exact_exact-inner/inner2 + +# re-add with recursive (default) SHOULD process nested exact directory +exec chezmoi re-add $HOME/outer-dir +exists $CHEZMOISOURCEDIR/outer-dir/exact_exact-inner/inner2 +cmp $CHEZMOISOURCEDIR/outer-dir/exact_exact-inner/inner2 golden/inner2 + +# verify no diff +exec chezmoi diff +! stdout . + +# test nested exact directories (both parent and child are exact) +exec chezmoi add --exact $HOME/exact-outer +exists $CHEZMOISOURCEDIR/exact_exact-outer/exact_exact-inner/nested1 + +# add a new file to the nested exact directory +cp golden/nested2 $HOME/exact-outer/exact-inner/nested2 + +# re-add should process both exact directories and add the new file +exec chezmoi re-add +exists $CHEZMOISOURCEDIR/exact_exact-outer/exact_exact-inner/nested2 +cmp $CHEZMOISOURCEDIR/exact_exact-outer/exact_exact-inner/nested2 golden/nested2 + +# verify no diff +exec chezmoi diff +! stdout . + +-- golden/inner2 -- +# contents of inner2 +-- golden/nested2 -- +# contents of nested2 +-- golden/test1 -- +# contents of test1 +-- golden/test2 -- +# contents of test2 +-- golden/test3 -- +# contents of test3 +-- home/user/exact-outer/exact-inner/nested1 -- +# contents of nested1 +-- home/user/exact-outer/outer1 -- +# contents of outer1 +-- home/user/outer-dir/exact-inner/inner1 -- +# contents of inner1 +-- home/user/outer-dir/file1 -- +# contents of outer file1 +-- home/user/test-dir/test1 -- +# contents of test1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/cmd/util.go new/chezmoi-2.67.0/internal/cmd/util.go --- old/chezmoi-2.66.1/internal/cmd/util.go 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/cmd/util.go 2025-11-02 19:55:46.000000000 +0100 @@ -97,8 +97,8 @@ // pluralize returns the English plural form of singular. func pluralize(singular string) string { - if strings.HasSuffix(singular, "y") { - return strings.TrimSuffix(singular, "y") + "ies" + if prefix, found := strings.CutSuffix(singular, "y"); found { + return prefix + "ies" } return singular + "s" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chezmoi-2.66.1/internal/cmds/generate-install.sh/install.sh.tmpl new/chezmoi-2.67.0/internal/cmds/generate-install.sh/install.sh.tmpl --- old/chezmoi-2.66.1/internal/cmds/generate-install.sh/install.sh.tmpl 2025-10-19 23:33:16.000000000 +0200 +++ new/chezmoi-2.67.0/internal/cmds/generate-install.sh/install.sh.tmpl 2025-11-02 19:55:46.000000000 +0100 @@ -302,7 +302,7 @@ checksums="${2}" basename="${target##*/}" - want="$(grep "${basename}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)" + want="$(grep "${basename}\$" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)" if [ -z "${want}" ]; then log_err "hash_sha256_verify unable to find checksum for ${target} in ${checksums}" return 1 ++++++ chezmoi.obsinfo ++++++ --- /var/tmp/diff_new_pack.g9bK5V/_old 2025-11-04 18:42:00.692554358 +0100 +++ /var/tmp/diff_new_pack.g9bK5V/_new 2025-11-04 18:42:00.696554527 +0100 @@ -1,5 +1,5 @@ name: chezmoi -version: 2.66.1 -mtime: 1760909596 -commit: 94b95eb0b6bf91e48dd7b584a80ad60d44d8de4d +version: 2.67.0 +mtime: 1762109746 +commit: 8591960c5b55b27d3806c6754232e1a6980957e1 ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/chezmoi/vendor.tar.gz /work/SRC/openSUSE:Factory/.chezmoi.new.1980/vendor.tar.gz differ: char 29, line 1
