1. Git script to rebase all child branches following a command

    This script looks at the current status of the DAG to find the children of the current branch, runs an action, then rebases those children. It is particularly useful for users of git-svn, who may find themselves having to rebase all topic branches (and sub-topics which build off those) every time they git svn rebase or git svn dcommit.

    For pure git projects, this is considered by many to be bad form, so use with discretion. People who like a linear history might like it.

    I expect the script, in its current state, will fail in cases where the rebase can’t be done automatically, but for simple day-to-day operations it makes git-svn that bit less painful to use :-)

    I have an alias set up to invoke it with git rar (“Run and Rebase”), so that I can type, for example, git rar svn rebase.


  2. Git alias to get a git commit sha1 from an SVN revision number in git-svn

    This little snippet is useful if you use git-svn — it gives you an alias to get a git commit ID from an SVN revision number. If you work with others who say things like, “I think this problem was introduced in revision 10342” it can come in pretty handy! Copy and paste it into the [alias] section of your global .gitconfig or your project-specific .git/config


  3. Git alias to amend old commits

    git commit --amend is a useful little command for fixing mistakes in log messages just after you’ve made a commit, but sometimes you don’t realise your error until a few commits down the line, by which time it’s too late. You have to reset to the earlier version, amend the commit message, and then rebase all your commits since then on top of the new, amended commit.

    Earlier today, in #git on freenode, somebody who went by the name of constant mentioned that they wanted to do this in one command. Another member of the chat, frogsonwheels, suggested a solution which essentially did as described above in a series of git commands strung together using &&.

    I decided to tidy it up a bit and put it into a git alias, thus:

    Note that this is still doing the rebase mentioned above, it’s just automating the steps a little bit. These means that all the usual warnings regarding rebase apply: don’t run this command on a commit which has already been published. Also, this rebases the currently checked out branch/revision, which means if any other branches have been made based off the amended commit or any commit since, those branches won’t be rebased and you’ll have to rebase them automatically once you’ve done the amend-commit. You can usually tell if this is the case pretty easily by inspecting the output of git log --graph --oneline --decorate.


  4. Bash oneliner: watch a filesize

    Sometimes, when running a long operation modifying a single file, I want to monitor its progress by watching that file’s size increase. Here’s a simple one-liner which will print the incrementing filesize until Ctrl-C is pressed:


  5. Git alias to open all diffs in vim tabs

    This is a handy little alias I’ve been using recently to open all unstaged diffs in a single instance of vim, one tab per file. Add the following to the [alias] section of your ~/.gitconfig:

    Known issues:

    • It requires tpope’s vim-fugitive plugin to work.
    • It only works with unstaged diffs — it would be nice to be able to pass an arbitrary range of commits and see the diffs between them

    Both of the above could be resolved by writing a little script to open all the diffs in vim rather than using fugitive’s :Gdiff command, but for now this little alias does the job nicely.


  6. SVN post-commit hook: email file owner

    It’s a common enough situation: we want SVN to email a notification to developers when somebody modifies a file they are in control of. SVN post-commit hooks let us send an email when the file is modified; but how do we determine to whom that email should be sent?

    I came up with two solutions. Neither is very clever, but they both give a little clue at least. The first looks through the log and determines who has committed changes to that file the greatest number of times. The second looks at the blame log for the file to determine who has modified the most lines in the file. My script just emails both people

    Just copy the script below and call it from your post-commit file to get started. You’ll want to change the value of DOMAIN to match the domain you want to email notifications to. The third parameter is the name of the project, so you can use the script for multiple repositories.

    I just threw this script together so it’s nothing special — if you’d like to make improvements why not fork the gist?


  7. File-specific merge resolution in git

    I’ve been using git-svn for a while now so that I can take advantage of the power and convenience of git without having to bother everyone else on the project (who are all happily using SVN). It was a bit frustrating at first, but once I got the hang of the basic workflow and settled into a routine I started to really like it, and now I don’t think I could ever go back to using the SVN client directly.

    One annoyance I’ve come across multiple times using both SVN and Git is that of checked in binary files. Ideally, we’d only check in the source files and build off that, but in practice this is problematic for a number of reasons. We’d like the non-programmers on the team to be able to build the project without having to have the compiler toolchain installed; we’d like the version of our executable everyone is running to be guaranteed to be the same; and we’d like it to be possible to checkout the project and start running it straight away without having to do a build.

    The problem with this is that we get a lot of merge conflicts on the binary files we’re checking in. Take the executable; programmers rebuild this every time they hit “compile”. It is almost certain that each time you pull, there’ll be a new copy of the executable in the repo that clashes with yours.

    The solution is simple: we always want to accept our version of the executable file. That way the timestamp will be older than the new source files we’ve received from the repo, so when we run make it will pick up on that and rebuild the executable with the new code we’ve just pulled in.

    The problem is, I’ve never found a way to automate that for specific files in the repo. With SVN, the majority of the team use TortoiseSVN as their interface, which doesn’t seem to offer that sort of flexibility. With git, I was aware of the “ours” and “Xours” merge strategies but didn’t know how to apply them only to specific files in a merge. I’d read some tips about adding merge=ours into the .gitattributes file, but it didn’t seem to work.

    Well, after a little bit of digging around on stackoverflow, I found this question, the first answer to which explains how to do exactly that simply and easily. Basically, you have to create a script, which acts as a custom merge driver. Since git’s default behaviour is to leave your copy as-is during a binary merge, all that driver has to do is exit 0:-

    As a convenience, I added a “keep theirs” driver to go with it:-

    Once those scripts are in place, it’s simply a matter of defining them in your .git/config file, and then setting which files should use them using .gitattributes:-

    And that’s it! My merges have become much more pleasant since I set this up.

    If anybody knows how to do this sort of thing using [Tortoise]SVN, I’d love to hear about it in the comments!

    (Note: All the above code samples were copied almost verbatim from the previously mentioned stackoverflow entry. I don’t claim credit for any of it.)


  8. プログラマは、詩人同様に、純粋な思考物からほんの少ししか離れていないところで仕事をする。想像力を発揮することによって空中に城郭を築く。創造のメディアでも、これほど柔軟で、こんなに容易に磨きをかけたり手直しできたり、壮大なコンセプトの構築をこれほどやすやすと実現できるものは、ほんのわずかしかない。
    — フレデリック・P・ブルックス Jr.、人月の神話

  9. thoughtbot:

    This method has a magic number:

    def wait_time @env[QUEUE_WAIT_HEADER].to_i / 1000

    Let’s extract that to an intention-revealing name. We’ll type:

    /1000<Enter> # Find the number we want to extract
    cwmilliseconds_per_second<Esc> # Replace the number with a variable name
    O<Ctrl+A> =...

    Nice vim tip for getting rid of magic numbers in code.

    (出典: thoughtbot)


  10. The program­mer, like the poet, works only slightly removed from pure thought­-stuff. He builds castles in the air, from air, creating by exertion of the imagina­tion. Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structu­res. Yet the program construct, unlike the poet’s words, is real in the sense that it moves and works, producing visible outputs separate from the construct itself. It prints results, draws pictures, produces sounds, moves arms. The magic of myth and legend has come true in our time. One types the correct incanta­tion on a keyboard, and a display screen comes to life, showing things that never were nor could be. … The computer resembles the magic of legend in this respect, too. If one character, one pause, of the incanta­tion is not strictly in proper form, the magic doesn’t work. Human beings are not accustomed to being perfect, and few areas of human activity demand it. Adjusting to the require­ment for perfection is, I think, the most difficult part of learning to program.
    — Frederick P. Brooks, The Mythical Man-Month