#1408·tig

[Bug]: unreliable `%(file)` variable

Author: jraygauthierCreated Mar 10, 2026Updated Jun 5, 2026

This %(file) seems to be set to a file when entering a file specific context (e.g.: moving to a file in the status view, moving to a file segment in the diff view, moving to a file in the blob view).

However, it won't be reset (to empty) when entering a non file context and is stuck to its previous value.

  • Moving to a file section in the status view (e.g.: "Changes to be committed", "Untracked files", etc).
  • Moving to a commit from the main view.

Because of that, it is impossible for external tools to know whether one must act on a single file or a set of files (full commit, all untracked files, etc.).

It is possible to workaround this for the status view section by using the %(status) variable (in a very hackish way). However, this variable is useless outside of the status view as it won't be updated either so it won't allow any workaround for per commit actions.

Here's couple of use cases.

Prerequisites

A mean to debug the variables.

I use something like:

rc
bind generic B >sh -c 'echo "commit=[%(commit)],ref=[%(ref)],head=[%(head)],blob=[%(blob)],status=[%(status)],file=[%(file)],text=[%(text)]" | less'

A repo with all kind of changes

A repo with the following kind of changes: "untracked", "unstaged", "staged" and "commited".

Use case 1

  1. Enter the main view ($tig)

  2. Go to the "Untracked changes" entry

    log
    commit=[0000000000000000000000000000000000000000],ref=[HEAD],head=[HEAD],blob=[],status=[Untracked file],file=[],text=[]`
  3. Hit s to enter the status view

  4. Move down to select a file entry

  5. Hit q to quit the status view and return to the main view Cursor is still on "Untracked changes", however its file is stuck to the file selected it the status view.

    log
    commit=[0000000000000000000000000000000000000000],ref=[HEAD],head=[HEAD],blob=[],status=[Untracked file ],file=[my/file.ext],text=[]

    I would have expected for file to be empty as it was when I entered the main view.

    See also that status gained a trailing space character.

Use case 2

  1. Enter the main view ($tig)

  2. Go to the an actual commit.

    log
    commit=[a0d59c4e549d08f18544abcdd85c8affa0646e33],ref=[HEAD],head=[HEAD],blob=[],status=[Staged changes],file=[],text=[]
  3. Hit d to enter the diff view

    log
    commit=[a0d59c4e549d08f18544abcdd85c8affa0646e33],ref=[HEAD],head=[HEAD],blob=[],status=[Untracked file ],file=[],text=[commit a0d59c4e549d08f18544abcdd85c8affa0646e33]

    Note that file is empty as expected. Note also this odd status value (which also has a trailing white-space).

  4. Move your cursor down to a line that belong to a file in the diff

    log
    commit=[a0d59c4e549d08f18544abcdd85c8affa0646e33],ref=[HEAD],head=[HEAD],blob=[],status=[Untracked file ],file=[my/file.ext],text=[ my/file.ext  | 2 --]
  5. Move back to the first line of the diff (file agnostic)

    log
    commit=[a0d59c4e549d08f18544abcdd85c8affa0646e33],ref=[HEAD],head=[HEAD],blob=[],status=[Untracked file ],file=[my/file.ext],text=[ my/file.ext  | 2 --]

    See how file is still stuck to the file instead of being reset.

  6. Hit q to quit the diff view and return to the main view

    log
    commit=[a0d59c4e549d08f18544abcdd85c8affa0646e33],ref=[HEAD],head=[HEAD],blob=[],status=[Untracked file ],file=[my/file.ext],text=[commit a0d59c4e549d08f18544abcdd85c8affa0646e33]

    See how file still refer to the file we had when in the diff view instead of being reset as expected.

    See also status still stuck to what it was in the diff view instead of having the same value it had originally.

Use case X

There are many more instances of this problem.