Home > other >  Git: confused - accidentally pushed main (inexistant) instead of master
Git: confused - accidentally pushed main (inexistant) instead of master

Time:10-04

This question is hard to ask because I'm quite confused and don't really understand what happened. What's more, I still have problems understanding git, I don't work in any team and I only use it to save changes I made locally, always on one branch.

When pushing a commit, I accidentally typed "origin main" instead of "origin master". I didn't have a branch named main.

I got an error: src refspec main does not match any error: failed to push some refs to '(...)' and my working directory was cleaned.

After this, I did a soft reset of this commit, but working directory is still clean. I'm not sure what to do now, and - honestly - I don't understand where am I now.

What should I do in order to undo this 'typo' action and see my changes as uncommitted?

CodePudding user response:

I don't understand where am I now

Because you did a git push origin/main, your changes are now live on the server (origin), on the main branch. There is also still a master branch on origin; it is just behind main.

What should I do in order to undo this 'typo' action and see my changes as uncommitted?

Assuming all you have done is a git push, your changes are also still stored as a local copy. Because you're not using pull requests, I'd wager that you're the only devloper working on this repository, and also that you have no need to run pulls from the origin. As such, the differences between your local branch and origin/master should be exactly the same as those that you just pushed to the wrong branch.

I did a soft reset of this commit, but working directory is still clean

That is because your working directory is up-to-date with origin/main.

To ensure origin/master gets updated with your lastest changes, you can simply do a git push origin/master. After this, you can safely delete the main branch on the origin.

CodePudding user response:

When pushing a commit, I accidentally typed "origin main" instead of "origin master". I didn't have a branch named main.

That's OK:

I got an

error: src refspec main does not match any
error: failed to push some refs to '(...)'

That's perfectly normal. Nothing happens at this point.

and my working directory was cleaned.

That's not normal (well, depending on what you mean by "cleaned"), and you must have done something else. As you say though you aren't quite sure what you did.

After this, I did a soft reset of this commit, but working directory is still clean. I'm not sure what to do now, and - honestly - I don't understand where am I now.

If you mean you ran:

git reset --soft

that probably did nothing. Exactly what it did would depend on what state you were in before that point, which of course we can't see. The git push origin main, which did nothing at all, didn't affect that state.

If you committed all your files then they are currently in Git and you can get them back, regardless of what else you do, provided you keep the repository itself around.

When you say that your working directory is "cleaned", if you mean that git status says nothing to commit, working directory clean, that also is perfectly normal.

Your working directory contains files (and folders / directories, which your OS insists on creating to hold those files) in which you can see and work with your files. These files are not in Git, in any useful sense. They're just there in your working tree.

What is in Git is a big database of commits, along with other supporting objects. Each commit has a number—a big ugly random-looking thing, expressed in hexadecimal—that is unique to that one particular commit. That number is how Git ultimately finds the commit.

Running git log will show you commits, starting with the current commit. One of the commits in your repository is always1 the current commit: that's the commit you have checked out. When you check out some commit, Git extracts the committed versions of those files, and stick copies into your working tree so that you can see and work with them.

Using git checkout and the unique commit number, you can select any commit to extract. Git will remove, from your working tree, the copies it extracted earlier, from whatever commit is current right now, and switch to copies extracted from the commit you choose. That commit becomes the current commit. So each commit saves all the files, as of the state they had at the time of the commit, for all time, so that you can get back the old versions, then switch back to the newer versions.

But those big ugly numbers, deadbeef and badc0ffee and dadcafe and f031905de2 or whatever, most of them are unpronounceable—unlike the clever ones I make up here like cabbabe—and impossible for humans to work with. So we use branch names and other names. Git arranges for these names to pick out one particular commit. That's where names like master or main come in.

The GitHub hosting site will, when you create a new Git repository, normally stick in it one initial commit. The full reason for the one initial commit is explained in footnote 1 below, but it allows branch names to exist. They now call this initial branch by the name main.

The Git software you're using, when you create a new Git repository, makes it totally empty. It says you're on an "unborn branch", or no commits yet, or something along these lines—the exact message depends on your Git version (and also any language translations you're using). When you create your first commit, that's when Git creates a branch name, and at that point, current Git software creates a branch named master, instead of one named main.

If you like, you can now rename your master to main, using:

git branch -m master main

The -m flag here stands for move, which is a funny way to spell rename.2

Once you've renamed master to main, your usage will match GitHub's usage, and you can try git push origin main. Note, however, that if you let GitHub create a first commit, and you made your own first commit, you now have two different first commits. Git can't have two first commits under one name, so you must now choose how to deal with that.

If you told GitHub to create your repository there as a totally empty repository, with no commits, you'll be OK here: git push origin main will push your renamed-to-main commits, which will create main over on GitHub, and all will be fine.


1There's one exception to this rule, which Git calls by several different names: an orphan branch or an unborn branch. In this state, there's no current commit.

This state has to be able to exist, because when you create a totally-new, totally-empty Git repository, it has no commits. There is therefore no existing commit to act as the current commit. So Git needs a "no current commit" state. In the distant past, making a new, totally-empty repository was the only way to get this. Then someone thought: gosh, at least for testing if nothing else, we ought to be able to re-create that state and they invented the --orphan flag and called this an orphan branch. But that was a bad name so they changed it to unborn branch, without changing the flag, and now we have this confusion.

In this weird state, in a new totally empty repository, no branch names are allowed to exist. So that's also pretty confusing. When you're in this state—this unborn or or orphan branch state—where there's no commit yet, the first commit you make becomes the current commit, creating the branch. This allows the branch name to spring into existence. So what Git does is record the name that you're on without creating the name. Then you make the commit, and Git creates the name, making it select the new commit you just made, resolving the problem.

GitHub will sidestep the problem entirely by creating the initial commit for you, which allows them to create the branch name too. This solves the whole orphan/unborn branch thing. When everyone agreed on the name of the first branch—master—this all worked pretty well, but now that GitHub use main and others use master, it creates its own problem.

2The use of move to mean rename comes from the Linux mv command, to "move a file". This name in turn comes from Unix, so this is a historical thing.

  •  Tags:  
  • git
  • Related