1

After thinking that I finally figured git out, I'm now finding myself super-confused about a git behavior I'm seeing -- whenever I push changes made and committed to my local machine up to my origin git repository, those changes immediately get staged to be undone on the origin server. Huh??!?

I have a machine (machine A) with a git repository on it for a project; that machine is running an SSH server, and I configured an account so I can connect to it remotely and clone the git repo. I then used git on machine B to clone the repo:

git clone ssh://username@remote.host/path/to/repo

without problem. I made changes to the project on machine B, and committed those changes to the git repository on B. Then, I pushed the changes back to the origin repository on machine A:

git push master origin

and that worked fine; on machine B, the output of git remote show origin shows that the origin is up to date:

$ git remote show origin
* remote origin
  Fetch URL: ssh://username@remote.host/path/to/repo
  Push  URL: ssh://username@remote.host/path/to/repo
  HEAD branch: master
  Remote branch:
    master tracked
  Local ref configured for 'git push':
    master pushes to master (up to date)

But when I go to machine A and do a git status, I see that all the changes I just pushed are now staged to be undone!

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   build-fatjar.xml
#       deleted:    src/monitor/config/client-lm-prod.xml
#       modified:   src/monitor/config/quartz-baseconfig.xml
#       modified:   src/monitor/service/task/BaseTask.java
#       new file:   src/monitor/service/task/CheckForCorrections.java
#       deleted:    src/monitor/service/task/CheckForDuplicates.java
#       deleted:    src/monitor/service/task/ProcessCorrections.java
#       renamed:    src/monitor/test/CheckForDuplicatesTest.java -> src/monitor/test/CheckForCorrectionsTest.java
#       deleted:    src/monitor/test/ProcessCorrectionsTest.java
#       modified:   src/monitor/test/TaskTestCase.java

The only way to get the origin repository (machine A) to the same state as the one on machine B is to git reset HEAD to reset all those changes-to-be-committed and then git rm each of them; otherwise, the next git commit on machine A will undo everything I just pushed from machine B.

I've read every reference I can get my hands on and none mention this behavior; likewise, I can't find reference to it online either. Any ideas?

tshepang
  • 12,111
  • 21
  • 91
  • 136
delfuego
  • 14,085
  • 4
  • 39
  • 39
  • 1
    Well, it's mentioned pretty often in several SO questions. See http://stackoverflow.com/questions/3523008/how-do-i-push-to-the-current-git-branch-on-remote-and-have-changes-reflected-immediately and http://toroid.org/ams/git-website-howto – MvanGeest Aug 19 '10 at 18:02

2 Answers2

5

Sounds like you're pushing to a non-bare repo (that is, a repo that has files checked out on-disk). Git will update the repo, but not the checked-out files, so it'll look like there are changes waiting to be staged. The fix is to do one of two things:

  1. Either push into a bare repo (origin) and then use a post-receive hook to check out the files (perhaps using git archive) to another place on the server, or
  2. Use a post-receive hook to run git checkout or somesuch to update the on-disk files.

You can read more in this Stack Overflow question or in this how-to article.

Community
  • 1
  • 1
mipadi
  • 398,885
  • 90
  • 523
  • 479
  • Fantastic -- yep, that's it. I set up a bare repo on machine A rather than a "regular" one, and now everything's swimmingly fab. – delfuego Aug 19 '10 at 18:51
0

yes @MvanGeest is right, you are pushing to a non-bare repo. If you intend to use a repo as a 'blessed repo', ie in the same way you would use a master repository in subversion, then you need to create a bare repo and push to it. if in the situation you have now, you have to ssh into a and pull from b.

Jed Schneider
  • 14,085
  • 4
  • 35
  • 46