Skip to content

Tags, worktrees and other pieces

These pieces don’t depend on each other, but each builds on objects and refs, and several come up again in transfer and merging.

.gitattributes files map path patterns to settings. Patterns follow the .gitignore rules with two exceptions: ! patterns aren’t allowed, and a directory pattern such as docs/ doesn’t match the files inside it, so use docs/** for that:

*.rs diff=rust
*.sh text eol=lf
*.png binary
*.psd filter=lfs diff=lfs merge=lfs -text
docs/** export-ignore

The common attributes are text and eol (line-ending conversion), diff= (the diff driver), merge= (the merge driver), filter= (a clean and smudge filter) and export-ignore (leave the path out of git archive). A macro names a group of settings: binary means -diff -merge -text. Diffs, merges, checkout, status and archives all consult attributes, and git check-attr -a path shows what applies to a path.

girtPartialAttributes and macros match git check-attr; text, eol and ident take effect through girt::filter, status and checkout. Consumer gaps include merging and archive. Named-user core.attributesFile paths are refused (#555).API docs

A lightweight tag is just a ref, refs/tags/v1.0, pointing at a commit. An annotated tag is a ref pointing at a tag object, which records the tagger, date, message and optional signature and points at the commit. Release tags are usually annotated, so the release has an author and a message of its own.

Peeling follows tag objects until it reaches something that isn’t a tag. v1.0^{} is the commit an annotated tag finally points at, and git show-ref --dereference prints peeled values. Because a tag can point at another tag, peeling may take several steps.

girtSupportedAPI docs

git worktree add ../hotfix hotfix checks out a second branch in another directory, sharing the same repository. The new directory’s .git is a file, not a directory, containing gitdir: /path/to/repo/.git/worktrees/hotfix. That administrative directory holds the worktree’s own HEAD, index and per-worktree refs, while objects, branches and configuration are shared. Git refuses to check out the same branch in two worktrees, because a commit in one would silently change the other’s checkout.

Administration covers listing (git worktree list), locking a worktree on a removable drive so it isn’t cleaned up, moving one, and pruning the records of worktrees whose directories were deleted.

girtPartialOrphan add, list, lock, unlock, prune and repair; no move, existing-history add or live removal (#487). Cross-worktree ref aliases are also absent (#550).issue #504

git clone --depth 1 downloads only the most recent commit, not the whole history. The file .git/shallow lists the cut-off commits; Git treats them as having no parents, even though their commit objects name parents that aren’t in the repository.

Everything that walks history has to respect this boundary. History walks must stop there instead of failing on a missing parent, and every fetch must tell the server where the boundary is, so the server doesn’t assume the client has commits it lacks. git fetch --deepen 10 or --unshallow moves the boundary.

girtSupportedAPI docs

When an HTTPS remote asks for a password, Git doesn’t store or prompt for it itself. It asks a credential helper: the OS keychain (osxkeychain, manager, libsecret), the in-memory cache, the plain-text store, or any program named in credential.helper. The protocol is key=value lines on standard input and output:

protocol=https
host=github.com

The helper replies with username= and password= lines. After the server accepts or refuses them, Git calls the helper again with store or erase (git credential approve and reject), so helpers keep working credentials and drop bad ones. If no helper answers, Git falls back to the program in GIT_ASKPASS or a terminal prompt.

girtSupportedGit-verified credential store and askpass protocol; applications supply terminal prompts.API docs