Skip to content

[Feature] Add support for the git-fetch --prune-tags flag #1692

Closed

Description

@goran-w

Since Git 2.17 (Q2 2018), the git-fetch command has a flag --prune-tags which can be used to:

  • Remove any local tags that no longer exist on the remote
  • Force-update any local tags that differ from the remote

NOTE: This flag must be used in combination with the --prune flag (or its corresponding git-config fetch.pruneTags) to actually do any pruning. The config variable is also considered by the git remote prune command (which does not have the --prune-tags flag).

This option should be used carefully, since (unlike --prune) it will remove any local tag that's missing on the remote. (Also, when refs are mapped from multiple remotes into a single local namespace, extra care should be taken when pruning Tags!) Given these considerations, I may not want the option enabled constantly via git-config, but I want to be able to specify it as a flag when manually triggering a Fetch/Prune command.

In SourceGit, this could be implemented by adding a "Prune Tags (--prune --prune-tags)" checkbox in the Fetch Remote Changes dialog.

(Alternatively, a confirmation dialog could be added to the "Prune" context-command for a selected Remote, with a "Prune Tags" checkbox which would modify the command flags used: git -c fetch.pruneTags=true remote prune <remote>)

Activity

  1. goran-w commented on Aug 12, 2025

    @goran-w
    ContributorAuthor

    @love-linger Could we put some prio to this? Just like fetch --prune is important for removing invalid remote-tracking branches, the --prune-tags feature is important for removing old tag-names when tags have been renamed or deleted remotely (and to avoid re-creating these old tag-names by mistake in a later push).

  2. love-linger commented on Aug 12, 2025

    @love-linger
    Collaborator

    I'm considering how to make this option appear reasonably with the existing options. For example: Fetch without tags etc.

  3. self-assigned this
    on Aug 12, 2025
  4. goran-w commented on Aug 12, 2025

    @goran-w
    ContributorAuthor

    I'm considering how to make this option appear reasonably with the existing options. For example: Fetch without tags etc.

    Thank you.

    Yes, this option may need to disable/uncheck some incompatible options if added to the Fetch dialog.

    Another possible implementation could be to add this as a completely separate context-command Prune Tags on each Remote (next to the existing Prune context-command)? However, there's some overlap since a normal --prune always needs to run for --prune-tags to be activated...

    So maybe (as hinted above) it's best to add a 'Prune Tags also' checkbox (with tooltip '--prune-tags') in a (added) dialog-popup from the existing Prune context-command on each Remote?

  5. goran-w commented on Aug 13, 2025

    @goran-w
    ContributorAuthor

    @love-linger - A quick fix (to solve the "urgent" need for this flag) would be to add a second command 'Prune (including Tags)' just below the existing 'Prune command 'in the context-menu for a Remote (root-node).

    Alternatively, add a dialog to the existing Prune command and put this option as a checkbox there.

    Arguably, the safest place to put this command/option is on a single Remote, since the user needs to be careful with which Remote is used to prune the local Tags. For example, if I have created my own tags in my fork of SourceGit, it's fine to run Prune Tags on origin (my fork repo) but doing it on upstream (the official repo) would remove my own (fork-)tags locally... (Therefore, a slight warning text associated with the command/option would make sense.)

    Image
  6. love-linger commented on Aug 13, 2025

    @love-linger
    Collaborator

    Alternatively, add a dialog to the existing Prune command and put this option as a checkbox there.

    Good idea!

  7. love-linger commented on Aug 13, 2025

    @love-linger
    Collaborator

    Unfortunately, I tested the following commands:

    • git -c fetch.pruneTags fetch --prune works
    • git -c remote.origin.pruneTags fetch --prune works
    • git -c remote.origin.pruneTags remote prune origin does not work

    It seems that we can only prune tags with git fetch command (which will fetch new refs from remote), and can not prune tags with git remote prune command (which will not fetch new refs from remote)

    I think we can only add this configuration in the panel for editing the remote. This way, we only need to configure the correct remote once, avoiding the need to consider whether to check the prune tags option every time we execute git remote prune command. Also, this option will be automatically applied by the git fetch command.

  8. goran-w commented on Aug 13, 2025

    @goran-w
    ContributorAuthor

    Hmm, I see. I can confirm that git -c fetch.pruneTags=true remote prune <remote> does not work as I thought it would. Apparently tag-pruning must be done WHILE fetching, basically.

    There is, HOWEVER, also a command git remote update --prune <remote> that seems capable of both fetching and pruning!

    I can confirm that the following command actually works :
    git -c fetch.pruneTags=true remote update --prune <remote>

    With that, we COULD implement a new context-command for selected Remote : 'Update & Prune (including Tags)' !

  9. goran-w commented on Aug 13, 2025

    @goran-w
    ContributorAuthor

    @love-linger - Also, thank you for implementing the option in Add/Edit Remote!

    While it's good to have the option, as noted earlier I may prefer to not have --prune-tags configured constantly. Since it could potentially have unexpected side-effects on unpushed tags, I'd like to only use it on a on-demand basis. Therefore, the 'Update & Prune (including Tags)' (on selected Remote) would be perfect. (Alternatively, that could be implemented as a Custom Action, see suggestion #1726.)

    BTW, the text on the new checkbox should be slightly corrected grammatically, to read as follows:
    Prune tags that don't exist in this remote

    Image
  10. love-linger commented on Aug 14, 2025

    @love-linger
    Collaborator

    I've decided to roll back the changes regarding this ISSUE.

    Since the Prune Tags operation in a repository should always be based on a specific remote, it is recommended to use the custom action feature.

  11. goran-w commented on Aug 14, 2025

    @goran-w
    ContributorAuthor

    @love-linger - Oh no, I'm sad to see it reverted, since the feature you implemented would be fine as a per-remote (persisted) option if the user wants the convenience of having it always enabled for that remote. I would have used that for some repos, but not everywhere. So I'd still like to have it implemented...

    Also, regardless, the #1726 feature needs to be implemented before we can create a custom action for Remotes!

  12. love-linger commented on Aug 14, 2025

    @love-linger
    Collaborator

    No. User can manually config it using git config --local remove.<name>.pruneTags true if they want.

    This configuration is not as useful as I expected. For example, when a user creates a new local tag and does not push it to the remote, if a fetch operation is executed at this time (may be executed by user or the auto-fetch timer), the tag will be directly cleared.

    Therefore, I prefer to provide an entry to run prune tags rather than a configuration that is always in effect.

  13. goran-w commented on Aug 15, 2025

    @goran-w
    ContributorAuthor

    Thanks! For reference, here's how this can be setup as a global Custom Action:

    Image Image

    NOTE - The Git command-arguments used can be either of these:

    • -c fetch.pruneTags=true remote update --prune ${REMOTE}
    • fetch --prune --prune-tags ${REMOTE}

    Words of warning:

    • A common case is that we have a local clone of a (GitHub etc) repo (remote origin) that's forked from a "official / base" repo (remote upstream).
    • It then often happens that origin is not synced with all the Tags from upstream, even though our local clone has received all Tags (when doing a git fetch --all, for example).
    • Newer tags originating from upstream would then get removed locally if we prune Tags using origin, while any fork-specific Tags would get removed (locally at first) if we prune Tags using origin.
    • To avoid this discrepancy and make sure origin has all the tags from upstream, after fetching all Tags from upstream these can be pushed to origin using the Push all tags (--tags) option.
    • Having taken these precautions, we can then "safely" prune Tags using origin, without losing neither the newer ones from upstream nor any fork-specific ones from origin. (These precaution steps could even be "baked into" our tag-pruning Custom Action, by using some additional scripting.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions