Live data from Hacker News

Git tips from the trenches

ochronus.com

11–20 of 47 posts

Re: Git tips from the trenches

#11
My personal favorites:

> git-rerere

will prevent you from getting stuck resolving the same merge conflicts repeatedly, by remembering how you resolved them the last time.

Also, instead of passing any arguments to "git-log", I usually just use "tig", an ncurses display of the commits: https://blogs.atlassian.com/2013/05/git-tig/

Finally, when I was first taught Git, I was told that I should never need to comment out code again. I never understood how this was possible until I learned how to use 'git add -p' and 'git rebase -i' in tandem.

Re: Git tips from the trenches

#13

My personal favorites: > git-rerere will prevent you from getting stuck resolving the same merge conflicts repeatedly, by remembering how you resolved them the last time. Also, instead of passing any arguments to "git-log", I usually just use "tig", an ncurses display of the commits: https://blogs.atlassian.com/2013/05/git-tig/ Finally, when I was first taught Git, I was told that I should never need to comment out c…

> git-rerere

> will prevent you from getting stuck resolving the same merge conflicts repeatedly, by remembering how you resolved them the last time.

That's on by default these days; if you re-do a merge and git finds the conflict in rerere, it'll automatically use the saved resolution rather than inserting conflict markers.

Re: Git tips from the trenches

#14

I'd like to mention a feature that's been making my life oh so much easier: git bisect If you're ever looking for "the commit that broke feature XYZ", git bisect is your trusty minion.

Git bisect is wonderful. TortoiseHg also has a bisect command in the Workbench. (But command line hg doesn't seem to have it.)

Here's a tip for anyone using bisect with a Rails app (or any system that uses database migrations):

I do a rake db:migrate after a pull to make sure the database schema is up to date. So the first time I used git bisect on a Rails app, I figured I would use db:migrate after each bisect step.

On this project, as in many Rails projects, schema.rb is checked into git along with the migration files.

Somewhat mysteriously, after some of the bisect steps and db:migrate operations I was seeing an uncommitted schema.rb that was different from the one in git. That shouldn't have happened, I thought.

I finally figured out what perhaps should have been obvious: db:migrate was working fine when bisect moved forward in the history, but it was messing up when bisect moved backward across a migration.

Rails experts will know what went wrong here: After bisect moved backward, the db:migrate had no way of knowing which database changes to reverse, because the migrations that were now in the "future" relative to the latest checkout were removed before I ran the migrate.

I fixed it by using db:reset instead of db:migrate, at least after bisect moved backward in time.

Another bisect tip: Sometimes it can be advantageous to run the equivalent of a bisect manually instead of automatically. For example, you may have some pretty good hunches about which commits may or may not be related to the problem. Or you may want to do a db:migrate before moving back in time to avoid the problem I described above, and by doing the checkouts manually you will know which migrations to reverse before doing the checkout.

In my case, I was looking at a somewhat intermittent bug. As I narrowed down the possible bad commits I wanted to keep track of the specific ones I'd looked at, and git bisect doesn't do this for you. So each time I checked out a different commit I created a local branch first on the commit I'd determined to be (likely) good or bad, giving them names like Good1, Good2, Bad1, Bad2, etc.

This way I could just look at the history as I went along and see at a glance which commits I'd investigated so far.

I guess this trick would work with git bisect as well - just create a local branch before each bisect step.

There may be some better way to do this, but it worked pretty well for me.

BTW, I use SmartGit/Hg and really like it. I know everyone likes their command lines, but I greatly prefer a visual way of working with a source code repo.

Re: Git tips from the trenches

#15
post #5

Worth it just for this: git rev-list --all | xargs git grep ' '

`git grep` is such a weird command: it defaults to being pointlessly redundant with `grep` (with a few default ignores). Contrast with hg grep, which defaults to searching the whole history (although it stops after finding the historical first match, `—all` will display all matches).

Re: Git tips from the trenches

#16
post #2

> $ git branch --merged | xargs git branch -d does this actually work? `git branch --merged` for me also returns '* master', which when xarg'd would include the '*' and also 'master'. I don't want to delete master, and I certainly dont want to delete * if it globs. EDIT : made this into a code block as I have no idea how to make asterisks display.

I'm not sure, but I can tell you how I'd find out. I'd clone the repo to a different directory and try it out in that test environment. Then delete the it when I'm done. #gitFTW

Re: Git tips from the trenches

#17
post #6

I liked this one: git blame -w Ignore the whitespace if a block was [un]indented, attribute to original author instead of person re-indenting due to control structure change around block.

The truth is that command-line blame is a pain in the ass. Blame is great for finding out where a piece of code comes from, but (especially on big projects with many contributors) there's a lot of small churn with code being moved around, slightly altered, etc… CLI blame requires an extensive danse of "blame to find out last change before $(rev:tip)" "log with patch to find out if it's the change I'm looking for" "get previous revision", rinse and repeat until step 2 yields a match.

And for all the GUIs available, most of them either don't even touch blame, or just return the output of the CLI blame command. The only GUI I've seen so far which makes it easy to traverse history through blame is for bazaar (qblame/qannotate).

Re: Git tips from the trenches

#19
My git shortcuts (in my bash_profile):

alias g='git'

alias pull='git pull origin master'

alias push='git push origin master'

alias gc='git commit -m $1'

alias ga='git add -A'

# Adds all and commits (gg 'Commit message')

function gg () {

  git add -A;

  git commit -m "$1";

  git push origin master;
}

alias gs='git status'

alias gd='git diff --color'

alias gdc='git diff --cached'

alias gstat='git diff --stat'

Re: Git tips from the trenches

#20

I'd like to mention a feature that's been making my life oh so much easier: git bisect If you're ever looking for "the commit that broke feature XYZ", git bisect is your trusty minion.

Git bisect is wonderful. TortoiseHg also has a bisect command in the Workbench. (But command line hg doesn't seem to have it.) Here's a tip for anyone using bisect with a Rails app (or any system that uses database migrations): I do a rake db:migrate after a pull to make sure the database schema is up to date. So the first time I used git bisect on a Rails app, I figured I would use db:migrate after each bisect step.…

> TortoiseHg also has a bisect command in the Workbench. (But command line hg doesn't seem to have it.)

It does, since v1.0 (so about 6 years ago): http://www.selenic.com/mercurial/hg.1.html#bisect

As is usually the case, it's not active by default.

> Rails experts will know what went wrong here: After bisect moved backward, the db:migrate had no way of knowing which database changes to reverse, because the migrations that were now in the "future" relative to the latest checkout were removed before I ran the migrate.

And you can't even do that automatically, because git doesn't have a pre-checkout hook (assuming bisect uses checkout internally, which I'm not certain of)

Post reply on HN