I am a new Git user, and I made a new project on GitLab and it by default had a README.md file and one branch called "main". Next, I wanted to upload the local repository to it. The repository went and sat in the "master" branch. I tried to push it to "main" branch but it was not possible.
I have 2 branched on Gitlab one called "main" with only the README.md file and one called "master" with the folder containing the python files that I have.
Why did it happen? Also, how come I cannot push to "main", why is that ? What can I do to only have one remote branch?
I have tried the answers for I cant push to the "main" default branch but it does not work. I get the error that I should use git pull, that I do but still cannot push to main. Also, I would like to know why this happens that when I try:
git branch -a
to see all the local and remote branches, I do not see then remote "main" branch.
Work around: I deleted the project and made a new one and manually uplaeded the files. Then on the terminal, I changed the default branch to main using:
git config --global init.defaultBranch main
and pushed and it worked. However, now when I want to see all the branches using
git branch -r
I see:
remotes/origin/HEAD -> origin/main
remotes/origin/main
this "origin/HEAD" looks like a branch but it doesn't appear as a branch on the GitLab.
CodePudding user response:
I am not an active GitLab user (Github instead) but I suggest you check the settings of your repository. Probably the default setting is that you cant push to the main branch. You should rather create a pull request that merges your master branch to the main branch.
Background info. All major git platforms are changing their default branch from "master" to "main". So "main" is used what master was before.
CodePudding user response:
To clean out the origin/master
, assuming you don't want it, simply run:
git fetch --prune origin
(or git remote origin prune
). You can also set fetch.prune
to true
.
As for origin/HEAD
: this is something Git calls a symbolic reference. Your Git software sets this up during your initial git clone from some other existing Git repository. You can have your Git software update it with git remote set-head --auto origin
, or you can have your Git software delete it with git remote set-head --delete origin
. However, origin/HEAD
itself is basically a useless thing, so there's no real point in worrying about it.
Longer
What's going on here is actually quite straightforward:
A Git repository consists mainly of a couple of databases. One holds commit objects and other Git objects, and the second holds names—branch names, tag names, and remote-tracking names among others.
A useful repository (the kind you make when you run
git clone
) has a bunch of other things in it, while a server-side repository is useless except for storing commits that someone sends to it withgit push
, and then delivering those commits to you (or other people) when yougit fetch
orgit clone
. Most hosting sites add a bunch of additional wrapper software to make the server-side repository more useful, such as adding things like Pull Requests (GitHub) or Merge Requests (GitLab), a separate "issues" database, and so on. These are all quite useful, but none of them are part of Git itself.The main purpose of a repository is to hold commits. You add your own commits to your own repository in the usual way ("check out" or
git switch
to some branch, do work,git add
, andgit commit
); this inserts a new commit into your repository's all-objects database. All commits get a unique (globally / universally unique) number, so every new commit you make gets a number that has never been used before, for any commit anywhere in the universe, and will never be used again. This means that number = that commit. Git somehow does this even though it's operating independently on your repository, without consulting any other Git software working on any other repository, and this is both deeply magic and also mathematically impossible (which means that someday Git will break, but that day is so far in the future—well, we hope it is—that nobody cares).These magical numbers are Git's hash IDs.
A Git repository finds commits, and keeps track of new commits you've made, using branch names (mostly—any name will do but branch names are the ones we use by convention). Each branch name stores exactly one hash ID: no more, no less. That might not seem like enough, but it is. We'll skip all the mechanism here but you do need to know it, to use Git effectively.
Git stores these names—branch names in this case—in its names database. This names database does not get copied by
git clone
. Thegit clone
operation copies only the objects database, so that right aftergit clone
, you have all the other repository's commits, but no branches—or more precisely, no branch names.
It's that last bit that is what is going on here. When you clone a repository, your Git software gets to see their repository's branch names. But their branch names are theirs, not yours. Your branch names are for you to use, to keep track of your commits. Were their branch names to override your branch names, you wouldn't be able to make and keep any new commits! So you don't use their branch names as is.
Instead, your Git—your software working with your repository—takes each of their branch names and changes those names into remote-tracking names, sticking origin/
in front (or, sticking in front the name of the remote, but origin
is the standard first name of the first remote, and most people never add a second one). So now instead of main
or master
or whatever branch name they have, you have origin/main
or origin/master
or whatever. This repeats for all of their branch names.
Later, you'll have your Git re-connect to their repository, using git fetch
(or git pull
but that starts by running git fetch
). Your Git software will once again be able to see all of their branch names, and all their latest commits. Your Git software can figure out which of their commits are new to you, obtain them from their Git software, and add those commits to your repository, to the all-objects (commits and supporting objects) database.
Then, to remember their latest commits, your Git creates or updates the remote-tracking names that go with their branch names. If they have a new branch feature
, you get a new origin/feature
.
Now, suppose they create a feature
and add some commits and you git fetch
and get those commits and an origin/feature
. Then they merge their new commits and delete their name feature
. They no longer have a branch named feature
. You run git fetch
now, and they list out all their branch names: main
, develop
, and test
perhaps. Your Git obtains any new commits as appropriate and creates or updates your origin/main
, origin/develop
, and origin/test
.
What happens to your origin/feature
? The answer is: nothing. Nothing happens to it. It just sits there being stale.
You can tell your Git software that, whenever it has their (origin
's) Git software list out all their branch names, your own software should delete any of these stale remote-tracking names that you have. You do this with the "prune" option. This option defaults to being off (false
).