Does “git push” make sense?

(written by lawrence krubner, however indented passages are often quotes). You can contact lawrence at:

I agree, especially for those of us coming from Subversion, there is a lot here that is counter-intuitive.

Let’s say you are a web developer, and you do development on your laptop, then when things are nice and shiny you want to push those changes to the webserver. Seems natural enough, right?

git clone server:/var/www/foo
# …
git pull

# edit stuff
git commit -a -m ‘i edited stuff’
Now, let’s say you’re a (possibly former) darcs/bzr/mercurial user and this time you’re using git. Git has git-push. You read the man page like a good little code monkey, and it seems like it does the same or similar thing to darcs push or hg push. It seems like if you want to push your changes to the server, you’d do this:

git push
Am I off in left field or does this not seem 100% rational? But wo be unto the code monkey that utters this unfortunate incantation. Observe:

$ mkdir foo
$ cd foo
$ git init
Initialized empty Git repository in /private/tmp/foo/.git/
$ echo hello > foo.txt
$ git add foo.txt
$ git commit -m ‘hello’
Created initial commit bee50da: hello
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 foo.txt
$ cd ..
$ git clone foo bar
Initialized empty Git repository in /private/tmp/bar/.git/
$ cd bar
$ echo goodbye >> foo.txt
$ git commit -a -m goodbye
Created commit 99c13c1: goodbye
1 files changed, 1 insertions(+), 0 deletions(-)
$ git push ../foo
Counting objects: 5, done.
Writing objects: 100% (3/3), 248 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
To ../foo
bee50da..99c13c1 master -> master
$ cd ../foo
$ git status
# On branch master
# Changes to be committed:
# (use “git reset HEAD …” to unstage)
# modified: foo.txt
$ git diff
$ git diff –cache
error: invalid option: –cache
$ git diff –cached
diff –git a/foo.txt b/foo.txt
index a32119c..ce01362 100644
— a/foo.txt
+++ b/foo.txt
@@ -1,2 +1 @@
$ git log
commit 99c13c1e60888ae2c0e221898411e1cd52ad3815
Author: Hans Fugal
Date: Mon Nov 10 17:11:57 2008 -0700


commit bee50da72798edc47ddc36dbc4f559f141b1e28b
Author: Hans Fugal
Date: Mon Nov 10 17:11:34 2008 -0700

I promise I didn’t fake that. Yes, you saw that correctly—git wants to undo the changes you just committed. If you happen to have a clean working directory, all you need to do to return to sanity is git reset HEAD. If not, heaven help you.

This is totally unacceptable. It’s unforgivable on so many levels. At the very least, the manpage should warn you to not push to repositories with working copies. Git should warn you before you push and screw up your repo that it has a working copy checked out. Ideally, git would behave like darcs and update the working copy. Suboptimally, it would behave like mercurial and make it a new revision that you have to manually checkout. But this is simply ridiculous.