threads / bug / 62748

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

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

## tl;dr

2 messages between Jan 6, 2025 and Jan 6, 2025.

replies: 1people: 2as markdown or json

Matthias Braun· Jan 6, 2025, 19:07 UTC · lore
(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· Jan 6, 2025, 22:25 UTC · re: Matthias Braun · lore

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

On 2025-01-06 at 19:07:01, Matthias Braun wrote:
Show 8 quoted lines
> (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.

Show 36 quoted lines
> ```
> #!/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

← back to recent threads