616

How do you stop tracking a remote branch in Git?

I am asking to stop tracking because in my concrete case, I want to delete the local branch, but not the remote one. Deleting the local one and pushing the deletion to remote will delete the remote branch as well:

Can I just do git branch -d the_branch, and it won't get propagated when I later git push?

Will it only propagate if I were to run git push origin :the_branch later on?

Community
  • 1
  • 1
Jason Cohen
  • 75,915
  • 26
  • 104
  • 111

10 Answers10

802

As mentioned in Yoshua Wuyts' answer, using git branch:

git branch --unset-upstream

Other options:

You don't have to delete your local branch.

Simply delete the local branch that is tracking the remote branch:

git branch -d -r origin/<remote branch name>

-r, --remotes tells git to delete the remote-tracking branch (i.e., delete the branch set to track the remote branch). This will not delete the branch on the remote repo!

See "Having a hard time understanding git-fetch"

there's no such concept of local tracking branches, only remote tracking branches.
So origin/master is a remote tracking branch for master in the origin repo

As mentioned in Dobes Vandermeer's answer, you also need to reset the configuration associated to the local branch:

git config --unset branch.<branch>.remote
git config --unset branch.<branch>.merge

Remove the upstream information for <branchname>.
If no branch is specified it defaults to the current branch.

(git 1.8+, Oct. 2012, commit b84869e by Carlos Martín Nieto (carlosmn))

That will make any push/pull completely unaware of origin/<remote branch name>.

MTV
  • 59
  • 7
VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283
  • 9
    The remote tracking branch is recreated after git fetch. Is it possible to exclude these? – Matt R Aug 06 '10 at 10:46
  • 1
    @Matt: I believe this would be done by setting the `remote..fetch` refspec config setting, but I am not sure if you can exclude a branch when specifying a refspec. – VonC Aug 06 '10 at 11:04
  • It appeared that way to me too; I was able to rebase my local branch though and after the fast-forward the apparent connection between the branches disappeared. – willoller Aug 30 '10 at 21:18
  • Didn't work for me. When pushing, I'm still getting warnings about the branches I deleted. As the OP, I want to stop tracking some of the remote branches I pushed to in the past. So after `git branch -d -r origin/development`, when I `git push` I still get `! [rejected] development -> development (non-fast-forward)` – ruffin May 15 '12 at 15:59
  • 7
    @ruffin: this is completely normal: `git branch -d -r origin/` will delete a remote tracking branch as declared *locally*, in your repo. It will *not* delete the branch on the remote repo itself (only a `git push :development` would do that). So when you are pushing your local `development`, with an history different than the remote development branch (on the remote repo), you will still get the `non-fast-forward` warning. – VonC May 15 '12 at 18:06
  • @VonC I did this primarily to have this repository "forget" it was tracking branch no longer used (in this clone), and this does unfortunately not help. – Thorbjørn Ravn Andersen Dec 10 '12 at 12:50
  • @ThorbjørnRavnAndersen what `git branch -a` and `git config -l` return (in particular `branch.name.remote` and `branch.name.merge`)? Those information could be the basis of a *new* Stack Overflow question. – VonC Dec 10 '12 at 13:10
  • I found that the steps provided by @Dobes Vandermeer worked - the repository forgot about the branch I once visited in this clone, but did not want to work on again there. – Thorbjørn Ravn Andersen Dec 10 '12 at 14:18
  • @VonC: *deleting* the remote branch is **not** required to stop tracking it! – Marco Mar 11 '13 at 15:27
  • 1
    @Marco true, but I prefer doing it anyway, I find it "cleaner". – VonC Mar 11 '13 at 15:29
  • Im using JIRA. When I do pull again the branch appears. How can I prevent that? – powder366 Jan 13 '15 at 13:42
  • @powder366 not sure: that could be a question of its own. – VonC Jan 13 '15 at 13:55
  • `there's no such concept of local tracking branches, only remote tracking branches.` This isn't quite true--or at least it requires further explanation. Someone _could_ say they have a "local tracking branch" and mean quite literally: "a branch which is locally-stored, and which is also a tracking branch," which would be a _correct_ (albeit somewhat ambiguous) thing to say. So, it's better to say **there's no such thing as a local-tracking branch, but there _is_ such thing as a _locally-stored_ remote-tracking branch, which is precisely what a remote-tracking branch is.** – Gabriel Staples Sep 06 '20 at 04:50
  • One should also note a locally-stored remote-tracking branch, named `remote_name/branch_name` (ex: `origin/my_branch`) is what is updated by `git fetch.` Note/source: I first mentioned my remarks in this comment and the one above [in a GitHub comment here](https://gist.github.com/magnusbae/10182865#gistcomment-3443489). – Gabriel Staples Sep 06 '20 at 04:52
  • 2
    @GabrielStaples I agree. For more on remote tracking: https://stackoverflow.com/a/44081446/6309, https://stackoverflow.com/a/38202006/6309 and https://stackoverflow.com/a/28341622/6309 – VonC Sep 06 '20 at 09:24
  • 1
    Thanks you have save my day :) – rudi Ladeon Jan 05 '21 at 13:20
223

To remove the upstream for the current branch do:

$ git branch --unset-upstream

This is available for Git v.1.8.0 or newer. (Sources: 1.7.9 ref, 1.8.0 ref)

source

nukeguy
  • 396
  • 1
  • 6
  • 19
Yoshua Wuyts
  • 3,326
  • 1
  • 17
  • 16
107

To remove the association between the local and remote branch run:

git config --unset branch.<local-branch-name>.remote
git config --unset branch.<local-branch-name>.merge

Optionally delete the local branch afterwards if you don't need it:

git branch -d <branch>

This won't delete the remote branch.

Alex
  • 8,838
  • 11
  • 67
  • 79
Dobes Vandermeer
  • 7,756
  • 3
  • 39
  • 41
  • 11
    `git branch -d ` is *not* required to remove the association. – Marco Mar 11 '13 at 15:27
  • 1
    Im using JIRA. When I do pull again the branch appears. How can I prevent that? – powder366 Jan 13 '15 at 13:42
  • 1
    @Marco Correct, but if you use `git branch -vv` you will still see the old branches until you do `git branch -d `. – Seldom 'Where's Monica' Needy Feb 13 '16 at 08:01
  • @powder366 Depending on your settings, `git pull` may grab **all** remote branches and re-add any it considers to have "appeared" on remote. You can change this "pull all branches" behavior by doing `git config [--global] push.default simple` or `git config [--global] push.default current`. [More on **`push.default`** here](https://git-scm.com/docs/git-config "load the page then ctrlF for push.default"). – Seldom 'Where's Monica' Needy Feb 13 '16 at 08:10
  • @SeldomNeedy They are *not* "old" branches! They're just branches that are no longer tracking the remote ones -- which happens to be the subject of the question. – Marco Feb 14 '16 at 22:32
  • @Marco would you prefer I said "(locally) disused" ? In most cases to most people, this translates as "old". – Seldom 'Where's Monica' Needy Feb 15 '16 at 00:08
  • 1
    @SeldomNeedy I think you might be missing the point of a DVCS? The point is that I can have a branch that starts out tracking an upstream branch, but that I detach in order to pursue an approach that the upstream branch is not using. In that case, the branch is neither "old" (because I'm still developing on it) nor "disused" (because I'm using it). This is a large part of the design of a DVCS.. Does that make sense? – Marco Feb 16 '16 at 14:00
35

The simplest way is to edit .git/config

Here is an example file

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
[remote "origin"]
        url = git@example.com:repo-name
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "test1"]
        remote = origin
        merge = refs/heads/test1
[branch "master"]
        remote = origin
        merge = refs/heads/master

Delete the line merge = refs/heads/test1 in the test1 branch section

Jacob Groundwater
  • 6,221
  • 1
  • 25
  • 40
  • 5
    +1 I cannot say definitively that this is the easiest method, but it certainly proves the easiest for me to understand (and hopefully therefor to remember)! – sage Jan 09 '13 at 20:07
  • Nice solution +1. This is actually the place where the tracking is registered, easy to change, clear what it does. Commandline `.git/config` is available, too. – hakre Apr 24 '13 at 13:43
  • 5
    fyi, this is the same as the "git config --unset" solution by Dobes Vandermeer. "git config" edits this file. – J.Z. Jul 28 '13 at 16:03
12

You can delete the remote-tracking branch using

git branch -d -r origin/<remote branch name>

as VonC mentions above. However, if you keep your local copy of the branch, git push will still try to push that branch (which could give you a non-fast-forward error as it did for ruffin). This is because the config push.default defaults to matching which means:

matching - push all matching branches. All branches having the same name in both ends are considered to be matching. This is the default.

(see http://git-scm.com/docs/git-config under push.default)

Seeing as this is probably not what you wanted when you deleted the remote-tracking branch, you can set push.default to upstream (or tracking if you have git < 1.7.4.3)

upstream - push the current branch to its upstream branch.

using

git config push.default upstream

and git will stop trying to push branches that you have "stopped tracking."

Note: The simpler solution would be to just rename your local branch to something else. That would eliminate some potential for confusion, as well.

Community
  • 1
  • 1
CletusW
  • 3,392
  • 1
  • 21
  • 37
3

Here's a one-liner to remove all remote-tracking branches matching a pattern:

git branch -rd $(git branch -a | grep '{pattern}' | cut -d'/' -f2-10 | xargs)

Danny Kopping
  • 4,037
  • 1
  • 22
  • 38
  • If only remote-tracking branches are to be untracked (deleted), then I think this is shorter one-line alternative: `git branch -r -D $(git branch -r | grep -v "master")` – dma_k Oct 03 '18 at 12:50
1

This is not an answer to the question, but I couldn't figure out how to get decent code formatting in a comment above... so auto-down-reputation-be-damned here's my comment.

I have the recipe submtted by @Dobes in a fancy shmancy [alias] entry in my .gitconfig:

# to untrack a local branch when I can't remember 'git config --unset'
cbr = "!f(){ git symbolic-ref -q HEAD 2>/dev/null | sed -e 's|refs/heads/||'; }; f"
bruntrack = "!f(){ br=${1:-`git cbr`};  \
    rm=`git config --get branch.$br.remote`; \
    tr=`git config --get branch.$br.merge`; \
    [ $rm:$tr = : ] && echo \"# untrack: not a tracking branch: $br\" && return 1; \
    git config --unset branch.$br.remote; git config --unset branch.$br.merge; \
    echo \"# untrack: branch $br no longer tracking $rm:$tr\"; return 0; }; f"

Then I can just run

$ git bruntrack branchname
qneill
  • 1,451
  • 12
  • 15
  • 1
    +1. Nice alias, in addition to [my answer above](http://stackoverflow.com/a/3046478/6309). – VonC Jun 04 '14 at 17:02
-1

git branch --unset-upstream stops tracking all the local branches, which is not desirable.

Remove the [branch "branch-name"] section from the .git/config file followed by

git branch -D 'branch-name' && git branch -D -r 'origin/branch-name'

works out the best for me.

Bob
  • 87
  • 6
-1

You can use this way to remove your remote branch

git remote remove <your remote branch name>
Hưng
  • 1
  • 2
    That would remove *all* remote tracking branches for that remote: il you have more than one, that could be problematic. – VonC Jul 11 '19 at 07:49
-2

The easiest way to do this is to delete the branch remotely and then use:

git fetch --prune (aka git fetch -p)

Mark Caudill
  • 114
  • 1
  • 1