Description
- Gitea version (or commit ref): 1.7.3
- Git version: 1.8.3.1
- Operating system: CentOS 7
- Database:
- PostgreSQL
- MySQL
- MSSQL
- SQLite
- Can you reproduce the bug at https://try.gitea.io:
- Yes (provide example URL)
- No
- Not relevant
Description
This is somewhat related to #2665.
I am trying to migrate from Gogs to Gitea but I'm having problems migrating repositories without a master branch (I tried doing an in-place upgrade but despite different success stories describing different upgrade paths I am having no luck and end up with a seemingly corrupt database so I'm trying to use migrations and do it by hand).
Symptoms
When trying to migrate a repository without a master branch the newly created repository always shows the quick-start guide.
Looking into the database the repo's respective is_bare
field is set to 1
. Manually setting this to 0
"fixes" the repository view as noted in #2665 but has the side-effect that the branch dropdown list still defaults to master
which doesn't exist (despite no default branch being set in the database). This in turn has the side-effect e.g. when looking at the commit history it is trying to load the history for the non-existent master
branch which obviously results in a 404. Manually switching to an existing branch in the dropdown list first "fixes" this. This seems to be identical to #3204 and #3525 which should have been fixed in #3715 but that doesn't seem to be the case?
In Gitea, it seems that the dropdown list always shows the default_branch
which defaults to master
if empty (and thus selects master
even if it doesn't exist). In Gogs a non-existent default_branch
doesn't get displayed in the dropdown list and instead seems to pick the first existing branch in the list, which is a saner approach in my opinion and also results in Gogs not exhibiting the above side-effects because the GUI never erroneously selects a branch which doesn't exist.
All that being said, the crux of the matter seems to be the remote bare repository's HEAD
state. When creating a repository without a master branch in either system the bare repository's HEAD
still points to refs/heads/master
(which is the default) unless you explicitly set a default branch in the GUI (as mentioned above #3715 states that the first push should set the default branch which doesn't seem to be the case here, at least it doesn't seem to update the remote HEAD
).
If I make HEAD
point to an existing ref either by manually changing the file or setting a default branch in the GUI before migrating then everything seems to work as expected. However, I would not expect having a dangling remote HEAD
to break migration.
Steps to reproduce
- Create a new uninitialized repository in the GUI
clone$ git clone http://gitea/foo/bar.git
clone$ cd bar
clone$ git init
clone$ git symbolic-ref HEAD refs/heads/no-master # it doesn't matter if you do it this way or later rename master to something else
clone$ echo foo >README.md
clone$ git add README.md
clone$ git commit -m "quux"
clone$ git push origin no-master
- The server repo has its
HEAD
pointing tomaster
which doesn't exist:
gitea$ pwd
/home/gitea/gitea-repositories/foo/bar.git
gitea$ cat HEAD
ref: refs/heads/master
gitea$ git branch -av
no-master 8839b32 quux
- Create a new migration with the new repository as origin. The migrated repository will show the symptoms described above.
This might or might not be related to what is explained here.
If you clone a repo with a remote "dangling" HEAD
(pointing to its default master
while master
doesn't exist) the cloned repository ends up in detached HEAD
state. That is expected and in my book totally fine and legal. If the remote HEAD
points to an existing branch then the client will set the default branch to the same when cloned. I assume that the detached HEAD
in the first scenario after cloning is what Gitea chokes on when doing a migration.
Having master
-less repositories with no explicitly set default branch is an informed decision I made and fits my use case for these repositories so I hope this can be resolved and fixed in a way which doesn't under all circumstances enforce a default branch even if there is no master
branch.