Index and working tree
The index records what the next commit would contain; the working tree is the checked-out files.
girt has no add or commit, so the examples use git to make changes for girt to look at. These
commands read both and, in the case of checkout and worktree, change them. Status and checkout
work on macOS and Linux only. The library side is in
The index and working tree.
List the index (girt index list)
Section titled “List the index (girt index list)”girt index list prints the path of every index entry. --stage adds the mode, the blob ID and
the stage number, which is 0 except during a conflicted merge.
$ girt index list --stage100644 2f7896d1d1365eafb0da03d9fe456fac81408487 0 .gitignore100644 94954abda49de8615a048f8d2e64b5de848e27a1 0 README.md100644 f328e4d9d04c31d0d70d16d21a07d1613be9d577 0 src/main.rsShow changes (girt status)
Section titled “Show changes (girt status)”girt status compares HEAD, the index and the working tree and prints one <XY> <path> line per
changed path, using the letters of git status --porcelain: the first column is the index against
HEAD, the second the working tree against the index. -u adds untracked files, filtered through
.gitignore, info/exclude and core.excludesFile. Without -u it corresponds to
git status --porcelain -uno, and with it to --untracked-files=all. -b starts with the branch
line of git status -sb, such as ## main...origin/main [ahead 1, behind 2]: the commits each side
has that the other lacks, or [gone] when the upstream reference no longer exists.
$ printf 'more\n' >> README.md$ printf 'new\n' > new.txt && git add new.txt$ printf 'scratch\n' > notes.txt$ girt status -u M README.mdA new.txt?? notes.txtStatus converts working files as Git does before comparing them: line endings, ident,
working-tree-encoding and filter programs such as Git LFS, configured in local or global config
and chosen per path by .gitattributes. --refuse-filter-commands fails instead of running a
filter program, and --raw compares literal bytes; see
Line endings and filters. It applies no core.filemode or core.symlinks
policy and no rename detection, so a repository that relies on those can show changes Git wouldn’t.
On macOS, non-ASCII working-tree paths are refused for now.
Explain ignore rules (girt ignore check)
Section titled “Explain ignore rules (girt ignore check)”girt ignore check reports, for each path, the rule that decides whether it is ignored, or that
none does. Tracked paths are never ignored. It exits 0 when any path is ignored and 1 otherwise.
$ mkdir -p target && touch target/app$ girt ignore check target/app notes.txttarget/app: ignored by .gitignore:1: target/notes.txt: not ignoredCheck out a tree (girt checkout)
Section titled “Check out a tree (girt checkout)”girt checkout <revision> replaces the index and working tree with that revision’s tree. It
doesn’t move HEAD, so afterwards status reports the difference as staged changes. It prints what
it changed. It refuses to run over uncommitted changes, so the first command puts the status
example’s changes away.
$ git reset -q --hard && rm notes.txt$ girt checkout main~1installed 0, removed 1, created 0 directories, removed 0 directories$ girt statusD .gitignore$ girt checkout main --from main~1installed 1, removed 0, created 0 directories, removed 0 directoriesCheckout updates the working tree from a known starting point, --from, which defaults to HEAD.
That baseline must match the index and working tree exactly: girt refuses to run over dirty, staged
or conflicted paths rather than overwrite them. After a clone --no-checkout, where there is no
index yet, the baseline is empty. Files are converted as in status, with the same --raw and
--refuse-filter-commands options, and on macOS non-ASCII paths are refused, as in status. Split
and sparse indexes, resolve-undo data and unknown index extensions are refused; the derived caches
(TREE, FSMN, UNTR, EOIE, IEOT) are dropped for Git to rebuild.
Move the branch or unstage files (girt reset)
Section titled “Move the branch or unstage files (girt reset)”girt reset <revision> moves the current branch, or a detached HEAD, to a commit and replaces the
index with that commit’s tree, so the commits you stepped back over show up as unstaged changes.
--soft moves only the branch and keeps those changes staged. Working files never change. Both
record the old commit in ORIG_HEAD and append reset: moving to <revision> to the reflogs, as
git reset does. With paths after --, only those index entries are reset, which unstages them
without moving anything.
$ printf 'draft\n' >> README.md && git add README.md$ girt reset -- README.md$ girt status M README.md$ girt reset --soft main~1$ girt statusA .gitignore M README.md--hard, --keep and --merge, which also rewrite working files, are not available yet, and an
index from a sparse checkout is refused.
Manage linked worktrees (girt worktree)
Section titled “Manage linked worktrees (girt worktree)”girt worktree list prints the main worktree and every linked one, with its HEAD and branch. The
other subcommands look after a registration under .git/worktrees/: lock protects it from
pruning, unlock removes that protection, prune deletes a registration whose checkout no longer
exists, with its HEAD and index, and repair relinks a registration with a checkout that has moved.
$ git worktree add -q ../review$ girt worktree list/home/me/demo 7ed7a0cc68995713f52d973e6adfd3d9e667324f [main]/home/me/review 7ed7a0cc68995713f52d973e6adfd3d9e667324f [review]
$ girt worktree lock review --reason "on a removable disk"$ girt worktree unlock review
$ mv ../review ../review-moved$ girt worktree repair review ../review-moved$ girt worktree list/home/me/demo 7ed7a0cc68995713f52d973e6adfd3d9e667324f [main]/home/me/review-moved 7ed7a0cc68995713f52d973e6adfd3d9e667324f [review]The CLI has no command to create a linked worktree. The library can
(Repository::create_orphan_worktree)
creates one with an unborn branch, and git worktree add works too.