jedi mind tricks for git

98
Jedi Mind Tricks in Git Help me Obi-Git, you’re my only hope

Upload: jan-krag

Post on 15-Apr-2017

472 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Jedi Mind Tricks for Git

Jedi Mind Tricks in GitHelp me Obi-Git, you’re my only hope

Page 2: Jedi Mind Tricks for Git

Who are we?@jankrag - @randomsort

Git Trainers

Page 3: Jedi Mind Tricks for Git

“Oh my. Software development sound rather perilous. I can assure you they will never get me

on one of those dreadful Computers”

- C3PO

Page 4: Jedi Mind Tricks for Git

this -is a command

This is the console output of a commandIt can be coloured as wellthis completed successfully.

#!/foo/barThis is the content of a script

[config]Or the content of a config filehello=git merge

Conventions

Page 5: Jedi Mind Tricks for Git

Working with git hooks

Page 6: Jedi Mind Tricks for Git

What are git hooks?

We can jam a hook into Git’s normal flow

Page 7: Jedi Mind Tricks for Git

Git hook control flow

CompleteFinalizeWrite MsgCommitStage

precommitPrepare commit msg

Commit msg

postcommit

NotificationActionable

Page 8: Jedi Mind Tricks for Git

Yes - but how do I get started?git init

Page 9: Jedi Mind Tricks for Git

Making Git hooksls .git/hooks

applypatch-msg.sample commit-msg.sample post-update.sample pre-commit.sample prepare-commit-msg.sample pre-rebase.sample pre-applypatch.sample pre-push.sample update.sample

Page 10: Jedi Mind Tricks for Git

Client side vs server side hooks

precommitprepare-commit-msgcommit-msgpost-commitpost-checkoutpre-rebase

pre-receive update post-receive

Page 11: Jedi Mind Tricks for Git
Page 12: Jedi Mind Tricks for Git

The truth is out there...

Specifically on master

Page 13: Jedi Mind Tricks for Git
Page 14: Jedi Mind Tricks for Git

pre-commit hook

●First thing that happens after git commit

●Able to abandon the commit

●We have not got any arguments

Page 15: Jedi Mind Tricks for Git

Where are we at?git symbolic-ref --short HEAD

master

Page 16: Jedi Mind Tricks for Git

pre-commit hook#!/bin/bash# Check where our HEAD is atif [ "$(git symbolic-ref --short HEAD)" == "master" ]; then

echo "This is not the branch you are looking for"exit 1

fiexit 0

Page 17: Jedi Mind Tricks for Git

pre-commit hook#!/bin/bash# Check where our HEAD is atif [ "$(git symbolic-ref --short HEAD)" == "master" ]; then

echo "This is not the branch you are looking for"exit 1

fiexit 0

Page 18: Jedi Mind Tricks for Git

pre-commit hook#!/bin/bash# Check where our HEAD is atif [ "$(git symbolic-ref --short HEAD)" == "master" ]; then

echo "This is not the branch you are looking for"exit 1

fiexit 0

Page 19: Jedi Mind Tricks for Git

cp pre-commit .git/hooks/pre-commitgit checkout mastergit commit -am “I want to commit this”

This is not the branch you’re looking for

Page 20: Jedi Mind Tricks for Git

Well, I should be able to commit on mastergit checkout mastergit commit -n -am “I want to commit this”

[master 5d5308b] I want to commit this 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 foo.md

Page 21: Jedi Mind Tricks for Git
Page 22: Jedi Mind Tricks for Git

The mission

● I want to reference an issue in my commit messages

● If I do not reference an issue in my repository - abandon my commit

Page 23: Jedi Mind Tricks for Git

Where are our issues? Git remote show origin

* remote origin Fetch URL: [email protected]:RandomSort/hooks Push URL: [email protected]:RandomSort/hooks HEAD branch: master Remote branch: master tracked Local branch configured for 'git pull': master merges with remote master Local ref configured for 'git push': master pushes to master (up to date)

Page 24: Jedi Mind Tricks for Git

I <3 APIScurl -s https://api.github.com/repos/$repo/issues/$issue_number

{ "url": "https://api.github.com/repos/RandomSort/hooks/issues/1", "repository_url": "https://api.github.com/repos/RandomSort/hooks", "labels_url": "https://api.github.com/repos/RandomSort/hooks/issues/1/labels{/name}", ....TONS OF JSON :D

Page 25: Jedi Mind Tricks for Git

commit-msg hook#!/bin/bash# $1 is the temp file containing the commit messageissue_number=`cat $1 | xargs | sed 's/.*#\([0-9]*\).*/\1/'`repo="`git remote show origin | grep "Push" | xargs | sed 's/.*:\(.*\)/\1/'`"curl -s https://api.github.com/repos/$repo/issues/$issue_number |\ grep -q "\"Not Found\"" > /dev/nullexit $((1 -$?))

Page 26: Jedi Mind Tricks for Git

commit-msg hook#!/bin/bash# $1 is the temp file containing the commit messageissue_number=`cat $1 | xargs | sed 's/.*#\([0-9]*\).*/\1/'`repo="`git remote show origin | grep "Push" | xargs | sed \ 's/.*:\(.*\)/\1/'`"curl -s https://api.github.com/repos/$repo/issues/$issue_number |\ grep -q "\"Not Found\"" > /dev/nullexit $((1 -$?))

Page 27: Jedi Mind Tricks for Git

commit-msg hook#!/bin/bash# $1 is the temp file containing the commit messageissue_number=`cat $1 | xargs | sed 's/.*#\([0-9]*\).*/\1/'`repo="`git remote show origin | grep "Push" | xargs | sed 's/.*:\(.*\)/\1/'`"curl -s https://api.github.com/repos/$repo/issues/$issue_number |\ grep -q "\"Not Found\"" > /dev/nullexit $((1 -$?))

Page 28: Jedi Mind Tricks for Git

commit-msg hook#!/bin/bash# $1 is the temp file containing the commit messageissue_number=`cat $1 | xargs | sed 's/.*#\([0-9]*\).*/\1/'`repo="`git remote show origin | grep "Push" | xargs | sed 's/.*:\(.*\)/\1/'`"curl -s https://api.github.com/repos/$repo/issues/$issue_number |\ grep -q "\"Not Found\"" > /dev/nullexit $((1 -$?))

Page 29: Jedi Mind Tricks for Git

So now we’ve done something sane ..

●Git hooks can do useful stuff

●Everything in moderation

● (bust the myth, then go all in)

Page 30: Jedi Mind Tricks for Git

Trust your workflow"Fear is the path to the dark side"

Page 31: Jedi Mind Tricks for Git

Branch based delivery

C1 C2 C3 C4

ready/feature

master

HEAD

git push origin feature:ready/feature

Page 32: Jedi Mind Tricks for Git

#serverless

These are not the servers you are looking for

Page 33: Jedi Mind Tricks for Git

Going native

Page 34: Jedi Mind Tricks for Git

The mission

● I want to work on a feature branch never on master

● I want to commit work referencing issues

● I want to be able to run my Continuous Integration setup

● I deliver through ready branches

●Only allow integration if

○ Tests succeed

○ it’s a fast forward merge

Page 35: Jedi Mind Tricks for Git

Where are we at (again)?git symbolic-ref --short HEAD

ready/foo

git rev-parse --show-toplevel

/home/randomsort/repos/hooks

.. And where’s our stuff?

Page 36: Jedi Mind Tricks for Git

We only want to do fast forward merges

● It’s prettiest

●We prefer to have our automation engine only do trivial merges

C1 C2 C3 C4

Feature#79

master

HEAD

Page 37: Jedi Mind Tricks for Git

We only want to do fast forward merges

● It’s prettiest

●We prefer to have our automation engine only do trivial merges

C1 C2 C3 C4

Feature#79

master

HEAD

Page 38: Jedi Mind Tricks for Git

How fast can we go?

git rev-list --maxcount 1 master..ready/foo

C1 C2 C3 C4

ready/foo

master

HEAD

Page 39: Jedi Mind Tricks for Git

Putting it together#!bin/bashif [ not on ready branch ] do nothingfiif [ not fast forwardable ] cleanupfirun testsif [ successful ] merge cleanupelse cleanup

Page 40: Jedi Mind Tricks for Git

Putting it together#!bin/bashif [ not on ready branch ] do nothingfiif [ not fast forwardable ] cleanupfirun testsif [ successful ] merge cleanupelse cleanup

Page 41: Jedi Mind Tricks for Git

Putting it together#!bin/bashif [ not on ready branch ] do nothingfiif [ not fast forwardable ] cleanupfirun testsif [ successful ] merge cleanupelse cleanup

Page 42: Jedi Mind Tricks for Git

Cleaning up fails#We can't do a fast forward merge so let's abort this and move some stuff aroundfailbranch=`echo $branch | xargs | sed 's/ready/failed/'`echo "Unable to fast forward master to $branch leaving state on \ $failbranch"git checkout -b $failbranchgit branch -D $branch

Page 43: Jedi Mind Tricks for Git

Cleaning up fails#We can't do a fast forward merge so let's abort this and move some stuff aroundfailbranch=`echo $branch | xargs | sed 's/ready/failed/'`echo "Unable to fast forward master to $branch leaving state on \ $failbranch"git checkout -b $failbranchgit branch -D $branch

Page 44: Jedi Mind Tricks for Git

Runninggit checkout -b ready/feature

Switched to a new branch 'ready/feature'Running testsTesting has failed, leaving state on failed/featureSwitched to a new branch 'failed/feature'Deleted branch ready/feature (was 462b135).

Page 45: Jedi Mind Tricks for Git

Runninggit checkout -b ready/feature

Switched to a new branch 'ready/feature'Running testsTesting has failed, leaving state on failed/featureSwitched to a new branch 'failed/feature'Deleted branch ready/feature (was 462b135).

Page 46: Jedi Mind Tricks for Git

Runninggit checkout -b ready/feature

Switched to a new branch 'ready/feature'Running testsTesting has failed, leaving state on failed/featureSwitched to a new branch 'failed/feature'Deleted branch ready/feature (was 462b135).

Page 47: Jedi Mind Tricks for Git

Runninggit checkout -b ready/feature

Switched to a new branch 'ready/feature'Running testsTesting has failed, leaving state on failed/featureSwitched to a new branch 'failed/feature'Deleted branch ready/feature (was 462b135).

Page 48: Jedi Mind Tricks for Git

Running with successful testsgit checkout -b ready/feature

Switched to a new branch 'ready/feature1'Running testsSwitched to branch 'master'Updating e28500e..06a16b1Fast-forward temp.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 temp.mdDeleted branch ready/feature1 (was 06a16b1).

Page 49: Jedi Mind Tricks for Git

It works on my machine"I find your lack of faith disturbing"

Page 50: Jedi Mind Tricks for Git

TatooineJan

Page 51: Jedi Mind Tricks for Git

TATOOINE - LARS OWENS HOMESTEAD

OWEN:

I have no need for a protocol droid.

C3P0:

Sir -- not in an environment such as this -- that's why I've also been programmed for over thirty secondary functions that...

OWEN:

What I really need is a droid that understands the binary language of moisture vaporators.

Page 52: Jedi Mind Tricks for Git

... secondary functions"I have no need for a protocol droid."

Page 53: Jedi Mind Tricks for Git

Binary is annoying...

git diff wordfile.docx

diff --git a/wordfile.docx b/wordfile.docxindex d24c436..3c4aa59 100644Binary files a/wordfile.docx and b/wordfile.docx differ

No idea what changed...

Page 54: Jedi Mind Tricks for Git

Teaching git new tricks

Combining two features:

Git attributes

Assign behaviour per file or path

Custom drivers

Define new behaviour

Page 55: Jedi Mind Tricks for Git

Git attributes

Each line in an attributes definition is of form:

pattern attr1 attr2 ...

Where a attribute can be set, unset or assigned a value:

*.txt text*.jpg -text*.sh text eol=lf

Page 56: Jedi Mind Tricks for Git

Git attributes - global

Default location: $XDG_CONFIG_HOME/git/attributes. Fallback:$HOME/.config/git/attributes

If you want to set the path you can use:

git config --global core.attributesfile <path>

git config --global core.attributesfile ~/.gitattributes

e.g.

Page 57: Jedi Mind Tricks for Git

Git attributes - local

Just add definitions to a local .gitattributes file.

Can be set in root folder and in subfolders

Page 58: Jedi Mind Tricks for Git

Git attributes

commonly used for changing (force'ing):

CRLF behaviour

text / binary behaviour

But that is not Jedi enough ...... so we will skip those

Page 59: Jedi Mind Tricks for Git

Diff driver

Set as a config parameter like diff.foo

[diff "hexify"] binary = true textconv = hexdump -v -C

Page 60: Jedi Mind Tricks for Git

Using the new driver is easy

In .gitattributes:*.bin diff=hexify

Note - we need both:

Driver definition in config

Path attribute that tells diff to use it

Page 61: Jedi Mind Tricks for Git

But hexdump is still pretty useless 00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|00000010 00 00 03 20 00 00 02 80 08 02 00 00 00 eb 79 8b |... ..........y.|00000020 65 00 00 00 09 70 48 59 73 00 00 0b 13 00 00 0b |e....pHYs.......|00000030 13 01 00 9a 9c 18 00 00 00 06 62 4b 47 44 00 ff |..........bKGD..|00000040 00 ff 00 ff a0 bd a7 93 00 00 8a b5 49 44 41 54 |............IDAT|00000050 78 da ec bd 09 5b 53 57 f7 fe df f7 55 32 9d cc |x....[SW....U2..|00000060 33 09 99 e7 79 20 09 19 50 91 41 90 41 26 41 44 |3...y ..P.A.A&AD|00000070 44 14 11 41 04 04 ad b5 b5 b6 b5 b5 56 ed ef 85 |D..A........V...|00000080 fd 17 a5 7f bf 3e 4a 4e 42 38 c9 39 27 e7 be ae |.....>JNB8.9'...|00000090 cf d5 cb c7 47 25 39 67 ef b5 ee bd f7 da f7 fa |....G%9g........|000000a0 ae a7 e7 7b 00 00 00 00 00 c0 21 df e1 11 00 00 |...{......!.....|000000b0 00 00 00 40 60 01 00 00 00 00 40 60 01 00 00 00 |...@`.....@`....|000000c0 00 40 60 01 00 00 00 00 00 08 2c 00 00 00 00 00 |.@`.......,.....|000000d0 08 2c 00 00 00 00 00 08 2c 00 00 00 00 00 00 81 |.,......,.......|000000e0 05 00 00 00 00 00 81 05 00 00 00 00 00 81 05 00 |................|000000f0 00 00 00 00 20 b0 00 00 00 00 00 20 b0 00 00 00 |.... ...... ....|00000100 00 00 20 b0 00 00 00 00 00 20 b0 00 00 00 00 00 |.. ...... ......|00000110 00 04 16 00 00 00 00 00 04 16 00 00 00 00 00 04 |................|<pages and pages without end>

Page 62: Jedi Mind Tricks for Git

Recipe for success

For each binary type:

1. Find a tool that extracts useful info from a file

2. Set up a diff driver to use it

3. Profit

4. Don't give in to the dark side

Page 63: Jedi Mind Tricks for Git

Word files

Page 64: Jedi Mind Tricks for Git

My brain parses markdown quite fine...

*.docx diff=pandoc2md

[diff "pandoc2md"]textconv=pandoc --to=markdown

brew install pandoc

For reference:

.gitattributes

config

Page 65: Jedi Mind Tricks for Git

git diff wordfile.docx

diff --git a/wordfile.docx b/wordfile.docxindex d24c436..48249e3 100644--- a/wordfile.docx+++ b/wordfile.docx@@ -1,8 +1,8 @@-Headline+Hi Git Merge This is some simple text -*and another important paragraph in italic*+*and another* **important** *paragraph in italic*

Word to MarkDown

Page 66: Jedi Mind Tricks for Git

git diff --word-diff=color wordfile.docx

diff --git a/wordfile.docx b/wordfile.docxindex d24c436..48249e3 100644--- a/wordfile.docx+++ b/wordfile.docx@@ -1,8 +1,8 @@HeadlineHi Git Merge

This is some simple text

*and another* **important** *paragraph in italic*

Word to MarkDown

Page 67: Jedi Mind Tricks for Git

Other ideas?

Page 68: Jedi Mind Tricks for Git

PDF files*.pdf diff=pdfconv[diff "pdfconv"]

textconv=pdftohtml -stdout

brew install pdftohtml

<BODY bgcolor="#A0A0A0" vlink="blue" link="blue"> <A name=1></a>Headline<br> This is some simple text<br>-and another paragraph<br>-and stuff<br>+and another important paragraph in italic<br>+stuff goes here<br>+Greetings from Denmark<br> <hr> </BODY>

Page 69: Jedi Mind Tricks for Git

Maybe even for non-binaries?

Page 70: Jedi Mind Tricks for Git

Syntax highlighting

*.py diff=color

pip install Pygments

For reference:

.gitattributes

config

[diff "color"]textconv=pygmentize

Page 71: Jedi Mind Tricks for Git

git diff --cached primes.py

...@@ -0,0 +1,22 @@+def primes(n):+ """+ Compute the sequence of the first n primes.+ """+ p = []+ if n > 0:+ p = [2, ]+ for x in range(1, n):+ q = p[-1] + 1+ while True:+ for y in p:+ if not (q % y):+ break+ else:+ p.append(q)

Syntax highlighted code in diff'sMy brain parses coloured python better

Snippet from:https://github.com/cbcunc/primer (GPL)

Page 72: Jedi Mind Tricks for Git

Reformatting

*.md diff=wrap

brew install fmt

For reference:

.gitattributes

config

[diff "wrap"]textconv=fmt

Page 73: Jedi Mind Tricks for Git

git diff autostash.md

>"Why can't I pull when I have a dirty workspace, when Mercurial can do this out of the box?" -I gave the immediate answer that this is just Git's way of protecting the user from possibly harmful and, more importantly, irreversible changes. Git by default takes a very paranoid approach to any operations that change dirty files in your file system, when Git itself can't get you out of those changes again. _This is normally considered a feature_. The known "workaround", or possible workflow, is to stash any changes before doing a pull (with `git stash save`, and then unstash them again (`git stash pop`) when done. It seems obvious that it should be easy to automate this with a git alias, but it turns out that this isn't trivial, as git stash doesn't fail gracefully when there are no local changes.+I gave the immediate answer that this is just Git's way of protecting the user from possibly harmful and, more importantly, irreversible changes. Git by default takes a very paranoid approach to any operations that change dirty files in your file system, when **Git** itself can't get you out of those changes again. _This is normally considered a feature_. The known "workaround", or possible workflow, is to stash any changes before doing a pull (with `git stash save`, and then unstash them again (`git stash pop`) when done. It seems obvious that it should be easy to automate this with a git alias but it turns out that this isn't trivial. Git stash does not fail gracefully when there are no local changes.

.md - Before reformatting

Page 74: Jedi Mind Tricks for Git

git diff autostash.md

@@ -13,13 +13,13 @@ can do this out of the box?" I gave the immediate answer that this is just Git's way of protecting the user from possibly harmful and, more importantly, irreversible changes. Git by default takes a very paranoid approach to any-operations that change dirty files in your file system, when Git+operations that change dirty files in your file system, when **Git** itself can't get you out of those changes again. _This is normally considered a feature_. The known "workaround", or possible workflow, is to stash any changes before doing a pull (with `git stash save`, and then unstash them again (`git stash pop`) when done. It seems-obvious that it should be easy to automate this with a git alias,-but it turns out that this isn't trivial, as git stash doesn't fail+obvious that it should be easy to automate this with a git alias+but it turns out that this isn't trivial. Git stash does not fail gracefully when there are no local changes.

.md - after formatting with fmt

Page 75: Jedi Mind Tricks for Git

Images

Page 76: Jedi Mind Tricks for Git

Extract meta data

Define a useful driver:[diff "exif"]

textconv=exiftool

*.jpg diff=exif*.jpeg diff=exif*.png diff=exif*.gif diff=exif

Page 77: Jedi Mind Tricks for Git

https://openclipart.org/detail/227445/yoda

Let's resize Yoda

Page 78: Jedi Mind Tricks for Git

git diff Yoda-800px.png

diff --git a/Yoda-800px.png b/Yoda-800px.pngindex fc8ee0f..8ed738c 100644--- a/Yoda-800px.png+++ b/Yoda-800px.png@@ -1,24 +1,26 @@-File Size : 35 kB-File Modification Date/Time : 2017:01:27 17:29:06+01:00+File Size : 85 kB+File Modification Date/Time : 2017:01:30 18:52:20+01:00 File Type : PNG-Image Width : 800-Image Height : 640+Image Width : 600+Image Height : 480 Bit Depth : 8-Color Type : RGB+Color Type : RGB with Alpha

Much more useful

Note: manually abbreviated for slide

But do I know what changed?

Page 79: Jedi Mind Tricks for Git

Can we see the difference?

cachetextconv caches the result

[diff "jpg"]textconv=jp2a --width=80cachetextconv = true

*.jpg diff=jpg*.jpeg diff=jpg

Can't quite do holograms yet, but...

brew install jp2a

Page 80: Jedi Mind Tricks for Git

git add Yoda.jpg git diff --cacheddiff --git a/Yoda.jpg b/Yoda.jpgnew file mode 100644index 0000000..cf0300a--- /dev/null+++ b/Yoda.jpg@@ -0,0 +1,32 @@+................................................................................+......................................''''......................................+................................,:ldxkkOOkkxdl:,................................+.............................,lxOOdlllxOOxllldOkxc'.............................+....',:ccllllollc:,'.......'lkOxllllllxOOxllllllkOkl'.......',:cllooollcc:,'....+..;okOOkccccclllodxkxoc;'.:xOOOkkxddddkOOkodddxkkOOOx;.';coxkxdollccccclkOOko;..+....':dOxl;;:::::;;;:ldx:oOxolllloddxxkOOkxxddollllokklcxdl:;;;:::::;:okkd:'....+.......;xOkd:;::::::::':xOxoxOOOOOOOOOOOOOOOOOOOOOOxokOx;,::::::::;:xOOx;.......+........'okOOd;;:::::,okOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOkl,:::::;;dOOkl'........+..........;dOOkl;;:;:xOOOOOOOkkOOOOOOOOOOOOOOOOOOkkOOOOOOOx;;:;;okOkd,..........+............;okOkd,ckOOOOOkc,..,oOOOOOOOOOOOOOkl,..,lkOOOOOk;;dkOkl,............+..............';lo;kOOOOOOl......xOOOOOOOOOOOOd......oOOOOOOk;dl;...............+..................lOOOOOOOk;...'ckOOOOOOOOOOOOk:'...:kOOOOOOOc..................+..................xOOOOOOOOOxddkOOOOOOOOOOOOOOOOkddkOOOOOOOOOo..................

Page 81: Jedi Mind Tricks for Git

https://openclipart.org/detail/227445/yoda

Let's give him eyes

Page 82: Jedi Mind Tricks for Git

diff --git a/Yoda.jpg b/Yoda.jpgindex cf0300a..c16b7de 100644--- a/Yoda.jpg+++ b/Yoda.jpg@@ -9,8 +9,8 @@ ........'okOOd;;:::::,okOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOkl,:::::;;dOOkl'........ ..........;dOOkl;;:;:xOOOOOOOkkOOOOOOOOOOOOOOOOOOkkOOOOOOOx;;:;;okOkd,.......... ............;okOkd,ckOOOOOkc,..,oOOOOOOOOOOOOOkl,..,lkOOOOOk;;dkOkl,............-..............';lo;kOOOOOOl......xOOOOOOOOOOOOd......oOOOOOOk;dl;...............-..................lOOOOOOOk;...'ckOOOOOOOOOOOOk:'...:kOOOOOOOc..................+..............';lo;kOOOOOOl'oxc..xOOOOOOOOOOOOd,dd:..oOOOOOOk;dl;...............+..................lOOOOOOOk:odc'ckOOOOOOOOOOOOkldd:.:kOOOOOOOc.................. ..................xOOOOOOOOOxddkOOOOOOOOOOOOOOOOkddkOOOOOOOOOo.................. ..................dOOOOOOOOOOOOOkookOOOOOOOOOdldOOOOOOOOOOOOOl.................. ..................,kOOOOOOOOOOkcc:oxkOOOOOOkxocccxOOOOOOOOOOx'..................

git diff Yoda.jpg

Page 83: Jedi Mind Tricks for Git

Even in gitk

Page 84: Jedi Mind Tricks for Git

Other quick onesMP3 file meta data: exiftool can do those too, or try mp3info:

[diff "mp3"]textconv=mp3info -x

Excel files:[diff "xlsconv"]

textconv=xls2csv

Zip files:[diff "zipshow"]

textconv=unzip -c -a[diff "ziplist"]

textconv=unzip -l

Page 85: Jedi Mind Tricks for Git

Length Date Time Name --------- ---------- ----- ---- 0 01-25-2017 12:52 stuff/ 0 01-25-2017 12:53 stuff/foo/ 7 01-25-2017 12:53 stuff/foo/bar 12 01-25-2017 12:52 stuff/hello.world- 9 01-25-2017 12:52 stuff/hi.txt --------- -------- 28 5 files+ 19 4 files

git diff stuff.zip

Page 86: Jedi Mind Tricks for Git

And we haven't even left Tatooine yet!

Page 87: Jedi Mind Tricks for Git

Recap - Git objects

https://github.com/pluralsight/git-internals-pdf

Page 88: Jedi Mind Tricks for Git

Filter driversProcess blobs on save or checkout

[filter "name"]clean =

<command>smudge =

<command>

Let's have some fun with them too...

Page 89: Jedi Mind Tricks for Git

There is no try...

Yapf = Yet Another Python Formatter( pip install --user yapf )

[filter "cleanpython"]clean = yapf smudge = cat

*.py filter=cleanpython

Page 90: Jedi Mind Tricks for Git

ugly.py x = { 'a':37,'b':42,

'c':927}

y = 'hello ''world'z = 'hello '+'world'a = 'hello {}'.format('world' )class foo ( object ): def f (self ): return 37*-+2 def g(self, x,y=42): return ydef f ( a ) : return 37+-+a[42-x : y**3]

git add ugly.pygit commit ....git push

Page 91: Jedi Mind Tricks for Git

... and behold.

Page 92: Jedi Mind Tricks for Git

Caveat

That was a conceptual demo - probably not production ready.

Git diff gets a bit confused:

git status now shows ugly.py as modified

git add - and it disappears :-)

Page 93: Jedi Mind Tricks for Git

“Your eyes can deceive you. Don’t trust them.” – Obi-Wan

For demo: simple rot13 'encryption' - only affects letters

[filter "secret"]clean = ruby -ne 'print $_.tr( \"A-Za-z\", \"N-ZA-Mn-za-

m\") ' smudge = perl -pe 'tr/N-ZA-Mn-za-m/A-Za-z/'

*.java filter=secret

Page 94: Jedi Mind Tricks for Git

public static void sort(int[] numbers) { int n = numbers.length; int temp = 0;

for (int i = 0; i < n; i++) { for (int j = 1; j < (n - i); j++) {

if (numbers[j - 1] > numbers[j]) { //comment temp = numbers[j - 1]; numbers[j - 1] = numbers[j]; numbers[j] = temp; } } }}

sort.java

Page 95: Jedi Mind Tricks for Git

git ls-tree HEAD

100644 blob cf0300a887b362db6e26891afb6ad86757e00f72 Yoda.jpg100644 blob 60f95e16c59e6e0ef7dc5542cc0f5c15a35e9df4 primes.py100644 blob 887177cdd3976c695ec5303e6a6d2c1832b458a9 sort.java100644 blob 809ec4f968232287368681257a0b5ad5c726c08a ugly.py

git show 887177cdd

choyvp fgngvp ibvq fbeg(vag[] ahzoref) { vag a = ahzoref.yratgu; vag grzc = 0;

sbe (vag v = 0; v < a; v++) { sbe (vag w = 1; w < (a - v); w++) {

vs (ahzoref[w - 1] > ahzoref[w]) { grzc = ahzoref[w - 1]; ahzoref[w - 1] = ahzoref[w]; ahzoref[w] = grzc; }

} }}

Page 96: Jedi Mind Tricks for Git

And on GitHub too, obviously

Page 97: Jedi Mind Tricks for Git

Now just imagine we had used

GPG or AES-256 with private key

*.cred filter=secret

Publish your private content to public repos :-)

Page 98: Jedi Mind Tricks for Git

The End"Already know you that which you need." – Yoda