Saturday, 28 December 2013

Git GitHub Cheat Sheet

Some of the most frequent git commands I use, but also forget between the times I need them.

Setup a repository

git clone <repository>
Clone the specified repo to current location. Think CVS checkout.
To clone a GitHub repository, copy the link to the repo on the GitHub site.
git clone https://github.com/johannoren/WeatherStation.git

If you instead start by creating your project locally you initialize git by
mkdir MyProject
cd MyProject
git init

To add a file
touch foo
git add foo
git commit -m "First commit"

To connect your local repository to GitHub (or other remote repository) assuming we have created a MyProject project on GitHub we create a remote named origin.
git remote add origin https://github.com/johannoren/MyProject.git

To push our local commited file to the remote origin on the main branch master
git push origin master

To clone a repository on one of your other machines, do this over ssh
git clone ssh://johan@192.168.1.6:/home/johan/gitrepos/MyRepo.git

Git configuration

git config -e
Open the Git config file in the default editor

git config --global user.name 'Johan Noren'
git config --global user.email abc@gmail.com
Edit the author and email when making commits

git config --list
List all Git configuration options

If you add --global after these config commands, they will be applied to all repositories and not only the current repo.

Diffs, shows, blames, history and info

git diff
What has changed since your last commit? To diff only a file use
git diff -- <filename>

git status
List added files to the staging area, changed files and untracked files.

git log
Show the most recent commits. Comes with a collection of options:
--color           Color coded
--graph           Commit graph added to the left
--decorate   Add branch and tag names to commits
--stat             Show files changed, inserted, deleted
-p                       Show all diffs
--author="Johan Noren"  Commits by a certain author
--after="MMM DD YYYY" ex. ("Jun 20 2008") Filter commits by date
--before="MMM DD YYYY"
--merge        Filter out commits occuring in the current merge conflict.

git show <revision>
Show the diff of a commit specified by <revision>. Revision can be any SHA1 commit ID, branch name, or tag.

git blame <filename>
Show the author of each line in a file.

git ls-files
List all files version controlled

Add and delete files

git add <file> <file> ...
Add files to the git project

git add <directory>
Add all files in direcotry including all subdirectories

git add .
Add all created/modified files in current directory (not deleted)

git add -u  
Add to index only files deleted/modified and not those created

git add -A  
Do both operation at once, add to index all files

git add -p
Patch mode allows you to stage parts of a changed file, instead of the entire file. This allows you to make concise, well-crafted commits that make for an easier to read history.

git rm <file> <file>
Remove the files from the git project.

git rm $(git ls-files --deleted)
Remove all deleted files from the git project

Stage and commit

git add <file1> <file2> ...
git stage <file1> <file2> ...
Add changes in <file1>, <file2> ... to the staging area which will be included in the next commit

git add -p
git stage --patch
Walk through the current changes (hunks) and decide for each change which to add to the staging area.

git reset HEAD <file1> <file2> ...
Remove files from the next commit

git commit <file1> <file2> ... [-m <message>]
Commit <file1>, <file2> ... optionally using commit message <msg>

git commit -a
Commit all files changed since your last commit not including new (untracked) files.

Branches and merging

git branch
List all local branches

git branch -r
List all remote branches

git branch <branchname>
Create a new branch named <branchname>, referencing the same point in history as the current branch.

git branch <branch> <start-point>
Create a new branch named <branch>, referencing <start-point>, which may be specified using a branch name or a tag name and more.

git push <repo> <start-point>:refs/heads/<branch>
Create a new remote branch named <branch>, referencing <start-point> on the remote. Repo is the name of the remote.
Examples:
git push origin origin:refs/heads/branch-1
git push origin origin/branch-1:refs/heads/branch-2
git push origin branch-1 ## shortcut

git branch -d <branchname>
Delete branch <branchname>

git branch -r -d <remote-branch>
Delete a remote-tracking branch. Example
git branch -r -d branchname/master

git checkout <branchname>
Update the working directory to reflect the version referenced by <branchname> and make the current branch <branchname>

git checkout -b <branchname> <start-point>
Create a new branch <branchname> referencing <start-point>, and check it out.


git merge <branchname>
Merge branch <branchname> into the current branch.

Tags

git tag
List all available tags

There are two types of tags, lightweight and annotated. Less information is stored in lightweight tags so always use annotated '-a' if unsure.
git tag -a v1.0_20140102_2122 -m 'Tag information'

To push the tag to GitHub use
git push origin <tagname>
or if you have many tags or if you are lazy, push all tags
git push origin --tags

Handle remote repositories

git fetch <remote>
Update the remote-tracking branches for <remote> (defaults to "origin"). Does not initiate a merge into the current branch, see "git pull".

git pull
Fetch changes from the server, and merge them into the current branch.

git push
Update the server with the commits across all branches that are common between the local copy and the server. Local branches that were never pushed to the server are not shared.

git push origin <branch>
Update the server with your commits made to <branch> since your last push. This is always required for new branches that you wish to share. After the first explicit push, "git push" is sufficient.

git remote add <remote> <remote_url>
Add a remote repository to your git config.  Can then be fetched locally.
git remote add myworkteam git://github.com/somename/someproject.git
git fetch myworkteam

Revert local changes

Assuming you did not commit the file, or add it to the index, then:
git checkout filename

Assuming you added it to the index, but did not commit it, then:
git reset HEAD filename
git checkout filename

Assuming you did commit it, then:
git checkout origin/master filename

Assuming you want to blow away all commits from your branch (VERY DESTRUCTIVE):
git reset --hard origin/master

Friday, 20 December 2013

CouchDB on Linux Mint - Cheat sheet

Here's my cheat sheet for working with CouchDB on a Linux Mint server.

Installation

Installation is trivial
sudo apt-get install couchdb -y

Test to see that it works.
curl http://127.0.0.1:5984/

should return something like

{"couchdb":"Welcome","version":"1.2.0"}

Create a database named 'johantest'
curl -X PUT http://127.0.0.1:5984/johantest

Delete the same database
curl -X DELETE http://127.0.0.1:5984/johantest


Adding documents

Assume you didn't delete the database, add a document like this
curl -X POST http://127.0.0.1:5984/johantest \
-H 'Content-Type: application/json' \
-d '{"SomeProperty":"Test1","AnotherProperty":"Test2","Age":32,"PropList":["Prop1","Prop2","Prop3"]}'

To retrieve all documents in a database

curl -X GET http://127.0.0.1:5984/johantest/_all_docs

Gives
{"total_rows":1,"offset":0,"rows":[
{"id":"4571d772c7d61fa34a7579ce6f04d47b","key":"4571d772c7d61fa34a7579ce6f04d47b","value":{"rev":"1-a268e2541be30dae295fb88015bd1a5c"}}
]}

That will only give references so you can GET each document detail. To fetch the contents of an individual document, fetch using the key from the provious GET.
curl -X GET http://127.0.0.1:5984/johantest/4571d772c7d61fa34a7579ce6f04d47b

Gives
{"_id":"4571d772c7d61fa34a7579ce6f04d47b","_rev":"1-a268e2541be30dae295fb88015bd1a5c","SomeProperty":"Test1","AnotherProperty":"Test2","Age":32,"PropList":["Prop1","Prop2","Prop3"]}

 If you wish to fetch all documents in one large JSON blob
curl -X GET http://127.0.0.1:5984/johantest/_all_docs?include_docs=true 

Gives
{"total_rows":1,"offset":0,"rows":[
{"id":"4571d772c7d61fa34a7579ce6f04d47b","key":"4571d772c7d61fa34a7579ce6f04d47b","value":{"rev":"1-a268e2541be30dae295fb88015bd1a5c"},"doc":{"_id":"4571d772c7d61fa34a7579ce6f04d47b","_rev":"1-a268e2541be30dae295fb88015bd1a5c","SomeProperty":"Test1","AnotherProperty":"Test2","Age":32,"PropList":["Prop1","Prop2","Prop3"]}}
]}

Settings and logs

Settings are stored in /etc/couchdb/default.ini
To be able to connect to the databse via HTTP from other machines on network, change
bind_address = 0.0.0.0

The actual database is stored by default at
/var/lib/couchdb/1.2.0 and is named in this case johantest.couch

If you wish to move it to another partition or similar, change the settings
database_dir = /var/lib/couchdb/1.2.0
view_index_dir = /var/lib/couchdb/1.2.0

To get a feel of the amount of disk used by Couch I notice that my Weather Station application has stored 8800 JSON documents in a format like this

{"id":"6ea52d20ab226121a325d0e3c5ffe4b5","key":"6ea52d20ab226121a325d0e3c5ffe4b5","value":{"rev":"1-087372f223546fb03c75605decb4a442"},"doc":{"_id":"6ea52d20ab226121a325d0e3c5ffe4b5","_rev":"1-087372f223546fb03c75605decb4a442","temperature":23.75858110517378563,"rawDate":1385961273368,"key":"holmon"}}

That will occupy 28.9 MB of disk with the default settings of compression etcetera.

To see what requests has been made against the database, the log is placed at
 /var/log/couchdb/couch.log
which can be changed in the settings file as well. Output for the tests above

[Sat, 28 Dec 2013 09:08:41 GMT] [info] [<0.2082.8>] 127.0.0.1 - - PUT /johantest 201
[Sat, 28 Dec 2013 09:34:03 GMT] [info] [<0.28823.7>] 127.0.0.1 - - DELETE /johantest 200
[Sat, 28 Dec 2013 09:34:07 GMT] [info] [<0.25248.7>] 127.0.0.1 - - PUT /johantest 201
[Sat, 28 Dec 2013 09:34:13 GMT] [info] [<0.3856.8>] 127.0.0.1 - - POST /johantest 201
[Sat, 28 Dec 2013 09:34:22 GMT] [info] [<0.2437.8>] 127.0.0.1 - - GET /johantest/_all_docs?include_docs=true 200
[Sat, 28 Dec 2013 09:35:29 GMT] [info] [<0.2449.8>] 127.0.0.1 - - GET /johantest/_all_docs 200
[Sat, 28 Dec 2013 09:35:41 GMT] [info] [<0.2339.8>] 127.0.0.1 - - GET /johantest/4571d772c7d61fa34a7579ce6f04d47b 200


Thursday, 19 December 2013

Clone a GitHub project into Eclipse

I've been using the Git command line tools to setup my workspaces against GitHub and then importing projects into Eclipse going back and forth to the command line to diff, commit and push back to origin. In my current project I've discovered the Git Repository Explorer in Eclipse and how it makes many of the tasks much easier.

To clone an existing GitHub repository add the perspective Git Repository Explorer

Choose to clone a repository
Add details about the remote repository
The URI can be found on the GitHub page for the repository you wish to clone

Select the branch to check out and in the next view tick the "Import all existing projects after clone finishes"
Then you got your project in your workspace as expected


Now the usual Eclipse goodies har here for you, to diff local changes is much clearer than the command line diff utility for example

The synchronize option to see all changes in your local copy

Inspecting the history of the file is also presented in a more readable manner


Commit and push to origin (GitHub in this case) is a single operation if you wish