Text

Over time, a remote will have branches added and deleted. Your local working snapshot can often get littered with stale, now removed branches.

To see what branches your local repo things exists you do something like this:

$ git branch -rv
  > origin/1620-upgrade  2e0cc56 Ignore active local.xml from vc
  > origin/HEAD          -> origin/master
  > origin/cas-sso       2351be5 Add gateway logiin and logout support
  > origin/giveaways   63daf5a Use cms blocks for banner placements
  > origin/master        496c975 Merge affiliate module
  > origin/newskin      d7220c9 Optimise skin and ui images
  > origin/release       496c975 Merge affiliate module
  

So this is my local Magento git repository, many of the branches here are now defunct and no longer in the remote (i.e. I had previously had used $ git push origin :branch from another host)

To refresh then I need to prune my branches list. The git incantation to do this is

$ git remote prune origin
  > Pruning origin
  > URL: [email protected]:git/store.git
  * [pruned] origin/1620-upgrade
  * [pruned] origin/giveaways
  * [pruned] origin/newskin
  

Looking at the remote branch list again:

$ git branch -rv
  > origin/HEAD    -> origin/master
  > origin/cas-sso 2351be5 Add gateway logiin and logout support
  > origin/master  496c975 Merge affiliate module
  > origin/release 496c975 Merge affiliate module
  
Tags: git scm
Text

A simple useful application for Git's stash feature came about today when I started making some amendments to a repo master branch, forgetting I wasn't on my develop branch. I didn't want to make the changes to the master branch and I didn't want to have to copy the files between the two branches manually.

Git stash to the rescue:

$ git stash save
  $ git checkout develop
  $ git stash apply
  $ git commit -m 'Apply stashed changes'
  
Tags: git scm
Text

If you have cloned a remote git repository you default into a checkout of the master branch. Odds are there will be other remote branches, and usually one called 'develop'.

To start developing on this branch instead of the master, use the following command

$ git checkout -b develop origin/develop
  > Branch develop set up to track remote branch develop from origin.
  > Switched to a new branch 'develop'
  

This command creates a local branch tracking the remote develop branch and switches your working directory to this branch.

If you already have a local develop branch and want it to track the remote you can use this instead

$ git checkout develop
  $ git branch --set-upstream develop origin/develop
  
Tags: git scm
Text

If you have an existing codebase and it's already in a git repository there's a number of ways to get it into github (or any other remote git repository). Many of these involve losing your branch history and creating a brand new repository.

This is where the git remote add command comes in handy.

$ git remote add origin [email protected]:ajbonner/foo.git
  

You can see the remotes associated with your branch:

$ git remote -v
  >> origin    [email protected]:ajbonner/foo.git (fetch)
  >> origin    [email protected]:ajbonner/foo.git (push)
  

To push the existing code to the remote:

$ git push origin master
  

You now have set up the remote and pushed your master branch into it. From here it gets tricky because subsequent git pull requests will give you an ugly error

$ git pull
  >> You asked me to pull without telling me which branch you
  want to merge with, and 'branch.master.merge' in
  your configuration file does not tell me, either. Please
  specify which branch you want to use on the command line and
  try again (e.g. 'git pull <repository> <refspec>').
  See git-pull(1) for details.
  
  If you often merge with the same branch, you may want to
  use something like the following in your configuration file:
  
  [branch "master"]
  remote = <nickname>
  merge = <remote-ref>
  
  [remote "<nickname>"]
  url = <url>
  fetch = <refspec>
  
  See git-config(1) for details.
  

There a few ways to get around this:

  1. Follow the directions given by git and edit your gitconfig
  2. Clone a fresh copy of the master branch from the remote
  3. When defining the remote add the --track option and give it the name of the master branch

    $ git remote add --track master origin [email protected]:ajbonner/foo.git

4 Refer to the remote branch using --set-upstream

$ git branch --set-upstream master origin/master
  

Personally I find option number 4 the best with the least amount of work.

You can also use:

$ git config --global branch.autosetupmerge true
  

To avoid having to do this.

Tags: git scm
Text

Create a new repository

$ git init <dirname>
  

Creates a new bare git repository in the current directory, or if a directory argument is given, in that directory.

Version control a file

$ git add file|dir <file|dir> ...
  

Adds, or to use git terminology ‘stages’ a file for a local commit.

Remove a version controlled file

$ git rm -rf --cached <file|dir>
  

This removes a file that has been previously staged (i.e added) for local commit. It does not remove the local file. If you omit the —cached option, the local file WILL be deleted. The rm command is roughly analagous to: $ svn del

Make a local commit

$ git commit <-a> -m 'Commit message' <file> ...
  

The -a flag will commit all pending files recursively in the current path, alternatively you can specify the exact files to commit at the end of the command separated by spaces.

See pending actions or status

$ git status <-u no|all|normal> <path> ...
  

Will show pending files and untracked files in the current working path. Optionally the -u (—untracked-files) option can be supplied to hide/show untracked files in the status report. Passing a path, or number of paths will run the status for that path rather than the current directory.

Create a bare centralised remote repository

$ git clone --bare pathtoinitialrepo <myrepo.git>
  

Alternatively if you don’t have an existing repo already:

$ git init --bare <path>
  

Often you’ll see the .git extension bandied about, particularly on github. This is a canonical reference to a bare git repository (i.e. only has the meta information and not a working copy) that is usually acts as a master or central repository.

Configuring a local repository to push to a remote

$ cd pathtoinitialrepo
  $ git remote add origin ssh://[email protected]/~/repos/myrepo.git
  $ git push origin master
  

If you initially clone from the remote repository you can skip the first step of setting up the origin. However if you have just created a new bare remote repository and want to setup an initial commit, you need to setup the origin first. Subsequent pushes to the remote repository can be done with git push origin master. This is the familiar model of subversion and svn commit.

Create a local copy of a remote git repository

$ git clone ssh://[email protected]/~/repos/myrepo.git
  

Create a local copy from remote repository created following the above approach.

Ignore changes to a tracked file

$ git update-index --assume-unchanged <file>
  

Use this command if you’ve added a file, e.g. a database defaults config file, but do not want further changes to be picked up for it.

To resume tracking changes to the file use:

$ git update-index --no-assume-unchanged <file>