# bug: Removing branch and creating branch-directory with same name breaks

2 messages from 2025-01-06 to 2025-01-06. Participants: Matthias Braun, brian m. carlson.
Thread: https://gitlist.dev/t/62748

## Matthias Braun, 2025-01-06 19:07

Subject: bug: Removing branch and creating branch-directory with same name breaks
Message-ID: <25913110-E42E-4028-B39D-44045623FDC4@braunis.de>
URL: https://gitlist.dev/e/25913110-E42E-4028-B39D-44045623FDC4%40braunis.de

```
(Note that I also tried this with latest git-2.47.1 after creating the repro script and it still fails there).

What did you do before the bug happened? (Steps to reproduce your issue)
- Removed remote branch. Created new directory (for branch names)
  with same name directory name as the previously used branch name.
  After that `git fetch` fails.

Reproduction script for your convenience:
ˋˋˋ
#!/bin/bash

mkdir -p repro
git init repro/remote.git
git clone repro/remote.git repro/cloned
pushd repro/cloned
echo "hello" > hello.txt
git add hello.txt
git commit -m "test commit"
git branch mystuff
git push origin mystuff
popd

git clone repro/remote.git repro/clone2

pushd repro/cloned
git branch -D mystuff
git push -d origin mystuff
git branch mystuff/branch_in_subdir
git push origin mystuff/branch_in_subdir
popd

pushd repro/clone2
git fetch    #  This fails as branch turned into directory
popd
ˋˋˋ

What did you expect to happen? (Expected behavior)

`git fetch` should work...

What happened instead? (Actual behavior)

`git fetch origin`
error: cannot lock ref 'refs/remotes/origin/mystuff/branch_in_subdir': 'refs/remotes/origin/mystuff' exists; cannot create 'refs/remotes/origin/mystuff/branch_in_subdir'

What's different between what you expected and what actually happened?

Anything else you want to add:

Please review the rest of the bug report below.
You can delete any lines you don't wish to share.


[System Info]
git version:
git version 2.43.5
cpu: x86_64
no commit associated with this build
sizeof-long: 8
sizeof-size_t: 8
shell-path: /bin/sh
uname: Linux 5.19.0-0_fbk12_hardened_11583_g0bef9520ca2b #1 SMP Fri Feb 2 17:56:12 PST 2024 x86_64
compiler info: gnuc: 11.4
libc info: glibc: 2.34
$SHELL (typically, interactive shell): /bin/zsh


[Enabled Hooks]
not run from a git repository - no hooks to show
```

## brian m. carlson, 2025-01-06 22:25

Subject: Re: bug: Removing branch and creating branch-directory with same name breaks
Message-ID: <Z3xYY5A7BblBiYmG@tapette.crustytoothpaste.net>
URL: https://gitlist.dev/e/Z3xYY5A7BblBiYmG%40tapette.crustytoothpaste.net
In-Reply-To: <25913110-E42E-4028-B39D-44045623FDC4@braunis.de>

```
On 2025-01-06 at 19:07:01, Matthias Braun wrote:
> (Note that I also tried this with latest git-2.47.1 after creating the repro script and it still fails there).
> 
> What did you do before the bug happened? (Steps to reproduce your issue)
> - Removed remote branch. Created new directory (for branch names)
>   with same name directory name as the previously used branch name.
>   After that `git fetch` fails.
> 
> Reproduction script for your convenience:

Thanks for the reproduction steps.  This is expected, and I'll explain
more below.

> ˋˋˋ
> #!/bin/bash
> 
> mkdir -p repro
> git init repro/remote.git
> git clone repro/remote.git repro/cloned
> pushd repro/cloned
> echo "hello" > hello.txt
> git add hello.txt
> git commit -m "test commit"
> git branch mystuff
> git push origin mystuff
> popd
> 
> git clone repro/remote.git repro/clone2
> 
> pushd repro/cloned
> git branch -D mystuff
> git push -d origin mystuff
> git branch mystuff/branch_in_subdir
> git push origin mystuff/branch_in_subdir
> popd
> 
> pushd repro/clone2
> git fetch    #  This fails as branch turned into directory
> popd
> ˋˋˋ
> 
> What did you expect to happen? (Expected behavior)
> 
> `git fetch` should work...
> 
> What happened instead? (Actual behavior)
> 
> `git fetch origin`
> error: cannot lock ref 'refs/remotes/origin/mystuff/branch_in_subdir': 'refs/remotes/origin/mystuff' exists; cannot create 'refs/remotes/origin/mystuff/branch_in_subdir'

git fetch does not by default delete remote tracking branches which no
longer exist on the remote.  That's because sometimes you want to keep
those around even though upstream does not.[0]

In this case, or if you just don't want to keep them around, you can use
`git fetch --prune origin` to prune those old branches when fetching, or
`git remote prune origin` to just prune and not fetch (and, of course,
these work with any remote, not just `origin`).  The `git fetch` manpage
mentions the `fetch.prune` and `remote.<name>.prune` options for you to
control this automatically as you see fit.

[0] At a previous employer, large projects were squashed-and-merged, and
I found keeping around the original history—and thus the original
branches—was invaluable to understanding why a change was made or who I
should talk to about a particular change if I had questions.
-- 
brian m. carlson (they/them or he/him)
Toronto, Ontario, CA

```
