Showing posts with label free software. Show all posts
Showing posts with label free software. Show all posts

30+ Exceptional GIMP Tutorials and Resources


GIMP is a freely distributed GNU Image Manipulation Program. Available for such tasks as photo retouching, image composition and image authoring. It’s always fun to experiment different techniques and learn how to work with various aspects of GIMP to spice up boring pictures and make them into works of arts and masterpieces.
So, if you’re interested in learning some new skills, whether you’re a beginner, intermediate or advanced user, these GIMP tutorials are for you.
Below you will find an incredible amount some of the best GIMP tutorials hand picked to enhance or highlight whatever action is going on in the photo.

1. Different Gimp Tutorials

1. Neon Lights Tutorial

Gimp-tut1 in 30+ Exceptional GIMP Tutorials and Resources
This tutorial illustrates how to implement a nice animated menu using Mootoolsand some lines of CSS and HTML code ready to reuse in your project. Tip: to get more of a glow, you can duplicate some of the blurred line layers.

2. Recoloring Eyes

Gimp-tut2 in 30+ Exceptional GIMP Tutorials and Resources
This tutorial will teach you a quick and simple way to recolor eyes. You can color anything using this tutorial.

3. Lineart Tutorial

Gimp-tut6 in 30+ Exceptional GIMP Tutorials and Resources
This is specially for anime/cartoon style lineart.

4. Easy Sig

Gimp-tut7 in 30+ Exceptional GIMP Tutorials and Resources
A fairly easy tutorial to follow to make a sig. You must know the bare basics of GIMP and brushes/filters is all.

5. A colored swirl of light

Gimp-tut9 in 30+ Exceptional GIMP Tutorials and Resources
Here is a great effect, usable for all kind of graphics such as flyers, splash-screens, wallpapers etc. Here you will learn how to create a colored light swirl.

6. Create a nice oilpainting from a photo

Gimp-tut10 in 30+ Exceptional GIMP Tutorials and Resources
Learn how to create a fantastic looking oilpainting from a photo.

7. Making a pencil drawing from a photo

Gimp-tut11 in 30+ Exceptional GIMP Tutorials and Resources
In this tutorial you will learn how to convert almost any image into a good-looking pencil drawing, and yon even won’t need edge detection filters. All you need are a few different layer modes.

8. Gimp Sin City Tutorial

Gimp-tut12 in 30+ Exceptional GIMP Tutorials and Resources
This tutorial has been converted from the original Photoshop tutorial into Gimp. Learn how to create this dramatic effect in Gimp.

9. Flame Abstract Tutorial

Gimp-tut13 in 30+ Exceptional GIMP Tutorials and Resources
In this tutorial we will learn how to use the flame filter to make a simple abstract background.

10. How to create Lightsaber effects

Gimp-tut17 in 30+ Exceptional GIMP Tutorials and Resources
Who doesn’t want to create lightsaber effects. In this tutorial you will learn how.

11. Authentic Vintage Effect

Gimp-tut19 in 30+ Exceptional GIMP Tutorials and Resources
Learn how to create beautiful effect for giving your photos an old vintage feel.

12. Grunge brush pack + tutorial

Gimp-tut23 in 30+ Exceptional GIMP Tutorials and Resources
A whole Gimp grunge back along with a tutorial on how to create your own brush set.

13. Resizing fade effect

Gimp-tut24 in 30+ Exceptional GIMP Tutorials and Resources
This tutorial is about that fade effect, at first glance it’s just a blur effect. This effect works best with pictures of definite figures, such as logos, people, and solid objects.

14. How to make a pile of worms in Gimp

Gimp-tut25 in 30+ Exceptional GIMP Tutorials and Resources
This is how to make something that looks like the image above.

15. Abstract Art

Gimp-tut27 in 30+ Exceptional GIMP Tutorials and Resources
Learn how to create an abstract background easily with Gimp.

2. GIMP Basics

16. GIMP tutorial Basics

Gimp-tut3 in 30+ Exceptional GIMP Tutorials and Resources
This tutorial will teach you some basic tips for working with Gimp: shadowing, coloring, lighting, using the brush and pencil tools.

17. Layers + Inking

Gimp-tut5 in 30+ Exceptional GIMP Tutorials and Resources
This is a tutorial about using Ink and layers in Gimp.

18. Using the Scissor Tool

Gimp-tut18 in 30+ Exceptional GIMP Tutorials and Resources
The scissor tool (selects shapes from images) can be a confusing tool at first, but once you get the hang of it, it’s great for extracting objects from your photos.

19. Using and Manipulating Layers with Gimp

Gimp-tut21 in 30+ Exceptional GIMP Tutorials and Resources
This tutorial will show you how to use and manipulate layers in Gimp. Using layers is essential for making skins, and learning to use them to your advantage will help you produce good results.

3. Photo Manipulation

20. Vintage Look

Gimp-tut4 in 30+ Exceptional GIMP Tutorials and Resources
A tutorial for creating a vintage look in Gimp.

21. GIMP Photomanip Tutorial

Gimp-tut8 in 30+ Exceptional GIMP Tutorials and Resources
A basic tutorial for photomanipulation. You will learn how to tone the brightness, add swirls, grungy effect to the photo.

22. GIMP Photo-manip Tutorial

Gimp-tut15 in 30+ Exceptional GIMP Tutorials and Resources
Learn how to make your photographs look like they came straight out of Hollywood by following a couple of simple steps!

23. How to do skin care with Gimp

Gimp-tut20 in 30+ Exceptional GIMP Tutorials and Resources
Gimp can help you to remove wrinkle, acne scars, red rash, blemish, pimple and other annoying skin problem on face in a photo portrait.This is a guide, manual and help for how to retouch skin with Gimp.

24. Selective Colorization

Gimp-tut26 in 30+ Exceptional GIMP Tutorials and Resources
How to convert a color photograph to a B&W one with color restored to selective areas.

4. Gimp Text Effects

125. Transparent Glass Lettering

Gimp-tut16 in 30+ Exceptional GIMP Tutorials and Resources
Learn how to make a stunning glass text effect. Adapted from a Photoshop tutorial

26. Smelting text / Creating blood text

Gimp-tut14 in 30+ Exceptional GIMP Tutorials and Resources
How you can liquify / smelt text or other graphical objects by creating a blood text.

27. Cool Glow Effect

Gimp-tut22 in 30+ Exceptional GIMP Tutorials and Resources
How you can a nice glow effect for any text yoiu want.

28. Glossy Web Logo

Gimp-tut29 in 30+ Exceptional GIMP Tutorials and Resources
In this tutorial we will learn how to create a cool glossy website logo.

29. Colourful glowing text effect

Gimp-tut31 in 30+ Exceptional GIMP Tutorials and Resources
In this tutorial we will learn how to create a colourful text effect using the gradient blend and blur effects.

30 Fitting Text to Uneven Surfaces

Gimp-tut32 in 30+ Exceptional GIMP Tutorials and Resources
In this tutorial we will learn how to FittText to Uneven Surfaces with GIMP’s Displace Tool.
To subscribe to the "Guy WhoSteals" feed, click here.
Stolen from: http://www.noupe.com/gimp/30-exceptional-gimp-tutorials-and-resources.html
You can add yourself to the GuyWhoSteals fanpage on Facebook or follow GuyWhoSteals on Twitter.

Git and Social Coding: How to Merge Without Fear

Git is great for social coding and community contributions to open source projects: contributors can try out the code easily, and there can be hordes of people all forking and experimenting with it but without endangering existing users. This article presents some examples with the Git command line that might help build your confidence with this process: how to fetch, pull and merge, and how to back out of mistakes. If you are interested in the social coding process itself, and how to contribute to Spring projects, check out another blog on this site by Keith Donald.

Grails has been on Github for a while and had a great experience with community contributions, so some other projects from SpringSource are starting to migrate over there as well. Some of the migrating projects are new (e.g. Spring AMQP) and some are already established and have migrated from SVN (e.g. Spring Batch). There are also some Spring projects on a SpringSource hosted Gitorious instance, for example Spring Integration. The social coding process is slightly different on Github and Gitorious, but the underlying Git manipulations are the same, and that is what we present here. Hopefully, after reading this article and maybe working through the examples, you will be inspired to try the new model and to make contributions to Spring projects. Git is fun and has some great features for this kind of development.

If you have never used Git this is probably not the place to start learning. If you are migrating from SVN to Git and are not as confident when things go wrong as you feel you need to be, or if you want to rid your history of those irritating "Merged branch 'master'..." log messages and keep it nice and linear, this is the place to be. If you are signed up on a social coding site and want to get crunching your changes into your favourite open source project, this article will help you feel more confident about it but you should still read the documentation from your coding host about forking and merging. Hopefully then it will all make sense.

This article takes you through a few simple but common scenarios with Git and multiple users. We start with two users sharing a single repository, and show some pitfalls they can encounter and some tricks for rescuing themselves. Then we move on to a social coding example where there are still two users, but now there are also two remote repositories. This is quite common in open source projects and has a some benefits from a change management perspective, as we will see.

Origins

We are going to start by setting up a simple repository to use for some examples. Here are some Git command line operations you can do yourself from any UN*X shell, and then a sketch of the Git index to show how the commits and branches are laid out:
$ mkdir test; cd test; touch foo.txt bar.txt
$ git init .
$ git add .
$ git status
To be added
$ git commit -m "Initial"
[master (root-commit) 5f1191e] initial
 2 files changed, 2 insertions(+), 0 deletions(-)
 create mode 100644 bar.txt
 create mode 100644 foo.txt
$ git checkout -b feature
$ echo bar > bar.txt
$ git commit -am "change bar"
$ git checkout master
$ echo foo > foo.txt
$ git commit -am "change foo

A - B (master)
  \
    C (feature)

A simple layout, but complex enough to be interesting. There are 3 commits (we ommitted the commit messages in the diagram), and two independent branches. The branches were deliberately engineered to have no conflicts – they contain changes to different files. If you are working through the command line examples and want to see the index tree as well, use a Git UI tool (I used gitk --all which is available on all platforms I believe).
The last thing to do is prepare this repository for cloning:
$ git checkout HEAD~1
We deliberately used a reference HEAD~1 instead of a branch name so that the origin is left with a detached HEAD. If you are used to a remote repository workflow, this will make sense because we are faking a remote repository locally, and remote repositories are usually "bare" (there is no checked out branch). The HEAD~1 reference means "go back a step, but don't assign the new HEAD to any branch", and this makes it possible to push changes to the repository from clones later.

Bob Makes a Clone and Tracks the Branch

Bob is our first user of the repository. Here is his terminal and the index layout in his local repository:
$ git clone test bob
$ cd bob
$ git checkout --track origin/feature

A - B (master,origin/master)
  \
    C (feature,origin/feature)

Bob knows that the feature branch was experimental, but has now been tested so he wants to move it onto the master for inclusion in the next release. But if he merges from here, he gets a non-linear mess (despite the fact that there are no conflicts):
$ git merge master
Merge made by recursive.
 foo.txt |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

A - B (master,origin/master) - D (feature) "Merge branch 'master' into feature"
  \                           /
    C (origin/feature) ------

Bob hates this. The history is non-linear so it's much harder to see where all the changes came from, and it also leaves him with the dreaded auto-generated commit message "Merge branch 'master'…". (It doesn't matter if he merges feature onto master or master onto feature, the result is the same structure with the same ancestors and the same child commits, but with a slightly different auto-generated message.) A push is legal from here but he ends up with the ugly history visible to everyone and also the less than useful auto-generated comments.
Bob doesn't panic! He can still revert to the original index because he hasn't pushed anything yet:
$ git reset --hard origin/feature

A - B (master,origin/master)
  \
    C (feature,origin/feature)

From there he can sit back and wait for someone else to solve the problem. Along comes Jane…
(Note that not everyone shares this view of Bob's, that unnecessary non-linear history and auto-generated commit logs with no new changes are a bad thing. Some people actually find it "re-assuring" that there are signs of parallel development. They generally don't use rebase and prefer the simple pull and merge approach to collaboration with Git.)

Jane Clones Another Copy and Does a Local Rebase

Jane is also a developer with write access to the test repository. She is bolder than Bob and decides that what is needed is a rebase to keep the history linear:
$ git clone test jane
$ cd jane
$ git checkout --track origin/feature
$ git rebase master

A - B (master,origin/master) - D (feature)
  \
    C (origin/feature)

(Note that Jane could have achieved the same result by starting down the same route as Bob – a merge of master, followed by a rebase has the same endpoint because rebase is smart enough to realize that it can save some duplication and not show intermediate states that contain no new changes.)
Now everything looks OK(ish), but git will not allow a push back to origin because the feature has diverged:
$ git push
To file:///path/to/test
 ! [rejected]        feature -> feature (non-fast-forward)
error: failed to push some refs to 'file:///path/to/test'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'Note about
fast-forwards' section of 'git push --help' for details.
If Jane takes the hint and merges from here and she really will regret it. The result of the rebase is only really OK*ish* – it has duplicate commits (C and D with the same log message and the same changes when you quint at them), so the merge will not be pretty. Git is only going to do what she told it, and the merge is legal, but the effect will be
* a non-linear history
* an auto-generated commit message
* duplicate commit messages (one on each ancestor branch)
Here's the result:
$ git merge origin/feature
Merge made by recursive.

A - B (master,origin/master) - D "change bar" - E (feature) "Merge branch 'master' into feature"
  \                                            /
    C (origin/feature) "change bar" ----------

She only made two changes to the source code but the result is 5 commits in the index. That sucks. To revert she can use the same trick as before, except that now there is no named branch at the commit she wants to reset to (D). Either she can add one, or use a UI tool gitk is good at this), or use a relative reference:
$ git reset --hard HEAD~1

A - B (master,origin/master) - D (feature)
  \
    C (origin/feature)

The unfriendly thing to do, and the one that all the Git manuals warn you about, is to force a push. Jane gives it a try:
$ git push --force

A - B (master,origin/master) - D (feature,origin/feature)

Now that's more like it! Two changes and three commits (one on either side of the changes), and a nice linear history with no unpleasant commit messages. So why is it such a bad thing to do? Let's look at our hapless friend Bob again.

Bob is Now Potentially in a Mess

He will be fine if he hasn't modified the "feature" branch:
$ git checkout master
$ git pull
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From file:///path/to/test
 + 4b223e2...4db65c2 feature       -> origin/feature  (forced update)
Already up-to-date.

A - B (master,origin/master) - D (origin/feature)
  \
    C (feature)

It looks a little ugly here, but Git has held everything together. Bob can see that Jane (or someone) has forced an update to the remote branch he was tracking, so his local branch has diverged through no fault of his. He might be a little peeved about that, but in this case it is harmless because he hasn't made any changes to his local branch so he can just reset his branch:
$ git checkout feature
Switched to branch 'feature'
Your branch and 'origin/feature' have diverged,
and have 1 and 2 different commit(s) each, respectively.
$ git reset --hard origin/feature

A - B (master,origin/master) - D (feature,origin/feature)

Everyone is happy! So a forced push is OK in some circumstances. In particular, it can be acceptable for someone working on a fork of a "main" project, as often arises with social coding (like at Github). Let's look at that use case in more detail.

Forks and Social Coding

One of the intended useful features of Git is that it can be used as a distributed repository – you don't have to take the single-origin approach common with SVN and older systems. The distributed feature is used heavily, but not extensively, when you fork from a public open-source project and then ask the project's owner to merge in some of your changes to the main repository.
So let's suppose that there is a cool open-source project called main, owned by Mary, and Bob goes and forks it from the project home page. He gets a new repository with a precise copy of the Git index of the main repository, and he can call it whatever he likes (he chooses bob-main to help us keep it straight). The Git part of this is trivial – effectively he is just cloning main, moving the origin reference to the new location in his own space on the server, and then pushing the changes back up. The social coding application handles all this behind the scenes and helpfully suggests to Bob that he clone his new remote fork.
So now we have a main repository (which is the origin for Mary, but not for Bob), and a bob-main repository which are identical. Let's make it start with just one commit to keep it simple (so take the origin creation recipe from the first example and stop after the first commit):

A (master)

Mary's local copy starts identical Bob's, and they both look like this:

A (master,origin/master)

But their origin references are different. For Mary:
$ git remote -v
origin git@host:/mary/main (fetch)
origin git@host:/mary/main (push)
and for Bob:
$ git remote -v
origin git@host:/bob/bob-main (fetch)
origin git@host:/bob/bob-main (push)
Typically Mary will not have permission to push to Bob's repository nor vice versa.


Bob Adds a Feature

Bob has a great idea for the main project so he creates his feature branch and starts coding, ending up here:
$ git checkout -b feature
$ echo foo >> foo.txt
$ git commit -am "change foo"

A(master,origin/master) - C (feature)

He is pleased with this, so he pushes it back to his own origin
$ git push origin feature

A(master,origin/master) - C (feature,origin/feature)

Notice how Bob keeps all his changes on a branch. This isn't compulsory, but as we'll see later, it makes it a lot easier to keep track of differences with the main repository (even though so far Bob has no explicit connection to there). The user documentation at Github actually doesn't recommend this approach, but you might find it helpful.


Mary Makes Some Changes

Mary is the project owner, and she can push to her master branch any time she likes. So she does this:
$ echo bar >> bar.txt
$ git commit -am "change bar"
$ git push

A - B (master,origin/master)


Bob Sends a Pull Request

Now Bob asks Mary to merge his changes. Mary follows the friendly instructions on the social coding site and pulls down Bob's changes to take a look
$ git checkout -b bob master
$ git pull https://host/bob/bob-main feature

A - B (master,origin/master) - D (bob) "Merge branch 'feature' of '...bob-main' into bob"
  \                           /
    C  ----------------------

Mary sees immediately that Bob has diverged from her master. What should she do?


Alternative 1: No Forced Push

In this case it might be quite straightforward if there are no conflicts. She decides to spend some time cleaning up the history, just in case it is easy. This is the same process that Bob used in the previous, single origin example.
$ git reset --hard HEAD~1
$ git rebase master

A - B (master,origin/master) - C (bob)

No problems there, and the history is linear again. Mary just needs to wrap up the change with her main project:
$ git checkout master
$ git merge bob
$ git push
$ git branch -D bob

A - B - C (master,origin/master)

She deleted the local branch bob at the end there because it is no longer marking anything significant, and it isn't tracking a remote branch so she doesn't have to deal with that reference as well.


Alternative 2: Forced Push in Fork

If the rebase failed above, or Mary simply takes the view that if it is Bob that wants his change to be merged then the onus is on him to make the history linear, she can ask him to rebase onto her master. She sends him a message via the nifty social coding site, and then resets her local copy:
$ git checkout master
$ git branch -D bob
$ git prune

A - B (master,origin/master)

Now Bob gets to work. He is still on his feature branch, so
$ git remote add main https://host/mary/main
$ git fetch main

A (master,origin/master) - B (main/master)
 \
  C (feature,origin/feature)

So now he has a read-only reference to the main repository and an alias for it so he can bring himself up to data quickly with Mary's work. (The alias is optional, but it will help him to stay up to date and see at a glance where his master is relative to Mary's.) First he brings his master in line with the main one
$ git checkout master
$ git merge main/master
$ git push

A - B (master,origin/master,main/master)
 \
  C (feature,origin/feature)

It is here that we see the benefit of working on a feature branch: it is always trivial to merge the master with the main repository if it is kept free of local changes (master is never ahead of main/master). Now he tries the rebase that Mary asked for:
$ git checkout feature
$ git rebase master

A - B (master,origin/master,main/master) - D (feature)
 \
  C (origin/feature)

Bob sees that the history is as he wants it, so he pushes it up to his remote repository:
$ git push --force

A - B (master,origin/master,main/master) - D (feature,origin/feature)

Bob has played the same trick here that Jane did in the previous example – he forced a push of a local branch to maintain a linear history.
Bob and Mary are consenting adults and the only reason the feature branch exists in Bob's repository is to anchor the pull request, so it is unlikely that anyone else is tracking that branch. If someone was tracking that branch they might be inconvenienced, even severely inconvenienced if they tagged a public release on that branch. It's a risk that Bob decides to take – it's no risk at all in fact in this example because Bob is the only person with write access to his repository and he's pretty confident that no-one is using his branch for making releases.

Conclusion

The process of merging the contribution is not simple unless the changes are trivial, but Git does take a lot of the pain out of it, and it's easy enough once you get the hang of it. The key point in the example is that Git is being used in a particular style, and there are some constraints and conventions that make it easier: Bob and Mary's repositories are read-only to each other, and Bob is actually the only person with write permission to his fork so he doesn't mind at all that Mary wants him to force a push there. This is by far not the only feature of Git that makes it interesting for open-source developers, but it goes a long way to explain why some of us are moving to sites like Github.

Also read this article on Tips for intermediate Git users.
To subscribe to the "Guy WhoSteals" feed, click here.
You can add yourself to the GuyWhoSteals fanpage on Facebook or follow GuyWhoSteals on Twitter.

Introduction
I’ve been using git for about 18 months now and thought I knew it pretty well. Then we had Scott Chacon from GitHub over to do some training at LVS, a supplier/developer of betting/gaming software (where I’m currently contracting) and I learnt a ton in the first day.
As someone who’s always felt fairly comfortable in Git, I thought sharing some of the nuggets I learnt with the community might help someone to find an answer without needing to do lots of research.


Basic Tips


1. First Steps After Install

After installing Git, the first thing you should do is configure your name and email, as every commit will have these details:
$ git config --global user.name "Some One"
$ git config --global user.email "someone@gmail.com"


2. Git is Pointer-Based

Everything stored in git is in a file. When you create a commit it creates a file containing your commit message and associated data (name, email, date/time, previous commit, etc) and links it to a tree file. The tree file contains a list of objects or other trees. The object or blob is the actual content associated with the commit (a file, if you will, although the filename isn’t stored in the object, but in the tree). All of these files are stored with a filename of a SHA-1 hash of the object.
From there branches and tags are simply files containing (basically) a SHA-1 hash which points to the commit. Using these references allows for a lot of flexibility and speed, as creating a new branch is as simple as creating a file with the name of the branch and the SHA-1 reference to the commit you’re branching from. Of course, you’d never do that as you’d use the Git command line tools (or a GUI), but it’s that simple.
You may have heard references to the HEAD. This is simply a file containing the SHA-1 reference of the commit you’re currently pointing to. If you’re resolving a merge conflict and see HEAD, that’s nothing to do with a particular branch or necessarily a particular point on the branch but where you currently are.
All the branch pointers are kept in .git/refs/heads, HEAD is in .git/HEAD and tags are in .git/refs/tags – feel free to have a look in there.


3. Two Parents – of course!

When viewing a merge commit message in a log, you will see two parents (as opposed to the normal one for a work-based commit). The first parent is the branch you were on and the second is the one you merged in to it.


4. Merge Conflicts

By now I’m sure you have had a merge conflict and had to resolve it. This is normally done by editing the file, removing the <<<<, ====, >>>> markers and the keeping the code you want to store. Sometimes it’s nice to see the code before either change, i.e. before you made the change in both branches that now conflicts. This is one command away:
$ git diff --merge
diff --cc dummy.rb
index 5175dde,0c65895..4a00477
--- a/dummy.rb
+++ b/dummy.rb
@@@ -1,5 -1,5 +1,5 @@@
  class MyFoo
    def say
-     puts "Bonjour"
 -    puts "Hello world"
++    puts "Annyong Haseyo"
    end
  end
If the file is binary, diffing files isn’t so easy… What you’ll normally want to do is to try each version of the binary file and decide which one to use (or manually copy portions over in the binary file’s editor). To pull a copy of the file from a particular branch (say you’re merging master and feature132):
$ git checkout master flash/foo.fla # or...
$ git checkout feature132 flash/foo.fla
$ # Then...
$ git add flash/foo.fla
Another way is to cat the file from git – you can do this to another filename then copy the correct file over (when you’ve decided which it is) to the normal filename:
$ git show master:flash/foo.fla > master-foo.fla
$ git show feature132:flash/foo.fla > feature132-foo.fla
$ # Check out master-foo.fla and feature132-foo.fla
$ # Let's say we decide that feature132's is correct
$ rm flash/foo.fla
$ mv feature132-foo.fla flash/foo.fla
$ rm master-foo.fla
$ git add flash/foo.fla
[update] Thanks to Carl in the comments for the reminder, you can actually use “git checkout —ours flash/foo.fla” and “git checkout —theirs flash/foo.fla” to checkout a particular version without remembering which branches you merge in. Personally I prefer to be more explicit, but the option is there…
Remember to add the file after resolving the merge conflict (as I do above).


Servers, Branches and Tagging


5. Remote Servers

One of the most powerful features of Git is the ability to have more than one remote server (as well as the fact that you’re running a local repository always). You don’t always need write access either, you may have multiple servers you read from (to merge work in) and then write to another. To add a new remote server is simple:
$ git remote add john git@github.com:johnsomeone/someproject.git
If you want to see information about your remote servers you can do:
# shows URLs of each remote server
$ git remote -v 

# gives more details about each
$ git remote show name 
You can always see the differences between a local branch and a remote branch:
$ git diff master..john/master
You can also see the changes on HEAD that aren’t on that remote branch:
$ git log remote/branch..
# Note: no final refspec after ..


6. Tagging

In Git there are two types of tag – a lightweight tag and an annotated tag. Bearing in mind Tip 2 about Git being pointer based, the difference between the two is simple. A lightweight tag is simply a named pointer to a commit. You can always change it to point to another commit. An annotated tag is a name pointer to a tag object, with it’s own message and history. As it has it’s own message it can be GPG signed if required.
Creating the two types of tag is easy (and one command line switch different)
$ git tag to-be-tested
$ git tag -a v1.1.0 # Prompts for a tag message


7. Creating Branches

Creating branches in git is very easy (and lightning quick due to it only needing to create a less than 100 byte file). The longhand way of creating a new branch and switching to it:
$ git branch feature132
$ git checkout feature132
Of course, if you know you’re going to want to switch to it straight away you can do it in one command:
$ git checkout -b feature132
If you want to rename a local branch it’s as easy as (the long way to show what happens):
$ git checkout -b twitter-experiment feature132
$ git branch -d feature132
[update] Or you can (as Brian Palmer points out in the comments) just use the -m switch to “git branch” to do it in one step (as Mike points out, if you only specify one branch it renames your current branch):
$ git branch -m twitter-experiment
$ git branch -m feature132 twitter-experiment


8. Merging Branches

At some point in the future, you’re going to want to merge your changes back in. There are two ways to do this:
$ git checkout master
$ git merge feature83 # Or...
$ git rebase feature83
The difference between merge and rebase is that merge tries to resolve the changes and create a new commit that blends them. Rebase tries to take your changes since you last diverged from the other branch and replay them from the HEAD of the other branch. However, don’t rebase after you’ve pushed a branch to a remote server – this can cause confusion/problems.
If you aren’t sure which branches still have unique work on them – so you know which you need to merge and which ones can be removed, there are two switches to git branch that help:
$ # Shows branches that are all merged in to your current branch
$ git branch --merged

$ # Shows branches that are not merged in to your current branch
$ git branch --no-merged


9. Remote Branches

If you have a local branch that you’d like to appear on a remote server, you can push it up with one command:
$ git push origin twitter-experiment:refs/heads/twitter-experiment
# Where origin is our server name and twitter-experiment is the branch
[update] Thanks to Erlend in the comments – this is actually the same as doing “git push origin twitter-experiment” but by using the full syntax you can see that you can actually use different names on both ends (so your local can be “add-ssl-support” while your remote name can be “issue-1723”).
If you want to delete a branch from the server (note the colon before the branch name):
$ git push origin :twitter-experiment
If you want to show the state of all remote branches you can view them like this:
$ git remote show origin
This may list some branches that used to exist on the server but now don’t exist. If this is the case you can easily remove them from your local checkout using:
$ git remote prune
[update] Thanks Alex for the correction.
Finally, if you have a remote branch that you want to track locally, the longhand way is:
$ git branch --track myfeature origin/myfeature
$ git checkout myfeature
However, newer versions of Git automatically set up tracking if you use the -b flag to checkout:
$ git checkout -b myfeature origin/myfeature


Storing Content in Stashes, Index and File System


10. Stashing

In Git you can drop your current work state in to a temporary storage area stack and then re-apply it later. The simple case is as follows:
$ git stash
# Do something...
$ git stash pop
A lot of people recommend using “git stash apply” instead of pop, however if you do this you end up with a long list of stashes left hanging around. “pop” will only remove it from the stack if it applies cleanly. If you’ve used “git stash apply” you can remove the last item from the stack anyway using:
$ git stash drop
Git will automatically create a comment based on the current commit message. If you’d prefer to use a custom message (as it may have nothing to do with the previous commit):
$ git stash save "My stash message"
If you want to apply a particular stash from your list (not necessarily the last one) you can list them and apply it like this:
$ git stash list
  stash@{0}: On master: Changed to German
  stash@{1}: On master: Language is now Italian
$ git stash apply stash@{1}


11. Adding Interactively

In the subversion world you change files and then just commit everything that has changed. In Git you have a LOT more power to commit just certain files or even certain patches. To commit certain files or parts of files you need to go in to interactive mode.
$ git add -i
           staged     unstaged path


*** Commands ***
  1: status   2: update   3: revert   4: add untracked
  5: patch   6: diff   7: quit   8: help
What now> 
This drops you in to a menu based interactive prompt. You can use the numbers of the commands or the highlighted letters (if you have colour highlighting turned on) to go in to that mode. Then it’s normally a matter of typing the numbers of the files you want to apply that action to (you can use formats like 1 or 1-4 or 2,4,7).
If you want to go to patch mode (‘p’ or ‘5’ from interactive mode) you can also go straight in to that mode:
$ git add -p 
diff --git a/dummy.rb b/dummy.rb
index 4a00477..f856fb0 100644
--- a/dummy.rb
+++ b/dummy.rb
@@ -1,5 +1,5 @@
 class MyFoo
   def say
-    puts "Annyong Haseyo"
+    puts "Guten Tag"
   end
 end
Stage this hunk [y,n,q,a,d,/,e,?]? 
As you can see you then get a set of options at the bottom for choosing to add this changed part of the file, all changes from this file, etc. Using the ‘?’ command will explain the options.


12. Storing/Retrieving from the File System

Some projects (the Git project itself for example) store additional files directly in the Git file system without them necessarily being a checked in file.
Let’s start off by storing a random file in Git:
$ echo "Foo" | git hash-object -w --stdin
51fc03a9bb365fae74fd2bf66517b30bf48020cb
At this point the object is in the database, but if you don’t set something up to point to that object it will be garbage collected. The easiest way is to tag it:
$ git tag myfile 51fc03a9bb365fae74fd2bf66517b30bf48020cb
Note that here we’ve used the tag myfile. When we need to retrieve the file we can do it with:
$git cat-file blob myfile
This can be useful for utility files that developers may need (passwords, gpg keys, etc) but you don’t want to actually check out on to disk every time (particularly in production).


Logging and What Changed


13. Viewing a Log

You can’t use Git for long without using ‘git log’ to view your recent commits. However, there are some tips on how to use it better. For example, you can view a patch of what changed in each commit with:
$ git log -p
Or you can just view a summary of which files changed with:
$ git log --stat
There’s a nice alias you can set up which shows abbreviated commits and a nice graph of branches with the messages on a single line (like gitk, but on the command line):
$ git config --global alias.lol "log --pretty=oneline --abbrev-commit --graph --decorate"
$ git lol
* 4d2409a (master) Oops, meant that to be in Korean
* 169b845 Hello world


14. Searching in the Log

If you want to search for a particular author you can specify that:
$ git log --author=Andy
[update] Thanks to Johannes in the comments, I’ve cleared up some of the confusion here.
Or if you have a search term that appears in the commit message:
$ git log --grep="Something in the message"
There’s also a more powerful command called the pickaxe command that look for the entry that removes or adds a particular piece of content (i.e. when it first appeared or was removed). This can tell you when a line was added (but not if a character on that line was later changed):
$ git log -S "TODO: Check for admin status"
What about if you changed a particular file (lib/foo.rb)
$ git log lib/foo.rb
Let’s say you have a feature132 branch and a feature 145 and you want to view the commits on those branches that aren’t on master (note the ^ meaning not):
$ git log feature132 feature145 ^master
You can also narrow it down to a date range using ActiveSupport style dates:
$ git log --since=2.months.ago --until=1.day.ago
By default it will use OR to combine the query, but you can easily change it to use AND (if you have more than one criteria)
$ git log --since=2.months.ago --until=1.day.ago --author=andy -S "something" --all-match


15. Selecting Revisions to View/Change

There are a number of items you can specify when referring to a revision, depending on what you know about it:
$ git show 12a86bc38 # By revision
$ git show v1.0.1 # By tag
$ git show feature132 # By branch name
$ git show 12a86bc38^ # Parent of a commit
$ git show 12a86bc38~2 # Grandparent of a commit
$ git show feature132@{yesterday} # Time relative
$ git show feature132@{2.hours.ago} # Time relative
Note that unlike the previous section, a caret on the end means the parent of that commit – a caret at the start means not on this branch.


16. Selecting a Range

The easiest way is to use:
$ git log origin/master..new
# [old]..[new] - everything you haven't pushed yet
You can also omit the [new] and it will use your current HEAD.


Rewinding Time/Fixing Mistakes


17. Resetting changes

You can easily unstage a change if you haven’t committed it using:
$ git reset HEAD lib/foo.rb
Often this is aliased to ‘unstage’ as it’s a bit non-obvious.
$ git config --global alias.unstage "reset HEAD"
$ git unstage lib/foo.rb
If you’ve committed the file already, you can do two things – if it’s the last commit you can just amend it:
$ git commit --amend
This undoes the last commit, puts your working copy back as it was with the changes staged and the commit message ready to edit/commit next time you commit.
If you’ve committed more than once and just want to completely undo them, you can reset the branch back to a previous point in time.
$ git checkout feature132
$ git reset --hard HEAD~2
If you actually want to bring a branch to point to a completely different SHA1 (maybe you’re bringing the HEAD of a branch to another branch, or a further commit) you can do the following to do it the long way:
$ git checkout FOO
$ git reset --hard SHA
There’s actually a quicker way (as it doesn’t change your working copy back to the state of FOO first then forward to SHA):
$ git update-ref refs/heads/FOO SHA


18. Committing to the Wrong Branch

OK, let’s assume you committed to master but should have created a topic branch called experimental instead. To move those changes over, you can create a branch at your current point, rewind head and then checkout your new branch:
$ git branch experimental   # Creates a pointer to the current master state
$ git reset --hard master~3 # Moves the master branch pointer back to 3 revisions ago
$ git checkout experimental
This can be more complex if you’ve made the changes on a branch of a branch of a branch etc. Then what you need to do is rebase the change on a branch on to somewhere else:
$ git branch newtopic STARTPOINT
$ git rebase oldtopic --onto newtopic


19. Interactive Rebasing

This is a cool feature I’ve seen demoed before but never actually understood, now it’s easy. Let’s say you’ve made 3 commits but you want to re-order them or edit them (or combine them):
$ git rebase -i master~3
Then you get your editor pop open with some instructions. All you have to do is amend the instructions to pick/squash/edit (or remove them) commits and save/exit. Then after editing you can “git rebase —continue” to keep stepping through each of your instructions.
If you choose to edit one, it will leave you in the state you were in at the time you committed that, so you need to use git commit —amend to edit it.
Note: DO NOT COMMIT DURING REBASE – only add then use —continue, —skip or —abort.


20. Cleaning Up

If you’ve committed some content to your branch (maybe you’ve imported an old repo from SVN) and you want to remove all occurrences of a file from the history:
$ git filter-branch --tree-filter 'rm -f *.class' HEAD
If you’ve already pushed to origin, but have committed the rubbish since then, you can also do this for your local system before pushing:
$ git filter-branch --tree-filter 'rm -f *.class' origin/master..HEAD


Miscellanous Tips


21. Previous References You’ve Viewed

If you know you’ve previously viewed a SHA-1, but you’ve done some resetting/rewinding you can use the reflog commands to view the SHA-1s you’ve recently viewed:
$ git reflog
$ git log -g # Same as above, but shows in 'log' format


22. Branch Naming

A lovely little tip – don’t forget that branch names aren’t limited to a-z and 0-9. It can be quite nice to use / and . in names for fake namespacing or versionin, for example:
$ # Generate a changelog of Release 132
$ git shortlog release/132 ^release/131
$ # Tag this as v1.0.1
$ git tag v1.0.1 release/132


23. Finding Who Dunnit

Often it can be useful to find out who changed a line of code in a file. The simple command to do this is:
$ git blame FILE
Sometimes the change has come from a previous file (if you’ve combined two files, or you’ve moved a function) so you can use:
$ # shows which file names the content came from
$ git blame -C FILE
Sometimes it’s nice to track this down by clicking through changes and going further and further back. There’s a nice in-built gui for this:
$ git gui blame FILE


24. Database Maintenance

Git doesn’t generally require a lot of maintenance, it pretty much takes care of itself. However, you can view the statistics of your database using:
$ git count-objects -v
If this is high you can choose to garbage collect your clone. This won’t affect pushes or other people but it can make some of your commands run much faster and take less space:
$ git gc
It also might be worth running a consistency check every so often:
$ git fsck --full
You can also add a “—auto” parameter on the end (if you’re running it frequently/daily from crontab on your server) and it will only fsck if the stats show it’s necessary.
When checking, getting “dangling” or “unreachable” is fine, this is often a result of rewinding heads or rebasing. Getting “missing” or “sha1 mismatch” is bad… Get professional help!


25. Recovering a Lost Branch

If you delete a branch experimental with -D you can recreate it with:
$ git branch experimental SHA1_OF_HASH
You can often find the SHA1 hash using git reflog if you’ve accessed it recently.
Another way is to use “git fsck —lost-found”. A dangling commit here is the lost HEAD (it will only be the HEAD of the deleted branch as the HEAD^ is referred to by HEAD so it’s not dangling)
Also, check this article on Merging code branches in Git.
To subscribe to the "Guy WhoSteals" feed, click here.
Stolen from: http://andyjeffries.co.uk/articles/25-tips-for-intermediate-git-users
You can add yourself to the GuyWhoSteals fanpage on Facebook or follow GuyWhoSteals on Twitter.
Related Posts Plugin for WordPress, Blogger...
top
Share