320

If someone deleted a remote branch because the work is over and I don't know, I won't do a git fetch --prune and eventually I will push back the deleted branch.

Is there a viable solution for forcing Git to use the prune mode when fetching / pulling without having to specify it every time?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Edmondo
  • 19,559
  • 13
  • 62
  • 115
  • 2
    You will soon (git 1.8.5, Q4 2013) be able to specify in the local config of a repo that you want to *always* prune on `git fetch`! See [my answer below](http://stackoverflow.com/a/18718936/6309) – VonC Sep 10 '13 at 12:26

4 Answers4

511

Since git 1.8.5 (Q4 2013):

"git fetch" (hence "git pull" as well) learned to check "fetch.prune" and "remote.*.prune" configuration variables and to behave as if the "--prune" command line option was given.

That means that, if you set remote.origin.prune to true:

git config remote.origin.prune true

Any git fetch or git pull will automatically prune.

Note: Git 2.12 (Q1 2017) will fix a bug related to this configuration, which would make git remote rename misbehave.
See "How do I rename a git remote?".


See more at commit 737c5a9:

Without "git fetch --prune", remote-tracking branches for a branch the other side already has removed will stay forever.
Some people want to always run "git fetch --prune".

To accommodate users who want to either prune always or when fetching from a particular remote, add two new configuration variables "fetch.prune" and "remote.<name>.prune":

  • "fetch.prune" allows to enable prune for all fetch operations.
  • "remote.<name>.prune" allows to change the behaviour per remote.

The latter will naturally override the former, and the --[no-]prune option from the command line will override the configured default.

Since --prune is a potentially destructive operation (Git doesn't keep reflogs for deleted references yet), we don't want to prune without users consent, so this configuration will not be on by default.

rjmunro
  • 27,203
  • 20
  • 110
  • 132
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 1
    I want this behavior by default in all my git repos. Is there some where I can put this in my .gitconfig to make that happen? – Andrew Jun 01 '15 at 20:36
  • 67
    @Andrew a good start would be `git config --global fetch.prune true` – VonC Jun 02 '15 at 06:42
  • 3
    what are the possible downsides to always pruning on pull? the quote mentions that reflog history is affected... but what practical problem might that introduce? – Grapho Oct 15 '18 at 22:27
  • 5
    @Grapho no real downside but... see more at https://stackoverflow.com/a/39862779/6309 – VonC Oct 16 '18 at 05:08
254

git config --global fetch.prune true

To always --prune for git fetch and git pull in all your Git repositories:

git config --global fetch.prune true

This above command appends in your global Git configuration (typically ~/.gitconfig) the following lines. Use git config -e --global to view your global configuration.

[fetch]
    prune = true

git config remote.origin.prune true

To always --prune but from one single repository:

git config remote.origin.prune true
                 #^^^^^^
                 #replace with your repo name

This above command adds in your local Git configuration (typically .git/config) the below last line. Use git config -e to view your local configuration.

[remote "origin"]
    url = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    fetch = +refs/heads/*:refs/remotes/origin/*
    prune = true

You can also use --global within the second command or use instead --local within the first command.


git config --global gui.pruneDuringFetch true

If you use git gui you may also be interested by:

git config --global gui.pruneDuringFetch true

that appends:

[gui]
    pruneDuringFetch = true

References

The corresponding documentations from git help config:

--global

  For writing options: write to global ~/.gitconfig file rather than the repository .git/config, write to $XDG_CONFIG_HOME/git/config file if this file exists and the ~/.gitconfig file doesn’t.

 

--local

  For writing options: write to the repository .git/config file. This is the default behavior.

 

fetch.prune

  If true, fetch will automatically behave as if the --prune option was given on the command line. See also remote.<name>.prune.

 

gui.pruneDuringFetch

  "true" if git-gui should prune remote-tracking branches when performing a fetch. The default value is "false".

 

remote.<name>.prune

  When set to true, fetching from this remote by default will also remove any remote-tracking references that no longer exist on the remote (as if the --prune option was given on the command line). Overrides fetch.prune settings, if any.

oHo
  • 51,447
  • 27
  • 165
  • 200
  • 2
    Side note: I just learned about `git config -e` and `git config -e --global` from this post. No more typing `vim` commands to point to a specific path to a git config file, and having to think about what that specific path is. – ecbrodie Aug 02 '18 at 17:51
  • This answer is quite thorough, but very hard to read because of its formatting. I’d have found "To always --prune for git fetch and git pull in all your Git repositories: `git config --global fetch.prune true`" just as good (with a link to the relevant docs). – Thibaud Colas Feb 28 '20 at 15:42
21

If you want to always prune when you fetch, I can suggest to use Aliases.

Just type git config -e to open your editor and change the configuration for a specific project and add a section like

[alias]
pfetch = fetch --prune   

the when you fetch with git pfetch the prune will be done automatically.

Snap
  • 3
  • 1
ThanksForAllTheFish
  • 7,101
  • 5
  • 35
  • 54
  • I understand. Pull by the way will use git fetch and not git pfetch... should I directly have an alias for pull? – Edmondo Aug 19 '13 at 08:59
  • 1
    I will. In this way you have both options, normal `pull` and `fetch` and their pruned version. Actually, I think (but I haven't tried) you can write `fetch = fetch --prune` directly in the alias section and therefore `pull` will use the pruned fetch automatically – ThanksForAllTheFish Aug 19 '13 at 09:18
  • 2
    As far as I know `fetch = fetch --prune` doesn't work, overwriting a command with an alias did not work for me. This could be because I'm using an old version (1.7.2.5) – Uipko Apr 30 '14 at 10:02
  • 4
    From the git config documentation: "To avoid confusion and troubles with script usage, aliases that hide existing Git commands are ignored." – Dewayne Christensen May 15 '15 at 16:00
2

and eventually I will push back the deleted branch

This is something that I think you should address. If you have git configured so that it pushes branches you aren't trying to push, this can be a problem. I personally prefer to set it up so that I only push a branch when I explicitly specify a branch that I want to push.

See https://stackoverflow.com/a/948397/3753318 for some guidance on how to configure the push settings in your git repository.

MarkR
  • 166
  • 1
  • 8