Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: microsoft/tgrep
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.2.6
Choose a base ref
...
head repository: microsoft/tgrep
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.2.7
Choose a head ref
  • 1 commit
  • 15 files changed
  • 2 contributors

Commits on Nov 4, 2026

  1. Filter no-op notifications for whitelisted dot-files and excluded tra…

    …cked files; bump to 1.2.7 (#222)
    
    * Filter no-op notifications for whitelisted dot-files and excluded tracked files
    
    The managed watcher drops a file notification when the published state
    shows that the file's trusted metadata and visibility are unchanged. Two
    gaps let such notifications invalidate the view and clear `ready`
    (#221):
    
    - Dot-files that an ignore-file whitelist admits. The filter compared
      the raw hidden status with the recorded one, which the whitelist had
      already adjusted. The walk now reports the whitelisted entries, and
      the filter compares raw status with raw status.
    - Tracked files that ignore rules exclude from the walk. They had no
      evidence. Each pass now records their trusted version and raw hidden
      status, and the filter drops a notification only when both are
      unchanged. Ignore and attributes files are never recorded, so their
      notifications invalidate exactly as before. A missing directory
      skips its tracked descendants without a stat each.
    
    Notifications for paths without evidence or a record still invalidate.
    That includes new files and untracked ignored files.
    
    Diagnostics are additive:
    - `watch_events.unchanged_excluded_filtered`;
    - `watch_events.unfiltered`, which counts why notifications were kept;
    - `last_reconcile.excluded_tracked`;
    - `last_reconcile.timings.excluded_records_us`.
    Nothing persisted changes.
    
    Co-authored-by: Copilot App <[email protected]>
    
    * Bump version to 1.2.7
    
    Co-authored-by: Copilot App <[email protected]>
    
    * Charge excluded-record scratch before allocating it
    
    excluded_records charged the listed-path set and the candidate list to
    the caller's charge, which held both until publication resized it or
    the pass ended. It charged the candidates only after allocating them,
    and by length. The directory stack and the per-directory name lists
    were not charged at all. A sparse checkout with many absent tracked
    paths could therefore exceed the private-memory reservation while
    underreporting peak_private_bytes.
    
    Scratch now has its own charge, taken before each allocation and
    released when the buffers drop:
    
    - The listed set is charged with an upper bound on its table, and
      released as soon as the candidates are known.
    - Candidates are counted first and allocated exactly.
    - The directory stack grows through a helper that charges the
      replacement storage while the old storage is still charged.
    - The per-directory name lists are gone: each directory entry's name
      is looked up by binary search in the directory's sorted candidate
      range.
    
    The caller's charge now grows only by the records. Records,
    exact-spelling matching and skipped absent subtrees are unchanged, and
    every entry visit still checks for cancellation, including the
    counting pass.
    
    Co-authored-by: Copilot App <[email protected]>
    
    * Require ignore rules to prove exclusion before recording
    
    excluded_records recorded every present tracked file that the walk had
    not listed, as if ignore rules excluded it. A tracked file restored
    after the walk is unlisted too, so it could get a record. If its create
    notification was missed, a later Modify that left it unchanged was
    dropped as unchanged, although the published state did not contain it.
    
    A candidate now gets a record only when the ignore rules the walk
    applied exclude it or a parent directory:
    
    - The metadata walk returns the point-query matcher it already builds
      for visibility, and a controlled walk keeps its input control alive
      with it.
    - When the walk built no matcher, one is built from the walk's rule
      files, only once a candidate is found on disk.
    - Under a permit, as managed views always walk, both matchers parse
      the rule-file contents the walk read through its input control, so
      nothing is read again and a rule changed since the walk proves
      nothing. A rebuilt matcher leaves out the case-insensitive
      tracked-file layer, which only adds exclusions.
    
    The input control's charge for those snapshots and patterns is now
    held until the records are built, then released. Tracked files that
    the walk skipped only for other reasons get no record, so their
    notifications keep invalidating.
    
    Co-authored-by: Copilot App <[email protected]>
    
    * Prune whitelisted hidden paths on unchanged verification
    
    This PR keeps the raw hidden status of whitelisted files beside the
    published visibility, so that a no-op notification for a whitelisted
    dot-file is dropped. A verification that found the publication current
    refreshed the evidence but kept that set as published.
    
    On Windows, a file can lose both its hidden attribute and the whitelist
    that admitted it without a change to its visibility or its file
    version, which has no change time. If neither change was notified,
    verification found nothing to publish and kept the stale entry. The
    notification for setting the attribute again then looked unchanged and
    was dropped, so the file stayed visible to queries without --hidden
    until a later pass or verification. v1.2.6 invalidated in that case.
    Elsewhere the raw hidden status depends only on the name, so changing
    it is a rename, which verification sees as a membership change.
    
    Unchanged verification now keeps only the entries that its own walk
    still reports as hidden and whitelisted. It prunes the set rather than
    replacing it, as it does the excluded records, because retained view
    memory is charged for the published set. A whitelisted file hidden
    since the last publication therefore has no entry and keeps
    invalidating until a pass publishes.
    
    Tests:
    
    - unchanged_verification_prunes_whitelisted_entries_its_walk_no_longer_reports
      (Windows) removes a file's hidden attribute and its info/exclude
      whitelist without a notification, verifies, sets the attribute again
      and expects HiddenChanged.
    - unchanged_file_drops_whitelisted_hidden_files now also checks that
      an unchanged verification keeps the entries its walk still reports.
    
    Co-authored-by: Copilot App <[email protected]>
    
    * Prove excluded-file records only with rules the walk applies
    
    An excluded-file record lets the watcher drop an unchanged notification
    for a tracked file the walk did not list. A record is made only when the
    pass's matcher proves the file excluded, so the matcher must not exclude
    a file the walk would list. It could in three cases.
    
    Below a nested repository, the walk stops applying the outer
    repository's `.gitignore` and `info/exclude` rules, while the matcher
    still applies them. A tracked file there that was absent during the walk
    and restored before the records were built could get a record although
    the next walk lists it. If its create notification was missed, a later
    notification that left it unchanged was dropped, although the published
    state did not contain the file. Records now skip every directory below
    the root that holds an entry named `.git` or `.jj`, of any type and in
    any ASCII case, or whose listing fails partway. The walk treats a
    directory as another repository only when a lookup of `.git` or `.jj`
    there finds an entry, and never with `--no-require-git`. Unless the file
    system equates another name with those beyond ASCII case, this skips at
    least every subtree the walk treats as one, and skipping only removes
    records. A listing can return the marker after other entries, so the
    records and queued subdirectories already taken from that directory are
    then released.
    
    Neither exclude file proves exclusion any more. The metadata walk never
    sets the walker's working directory, so it matches global patterns
    relative to the process's working directory, while the matcher roots
    them at the view root. An anchored global pattern could therefore
    exclude a file in the matcher that the walk lists. Behind a `.git` file,
    the walk applies the repository's `info/exclude` only when Git is
    required and the pointer, resolved against the process's working
    directory, leads to a Git directory with a `commondir` file. The matcher
    resolves a relative pointer against the directory holding `.git`, and
    takes a Git directory without `commondir`, such as a submodule's or a
    `--separate-git-dir` checkout's, as its own common directory, so it
    applied `info/exclude` where the walk did not. Both files have the
    lowest precedence of the standard rules, and the p4ignore and case
    filters don't read the standard decision, so leaving them out of the
    proof only removes exclusions and stays safe however the walk resolves
    them. When Git ignores case, the case filter still matches
    `info/exclude`'s rules, but it never hides a tracked file, and the walk
    applies the same filter. Tracked files that only an exclude file
    excludes get no record and keep invalidating, as in 1.2.6. Outside
    nested repositories, records proven by `.gitignore`, `.ignore` or the
    p4ignore filter are unchanged, as are the walk, visibility and
    whitelists.
    
    The tests remove tracked files before the walk and restore them before
    the records are built, with the walk's matcher and with a rebuilt one, an
    injected matcher whose only proof is global, a daemon whose global
    excludes file holds anchored and unanchored patterns, and `info/exclude`
    behind a `.git` directory, a separate Git directory and a linked
    worktree's relative pointer.
    
    Co-authored-by: Copilot App <[email protected]>
    
    ---------
    
    Co-authored-by: Copilot App <[email protected]>
    shengyfu and Copilot authored Nov 4, 2026
    Configuration menu
    Copy the full SHA
    70c3b0a View commit details
    Browse the repository at this point in the history
Loading