views:

37

answers:

2

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://[email protected]/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://[email protected]/path/to/repo
  Push  URL: ssh://[email protected]/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?

+4  A: 

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.

mipadi
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
A: 

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