How can I check the status of a remote Git repository?
git fetch --dry-run --verbose
may show what you need.
Example:
# Before a remote update:
user@localhost:~/build/demo/myrepo$ git fetch --dry-run --verbose
From https://gitserver.local/git/myrepo
= [up to date] master -> origin/master
# After a remote update:
user@localhost:~/build/demo/myrepo$ git fetch --dry-run --verbose
POST git-upload-pack (328 bytes)
remote: Counting objects: 12, done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 8 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.
From https://gitserver.local/git/myrepo
83619a7..67ea28b master -> origin/master
Caveats:
- The exit code does not reflect your local repository being in sync with the remote repository; it only reflects on the action itself being successful or not.
- If your local repository contains newer changes than the remote repository, Git fetch still considers your local repository up to date. Maybe
git push --dry-run
helps for this case.
If you have a Git remote repository, to which you can git push
via SSH, it should generally1 be a --bare
repository (see the description of setting up a bare repository on a server in the on-line Git book). A bare repository doesn't have any place in which to do any work on it. This means git status
has nothing to report—in fact, if you have a bare repository and cd
to it, you get an error message: it needs a work directory in order to report anything.)
The technical definition of a bare repository is one in which git config --get --bool core.bare
prints true
. I have a non-bare repository in /tmp/t
to start, here:
$ cd /tmp/t; git config --get --bool core.bare
false
$ cd /tmp; git clone --bare t bare.t.git
Cloning into bare repository 'bare.t.git'...
done.
$ cd bare.t.git
$ git config --get --bool core.bare
true
But it's usually obvious from inspection: if your clone says that the origin is ssh://some.host/some/dir/repo
, and you can ssh some.host
and cd /some/dir/repo
and ls
, a "bare" clone looks much like the contents of the .git
directory on the non-bare clone:
$ cd /tmp/t; ls .git
COMMIT_EDITMSG ORIG_HEAD description index objects
FETCH_HEAD branches gitk.cache info packed-refs
HEAD config hooks logs refs
vs:
$ cd /tmp/bare.t.git; ls
HEAD config hooks objects refs
branches description info packed-refs
(The bare clone lacks a few of the files made doing ordinary Git work in the non-bare one, but they are clearly related.)
1It's possible to push to non-bare repositories—it's just a bad idea. If you look at your own non-bare clone's .git/config
(or use the more official interface, git config --get receive.denyCurrentBranch
), you will generally see something like this:
[receive]
denyCurrentBranch = warn
The value here may be any of refuse
, true
, warn
, false
, or ignore
. Most values set things up so that push
is only accepted if the push is to some branch other than the "current" branch.
The problem here is ... well, suppose you're logged in on the server to which other people push. And lo and behold, you cd /some/dir/repo
and there are all these work files.
It's quite tempting to git checkout zorg
, edit the number of taxi drivers, and git commit
the result. But what happens when someone else is editing the same branch elsewhere, and commits and then git push
-es in the middle of you doing something similar?
If he/she finishes his/her push before you start your commit
, you have kind of a mess. Normally, both of you do this on systems other than the server, and whoever pushes first "wins" and the other person gets a failed "non fast forward" push and knows to fetch-and-(merge-or-rebase) (git pull
or git pull --rebase
or whatever).
But you're already on the server, so you can't use the normal work flow. In fact, it's tough to keep the work tree up-to-date in the first place: you can do this with a hook, but if you have the hook git reset --hard
to update the work tree, it throws away any work anyone was doing.2
It's easier to just avoid the problem entirely: decree that there is no work tree, and that this is to be a --bare
clone. All the temptations and problems vanish.
2At one job, I inherited a setup that did just that (git reset --hard
in a post-receive hook, and also at six-hour intervals via cron
). It caused a lot of confusion at least once every few months. Unfortunately, the server and directory paths were hard-wired lots of places, making it hard to fix, too (and this particular issue was low priority). We just lived with it.
(As requested in comments, this is the two comments in "answer" form. I've expanded them a bit since there is more space here.)