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++;