git « Intelligrape Groovy & Grails Blogs

Posts Tagged ‘ git ’

Modify promt to make it GIT specific.

Posted by on September 24th, 2012

We use git a lot, and one of the most used commands is “git branch”. Few Months back we found a script that enabled us to modify our prompt so that it shows our current branch. We have modified it further to add extra functionality, and our modified script enables prompt to show number of files modified, number untracked files, and also the new files along with the branch name.

Below is sample image from terminal.

GIT CONSOLE

In image the prompt shows same information briefly as shown by git status. Here

  1. U shows Untracked files.
  2. M shows modified files
  3. And NEW Shows new file that has been added to Git

And below is the actual script.

GST="git status"
OLDPS1=$PS1 

function parse_git_branch {
	git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/[\1] /'
}

function git_status() {
    	if current_git_status=$($GST 2> /dev/null | grep 'modified'); then
		COUNT=`git status |grep "modified" | wc -l| sed -e 's/^[ \t]*//'`
		echo "[M x $COUNT]"
	fi
}

function git_untracked(){
    	if current_git_status=$($GST 2> /dev/null | grep 'Untracked files:' ); then
     		echo "[U]"
    	fi
}
function new_file_check(){
	if git_dir=$(git branch 2> /dev/null | grep '*' ); then
                COUNTNEW=`git status |  grep "new file:" | wc -l| sed -e 's/^[ \t]*//'`
                if [ $COUNTNEW -gt 0 ]; then
                echo "[New x $COUNTNEW]"
		fi

        fi
}

function ren_file_check(){
        if git_dir=$(git branch 2> /dev/null | grep '*' ); then
                COUNTREN=`git status |  grep "renamed:" | wc -l| sed -e 's/^[ \t]*//'`
                if [ $COUNTREN -gt 0 ]; then
                echo "[Renamed x $COUNTREN]"
                fi

        fi
}


function git_hash(){
	if git_dir=$(git branch 2> /dev/null | grep '*' ); then
		echo "[`git log -1 --oneline | cut -d" " -f1 `]"
	fi
}

function gitfyPrompt(){
	if updatePrompt=$(git branch 2> /dev/null | grep '*' ); then 
	echo "   ###############################################"	
	echo "   #            Welcome to Git Console           #" 
	echo "   #   Use restorePrompt to restore your prompt  #"
	echo "   ###############################################"
	PS1="\[\e[1;31m\]Git-Console \[\e[0m\] \W : \$(new_file_check)\$(ren_file_check)\$(git_status)\$(git_untracked)\$(parse_git_branch)$ "
	else 
	echo "WORKS ONLY IN GIT REPO"
	fi

}



function restorePrompt(){
	echo "   ###############################################"
        echo "   #               Exiting Git Console           #"
        echo "   ###############################################"

PS1=$OLDPS1
}

gitfyPrompt

This really saves tons of time and is pretty handy for a quick reference.

_________________________________
Hitesh Bhatia
Mail LinkedIn,Facebook,Twitter
_________________________________
Posted in git

Git Bisect : Find that DAMN Commit!!!

Posted by on September 24th, 2012

While working on a project with a team, there is a chance that once in a while erroneous pieces of code (bad programming, wrong conflict resolution etc) creep in. Now wading thorugh individual commits looking for a specific line in a file that looks suspicious can be hard work and takes a lot of time.

I was in one of these situations recently and decided early on that rather than take the Brute -Force approach of wading through each of those files, i’d rather use something that GIT already provides …. GIT BISECT

So lets find that commit in 5 simple steps and kick it’s a$$. First thing is to start it up …

1) Fire up the engines …
git bisect start

This will start the Bisect process within the current branch.

2) Define the range at which your target resides ….

Next we need to define the start and end points in which to search for the bad commit..
Find the commit for which the code is working as needed and mark it as ‘good’

git bisect good  

After that find the commit for which the code  does not work as expected and mark it as ‘bad’

git bisect bad 

The good commit will always precede the bad commit*. On doing this, GIT would find the middle most commit between the 2 commits marked above, display the commit details on console and checkout that version .. all in one go :)

3) Fire …

Now the next step is to simply run that checkout version and see if it works accordingly. If it does mark it as

git bisect good

else

 git bisect bad 

On doing this git would now traverse between the last commit marked as ‘good’ and ‘bad’ and find out the middlemost and checkout that version.

4) Reload ….

Repeat step 3 until you it spews out the commit that was causing the error, until you see something like

5) Turn off the engine..

Once that is done all you need to do is

 git bisect reset

to stop the engine ..

* Additional Notes

A good commit will always precede a bad commit because we are finding the buggy code/commit and not the one where the code has been fixed. So git assumes that the code is still error prone and we are searching for the same.

To review what all has been accomplished in this process of marking good/bad you can hit git bisect log to view a list of commits analysed

If you know for sure that a certain commit is not the one, you can skip it to speed up the process by issuing a git bisect skip [commit] command. It can also skip a range of commits using git bisect skip [commit]… [commit]

Hope this helps …

Manoj Mohan
manoj[at]intelligrape[dot]com

Tags: , ,
Posted in git

Migrating a Git repository from one server to another.

Posted by on September 18th, 2012

Recently, I had to migrate one of the git repository from our local git server to Github along with all the branches, tags etc. Since ours is a big project and with many branches, adding second remote and pushing master branch was not an option. And with Git it’s a very simple three step process.

1) Clone bare structure of an existing repository with full source.

git clone --bare --mirror gitrepourl.git repo.git 

The option –bare will make a bare repository with the specified name that is “repo.git” in this case.And the option – mirror will set up a mirror of the source repository, it will not only clone branches of the source but also remote-tracking branches,tags etc

2) Step into folder created.

cd repo.git 

3) Push complete mirror to another git server.

git push --mirror gitrepourl 

And it’s done, a git repo migrated from one server to another.

_________________________________
Hitesh Bhatia
Mail LinkedIn,Facebook,Twitter
_________________________________
Posted in git

Using Git Rebase

Posted by on January 22nd, 2012

Working on a cool project, doing cool and unusual stuff has its own charms and challenges. For doing cool things, you need cool tools to play with and Git surely is one of the coolest ones around. One of the many powerful features of git is rebase.

While working on a large project, you almost always develop your feature on a new branch, and for a large enough feature/requirement, It could take up to month or more to deliver it.

Lets consider a scenario where you need to begin on a new feature and you create a separate branch,(coolNewStuff) , off your main integration branch, (master).

New Branch from master

While you were working on the stuff, other guys in your team were pushing and integrating their stuff into the master branch. As a result master branch moved ahead and there were loads of commits and other stuff added to it.

Now before pushing your cool stuff into master, you would need to pull in the changes in the master to your current(coolNewStuff) branch. You could easily do that using

git pull origin master

Resolve conflicts. commit changes and merge this branch with master.

Nothing wrong with that actually, except that it creates a lot of intermingled commits in the branch, and it won’t give a clear roll back point.

What you actually want to do is put your work on top of the existing master branch as a separate commit so that you get a clear roll back point in case something goes wrong.

You want your changes of coolNewStuff branch on top of current master head, you don’t want master on top your coolNewStuffBranch.


Enter Rebase.

What rebase allows you to do is rewrite the history of your branch. You can actually pull in the changes from master branch place them above the master branch, you branched out off  (some 30-45 days back) and then place all the stuff you developed (all commits you made since the day you branched off) on top of this new pulled in changes from master. So, this looks like…

All you need to do is on the coolNewStuff branch call

git rebase master

This will start your rebasing process. It will basically collect the changes you made since you branched out of master to another temporary location, merge the old coolNewStuff (which was same as the master at the time you branched off) with the new changes on the master and then places your changes on top of it.

This process rewrites the history of the branch.

If you get conflicts. resolve the conflicts and add the files back

git add fileName

Continue with rebase

git rebase --continue

Do a git log and see that your changes are on top of the latest changes of master branch.

Now You won’t be able to push the changes to coolNewStuff branch as the history of branch has been rewritten.

On doing git status you would get a message saying

Your branch and ‘origin/coolNewStuff’ have diverged

You will need to remove your remote branch

git push origin :coolNewStuff

and push again. Do remember to notify other guys who are working on the coolNewStuff branch to delete their local coolNewStuff branch and fetch the new coolNewStuff branch.

Now when you merge this branch with master you will see that your changes are on top of the recent stuff on master and you can easily roll back the stuff in case something goes wrong.

Hope this helps.

Sachin Anand

email : sachin[at]intelligrape[dot]com

twitter : @sachin__anand

Posted in git

Creating GIT Alias

Posted by on December 30th, 2011

Since Git is awesome. It also provides functionality of making aliases.
Example

git config --global alias.co checkout 

Here we created co as an alias for checkout (All the aliases that are created goes into .gitconfig file under home folder). Now to checkout a branch named testBranch, We can also write

git co testBranch
Switched to branch 'testBranch'

Here are couple of interesting git aliases that we can make

1.git config –global alias.undo ‘reset –hard’

Now if we write “git undo” then any of changes after my last commit will be removed.

2.git config –global alias.cleanup = ! git fsck && git prune && git gc

In this Command we have used exclamation mark (!), this indicates that these commands would be running on terminal.
And in git if I want multiple command to be running one after another we use double ampersand (&&) (We cannot use semicolon as we would usually do in terminal).
This command will run git fsck (file check), git prune (to clean dangling commits/blobs) and git garage collection

Number of git alias that can be made are endless all it needs is little creativity.

_________________________________
Hitesh Bhatia
Mail,LinkedIn,Facebook,Twitter
_________________________________
Posted in Grails

GIT Maintenance

Posted by on December 30th, 2011

Since we use git numerous times a day over and over, hence needs maintenance. There are few commands that will help you to keep our git healthy. If you feel that you git has somewhat slowed down, these would do the trick for you.

Since ours is a pretty big project . I run it once a week to make sure my git is healthy.

1.git fsck

This commands helps to identify any corrupted, unreachable (dangling blobs) objects in your database.
Example

git fsck
dangling commit 652424f02c17b5d881158a625f1a34f6039dc231
dangling commit 7e6510c2663530d949ea9fb67900496dcf5cbc4c
dangling commit 177864469ea87564ade9101106d5aa85cceb0d29
dangling commit 848665007bc412910b68dc3e528e74c23ce1f165
dangling blob dfa6756511b525996946de84fa7f67b6f9a0d32f
dangling blob e7f8f1145c7e739a6ffd8806a6d26d60f0443897
dangling blob f1f905a5eb35724622249f25f6d9ef7c646e4283
dangling blob 221417781e017cf02f90b872aea80f30ed41787c
dangling blob c1356b24fb2a4ea453dba87ed4058e7a48e97dce
dangling blob cb6fe3d5321b7b152a8781541bbc6132c59b9c94
dangling blob 3ce2e76cd54f0c8265ec6167f78d5dfe71c2242d
dangling blob daf073729960c40a44c5291c745092445bb2c3b0

2.git prune
With git fsck, we identified some of dangling commits and blobs, now to remove them we use git prune.
Now After running git prune, If I run git fsck again, my git would be cleaner than before and healthy.

git fsck
dangling commit 177864469ea87564ade9101106d5aa85cceb0d29
dangling commit 848665007bc412910b68dc3e528e74c23ce1f165

But it still has some dangling commits.This is where git’s garbage collection comes in play.

3.git gc (Garbage Collection)
This command will gathers up all the loose objects and places them in packfiles. And removes objects that aren’t reachable from any commit. This command will save some space and speed up many of git commands.
Example

git gc
Counting objects: 121775, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (18239/18239), done.
Writing objects: 100% (121775/121775), done.
Total 121775 (delta 76189), reused 120913 (delta 75659)
Removing duplicate objects: 100% (256/256), done.

Output of this commands tells several things to us , that is compressed 18239 objects for us out of total 121775 objects. And it also removed 256 duplicate objects. This way my git stayed healthy.

_________________________________
Hitesh Bhatia
Mail,LinkedIn,Facebook,Twitter
_________________________________
Posted in Grails

Git – How to Change Master Branch

Posted by on August 29th, 2011

While working on Git with a big team, there are chances that a situation might arise when you want to set some other branch as master branch.Recently we were in a same situation. Several of branches were merged to master branch. And unfortunately one of the branches merged was created from an unstable branch. Making our master branch unstable. And we cherry-picked all stable changes to masterTemp branch.So we landed in a situation where we wanted masterTemp branch as master branch.And Here is how we did it.

1 ) Renamed master branch to oldmaster.

git branch -m master oldmaster

Now there is no master branch on my local machine.

2) Renamed my masterTemp branch to master

git branch -m masterTemp master

The branch which was named masterTemp on my local machine is now master

3) Delete the branch from remote

git branch -rD master

4) Push the new master branch to remote

git push --force origin master


And its done.We had to perform step 3 and 4 because git does not allows us to delete master branch from remote. i.e git push origin :master wont work. Hence we forcefully pushed out new master branch to remote. Plus anyone who is working on same repo should delete their master branch , take git pull and create new master branch.
(i.e git branch -d master; git branch -rD master;git pull ; git checkout -b master origin/master )

_________________________________
Hitesh Bhatia
Mail,LinkedIn,Facebook,Twitter
_________________________________
Posted in Grails

Using git diff feature on Github

Posted by on June 7th, 2011

Hi Folks,

Recently I came across a cool way to compare differences between two branches, two tags, or between two commits on Github. Many a times in our project we have to thoroughly see what has been a specific change in the code base before we push it on our production branch.

Here is how you can view the differences in commits:

On the Github, go to the Source view of your project. You will see a link named ‘Branch List’. Once the page opens you can see a list of all the remote branches. Hit on the Compare button in front of any of the available branches to see the difference between two branches.

Now note the URL in the address bar. It should end with something like ‘…/compare/<x>…<y>’ where x and y are separated by three dots(…) and their values could be project’s branch names

Isn’t it good?

Well, Git’s (read about git diff) and Github’s goodness does not stop just here. Instead of branch names as the values of x and y, you can also put two different commit hashes or tag names to view the differences in the code-base. More so, the commit hashes do not have to belong to the same branch. So you can pretty much compare your code’s current snap-shot with any of its past snap-shot irrespective of branch or a tag or a commit hash.

Hope this helps someone.

Abhishek Tejpaul
abhishek@intelligrape.com
[IntelliGrape Software Pvt. Ltd.]

Posted in System

git branching model: choose branches for deletion – see whats remaining for the merge

Posted by on March 4th, 2011

This post is for people who are already familiar with Git and work on multiple branches (esp. feature branches).
By practice, feature branches are the branches created from a root branch (master or any other as per your branching model) and once feature is complete/tested – they are merged back into the same root branch.



Working in such a manner is pretty nice and clean. But things start getting messy if we don’t delete the branches on time (esp. after merging into root branch). In that case when we run command –

     git branch

It shows us zillions of branches and we start getting feeling to get a rid of all futile branches. But we don’t know which branches are already merged and which are still under progress or yet to be tested.

Solution to this problem:

      # I am assuming that your root branch is master
      git checkout master
      git branch --merged


Above command will show you all branches which are already merged into the current branch (master branch in this case). This means you can delete these (feature) branches now.
For deleting a branch on local: git branch {-d | D} ‘feature-branch-1′
For deleting from remote: git push origin :feature-branch-1
I assumed that origin is your remote.

Similarly if you run

      git branch --no-merged

It will give a list of branches which are yet to be merged.



Question: I got a list of branches which are not merged yet. Now I want to see the commits in particular branch which are not merged into root branch yet?
Solution:

      git log --pretty=oneline maser..branch1

Again, master is your root branch. And branch1 is your feature branch having commits yet to be merged.

Your comments are always Welcome. Please post if you have any!



Cheers!
Salil Kalia
Salil [at] IntelliGrape [dot] com
Twitter LinkedIn

Posted in Grails

GIT –pretty

Posted by on February 18th, 2011

git log is one of most useful commands to see information about commit , author , date and subject(comment)  while using GIT.This displays information in blocks and hardly 5 – 7 can be listed on normal screen size. But git provides –pretty option , so that we can format the output of git log;

Here are some ways to do that

git log --pretty=oneline

Displays just a single line log ,which includes a commit-hash and Subject(Comment).something like this

d1fc23c1edfd2d4ffe8ef5a873adff9321cde909 comment 3
a8560c814ece4e03d39164885f44e0c5cb749928 comment 2
db6195c635179b3556c41e2a974829c7e101ef51 comment 1

some other predefined options are raw,fuller,full,medium and short. Since Git is Cool we can also use some custom formats.Like

git log --pretty=format:"$h"

will give abbreviated hash of committs(Where %h defines abbreviated hash).And it would be something like

d1fc23c
a8560c8
db6195c

Which is not quite useful , to make it better lets first see other options

  • %H  – Commit hash
  • %s  – Subject
  • %h  – Abbreviated hash
  • %an – Author name
  • %ae – Author e-mail
  • %ad – Author date
  • %ar – Author date, relative



While using “format” with option “–pretty” we can also specify string inside quotes.Like

git log --pretty=format:"%h was committed by %an , %ar"

Would give something like

d1fc23c was committed by hiteshBhatia , 5 months ago a8560c8 was committed by hiteshBhatia , 5 months ago db6195c was committed by hiteshBhatia , 5 months ago

To make this more useful we can make slight changes to string passed to “format”

git log -3 --pretty=format:"%h ||  %an  ||   %s  (%ar)"

Which will give us commit hash , author name , subject  and relative date inside paranthesis.And -3 here is number of logs .So that his whole screen is not cluttered.This is the way I like to use it.

d1fc23c ||  hiteshBhatia  ||   comment 3  (5 months ago)
a8560c8 ||  hiteshBhatia  ||   comment 2  (5 months ago)
db6195c ||  hiteshBhatia  ||   comment 1  (5 months ago)



To explore more visit. git grep manual page or the git community book which is maintained by Scott Chacon

_________________________________
Hitesh Bhatia
Mail,LinkedIn,Facebook,Twitter
_________________________________
Posted in System