tags:

views:

126

answers:

2

Ok, a few things I'm not quite sure about.

For starters:

  • I have a "bare" repo on a VPS in a remote DC.
  • I have a workstation at work that I also code on.
  • I have a workstation at home that I also code on.

1 - When I set up my initial repo on one of my workstation (i think Git calls this the master), should I check out and work from a different directory? Like subversion.

2 - When I want to work on the code at work, I'm confused, how do I go about making commits to the LOCAL repo on my work desktop and then at the end of the day, push my changes to the "bare" repo on my VPS so that I can pull the updates to my home desktop.

I tried using clone but every push I make from my home desktop ended up w/ me pushing the changes back to the remote repo.

A: 

In Git you can (and usually should) switch branches "in place". For example if you are on branch 'master', and want to start working on branch 'devel', you can simply use

$ git checkout devel

and your working area would reflect branch 'devel'. You need usually to be in a clean state, i.e. do not have uncomitted changes.


As to setup between "work", "home" and "bare" repositories:

First, a matter of configuration. I'll assume there that both on "work" and on "home" computer there is configured "bare" (or whatever you name your bare repository), with configuration that looks like the following (you can use "git remote add" to create it):

[remote "bare"]
    url = [email protected]:/path/to/repo.git
    fetch = +refs/heads/*:refs/remotes/bare/*
    push = refs/heads/*:refs/heads/*

There can be other remote configuration, for example about tags (e.g. fetch = +refs/tags/*:refs/tags/* etc.), but I am omitting it for simplicity.

Second, let's assume that you are working on branch 'master', and uou have the following configuration for such branch both in "work" and "home" repositories:

[branch "master"]
    remote = bare
    merge = refs/heads/master

You can of course have similar configurations for other branches.

Let's now examine some example sessions. You are either at "work" or at "home".

  1. First thing you should do before starting work is to get updates from the "bare" repository. I'm assuming here that you are on 'master' branch. You can do that using "git pull bare", or with above branch configuration simply "git pull":

    $ git pull bare
    Updating 8818df8..9ad6770
    Fast forward
     foo |    1 +
     1 files changed, 1 insertions(+), 0 deletions(-)
    

    "Fast-forward" means here that "bare" repository is in advance of the repository you are working in (and tat you don't have any changes that are not in "bare" repository). If you are working either from "work", or from "home", but not on those simultaneously, this should be the situation you get.

  2. Now do some work (this is an example session only):

    $ edit, edit, edit
    $ git commit -a
    $ git add somefile
    $ git commit -a
    $ git commit --amend
    

    Note that you better finish your work so that there are no uncomited changes, but it is not a strict requirement. If you leave some uncomitted changes, you can finish commit before "git pull", but then you wouldn't get fast-forward but a merge. Or you can use "git stash" to stash away your oncomitted changes, and then apply stash (unstash) them after pull.

  3. After finishing your work, you push your changes to the "bare" repository, so you would be able to access your work in other repository.

    $ git push bare
    Counting objects: 8, done.
    Compressing objects: 100% (3/3), done.
    Writing objects: 100% (6/6), 493 bytes, done.
    Total 6 (delta 0), reused 0 (delta 0)
    Unpacking objects: 100% (6/6), done.
    To [email protected]:/path/to/repo.git
       9ad6770..4230584  master -> master
    

I hope that such example would help.

Jakub Narębski
Since the OP seems to be pretty new to git, I'd suggest the simpler approach of `git-pull`, which combines `git-fetch` and `git-merge`. However, if you'd like the additional control of separating fetch and merge, after using `git-fetch`, you'll have to do something like `git merge bare/master`.
Jefromi
+3  A: 

1 - master is git's default name for the main branch of a repository. It does not refer to the entire repository, but to that one line of development. You don't need a separate working directory - the general idea of local git development is to work in the directory, commit changes to the repository, then push them upstream as necessary.

2 - You should have a remote in both your home and work repos pointed at the bare VPS repo. If you created your repo by cloning the VPS repo, it will be 'origin'. Pushing to and pulling from origin are the defaults, so this is why your pushes are going there. This is the designed behavior - there's a good chance that when you clone a repo, it's the one you want to get updates from and push your changes back to.

I would suggest having both home and work treat the VPS repo as origin. You can then push to and pull from it on each computer when necessary, simply using git push and git pull. If one of your repos isn't already set up this way, you could either reclone the VPS repo to do it automatically, or use

git remote add origin <url-of-VPS-repo>
git config branch.master.remote origin
git config branch.master.merge = refs/heads/master

The last two lines let git know that you would like your master branch to be associated with the master branch on the origin remote (your VPS).

Jefromi
Ok, maybe I'm confused with what you're saying. I dont want any changes on the VPS repo. I only want to be able to push changes to it so I can download them somewhere else (i.e. desktop crashes so I have to grab the code again). Isn't that the point of a "bare" repo? I guess the way I'm describing it is the way developers have been doing so w/ subversion. My issue is, my net connection from work to anything remote is freaking slow. I want to continue to make commits locally as I work but before I leave, push the changes to the remote and pull when I'm home so I can continue my development.
luckytaxi
1. You say you want to push changes to the VPS repo, but not have any changes on it? To answer what I think you're asking, a bare repo has no working directory, no checked-out copy of the files, just the stored objects. I have described exactly how to push to it and pull from it.
Jefromi
2. Working with git is *always* local. You'll make your commits at work or at home, then push them to the remote, and pull them from the other location. You can push and pull as (in)frequently as you want - e.g. once at the beginning and end of the day.
Jefromi
sorry, for some reason, the whole "bare" thing confused me. Yea, I realized how silly i sounded by saying I didnt want to make changes to the repo. Sorry for that! :-PNow back to my local commits. What do I need to do so that my commits at home are going to my local repo unless I tell it to push to the remote VPS repo?
luckytaxi
That's what I was trying to say. When you commit, it goes into the repo you're currently working in. There is no other way to do that. Similarly, there's no way to get them into the remote repo except by pushing. (Since it's bare, you couldn't even ssh there and pull/apply patches)
Jefromi
I can't think off the top of my head of a good git document explaining this really basic philosophy, but what you should keep in mind is that it's absolutely designed to be distributed, let you work offline, etc. Commands always operate on the current [local] repository, unless their very nature requires a remote repository (push, pull, fetch, ls-remote, remote update).
Jefromi
I thought git's commit are a two step process? You commit to your local repo and if needed, you can push them to a centralize repo if you wanted to.
luckytaxi
Oooooh ... I'm an idiot, the push, pull, fetch will always happen from a remote repo. See, I thought I could "clone" the VPS repo onto my desktop. Then have individual "repos" on both my work and home desktop.
luckytaxi
You can (and did!) clone it. And yes, you then have repos in all three locations. All three contain all the history, and two of them have working directories with the tracked data checked out.
Jefromi
ugh, i got it now. "commit" is what makes the changes go into the local repo. the "push" "pull" is what updates one's repo w/ others, in my case the VPS repo so I can grab this from a different computer.
luckytaxi