Chapter 04Lesson 03~85 minutes

Repositories, Working Tree, Index, HEAD, and the File Lifecycle: Configuration, Design Choices, and Tradeoffs

Design portable tracking and ignore policy across repository, local, and global scopes; reason about pathspecs, shell expansion, file modes, case sensitivity, partial staging, intent-to-add, generated files, dependencies, and secrets.

gitignorePath policyCross-platformIntent-to-add

Learning objectives

  • Choose the correct ignore source for shared, repository-local, and user-global exclusions.
  • Separate Git pathspec matching from shell wildcard expansion and use -- to disambiguate paths.
  • Reason about file-mode and case-sensitivity behavior without copying machine-specific settings blindly.
  • Evaluate partial staging and intent-to-add as deliberate advanced workflows.
  • Define tracking policy for generated artifacts, caches, dependencies, and secrets.

1. File lifecycle becomes a team policy problem

The mechanics from Lesson 2 answer “how do I stage or restore this path?” Production repositories also need a policy for which paths should exist in history at all, which excludes are shared, which are private, and how cross-platform filesystems affect path identity.

2. Ignore sources and precedence

Git's current ignore precedence, highest to lowest, is:

  1. patterns supplied on the command line by commands that support them;
  2. .gitignore files from the path's directory upward to the working-tree root, with deeper files able to override higher ones;
  3. $GIT_COMMON_DIR/info/exclude for repository-specific but unshared ignores;
  4. the file configured by core.excludesFile for user-wide personal patterns.
Need Best home Why
Build output every contributor should ignore Versioned .gitignore Shared project policy
One developer's local scratch directory .git/info/exclude Repository-local, not shared
Editor backup files across all repos core.excludesFile User preference
Already tracked secret/config Not solved by ignore alone Tracking/history/security action required

3. Ignore rules do not untrack existing files

If a file is already in the index, adding a matching ignore rule does not silently remove it from history. This is a safety property: a new ignore pattern should not unexpectedly delete versioned content.

git ls-files -- config.local
git check-ignore -v --no-index -- config.local

If the project deliberately wants to keep a local copy but stop tracking future versions, git rm --cached -- path can change the index while preserving the working-tree file. That decision should be reviewed, especially if the path ever contained credentials: ignoring it does not erase prior commits or revoke exposed secrets.

4. Git pathspecs versus shell wildcard expansion

These two commands can behave differently:

git add src/*.py
git add -- "src/*.py"

In shells that expand globs, the first form may be converted into a concrete list of files before Git starts. The quoted second form lets Git receive and interpret the pathspec. PowerShell wildcard behavior differs from Bash/zsh, so portable documentation should quote Git pathspec patterns when Git—not the shell—is intended to perform matching.

5. Separate revisions from paths with --

Git commands such as diff can accept both revision expressions and paths. If a branch/tag and path share the same name, ambiguity becomes operationally dangerous.

git diff HEAD -- release
git show HEAD:release
git status -- release

Teach scripts and runbooks to use -- whenever the command grammar accepts both revisions/options and paths. A path beginning with - is another reason to make the boundary explicit.

6. File-mode differences across filesystems

Git tracks a limited executable-bit concept in tree entries. core.fileMode tells Git whether to honor working-tree executable-bit changes. Git normally probes this during repository creation/clone, but copied repositories, network mounts, containers, or Windows interoperability layers can alter behavior.

git config --show-origin --get core.fileMode
git diff --summary

Do not set one global value for every machine merely to silence a symptom. Decide whether executable-bit changes are meaningful for the project and whether the filesystem can represent them reliably.

7. Case sensitivity is a filesystem boundary, not just style

Git relies on core.ignoreCase workarounds on case-insensitive filesystems. Paths such as Makefile and makefile can coexist on a case-sensitive filesystem but cause ambiguity on common Windows/macOS setups. A portable repository should avoid case-only path distinctions even if one contributor's filesystem permits them.

For case-only renames on case-insensitive filesystems, an intermediate name is often clearer:

git mv Readme.md readme.tmp
git mv readme.tmp README.md
git status --short

8. Partial staging — powerful, but it changes review assumptions

git add -p lets the index contain only selected hunks from a working-tree file. This supports focused commits, but it means “the file on disk” is no longer “the file being committed.” Teams that use partial staging should require a final git diff --staged review and ideally run tests against the exact staged snapshot when correctness depends on the split.

9. Intent-to-add is an advanced visibility choice

git add -N -- new-file.txt
git status --short
git diff -- new-file.txt

--intent-to-add records an index entry indicating that the path is intended to be added later while allowing the working-tree content to participate in diff workflows. It is useful in some review/partial-staging workflows, but beginners should not treat it as ordinary staging: the file's content still needs to be added before a normal commit records it.

10. Generated files, caches, dependencies, and secrets need different reasoning

Path category Default reasoning Exceptions
Build output / caches Usually ignore Checked-in generated artifacts when reproducibility/release policy explicitly requires them
Vendored dependencies Prefer package lockfiles + package manager Air-gapped/reproducible vendor policy may justify tracking
Generated docs/API clients Team decision Track when consumers need artifacts without generator toolchain
Secrets/private keys/tokens Never track as ordinary source Use secret-management references/templates, not live credentials
Local IDE/editor files User/global or repo-local excludes Track shared workspace config only when intentionally standardized

11. Ignoring a secret is prevention, not incident response

If a credential was committed, add it to ignore only after rotating/revoking the credential. The old value may still exist in reachable or recoverable Git history. Chapter 21 covers coordinated secret-removal and integrity workflows.

12. Worked policy scenario

A cross-platform service repository contains Python bytecode caches, a generated dist/ directory, a developer-only .notes/ folder, a tracked shell deployment script, and an .env file containing real credentials.

  1. Version __pycache__/ and dist/ patterns in project .gitignore unless distribution artifacts are intentionally versioned.
  2. Put .notes/ in .git/info/exclude if only one developer needs it.
  3. Preserve executable-bit intent for the deployment script on capable filesystems; avoid global core.fileMode cargo-culting.
  4. Ignore .env before it is ever committed; ship a safe .env.example template.
  5. If real credentials were already committed, rotate first and follow the later history-remediation process.

13. Knowledge check

Question 1. Where should a team-wide generated dist/ ignore normally live?

Question 2. Why quote "src/*.py" in a Git command?

Question 3. Is git add -N equivalent to staging the file's full contents?

Question 4. A secret is already committed. Is adding it to .gitignore sufficient?

14. Summary

Tracking policy has three owners: the project, the repository-local user, and the global user environment. Pathspecs are Git syntax, shell expansion is a separate boundary, filesystem case/mode behavior is machine-sensitive, and advanced index workflows such as partial staging or intent-to-add require deliberate review discipline.

Next

Diagnose the wrong repository, wrong pathspec, wrong layer, and detached HEAD

Lesson 4 deliberately creates common file-lifecycle failures and repairs them without using destructive recovery commands.

Authoritative references

 gitignore
 git-check-ignore
 Git pathspec glossary
 git-add
 git-config

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.