The repository exists, but all my commits have disappeared.
What exactly do you mean?
Is the working tree still there?
Does .git/
exist?
Are there any files in it?
The messages you posted suggest that the file .git/HEAD
does not exist.
It defines the expected state of the working tree (what you had checked out).
If that file is gone, git doesn't know where you were.
You could try creating the file yourself, with this content:
ref: refs/heads/master
If you were on a different branch, just replace "master" with the branch name.
If you were not on a branch, it would be more complicated.
.git/logs/HEAD
records past states of HEAD, with later lines at the bottom.
This example line shows a checkout:
25f2a6099fb5f9f2192a510c42f704f9fc4bcecb 65abb1a3dc102e2498860f01fb179cda4c51decb Rainer Blome <rainer.blome@wherever.you.are.com> 1346938344 +0200 checkout: moving from master to MySuperBranch
The SHA1s in front refer to commits.
You ought to be able to find these in the branch log,
for example .git/logs/refs/heads/master
.
The git reflog output you gave looks like refs/heads/master
is missing as well.
Its sole content is supposed to be the SHA1 of the latest commit on it (and a newline).
You can find the latest SHA1 at the end of the branch log,
for example .git/logs/refs/heads/master
.
You can set up an alias that uses git fetch
with refspecs to fast-forward merge your branches with just one command. Set this up as an alias in your user .gitconfig
file:
[alias]
sync = "!sh -c 'git checkout --quiet --detach HEAD && \
git fetch origin master:master develop:develop ; \
git checkout --quiet -'"
Usage: git sync
.
Here is why it works:
git checkout --quiet HEAD
directly checks out your current commit, putting you into detached head state. This way, if you're on master
or develop
, you detach your working copy from those branch pointers, allowing them to be moved (Git won't allow you to move the branch references while your working copy has them checked out).
git fetch origin master:master develop:develop
uses refspecs with fetch
to fast-forward the master
and develop
branches in your local repo. The syntax basically tells Git "here is a refspec of the form <source>:<destination>
, take <destination>
and fast-forward it to the same point as <source>
". So the sources in the alias are the branches from origin
, while the destinations are the local repo versions of those branches.
Finally, git checkout --quiet -
checks out the branch you were last on, regardless of whether or not there was a failure in the previous commands. So if you were on master
when you ran git sync
, and everything succeeds, you'll leave detached head state and check out the newly updated master
.
See also my answer to git: update a local branch without checking it out?.
Best Answer
In Git, a branch is just an ordered list of commits (a.k.a.: checkins). Something that can be a bit confusing for new users is that branches don't need to have a name (although in most circumstances you want one); and there is nothing particularly special about any particular branch (the
master
branch is just the default one that's created for you when you initialize a repository).You probably already know this, but Git is different than some other version control systems like the popular "Subversion", because every "working copy" (in Subversion language) is a repository of it's own... in fact, there is nothing particularly special about any particular copy; except that one copy has been generally agreed-upon as the "canonical" one that is used to store the final product.
So, back to your question... the "canonical" repository that you cloned when you started your local copy contained a "master" branch by default; and it's stuck around. Now, if you had access to the computer that contains the master repository you could log in and run:
However, if you aren't able to do that, you can still do it from your local machine. The
git branch
command has a-r
option which affects the remote repository. In other words, running the following command should work:Note that in both of those cases; I am assuming that
master
has been completely merged into the development history that your local copy is currently sitting at. If you have never usedmaster
before (i.e.: you've only ever checked in todevelopment
orproduction
), you have nothing to worry about. However, if you (or someone else) has been checking things in tomaster
, then you might have a problem. You can force a delete by changing the-d
to-D
in the above commands; but I highly recommend checking to see what's inmaster
beforehand! If you don't have access to the remote computer, you probably won't be able to recover it!By the way; if you (or anyone else) is new to Git, I highly recommend reading Git from the Bottom Up by John Wiegley. Even though I had used Git a little bit on my own before found this article, I didn't really understand how it worked until I read it. It is quite useful!