Take the 2-minute tour ×

Here is the scenario. I have two machines, "desktop" and "laptop".

On desktop I do:

mkdir git_test
cd git_test
git init
dd if=/dev/urandom of=test.img bs=1k count=1000
git add test.img
git commit -m "Added first image"

Then on laptop I do:

git clone [USER]@desktop:/home/[USER]/git_test    
cd git_test
dd if=/dev/urandom of=test2.img bs=1k count=1000
git add test2.img
git commit -m "Added second image"

Then I want the git repo on my desktop to look like the git repo on my laptop. On the laptop, I issue the following: git push origin master

But then I get:

remote: error: the work tree to HEAD.
remote: error: 
remote: error: other way.
remote: error: 

How do I keep these two repos in sync?

The error messages seem to imply that git has the functionality that I desire, but for some reason it seems to be a more advanced workflow. I heard someone say once that you can't push to the branch you are currently on, can someone elaborate on that as a possible solution? I would have no problem with a solution of that nature, ie, I could work on a certain branch on my laptop, and a different branch on my desktop, and then just sync those up somehow so they are identical.

Please note the following!

  • I do not want to use a centralized repo, like github, for several reasons. The first is security. The second is simplicity. The third is that due to circumstances I won't go into here, I can't count on having an internet connection to some remote server, I just have my two machines connected via LAN. Finally, I want to learn how to do things the way I requested here, as to gain that specific piece of knowledge.

  • I also do not want to use a bare repo, as a bare repo has a bunch of cruft in the root dir. This is ugly and messy. The whole reason I moved to git from subversion is that git looked like a much cleaner, decentralized solution. Also, I have some somewhat non-technical people that will be operating in the root dir of the desktop, they will get quite confused by the cruft. The beauty of git is (I thought) that everything hides in .git folders. Edit: Apparently I wasn't clear enough with this point. Imagine I have a "Documents" folder with the following sub folders: mydata1 and mydata2. This isn't a contrived example, this is exactly the issue I am trying to deal with. mydata1 should contain "test.img" and that file only, but instead it now has:

    branches config description HEAD hooks info objects refs

I wanted to be able to just cd into mydata1 and start editing files, but instead I have to try and cd through branches, or whatever even just to get work done. And to have this sort of directory structure for every subfolder that was in "documents" is just unworkable. Please, please don't tell me to do things this way. Please just answer the question. Thanks.

These two points are the entire reason I am posting this question here. Please only reply if you have an answer to this question. :) Thanks!!

share|improve this question
the "cruft" I am referring to is the following: "branches config description HEAD hooks info objects refs" I just want /home/[User]/git_repo to only contain the files I am working with. Also: .git folders are hidden. –  cat pants Jan 17 '13 at 1:50
You can hide the repo. –  nobar Jan 17 '13 at 1:53

4 Answers 4

up vote 9 down vote accepted

One way of doing this is to pull, not push. After you've set up your two machines, on the first machine:

git remote add origin [USER]@laptop:/home/[USER]/git_test
git pull # Complains about untracked branch while adding the branch you want to track
git branch --set-upstream master origin/master
git pull

Now you can pull commits from either machine. If you wanted to push, I'm not sure how to go about that with a decentralized setup.

share|improve this answer
pull absolutely works for my workflow, as long as I don't have to deal with a bare repo or a centralized repo. Thank you for this clarification. I will test this workflow and report back. Thanks! –  cat pants Jan 17 '13 at 2:00
One possibility for not-quite-pushing if the machines are even slightly physically separated: create a bash alias for something like alias git_push="ssh remotemachine 'cd git_test; git pull'" –  cjc343 Jan 17 '13 at 2:06
This is definitely the way to go. Consider if the two repos belonged to you and someone else; you wouldn't want that other person dumping his stuff into your repository and he wouldn't want you dumping yours into his. Quite a different story to pull the new work in, perhaps in a different branch, than to have it pushed. –  David Culp Jan 17 '13 at 2:19
Ok, I have tried this, running these commands from machine "A". The second command, git branch --set-upstream master origin/master, fails with fatal: Not a valid object name: 'origin/master' –  cat pants Jan 17 '13 at 2:29
Ah, just run git pull before that. It will complain that you haven't specified a branch, but it will also add origin/master to your refs. –  cjc343 Jan 17 '13 at 2:44

I may be missing why you don't want to use a bare repo, and I believe the pull only solution should work fine, but I also believe the "cruft" can still be hidden in the way you desire when working with a bare repo.

On your desktop, if you:

mkdir git_test
git init --bare git_test

And then:

git clone bare_repo_directory new_location

You can push and pull normally to the bare repo (referencing it as origin by default) from the clone, and no one will have to deal with the extra content it contains; the clones will only have the .git directory.

To push you'll need to run:

git push origin master (assuming you're working out of master)

For your laptop:

git clone [USER]@desktop:path_to_bare

And work should be normal in the cloned copy. You'll push and pull from origin (which is the bare repo), but you shouldn't need to work in it directly.

share|improve this answer

The reason the push do not work is exactly what you mention. By default you can't push to a brach if that repository (the remote receiving the push) current workspace points to that same branch. So if your remote has master currently checked out, you will not be able to push to master.

Two quick solutions:

If you have already any commit in the repo, just checkout a hash directly, that will put you in a headless state, which means that you are not at any branch:

> git checkout <any-hash>
Note: checking out '<any-hash>'.

You are in 'detached HEAD' state...

Another way with a brand new repo, if you want to push to master, is just to change that initial branch to something else not named master:

> git symbolic-ref HEAD refs/heads/non-existent

This will put you in a similar state as with master in a new repository, in a branch with no commits on it. Just you will not be grabbing master and thus it will be allowed to receive pushes.

share|improve this answer

I recently had an issue where my server and desktop got out of sync. After searching around the web for a while I wasn't able to find an answer that dealt with my exact situation. So I called Rackspace support and they were able to provide me with what I think is a better answer than I was able to find online.

This particular thread was the closest to my issue so I thought I would share how I solved the problem on here in case anyone encounters the same issue in the future.

Here's what went wrong

I was trying to install the Sweet Tooth plugin for Magento and followed along with the usual steps we all go through to install Magento extensions. This means taking a bunch of files and putting them in my App, JS, and Skin directories.

In the app/design/adminhtml directory there is a "base" folder. If you know anything about Magento then you know they have a zillion warnings about messing with the base files. In short - don't do it.

I assumed that since my local repo didn't have the "base" directory I'd be a-okay putting it on my local machine. Unfortunately and much to my dismay, this meant that when I did my add it added a "base" directory with only the files for Sweet Tooth. When I then put this on the server it wiped-out my entire base directory and Boom! down went Magento.

Luckily I was able to get back to the previous server state by using the following life-saving command:

git reset --hard HEAD@{1}

This command takes you back to the previous commit and instantly everything was back to normal. Of course now my server and desktop were out of sync since my server was now one commit behind.

To add insult to injury I made a very stupid mistake and deleted the files for the extension from my computer and did another commit on my desktop so now the server and desktop were out of sync by two commits and git now has these files in its cache.

Here's how I solved it

Obviously this leaves you in a pretty annoying place because doing a git pull on my server will wipe-out my "base" directory every single time. Also since it's two commits ahead I can't just rollback one commit.

I called Rackspace who at this point are Gods in my mind and found two different ways to solve this depending on whether you want to do this from the server-side or the desktop-side.

As it turns-out you really can't do this from the server-side since the files are now no longer on the desktop. While they recommended doing a git commit -a and then doing a push from the server followed by a pull from the desktop this just won't work, the files aren't on the desktop any more.

So you have to fix it from the Desktop and you need to get those darn files out of the cache.

Fixing Sync Issue From The Desktop

To get the files out of the cache I issued the following command over, and over, and over again until the files that I had removed were also removed according to git.

git rm -r --cached /folder/directory for directories


git rm --cached /folder/file for files

Now that this was out of the cache I was able to do a commit and finally let git know these files were actually gone.

This was followed by a push to the master. Then all that was left to do was a pull from the server and viola, back in business!

** Conclusion and Lessons Learned **

The lessons learned here were some big ones and I'm writing this post for other programmers that have a similar issue as well as myself to remind me of what not to do ever again.

  1. If you don't have a folder in your local repo that is on the server, don't add it to your local repo with only a few files in it, this will zero-out the directory on the server.

  2. If you do accidentally screw things up, make sure to remove the files with git, don't delete them from your local filesystem

  3. git rest --hard HEAD@{1} can be your best friend sometimes

I hope this helps anyone else that is in a similar situation. I spent hours pouring through docs online but couldn't find anything with the complexities that I ran-into here so if I can help someone else save some time and get a few less grey hairs then my nightmare will have served some good for the world!

share|improve this answer

Your Answer


