How can I check the status of a remote Git repository?

git
18,361

Solution 1

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.)

Solution 2

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.
Share:
18,361

Related videos on Youtube

John
Author by

John

Updated on September 16, 2022

Comments

  • John
    John over 1 year

    I have a remote Git repository to which I can push/pull from a local repository via SSH.

    I can use the Git status command to check the untracked/unstaged files in the local repository. How do I do the same with the remote repository?

    Please note that I'm not looking at finding the differences between the local commit and the remote commit.

    • Viji
      Viji over 10 years
      Do you want to check, what changes others had checked in / added?
    • torek
      torek over 10 years
      If you can push to it, it should generally be a --bare repo, so there will never be any work done on it and git status over on the server should never have anything to report in the first place.
    • torek
      torek over 10 years
      On the server, look at the repo. If it consists of just the git directory, it's bare. (Technically it's bare if git config --get --bool core.bare says true. But it tends to be super-obvious: ls in a non-bare repo shows working files, ls in a bare repo shows what you see when you ls .git in a working tree.)