Much ado about scripting, Linux & Eclipse: card subject to change


Using Git like CVS

Tonight I moved the sources from phpeclipse and CVS to PDT and Git.

Below are some gotchas and tips for initial repo creation, how to keep the central remote copy up to date, and how to work around complaints about updating master directly from remote. I'm sure there's a better way to do this w/o the need for the workaround, but this is what I found worked.

Initial setup

To crawl a directory and create a git project for each subfolder:

for d in $(find . -maxdepth 1 -type d -not -name "." | \
  egrep -v ".ssh|logs|OLD|download|upload"); do cd $d; \
    git init; git add .; git commit -m "initial commit" .; \
  cd ..; \

See also Setting up a shared repository.

Create local clone via commandline

git clone ssh://servername/path/to/.git folderToCreateLocally

Create local clone w/ eGit

Once your repo is created, you can clone a copy from the remote server onto your local box, and import it into Eclipse (with eGit installed) using File > Import > Git > Projects from Git > Clone... .

Commit local changes via commandline

As outlined before, you can git pull, git checkout, git commit, and finally git push your changes.

If you encounter an error trying to commit changes back to the repo, see the section below, "Allow a ref update to the currently checked out branch of a non-bare repository".

Commit local changes w/ eGit

With eGit, you can pull, push, checkout, commit, merge, etc. using the context menu on a Git project or with the Synchronize view. I don't recommend using any of the change sets / models except the Git Change Set, since the others will tend to show more than is actually needed (like local changes which Git doesn't track).

Allow a ref update to the currently checked out branch of a non-bare repository

Update the ~/.gitconfig file on the remote server to look something like this:
    name = Your Name
    email = your@email.address
    branch = auto
    diff = auto
    interactive = auto
    status = auto
    editor = vim
    tool = vimdiff
    denyCurrentBranch = warn

Retrieve changes into remote repo

Because I'm using the remote server to both host http-accessible files AND host the git repo, it's important that changes checked into the git repo be then checked out into the local filesystem so that the local workspace is in synch with the repo's metadata.

To pull changes, I use git status (to review changes), git reset HEAD <filename> (to reset specified file, or omit filename to reset all changes) and finally git checkout to retrieve the changed file from the repo into the working directory.

Access the server w/o a password prompt

To skip being prompted for a password when you connect over ssh, scp, or fish, add your public SSH key to the ~/.ssh/authorized_keys file on the remote server.

Access the server via an alias

Instead of having to reference the server as username@server when connecting, you can add an entry to your ~/.ssh/config file that looks like this:

Host shortName
User yourUsername
Port 22


AlBlue said...

It's usually bad practice to have a server repository have a working directory as well - after all, you don't do a cvs checkout into the CVSRoot on a server. Apart from antthing else it makes it slightly more difficult to figure out what is where.

Instead, you can create a separate location on the server (and the convention is to use git init --bare in a dir called myproject.git) and then push/pull that from different locations. So I'd amend the instructions to set up a similar set of git repositories in a different location, do the git add remote, and then do a git push instead.

Generally pushing directly into another repositories .git dir isn't done though if it has a working copy, hence the central bare one.

Lastly the instructions for the gitconfig have a number of items which aren't relevant for some - it'd be worth mentioning that these aren't necessary but explain what they do (eg vimdiff)

Denis Roy said...

Great tip about ~/.ssh/config -- thanks!

Davi K. Vidal said...

Why are you creating a git repository for each folder you have?

Any special need?


nickb said...

@Davi because the CVS history is too big to generate a .git repo without running into OutOfMemory errors and having the process die.

In dealing with SVN, I've found a better workaround using a tip from stackoverflow. Will post new blog about this later.