16 April 2016

Git

configuration

git config --system

System level

C:\Program Files (x86)\Git\etc\gitconfig

User level

git config --global

File dump example

C:\Users\<name>\.gitconfig

[gui]
	recentrepo = <repo>
	recentrepo = <recent repo>
[user]
	name = <name>
	email = <email>
[alias]
	st = status

example

set user name :
git config --global user.name "kris kringle"
set main editor for diffs etc..
git config --global core.editor "notepad++"

This is easy to do in linux/mac but for this to work in windows we need to make it a bit harder. We need a .bat file to point out our editor

c:/dev/ npp.bat  // you put it where you want it

Containing the following:

#!/bin/sh
"C:\Program Files (x86)\Notepad++\notepad++.exe" -multiInst "$*"
And then we run the following command
git config --global core.editor c:dev/npp.bat
set ui, diffs and status etc will be shown in nice colors
git config --global color.ui auto
If you are doing cross platform development in your project you should set a policy for the following so it handles line feed correctly between systems
git config --global core.autocrlf true

false when windows only contributors

input when only on mac/linux means that text file with windows style line feeds are converted to linux/mac style

and finally to see all commands

git config --global --list

repository level

Command for setting repository level config

git config

Location of local config file

.git/config

Output of local git config file

cat .git/config

It is entirely possible to override global settings by doing

git config user.name <new user>

If you want to remove a setting do

git config --unset <property> <new value>

Working locally

Create a new repository

git init

Let’s add content

echo "hello git" > README.md

Check repo status

git status

Adds the file to the staging area

Create new file.

Our new file is indicated as untracked

git add README.md

This means our file is now tracked by git repo.

commit with text editor

git commit

Brings up the configured editor

Shows what happened in repo so far

git log

Here it will show all your commits over several pages. To abort type q + enter.

Do an update of a tracked file. See it is modified and then run

git add -u

To add updated files

shorthand commit

So far we have been using

git commit

To get up a text editor to write our commit message in. But we can just type a commit message in the command window if we don’t want the editor like so:

git commit -m 'a message'

diffing files

git diff <revision number>..<revision number of other version>

You get a print in the command line indicating what the diff is with:

++ added lines
-- removed lines

You only need to use the first 5 characters in a revision to diff, it might get tedious to type the whole revision number otherwise.

diffing current with the next latest

Oftentimes you just want to diff what you are working on now with your latest commit. Your recent commit is called HEAD and your commit before that is called HEAD~1

git diff HEAD~1..HEAD

You will get the same result as diffing the two versions Read as

git diff <old version>..<new version>

I can type this with even less characters

git HEAD~1

It will assume I mean diff one commit back with latest

adding files

We said before we can add updated files by typing

git add -u

BUT this only add files that already exist in the staging area. What about newly created files for example?

git add -A

Will add even untracked files and make them ready for commit.

Doing a

git diff HEAD~1

Will indicate that our newly created files are added to the repository as well. So HEAD is actually also what we have added to the repository not just commited..

undoing work

So lets say we start editing a file and we want to discard the changes, what then?

git checkout <filename>

Will restore the file to the old status

Another way is to type

git reset --hard

If you however type the following

git reset --soft HEAD~1

You will take you last commit and make it end up in the state just before commit, your files are added to staging area but needs to be commited. Great command for doing an undo of what you did last.

NOW lets say that last commit commit was so bad and everything with it just needs to go away, what then?

git reset --hard HEAD~1

There it never ever ever happened.

BUT before trying reset –hard think wether this is what you really want, maybe you just want to back it up a bit, like reset –soft?

clean

Sometimes you will want to clean your repo of created non staged files. You however need to add a force to your command

git clean

Adding the flag -n indicated you want to know what will happen if you attempt the command, so its like a preview.

git clean -n

If you want to actually enforce the command and clean up your repo then add -f flag.

git clean -f

ignoring files

So first thing you should have in your repo is a .gitignore file so you can say what files and directories you don’t want to be part of your repo.

touch .gitignore

Let’s say we create an directory called ignore like so

mkdir ignore

To ensure git ignores it we need to add an entry to our .gitignore like so:

// .gitignore

// will ignore ignore/**/*
ignore  

You should know however that this ignores all sub directories called ignore so this ignore for example

ignore/
path/ignore
path/otherpath/ignore

To make sure it ignores on a more exact level you need to type

/ignore

This will ignore the ignore/ directory on the root level of the repository, nothing else.

If you are working with nodejs applications or pulling in nodejs libs it is a good idea to go for

node_modules

Because a lot of libs have dependencies themselves and have pulled in sub directories called node_modules.

And a last note if you don’t want to exclude eveything in a directory you can block certain file endings for example

ignore/*.txt

Working remotely

One thing you might wanna do when working remotely is to continue working on an existing project on github. Let’s take jquery, clone it and continue our work on it.

cloning

We copy the project, we get the files and all commit history

git clone git://github.com/jquery/jquery.git

See a complete log

git log

Don’t forget to quit with q + enter, its long :)

commits on one line

Lets format how we see our commit history. Let’s us see everything on one line.

git log --oneline

merges and branches

If you want to see all history like branches being merged into default you can type

git log --oneline -graph

author stats

Another very interesting command is this

git shortlog

it will show us all authors, the number of commits and what they were, how cool is that?

author stats - ranking

And a little more detailed, summary, number ordered, email address

git shortlog -sne	

This last is a good way to get a good understanding of all contributors and how much impact they made to the project.

last added commit to project, row for row

See the last commit made to a project, what rows were added and removed.

git show HEAD

remotes

The name of the remote

git remote

All urls associated to the remote

git remote -v

To add a remote repository to pull from

git remote add origin <name of git file on remote url>.git

It’s normal to have a number of remotes

With git fetch you fetch any changes from your remote

git fetch

git fetch <remote name>

Branches

View all branches

git branch

To view all remote branches

git branch -r 

fetching content

You need to answer the following question

What branch remotely does local branch mirror?

This question has two answers:

1)

git pull origin master

2)

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

plus

git pull

pushing content

git push

Tags

Tag is a stable point in your code like 1.0, 1,1 etc.

Tags are stable points in your codebase

git tag <tagname>

Creating a tag

git tag 1.0

Creates a tag called 1.0

To see your tags type

git tag

annotated tag

This is a tag with no message attached to it. However if you want to describe the tag I can do so by providing an annitation flag -a

git tag -a 1.1

Then you are prompted for a tag message

signed tag

Signing is a way to verify for certain that a certain commit has been done by a certain person.

git tag -s 1.2

The difference between annotated and signed is that signed requires you to type a password

And to verify the tag you use the verify, -v

git tag -v <tag name>

So one final thing about tags, if you want to push them to github you need to provide the –tags option when pushing like so:

git push --tags

Working with tags

Of course for it to be useful we need to be able to checkout a specific tag. Like so:

git checkout tags/<tagname>

Or even better we checkout a tag, creates a branch based on it and continue working from there:

git checkout tags/<tagname> -b <branchname>

Branches

Branch overview

A nice way of showing commits, tags and your branches is

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

Create a branch

git branch <branchname>

e.g

git branch feature1

Switching to new branch

git checkout feature1

create and switch

You can do both, here is how

git checkout -b "feature1"

And do

git branch

To verify you are on the intended branch

renaming a branch

What if a branch was created with a bad name and you realized you wanted to name it something else?

git branch -m <oldname>  <newname>

deleting branches

git branch -d <branchname>

BUT if you have things in there you havnt merged then you either need to do that first or go with hard delete, -D

git branch -D <branchname>

Pausing and resuming work

If you are working on something not ready to be checked in and need to change branch you can stash it, also called shelve in other systems.

git stash

If you forgot what you put in there you can type

git stash list

Then you can change to other branch, do work and come back to this branch and resume your work doing:

git stash apply

This effectively undos the stash, you would hope this would be called unstash, but no such luck, remember to apply to undo.

Your stash list may grow with time.. So besides using

git stash apply 

You can use another command that cleans your stash

git stash pop

This does the same as apply but also cleans your stash’s latest entry.

And to clean up the stash for various reasons do a

git stash drop

This will remove the latest stash entry.

merge

Ok so you performed a bunch of changes on your feature branch.. What then.. Well you want to merge your changes from the feature branch to your master.

A sound approach here is to merge from master into your feature branch to ensure that any conflicts happen in master branch.

git checkout feature1
git merge master

And after that switch to master branch and merge

git checkout master
git merge feature1

If everything goes well the merge will just happen this is called a fast-forward merge.

BUT what if I have done a change in the same file on the same row but on different branches?

Then we will get a conflict that we need to resolve, either with a merge tool or manually. It will be written into the file where the problem lies

<<<<<< master
stuff
========
other stuff
>>>>>> feature1

Resolve it and commit, this is known as a merge commit.

The resolve consists of either manually correct the results to what it should be or use the following command

git mergetool

We are presented with 3 windows

middle : local copy right: the branch we are trying to merge in left : the common commit both these came from

If you don’t have a merge tool present it is a good idea to setup one, for example like so, in windows:

[merge]
	tool = kdiff3

[mergetool "kdiff3"]
    path = C:/Program Files/KDiff3/kdiff3.exe
    keepBackup = false
    trustExitCode = false

rebasing

The business case for performing a rebase is that some point in history we have performed a branch, carried out some work and we think that that work should be moved on top of the master. Imagine the following:

  E-F-G-H  -- feature/bug branch 
A-B-C-D    -- master

Here we have branched at B, and carried out some changes. We want E however to be appended after D like so

	  E-F-G-H
A-B-C-D

We can either stand in the feature/bug branch and perform

git rebase master
git rebase master featurebranch

Imagine in the featurebranch we added a few lines of code to feature.js

+ function a(){}

And in the master branch we added a few lines to app.js like so

+ var basePath= "test";

After

git checkout featurebranch

We run

git rebase master

Effectively appending the featurebranch to the HEAD of master branch. We get both these changes applied to HEAD of master branch

Thats all for now

Next blogpost will cover git with github. Stay tuned.



blog comments powered by Disqus