redrabbit / git.limo

A Git source code management tool powered by Elixir with easy installation & high extensibility.
https://git.limo
MIT License
497 stars 42 forks source link

Trying to fix a non-existent HEAD #87

Closed EdmondFrank closed 1 year ago

EdmondFrank commented 2 years ago

Because the default branch of some recently new repository is main now, but when you create a new repository and do the first push, the HEAD is still points to to refs/head/master.

So when you access the repository on the page that was just pushed with the default branch of main, it will trigger an error that the refs/heads/master was not found.

This PR tries to fix the problem by setting the first branch in the branch list to HEAD if the current HEAD does not exist.

redrabbit commented 2 years ago

Hi @EdmondFrank and thank for the help.

Can you further explain when/how this does happen?

As long as I know, the HEAD is not hardcoded anywhere in the code. If I remember correctly the repository HEAD symbolic reference is assigned on the first push (when the server receives the first PACK) and is specified by the client.

What we could do is let the repository owner/admin change the default branch (HEAD) in the repository settings (like GitHub and GitLab do).

EdmondFrank commented 2 years ago

Hi @EdmondFrank and thank for the help.

Can you further explain when/how this does happen?

As long as I know, the HEAD is not hardcoded anywhere in the code. If I remember correctly the repository HEAD symbolic reference is assigned on the first push (when the server receives the first PACK) and is specified by the client.

What we could do is let the repository owner/admin change the default branch (HEAD) in the repository settings (like GitHub and GitLab do).

Hi @redrabbit Thank you for your reply.

https://github.com/libgit2/libgit2/blob/a3841af5eecc6301e87f8302c7fdce6555e39247/include/git2/repository.h#L342

According to the source code of libgit2, the initial_head It is set during the initialization of the repository and does not change with the first push of the branch.

Although we can provide the user with a global setting for the default branch of the initialized repository, there are still two problems: one, the setting cannot directly affect the existing repository, it can only take effect when the repository is initialized, and two, this global default branch is not always the same as the branch the user pushed for the first time.

And when the branch pointed to by HEAD does not exist in the repository, we cannot access the repository through the front-end page and update default branch settings. image

redrabbit commented 1 year ago

Hey @EdmondFrank.

I've pushed a few changes for fixing the issue:

This allows for setting a custom default branch when creating/updating a repository.

one, the setting cannot directly affect the existing repository, it can only take effect when the repository is initialized,

GitGud.Repo.update/2 now takes care of this by updating the Git symbolic reference accordingly.

and two, this global default branch is not always the same as the branch the user pushed for the first time.

This is still true but now the user can customize the default branch when creating the repository or update it later on. GitHub seems to override the default branch on initial push. We could technically do that too but I'm ok with letting the repository owner change the default branch in the settings.

My preferred approach would be showing an alert in GitGud.Web.TreeBrowserLive for the repository admin/owner if the repository has been pushed already but HEAD is pointing to an invalid reference.

when the branch pointed to by HEAD does not exist in the repository, we cannot access the repository through the front-end page and update default branch settings.

I've fixed that (and a few other things). All views should be able to work even when @head is nil. Accessing a repository through GitGud.Web.TreeBrowserLive will render the "Quick Setup" if @head is nil.

redrabbit commented 1 year ago

I deployed the code to https://git.limo.

EdmondFrank commented 1 year ago

Hey @EdmondFrank.

I've pushed a few changes for fixing the issue:

  • GitGud.Repo has a new :default_branch field (default to "main").
  • Git.repository_init/3 takes a third initial_head argument for initializing a Git repo with a custom HEAD.

This allows for setting a custom default branch when creating/updating a repository.

one, the setting cannot directly affect the existing repository, it can only take effect when the repository is initialized,

GitGud.Repo.update/2 now takes care of this by updating the Git symbolic reference accordingly.

and two, this global default branch is not always the same as the branch the user pushed for the first time.

This is still true but now the user can customize the default branch when creating the repository or update it later on. GitHub seems to override the default branch on initial push. We could technically do that too but I'm ok with letting the repository owner change the default branch in the settings.

My preferred approach would be showing an alert in GitGud.Web.TreeBrowserLive for the repository admin/owner if the repository has been pushed already but HEAD is pointing to an invalid reference.

when the branch pointed to by HEAD does not exist in the repository, we cannot access the repository through the front-end page and update default branch settings.

I've fixed that (and a few other things). All views should be able to work even when @head is nil. Accessing a repository through GitGud.Web.TreeBrowserLive will render the "Quick Setup" if @head is nil.

Thanks @redrabbit . This solution does seem to make more reasonable. If you still want to keep the geef_repository_set_head related code in this PR, please let me know and I will create a new PR with the related code individually , otherwise, I will just turn off the PR, thanks again for your reply and contribution.

redrabbit commented 1 year ago

If you still want to keep the geef_repository_set_head related code in this PR, please let me know...

I think we're good, GitRekt.Git.reference_create/5 can be used to do the same thing:

https://github.com/redrabbit/git.limo/blob/b8b94d6018f518abea50098da27c2859a7f2e7f2/apps/gitgud/lib/gitgud/schemas/repo.ex#L316-L322

redrabbit commented 1 year ago

Closing this PR. Support for custom default branch has been added to master branch.