GitHub pull requests as seen by GIT

First off, some links to github documentation:

For just working with pull requests and even manually fetching / merging pull requests locally this information is more than enough. I found that by adding a new refspec, my branches are getting polluted with a looooong list of pull requests for certain projects. I would rather have a simple quick execute-once way of doing the same thing.

An extremely simple way is by adding a new alias:

git config alias.fpr '!sh -c "git fetch origin pull/${1}/head:pr/${1}" -'

This allows you to use git fpr 696 to pull in #696. Mind you, the remote is hardcoded to ‘origin‘ here.

In some cases, I’m really inpatient towards pull requests on upstream repositories and I want to merge them in my local repository more easily.
I created the following script for just that: git-merge-pr.sh.

A quick example:

$ ./git-merge-pr.sh 696
$ git log -n1
commit c0f62a0b1ed09ce928d35a90854a1eb2c2ac6d10
Merge: 1d837ed 54988e1
Author: Jan Vansteenkiste 
Date:   Tue May 6 06:48:43 2014 +0200

    Merged pull request: #696: Bugfix/debian control file permissions
    
    See jordansissel/fpm#696 for more information
    
    * pr/696:
      Ignore lsb init scripts warning since we are not providing a proper init script for testing
      Feeling brave, enable lintian for travis
      Fix file permissions on deb control files
    
    Conflicts:
    	.travis.yml

Diffing gems in GIT.

Recently, I’ve been doing some patching on fpm and today I also started writing some tests for the changes I made. One change required that the gem in the repository used for testing had a bin in it so I modified the .gemspec and rebuild it.

After building and about to push it, I thought on how it must seem to the maintainer when somebody sends a pull request for a binary blob. I would like to know what really changed in there without having to go checkout the internals myself. How wonderful would life be if we could just use git diff to show the differences.

Here is a way to do just that using .gitattributes and a little shell script:

misc/gemdiff.sh:

#!/bin/bash
echo "============== metadata =============="
tar -xOf $1 metadata.gz 2>/dev/null | gunzip -c 2>/dev/null
echo "============== checksums ============="
tar -xOf $1 checksums.yaml.gz 2>/dev/null | gunzip -c 2>/dev/null
echo "=============== files ================"
tar -xOf $1 data.tar.gz 2>/dev/null | tar -xvOzf - 2>&1

.gitattributes:

*.gem diff=gemdiff

.git/config:

[diff "gemdiff"]
    textconv = misc/gemdiff.sh

The result looks like this:

diff --git a/spec/fixtures/gem/example/example-1.0.gem b/spec/fixtures/gem/example/example-1.0.gem
index 0241779..f762e52 100644
--- a/spec/fixtures/gem/example/example-1.0.gem
+++ b/spec/fixtures/gem/example/example-1.0.gem
@@ -3,19 +3,17 @@
 name: example
 version: !ruby/object:Gem::Version
   version: '1.0'
-  prerelease: 
 platform: ruby
 authors:
 - sample author
 autorequire: 
 bindir: bin
 cert_chain: []
-date: 2012-03-15 00:00:00.000000000 Z
+date: 2014-05-01 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: dependency1
   requirement: !ruby/object:Gem::Requirement
-    none: false
     requirements:
     - - ! '>='
       - !ruby/object:Gem::Version
@@ -23,7 +21,6 @@ dependencies:
   type: :runtime
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
-    none: false
     requirements:
     - - ! '>='
       - !ruby/object:Gem::Version
@@ -31,7 +28,6 @@ dependencies:
 - !ruby/object:Gem::Dependency
   name: dependency2
   requirement: !ruby/object:Gem::Requirement
-    none: false
     requirements:
     - - ! '>='
       - !ruby/object:Gem::Version
@@ -39,42 +35,59 @@ dependencies:
   type: :runtime
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
-    none: false
     requirements:
     - - ! '>='
       - !ruby/object:Gem::Version
         version: '0'
 description: sample description
 email: sample email
-executables: []
+executables:
+- example
 extensions: []
 extra_rdoc_files: []
-files: []
+files:
+- bin/example
 homepage: http://sample-url/
 licenses: []
+metadata: {}
 post_install_message: 
 rdoc_options: []
 require_paths:
 - lib
 required_ruby_version: !ruby/object:Gem::Requirement
-  none: false
   requirements:
   - - ! '>='
     - !ruby/object:Gem::Version
       version: '0'
 required_rubygems_version: !ruby/object:Gem::Requirement
-  none: false
   requirements:
   - - ! '>='
     - !ruby/object:Gem::Version
       version: '0'
 requirements: []
 rubyforge_project: 
-rubygems_version: 1.8.18
+rubygems_version: 2.0.14
 signing_key: 
-specification_version: 3
+specification_version: 4
 summary: sample summary
 test_files: []
 has_rdoc: 
 ============== checksums =============
+---
+!binary "U0hBMQ==":
+  metadata.gz: !binary |-
+    MjYwNGQ5MDZjYTE0MjY5MWQyZTA5Yzk0MjgyYjk2ZGM0ZTk3YzE3Mw==
+  data.tar.gz: !binary |-
+    YmZmYzJlNDU0ZGNmMDEzZjJmZGExYWZiYWE2ZjBjYTQ2MTMzYzFkNA==
+!binary "U0hBNTEy":
+  metadata.gz: !binary |-
+    MzYyYTVlNDk0ODRiNzdhNDBjOWE0ZmEyOGM0NjAzNzg3M2VlZTA4MzgzZDAw
+    ZjVhMjc5ZjFjYTIzOTk2MWFhYjZmMjNiNmVkNzRlMzMzMTdiOTMxMzlmM2Nl
+    ZGE3ZDc5ZDRkNjUwNDE1ODkzNDkxNDhmNmI5YmUyYjg2NjEwMjk=
+  data.tar.gz: !binary |-
+    MGY3NzllNTgwOGQ2YzhmOGUwNjlkMTk5NTlhOTIzZjJkZTkyMjdiNzQxZDQ3
+    NDc4ZjU5NGU1YTA4ODc1NzQwNTc3OWNlOWZkZjMwNWFmMDE3MWE4ZDUzNGY3
+    NDE0NGVmMjA4MDM1MDA4ZjdiMzliNWIwYTNiNDVkMWExZmIyYTY=
 =============== files ================
+bin/example
+#!/usr/bin/env ruby

Life.wonderfulness++;