Git: Accessing lost commits

Every time you amend, rebase or reset, git commits get "overwritten".

However, git still allows you to checkout those commits using their SHA1, given you can find it.

One option to do this is

git reflog
# or
git reflog show [BRANCH]

This will show a list of all commits the branch has recently pointed to.

Git might garbage collect those commits eventually, but this should only happen after several weeks.

Git: Force a rejected push

If you modified git's history and the change was already pushed, you will usually get a
! [rejected] my-branch -> my-branch (non-fast-forward)
error, when trying to push.

You can force the push, with
git push --force origin my-branch

Careful:

  • You might lose history.
  • Unless your git is configured to push only the current branch, you must supply the remote branch name or you will force-push all your branches!
  • Anyone else who has already pulled the changes will run into significant trouble.

Only...

Git: Changing commit messages

To change the commit message of the latest (unpushed, unmerged) commit, you can use
git commit --amend

To change the commit message of an earlier (unpushed, unmerged) commit [COMMIT], you can do
git rebase -i COMMIT~

For a current version of git, you can simply mark the line with "reword", and git will ask you later for the new message.

For older versions:

  • mark the line with edit
  • save the file
  • do a git commit --amend when rebasing stops at the relevant commit
  • git rebase --continue

Git: Amending older commits

Lets say you need to make a change to a commit OLD_COMMIT, but this is not the most recent. If you have neither pushed nor merged it, you can do this:

  • Make a new commit now, with a message like "fix".
  • Do a
git rebase -i OLD_COMMIT~
  • In the editor window that opened, move the "fix" commit directly after the one you want to amend (so it should be the second from the top), and mark it as "fixup". Save the file.
  • If there are conflicts, solve them, add them, and do
git rebase --continue

Use the back button in Cucumber

In order to go back one page in your Cucumber tests, you can use the following step definition for Capybara:

When(/^I go back$/) do
  visit page.driver.request.env['HTTP_REFERER']
end

If you're on Webrat, this should work:

When(/^I go back$/) do
  visit request.env["HTTP_REFERER"])
end

An improved version of this step is now part of our gem spreewald on Github.

Change commit messages of past Git commits

To change a commit message of the most recent (unpushed) commit, you can simply use
git commit --amend -m 'new message'

To change messages of (unpushed) commits further in the past:

git rebase -i [COMMIT BEFORE THE FIRST YOU WANT TO EDIT]

Mark all messages to be changed with "edit".

Git will start the rebasing and stop at every marked commit. For each of those, do a
git commit --amend -m 'new message'
git rebase --continue

Test a gem in multiple versions of Rails

Plugins (and gems) are typically tested using a complete sample rails application that lives in the spec folder of the plugin. If your gem is supposed to work with multiple versions of Rails, you might want to use to separate apps - one for each rails version.

For best practice examples that give you full coverage with minimal repitition of code, check out our gems has_defaults and assignable_values. In particular, take a look at:

  • Multiple `sp...

kangax's protolicious - GitHub

Added utility methods for the Prototype Javascript framework.

scribd's flash_heed at master - GitHub

Fixes all Flash elements on a page so that they heed DOM stacking order

Git: Stash unstaged changes

This will stash all modifications that you did not git add:

git stash -k

Note that newly created (and non-added) files will remain in your working directory unless you also use the -u switch.

git stash -k -u

Also, your working directory must be clean (i.e. all changes need to be added) when you git stash pop later on.

Bookmarklet to generate a commit message with Pivotal Tracker story ID and title

For clarity and traceability, your commit messages should include the ID and title of the Pivotal Tracker story you're working on. For example:

[#12345] Add Google Maps to user profiles
Optional further commit messages in the body

Also see Howto: Write a proper git commit message

To quickly generate such commit messages, add a new link "Commit" to your bookmarks and use the following Javascript as the link URL:

javascript:(function() { ...

Git: "Interactive reverts"

If you need to revert only parts of one or several commits the following workflow can help:

If you need to revert multiple changes, make a branch and squash it afterwards.

For every commit you need to revert, starting at the most recent, do:

git revert -n [COMMIT] #revert, but don't automatically commit
... #fix any conflicts
git reset #unstage all changes
git add -p #this will ask you for every change, whethe...

Git diff a file with another revision (or branch)

git diff commit_hash -- path/to/file

Provide any commit hashes or branch names like "master" for commit_hash.

Migrating to RSpec 2 from RSpec 1

You will need to upgrade to RSpec >= 2 and rspec-rails >= 2 for Rails 3. Here are some hints to get started:

  • In RSpec 2 the executable is rspec, not spec.
  • RSpec and rspec-rails have been completely refactored internally. All RSpec classes have been renamed from Spec::Something to RSpec::Something. This also means that every require 'spec/something' must now be require 'rspec/something'.
  • In spec_helper.rb, Spec::Runner.configure becomes RSpec.configure
  • It has become really hard to extend specific example groups ...

Shell script to quickly switch Apache sites

I prefer the application that I'm currently working on to be reachable at http://localhost/.

So when I switch to another project, I use this handy shell script to set one site as the current one. Call it just like this:
apache-site makandra-com

Note that it disables all other sites in your Apache configuration so you would not want to use this on production machines.
Furthermore it will also enable the default site if that was available.

When you call apache-site with no arguments, it will list all available sites.


...

apotonick's hooks at master - GitHub

Hooks lets you define hooks declaratively in your ruby class. You can add callbacks to your hook, which will be run as soon as you run the hook.

jsmestad's pivotal-tracker at master - GitHub

Ruby gem that provides an AR-style interface for the Pivotal Tracker API.

Sun Java JVM/JRE on Ubuntu Linux

Note that you should disable the Java plug-in in your browsers after installation.

Ubuntu >= 12.04

Java 11

sudo apt install openjdk-11-jre-headless

Java 10

sudo add-apt-repository ppa:linuxuprising/java
sudo apt-get update
sudo apt-get install oracle-java10-installer

Java 8

You probably want to get rid of OpenJDK (which is installed by default and leads to bad RubyMine performance):

...

Use Sass without Rails

You don't need a Rails application to use Sass. Even when you're working on a static site you can generate your CSS through Sass.

  • Install Sass with sudo gem install haml
  • Create a folder sass in the folder, that stores your stylesheets, e.g. mkdir css/sass
  • In a separate terminal window, run sass --watch css/sass:css. This will watch your sass files for changes and rewrite stylesheets as required.

This even works on Windows.

Note about your .gitignore

You might want to change our [typical .gitignor...

A quick guide to pull requests

It’s pretty common for projects hosted on GitHub to receive “pull requests”: requests from people who have cloned your project, made a modification to it and then asking you to merge their changes back into the main project.

There are a lot of ways you can handle these pull requests, here are some of them.

Run a rake task in all environments

Use like this:

power-rake db:migrate VERSION=20100913132321

By default the environments development, test, cucumber and performance are considered. The script will not run rake on a production or staging environment.


This script is part of our geordi gem on github.

Deliver Paperclip attachments to authorized users only

When Paperclip attachments should only be downloadable for selected users, there are three ways to go.
The same applies to files in Carrierwave.

  1. Deliver attachments through Rails

The first way is to store Paperclip attachments not in the default public/system, but in a private path like storage inside the current release. You should prefer this method when dealing with sensitive data.

Make ...

clemens's delocalize at master - GitHub

delocalize provides localized date/time and number parsing functionality for Rails.

Install RubyGems on Ubuntu/Debian

First of all: You could just use RVM which would make the pain go away. If for some reason you can't, proceed.


Do not use rubygems from the apt repository.

  1. Get the latest RubyGems TGZ
  2. Change to the download directory and extract it:\
    tar xvfz rubygems-1.3.7.tgz
  3. If you previously had RubyGems installed via apt: \
    sudo apt-get remove rubygems
  4. Install RubyGems:\
    cd rubygems-1.3.7 && sudo ruby setup.rb
  5. Link gem to gem1.8:\
    `sudo ...