Showing posts with label github. Show all posts
Showing posts with label github. Show all posts

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

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

Sunday, 19 August 2012

Learning Scala - Photo collage creator

I finally took the time this summer to read a book on Scala. I bought Programming in Scala by Martin Odersky, the father of the language, which I think was a good choice. Regardless whether I'll write a lot of Scala programs in the future I learnt some new general programming techniques and a well needed recap on  programming language fundamentals from school. After reading it and applied it on a couple of hobby projects I must say that I feel excited.

My first project to play around with the language is a photo collage creator where you supply the program a motive and a set of images to create a collage from. The algorithm tries to puzzle the images together to create a collage that best fits the motive.

The motive to create collage from.
The motive is divided in segments and the image catalogue is searched for best fitting images to puzzle together.

The final collage in low-res.
When printing the collage in high resolution, for example 16384 x 10922 pixels the effect becomes quite cool when you approach the collage from a distance to a near closeup.

Let me just show you an arbitrary Scala function in this program that demonstrates a few of the things that I like compared to my daily work horse Java.

  /**
   * Calculate the average brightness of a portion of an image.
   * 
   * @param img Image to analyse for average brightness.
   * @param startx Start x coordinate of image subset to analyze 
   * @param starty Start y coordinate of image subset to analyze
   * @param stopx Stop x coordinate of image subset to analyze
   * @param stopy Stop y coordinate of image subset to analyze
   * @return Average brightness of the subset of the image
   */
  def brightness(img: BufferedImage, startx: Int, starty: Int, stopx: Int, stopy: Int): Int = {

    @tailrec
    def estimateBrightness(x: Int, y: Int, maxx: Int, maxy: Int, aggr: Int): Int = {
      if (y == maxy)
        aggr
      else if (x == maxx)
        estimateBrightness(startx, y + 1, maxx, maxy, aggr)
      else
        estimateBrightness(x + 1, y, maxx, maxy, aggr + rgb2gray(img.getRGB(x, y)))
    }
   
    /*
     * Average the brightness of the number of evaluated pixels with 
     * the aggregate of their calculated values.
     */
    val aggregatedBrightness = estimateBrightness(startx, starty, stopx, stopy, 0)
    aggregatedBrightness / ((stopx - startx) * (stopy - starty))
  }



As you can see, Scala is statically typed, but the compiler tries to infer as much as possible. You can create a constant variable with the val keyword. But it will in this example figure out that the variable aggregatedBrightness must be of the type (or subclass) Int since it is evaluated via the function estimateBrightness(). You will save yourself a lot of boilerplate declarations.

But what about the function estimateBrightness? It is declared inside the scope of the function brightness(). In Scala a function is on par with any plain old objects and can be referenced via variables or passed as arguments to functions and also be declared inside functions as a consequence. Why wouldn't it always be so?

Everything has a value, even a for loop or an if clause will result in something that can be passed to a variable or statement. This makes for concise and beautiful code.

Scala is basically a functional language but with all the imperative concepts around to make it easy for imperative people like me to make the transition to a more functional style in the tempo that suits me. In this example I made my calculations in a functional style using recursion instead of using loop constructs. I tried to write the program without any for or while loops at all but my conclusion is that just because it is nice to make everything recursive and functional it must not inherently be readable and understandable. I'll stick to my imperative guns when I need them for some time more.

An interesting annotation is @tailrec on the local function declaration. It forces the compiler to verify that this recursive function will be tail-call optimized, meaning that you can be sure that this function will not create stack frames for each invocation in the recusive loop. If so you would be running out of stack after some 10 000 invocations depending on your JVM startup flags.

To be able to write efficient and understandable functional programs my impression is that the requirements of the programmer are heightened compared to programming in plain old Java/C/C++. A challenge I'm gladly willing to continue with.

Instead of me trying to convince you that Scala seems like a great contribution to the Java VM family I strongly recommend you to read the book. You'll definitively become a better C# or Java programmer as well afterwards.



If you want to play around with the Photo Collage creator program and generate som collages of your own clone the code from GitHub.

https://github.com/johannoren/PhotoCollage

I have used Eclipse with the Scala plugin which make the program run without any hazzle. To configure it without any code changes, create a directory photos in the module, and put one image in that directory as your motive and name if motive.jpg. Put all your images that will be part of the puzzle in a subdirectory called inputphotos. Run PhotoCollage and monitor the standard out until the program is finished. Run time depends mainly on the number of images in the directory inputphotos.