Posted on

Working With Git

Here are some basic cheat-sheet style hints for working with the git version control system.

Creating A Repository

These are the steps for starting a new repository with git.  The commands here assume you will be working with a group of people that all need access to the repository from your server.  You will need command line access to the Linux shell to do this.

In our example we assume our developers all belong to the user group “dev” on the Linux box and our storage of the git repositories is in the /devdir/gitrepos directory.

  1. Log in as a user who belongs to the dev group.
  2. Make your way over to /devdir/gitrepos.
  3. Create the directory for your project. Make sure it ends with .git, e.g. wego.git.
  4. Go inside the directory you just made.
  5. Enter git --bare init --shared=group
  6. Finally do a chmod a+x hooks/post-update.

That last step is required because without it you would always have to run git update-server-info in the remote repository after every push. Git comes with a hook that automatically handles that for when you are pushing over SSH or HTTP, or really anything except Git’s own protocol.

Also the part about ending the repo name with .git is not mandatory—simply convention. People tend to suffix that whenever the repository is “bare”, meaning it has no working copy associated with it.

Adding Content To Your Newly Created Repository

Now that you have new, and empty, git repository you are ready to begin work in your development directory.  Here we are assuming you are working on your development server.  This may not be, and often is not, the same server where you store your git repositories.

  1. Login to your development server.
  2. Go to the directory where you want to start working on your new wego project.
  3. Enter git init
  4. Enter git remote add origin ssh://yourname@yourdomain.com/devdir/gitrepos/wego.git/.
    • Obviously substitute your login and repository name above.
  5. Load up something to put in the repo…
    1. touch README
    2. git add README
    3. git commit README
  6. git push origin master

If you clone an existing repo Git will set remote to the http (e.g. http://yourhost.yourdomain.com/wego.git/) address, which you cannot push back to because the server won’t allow it for security reasons—otherwise any one in the world could update our repos. So do this right after you clone the repo:

  • git config remote.origin.url ssh://yourname@yourdomain.com/home/gitrepos/wego.git/

Then git push origin master will do the right thing.

For bonus points you can open the .git/config file inside your local repo (or create it) and add this:

[branch "master"]
[remote "origin"]
        url = ssh://yourname@yourdmain.com/devdir/gitrepos/wego.git/
        fetch = +refs/heads/*:refs/remotes/origin/*

This tells Git that your master branch should track the origin branch. So now you can just type git push and git pull to upload and download commits.

Cloning That Repository Somewhere Else

Now that you’ve got stuff in your git repository other people are going to want to use it.   They can copy (clone) the repository by logging into their development server and using the git clone command:

# git clone ssh://theirname@yourdomain.com/devdir/gitrepos/wego.git/ ./wego

This assumes that theirname@yourdomain.com is a user in your development group on the server where the original repository lives.

On A New Development Server?  Setup Your Environment

This is what you’ll want to do if you are working on your own development server.  It will save you some typing when you add stuff to the repository when working in a shared development environment.

  1. git config --global user.name your name
  2. git config --global user.email your email
  3. git config --global core.autocrlf true
  4. git config --global core.safecrlf warn

On A Shared Server? Setting Author Per Commit

# git commit --author='user <user@email.com>'

Ignore That File

You can tell Git to ignore various files in your directory structure by adding a file .gitignore into the parent directory.  Inside that file you can specify a file name, or a group of files via a wild-card match.   This gets checked against each file regardless of the directory to which it belongs, in essence it is a recursive match.

Ignore the .htaccess file and anything ending with .backup as an extension
 # vi .gitignore
 .htaccess
 *.backup

Show Me The Branches

Get a visual look at the branches from a command line / ASCII terminal.

# git log --graph --oneline --decorate --all

Rename A Git Branch

You named your branch “temp/this-will-never-work” then realized what you did in there actually DID work.  Here is how you rename it locally and back on the remote box.

 # git checkout $branch
 # git branch -m minor/nystore
 # git push origin HEAD

This will add a NEW branch on the remote box, the old branch will still remain, so you’ll need to do some cleanup:

Local cleanup of remote references:

 # git branch -r -d origin/branch-to-delete

For git version 1.6.6.1 or higher:

 # git push origin --delete branch-to-delete

For older git version, you should upgrade, but this trick may help:

 # git push origin :branch-to-delete

Oops, Didn’t Mean That, Redo

To redo a commit you just pushed…

Delete the remote branch (you don’t always want to do this, be careful here) using the method described above in “Renaming A Git Branch”.

Go back to the last group of edits before you made your commit:

  # git reset --soft HEAD^

The HEAD^ says “go back from where I am now (HEAD) by one level”.   The –soft tells git to “keep all my edits please”, as opposed to –hard, which throws away all of your work.

Cherry Picking

Cherry picking allows you to build a new branch based on select commits from other branches.  Here is an example:

# Add the files from this commit to your current branch, but don't commit them yet
# This just puts the updated files in your directory
#
git cherry-pick --no-commit e85cd343234521c392950a208d677843c92a0392
# Change the author on those new files & add them with a commit
#
git commit -a --author='Lance C <Lance-isnt-here@cybersprocket.com>'
# Go get another one...
#
git cherry-pick -n 15a5454403f4fd75f469d6410d6de06ab008027d
# Now commit the new stuff, using the commit message that was
# in the commit ID specified here
#
git commit -c 15a5454403f4fd75f469d6410d6de06ab008027d
# Go and delete the driver/cafepress branch on the origin repo
#
git push origin --delete driver/cafepress
# Rename our driver/temp-cafepress branch to driver/cafepress
#
git branch -m driver/temp-cafepress driver/cafepress
# Go push our stuff back to origin
#
git push origin HEAD

Tagging Your Work

Tags are useful for marking your commits with short phrases, release numbers, or other pieces of info that will help you identify important commits.  Here are some short tips on how to tag your work.

First, you’ll need a PGP key.   Login to your linux box and stay in your home directory.  Run this command:

gpg --gen-key

Look for the key ID in the first few lines of output.  It should look something like this:

gpg: /home/lcleveland/.gnupg/trustdb.gpg: trustdb created
gpg: key D7809C04 marked as ultimately trusted
public and secret key created and signed.

gpg: /home/lcleveland/.gnupg/trustdb.gpg: trustdb createdgpg: key D6808C94 marked as ultimately trustedpublic and secret key created and signed.

This 8-digit number is your signing key.  Now use that to set your git configuration for your user so that your tags can be automatically signed:

git config --global user.signingkey $KEY_ID

Now to tag commits:

git tag -s v1.0
git push --tags origin master