Skip to content

git-absorb clears skip-worktree (index entry flags reset; file becomes visible again) #202

@Koswu

Description

@Koswu

Summary

Running git absorb (with absorb.autoStageIfNothingStaged=true) clears the skip-worktree bit on index entries. After git absorb, files previously marked via git update-index --skip-worktree <path> become visible as normal modified files again (unstaged), even though they were still skip-worktree before running git absorb.

In my repo, the index entry flags get reset to 0.

Steps to reproduce

  1. Create and commit a file:

    echo "base" > .absorb-skip-worktree-repro.txt
    git add .absorb-skip-worktree-repro.txt
    git commit -m "repro: add .absorb-skip-worktree-repro.txt"
  2. Mark it as skip-worktree and modify it:

    git update-index --skip-worktree .absorb-skip-worktree-repro.txt
    echo "local-only change" >> .absorb-skip-worktree-repro.txt
  3. Enable auto-stage and run absorb:

    git config absorb.autoStageIfNothingStaged true
    git reset # unstage everything
    git absorb

Evidence (before vs after)

Before git absorb

skip-worktree is set and the file is NOT reported by status:

$ git ls-files -v -- .absorb-skip-worktree-repro.txt
S .absorb-skip-worktree-repro.txt

$ git status --porcelain=v1 -- .absorb-skip-worktree-repro.txt
# (no output)

Also, index debug flags are non-zero (indicating flags were present):

$ git ls-files --debug -- .absorb-skip-worktree-repro.txt
.absorb-skip-worktree-repro.txt
  ...
  flags: 40004000

After git absorb

The file becomes visible again as an unstaged modification, and the index entry flags are reset:

$ git ls-files -v -- .absorb-skip-worktree-repro.txt
H .absorb-skip-worktree-repro.txt

$ git status --porcelain=v1 -- .absorb-skip-worktree-repro.txt
 M .absorb-skip-worktree-repro.txt

$ git diff --cached -- .absorb-skip-worktree-repro.txt
# (no output; it was NOT staged)

$ git diff -- .absorb-skip-worktree-repro.txt
diff --git a/.absorb-skip-worktree-repro.txt b/.absorb-skip-worktree-repro.txt
index df967b96a5..54dd57f7b2 100644
--- a/.absorb-skip-worktree-repro.txt
+++ b/.absorb-skip-worktree-repro.txt
@@ -1 +1,2 @@
 base
+local-only change ...

$ git ls-files --debug -- .absorb-skip-worktree-repro.txt
.absorb-skip-worktree-repro.txt
  ...
  flags: 0

Expected behavior

git absorb should not clear or modify the skip-worktree bit (or any other unrelated index entry flags). Files marked skip-worktree should remain skip-worktree after running git absorb.

Actual behavior

  • Before git absorb:
    • git ls-files -v shows S .absorb-skip-worktree-repro.txt
    • git status does not report the file
  • After git absorb:
    • git ls-files -v no longer shows S (in my case it showed H)
    • git status reports the file as modified (unstaged)
    • git diff --cached is empty (so it was not staged)
    • git ls-files --debug shows the index entry flags: 0 (flags got reset)

Environment

  • git-absorb version: 0.8.0
  • git version: 2.39.5
  • OS: Debian GNU/Linux 12 (bookworm) (WSL2 kernel 6.6.87.2-microsoft-standard-WSL2 )

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions