Open junderw opened 4 years ago
I don't follow steps 5-6 -- if you just cloned the repo but didn't actually switch to the origin/develop
branch on the new clone, wouldn't you expect the repo to be empty if there's nothing in master
? Or is there some other step missing there?
is it git protocol to pull master if no branch is specified during clone?
And if origin/master doesn't exist it just doesn't clone anything? (no .git folder even)
the keybase repo should have one branch origin/develop.
it does create the folder though... but no .git folder until I push up devlop after renaming as master.
Here's some repro steps for bash
mkdir ws1 ws2
cd ws1
git clone https://github.com/junderw/testkeybasegitissue22929
cd testkeybasegitissue22929/
keybase git create testkeybasegitissue22929
MY_KB_USER=$(keybase whoami)
git remote add keybase keybase://private/$MY_KB_USER/testkeybasegitissue22929
git push keybase develop
cd ../../ws2
# errors
git clone keybase://private/$MY_KB_USER/testkeybasegitissue22929
cd testkeybasegitissue22929/
# "is not a git repository"
git checkout develop
# "is not a git repository"
git branch --all
# .git folder is there but not recognized
ls -a
Notice my github only has a develop branch. and it is default.
The workaround is to locally create a master branch off develop and push that to keybase... then the clone works fine.
Ah I see. Thanks for the full repro, that was useful!
Github has a special notion of "default" branch that is not really related to git itself. See the top answer to this question: https://stackoverflow.com/questions/51274430/change-from-master-to-a-new-default-branch-git
Basically, it looks like github is setting the .git/HEAD
file to point to your develop
branch, while Keybase (and git in general) always initializes it to master
. That only works because Github has a non-standard feature that lets you set it that way on the server. Keybase doesn't have that feature, so the "server" repository that you clone from (and that's stored in your private KBFS folder) always has it set to master.
If you'd like to clone a certain branch from the Keybase repo, you can use this command to set the branch:
git clone -b develop keybase://private/$MY_KB_USER/testkeybasegitissue22929
You can also muck around manually in your hidden .kbfs_git
subfolder if you want to set the HEAD branch of the server repo (this is what Github does under the covers), but I don't really recommend it. If you mess up, you risk breaking the repository.
Ok sounds good.
So a task I might suggest branching from this:
I had no idea about the fact that Github / Gitlab are not adhering to the spec of git... I'm sure many people just assume github is the spec :-D
Thoughts?
It's worth noting that in Git 2.28 (not just GitHub/Gitlab), a new configuration option, init.defaultBranch
has been introduced to replace the hard-coded term.
- The name of the primary branch in existing repositories, and the default name used for the first branch in newly created repositories, is made configurable, so that we can eventually wean ourselves off of the hardcoded 'master'.
https://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/2.28.0.txt. For background on this change, see https://sfconservancy.org/news/2020/jun/23/gitbranchname/
This seems like a good enough reason for Keybase to support non-master branches within the Keybase UI
Unfortunately, Keybase was bought by Zoom and suddenly commits became extremely sparse.
I doubt they will have the resources to fix any of these problems...
But that's the great thing about open source. Someone could do it for them.
Not sure if they'd have the resources to be able to merge and release it though...
https://git-scm.com/book/en/v2/Git-Internals-Git-References#ref_the_ref seems to indicate it's safe to modify this file, but the only way to do it on the remote is to edit it in .kbfs_git
A few things to point out ...
HEAD
file in a bare repo is used by git clone
to identify which branch to check out when a repo is first cloned from that bare repo and a branch was not specified. This is really the only place where the concept of a "primary" branch exists within the context of git itself - and the only reason master
ended up being the "default" was because the git init
command uses it as a default. Otherwise there's nothing special about the name master
at all.HEAD
file in the copy of the bare repo on their disk, so that future git clone
commands will default to that branch.HEAD
file) to be whatever branch that push is adding commits to. I just checked, when a repo is first created it doesn't even show the "Branches" page in the repo settings. (I don't know what happens if the initial commit is pushing multiple branches at the same time.)HEAD
file pointing to a branch named master
, whether such a branch exists or not.For a long time I was in the habit of creating new repos with a master
branch containing nothing but a README.md
file explaining the actual branch names used in the repo, and creating the primary branch off of that. Later I figured out how to create the actual primary branch as an "orphan", so the master
branch ended up not being part of the "real" commit history at all.
As @strib pointed out, you can use git clone -b xxx
to manually check out a specific branch after cloning the repo, or as I explained in this comment you can manually edit the HEAD
file in the "hidden" KBFS directory which acts as the "upstream" for the repo.
As for how to best "fix" the issue, my suggestions are ...
GOOD: Having a keybase git set-primary-branch
command would be useful, if for no other reason than it saves the risk of the user mucking about in the "hidden" directory. I also think it would be a fairly easy task, and if I had the time (and more experience with golang) I would try and write it myself.
BETTER: Give keybase git create
a -b
option to specify the initial branch. That value could be stored in the new empty directory, or maybe as a field in the directory's kbfs_config
file, and then used when handling the first push, while building out the rest of the bare repo's directory structure.
BEST: Update the push handler so that if the HEAD
file doesn't exist already (i.e. no commits have been pushed yet), it will detect which branch is being pushed into, and use that to initialize the repo's "primary" branch (i.e. write it to the HEAD
file).
Repro:
git push keybase develop
ls -a
and see the folder is emptyWork around:
checking out master and pushing master first, then pushing develop etc. allows the data to be uploaded to keybase. Then cloning works and you can checkout develop and it will link to the remote keybase develop.
Perhaps this is spec for git... not too sure. Please close if so.