2

I'm currently trying to follow the small project based work-group mentioned in the Pro Git book : http://progit.org/book/ch5-2.html

So, here's my set-up:

[Live Website Folder] 
|             |
|             |
Developer1    Developer2

The way that I achieved that was I did the following:

  1. git init --shared=0777
  2. git clone /live/website developer1
  3. git clone /live/website developer2

I was able to successfully clone my project and I went into developer1 folder. Here I make changes to my file index.html. Once, I make these changes, I do:

git add index.html
git commit -m 'Modified index.html --developer1'
git push

Now when I go to my /live/website directory and do a git status, it correctly tells me that the file index.html is modified. When I do:

git add index.html
git commit -m 'Modified index.html by developer1' 

It successfully makes the commit, but when I try to vi index.html, the file that I see is the original/un-modified one. I don't see the changes made by developer1, within that file. Is this expected behavior?

3 Answers 3

2

What git status is telling you is that index.html is different to what is in the git index.

After you push, your /live/website repo contains the updated index.html in the index, but the old index.html in the working copy. You need to do git reset --hard HEAD followed by git checkout -f inside /live/website to reset the working copy to the same as the HEAD commit.

I'd suggest that you modify your setup slightly. Add a staging repository that is bare and push changes into that. Add a post-update hook that runs git pull staging master inside /live/website. This will ensure that the live website gets updated as soon as a commit is pushed in.

In glorious ascii art:

 /live/website
       |
       |
/path/to/staging (bare)
  |          |
  |          |
dev1        dev2

EDIT: Updated to correct command sequence for fixing the working copy.

8
  • Cameron, is there a particular reason your suggesting adding the bare repo inbetween?
    – g1t
    Commented Dec 9, 2010 at 2:42
  • It just makes things a bit easier. Without it you wind up with the weird situation you've just encountered: the working copy doesn't match the index in your live website. It's possible to fix without the staging repo (using git reset and git checkout) but that approach is a little riskier: git reset may throw data away which is generally A Bad Thing. Commented Dec 9, 2010 at 2:46
  • By the way, the hook should be in the staging repo. Commented Dec 9, 2010 at 2:50
  • So Cameron, I would be cloning /live/website into dev1 and dev2. However, I would push into /path/to/staging? Or would I clone /live/website to /path/to/staging and then clone /path/to/staging into dev1 and dev2?
    – g1t
    Commented Dec 9, 2010 at 3:04
  • 1) Set up staging with --bare. 2) Run git clone in each of dev1, dev2 and live (clone staging). 3) Set up the post-update hook in staging that does something like cd /live/website && git pull origin master. 4) Push from devN into staging. 5) Enjoy! Commented Dec 9, 2010 at 3:09
2

It looks like you are pushing into a non-bare repository. This is not recommended and can have unexpected effects to trap the unwary. Instead, you might want to create a new, bare repository to serve as the main repository.

mkdir /git/project.git
cd /git/project.git
git init --bare --shared
cd /live/website
git remote add origin /git/project.git
git push origin master

Then, developer1 and developer2 should clone from /git/project.git, and push there too. When you want to update your live website:

cd /live/website
git pull
5
  • Greg, you are correct. It is a non-bare repository. The reason being, I want to see the latest version of my working files in /live/website.
    – g1t
    Commented Dec 9, 2010 at 2:30
  • You can set up a hook in your bare repository to update the /live/website immediately if you like. Commented Dec 9, 2010 at 2:35
  • Could you mention why is it such a no-no to be using it as a non-bare repo. I mean, if someone who was not used to git, went into the folder. He'd be amazed as to how its working? I just want the option to have the working files there too, so that a user not familiar with git could see them as well. Additionally, would the hook, just be a git pull?
    – g1t
    Commented Dec 9, 2010 at 2:41
  • When pushing to a non-bare repository, Git does not change the files in the working tree (this is exactly the problem that you originally saw). All it does is store the commit object(s) inside its internal representation. Git does this because it doesn't want to lose any work that might be going on in the working tree (consider the case of somebody else editing a file at the same time). And yes, the hook would just be a git pull into /live/website. For the user unfamiliar with Git, they wouldn't even have to know that you've got a bare repository in the middle. Commented Dec 9, 2010 at 2:48
  • Thankgs Greg ... I understand thanks to Cameron the significance of the bare repo in the middle ..
    – g1t
    Commented Dec 9, 2010 at 5:44
0

When you push to another directory it does not update the checkout of that remote directory.

You would have to do (on live/website):

git reset --hard

to get the new updates from developers.

This happens because your tree is currently pointing to a previous commit tree. but when doing 'git status' it fetches the most recent changes from the branch you are on.

One way to get out of this is to set up a git-hook on post-receive

3
  • sorry i put the bad command from memory. here's the good one. From ryanflorence.com/deploying-websites-with-a-tiny-git-hook
    – pastjean
    Commented Dec 9, 2010 at 2:48
  • @g1t but has the other says this is not the prefered git workflow
    – pastjean
    Commented Dec 9, 2010 at 2:49
  • Thankt pastjean, I've followed the other way. But your link of hooks helped!
    – g1t
    Commented Dec 9, 2010 at 5:46

Not the answer you're looking for? Browse other questions tagged or ask your own question.