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: uutils/shadow
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: uutils/shadow
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: refactor/249-multi-file-commit
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 1 commit
  • 7 files changed
  • 1 contributor

Commits on Sep 4, 2026

  1. shadow-core: commit several files together, and convert the last six …

    …tools
    
    group and gshadow have to agree: a group present in one and absent from
    the other is a broken system, and every tool that touches a group touches
    both. Committing them one at a time leaves a window in which they
    disagree, and a failure in the second makes that permanent.
    
    commit_all validates every file before writing any, which closes the
    failure this actually hits -- a value that would corrupt a record is
    rejected while nothing has been touched, instead of after the first file
    is already on disk. A genuine I/O error partway through can still leave
    the set half applied; there is no journal, and a rollback that can itself
    fail would not be an improvement. All the locks are held until the last
    write finishes, so no other process sees the intermediate state.
    
    A commit that would write the same bytes now writes nothing. A rewrite is
    not free: it replaces the inode and moves the mtime, and for an unchanged
    empty file it failed outright, since the atomic writer refuses to produce
    a zero-length file. Every tool used to carry its own 'did anything
    change' flag to work around that; those are gone. Found by usermod's
    tests, whose fixture has an empty gshadow that -G does not touch.
    
    groupmod, useradd, usermod, userdel, pwck and grpck are converted, and
    there is no longer a single FileLock::acquire left in any tool. userdel
    loses its hand-rolled line filter, which had its own idea of which lines
    were comments next to the parser that already knows; one consequence is
    that a comment above a removed account now moves to the end of the file
    rather than staying in place, which is what every other tool already did.
    
    Exit codes are preserved, including the two pwck keeps for a failed
    write: 6 'can not sort' and 5 'can not update the files' stay distinct by
    matching on the file the error names.
    
    Verified against a prefix tree for each tool: useradd creating an account
    with a user group, supplementary groups, aging and subid; usermod
    renaming across four files and replacing a group list; groupmod moving a
    GID and following it into passwd; userdel removing an account from six
    files; grpck sorting group and gshadow together, keeping each comment
    with its group, and writing nothing on a second run.
    pierre-warnier committed Sep 4, 2026
    Configuration menu
    Copy the full SHA
    d0dc9e7 View commit details
    Browse the repository at this point in the history
Loading