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.…
Git tips from the trenches
21–30 of 47 posts
Re: Git tips from the trenches
#22git log --graph --abbrev-commit --decorate --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all
(Kudos to the unremembered internet person who posted this in the first place)
Re: Git tips from the trenches
#23for k in `git branch -a|perl -pe s/^..//`;do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k|head -n 1`\\t$k;done|sort -r
Re: Git tips from the trenches
#24Worth 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
#25Worth it just for this: git rev-list --all | xargs git grep ' '
Re: Git tips from the trenches
#26git status --untracked=no
This shows only files that are tracked. I tend to do a lot of work which leaves files that I don't want to check in lying around in my git repo, this eliminates these and lets me see exactly what I have been working on. The slight caveat to this is when you are working on a new file that you have not yet checked in ever.
This goes hand in hand with:
git add -u
Which only adds untracked files. With aliased commands this usually results in a flow like this:
> git stu
> git adu
Re: Git tips from the trenches
#27Earlier quoted context omitted.
`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).
"git grep" is a lot faster than grep in a large codebase. One obvious reason is that "git grep" ignores non-checked-in files in the project directory. But I also notice a speed difference even when the project directory is clean.
On my machine, using postgres's repository, I get the following:
> time git grep foo > /dev/null
0.22s user 0.25s system 151% cpu 0.312 total
> time ag foo > /dev/null
0.85s user 0.19s system 174% cpu 0.596 total
> time grep foo $(git ls-tree --full-tree --name-only -r HEAD) > /dev/null
0.13s user 0.10s system 93% cpu 0.255 total
grep's faster than git grep. In fact, grep is already as fast as git grep just ignoring .git: > time grep foo -r . --exclude-dir=.git > /dev/null
0.15s user 0.16s system 91% cpu 0.338 totalRe: Git tips from the trenches
#28I'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.…
At that point, git will check out the "middle" revision and you can do whatever's needed to decide if you should mark it as either good or bad with 'git bisect [good|bad]'. This will check out the new "middle" - lather, rinse, repeat until you get down to one commit.
When you're done, 'git bisect reset' will take you back to the present.
While this isn't quite as quick as the automated version, it's a lifesaver when tracking down a regression in a library whose dependencies have changed radically (finding what b0rked your tests between Rails 3.0 and 4.0, for instance).
Re: Git tips from the trenches
#29Earlier quoted context omitted.
"git grep" is a lot faster than grep in a large codebase. One obvious reason is that "git grep" ignores non-checked-in files in the project directory. But I also notice a speed difference even when the project directory is clean.
By default grep is going through all of the .git directly, which is the part `git grep` filters out. `ag` also filters them out (and is only slightly slower than git grep by default, with all the colors and stuff), or you can tell grep to only check relevant files with e.g. `grep $PATTERN $(git ls-tree --full-tree --name-only -r HEAD)`. On my machine, using postgres's repository, I get the following: > time git grep…
I ran a test on a large repository and here are my results. The repository was Hadoop, and is available from git://github.com/apache/hadoop-common.git.
cmccabe@keter:~/hadoop4> du -cksh .
375M .
375M total
sudo -- sh -c 'sync ; echo 3 > /proc/sys/vm/drop_caches'
cmccabe@keter:~/hadoop4> /usr/bin/time git grep 'class TestDefaultNameNodePort'
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDefaultNameNodePort.java:public class TestDefaultNameNodePort {
0.11user 0.34system 0:00.74elapsed 61%CPU (0avgtext+0avgdata 60512maxresident)k
260256inputs+0outputs (19major+9718minor)pagefaults 0swaps
sudo -- sh -c 'sync ; echo 3 > /proc/sys/vm/drop_caches'
cmccabe@keter:~/hadoop4> /usr/bin/time grep -rI --exclude .git 'class TestDefaultNameNodePort' *
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDefaultNameNodePort.java:public class TestDefaultNameNodePort {
0.13user 0.56system 0:02.40elapsed 29%CPU (0avgtext+0avgdata 5584maxresident)k
252792inputs+0outputs (2major+414minor)pagefaults 0swaps
So you can see that it is faster, even when excluding the .git directory.Running grep a second time without clearing the cache gives a bogus result:
cmccabe@keter:~/hadoop4> /usr/bin/time grep -rI --exclude .git 'class TestDefaultNameNodePort' *
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDefaultNameNodePort.java:public class TestDefaultNameNodePort {
0.03user 0.04system 0:00.08elapsed 97%CPU (0avgtext+0avgdata 5584maxresident)k
0inputs+0outputs (0major+416minor)pagefaults 0swaps
This is because the data is all in the page cache at that point, so we're not actually accessing the disk.I was curious about the true source of the speedup, and so I checked the output of the 'perf' tool. git had 1,922 CPU migrations, whereas grep had 52. Following up on this, you can see that git is spawning a bunch of threads, whereas grep only has one thread.
cmccabe@keter:~/hadoop4> strace -f -e trace=clone git grep 'class TestDefaultNameNodePort' 2>&1 | grep -c '] +++ exited with '
8
cmccabe@keter:~/hadoop4> strace -f -e trace=clone grep -rI --exclude=.git 'class TestDefaultNameNodePort' * 2>&1 | grep -c '] +++ exited with '
0
I also think git might be cheating and using a simpler regex engine than grep, but at this point I got bored. Case closed.Re: Git tips from the trenches
#30My 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…
Agree, tig is awesome and in my opinion the best git GUI (or at least representation). Use the normal commandline tools for commiting/cutting/rebasing/... and tig to see where everything is at!