Vous êtes sur la page 1sur 6

ne t .t ut splus.

co m

http://net.tutsplus.co m/tuto rials/to o ls-and-tips/git-tips-fro m-the-pro s/

Git Tips From the Pros

Chris Kelly

You're already using source control f or managing your code, right? You might even be using your SCM as the central piece of your workf low, like we do at New Relic. In this article, we're not going to review the basics of source control management, regardless of which one you use. Let's just assume that you already know how to get around. What we are going to cover is how the pros use git. We'll take a look at some of the advanced f eatures and workf lows that you might not already be f amiliar with. Hopef ully, youll walk away with your mouth agape at the sheer possibilities that git provides!

If you are anything like me, you love to explore how other developers work.

For the uninitiated, or those coming f rom another SCM, Git is a distributed version control system. It is f ree and open source, has a tiny f ootprint, and can f it within the workf low that suits you best. Generally, it doesn't f orce you to work in a particular way, which means there are many dif f erent methodologies on how to use its f eatures, like staging areas, branching and tagging releases. If you are anything like me, you love to explore how other developers work. So get ready to start modif ying your .git cong, because you're in f or a treat. Lets see how the pros use git.

Stage Your Changes in Hunks

You are likely familiar with accidentally modifying a single file for two different reasons without committing in between.

You are certainly f amiliar with adding f iles to the staging area with the appropriately named add command. And you are likely f amiliar with accidentally modif ying a single f ile f or two dif f erent reasons without committing in between. So you will sure have a git log f illed with messages like "Edit X and change unrelated Y". If this sounds like your workf low, then interactive adding is your new best f riend. Interactive adding, or adding a patch, walks you through your changes one hunk at a time. When you add a f ile with the -p command, you will be prompted at each logical change (i.e., successively edited lines will be grouped together). T here are a number of choices you can make on each hunk, f rom splitting the current hunk into smaller ones, skipping a hunk, or even manually editing it. Use the ? option to see a complete list of commands. Getting started with staging hunks is as simple as: 1 git add -p <FILE>

Checkout Your Last Branch

As a good coding citizen, when you come across something that needs a quick f ix or cleanup, you should probably take a moment to change it. But if you are using a heavy f eature-branch workf low, then you don't want that unrelated f ix in your f eature branch. T his means you'll need to st ash your current changes, change to your master branch and then make the f ix there. Bouncing around between branches can be tedious, but, luckily, there is a quick shortcut f or switching to your last branch. (via Z ach Holman) 1 git checkout -

T his syntax should look pretty f amiliar to *NIX users. T he cd command has a similar shortcut (cd -) that will jump to the last directory you were in. Youll never have to remember what you named that f eature branch when you need to switch back; just git checkout -.

Show Which Branches are Merged (or not)

When working with f eature branches, you can quickly create so many that clutter up the output of git branch --list . Every now and again you want to get rid of the branches that have made it into master. But you probably have a quick pause bef ore you git branch -d <BRANCH>, but with the below commands you can conf idently delete them without a second thought. (via Z ach Holman) If you want to see which local branches you have that are merged into the branch you are currently on, then all you need is: 1 git branch --merged

T he reverse is also available. Show which branches haven't been merged into the currently selected branch with: 1 git branch --no-merged

Mash this up with a couple easy UNIX tools and you can quickly delete everything that has already been merged: 1 git branch --merged |xargs git branch -d

Grab a File f rom Another Branch without Switching Branches

Let's say that you're experimenting with some ref actorings, and you have a f ew branches that have various changes you've made. If you have changes in a f ile in some distant branch that you want to bring into your current working branch, then you could do any number of steps. Without the below tip, you'd probably stash your current changes, switch branches and grab the f ile contents you want to change, switch back (with git checkout - of course) and make your edits. Or you could simply checkout just that f ile which will merge it into your current branch (via Z ach Holman): 1 git checkout <BRANCH> -- pat h/t o/le.rb

Git Branches Sorted by Last Commit

So you've got the cluttered branch list that we talked about bef ore; some of those you've cleaned up with the --merged f lag. But what about all those other branches? How do you know which ones are usef ul or entirely out of date? T he for-each-ref command will output a list f or each branch and show the ref erence inf ormation f or the last commit. We can customize the output to include some usef ul inf ormation, but, more importantly, we can sort the list by date. T his command will give us a list of branches with the last commit message and committer, sorted in descending date order. (via Rein Henrichs) 1 git for-each-ref --sort =-commit t erdat e --format = '%(commit t erdat e:short ) %(refname:short ) [%(commit t ername)]'

While you could type this command each time, I highly recommend making it an alias and save yourself some serious headaches. 1 git cong --globalalias.lat est "for-each-ref --sort =-commit t erdat e --format ='%(commit t erdat e:short ) %(refname:short ) [%(commit t ername)]'"

People in Glass Houses Shouldn't Use Git Blame

Or at least they shouldn't use git blame without one of the options f lags below. Git blame is powerf ul; it's basically like using science to prove you're right. But be caref ul, many changes are superf icial and to f ind the real source of the in-question code takes a bit more hunting. T hings like removing white space, moving text to new lines, or even moving text f rom another f ile can be ignored to get to the original author of the code much easier. Bef ore you git blame someone, make sure you check one of these: 1 2 3 git blame -w git blame -M git blame -C

Find a String in the Entire Git History (and Remove It)

From time to time, you need to hunt down a line of code you know you wrote but just can't f ind. It could be stuck in some distant branch, deleted a long long time ago, or hiding in plain site; but either way you can f ind any string in your entire git history by mashing up a f ew commands. First, we're going to get a list of all commits, and then grep each of them f or our string. 1 git rev-list --all |xargs git grep -F'<YOUR STRING>'

You probably have a f riend who has accidentally committed sensitive data to a repo: access keys, passwords, your grandmother's secret marinara recipe. T he f irst thing they should do is change their passwords and revoke access with those keys (and apologize to your grandmother). Next, you'll want to hunt down the of f ending f ile and remove it f rom the entire git history, which sounds f ar easier than it

actually is. Af ter this process is complete, anyone that pulls in the cleaned changes will have the sensitive data removed as well. Forks of your repo that do not merge your upstream changes will still contain the compromised f iles (so don't skip changing passwords and revoking access keys). First, we'll rewrite the git history f or each branch, removing the f ile with the sensitive data. 1 git lt er-branch --index-lt er'git rm --cached --ignore-unmat ch <FILENAME>' --prune-empt y --t ag-name-lt ercat -- --all

Add the f ile to .git ignore and commit to update .git ignore. 1 2 3 echo <FILENAME> >> .git ignore git add .git ignore git commit -m"Add sensit ive <FILENAME> le t o git ignore"

Since we are rewriting history, you'll need to f orce push the changes to your remote. 1 git push origin mast er --force

T he compromised f iles still exist in your local repo, so you'll need to do a f ew clean-up tasks to purge them entirely. 1 2 3 4 rm -rf .git /refs/original/ git reog expire --expire=now --all git gc --prune=now git gc --aggressive --prune=now

Your f riend's repo should be f ree of sensitive data and you'll be the hero f or helping them with your pro git knowledge. (via StackOverf low and GitHub)

Ignore Changes in a Tracked File

Working with someone else's code in your environment can mean that you need to make any number of conf ig changes to get the application running. It is all too easy to accidentally commit a change to those conf igs that were meant exclusively f or your environment. So, instead of always watching out f or those f iles and having them linger in the "modif ied" staging area, you can simply tell the git index to ignore changes to that f ile. You can think of this somewhat like a git ignored f ile that stays with the repo. (via Arnaud Coomans) 1 git updat e-index --assume-unchanged <FILENAME>

Zero Out a Branch's History

Sometimes starting f rom scratch is exactly what you need to do, f or any number of reasons. Maybe you've

inherited a codebase that you can't ensure is saf e to open source, maybe you're just going to try something entirely new, or maybe you're adding a branch that serves a separate purpose that you want maintained with the repo (like GitHub Pages). For this case, there is a very simple way to create a new branch in your repo that essentially has no history. (via Nicola Paolucci) 1 git checkout --orphan <NEWBRANCH>

Aliases You Can't Live Without

Stop wasting time typing long commands and make yourself a few useful aliases.

No discussion of git would be complete without talking about various aliases that will literally save you minutes a year in saved keystrokes. Stop wasting time typing long commands and make yourself a f ew usef ul aliases. Aliases can be made by adding them to your .gitconf ig f ile or using the command-line git cong --global alias.<NAME> "<COMMAND>". Below are just a sample of alias that you can use as a springboard f or ideas. co: with a f eature branch workf low, you'll be moving between branches regularly. Save yourself six characters every time. 1 co = checkout

ds: it is always best practice to review the changes you're going to commit bef ore making the actual commit. T his allows you to catch typos, accidental inclusion of sensitive data and grouping code into logical groups. Stage your changes and then use git ds to see the dif f of those changes. 1 ds =di --st aged

st: you should be pretty f amiliar with the verbose output of git status. At some point you'll want to skip all the f ormality and get down to business. T his alias shows the short f orm of status and includes the branch details. 1 st = st at us -sb

amend: did you f orget to include a f ile with your last commit, or maybe you had one tweak you needed to make? Amend the staged changes to your last commit. 1 amend = commit --amend -C HEAD

undo: sometimes, amending your last commit isn't enough and you'll need to undo it instead. T his alias will step back one commit and leave the changes f rom that commit staged. Now you can make additional changes, or recommit with a new message. 1 undo = reset --soft HEAD^

ls: working on a codebase with a group of developers means trying to keep up with what people are working on. T his alias will provide a one line git log including date and committer name. 1 ls = log --pret t y=format : "%C(yellow)%h %C(blue)%ad%C(red)%d %C(reset )%s%C(green) [%cn]" --decorat e --dat e =short

standup: this alias is great f or reviewing what you worked on yesterday f or any type of daily standup, or just to ref resh your memory in the morning. 1 st andup = log --since'1 day ago' --oneline --aut hor <YOUREMAIL>

graph: a complex git history can be dif f icult to review in a straight line. Using the graph f lag shows you how and when commits were added to the current branch. 1 graph = log --graph --pret t y=format ':%C(yellow)%h%Cblue%d%Creset %s %C(whit e) %an, %ar%Creset '

In Closing
Git can be both amazingly simple and mind-blowingly complex. You can start with the basics and work yourself into more complex graph manipulation over time. T here's no need to grok all of it bef ore you can use it. T he command that will be most powerf ul as you learn is man git -<command>-<name>. Try using it bef ore you ref er to Google f or an answer.