Full Code of Gazler/githug for AI

master a613718f5625 cached
413 files
261.7 KB
96.9k tokens
89 symbols
1 requests
Download .txt
Showing preview only (335K chars total). Download the full file or copy to clipboard to get everything.
Repository: Gazler/githug
Branch: master
Commit: a613718f5625
Files: 413
Total size: 261.7 KB

Directory structure:
gitextract_yw6bj_tb/

├── .gitignore
├── .rspec
├── .travis.yml
├── Dockerfile
├── Gemfile
├── LICENCE.txt
├── README.md
├── Rakefile
├── bin/
│   └── githug
├── githug.gemspec
├── levels/
│   ├── add.rb
│   ├── bisect/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── ORIG_HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── gitk.cache
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-commit.sample
│   │   │   │   ├── post-receive.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   ├── exclude
│   │   │   │   └── refs
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── info/
│   │   │   │   │   └── packs
│   │   │   │   └── pack/
│   │   │   │       ├── pack-59fab357f3158a9640633de6a3326ed79a2b4fe6.idx
│   │   │   │       └── pack-59fab357f3158a9640633de6a3326ed79a2b4fe6.pack
│   │   │   └── packed-refs
│   │   ├── makefile
│   │   ├── prog.rb
│   │   └── test.rb
│   ├── bisect.rb
│   ├── blame/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-commit.sample
│   │   │   │   ├── post-receive.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── 00/
│   │   │   │   │   └── d6bf5341b263ccaf32e7973be55126eb30a343
│   │   │   │   ├── 05/
│   │   │   │   │   └── 07c26fed4d111a8344763be9af68af90f0ecf2
│   │   │   │   ├── 09/
│   │   │   │   │   └── 4094808dc6dc336c93c8602190a9e5f7bd6a11
│   │   │   │   ├── 21/
│   │   │   │   │   └── 15d78864000292628872941b14521f90187eed
│   │   │   │   ├── 31/
│   │   │   │   │   └── 11dda1f5b08d50ac44b99acabfa54f1e6e72b0
│   │   │   │   ├── 50/
│   │   │   │   │   └── 8db115ba34a0e4e8667653aebe0265bb4f7e80
│   │   │   │   ├── 5e/
│   │   │   │   │   └── 8863df752e3b7f2150df7c78f12bef6f1ff00e
│   │   │   │   ├── 67/
│   │   │   │   │   └── 788a4b90180c7588d7bd0ad8032957b0f429ba
│   │   │   │   ├── 70/
│   │   │   │   │   └── d00535a3a25b0ac1736dd3d306d6271e5427ed
│   │   │   │   ├── 97/
│   │   │   │   │   └── bdd0cccf9f4b8730f78cb53a81a74f205dbcc2
│   │   │   │   ├── ab/
│   │   │   │   │   └── 08819ba3ffaeba17d4f870dc3a458a904519f4
│   │   │   │   ├── be/
│   │   │   │   │   └── 96fe46de646f6a5c728f90cc884aef96fa1d6f
│   │   │   │   ├── cd/
│   │   │   │   │   └── 9c6b9ab1a6f56cccc69b6aa661f1d67ba5fb46
│   │   │   │   ├── dd/
│   │   │   │   │   └── df1d8ebd60eec169c15a5b23cb49a58d2ed5a0
│   │   │   │   └── ff/
│   │   │   │       └── d39c2dbfd94bdbca06d48686e0cbda642f3de7
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           └── master
│   │   └── config.rb
│   ├── blame.rb
│   ├── branch.rb
│   ├── branch_at.rb
│   ├── checkout.rb
│   ├── checkout_file.rb
│   ├── checkout_tag.rb
│   ├── checkout_tag_over_branch.rb
│   ├── cherry-pick/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           ├── master
│   │   │   │           └── new-feature
│   │   │   ├── objects/
│   │   │   │   ├── 05/
│   │   │   │   │   └── aa97588aff673dcf00e0e1b835d6ec6207a7d9
│   │   │   │   ├── 14/
│   │   │   │   │   └── ad8f1413c40e0e5be6f6cbdec392a783c1d754
│   │   │   │   ├── 1b/
│   │   │   │   │   └── 912962174dd58fbbf1627ec816fa6672c70854
│   │   │   │   ├── 22/
│   │   │   │   │   └── f99f3abfd02190a760388c8845c190247859fe
│   │   │   │   ├── 23/
│   │   │   │   │   └── 2d266a78d5ef7196f1ede14972ccf7ee19e587
│   │   │   │   ├── 31/
│   │   │   │   │   └── 68bdc3ae7e0ab987dda238beab9c0582c7fc07
│   │   │   │   ├── 49/
│   │   │   │   │   └── 4fa3fc1c15986f9a950aba8607da591223614c
│   │   │   │   ├── 4a/
│   │   │   │   │   └── 1961bce62840eaef9c4392fe5cc799e38c9b7b
│   │   │   │   ├── 54/
│   │   │   │   │   ├── 22c2405527c05c23b243b2535a97b6cefa1427
│   │   │   │   │   └── f3308533fd4400c94c4cd5827cd38036a67a76
│   │   │   │   ├── 58/
│   │   │   │   │   └── a8c8edcfdd00c6d8cce9aada8f987a1677571f
│   │   │   │   ├── 6e/
│   │   │   │   │   └── dea632d9540e060bca97dda0897df2b7da0ec0
│   │   │   │   ├── 85/
│   │   │   │   │   └── 4e7ac38b3e8df02ea1480ec45aa9e7865f03d7
│   │   │   │   ├── 93/
│   │   │   │   │   └── 3a97260a11a5ee49bb8a4b7b097cb2fb38f85c
│   │   │   │   ├── 9a/
│   │   │   │   │   └── e59e88e6af362c069847e621b971bafff158ac
│   │   │   │   ├── a2/
│   │   │   │   │   └── 14badc644facc4722083aedf91d9339ffdffbf
│   │   │   │   ├── b3/
│   │   │   │   │   └── 0c6a965415df6aef5f2903f9892fa5481152fc
│   │   │   │   ├── c6/
│   │   │   │   │   └── 0c612734f25b9c989d954621491e9ca3c9e061
│   │   │   │   ├── ca/
│   │   │   │   │   └── 32a6dac7b6f97975edbe19a4296c2ee7682f68
│   │   │   │   ├── cf/
│   │   │   │   │   └── d8ce38c22c5fe83cc04e23f94646464f20d990
│   │   │   │   ├── d5/
│   │   │   │   │   ├── 02e68bfe397140e4ac2a819b138545abca604e
│   │   │   │   │   └── 123e58b37fd886dff2b96bfe5ec08a498192aa
│   │   │   │   └── ea/
│   │   │   │       ├── 2a47c19b85fc321e2737ddc49db3deeba3a1b5
│   │   │   │       └── 3dbcc5e2d2359698c3606b0ec44af9f76def54
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           ├── master
│   │   │           └── new-feature
│   │   ├── README.md
│   │   ├── hardcore-math.js
│   │   └── nokia.js
│   ├── cherry-pick.rb
│   ├── clone.rb
│   ├── clone_to_folder.rb
│   ├── commit.rb
│   ├── commit_amend.rb
│   ├── commit_in_future.rb
│   ├── config.rb
│   ├── conflict/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           ├── master
│   │   │   │           └── mybranch
│   │   │   ├── objects/
│   │   │   │   ├── 1d/
│   │   │   │   │   └── b9aa5013e47f1482ec90323d926171a99c28af
│   │   │   │   ├── 25/
│   │   │   │   │   └── b3f9c339430b35ae5822b2ef90e763284dc007
│   │   │   │   ├── 2d/
│   │   │   │   │   └── 0d90051e320215f54f357e746c9838490557e7
│   │   │   │   ├── 30/
│   │   │   │   │   ├── 6868e3258be1f35ae43db71e3a6d7edf42ffe7
│   │   │   │   │   └── cc28e66966109bb5bfbe96d6c817c367d2050a
│   │   │   │   ├── 38/
│   │   │   │   │   └── 21e4362c5a76db1112b46b9210670cd5bab482
│   │   │   │   ├── 3c/
│   │   │   │   │   └── b65bef44ae724ddf9e89640e7e2754dea1a47f
│   │   │   │   ├── 3d/
│   │   │   │   │   └── 7aec017559be2b61cab850dafdcb2b6212f1c3
│   │   │   │   ├── 40/
│   │   │   │   │   └── e20a455ac2731ad25c297b03aa543d7eedf6ab
│   │   │   │   ├── 44/
│   │   │   │   │   └── 30fd3f45c832e685350417600a9862c94d20f1
│   │   │   │   ├── 46/
│   │   │   │   │   └── 677964e679f3e727356d0860c643a12a87902b
│   │   │   │   ├── 50/
│   │   │   │   │   └── a127cb066eb903a6fa59d71802c10cb442fb3b
│   │   │   │   ├── 55/
│   │   │   │   │   └── ad5af2a93afa778971e3d04faf20f6c368b6ba
│   │   │   │   ├── 6b/
│   │   │   │   │   └── 0c0b32bdca3af9beb831744cb755d6fdc7c7c0
│   │   │   │   ├── 75/
│   │   │   │   │   └── 179304f4fab00613f08a9412b6cb0965bfa564
│   │   │   │   ├── 7c/
│   │   │   │   │   └── 36daf29660ae4a2f09345427ef76f1d38f902f
│   │   │   │   ├── 88/
│   │   │   │   │   └── e0473c9da347c6311f5f8eca8d256bf25402b6
│   │   │   │   ├── bd/
│   │   │   │   │   └── c7bec8acae9b3eabf0a15b223a48211b7a89a1
│   │   │   │   ├── c7/
│   │   │   │   │   └── 97f979cf24ba148bf10d5e26f5d7402dd5f2e1
│   │   │   │   └── da/
│   │   │   │       └── ae380200ed6eeaafd926177018e8ff3009b988
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           ├── master
│   │   │           └── mybranch
│   │   └── poem.txt
│   ├── conflict.rb
│   ├── contribute.rb
│   ├── delete_branch/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-push.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           ├── delete_me
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── b6/
│   │   │   │   │   └── 0afe294eb3c200d646995c9e0234470157c1b0
│   │   │   │   ├── e6/
│   │   │   │   │   └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│   │   │   │   └── e8/
│   │   │   │       └── 0ad49ace82167de62e498622d70377d913c79e
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           ├── delete_me
│   │   │           └── master
│   │   └── readme
│   ├── delete_branch.rb
│   ├── diff/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-commit.sample
│   │   │   │   ├── post-receive.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── 1b/
│   │   │   │   │   └── 6582364621c92707b587409cedbc4f77fc0cee
│   │   │   │   ├── 4f/
│   │   │   │   │   └── 703ca9bd25781b6758eeb3c42ed5348610ba6d
│   │   │   │   └── dc/
│   │   │   │       └── aa55e97af34402e84d5336da37abcccc23cba6
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           └── master
│   │   └── app.rb
│   ├── diff.rb
│   ├── fetch.rb
│   ├── find_old_branch/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── ORIG_HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-commit.sample
│   │   │   │   ├── post-receive.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           ├── blowup_sun_for_ransom
│   │   │   │           ├── cure_common_cold
│   │   │   │           ├── kill_the_batman
│   │   │   │           └── solve_world_hunger
│   │   │   ├── objects/
│   │   │   │   ├── 05/
│   │   │   │   │   └── e9c01bd3c9264761dd0cde477400a2c3104642
│   │   │   │   ├── 1f/
│   │   │   │   │   └── 0a136ddd98f61934d15eb00444df32d8e8254b
│   │   │   │   ├── 32/
│   │   │   │   │   └── 4336a8401afc8ca384eaafe6615c84d552dd2c
│   │   │   │   ├── 50/
│   │   │   │   │   └── 72aab6bd73accec89ad3aa077f43aab8a5e507
│   │   │   │   ├── 5d/
│   │   │   │   │   └── 130caf89f1a4bba6a1fffe72c484f3ab659e08
│   │   │   │   ├── 68/
│   │   │   │   │   └── 76e5b41fb693190df76b1baef6ef98623b4f1a
│   │   │   │   ├── 6a/
│   │   │   │   │   └── 7702145d1eb91c9f79583eabb984027b12e60c
│   │   │   │   ├── 89/
│   │   │   │   │   └── 4a16d6f1a48224e9006b4a6f0fe3846da19bec
│   │   │   │   ├── b8/
│   │   │   │   │   └── c67b45e5fe9e4b39ac7ade725673f7c90bdfc3
│   │   │   │   └── bf/
│   │   │   │       └── 76434bc7e7346c6fef5a98aee0f7cfc0788f34
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           ├── blowup_sun_for_ransom
│   │   │           ├── cure_common_cold
│   │   │           ├── kill_the_batman
│   │   │           └── solve_world_hunger
│   │   ├── TODO
│   │   └── myfile.txt
│   ├── find_old_branch.rb
│   ├── grep/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-commit.sample
│   │   │   │   ├── post-receive.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── 12/
│   │   │   │   │   └── c702f8b25b6b528cf904670b854dba3eba0f45
│   │   │   │   ├── 6f/
│   │   │   │   │   └── 45753f4a16b69f5b2215f2dbe8245f073353cc
│   │   │   │   ├── a4/
│   │   │   │   │   └── 1fe0c342be5c9930328cbb4315acebbd9c94b2
│   │   │   │   └── d3/
│   │   │   │       └── f53e82aa015d1eea3b06c3b62dfbacee83bbe1
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           └── master
│   │   ├── app.rb
│   │   └── config.rb
│   ├── grep.rb
│   ├── ignore.rb
│   ├── include.rb
│   ├── init.rb
│   ├── log.rb
│   ├── merge/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-commit.sample
│   │   │   │   ├── post-receive.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           ├── feature
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── ad/
│   │   │   │   │   └── 24149d789e59d4b5f9ce41cda90110ca0f98b7
│   │   │   │   ├── ae/
│   │   │   │   │   └── fde3a01f6e10d72fd4899ce14c8b2654d3eb45
│   │   │   │   ├── cc/
│   │   │   │   │   └── 8ea5a233df119d025eb240b9470e1ca76a151c
│   │   │   │   ├── e1/
│   │   │   │   │   └── 2277fe88657a072f1c4eb7d9320e4e6a74ba95
│   │   │   │   └── e6/
│   │   │   │       └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           ├── feature
│   │   │           └── master
│   │   └── file1
│   ├── merge.rb
│   ├── merge_squash.rb
│   ├── number_of_files_committed.rb
│   ├── pull.rb
│   ├── push.rb
│   ├── push_branch.rb
│   ├── push_tags.rb
│   ├── rebase/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── ORIG_HEAD
│   │   │   ├── config
│   │   │   ├── index
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           ├── feature
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── 0c/
│   │   │   │   │   └── d212c5b28da2e65ed4900712dd36c8adce48ad
│   │   │   │   ├── 44/
│   │   │   │   │   └── 19b972c0cd1b346ac90332aa7c5cc949589f78
│   │   │   │   ├── 54/
│   │   │   │   │   └── 3b9bebdc6bd5c4b22136034a95dd097a57d3dd
│   │   │   │   ├── 81/
│   │   │   │   │   └── 78c76d627cade75005b40711b92f4177bc6cfc
│   │   │   │   ├── 98/
│   │   │   │   │   └── 205e9faf10cf33d2ef7c0f66e402540c62613a
│   │   │   │   ├── a7/
│   │   │   │   │   └── 8bcab6232e9382a86436cdfcb2ed0391b1f0ac
│   │   │   │   ├── b7/
│   │   │   │   │   └── 7313d7be366609dd2e77aa96d7fd73f4e27853
│   │   │   │   ├── b9/
│   │   │   │   │   └── 2d5d55d379cfb90b750e6472fc983f32ad9a71
│   │   │   │   ├── e6/
│   │   │   │   │   └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│   │   │   │   └── ed/
│   │   │   │       └── 0fdcf366b21b8984fb37ea34106978a2e5c5ba
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           ├── feature
│   │   │           └── master
│   │   └── README
│   ├── rebase.rb
│   ├── rebase_onto.rb
│   ├── remote.rb
│   ├── remote_add.rb
│   ├── remote_url.rb
│   ├── rename.rb
│   ├── rename_commit.rb
│   ├── reorder.rb
│   ├── repack.rb
│   ├── reset.rb
│   ├── reset_soft.rb
│   ├── restore.rb
│   ├── restructure.rb
│   ├── revert.rb
│   ├── rm.rb
│   ├── rm_cached.rb
│   ├── squash.rb
│   ├── stage_lines.rb
│   ├── stash/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── 02/
│   │   │   │   │   └── 060592b31c9e12ffe1b282addf9537c5ef8e1f
│   │   │   │   ├── 4b/
│   │   │   │   │   └── 825dc642cb6eb9a060e54bf8d69288fbee4904
│   │   │   │   ├── 7f/
│   │   │   │   │   └── 82d7e4fba66980af16da540e18d8955518cdc2
│   │   │   │   └── 85/
│   │   │   │       └── e560abcd7e3255dcd91982476e432f4d3d1b51
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           └── master
│   │   └── lyrics.txt
│   ├── stash.rb
│   ├── status.rb
│   ├── submodule.rb
│   └── tag.rb
├── lib/
│   ├── githug/
│   │   ├── cli.rb
│   │   ├── extensions/
│   │   │   └── grit/
│   │   │       └── ruby1.9.rb
│   │   ├── game.rb
│   │   ├── level.rb
│   │   ├── profile.rb
│   │   ├── repository.rb
│   │   ├── ui.rb
│   │   └── version.rb
│   └── githug.rb
└── spec/
    ├── githug/
    │   ├── cli_spec.rb
    │   ├── game_spec.rb
    │   ├── level_spec.rb
    │   ├── profile_spec.rb
    │   ├── repository_spec.rb
    │   └── ui_spec.rb
    ├── githug_spec.rb
    ├── spec_helper.rb
    └── support/
        └── files/
            └── test_level.rb

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
*.gem
.bundle
Gemfile.lock
pkg/*
*.swp
.rvmrc
git_hug/*
.profile.yml

================================================
FILE: .rspec
================================================
--color
--order default


================================================
FILE: .travis.yml
================================================
language: ruby
dist: focal
rvm:
  - 2.4.10
  - 2.5.9
  - 2.6.8
  - 2.7.4
  - 3.0.1
  - ruby-head

matrix:
  allow_failures:
    - rvm: ruby-head

before_install:
  - gem update --system
  - git config --global user.email 'user@example.com'
  - git config --global user.name 'Test User'


================================================
FILE: Dockerfile
================================================
FROM ruby:slim

LABEL org.opencontainers.image.authors="diraneyya@ip.rwth-aachen.de"

# This is in order to have the man pages during exercises
RUN sed -i '/path-exclude \/usr\/share\/man/d' /etc/dpkg/dpkg.cfg.d/docker
RUN sed -i '/path-exclude \/usr\/share\/groff/d' /etc/dpkg/dpkg.cfg.d/docker
RUN apt update && apt install -y man git && apt install --reinstall coreutils

# The DATA_PATH is used for the deliverables, or the submissible
# content for the classroom activity.
ENV DATA_PATH="/data"
# The REPO_PATH is where the original or the teacher's forked repo
# resides inside the container.
ENV REPO_PATH="/root/githug"
# The LEVEL_PATH is where the current challenge resides and where
# students should navigate prior to attemping to use the `githug`
# commands.
ENV LEVEL_PATH="/git_hug"
ENV GITHUG_GITCONF="/root/.gitconfig"
ENV GITHUG_PROFILE="$LEVEL_PATH/.profile.yml"
ENV GITHUG_HISTORY_OUTPUT="$DATA_PATH/history.txt"
ENV GITHUG_PROFILE_OUTPUT="$DATA_PATH/profile.yml"
ENV GITHUG_GITCONF_OUTPUT="$DATA_PATH/gitconfig"

RUN mkdir -p $DATA_PATH
ADD . $REPO_PATH
WORKDIR $REPO_PATH
RUN gem build
RUN gem install *.gem

WORKDIR /
RUN echo "y" | $GEM_HOME/bin/githug
RUN cp $GITHUG_PROFILE $GITHUG_PROFILE_OUTPUT

WORKDIR $LEVEL_PATH

# The bash login script in below clears the history and restores
# progress using the contents of the $GITHUG_PROFILE_OUTPUT file.
RUN printf "history -c\nHISTSIZE= \nHISTFILESIZE= \n\
echo '--- NEW SESSION ---' >> $GITHUG_HISTORY_OUTPUT \n\
if ! [ -e $GITHUG_PROFILE_OUTPUT ]; then \n\
    echo 'ERROR: Corrupt level progress data. Exiting.' \n\
    echo '>>> CORRUPT DATA <<<' >> $GITHUG_HISTORY_OUTPUT \n\
    exit 1; fi \n\
cp $GITHUG_GITCONF_OUTPUT $GITHUG_GITCONF \n\
mkdir -p $LEVEL_PATH && cp $GITHUG_PROFILE_OUTPUT $GITHUG_PROFILE \n\
export PATH=\"\$GEM_HOME/bin:\$PATH\" \n\
cd $LEVEL_PATH && githug reset \n\
echo -e '\nIMPORTANT: everything you type in this container is \
recorded to assist in the grading process.' \n" >> ~/.bash_profile

RUN printf "history -a\ncat \$HISTFILE >> $GITHUG_HISTORY_OUTPUT \n\
cp $GITHUG_PROFILE $GITHUG_PROFILE_OUTPUT \n\
cp $GITHUG_GITCONF $GITHUG_GITCONF_OUTPUT 2>/dev/null \n\
cp $GITHUG_PROFILE $GITHUG_PROFILE_OUTPUT \n" >> ~/.bash_logout 

ENTRYPOINT ["/bin/bash", "--login"]
VOLUME $DATA_PATH


================================================
FILE: Gemfile
================================================
source "http://rubygems.org"

# Specify your gem's dependencies in githug.gemspec
gemspec


================================================
FILE: LICENCE.txt
================================================
Copyright (c) 2013  Gary 'Gazler' Rennie

MIT License

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# Githug
Git Your Game On 

[![Build Status](https://travis-ci.org/Gazler/githug.svg?branch=master)](https://travis-ci.org/Gazler/githug) [![Code Climate](https://codeclimate.com/github/Gazler/githug.svg)](https://codeclimate.com/github/Gazler/githug)

## About
Githug is designed to give you a practical way of learning git.  It has a series of levels, each requiring you to use git commands to arrive at a correct answer.

## Playing Githug

Githug should work on Linux, OS X and Windows.

### Prerequisites

Githug requires Ruby 1.8.7 or higher.

You can check which version of Ruby is installed with the following command:

```
ruby --version
```

If ruby is not installed, follow the installation instructions on [ruby-lang.org](https://www.ruby-lang.org/en/documentation/installation/).

### Installation

To install Githug, run

    gem install githug

If you get a complaint about permissions, you can rerun the command with `sudo`:

    sudo gem install githug
    
#### Usage with Docker

An unofficial _Docker_ image for this project by [@odiraneyya](https://github.com/odiraneyya) is available on ([Docker Hub](https://hub.docker.com/r/orwa84/githug)).

### Starting the Game

After the gem is installed change directory to the location where you want the game-related assets to be stored.
Then run `githug`:

    githug

You will be prompted to create a directory.

    No githug directory found, do you wish to create one? [yn]

Type `y` (yes) to continue, `n` (no) to cancel and quit Githug.

### Commands

Githug has 4 game commands:

 * play - The default command, checks your solution for the current level
 * hint - Gives you a hint (if available) for the current level
 * reset - Reset the current level or reset the level to a given name or path
 * levels - List all the levels

## Change Log

The change log is available on the wiki.  [Change log](https://github.com/Gazler/githug/wiki/Change-Log)

## Contributing

To suggest a level or create a level that has been suggested, check out [the wiki](https://github.com/Gazler/githug/wiki).

 Get yourself on the [contributors list](https://github.com/Gazler/githug/contributors) by doing the following:

 * Fork the repository
 * Make a level in the levels directory (covered below)
 * Add your level to the LEVELS array inside `lib/githug/level.rb` in a position that makes sense (the "commit" level after the "add" and "init" levels for example)
 * Make sure your level works (covered below)
 * Submit a pull request

## Todo List

 * A follow-up to the level, more information on a specific command, etc.
 * More levels!

## Writing Levels

Githug has a DSL for writing levels. Here is an example:

```ruby
difficulty 1
description "There is a file in your folder called README, you should add it to your staging area"

setup do
  repo.init
  FileUtils.touch("README")
end

solution do
  return false unless repo.status.files.keys.include?("README")
  return false if repo.status.files["README"].untracked

  true
end

hint do
  puts "You can type `git` in your shell to get a list of available git commands"
end
```

 `difficulty`, `description` and `solution` are required.

You can include multiple hints like this:

```ruby
hints [
  "You can type `git` in your shell to get a list of available git commands",
  "Check the man for `git add`"]
```

 By default, `setup` will remove all files from the game folder.  You do not need to include a setup method if you don't want an initial git repository (if you are testing `git init` or only checking an answer.)

 You can call `repo.init` to initialize an empty repository.

 All methods called on `repo` are sent to the [grit gem](https://github.com/mojombo/grit) if the method does not exist, and you can use that for most git related commands (`repo.add`, `repo.commit`, etc.).

Another method exists called `init_from_level` and it is used like so:

```ruby
setup do
  init_from_level
end
```

This will copy the contents of a repository specified in the levels folder for your level.  For example, if your level is called "merge" then it will copy the contents of the "merge" folder.  It is recommended that you perform the following steps:

 * mkdir "yourlevel"
 * cd "yourlevel"
 * git init
 * some git stuff
 * **important** rename ".git" to ".githug" so that it isn't treated as a submodule
 * cd "../"
 * git add "yourlevel"

After doing this, your level should be able to copy the contents from that git repository and use those for your level.  See the "blame" level for an example of this.

## Testing Levels

The easiest way to test a level is:

 * Change into your git_hug repository
 * Run `githug reset PATH_TO_YOUR_LEVEL`
 * Solve the level
 * Run `githug test PATH_TO_YOUR_LEVEL`

Please note that the `githug test` command can be run as `githug test --errors` to get an error stack trace from your solve method.

It would be ideal if you add an integration test for your level.  These tests live in `spec/githug_spec` and **must** be run in order.  If you add a level but do not add a test, please add a simple `skip_level` test case similar to the `contribute` level.

## FAQs

1. Answers are not being checked properly

   *This is a common issue we are facing and we are actively working to fix it.*

   For now, run the following commands to change the default branch name to master. This should fix most of the issues you may face.
   ```
   $ git config --global init.defaultBranch master
   $ githug reset
   ```

   From the current level forward, the default branch will be `master`.

2. `githug` command doesn't work

    Githug currently isn't supported on ruby versions ^3.0.0. Use any ruby version below 3.0.0 (preferrably 2.7.1).

    If you use rvm, execute the below commands

    ```
    $ rvm install 2.7.1
    $ rvm use 2.7.1
    ```

    If you use rbenv, execute the below commands

    ```
    $ rbenv install 2.7.1
    $ rbenv global 2.7.1
    ```



================================================
FILE: Rakefile
================================================
require "bundler/gem_tasks"
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec)

task :default => [:spec]


================================================
FILE: bin/githug
================================================
#!/usr/bin/env ruby
require 'githug/cli'

Githug::CLI.start


================================================
FILE: githug.gemspec
================================================
# -*- encoding: utf-8 -*-
$:.push File.expand_path("../lib", __FILE__)
require "githug/version"

Gem::Specification.new do |s|
  s.name        = "githug"
  s.version     = Githug::VERSION
  s.authors     = ["Gary Rennie"]
  s.email       = ["gazler@gmail.com"]
  s.homepage    = "https://github.com/Gazler/githug"
  s.summary     = %q{An interactive way to learn git.}
  s.description = %q{An interactive way to learn git.}

  s.rubyforge_project = "githug"

  s.files         = `git ls-files`.split("\n")
  s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
  s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
  s.require_paths = ["lib"]

  # specify any dependencies here; for example:
  s.add_development_dependency "rspec", "~>2.8.0"

  s.add_dependency "grit", "~>2.3.0"
  s.add_dependency "thor", "~>0.14.6"
  s.add_dependency "rake", "<11"
end


================================================
FILE: levels/add.rb
================================================
difficulty 1
description "There is a file in your folder called `README`; add it to your staging area.
Note: Each level starts with a new repo. Don't look for files of the previous one."

setup do
  repo.init
  FileUtils.touch("README")
  system "git branch -m master"
end

solution do
  return false unless repo.status.files.keys.include?("README")
  return false if repo.status.files["README"].untracked
  true
end

hint do
  puts "You can type `git` in your shell to get a list of available git commands."
end


================================================
FILE: levels/bisect/.githug/COMMIT_EDITMSG
================================================
Another Commit


================================================
FILE: levels/bisect/.githug/HEAD
================================================
ref: refs/heads/master


================================================
FILE: levels/bisect/.githug/ORIG_HEAD
================================================
f351ca63a759f56bb26924fd566294eb23455c71


================================================
FILE: levels/bisect/.githug/config
================================================
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[pack]
	deltaCacheSize = 1


================================================
FILE: levels/bisect/.githug/description
================================================
Unnamed repository; edit this file 'description' to name the repository.


================================================
FILE: levels/bisect/.githug/gitk.cache
================================================
1 1
f351ca63a759f56bb26924fd566294eb23455c71 f608824888b83bbedc1f658be7496ffea467a8fb {7f8406e742c5281ec2c9bc3c6cc69dc6ba5311fd 36da01fb0571360b0e1170f0cb46e74f72927cda c1b80f5ed4995cda8e19027f0776351af6b76703 4145057e11ab90109c95882b1f40d560da408bfa 94e162b505bc2290fb67764357a625192f8a4e8a bfb16eec1081387b586dc8009ef422cfff60b622 c0a1cdff8dd63948a5fc41f5871681c5b133c053 e8dd08d5aabb62b56c80320672cd8d42e2b8954d 89d27c5f4680cd21028947be75c33a68511decb9 98d617d3bdf0b6c59d6177233acb4b9fd54b7aac 0b194f30d6867522d1666590087e6c0b5e20dc93 d406b1b8bc269c9aef9127299e83947220e7a9b0 f608824888b83bbedc1f658be7496ffea467a8fb}
1


================================================
FILE: levels/bisect/.githug/hooks/applypatch-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message taken by
# applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.  The hook is
# allowed to edit the commit message file.
#
# To enable this hook, rename this file to "applypatch-msg".

. git-sh-setup
test -x "$GIT_DIR/hooks/commit-msg" &&
	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
:


================================================
FILE: levels/bisect/.githug/hooks/commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message.  The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit.  The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".

# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

# This example catches duplicate Signed-off-by lines.

test "" = "$(grep '^Signed-off-by: ' "$1" |
	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
	echo >&2 Duplicate Signed-off-by lines.
	exit 1
}


================================================
FILE: levels/bisect/.githug/hooks/post-commit.sample
================================================
#!/bin/sh
#
# An example hook script that is called after a successful
# commit is made.
#
# To enable this hook, rename this file to "post-commit".

: Nothing


================================================
FILE: levels/bisect/.githug/hooks/post-receive.sample
================================================
#!/bin/sh
#
# An example hook script for the "post-receive" event.
#
# The "post-receive" script is run after receive-pack has accepted a pack
# and the repository has been updated.  It is passed arguments in through
# stdin in the form
#  <oldrev> <newrev> <refname>
# For example:
#  aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
#
# see contrib/hooks/ for a sample, or uncomment the next line and
# rename the file to "post-receive".

#. /usr/share/doc/git-core/contrib/hooks/post-receive-email


================================================
FILE: levels/bisect/.githug/hooks/post-update.sample
================================================
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".

exec git update-server-info


================================================
FILE: levels/bisect/.githug/hooks/pre-applypatch.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed
# by applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-applypatch".

. git-sh-setup
test -x "$GIT_DIR/hooks/pre-commit" &&
	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
:


================================================
FILE: levels/bisect/.githug/hooks/pre-commit.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
	against=HEAD
else
	# Initial commit: diff against an empty tree object
	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# If you want to allow non-ascii filenames set this variable to true.
allownonascii=$(git config hooks.allownonascii)

# Cross platform projects tend to avoid non-ascii filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
	# Note that the use of brackets around a tr range is ok here, (it's
	# even required, for portability to Solaris 10's /usr/bin/tr), since
	# the square bracket bytes happen to fall in the designated range.
	test "$(git diff --cached --name-only --diff-filter=A -z $against |
	  LC_ALL=C tr -d '[ -~]\0')"
then
	echo "Error: Attempt to add a non-ascii file name."
	echo
	echo "This can cause problems if you want to work"
	echo "with people on other platforms."
	echo
	echo "To be portable it is advisable to rename the file ..."
	echo
	echo "If you know what you are doing you can disable this"
	echo "check using:"
	echo
	echo "  git config hooks.allownonascii true"
	echo
	exit 1
fi

exec git diff-index --check --cached $against --


================================================
FILE: levels/bisect/.githug/hooks/pre-rebase.sample
================================================
#!/bin/sh
#
# Copyright (c) 2006, 2008 Junio C Hamano
#
# The "pre-rebase" hook is run just before "git rebase" starts doing
# its job, and can prevent the command from running by exiting with
# non-zero status.
#
# The hook is called with the following parameters:
#
# $1 -- the upstream the series was forked from.
# $2 -- the branch being rebased (or empty when rebasing the current branch).
#
# This sample shows how to prevent topic branches that are already
# merged to 'next' branch from getting rebased, because allowing it
# would result in rebasing already published history.

publish=next
basebranch="$1"
if test "$#" = 2
then
	topic="refs/heads/$2"
else
	topic=`git symbolic-ref HEAD` ||
	exit 0 ;# we do not interrupt rebasing detached HEAD
fi

case "$topic" in
refs/heads/??/*)
	;;
*)
	exit 0 ;# we do not interrupt others.
	;;
esac

# Now we are dealing with a topic branch being rebased
# on top of master.  Is it OK to rebase it?

# Does the topic really exist?
git show-ref -q "$topic" || {
	echo >&2 "No such branch $topic"
	exit 1
}

# Is topic fully merged to master?
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
if test -z "$not_in_master"
then
	echo >&2 "$topic is fully merged to master; better remove it."
	exit 1 ;# we could allow it, but there is no point.
fi

# Is topic ever merged to next?  If so you should not be rebasing it.
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
only_next_2=`git rev-list ^master           ${publish} | sort`
if test "$only_next_1" = "$only_next_2"
then
	not_in_topic=`git rev-list "^$topic" master`
	if test -z "$not_in_topic"
	then
		echo >&2 "$topic is already up-to-date with master"
		exit 1 ;# we could allow it, but there is no point.
	else
		exit 0
	fi
else
	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
	/usr/bin/perl -e '
		my $topic = $ARGV[0];
		my $msg = "* $topic has commits already merged to public branch:\n";
		my (%not_in_next) = map {
			/^([0-9a-f]+) /;
			($1 => 1);
		} split(/\n/, $ARGV[1]);
		for my $elem (map {
				/^([0-9a-f]+) (.*)$/;
				[$1 => $2];
			} split(/\n/, $ARGV[2])) {
			if (!exists $not_in_next{$elem->[0]}) {
				if ($msg) {
					print STDERR $msg;
					undef $msg;
				}
				print STDERR " $elem->[1]\n";
			}
		}
	' "$topic" "$not_in_next" "$not_in_master"
	exit 1
fi

exit 0

<<\DOC_END
################################################################

This sample hook safeguards topic branches that have been
published from being rewound.

The workflow assumed here is:

 * Once a topic branch forks from "master", "master" is never
   merged into it again (either directly or indirectly).

 * Once a topic branch is fully cooked and merged into "master",
   it is deleted.  If you need to build on top of it to correct
   earlier mistakes, a new topic branch is created by forking at
   the tip of the "master".  This is not strictly necessary, but
   it makes it easier to keep your history simple.

 * Whenever you need to test or publish your changes to topic
   branches, merge them into "next" branch.

The script, being an example, hardcodes the publish branch name
to be "next", but it is trivial to make it configurable via
$GIT_DIR/config mechanism.

With this workflow, you would want to know:

(1) ... if a topic branch has ever been merged to "next".  Young
    topic branches can have stupid mistakes you would rather
    clean up before publishing, and things that have not been
    merged into other branches can be easily rebased without
    affecting other people.  But once it is published, you would
    not want to rewind it.

(2) ... if a topic branch has been fully merged to "master".
    Then you can delete it.  More importantly, you should not
    build on top of it -- other people may already want to
    change things related to the topic as patches against your
    "master", so if you need further changes, it is better to
    fork the topic (perhaps with the same name) afresh from the
    tip of "master".

Let's look at this example:

		   o---o---o---o---o---o---o---o---o---o "next"
		  /       /           /           /
		 /   a---a---b A     /           /
		/   /               /           /
	       /   /   c---c---c---c B         /
	      /   /   /             \         /
	     /   /   /   b---b C     \       /
	    /   /   /   /             \     /
    ---o---o---o---o---o---o---o---o---o---o---o "master"


A, B and C are topic branches.

 * A has one fix since it was merged up to "next".

 * B has finished.  It has been fully merged up to "master" and "next",
   and is ready to be deleted.

 * C has not merged to "next" at all.

We would want to allow C to be rebased, refuse A, and encourage
B to be deleted.

To compute (1):

	git rev-list ^master ^topic next
	git rev-list ^master        next

	if these match, topic has not merged in next at all.

To compute (2):

	git rev-list master..topic

	if this is empty, it is fully merged to "master".

DOC_END


================================================
FILE: levels/bisect/.githug/hooks/prepare-commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to prepare the commit log message.
# Called by "git commit" with the name of the file that has the
# commit message, followed by the description of the commit
# message's source.  The hook's purpose is to edit the commit
# message file.  If the hook fails with a non-zero status,
# the commit is aborted.
#
# To enable this hook, rename this file to "prepare-commit-msg".

# This hook includes three examples.  The first comments out the
# "Conflicts:" part of a merge commit.
#
# The second includes the output of "git diff --name-status -r"
# into the message, just before the "git status" output.  It is
# commented because it doesn't cope with --amend or with squashed
# commits.
#
# The third example adds a Signed-off-by line to the message, that can
# still be edited.  This is rarely a good idea.

case "$2,$3" in
  merge,)
    /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;

# ,|template,)
#   /usr/bin/perl -i.bak -pe '
#      print "\n" . `git diff --cached --name-status -r`
#	 if /^#/ && $first++ == 0' "$1" ;;

  *) ;;
esac

# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"


================================================
FILE: levels/bisect/.githug/hooks/update.sample
================================================
#!/bin/sh
#
# An example hook script to blocks unannotated tags from entering.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
# Config
# ------
# hooks.allowunannotated
#   This boolean sets whether unannotated tags will be allowed into the
#   repository.  By default they won't be.
# hooks.allowdeletetag
#   This boolean sets whether deleting tags will be allowed in the
#   repository.  By default they won't be.
# hooks.allowmodifytag
#   This boolean sets whether a tag may be modified after creation. By default
#   it won't be.
# hooks.allowdeletebranch
#   This boolean sets whether deleting branches will be allowed in the
#   repository.  By default they won't be.
# hooks.denycreatebranch
#   This boolean sets whether remotely creating branches will be denied
#   in the repository.  By default this is allowed.
#

# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"

# --- Safety check
if [ -z "$GIT_DIR" ]; then
	echo "Don't run this script from the command line." >&2
	echo " (if you want, you could supply GIT_DIR then run" >&2
	echo "  $0 <ref> <oldrev> <newrev>)" >&2
	exit 1
fi

if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
	exit 1
fi

# --- Config
allowunannotated=$(git config --bool hooks.allowunannotated)
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
denycreatebranch=$(git config --bool hooks.denycreatebranch)
allowdeletetag=$(git config --bool hooks.allowdeletetag)
allowmodifytag=$(git config --bool hooks.allowmodifytag)

# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
case "$projectdesc" in
"Unnamed repository"* | "")
	echo "*** Project description file hasn't been set" >&2
	exit 1
	;;
esac

# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero="0000000000000000000000000000000000000000"
if [ "$newrev" = "$zero" ]; then
	newrev_type=delete
else
	newrev_type=$(git cat-file -t $newrev)
fi

case "$refname","$newrev_type" in
	refs/tags/*,commit)
		# un-annotated tag
		short_refname=${refname##refs/tags/}
		if [ "$allowunannotated" != "true" ]; then
			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
			exit 1
		fi
		;;
	refs/tags/*,delete)
		# delete tag
		if [ "$allowdeletetag" != "true" ]; then
			echo "*** Deleting a tag is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/tags/*,tag)
		# annotated tag
		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
		then
			echo "*** Tag '$refname' already exists." >&2
			echo "*** Modifying a tag is not allowed in this repository." >&2
			exit 1
		fi
		;;
	refs/heads/*,commit)
		# branch
		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
			echo "*** Creating a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/heads/*,delete)
		# delete branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/remotes/*,commit)
		# tracking branch
		;;
	refs/remotes/*,delete)
		# delete tracking branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	*)
		# Anything else (is there anything else?)
		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
		exit 1
		;;
esac

# --- Finished
exit 0


================================================
FILE: levels/bisect/.githug/info/exclude
================================================
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~


================================================
FILE: levels/bisect/.githug/info/refs
================================================
94e162b505bc2290fb67764357a625192f8a4e8a	refs/bisect/bad
bfb16eec1081387b586dc8009ef422cfff60b622	refs/bisect/good-bfb16eec1081387b586dc8009ef422cfff60b622
c0a1cdff8dd63948a5fc41f5871681c5b133c053	refs/bisect/good-c0a1cdff8dd63948a5fc41f5871681c5b133c053
f608824888b83bbedc1f658be7496ffea467a8fb	refs/bisect/good-f608824888b83bbedc1f658be7496ffea467a8fb
12628f463f4c722695bf0e9d603c9411287885db	refs/heads/master
32ae79196bd49a3416264970b0cd873e26bd1824	refs/tags/graetsch
89d27c5f4680cd21028947be75c33a68511decb9	refs/tags/graetsch^{}
2a5197909a0a1575145e0a40bb13dd54f5d6a9f7	refs/tags/orig_head
f351ca63a759f56bb26924fd566294eb23455c71	refs/tags/orig_head^{}


================================================
FILE: levels/bisect/.githug/logs/HEAD
================================================
f351ca63a759f56bb26924fd566294eb23455c71 f608824888b83bbedc1f658be7496ffea467a8fb Florian Sesser <fs@it-agenten.com> 1348697815 +0200	reset: moving to f608824888b83bbedc1f658be7496ffea467a8fb
f608824888b83bbedc1f658be7496ffea467a8fb f608824888b83bbedc1f658be7496ffea467a8fb Florian Sesser <fs@it-agenten.com> 1348697842 +0200	checkout: moving from master to hacklschorsch
f608824888b83bbedc1f658be7496ffea467a8fb 80a9b3d94237f982b6c9052e6d56b930f18a4ef5 Florian Sesser <fs@it-agenten.com> 1348697952 +0200	cherry-pick: Another Commit
80a9b3d94237f982b6c9052e6d56b930f18a4ef5 8c992afff5e16c97f4ef82d58671a3403d734086 Florian Sesser <fs@it-agenten.com> 1348697967 +0200	cherry-pick: Another Commit
8c992afff5e16c97f4ef82d58671a3403d734086 49774ea84ae3723cc4fac75521435cc04d56b657 Florian Sesser <fs@it-agenten.com> 1348698291 +0200	cherry-pick: Another Commit
49774ea84ae3723cc4fac75521435cc04d56b657 e060c0d789288fda946f91254672295230b2de9d Florian Sesser <fs@it-agenten.com> 1348698316 +0200	cherry-pick: Another Commit
e060c0d789288fda946f91254672295230b2de9d ffb097e3edfa828afa565eeceee6b506b3f2a131 Florian Sesser <fs@it-agenten.com> 1348698720 +0200	commit: Another Commit
ffb097e3edfa828afa565eeceee6b506b3f2a131 2e1735d5bef6db0f3e325051a179af280f05573a Florian Sesser <fs@it-agenten.com> 1348698824 +0200	commit: Another Commit
2e1735d5bef6db0f3e325051a179af280f05573a ccddb96f824a0e929f5fecf55c0f4479552246f3 Florian Sesser <fs@it-agenten.com> 1348698884 +0200	commit: Another Commit
ccddb96f824a0e929f5fecf55c0f4479552246f3 a530e7ed25173d0800cfe33cc8915e5929209b8e Florian Sesser <fs@it-agenten.com> 1348698911 +0200	commit: Another Commit
a530e7ed25173d0800cfe33cc8915e5929209b8e fdbfc0d403e5ac0b2659cbfa2cbb061fcca0dc2a Florian Sesser <fs@it-agenten.com> 1348699468 +0200	commit: Another Commit
fdbfc0d403e5ac0b2659cbfa2cbb061fcca0dc2a 5d1eb75377072c5c6e5a1b0ac4159181ecc4edff Florian Sesser <fs@it-agenten.com> 1348699592 +0200	commit: Another Commit
5d1eb75377072c5c6e5a1b0ac4159181ecc4edff 9f54462abbb991b167532929b34118113aa6c52e Florian Sesser <fs@it-agenten.com> 1348699604 +0200	cherry-pick: Another Commit
9f54462abbb991b167532929b34118113aa6c52e 7c03a99ba384572c216769f0273b5baf3ba83694 Florian Sesser <fs@it-agenten.com> 1348699614 +0200	cherry-pick: Another Commit
7c03a99ba384572c216769f0273b5baf3ba83694 5db7a7cb90e745e2c9dbdd84810ccc7d91d92e72 Florian Sesser <fs@it-agenten.com> 1348699625 +0200	cherry-pick: Another Commit
5db7a7cb90e745e2c9dbdd84810ccc7d91d92e72 18ed2ac1522a014412d4303ce7c8db39becab076 Florian Sesser <fs@it-agenten.com> 1348699635 +0200	cherry-pick: Another Commit
18ed2ac1522a014412d4303ce7c8db39becab076 bb736ddd9b83d6296d23444a2ab3b0d2fa6dfb81 Florian Sesser <fs@it-agenten.com> 1348699648 +0200	cherry-pick: Another Commit
bb736ddd9b83d6296d23444a2ab3b0d2fa6dfb81 888386c77c957dc52f3113f2483663e3132559d4 Florian Sesser <fs@it-agenten.com> 1348699657 +0200	cherry-pick: Another Commit
888386c77c957dc52f3113f2483663e3132559d4 028763b396121e035f672ef5af75d2dcb1cc8146 Florian Sesser <fs@it-agenten.com> 1348699668 +0200	cherry-pick: Another Commit
028763b396121e035f672ef5af75d2dcb1cc8146 979576184c5ec9667cf7593cf550c420378e960f Florian Sesser <fs@it-agenten.com> 1348699679 +0200	cherry-pick: Another Commit
979576184c5ec9667cf7593cf550c420378e960f 12628f463f4c722695bf0e9d603c9411287885db Florian Sesser <fs@it-agenten.com> 1348699693 +0200	cherry-pick: Another Commit


================================================
FILE: levels/bisect/.githug/logs/refs/heads/master
================================================
0000000000000000000000000000000000000000 f608824888b83bbedc1f658be7496ffea467a8fb Florian Sesser <fs@it-agenten.com> 1348697842 +0200	branch: Created from HEAD
f608824888b83bbedc1f658be7496ffea467a8fb 80a9b3d94237f982b6c9052e6d56b930f18a4ef5 Florian Sesser <fs@it-agenten.com> 1348697952 +0200	cherry-pick: Another Commit
80a9b3d94237f982b6c9052e6d56b930f18a4ef5 8c992afff5e16c97f4ef82d58671a3403d734086 Florian Sesser <fs@it-agenten.com> 1348697967 +0200	cherry-pick: Another Commit
8c992afff5e16c97f4ef82d58671a3403d734086 49774ea84ae3723cc4fac75521435cc04d56b657 Florian Sesser <fs@it-agenten.com> 1348698291 +0200	cherry-pick: Another Commit
49774ea84ae3723cc4fac75521435cc04d56b657 e060c0d789288fda946f91254672295230b2de9d Florian Sesser <fs@it-agenten.com> 1348698316 +0200	cherry-pick: Another Commit
e060c0d789288fda946f91254672295230b2de9d ffb097e3edfa828afa565eeceee6b506b3f2a131 Florian Sesser <fs@it-agenten.com> 1348698720 +0200	commit: Another Commit
ffb097e3edfa828afa565eeceee6b506b3f2a131 2e1735d5bef6db0f3e325051a179af280f05573a Florian Sesser <fs@it-agenten.com> 1348698824 +0200	commit: Another Commit
2e1735d5bef6db0f3e325051a179af280f05573a ccddb96f824a0e929f5fecf55c0f4479552246f3 Florian Sesser <fs@it-agenten.com> 1348698884 +0200	commit: Another Commit
ccddb96f824a0e929f5fecf55c0f4479552246f3 a530e7ed25173d0800cfe33cc8915e5929209b8e Florian Sesser <fs@it-agenten.com> 1348698911 +0200	commit: Another Commit
a530e7ed25173d0800cfe33cc8915e5929209b8e fdbfc0d403e5ac0b2659cbfa2cbb061fcca0dc2a Florian Sesser <fs@it-agenten.com> 1348699468 +0200	commit: Another Commit
fdbfc0d403e5ac0b2659cbfa2cbb061fcca0dc2a 5d1eb75377072c5c6e5a1b0ac4159181ecc4edff Florian Sesser <fs@it-agenten.com> 1348699592 +0200	commit: Another Commit
5d1eb75377072c5c6e5a1b0ac4159181ecc4edff 9f54462abbb991b167532929b34118113aa6c52e Florian Sesser <fs@it-agenten.com> 1348699604 +0200	cherry-pick: Another Commit
9f54462abbb991b167532929b34118113aa6c52e 7c03a99ba384572c216769f0273b5baf3ba83694 Florian Sesser <fs@it-agenten.com> 1348699614 +0200	cherry-pick: Another Commit
7c03a99ba384572c216769f0273b5baf3ba83694 5db7a7cb90e745e2c9dbdd84810ccc7d91d92e72 Florian Sesser <fs@it-agenten.com> 1348699625 +0200	cherry-pick: Another Commit
5db7a7cb90e745e2c9dbdd84810ccc7d91d92e72 18ed2ac1522a014412d4303ce7c8db39becab076 Florian Sesser <fs@it-agenten.com> 1348699635 +0200	cherry-pick: Another Commit
18ed2ac1522a014412d4303ce7c8db39becab076 bb736ddd9b83d6296d23444a2ab3b0d2fa6dfb81 Florian Sesser <fs@it-agenten.com> 1348699648 +0200	cherry-pick: Another Commit
bb736ddd9b83d6296d23444a2ab3b0d2fa6dfb81 888386c77c957dc52f3113f2483663e3132559d4 Florian Sesser <fs@it-agenten.com> 1348699657 +0200	cherry-pick: Another Commit
888386c77c957dc52f3113f2483663e3132559d4 028763b396121e035f672ef5af75d2dcb1cc8146 Florian Sesser <fs@it-agenten.com> 1348699668 +0200	cherry-pick: Another Commit
028763b396121e035f672ef5af75d2dcb1cc8146 979576184c5ec9667cf7593cf550c420378e960f Florian Sesser <fs@it-agenten.com> 1348699679 +0200	cherry-pick: Another Commit
979576184c5ec9667cf7593cf550c420378e960f 12628f463f4c722695bf0e9d603c9411287885db Florian Sesser <fs@it-agenten.com> 1348699693 +0200	cherry-pick: Another Commit
12628f463f4c722695bf0e9d603c9411287885db 12628f463f4c722695bf0e9d603c9411287885db Florian Sesser <fs@it-agenten.com> 1348701064 +0200	Branch: renamed refs/heads/hacklschorsch to refs/heads/master


================================================
FILE: levels/bisect/.githug/objects/info/packs
================================================
P pack-59fab357f3158a9640633de6a3326ed79a2b4fe6.pack



================================================
FILE: levels/bisect/.githug/packed-refs
================================================
# pack-refs with: peeled 
94e162b505bc2290fb67764357a625192f8a4e8a refs/bisect/bad
bfb16eec1081387b586dc8009ef422cfff60b622 refs/bisect/good-bfb16eec1081387b586dc8009ef422cfff60b622
c0a1cdff8dd63948a5fc41f5871681c5b133c053 refs/bisect/good-c0a1cdff8dd63948a5fc41f5871681c5b133c053
f608824888b83bbedc1f658be7496ffea467a8fb refs/bisect/good-f608824888b83bbedc1f658be7496ffea467a8fb
12628f463f4c722695bf0e9d603c9411287885db refs/heads/master
32ae79196bd49a3416264970b0cd873e26bd1824 refs/tags/graetsch
^89d27c5f4680cd21028947be75c33a68511decb9
2a5197909a0a1575145e0a40bb13dd54f5d6a9f7 refs/tags/orig_head
^f351ca63a759f56bb26924fd566294eb23455c71


================================================
FILE: levels/bisect/makefile
================================================
test:
	ruby prog.rb 5 | ruby test.rb


================================================
FILE: levels/bisect/prog.rb
================================================
#!/usr/bin/env ruby

puts Integer((Integer(ARGV[0])-3)*9)-1


================================================
FILE: levels/bisect/test.rb
================================================
#!/usr/bin/env ruby

line = gets
exit 1 if line != "15\n"


================================================
FILE: levels/bisect.rb
================================================
difficulty 3
description "A bug was introduced somewhere along the way. You know that running `ruby prog.rb 5` should output 15. You can also run `make test`. What are the first 7 chars of the hash of the commit (the abbreviated hash) that introduced the bug?"

setup do
  init_from_level
  repo.init
  system "git branch -m master"
end

solution do
  "18ed2ac" == request("What are the first 7 characters of the hash of the commit that introduced the bug?")[0..6]
end

hint do
  puts ["The fastest way to find the bug is with bisect.", "Don't forget to start bisect first, identify a good or bad commit, then run `git bisect run make test`."]
end


================================================
FILE: levels/blame/.githug/COMMIT_EDITMSG
================================================
added more options (no really)


================================================
FILE: levels/blame/.githug/HEAD
================================================
ref: refs/heads/master


================================================
FILE: levels/blame/.githug/config
================================================
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true


================================================
FILE: levels/blame/.githug/description
================================================
Unnamed repository; edit this file 'description' to name the repository.


================================================
FILE: levels/blame/.githug/hooks/applypatch-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message taken by
# applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.  The hook is
# allowed to edit the commit message file.
#
# To enable this hook, rename this file to "applypatch-msg".

. git-sh-setup
test -x "$GIT_DIR/hooks/commit-msg" &&
	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
:


================================================
FILE: levels/blame/.githug/hooks/commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message.  The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit.  The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".

# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

# This example catches duplicate Signed-off-by lines.

test "" = "$(grep '^Signed-off-by: ' "$1" |
	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
	echo >&2 Duplicate Signed-off-by lines.
	exit 1
}


================================================
FILE: levels/blame/.githug/hooks/post-commit.sample
================================================
#!/bin/sh
#
# An example hook script that is called after a successful
# commit is made.
#
# To enable this hook, rename this file to "post-commit".

: Nothing


================================================
FILE: levels/blame/.githug/hooks/post-receive.sample
================================================
#!/bin/sh
#
# An example hook script for the "post-receive" event.
#
# The "post-receive" script is run after receive-pack has accepted a pack
# and the repository has been updated.  It is passed arguments in through
# stdin in the form
#  <oldrev> <newrev> <refname>
# For example:
#  aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
#
# see contrib/hooks/ for a sample, or uncomment the next line and
# rename the file to "post-receive".

#. /usr/share/doc/git-core/contrib/hooks/post-receive-email


================================================
FILE: levels/blame/.githug/hooks/post-update.sample
================================================
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".

exec git update-server-info


================================================
FILE: levels/blame/.githug/hooks/pre-applypatch.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed
# by applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-applypatch".

. git-sh-setup
test -x "$GIT_DIR/hooks/pre-commit" &&
	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
:


================================================
FILE: levels/blame/.githug/hooks/pre-commit.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
	against=HEAD
else
	# Initial commit: diff against an empty tree object
	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# If you want to allow non-ascii filenames set this variable to true.
allownonascii=$(git config hooks.allownonascii)

# Cross platform projects tend to avoid non-ascii filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
	# Note that the use of brackets around a tr range is ok here, (it's
	# even required, for portability to Solaris 10's /usr/bin/tr), since
	# the square bracket bytes happen to fall in the designated range.
	test "$(git diff --cached --name-only --diff-filter=A -z $against |
	  LC_ALL=C tr -d '[ -~]\0')"
then
	echo "Error: Attempt to add a non-ascii file name."
	echo
	echo "This can cause problems if you want to work"
	echo "with people on other platforms."
	echo
	echo "To be portable it is advisable to rename the file ..."
	echo
	echo "If you know what you are doing you can disable this"
	echo "check using:"
	echo
	echo "  git config hooks.allownonascii true"
	echo
	exit 1
fi

exec git diff-index --check --cached $against --


================================================
FILE: levels/blame/.githug/hooks/pre-rebase.sample
================================================
#!/bin/sh
#
# Copyright (c) 2006, 2008 Junio C Hamano
#
# The "pre-rebase" hook is run just before "git rebase" starts doing
# its job, and can prevent the command from running by exiting with
# non-zero status.
#
# The hook is called with the following parameters:
#
# $1 -- the upstream the series was forked from.
# $2 -- the branch being rebased (or empty when rebasing the current branch).
#
# This sample shows how to prevent topic branches that are already
# merged to 'next' branch from getting rebased, because allowing it
# would result in rebasing already published history.

publish=next
basebranch="$1"
if test "$#" = 2
then
	topic="refs/heads/$2"
else
	topic=`git symbolic-ref HEAD` ||
	exit 0 ;# we do not interrupt rebasing detached HEAD
fi

case "$topic" in
refs/heads/??/*)
	;;
*)
	exit 0 ;# we do not interrupt others.
	;;
esac

# Now we are dealing with a topic branch being rebased
# on top of master.  Is it OK to rebase it?

# Does the topic really exist?
git show-ref -q "$topic" || {
	echo >&2 "No such branch $topic"
	exit 1
}

# Is topic fully merged to master?
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
if test -z "$not_in_master"
then
	echo >&2 "$topic is fully merged to master; better remove it."
	exit 1 ;# we could allow it, but there is no point.
fi

# Is topic ever merged to next?  If so you should not be rebasing it.
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
only_next_2=`git rev-list ^master           ${publish} | sort`
if test "$only_next_1" = "$only_next_2"
then
	not_in_topic=`git rev-list "^$topic" master`
	if test -z "$not_in_topic"
	then
		echo >&2 "$topic is already up-to-date with master"
		exit 1 ;# we could allow it, but there is no point.
	else
		exit 0
	fi
else
	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
	/usr/bin/perl -e '
		my $topic = $ARGV[0];
		my $msg = "* $topic has commits already merged to public branch:\n";
		my (%not_in_next) = map {
			/^([0-9a-f]+) /;
			($1 => 1);
		} split(/\n/, $ARGV[1]);
		for my $elem (map {
				/^([0-9a-f]+) (.*)$/;
				[$1 => $2];
			} split(/\n/, $ARGV[2])) {
			if (!exists $not_in_next{$elem->[0]}) {
				if ($msg) {
					print STDERR $msg;
					undef $msg;
				}
				print STDERR " $elem->[1]\n";
			}
		}
	' "$topic" "$not_in_next" "$not_in_master"
	exit 1
fi

exit 0

################################################################

This sample hook safeguards topic branches that have been
published from being rewound.

The workflow assumed here is:

 * Once a topic branch forks from "master", "master" is never
   merged into it again (either directly or indirectly).

 * Once a topic branch is fully cooked and merged into "master",
   it is deleted.  If you need to build on top of it to correct
   earlier mistakes, a new topic branch is created by forking at
   the tip of the "master".  This is not strictly necessary, but
   it makes it easier to keep your history simple.

 * Whenever you need to test or publish your changes to topic
   branches, merge them into "next" branch.

The script, being an example, hardcodes the publish branch name
to be "next", but it is trivial to make it configurable via
$GIT_DIR/config mechanism.

With this workflow, you would want to know:

(1) ... if a topic branch has ever been merged to "next".  Young
    topic branches can have stupid mistakes you would rather
    clean up before publishing, and things that have not been
    merged into other branches can be easily rebased without
    affecting other people.  But once it is published, you would
    not want to rewind it.

(2) ... if a topic branch has been fully merged to "master".
    Then you can delete it.  More importantly, you should not
    build on top of it -- other people may already want to
    change things related to the topic as patches against your
    "master", so if you need further changes, it is better to
    fork the topic (perhaps with the same name) afresh from the
    tip of "master".

Let's look at this example:

		   o---o---o---o---o---o---o---o---o---o "next"
		  /       /           /           /
		 /   a---a---b A     /           /
		/   /               /           /
	       /   /   c---c---c---c B         /
	      /   /   /             \         /
	     /   /   /   b---b C     \       /
	    /   /   /   /             \     /
    ---o---o---o---o---o---o---o---o---o---o---o "master"


A, B and C are topic branches.

 * A has one fix since it was merged up to "next".

 * B has finished.  It has been fully merged up to "master" and "next",
   and is ready to be deleted.

 * C has not merged to "next" at all.

We would want to allow C to be rebased, refuse A, and encourage
B to be deleted.

To compute (1):

	git rev-list ^master ^topic next
	git rev-list ^master        next

	if these match, topic has not merged in next at all.

To compute (2):

	git rev-list master..topic

	if this is empty, it is fully merged to "master".


================================================
FILE: levels/blame/.githug/hooks/prepare-commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to prepare the commit log message.
# Called by "git commit" with the name of the file that has the
# commit message, followed by the description of the commit
# message's source.  The hook's purpose is to edit the commit
# message file.  If the hook fails with a non-zero status,
# the commit is aborted.
#
# To enable this hook, rename this file to "prepare-commit-msg".

# This hook includes three examples.  The first comments out the
# "Conflicts:" part of a merge commit.
#
# The second includes the output of "git diff --name-status -r"
# into the message, just before the "git status" output.  It is
# commented because it doesn't cope with --amend or with squashed
# commits.
#
# The third example adds a Signed-off-by line to the message, that can
# still be edited.  This is rarely a good idea.

case "$2,$3" in
  merge,)
    /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;

# ,|template,)
#   /usr/bin/perl -i.bak -pe '
#      print "\n" . `git diff --cached --name-status -r`
#	 if /^#/ && $first++ == 0' "$1" ;;

  *) ;;
esac

# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"


================================================
FILE: levels/blame/.githug/hooks/update.sample
================================================
#!/bin/sh
#
# An example hook script to blocks unannotated tags from entering.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
# Config
# ------
# hooks.allowunannotated
#   This boolean sets whether unannotated tags will be allowed into the
#   repository.  By default they won't be.
# hooks.allowdeletetag
#   This boolean sets whether deleting tags will be allowed in the
#   repository.  By default they won't be.
# hooks.allowmodifytag
#   This boolean sets whether a tag may be modified after creation. By default
#   it won't be.
# hooks.allowdeletebranch
#   This boolean sets whether deleting branches will be allowed in the
#   repository.  By default they won't be.
# hooks.denycreatebranch
#   This boolean sets whether remotely creating branches will be denied
#   in the repository.  By default this is allowed.
#

# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"

# --- Safety check
if [ -z "$GIT_DIR" ]; then
	echo "Don't run this script from the command line." >&2
	echo " (if you want, you could supply GIT_DIR then run" >&2
	echo "  $0 <ref> <oldrev> <newrev>)" >&2
	exit 1
fi

if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
	exit 1
fi

# --- Config
allowunannotated=$(git config --bool hooks.allowunannotated)
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
denycreatebranch=$(git config --bool hooks.denycreatebranch)
allowdeletetag=$(git config --bool hooks.allowdeletetag)
allowmodifytag=$(git config --bool hooks.allowmodifytag)

# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
case "$projectdesc" in
"Unnamed repository"* | "")
	echo "*** Project description file hasn't been set" >&2
	exit 1
	;;
esac

# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero="0000000000000000000000000000000000000000"
if [ "$newrev" = "$zero" ]; then
	newrev_type=delete
else
	newrev_type=$(git cat-file -t $newrev)
fi

case "$refname","$newrev_type" in
	refs/tags/*,commit)
		# un-annotated tag
		short_refname=${refname##refs/tags/}
		if [ "$allowunannotated" != "true" ]; then
			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
			exit 1
		fi
		;;
	refs/tags/*,delete)
		# delete tag
		if [ "$allowdeletetag" != "true" ]; then
			echo "*** Deleting a tag is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/tags/*,tag)
		# annotated tag
		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
		then
			echo "*** Tag '$refname' already exists." >&2
			echo "*** Modifying a tag is not allowed in this repository." >&2
			exit 1
		fi
		;;
	refs/heads/*,commit)
		# branch
		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
			echo "*** Creating a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/heads/*,delete)
		# delete branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/remotes/*,commit)
		# tracking branch
		;;
	refs/remotes/*,delete)
		# delete tracking branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	*)
		# Anything else (is there anything else?)
		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
		exit 1
		;;
esac

# --- Finished
exit 0


================================================
FILE: levels/blame/.githug/info/exclude
================================================
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~


================================================
FILE: levels/blame/.githug/logs/HEAD
================================================
0000000000000000000000000000000000000000 5e8863df752e3b7f2150df7c78f12bef6f1ff00e Gary Rennie <webmaster@gazler.com> 1331247924 +0000	commit (initial): added config with name
5e8863df752e3b7f2150df7c78f12bef6f1ff00e 094094808dc6dc336c93c8602190a9e5f7bd6a11 Spider Man <spidey-sense@tingling.com> 1331247978 +0000	commit: added options
094094808dc6dc336c93c8602190a9e5f7bd6a11 70d00535a3a25b0ac1736dd3d306d6271e5427ed Bruce Banner <hulk@smash.com> 1331248061 +0000	commit: added password
70d00535a3a25b0ac1736dd3d306d6271e5427ed 97bdd0cccf9f4b8730f78cb53a81a74f205dbcc2 Spider Man <spidey-sense@tingling.com> 1331248095 +0000	commit: added more options
97bdd0cccf9f4b8730f78cb53a81a74f205dbcc2 ffd39c2dbfd94bdbca06d48686e0cbda642f3de7 Gary Rennie <webmaster@gazler.com> 1331248138 +0000	commit: added more options (no really)


================================================
FILE: levels/blame/.githug/logs/refs/heads/master
================================================
0000000000000000000000000000000000000000 5e8863df752e3b7f2150df7c78f12bef6f1ff00e Gary Rennie <webmaster@gazler.com> 1331247924 +0000	commit (initial): added config with name
5e8863df752e3b7f2150df7c78f12bef6f1ff00e 094094808dc6dc336c93c8602190a9e5f7bd6a11 Spider Man <spidey-sense@tingling.com> 1331247978 +0000	commit: added options
094094808dc6dc336c93c8602190a9e5f7bd6a11 70d00535a3a25b0ac1736dd3d306d6271e5427ed Bruce Banner <hulk@smash.com> 1331248061 +0000	commit: added password
70d00535a3a25b0ac1736dd3d306d6271e5427ed 97bdd0cccf9f4b8730f78cb53a81a74f205dbcc2 Spider Man <spidey-sense@tingling.com> 1331248095 +0000	commit: added more options
97bdd0cccf9f4b8730f78cb53a81a74f205dbcc2 ffd39c2dbfd94bdbca06d48686e0cbda642f3de7 Gary Rennie <webmaster@gazler.com> 1331248138 +0000	commit: added more options (no really)


================================================
FILE: levels/blame/.githug/objects/09/4094808dc6dc336c93c8602190a9e5f7bd6a11
================================================
xNK1tS^/dN2$qW.*majjK6褧HDа0UVGR>]t\,	"Α
{N
\WOK9yuPJH'L1_m`!%LPkdM

================================================
FILE: levels/blame/.githug/objects/31/11dda1f5b08d50ac44b99acabfa54f1e6e72b0
================================================
x5
1D=MAD/l7@MdSݶ&CzEH䎋i;6SzrGJJu[+oSJV@쭁o-e[#3

================================================
FILE: levels/blame/.githug/objects/97/bdd0cccf9f4b8730f78cb53a81a74f205dbcc2
================================================
xKj1DS$t`L.UNi(>((-ulͩ7U`"'!Fo{1p4uL?	)Uܴt(θl2Bx#xr6_CZϡϥnW cm<@pc߇)VBZ1nK

================================================
FILE: levels/blame/.githug/objects/dd/df1d8ebd60eec169c15a5b23cb49a58d2ed5a0
================================================
xeA
0E]cW
Ņ.Ģ xITLIw7I(]$T+X7isp`YHc%.lӲUP$(>v@h
#k$}c>qcAە.RqKR8}JgbH)դxkZIэ
?X

================================================
FILE: levels/blame/.githug/objects/ff/d39c2dbfd94bdbca06d48686e0cbda642f3de7
================================================
xMJD1]t$t`ܹNG$C&"Ž}ix|ڠ!搲ٸ1Ґ6!.53X|t	is/Vo91[E?qOim8Jt2޿ʽ^8gG^Zfيr~{o7xnqOdbO[

================================================
FILE: levels/blame/.githug/refs/heads/master
================================================
ffd39c2dbfd94bdbca06d48686e0cbda642f3de7


================================================
FILE: levels/blame/config.rb
================================================
class Config
  attr_accessor :name, :password
  def initialize(name, password = nil, options = {})
    @name = name
    @password = password || "i<3evil"

    if options[:downcase]
      @name.downcase!
    end

    if options[:upcase]
      @name.upcase!
    end

  end
end


================================================
FILE: levels/blame.rb
================================================
difficulty 2
description "Identify who put a password inside the file `config.rb`."

setup do
  init_from_level
  system "git branch -m master"
end

solution do
  offender = repo.commit("97bdd0cccf9f4b8730f78cb53a81a74f205dbcc2").author.name
  request("Who made the commit with the password?").downcase.strip == offender.downcase
end

hint do
  puts "You want to research the `git blame` command."
end


================================================
FILE: levels/branch.rb
================================================
difficulty 1
description "To work on a piece of code that has the potential to break things, create the branch test_code."

setup do
  repo.init
  FileUtils.touch("README")
  repo.add "README"
  repo.commit_all("Initial commit")
  system "git branch -m master"
end

solution do
  repo.branches.map(&:name).include?("test_code")
end

hint do
  puts "`git branch` is what you want to investigate."
end



================================================
FILE: levels/branch_at.rb
================================================
difficulty 3
description "You forgot to branch at the previous commit and made a commit on top of it. Create the branch test_branch at the commit before the last."

setup do
  repo.init
  FileUtils.touch("file1")
  repo.add("file1")
  repo.commit_all("Adding file1")
  File.open("file1", 'w') { |f| f.write("content") }
  repo.add("file1")
  repo.commit_all("Updating file1")
  File.open("file1", 'a') { |f| f.write("\nAdding some more text") }
  repo.add("file1")
  repo.commit_all("Updating file1 again")
  system "git branch -m master"
end

solution do
  return false unless repo.branches.map(&:name).include?("test_branch")
  repo.commits("test_branch").each { |commit| return false if commit.message == "Updating file1 again" }
  true
end

hint do
  puts "Just like creating a branch, but you have to pass an extra argument."
end


================================================
FILE: levels/checkout.rb
================================================
difficulty 2
description "Create and switch to a new branch called my_branch. You will need to create a branch like you did in the previous level."

setup do
  repo.init
  FileUtils.touch("README")
  repo.add("README")
  repo.commit_all("initial commit")
  system "git branch -m master"
end

solution do
  return false unless repo.head.name == "my_branch"
  true
end

hint do
  puts "Try looking up `git checkout` and `git branch`."
end


================================================
FILE: levels/checkout_file.rb
================================================
difficulty 3

description "A file has been modified, but you don't want to keep the modification. Checkout the `config.rb` file from the last commit."

setup do
  repo.init
  File.open("config.rb", "w") do |file|
    file.puts("This is the initial config file")
  end

  repo.add("config.rb")
  repo.commit_all("Added initial config file")

  File.open("config.rb", "a") do |file|
    file.puts("These are changed you don't want to keep!")
  end
  system "git branch -m master"
end

solution do
  repo.status.files["config.rb"].type != "M" && repo.commits.length == 1
end

hint do
  puts "You will need to do some research on the checkout command for this one."
end


================================================
FILE: levels/checkout_tag.rb
================================================
difficulty 2

description "You need to fix a bug in the version 1.2 of your app. Checkout the tag `v1.2`."

setup do
  repo.init
  FileUtils.touch("app.rb")
  repo.add("app.rb")
  repo.commit_all("Initial commit")

  `echo "Some code" >> app.rb`
  repo.add("app.rb")
  repo.commit_all("Some changes")
  repo.git.tag( { 'f' => true }, "v1.0" )

  `echo "Buggy code" >> app.rb`
  repo.add("app.rb")
  repo.commit_all("Some more changes")
  repo.git.tag( { 'f' => true }, "v1.2" )

  `echo "More code" >> app.rb`
  repo.add("app.rb")
  repo.commit_all("Yet more changes")

  `echo "Some more code" >> app.rb`
  repo.add("app.rb")
  repo.commit_all("Changes galore")
  repo.git.tag( { 'f' => true }, "v1.5" )

  system "git branch -m master"
end

solution do
  return false unless repo.commits.length == 5
  return false unless `git show HEAD --format=%s` =~ /Some more changes/
  true
end

hint do
  puts "There's no big difference between checking out a branch and checking out a tag."
end


================================================
FILE: levels/checkout_tag_over_branch.rb
================================================
difficulty 2

description "You need to fix a bug in the version 1.2 of your app. Checkout the tag `v1.2` (Note: There is also a branch named `v1.2`)."

setup do
  repo.init
  FileUtils.touch("app.rb")
  repo.add("app.rb")
  repo.commit_all("Initial commit")
  system "git branch -m master"

  `echo "Some code" >> app.rb`
  repo.add("app.rb")
  repo.commit_all("Some changes")
  repo.git.tag( { 'f' => true }, "v1.0" )

  `echo "Buggy code" >> app.rb`
  repo.add("app.rb")
  repo.commit_all("Some more changes")
  repo.git.tag( { 'f' => true }, "v1.2" )

  `echo "More code" >> app.rb`
  repo.add("app.rb")
  repo.commit_all("Yet more changes")

  `echo "Some more code" >> app.rb`
  repo.add("app.rb")
  repo.commit_all("Changes galore")
  repo.git.tag( { 'f' => true }, "v1.5" )

  repo.git.native :checkout, {"b" => true}, 'v1.2'
  File.open("file3", 'w') { |f| f << "some feature\n" }
  repo.add "file3"
  repo.commit_all "Developing new features"

  repo.git.native :checkout, {}, 'master'
end

solution do
  return false unless repo.commits.length == 5
  return false unless `git show HEAD --format=%s` =~ /Some more changes/
  true
end

hint do
  puts "You should think about specifying you're after the tag named `v1.2` (think `tags/`)."
end


================================================
FILE: levels/cherry-pick/.githug/COMMIT_EDITMSG
================================================
some small fixes


================================================
FILE: levels/cherry-pick/.githug/HEAD
================================================
ref: refs/heads/master


================================================
FILE: levels/cherry-pick/.githug/config
================================================
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true


================================================
FILE: levels/cherry-pick/.githug/description
================================================
Unnamed repository; edit this file 'description' to name the repository.


================================================
FILE: levels/cherry-pick/.githug/hooks/applypatch-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message taken by
# applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.  The hook is
# allowed to edit the commit message file.
#
# To enable this hook, rename this file to "applypatch-msg".

. git-sh-setup
test -x "$GIT_DIR/hooks/commit-msg" &&
	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
:


================================================
FILE: levels/cherry-pick/.githug/hooks/commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message.  The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit.  The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".

# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

# This example catches duplicate Signed-off-by lines.

test "" = "$(grep '^Signed-off-by: ' "$1" |
	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
	echo >&2 Duplicate Signed-off-by lines.
	exit 1
}


================================================
FILE: levels/cherry-pick/.githug/hooks/post-update.sample
================================================
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".

exec git update-server-info


================================================
FILE: levels/cherry-pick/.githug/hooks/pre-applypatch.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed
# by applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-applypatch".

. git-sh-setup
test -x "$GIT_DIR/hooks/pre-commit" &&
	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
:


================================================
FILE: levels/cherry-pick/.githug/hooks/pre-commit.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
	against=HEAD
else
	# Initial commit: diff against an empty tree object
	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# If you want to allow non-ascii filenames set this variable to true.
allownonascii=$(git config hooks.allownonascii)

# Redirect output to stderr.
exec 1>&2

# Cross platform projects tend to avoid non-ascii filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
	# Note that the use of brackets around a tr range is ok here, (it's
	# even required, for portability to Solaris 10's /usr/bin/tr), since
	# the square bracket bytes happen to fall in the designated range.
	test $(git diff --cached --name-only --diff-filter=A -z $against |
	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
	echo "Error: Attempt to add a non-ascii file name."
	echo
	echo "This can cause problems if you want to work"
	echo "with people on other platforms."
	echo
	echo "To be portable it is advisable to rename the file ..."
	echo
	echo "If you know what you are doing you can disable this"
	echo "check using:"
	echo
	echo "  git config hooks.allownonascii true"
	echo
	exit 1
fi

# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --


================================================
FILE: levels/cherry-pick/.githug/hooks/pre-rebase.sample
================================================
#!/bin/sh
#
# Copyright (c) 2006, 2008 Junio C Hamano
#
# The "pre-rebase" hook is run just before "git rebase" starts doing
# its job, and can prevent the command from running by exiting with
# non-zero status.
#
# The hook is called with the following parameters:
#
# $1 -- the upstream the series was forked from.
# $2 -- the branch being rebased (or empty when rebasing the current branch).
#
# This sample shows how to prevent topic branches that are already
# merged to 'next' branch from getting rebased, because allowing it
# would result in rebasing already published history.

publish=next
basebranch="$1"
if test "$#" = 2
then
	topic="refs/heads/$2"
else
	topic=`git symbolic-ref HEAD` ||
	exit 0 ;# we do not interrupt rebasing detached HEAD
fi

case "$topic" in
refs/heads/??/*)
	;;
*)
	exit 0 ;# we do not interrupt others.
	;;
esac

# Now we are dealing with a topic branch being rebased
# on top of master.  Is it OK to rebase it?

# Does the topic really exist?
git show-ref -q "$topic" || {
	echo >&2 "No such branch $topic"
	exit 1
}

# Is topic fully merged to master?
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
if test -z "$not_in_master"
then
	echo >&2 "$topic is fully merged to master; better remove it."
	exit 1 ;# we could allow it, but there is no point.
fi

# Is topic ever merged to next?  If so you should not be rebasing it.
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
only_next_2=`git rev-list ^master           ${publish} | sort`
if test "$only_next_1" = "$only_next_2"
then
	not_in_topic=`git rev-list "^$topic" master`
	if test -z "$not_in_topic"
	then
		echo >&2 "$topic is already up-to-date with master"
		exit 1 ;# we could allow it, but there is no point.
	else
		exit 0
	fi
else
	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
	/opt/local/bin/perl5.12 -e '
		my $topic = $ARGV[0];
		my $msg = "* $topic has commits already merged to public branch:\n";
		my (%not_in_next) = map {
			/^([0-9a-f]+) /;
			($1 => 1);
		} split(/\n/, $ARGV[1]);
		for my $elem (map {
				/^([0-9a-f]+) (.*)$/;
				[$1 => $2];
			} split(/\n/, $ARGV[2])) {
			if (!exists $not_in_next{$elem->[0]}) {
				if ($msg) {
					print STDERR $msg;
					undef $msg;
				}
				print STDERR " $elem->[1]\n";
			}
		}
	' "$topic" "$not_in_next" "$not_in_master"
	exit 1
fi

exit 0

################################################################

This sample hook safeguards topic branches that have been
published from being rewound.

The workflow assumed here is:

 * Once a topic branch forks from "master", "master" is never
   merged into it again (either directly or indirectly).

 * Once a topic branch is fully cooked and merged into "master",
   it is deleted.  If you need to build on top of it to correct
   earlier mistakes, a new topic branch is created by forking at
   the tip of the "master".  This is not strictly necessary, but
   it makes it easier to keep your history simple.

 * Whenever you need to test or publish your changes to topic
   branches, merge them into "next" branch.

The script, being an example, hardcodes the publish branch name
to be "next", but it is trivial to make it configurable via
$GIT_DIR/config mechanism.

With this workflow, you would want to know:

(1) ... if a topic branch has ever been merged to "next".  Young
    topic branches can have stupid mistakes you would rather
    clean up before publishing, and things that have not been
    merged into other branches can be easily rebased without
    affecting other people.  But once it is published, you would
    not want to rewind it.

(2) ... if a topic branch has been fully merged to "master".
    Then you can delete it.  More importantly, you should not
    build on top of it -- other people may already want to
    change things related to the topic as patches against your
    "master", so if you need further changes, it is better to
    fork the topic (perhaps with the same name) afresh from the
    tip of "master".

Let's look at this example:

		   o---o---o---o---o---o---o---o---o---o "next"
		  /       /           /           /
		 /   a---a---b A     /           /
		/   /               /           /
	       /   /   c---c---c---c B         /
	      /   /   /             \         /
	     /   /   /   b---b C     \       /
	    /   /   /   /             \     /
    ---o---o---o---o---o---o---o---o---o---o---o "master"


A, B and C are topic branches.

 * A has one fix since it was merged up to "next".

 * B has finished.  It has been fully merged up to "master" and "next",
   and is ready to be deleted.

 * C has not merged to "next" at all.

We would want to allow C to be rebased, refuse A, and encourage
B to be deleted.

To compute (1):

	git rev-list ^master ^topic next
	git rev-list ^master        next

	if these match, topic has not merged in next at all.

To compute (2):

	git rev-list master..topic

	if this is empty, it is fully merged to "master".


================================================
FILE: levels/cherry-pick/.githug/hooks/prepare-commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to prepare the commit log message.
# Called by "git commit" with the name of the file that has the
# commit message, followed by the description of the commit
# message's source.  The hook's purpose is to edit the commit
# message file.  If the hook fails with a non-zero status,
# the commit is aborted.
#
# To enable this hook, rename this file to "prepare-commit-msg".

# This hook includes three examples.  The first comments out the
# "Conflicts:" part of a merge commit.
#
# The second includes the output of "git diff --name-status -r"
# into the message, just before the "git status" output.  It is
# commented because it doesn't cope with --amend or with squashed
# commits.
#
# The third example adds a Signed-off-by line to the message, that can
# still be edited.  This is rarely a good idea.

case "$2,$3" in
  merge,)
    /opt/local/bin/perl5.12 -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;

# ,|template,)
#   /opt/local/bin/perl5.12 -i.bak -pe '
#      print "\n" . `git diff --cached --name-status -r`
#	 if /^#/ && $first++ == 0' "$1" ;;

  *) ;;
esac

# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"


================================================
FILE: levels/cherry-pick/.githug/hooks/update.sample
================================================
#!/bin/sh
#
# An example hook script to blocks unannotated tags from entering.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
# Config
# ------
# hooks.allowunannotated
#   This boolean sets whether unannotated tags will be allowed into the
#   repository.  By default they won't be.
# hooks.allowdeletetag
#   This boolean sets whether deleting tags will be allowed in the
#   repository.  By default they won't be.
# hooks.allowmodifytag
#   This boolean sets whether a tag may be modified after creation. By default
#   it won't be.
# hooks.allowdeletebranch
#   This boolean sets whether deleting branches will be allowed in the
#   repository.  By default they won't be.
# hooks.denycreatebranch
#   This boolean sets whether remotely creating branches will be denied
#   in the repository.  By default this is allowed.
#

# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"

# --- Safety check
if [ -z "$GIT_DIR" ]; then
	echo "Don't run this script from the command line." >&2
	echo " (if you want, you could supply GIT_DIR then run" >&2
	echo "  $0 <ref> <oldrev> <newrev>)" >&2
	exit 1
fi

if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
	exit 1
fi

# --- Config
allowunannotated=$(git config --bool hooks.allowunannotated)
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
denycreatebranch=$(git config --bool hooks.denycreatebranch)
allowdeletetag=$(git config --bool hooks.allowdeletetag)
allowmodifytag=$(git config --bool hooks.allowmodifytag)

# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
case "$projectdesc" in
"Unnamed repository"* | "")
	echo "*** Project description file hasn't been set" >&2
	exit 1
	;;
esac

# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero="0000000000000000000000000000000000000000"
if [ "$newrev" = "$zero" ]; then
	newrev_type=delete
else
	newrev_type=$(git cat-file -t $newrev)
fi

case "$refname","$newrev_type" in
	refs/tags/*,commit)
		# un-annotated tag
		short_refname=${refname##refs/tags/}
		if [ "$allowunannotated" != "true" ]; then
			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
			exit 1
		fi
		;;
	refs/tags/*,delete)
		# delete tag
		if [ "$allowdeletetag" != "true" ]; then
			echo "*** Deleting a tag is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/tags/*,tag)
		# annotated tag
		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
		then
			echo "*** Tag '$refname' already exists." >&2
			echo "*** Modifying a tag is not allowed in this repository." >&2
			exit 1
		fi
		;;
	refs/heads/*,commit)
		# branch
		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
			echo "*** Creating a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/heads/*,delete)
		# delete branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/remotes/*,commit)
		# tracking branch
		;;
	refs/remotes/*,delete)
		# delete tracking branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	*)
		# Anything else (is there anything else?)
		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
		exit 1
		;;
esac

# --- Finished
exit 0


================================================
FILE: levels/cherry-pick/.githug/info/exclude
================================================
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~


================================================
FILE: levels/cherry-pick/.githug/logs/HEAD
================================================
0000000000000000000000000000000000000000 ea3dbcc5e2d2359698c3606b0ec44af9f76def54 Andrey <aslushnikov@gmail.com> 1332886832 +0400	commit (initial): Initial commit
ea3dbcc5e2d2359698c3606b0ec44af9f76def54 b30c6a965415df6aef5f2903f9892fa5481152fc Andrey <aslushnikov@gmail.com> 1332886882 +0400	commit: Added a hardcore math module
b30c6a965415df6aef5f2903f9892fa5481152fc 232d266a78d5ef7196f1ede14972ccf7ee19e587 Andrey <aslushnikov@gmail.com> 1332886949 +0400	commit: Renamed project.js -> herdcore-math.js
232d266a78d5ef7196f1ede14972ccf7ee19e587 6edea632d9540e060bca97dda0897df2b7da0ec0 Andrey <aslushnikov@gmail.com> 1332887008 +0400	commit: Added fancy branded output
6edea632d9540e060bca97dda0897df2b7da0ec0 ea3dbcc5e2d2359698c3606b0ec44af9f76def54 Andrey <aslushnikov@gmail.com> 1332887015 +0400	checkout: moving from master to ea3dbcc
ea3dbcc5e2d2359698c3606b0ec44af9f76def54 ea3dbcc5e2d2359698c3606b0ec44af9f76def54 Andrey <aslushnikov@gmail.com> 1332887030 +0400	checkout: moving from ea3dbcc5e2d2359698c3606b0ec44af9f76def54 to new-feature
ea3dbcc5e2d2359698c3606b0ec44af9f76def54 58a8c8edcfdd00c6d8cce9aada8f987a1677571f Andrey <aslushnikov@gmail.com> 1332887081 +0400	commit: Added a stub for the feature
58a8c8edcfdd00c6d8cce9aada8f987a1677571f cfd8ce38c22c5fe83cc04e23f94646464f20d990 Andrey <aslushnikov@gmail.com> 1332887151 +0400	commit: README.md
cfd8ce38c22c5fe83cc04e23f94646464f20d990 ca32a6dac7b6f97975edbe19a4296c2ee7682f68 Andrey <aslushnikov@gmail.com> 1332887177 +0400	commit (amend): Filled in README.md with proper input
ca32a6dac7b6f97975edbe19a4296c2ee7682f68 4a1961bce62840eaef9c4392fe5cc799e38c9b7b Andrey <aslushnikov@gmail.com> 1332887238 +0400	commit: Fixed feature
4a1961bce62840eaef9c4392fe5cc799e38c9b7b ea2a47c19b85fc321e2737ddc49db3deeba3a1b5 Andrey <aslushnikov@gmail.com> 1332887315 +0400	commit: some small fixes
ea2a47c19b85fc321e2737ddc49db3deeba3a1b5 6edea632d9540e060bca97dda0897df2b7da0ec0 Andrey <aslushnikov@gmail.com> 1332887329 +0400	checkout: moving from new-feature to master
6edea632d9540e060bca97dda0897df2b7da0ec0 ea2a47c19b85fc321e2737ddc49db3deeba3a1b5 Andrey <aslushnikov@gmail.com> 1332887695 +0400	checkout: moving from master to new-feature
ea2a47c19b85fc321e2737ddc49db3deeba3a1b5 6edea632d9540e060bca97dda0897df2b7da0ec0 Andrey <aslushnikov@gmail.com> 1332887737 +0400	checkout: moving from new-feature to master


================================================
FILE: levels/cherry-pick/.githug/logs/refs/heads/master
================================================
0000000000000000000000000000000000000000 ea3dbcc5e2d2359698c3606b0ec44af9f76def54 Andrey <aslushnikov@gmail.com> 1332886832 +0400	commit (initial): Initial commit
ea3dbcc5e2d2359698c3606b0ec44af9f76def54 b30c6a965415df6aef5f2903f9892fa5481152fc Andrey <aslushnikov@gmail.com> 1332886882 +0400	commit: Added a hardcore math module
b30c6a965415df6aef5f2903f9892fa5481152fc 232d266a78d5ef7196f1ede14972ccf7ee19e587 Andrey <aslushnikov@gmail.com> 1332886949 +0400	commit: Renamed project.js -> herdcore-math.js
232d266a78d5ef7196f1ede14972ccf7ee19e587 6edea632d9540e060bca97dda0897df2b7da0ec0 Andrey <aslushnikov@gmail.com> 1332887008 +0400	commit: Added fancy branded output


================================================
FILE: levels/cherry-pick/.githug/logs/refs/heads/new-feature
================================================
0000000000000000000000000000000000000000 ea3dbcc5e2d2359698c3606b0ec44af9f76def54 Andrey <aslushnikov@gmail.com> 1332887030 +0400	branch: Created from HEAD
ea3dbcc5e2d2359698c3606b0ec44af9f76def54 58a8c8edcfdd00c6d8cce9aada8f987a1677571f Andrey <aslushnikov@gmail.com> 1332887081 +0400	commit: Added a stub for the feature
58a8c8edcfdd00c6d8cce9aada8f987a1677571f cfd8ce38c22c5fe83cc04e23f94646464f20d990 Andrey <aslushnikov@gmail.com> 1332887151 +0400	commit: README.md
cfd8ce38c22c5fe83cc04e23f94646464f20d990 ca32a6dac7b6f97975edbe19a4296c2ee7682f68 Andrey <aslushnikov@gmail.com> 1332887177 +0400	commit (amend): Filled in README.md with proper input
ca32a6dac7b6f97975edbe19a4296c2ee7682f68 4a1961bce62840eaef9c4392fe5cc799e38c9b7b Andrey <aslushnikov@gmail.com> 1332887238 +0400	commit: Fixed feature
4a1961bce62840eaef9c4392fe5cc799e38c9b7b ea2a47c19b85fc321e2737ddc49db3deeba3a1b5 Andrey <aslushnikov@gmail.com> 1332887315 +0400	commit: some small fixes


================================================
FILE: levels/cherry-pick/.githug/objects/6e/dea632d9540e060bca97dda0897df2b7da0ec0
================================================
xA E]s
&{тAjy/,ܤ̩Uf	쉌Kj`-ʙ^C|N&`bnƄ8amSrTyy)?0.,7	]C<^)_K11rXC>VY{m[K(

================================================
FILE: levels/cherry-pick/.githug/refs/heads/master
================================================
6edea632d9540e060bca97dda0897df2b7da0ec0


================================================
FILE: levels/cherry-pick/.githug/refs/heads/new-feature
================================================
ea2a47c19b85fc321e2737ddc49db3deeba3a1b5


================================================
FILE: levels/cherry-pick/README.md
================================================
I'll fill in the file some time later..



================================================
FILE: levels/cherry-pick/hardcore-math.js
================================================
for(var i = 0; i < 10; i++) {
    console.log(42 * i);
}


================================================
FILE: levels/cherry-pick/nokia.js
================================================
console.log("[NOKIA] Connecting people");


================================================
FILE: levels/cherry-pick.rb
================================================
difficulty 3
description "Your new feature isn't worth the time and you're going to delete it. But it has one commit that fills in `README` file, and you want this commit to be on the master as well."

setup do
  init_from_level
  `git stash` # fix for README.md being in githug root an the level
  system "git branch -m master"
end

solution do
  return false unless repo.commits[1].message == "Added fancy branded output"
  return false unless repo.commits[0].message == "Filled in README.md with proper input"
  true
end

hint do
  puts "Sneak a peek at the `git help cherry-pick` command."
end


================================================
FILE: levels/clone.rb
================================================
difficulty 1
description "Clone the repository at https://github.com/Gazler/cloneme."

solution do
  repo("cloneme").commit("157b2b61f29ab9df45f31c7cd9cb5d8ff06ecde4")
end

hint do
  puts "You should have a look at this site: https://github.com/Gazler/cloneme."
end


================================================
FILE: levels/clone_to_folder.rb
================================================
difficulty 1
description "Clone the repository at https://github.com/Gazler/cloneme into the folder `my_cloned_repo`."

solution do
  repo("my_cloned_repo").commit("157b2b61f29ab9df45f31c7cd9cb5d8ff06ecde4")
end

hint do
  puts "This is like the last level, `git clone` has an optional argument."
end


================================================
FILE: levels/commit.rb
================================================
difficulty 1
description "The `README` file has been added to your staging area, now commit it."

setup do
  repo.init
  system "git branch -m master"
  FileUtils.touch("README")
  repo.add("README")
end

solution do
  return false if repo.commits.empty?
  true
end

hint do
  puts "You must include a message when you commit."
end


================================================
FILE: levels/commit_amend.rb
================================================
difficulty 2
description "The `README` file has been committed, but it looks like the file `forgotten_file.rb` was missing from the commit. Add the file and amend your previous commit to include it."

setup do
  repo.init
  FileUtils.touch("README")
  repo.add("README")
  repo.commit_all("Initial commit")
  FileUtils.touch("forgotten_file.rb")
  system "git branch -m master"
end

solution do
  # Reset config - see issue #74
  file = File.open(".git/config", "w") do |file|
    file.puts("[format]")
    file.puts(" pretty = medium")
  end
  repo.commits.length == 1 && Grit::CommitStats.find_all(repo, repo.commits.first.sha).first[1].files.length == 2
end

hint do
  puts "Running `git commit --help` will display the man page and possible flags."
end


================================================
FILE: levels/commit_in_future.rb
================================================
require 'time'

difficulty 2
description "Commit your changes with the future date (e.g. tomorrow)."

setup do
  repo.init

  FileUtils.touch("README")
  repo.add("README")
  system "git branch -m master"
end

solution do
  repo.commits.length == 1 && repo.commits.first.authored_date > Time.now
end

hint do
  puts "Build a time format, and commit your code using --date parameter for \"future\"."
end


================================================
FILE: levels/config.rb
================================================
difficulty 1
description "Set up your git name and email; this is important so that your commits can be identified."

setup do
  repo.init
end

solution do
  valid = false

  name = request("What is your name?")
  email = request("What is your email?")
  config_name = repo.config["user.name"]
  config_email = repo.config["user.email"]

  if name.respond_to?(:force_encoding)
    config_name = config_name.force_encoding("UTF-8")
    config_email = config_email.force_encoding("UTF-8")
  end

  if name == config_name && email == config_email
    valid = true
  end

  puts "Your config has the following name: #{config_name}"
  puts "Your config has the following email: #{config_email}"

  valid
end

hint do
  puts "These settings are config settings. You should run `git help config` if you are stuck."
end


================================================
FILE: levels/conflict/.githug/COMMIT_EDITMSG
================================================
Updated the poem

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Author:    Thameera Senanayaka <thameera123@gmail.com>
# Committer: Alex <snooz@localhost.localdomain>
#
# On branch master
# Changes to be committed:
#   (use "git reset HEAD^1 <file>..." to unstage)
#
#	modified:   poem.txt
#


================================================
FILE: levels/conflict/.githug/HEAD
================================================
ref: refs/heads/master


================================================
FILE: levels/conflict/.githug/config
================================================
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true


================================================
FILE: levels/conflict/.githug/description
================================================
Unnamed repository; edit this file 'description' to name the repository.


================================================
FILE: levels/conflict/.githug/hooks/applypatch-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message taken by
# applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.  The hook is
# allowed to edit the commit message file.
#
# To enable this hook, rename this file to "applypatch-msg".

. git-sh-setup
test -x "$GIT_DIR/hooks/commit-msg" &&
	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
:


================================================
FILE: levels/conflict/.githug/hooks/commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message.  The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit.  The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".

# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

# This example catches duplicate Signed-off-by lines.

test "" = "$(grep '^Signed-off-by: ' "$1" |
	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
	echo >&2 Duplicate Signed-off-by lines.
	exit 1
}


================================================
FILE: levels/conflict/.githug/hooks/post-update.sample
================================================
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".

exec git update-server-info


================================================
FILE: levels/conflict/.githug/hooks/pre-applypatch.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed
# by applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-applypatch".

. git-sh-setup
test -x "$GIT_DIR/hooks/pre-commit" &&
	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
:


================================================
FILE: levels/conflict/.githug/hooks/pre-commit.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
	against=HEAD
else
	# Initial commit: diff against an empty tree object
	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# If you want to allow non-ascii filenames set this variable to true.
allownonascii=$(git config hooks.allownonascii)

# Redirect output to stderr.
exec 1>&2

# Cross platform projects tend to avoid non-ascii filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
	# Note that the use of brackets around a tr range is ok here, (it's
	# even required, for portability to Solaris 10's /usr/bin/tr), since
	# the square bracket bytes happen to fall in the designated range.
	test $(git diff --cached --name-only --diff-filter=A -z $against |
	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
	echo "Error: Attempt to add a non-ascii file name."
	echo
	echo "This can cause problems if you want to work"
	echo "with people on other platforms."
	echo
	echo "To be portable it is advisable to rename the file ..."
	echo
	echo "If you know what you are doing you can disable this"
	echo "check using:"
	echo
	echo "  git config hooks.allownonascii true"
	echo
	exit 1
fi

# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --


================================================
FILE: levels/conflict/.githug/hooks/pre-rebase.sample
================================================
#!/bin/sh
#
# Copyright (c) 2006, 2008 Junio C Hamano
#
# The "pre-rebase" hook is run just before "git rebase" starts doing
# its job, and can prevent the command from running by exiting with
# non-zero status.
#
# The hook is called with the following parameters:
#
# $1 -- the upstream the series was forked from.
# $2 -- the branch being rebased (or empty when rebasing the current branch).
#
# This sample shows how to prevent topic branches that are already
# merged to 'next' branch from getting rebased, because allowing it
# would result in rebasing already published history.

publish=next
basebranch="$1"
if test "$#" = 2
then
	topic="refs/heads/$2"
else
	topic=`git symbolic-ref HEAD` ||
	exit 0 ;# we do not interrupt rebasing detached HEAD
fi

case "$topic" in
refs/heads/??/*)
	;;
*)
	exit 0 ;# we do not interrupt others.
	;;
esac

# Now we are dealing with a topic branch being rebased
# on top of master.  Is it OK to rebase it?

# Does the topic really exist?
git show-ref -q "$topic" || {
	echo >&2 "No such branch $topic"
	exit 1
}

# Is topic fully merged to master?
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
if test -z "$not_in_master"
then
	echo >&2 "$topic is fully merged to master; better remove it."
	exit 1 ;# we could allow it, but there is no point.
fi

# Is topic ever merged to next?  If so you should not be rebasing it.
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
only_next_2=`git rev-list ^master           ${publish} | sort`
if test "$only_next_1" = "$only_next_2"
then
	not_in_topic=`git rev-list "^$topic" master`
	if test -z "$not_in_topic"
	then
		echo >&2 "$topic is already up-to-date with master"
		exit 1 ;# we could allow it, but there is no point.
	else
		exit 0
	fi
else
	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
	/usr/bin/perl -e '
		my $topic = $ARGV[0];
		my $msg = "* $topic has commits already merged to public branch:\n";
		my (%not_in_next) = map {
			/^([0-9a-f]+) /;
			($1 => 1);
		} split(/\n/, $ARGV[1]);
		for my $elem (map {
				/^([0-9a-f]+) (.*)$/;
				[$1 => $2];
			} split(/\n/, $ARGV[2])) {
			if (!exists $not_in_next{$elem->[0]}) {
				if ($msg) {
					print STDERR $msg;
					undef $msg;
				}
				print STDERR " $elem->[1]\n";
			}
		}
	' "$topic" "$not_in_next" "$not_in_master"
	exit 1
fi

<<\DOC_END

This sample hook safeguards topic branches that have been
published from being rewound.

The workflow assumed here is:

 * Once a topic branch forks from "master", "master" is never
   merged into it again (either directly or indirectly).

 * Once a topic branch is fully cooked and merged into "master",
   it is deleted.  If you need to build on top of it to correct
   earlier mistakes, a new topic branch is created by forking at
   the tip of the "master".  This is not strictly necessary, but
   it makes it easier to keep your history simple.

 * Whenever you need to test or publish your changes to topic
   branches, merge them into "next" branch.

The script, being an example, hardcodes the publish branch name
to be "next", but it is trivial to make it configurable via
$GIT_DIR/config mechanism.

With this workflow, you would want to know:

(1) ... if a topic branch has ever been merged to "next".  Young
    topic branches can have stupid mistakes you would rather
    clean up before publishing, and things that have not been
    merged into other branches can be easily rebased without
    affecting other people.  But once it is published, you would
    not want to rewind it.

(2) ... if a topic branch has been fully merged to "master".
    Then you can delete it.  More importantly, you should not
    build on top of it -- other people may already want to
    change things related to the topic as patches against your
    "master", so if you need further changes, it is better to
    fork the topic (perhaps with the same name) afresh from the
    tip of "master".

Let's look at this example:

		   o---o---o---o---o---o---o---o---o---o "next"
		  /       /           /           /
		 /   a---a---b A     /           /
		/   /               /           /
	       /   /   c---c---c---c B         /
	      /   /   /             \         /
	     /   /   /   b---b C     \       /
	    /   /   /   /             \     /
    ---o---o---o---o---o---o---o---o---o---o---o "master"


A, B and C are topic branches.

 * A has one fix since it was merged up to "next".

 * B has finished.  It has been fully merged up to "master" and "next",
   and is ready to be deleted.

 * C has not merged to "next" at all.

We would want to allow C to be rebased, refuse A, and encourage
B to be deleted.

To compute (1):

	git rev-list ^master ^topic next
	git rev-list ^master        next

	if these match, topic has not merged in next at all.

To compute (2):

	git rev-list master..topic

	if this is empty, it is fully merged to "master".

DOC_END


================================================
FILE: levels/conflict/.githug/hooks/prepare-commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to prepare the commit log message.
# Called by "git commit" with the name of the file that has the
# commit message, followed by the description of the commit
# message's source.  The hook's purpose is to edit the commit
# message file.  If the hook fails with a non-zero status,
# the commit is aborted.
#
# To enable this hook, rename this file to "prepare-commit-msg".

# This hook includes three examples.  The first comments out the
# "Conflicts:" part of a merge commit.
#
# The second includes the output of "git diff --name-status -r"
# into the message, just before the "git status" output.  It is
# commented because it doesn't cope with --amend or with squashed
# commits.
#
# The third example adds a Signed-off-by line to the message, that can
# still be edited.  This is rarely a good idea.

case "$2,$3" in
  merge,)
    /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;

# ,|template,)
#   /usr/bin/perl -i.bak -pe '
#      print "\n" . `git diff --cached --name-status -r`
#	 if /^#/ && $first++ == 0' "$1" ;;

  *) ;;
esac

# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"


================================================
FILE: levels/conflict/.githug/hooks/update.sample
================================================
#!/bin/sh
#
# An example hook script to blocks unannotated tags from entering.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
# Config
# ------
# hooks.allowunannotated
#   This boolean sets whether unannotated tags will be allowed into the
#   repository.  By default they won't be.
# hooks.allowdeletetag
#   This boolean sets whether deleting tags will be allowed in the
#   repository.  By default they won't be.
# hooks.allowmodifytag
#   This boolean sets whether a tag may be modified after creation. By default
#   it won't be.
# hooks.allowdeletebranch
#   This boolean sets whether deleting branches will be allowed in the
#   repository.  By default they won't be.
# hooks.denycreatebranch
#   This boolean sets whether remotely creating branches will be denied
#   in the repository.  By default this is allowed.
#

# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"

# --- Safety check
if [ -z "$GIT_DIR" ]; then
	echo "Don't run this script from the command line." >&2
	echo " (if you want, you could supply GIT_DIR then run" >&2
	echo "  $0 <ref> <oldrev> <newrev>)" >&2
	exit 1
fi

if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
	exit 1
fi

# --- Config
allowunannotated=$(git config --bool hooks.allowunannotated)
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
denycreatebranch=$(git config --bool hooks.denycreatebranch)
allowdeletetag=$(git config --bool hooks.allowdeletetag)
allowmodifytag=$(git config --bool hooks.allowmodifytag)

# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
case "$projectdesc" in
"Unnamed repository"* | "")
	echo "*** Project description file hasn't been set" >&2
	exit 1
	;;
esac

# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero="0000000000000000000000000000000000000000"
if [ "$newrev" = "$zero" ]; then
	newrev_type=delete
else
	newrev_type=$(git cat-file -t $newrev)
fi

case "$refname","$newrev_type" in
	refs/tags/*,commit)
		# un-annotated tag
		short_refname=${refname##refs/tags/}
		if [ "$allowunannotated" != "true" ]; then
			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
			exit 1
		fi
		;;
	refs/tags/*,delete)
		# delete tag
		if [ "$allowdeletetag" != "true" ]; then
			echo "*** Deleting a tag is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/tags/*,tag)
		# annotated tag
		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
		then
			echo "*** Tag '$refname' already exists." >&2
			echo "*** Modifying a tag is not allowed in this repository." >&2
			exit 1
		fi
		;;
	refs/heads/*,commit)
		# branch
		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
			echo "*** Creating a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/heads/*,delete)
		# delete branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/remotes/*,commit)
		# tracking branch
		;;
	refs/remotes/*,delete)
		# delete tracking branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	*)
		# Anything else (is there anything else?)
		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
		exit 1
		;;
esac

# --- Finished
exit 0


================================================
FILE: levels/conflict/.githug/info/exclude
================================================
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~


================================================
FILE: levels/conflict/.githug/logs/HEAD
================================================
0000000000000000000000000000000000000000 306868e3258be1f35ae43db71e3a6d7edf42ffe7 Thameera Senanayaka <thameera123@gmail.com> 1352041121 +0530	commit (initial): Initial commit
306868e3258be1f35ae43db71e3a6d7edf42ffe7 40e20a455ac2731ad25c297b03aa543d7eedf6ab Thameera Senanayaka <thameera123@gmail.com> 1352041153 +0530	commit: Added two lines
40e20a455ac2731ad25c297b03aa543d7eedf6ab 306868e3258be1f35ae43db71e3a6d7edf42ffe7 Thameera Senanayaka <thameera123@gmail.com> 1352041162 +0530	checkout: moving from master to mybranch
306868e3258be1f35ae43db71e3a6d7edf42ffe7 50a127cb066eb903a6fa59d71802c10cb442fb3b Thameera Senanayaka <thameera123@gmail.com> 1352041213 +0530	commit: Added lines
50a127cb066eb903a6fa59d71802c10cb442fb3b 75179304f4fab00613f08a9412b6cb0965bfa564 Thameera Senanayaka <thameera123@gmail.com> 1352041234 +0530	commit: Added comment
75179304f4fab00613f08a9412b6cb0965bfa564 40e20a455ac2731ad25c297b03aa543d7eedf6ab Thameera Senanayaka <thameera123@gmail.com> 1352041240 +0530	checkout: moving from mybranch to master
40e20a455ac2731ad25c297b03aa543d7eedf6ab 75179304f4fab00613f08a9412b6cb0965bfa564 Alex <snooz@localhost.localdomain> 1382868220 -0700	checkout: moving from master to mybranch
75179304f4fab00613f08a9412b6cb0965bfa564 bdc7bec8acae9b3eabf0a15b223a48211b7a89a1 Alex <snooz@localhost.localdomain> 1382868333 -0700	commit: Changed the poem
bdc7bec8acae9b3eabf0a15b223a48211b7a89a1 3d7aec017559be2b61cab850dafdcb2b6212f1c3 Alex <snooz@localhost.localdomain> 1382868450 -0700	commit (amend): Changed the poem
3d7aec017559be2b61cab850dafdcb2b6212f1c3 40e20a455ac2731ad25c297b03aa543d7eedf6ab Alex <snooz@localhost.localdomain> 1382868483 -0700	checkout: moving from mybranch to master
40e20a455ac2731ad25c297b03aa543d7eedf6ab 30cc28e66966109bb5bfbe96d6c817c367d2050a Alex <snooz@localhost.localdomain> 1382868518 -0700	commit: Updated the poem
30cc28e66966109bb5bfbe96d6c817c367d2050a c797f979cf24ba148bf10d5e26f5d7402dd5f2e1 Alex <snooz@localhost.localdomain> 1382868533 -0700	commit (amend): Updated the poem


================================================
FILE: levels/conflict/.githug/logs/refs/heads/master
================================================
0000000000000000000000000000000000000000 306868e3258be1f35ae43db71e3a6d7edf42ffe7 Thameera Senanayaka <thameera123@gmail.com> 1352041121 +0530	commit (initial): Initial commit
306868e3258be1f35ae43db71e3a6d7edf42ffe7 40e20a455ac2731ad25c297b03aa543d7eedf6ab Thameera Senanayaka <thameera123@gmail.com> 1352041153 +0530	commit: Added two lines
40e20a455ac2731ad25c297b03aa543d7eedf6ab 30cc28e66966109bb5bfbe96d6c817c367d2050a Alex <snooz@localhost.localdomain> 1382868518 -0700	commit: Updated the poem
30cc28e66966109bb5bfbe96d6c817c367d2050a c797f979cf24ba148bf10d5e26f5d7402dd5f2e1 Alex <snooz@localhost.localdomain> 1382868533 -0700	commit (amend): Updated the poem


================================================
FILE: levels/conflict/.githug/logs/refs/heads/mybranch
================================================
0000000000000000000000000000000000000000 306868e3258be1f35ae43db71e3a6d7edf42ffe7 Thameera Senanayaka <thameera123@gmail.com> 1352041133 +0530	branch: Created from master
306868e3258be1f35ae43db71e3a6d7edf42ffe7 50a127cb066eb903a6fa59d71802c10cb442fb3b Thameera Senanayaka <thameera123@gmail.com> 1352041213 +0530	commit: Added lines
50a127cb066eb903a6fa59d71802c10cb442fb3b 75179304f4fab00613f08a9412b6cb0965bfa564 Thameera Senanayaka <thameera123@gmail.com> 1352041234 +0530	commit: Added comment
75179304f4fab00613f08a9412b6cb0965bfa564 bdc7bec8acae9b3eabf0a15b223a48211b7a89a1 Alex <snooz@localhost.localdomain> 1382868333 -0700	commit: Changed the poem
bdc7bec8acae9b3eabf0a15b223a48211b7a89a1 3d7aec017559be2b61cab850dafdcb2b6212f1c3 Alex <snooz@localhost.localdomain> 1382868450 -0700	commit (amend): Changed the poem


================================================
FILE: levels/conflict/.githug/objects/2d/0d90051e320215f54f357e746c9838490557e7
================================================
x+)JMU06c040031Q(O+(apKLyVi.G1Z>

================================================
FILE: levels/conflict/.githug/objects/3d/7aec017559be2b61cab850dafdcb2b6212f1c3
================================================
x=[JC1E(,'8ISz4:z/R,XZ/QOs0C"bQ!rD9es(=5b{qm[M6":`v3-(T;7jMW|@\^_@jZkxF(v<u/8[?~^hYaB	fauM

================================================
FILE: levels/conflict/.githug/objects/6b/0c0b32bdca3af9beb831744cb755d6fdc7c7c0
================================================
xU	0EQשU 
 `3~`	vop'\cE-acyྙE"Gb*ةY+ETQكoNF>0Л&

================================================
FILE: levels/conflict/.githug/objects/75/179304f4fab00613f08a9412b6cb0965bfa564
================================================
xKn@@Y)@瓤=\q j'AtI^bO֩~V3=8GRQ"b
I&LU4 wY1%QP:3axTN~mYrj
mY% ?]L߇#a0ztbqX_۶yV8Db

================================================
FILE: levels/conflict/.githug/objects/88/e0473c9da347c6311f5f8eca8d256bf25402b6
================================================
x+)JMU06c040031Q(O+(ap1kzY)x׌
/

================================================
FILE: levels/conflict/.githug/objects/bd/c7bec8acae9b3eabf0a15b223a48211b7a89a1
================================================
xA
0@Q9\@dd"'4[h=y,SGth*d%F٫!eR1l 6D®tET%v%?$OEzynpZ:A汾i\XbǞͰ?6O(C3QYu1?6lJ

================================================
FILE: levels/conflict/.githug/refs/heads/master
================================================
c797f979cf24ba148bf10d5e26f5d7402dd5f2e1


================================================
FILE: levels/conflict/.githug/refs/heads/mybranch
================================================
3d7aec017559be2b61cab850dafdcb2b6212f1c3


================================================
FILE: levels/conflict/poem.txt
================================================
Humpty dumpty
Categorized shoes by color
Humpty dumpty
Had a great fall



================================================
FILE: levels/conflict.rb
================================================
difficulty 4
description "You need to merge mybranch into the current branch (master). But there may be some incorrect changes in mybranch which may cause conflicts. Solve any merge-conflicts you come across and finish the merge."

setup do
  init_from_level
  system "git branch -m master"
end

solution do
  solved = true

  solved = false unless repo.head.name == "master"
  solved = false unless repo.commits("master")[0].parents.length == 2

  txt = File.read("poem.txt")
  solved = false if txt =~ /[<>=|]/
  solved = false unless txt =~ /Sat on a wall/

  solved
end

hint do
  puts ["First you have to do a merge. Then resolve any conflicts and finish the merge", "Take a look at the sections on merge conflicts in 'git merge'.", "Remove the unnecessary lines in `poem.txt`, so only the correct poem remains."]
end


================================================
FILE: levels/contribute.rb
================================================
difficulty 3
description "This is the final level, the goal is to contribute to this repository by making a pull request on GitHub. Please note that this level is designed to encourage you to add a valid contribution to Githug, not testing your ability to create a pull request. Contributions that are likely to be accepted are levels, bug fixes and improved documentation."

solution do
  location = "/tmp/githug"
  FileUtils.rm_rf(location)
  puts "Cloning repository to #{location}"
  `git clone https://github.com/Gazler/githug #{location}`

  contributor = false

  repo = Grit::Repo.new(location)
  repo.commits('master', false).each do |commit|
    if commit.author.name == repo.config["user.name"]
      if commit.author.email == repo.config["user.email"]
        contributor = true
      end
    end
  end
  contributor
end

hint do
  puts "Forking the repository would be a good start!"
end


================================================
FILE: levels/delete_branch/.githug/COMMIT_EDITMSG
================================================
delete_me branch


================================================
FILE: levels/delete_branch/.githug/HEAD
================================================
ref: refs/heads/master


================================================
FILE: levels/delete_branch/.githug/config
================================================
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
	precomposeunicode = false


================================================
FILE: levels/delete_branch/.githug/description
================================================
Unnamed repository; edit this file 'description' to name the repository.


================================================
FILE: levels/delete_branch/.githug/hooks/applypatch-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message taken by
# applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.  The hook is
# allowed to edit the commit message file.
#
# To enable this hook, rename this file to "applypatch-msg".

. git-sh-setup
test -x "$GIT_DIR/hooks/commit-msg" &&
	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
:


================================================
FILE: levels/delete_branch/.githug/hooks/commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message.  The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit.  The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".

# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

# This example catches duplicate Signed-off-by lines.

test "" = "$(grep '^Signed-off-by: ' "$1" |
	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
	echo >&2 Duplicate Signed-off-by lines.
	exit 1
}


================================================
FILE: levels/delete_branch/.githug/hooks/post-update.sample
================================================
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".

exec git update-server-info


================================================
FILE: levels/delete_branch/.githug/hooks/pre-applypatch.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed
# by applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-applypatch".

. git-sh-setup
test -x "$GIT_DIR/hooks/pre-commit" &&
	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
:


================================================
FILE: levels/delete_branch/.githug/hooks/pre-commit.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
	against=HEAD
else
	# Initial commit: diff against an empty tree object
	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config hooks.allownonascii)

# Redirect output to stderr.
exec 1>&2

# Cross platform projects tend to avoid non-ASCII filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
	# Note that the use of brackets around a tr range is ok here, (it's
	# even required, for portability to Solaris 10's /usr/bin/tr), since
	# the square bracket bytes happen to fall in the designated range.
	test $(git diff --cached --name-only --diff-filter=A -z $against |
	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
	cat <<\EOF
Error: Attempt to add a non-ASCII file name.

This can cause problems if you want to work with people on other platforms.

To be portable it is advisable to rename the file.

If you know what you are doing you can disable this check using:

  git config hooks.allownonascii true
EOF
	exit 1
fi

# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --


================================================
FILE: levels/delete_branch/.githug/hooks/pre-push.sample
================================================
#!/bin/sh

# An example hook script to verify what is about to be pushed.  Called by "git
# push" after it has checked the remote status, but before anything has been
# pushed.  If this script exits with a non-zero status nothing will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
#   <local ref> <local sha1> <remote ref> <remote sha1>
#
# This sample shows how to prevent push of commits where the log message starts
# with "WIP" (work in progress).

remote="$1"
url="$2"

z40=0000000000000000000000000000000000000000

IFS=' '
while read local_ref local_sha remote_ref remote_sha
do
	if [ "$local_sha" = $z40 ]
	then
		# Handle delete
	else
		if [ "$remote_sha" = $z40 ]
		then
			# New branch, examine all commits
			range="$local_sha"
		else
			# Update to existing branch, examine new commits
			range="$remote_sha..$local_sha"
		fi

		# Check for WIP commit
		commit=`git rev-list -n 1 --grep '^WIP' "$range"`
		if [ -n "$commit" ]
		then
			echo "Found WIP commit in $local_ref, not pushing"
			exit 1
		fi
	fi
done

exit 0


================================================
FILE: levels/delete_branch/.githug/hooks/pre-rebase.sample
================================================
#!/bin/sh
#
# Copyright (c) 2006, 2008 Junio C Hamano
#
# The "pre-rebase" hook is run just before "git rebase" starts doing
# its job, and can prevent the command from running by exiting with
# non-zero status.
#
# The hook is called with the following parameters:
#
# $1 -- the upstream the series was forked from.
# $2 -- the branch being rebased (or empty when rebasing the current branch).
#
# This sample shows how to prevent topic branches that are already
# merged to 'next' branch from getting rebased, because allowing it
# would result in rebasing already published history.

publish=next
basebranch="$1"
if test "$#" = 2
then
	topic="refs/heads/$2"
else
	topic=`git symbolic-ref HEAD` ||
	exit 0 ;# we do not interrupt rebasing detached HEAD
fi

case "$topic" in
refs/heads/??/*)
	;;
*)
	exit 0 ;# we do not interrupt others.
	;;
esac

# Now we are dealing with a topic branch being rebased
# on top of master.  Is it OK to rebase it?

# Does the topic really exist?
git show-ref -q "$topic" || {
	echo >&2 "No such branch $topic"
	exit 1
}

# Is topic fully merged to master?
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
if test -z "$not_in_master"
then
	echo >&2 "$topic is fully merged to master; better remove it."
	exit 1 ;# we could allow it, but there is no point.
fi

# Is topic ever merged to next?  If so you should not be rebasing it.
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
only_next_2=`git rev-list ^master           ${publish} | sort`
if test "$only_next_1" = "$only_next_2"
then
	not_in_topic=`git rev-list "^$topic" master`
	if test -z "$not_in_topic"
	then
		echo >&2 "$topic is already up-to-date with master"
		exit 1 ;# we could allow it, but there is no point.
	else
		exit 0
	fi
else
	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
	/usr/bin/perl -e '
		my $topic = $ARGV[0];
		my $msg = "* $topic has commits already merged to public branch:\n";
		my (%not_in_next) = map {
			/^([0-9a-f]+) /;
			($1 => 1);
		} split(/\n/, $ARGV[1]);
		for my $elem (map {
				/^([0-9a-f]+) (.*)$/;
				[$1 => $2];
			} split(/\n/, $ARGV[2])) {
			if (!exists $not_in_next{$elem->[0]}) {
				if ($msg) {
					print STDERR $msg;
					undef $msg;
				}
				print STDERR " $elem->[1]\n";
			}
		}
	' "$topic" "$not_in_next" "$not_in_master"
	exit 1
fi

exit 0

################################################################

This sample hook safeguards topic branches that have been
published from being rewound.

The workflow assumed here is:

 * Once a topic branch forks from "master", "master" is never
   merged into it again (either directly or indirectly).

 * Once a topic branch is fully cooked and merged into "master",
   it is deleted.  If you need to build on top of it to correct
   earlier mistakes, a new topic branch is created by forking at
   the tip of the "master".  This is not strictly necessary, but
   it makes it easier to keep your history simple.

 * Whenever you need to test or publish your changes to topic
   branches, merge them into "next" branch.

The script, being an example, hardcodes the publish branch name
to be "next", but it is trivial to make it configurable via
$GIT_DIR/config mechanism.

With this workflow, you would want to know:

(1) ... if a topic branch has ever been merged to "next".  Young
    topic branches can have stupid mistakes you would rather
    clean up before publishing, and things that have not been
    merged into other branches can be easily rebased without
    affecting other people.  But once it is published, you would
    not want to rewind it.

(2) ... if a topic branch has been fully merged to "master".
    Then you can delete it.  More importantly, you should not
    build on top of it -- other people may already want to
    change things related to the topic as patches against your
    "master", so if you need further changes, it is better to
    fork the topic (perhaps with the same name) afresh from the
    tip of "master".

Let's look at this example:

		   o---o---o---o---o---o---o---o---o---o "next"
		  /       /           /           /
		 /   a---a---b A     /           /
		/   /               /           /
	       /   /   c---c---c---c B         /
	      /   /   /             \         /
	     /   /   /   b---b C     \       /
	    /   /   /   /             \     /
    ---o---o---o---o---o---o---o---o---o---o---o "master"


A, B and C are topic branches.

 * A has one fix since it was merged up to "next".

 * B has finished.  It has been fully merged up to "master" and "next",
   and is ready to be deleted.

 * C has not merged to "next" at all.

We would want to allow C to be rebased, refuse A, and encourage
B to be deleted.

To compute (1):

	git rev-list ^master ^topic next
	git rev-list ^master        next

	if these match, topic has not merged in next at all.

To compute (2):

	git rev-list master..topic

	if this is empty, it is fully merged to "master".


================================================
FILE: levels/delete_branch/.githug/hooks/prepare-commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to prepare the commit log message.
# Called by "git commit" with the name of the file that has the
# commit message, followed by the description of the commit
# message's source.  The hook's purpose is to edit the commit
# message file.  If the hook fails with a non-zero status,
# the commit is aborted.
#
# To enable this hook, rename this file to "prepare-commit-msg".

# This hook includes three examples.  The first comments out the
# "Conflicts:" part of a merge commit.
#
# The second includes the output of "git diff --name-status -r"
# into the message, just before the "git status" output.  It is
# commented because it doesn't cope with --amend or with squashed
# commits.
#
# The third example adds a Signed-off-by line to the message, that can
# still be edited.  This is rarely a good idea.

case "$2,$3" in
  merge,)
    /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;

# ,|template,)
#   /usr/bin/perl -i.bak -pe '
#      print "\n" . `git diff --cached --name-status -r`
#	 if /^#/ && $first++ == 0' "$1" ;;

  *) ;;
esac

# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"


================================================
FILE: levels/delete_branch/.githug/hooks/update.sample
================================================
#!/bin/sh
#
# An example hook script to blocks unannotated tags from entering.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
# Config
# ------
# hooks.allowunannotated
#   This boolean sets whether unannotated tags will be allowed into the
#   repository.  By default they won't be.
# hooks.allowdeletetag
#   This boolean sets whether deleting tags will be allowed in the
#   repository.  By default they won't be.
# hooks.allowmodifytag
#   This boolean sets whether a tag may be modified after creation. By default
#   it won't be.
# hooks.allowdeletebranch
#   This boolean sets whether deleting branches will be allowed in the
#   repository.  By default they won't be.
# hooks.denycreatebranch
#   This boolean sets whether remotely creating branches will be denied
#   in the repository.  By default this is allowed.
#

# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"

# --- Safety check
if [ -z "$GIT_DIR" ]; then
	echo "Don't run this script from the command line." >&2
	echo " (if you want, you could supply GIT_DIR then run" >&2
	echo "  $0 <ref> <oldrev> <newrev>)" >&2
	exit 1
fi

if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
	echo "usage: $0 <ref> <oldrev> <newrev>" >&2
	exit 1
fi

# --- Config
allowunannotated=$(git config --bool hooks.allowunannotated)
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
denycreatebranch=$(git config --bool hooks.denycreatebranch)
allowdeletetag=$(git config --bool hooks.allowdeletetag)
allowmodifytag=$(git config --bool hooks.allowmodifytag)

# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
case "$projectdesc" in
"Unnamed repository"* | "")
	echo "*** Project description file hasn't been set" >&2
	exit 1
	;;
esac

# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero="0000000000000000000000000000000000000000"
if [ "$newrev" = "$zero" ]; then
	newrev_type=delete
else
	newrev_type=$(git cat-file -t $newrev)
fi

case "$refname","$newrev_type" in
	refs/tags/*,commit)
		# un-annotated tag
		short_refname=${refname##refs/tags/}
		if [ "$allowunannotated" != "true" ]; then
			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
			exit 1
		fi
		;;
	refs/tags/*,delete)
		# delete tag
		if [ "$allowdeletetag" != "true" ]; then
			echo "*** Deleting a tag is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/tags/*,tag)
		# annotated tag
		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
		then
			echo "*** Tag '$refname' already exists." >&2
			echo "*** Modifying a tag is not allowed in this repository." >&2
			exit 1
		fi
		;;
	refs/heads/*,commit)
		# branch
		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
			echo "*** Creating a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/heads/*,delete)
		# delete branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/remotes/*,commit)
		# tracking branch
		;;
	refs/remotes/*,delete)
		# delete tracking branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	*)
		# Anything else (is there anything else?)
		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
		exit 1
		;;
esac

# --- Finished
exit 0


================================================
FILE: levels/delete_branch/.githug/info/exclude
================================================
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~


================================================
FILE: levels/delete_branch/.githug/logs/HEAD
================================================
0000000000000000000000000000000000000000 b60afe294eb3c200d646995c9e0234470157c1b0 Daniel Smilansky <dsmilansky@gmail.com> 1386225561 -0800	commit (initial): first commit
b60afe294eb3c200d646995c9e0234470157c1b0 b60afe294eb3c200d646995c9e0234470157c1b0 Daniel Smilansky <dsmilansky@gmail.com> 1386225573 -0800	checkout: moving from master to master
b60afe294eb3c200d646995c9e0234470157c1b0 b60afe294eb3c200d646995c9e0234470157c1b0 Daniel Smilansky <dsmilansky@gmail.com> 1386225580 -0800	checkout: moving from master to delete_me
b60afe294eb3c200d646995c9e0234470157c1b0 b60afe294eb3c200d646995c9e0234470157c1b0 Daniel Smilansky <dsmilansky@gmail.com> 1386225584 -0800	checkout: moving from delete_me to master


================================================
FILE: levels/delete_branch/.githug/logs/refs/heads/delete_me
================================================
0000000000000000000000000000000000000000 b60afe294eb3c200d646995c9e0234470157c1b0 Daniel Smilansky <dsmilansky@gmail.com> 1386225568 -0800	branch: Created from master


================================================
FILE: levels/delete_branch/.githug/logs/refs/heads/master
================================================
0000000000000000000000000000000000000000 b60afe294eb3c200d646995c9e0234470157c1b0 Daniel Smilansky <dsmilansky@gmail.com> 1386225561 -0800	commit (initial): first commit


================================================
FILE: levels/delete_branch/.githug/objects/b6/0afe294eb3c200d646995c9e0234470157c1b0
================================================
x
!aT1
h'v`Kx{+=<_q73'OBc#œwFh6zzLk2%>
|ǘgNJx|%1?Q

================================================
FILE: levels/delete_branch/.githug/refs/heads/delete_me
================================================
b60afe294eb3c200d646995c9e0234470157c1b0


================================================
FILE: levels/delete_branch/.githug/refs/heads/master
================================================
b60afe294eb3c200d646995c9e0234470157c1b0


================================================
FILE: levels/delete_branch/readme
================================================


================================================
FILE: levels/delete_branch.rb
================================================
difficulty 2

description "You have created too many branches for your project. There is an old branch in your repo called 'delete_me', you should delete it."

setup do
  init_from_level
  system "git branch -m master"
end

solution do
  return true unless repo.branches.map(&:name).include?('delete_me')
end

hint do
  puts "Running 'git --help branch' will give you a list of branch commands."
end


================================================
FILE: levels/diff/.githug/COMMIT_EDITMSG
================================================
added app.rb


================================================
FILE: levels/diff/.githug/HEAD
================================================
ref: refs/heads/master


================================================
FILE: levels/diff/.githug/config
================================================
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true


================================================
FILE: levels/diff/.githug/description
================================================
Unnamed repository; edit this file 'description' to name the repository.


================================================
FILE: levels/diff/.githug/hooks/applypatch-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message taken by
# applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.  The hook is
# allowed to edit the commit message file.
#
# To enable this hook, rename this file to "applypatch-msg".

. git-sh-setup
test -x "$GIT_DIR/hooks/commit-msg" &&
	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
:


================================================
FILE: levels/diff/.githug/hooks/commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message.  The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit.  The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".

# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

# This example catches duplicate Signed-off-by lines.

test "" = "$(grep '^Signed-off-by: ' "$1" |
	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
	echo >&2 Duplicate Signed-off-by lines.
	exit 1
}


================================================
FILE: levels/diff/.githug/hooks/post-commit.sample
================================================
#!/bin/sh
#
# An example hook script that is called after a successful
# commit is made.
#
# To enable this hook, rename this file to "post-commit".

: Nothing


================================================
FILE: levels/diff/.githug/hooks/post-receive.sample
================================================
#!/bin/sh
#
# An example hook script for the "post-receive" event.
#
# The "post-receive" script is run after receive-pack has accepted a pack
# and the repository has been updated.  It is passed arguments in through
# stdin in the form
#  <oldrev> <newrev> <refname>
# For example:
#  aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
#
# see contrib/hooks/ for a sample, or uncomment the next line and
# rename the file to "post-receive".

#. /usr/share/doc/git-core/contrib/hooks/post-receive-email


================================================
FILE: levels/diff/.githug/hooks/post-update.sample
================================================
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".

exec git update-server-info


================================================
FILE: levels/diff/.githug/hooks/pre-applypatch.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed
# by applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-applypatch".

. git-sh-setup
test -x "$GIT_DIR/hooks/pre-commit" &&
	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
:


================================================
FILE: levels/diff/.githug/hooks/pre-commit.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
	against=HEAD
else
	# Initial commit: diff against an empty tree object
	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# If you want to allow non-ascii filenames set this variable to true.
allownonascii=$(git config hooks.allownonascii)

# Cross platform projects tend to avoid non-ascii filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
	# Note that the use of brackets around a tr range is ok here, (it's
	# even required, for portability to Solaris 10's /usr/bin/tr), since
	# the square bracket bytes happen to fall in the designated range.
	test "$(git diff --cached --name-only --diff-filter=A -z $against |
	  LC_ALL=C tr -d '[ -~]\0')"
then
	echo "Error: Attempt to add a non-ascii file name."
	echo
	echo "This can cause problems if you want to work"
	echo "with people on other platforms."
	echo
	echo "To be portable it is advisable to rename the file ..."
	echo
	echo "If you know what you are doing you can disable this"
	echo "check using:"
	echo
	echo "  git config hooks.allownonascii true"
	echo
	exit 1
fi

exec git diff-index --check --cached $against --


================================================
FILE: levels/diff/.githug/hooks/pre-rebase.sample
================================================
#!/bin/sh
#
# Copyright (c) 2006, 2008 Junio C Hamano
#
# The "pre-rebase" hook is run just before "git rebase" starts doing
# its job, and can prevent the command from running by exiting with
# non-zero status.
#
# The hook is called with the following parameters:
#
# $1 -- the upstream the series was forked from.
# $2 -- the branch being rebased (or empty when rebasing the current branch).
#
# This sample shows how to prevent topic branches that are already
# merged to 'next' branch from getting rebased, because allowing it
# would result in rebasing already published history.

publish=next
basebranch="$1"
if test "$#" = 2
then
	topic="refs/heads/$2"
else
	topic=`git symbolic-ref HEAD` ||
	exit 0 ;# we do not interrupt rebasing detached HEAD
fi

case "$topic" in
refs/heads/??/*)
	;;
*)
	exit 0 ;# we do not interrupt others.
	;;
esac

# Now we are dealing with a topic branch being rebased
# on top of master.  Is it OK to rebase it?

# Does the topic really exist?
git show-ref -q "$topic" || {
	echo >&2 "No such branch $topic"
	exit 1
}

# Is topic fully merged to master?
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
if test -z "$not_in_master"
then
	echo >&2 "$topic is fully merged to master; better remove it."
	exit 1 ;# we could allow it, but there is no point.
fi

# Is topic ever merged to next?  If so you should not be rebasing it.
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
only_next_2=`git rev-list ^master           ${publish} | sort`
if test "$only_next_1" = "$only_next_2"
then
	not_in_topic=`git rev-list "^$topic" master`
	if test -z "$not_in_topic"
	then
		echo >&2 "$topic is already up-to-date with master"
		exit 1 ;# we could allow it, but there is no point.
	else
		exit 0
	fi
else
	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
	/usr/bin/perl -e '
		my $topic = $ARGV[0];
		my $msg = "* $topic has commits already merged to public branch:\n";
		my (%not_in_next) = map {
			/^([0-9a-f]+) /;
			($1 => 1);
		} split(/\n/, $ARGV[1]);
		for my $elem (map {
				/^([0-9a-f]+) (.*)$/;
				[$1 => $2];
			} split(/\n/, $ARGV[2])) {
			if (!exists $not_in_next{$elem->[0]}) {
				if ($msg) {
					print STDERR $msg;
					undef $msg;
				}
				print STDERR " $elem->[1]\n";
			}
		}
	' "$topic" "$not_in_next" "$not_in_master"
	exit 1
fi

exit 0

################################################################

This sample hook safeguards topic branches that have been
published from being rewound.

The workflow assumed here is:

 * Once a topic branch forks from "master", "master" is never
   merged into it again (either directly or indirectly).

 * Once a topic branch is fully cooked and merged into "master",
   it is deleted.  If you need to build on top of it to correct
   earlier mistakes, a new topic branch is created by forking at
   the tip of the "master".  This is not strictly necessary, but
   it makes it easier to keep your history simple.

 * Whenever you need to test or publish your changes to topic
   branches, merge them into "next" branch.

The script, being an example, hardcodes the publish branch name
to be "next", but it is trivial to make it configurable via
$GIT_DIR/config mechanism.

With this workflow, you would want to know:

(1) ... if a topic branch has ever been merged to "next".  Young
    topic branches can have stupid mistakes you would rather
    clean up before publishing, and things that have not been
    merged into other branches can be easily rebased without
    affecting other people.  But once it is published, you would
    not want to rewind it.

(2) ... if a topic branch has been fully merged to "master".
    Then you can delete it.  More importantly, you should not
    build on top of it -- other people may already want to
    change things related to the topic as patches against your
    "master", so if you need further changes, it is better to
    fork the topic (perhaps with the same name) afresh from the
    tip of "master".

Let's look at this example:

		   o---o---o---o---o---o---o---o---o---o "next"
		  /       /           /           /
		 /   a---a---b A     /           /
		/   /               /           /
	       /   /   c---c---c---c B         /
	      /   /   /             \         /
	     /   /   /   b---b C     \       /
	    /   /   /   /             \     /
    ---o---o---o---o---o---o---o---o---o---o---o "master"


A, B and C are topic branches.

 * A has one fix since it was merged up to "next".

 * B has finished.  It has been fully merged up to "master" and "next",
   and is ready to be deleted.

 * C has not merged to "next" at all.

We would want to allow C to be rebased, refuse A, and encourage
B to be deleted.

To compute (1):

	git rev-list ^master ^topic next
	git rev-list ^master        next

	if these match, topic has not merged in next at all.

To compute (2):

	git rev-list master..topic

	if this is empty, it is fully merged to "master".


================================================
FILE: levels/diff/.githug/hooks/prepare-commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to prepare the commit log message.
# Called by "git commit" with the name of the file that has the
# commit message, followed by the description of the commit
# message's source.  The hook's purpose is to edit the commit
# message file.  If the hook fails with a non-zero status,
# the commit is aborted.
#
# To enable this hook, rename this file to "prepare-commit-msg".

# This hook includes three examples.  The first comments out the
# "Conflicts:" part of a merge commit.
#
# The second includes the output of "git diff --name-status -r"
# into the message, just before the "git status" output.  It is
# commented because it doesn't cope with --amend or with squashed
# commits.
#
# The third example adds a Signed-off-by line to the message, that can
# still be edited.  This is rarely a good idea.

case "$2,$3" in
  merge,)
    /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;

# ,|template,)
#   /usr/bin/perl -i.bak -pe '
#      print "\n" . `git diff --cached --name-status -r`
#	 if /^#/ && $first++ == 0' "$1" ;;

  *) ;;
esac

# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"


================================================
FILE: levels/diff/.githug/hooks/update.sample
================================================
#!/bin/sh
#
# An example hook script to blocks unannotated tags from entering.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
# Config
# ------
# hooks.allowunannotated
#   This boolean sets whether unannotated tags will be allowed into the
#   repository.  By default they won't be.
# hooks.allowdeletetag
#   This boolean sets whether deleting tags will be allowed in the
#   repository.  By default they won't be.
# hooks.allowmodifytag
#   This boolean sets whether a tag may be modified after creation. By default
#   it won't be.
# hooks.allowdeletebranch
#   This boolean sets whether deleting branches will be allowed in the
#   repository.  By default they won't be.
# hooks.denycreatebranch
#   This boolean sets whether remotely creating branches will be denied
#   in the repository.  By default this is allowed.
#

# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"

# --- Safety check
if [ -z "$GIT_DIR" ]; then
	echo "Don't run this script from the command line." >&2
	echo " (if you want, you could supply GIT_DIR then run" >&2
	echo "  $0 <ref> <oldrev> <newrev>)" >&2
	exit 1
fi

if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
	exit 1
fi

# --- Config
allowunannotated=$(git config --bool hooks.allowunannotated)
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
denycreatebranch=$(git config --bool hooks.denycreatebranch)
allowdeletetag=$(git config --bool hooks.allowdeletetag)
allowmodifytag=$(git config --bool hooks.allowmodifytag)

# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
case "$projectdesc" in
"Unnamed repository"* | "")
	echo "*** Project description file hasn't been set" >&2
	exit 1
	;;
esac

# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero="0000000000000000000000000000000000000000"
if [ "$newrev" = "$zero" ]; then
	newrev_type=delete
else
	newrev_type=$(git cat-file -t $newrev)
fi

case "$refname","$newrev_type" in
	refs/tags/*,commit)
		# un-annotated tag
		short_refname=${refname##refs/tags/}
		if [ "$allowunannotated" != "true" ]; then
			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
			exit 1
		fi
		;;
	refs/tags/*,delete)
		# delete tag
		if [ "$allowdeletetag" != "true" ]; then
			echo "*** Deleting a tag is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/tags/*,tag)
		# annotated tag
		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
		then
			echo "*** Tag '$refname' already exists." >&2
			echo "*** Modifying a tag is not allowed in this repository." >&2
			exit 1
		fi
		;;
	refs/heads/*,commit)
		# branch
		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
			echo "*** Creating a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/heads/*,delete)
		# delete branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/remotes/*,commit)
		# tracking branch
		;;
	refs/remotes/*,delete)
		# delete tracking branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	*)
		# Anything else (is there anything else?)
		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
		exit 1
		;;
esac

# --- Finished
exit 0


================================================
FILE: levels/diff/.githug/info/exclude
================================================
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~


================================================
FILE: levels/diff/.githug/logs/HEAD
================================================
0000000000000000000000000000000000000000 dcaa55e97af34402e84d5336da37abcccc23cba6 Gary Rennie <webmaster@gazler.com> 1331585213 +0000	commit (initial): added app.rb


================================================
FILE: levels/diff/.githug/logs/refs/heads/master
================================================
0000000000000000000000000000000000000000 dcaa55e97af34402e84d5336da37abcccc23cba6 Gary Rennie <webmaster@gazler.com> 1331585213 +0000	commit (initial): added app.rb


================================================
FILE: levels/diff/.githug/objects/4f/703ca9bd25781b6758eeb3c42ed5348610ba6d
================================================
xSn03_ajZiQtKfjuZU!o6tڿeos=Dǯ$<\qϩԱ~W-u2r@Jq+bpGC-B3M͡s|.UUMDS)QUe+~;M'/~]YǫjujʎxCo5;b'Z"i"}߷Y=hb{fO6auJ`8w;容c?CXt<TF4:-c*b9$D堠f&0:nq>KnB}[݆G~z{U64c` #tm9x5*Dzaƒ
F5u
hXa*koT!i֠?fGMh@bX-/]Ntty+y O{F]\ZkE6W:DbXN4^ej\GY㛜]EP~W

================================================
FILE: levels/diff/.githug/objects/dc/aa55e97af34402e84d5336da37abcccc23cba6
================================================
xM
0F]J&?M
EܹdӔ=9*3`Wz4B.ZS$8$f^^*\Bmesx6[>T	Pk*p}ٵjRa߇+:

================================================
FILE: levels/diff/.githug/refs/heads/master
================================================
dcaa55e97af34402e84d5336da37abcccc23cba6


================================================
FILE: levels/diff/app.rb
================================================
require 'sinatra'
require 'oauth2'
require 'json'
enable :sessions

def client
  OAuth2::Client.new("mTeZFqkCmzc8JnjKXaSww95bFFxhUpp1wwmSi8vG", "a9OMyEdW7JvWThHmmvFcShR9P2dyad3EGuA2ULDh", :site => "http://localhost:3000")
end

get "/auth/test" do
  redirect client.auth_code.authorize_url(:redirect_uri => redirect_uri)
end

get '/auth/test/callback' do
  access_token = client.auth_code.get_token(params[:code], :redirect_uri => redirect_uri)
  session[:access_token] = access_token.token
  @message = "Successfully authenticated with the server"
  erb :success
end

get '/yet_another' do
  @message = get_response('data.json')
  erb :success
end
get '/another_page' do
  @message = get_response('server.json')
  erb :another
end

def get_response(url)
  access_token = OAuth2::AccessToken.new(client, session[:access_token])
  JSON.parse(access_token.get("/api/v1/#{url}").body)
end


def redirect_uri
  uri = URI.parse(request.url)
  uri.path = '/auth/test/callback'
  uri.query = nil
  uri.to_s
end



================================================
FILE: levels/diff.rb
================================================
difficulty 2
description "Since your last commit, file `app.rb` was modified. Find out which line has changed."

setup do
  init_from_level
  system "git branch -m master"
end

solution do
  line = request "What is the number of the line which has changed?"
  return false unless line == "26"
  true
end

hint do
  puts "You are looking for the difference since your last commit. Don't forget that running `git` on its own will list the possible commands."
end


================================================
FILE: levels/fetch.rb
================================================
difficulty 2
description "Looks like a new branch was pushed into our remote repository. Get the changes without merging them with the local repository "

setup do
  # remember the working directory so we can come back to it later
  cwd = Dir.pwd
  # initialize another git repo to be used as a "remote"
  tmpdir = Dir.mktmpdir

  # local repo
  repo.init
  system "git branch -m master"

  # adds a file to origin/master
  FileUtils.touch "master_file"
  repo.add        "master_file"
  repo.commit_all 'Commits master_file'

  # remote repo
  Dir.chdir tmpdir
  repo.init

  # adds a file to origin/master
  FileUtils.touch "master_file"
  repo.add        "master_file"
  repo.commit_all 'Commits master_file'

  # adds remote repo
  Dir.chdir cwd
  `git remote add origin #{tmpdir}/.git`
  `git fetch origin --quiet`
  `git branch -u origin/master master 2> /dev/null`

  Dir.chdir tmpdir
  # create a new branch in the remote repo
  `git checkout -b new_branch --quiet`

  # adds a file into the new branch.  Should not be pulled into the local
  FileUtils.touch "file1"
  repo.add        "file1"
  repo.commit_all 'Commits file 1'

end

solution do
  repo.init
  result = true

  # counts the number of local branches. Should equal 1
  local_branches = repo.branches.size

  # after a git fetch command, each branch will be stored in in the .git/FETCH_HEAD file. Each branch is on its own line
  # This command will count the number of lines, which will give the number of branches
  if File.file?('.git/FETCH_HEAD') # checks for file existence
    num_remote = File.read(".git/FETCH_HEAD").split("\n").count
  else
    num_remote = 0
  end

  # there should be 1 local branch and 2 remote branches for a success condition
  if local_branches == 1 and num_remote == 2
    result = true
  else
    result = false
  end
end

hint do
  puts "Look up the 'git fetch' command"
end


================================================
FILE: levels/find_old_branch/.githug/COMMIT_EDITMSG
================================================
commit another todo


================================================
FILE: levels/find_old_branch/.githug/HEAD
================================================
ref: refs/heads/kill_the_batman


================================================
FILE: levels/find_old_branch/.githug/ORIG_HEAD
================================================
05e9c01bd3c9264761dd0cde477400a2c3104642


================================================
FILE: levels/find_old_branch/.githug/config
================================================
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true


================================================
FILE: levels/find_old_branch/.githug/description
================================================
Unnamed repository; edit this file 'description' to name the repository.


================================================
FILE: levels/find_old_branch/.githug/hooks/applypatch-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message taken by
# applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.  The hook is
# allowed to edit the commit message file.
#
# To enable this hook, rename this file to "applypatch-msg".

. git-sh-setup
test -x "$GIT_DIR/hooks/commit-msg" &&
	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
:


================================================
FILE: levels/find_old_branch/.githug/hooks/commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message.  The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit.  The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".

# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

# This example catches duplicate Signed-off-by lines.

test "" = "$(grep '^Signed-off-by: ' "$1" |
	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
	echo >&2 Duplicate Signed-off-by lines.
	exit 1
}


================================================
FILE: levels/find_old_branch/.githug/hooks/post-commit.sample
================================================
#!/bin/sh
#
# An example hook script that is called after a successful
# commit is made.
#
# To enable this hook, rename this file to "post-commit".

: Nothing


================================================
FILE: levels/find_old_branch/.githug/hooks/post-receive.sample
================================================
#!/bin/sh
#
# An example hook script for the "post-receive" event.
#
# The "post-receive" script is run after receive-pack has accepted a pack
# and the repository has been updated.  It is passed arguments in through
# stdin in the form
#  <oldrev> <newrev> <refname>
# For example:
#  aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
#
# see contrib/hooks/ for a sample, or uncomment the next line and
# rename the file to "post-receive".

#. /usr/share/doc/git-core/contrib/hooks/post-receive-email


================================================
FILE: levels/find_old_branch/.githug/hooks/post-update.sample
================================================
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".

exec git update-server-info


================================================
FILE: levels/find_old_branch/.githug/hooks/pre-applypatch.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed
# by applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-applypatch".

. git-sh-setup
test -x "$GIT_DIR/hooks/pre-commit" &&
	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
:


================================================
FILE: levels/find_old_branch/.githug/hooks/pre-commit.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
	against=HEAD
else
	# Initial commit: diff against an empty tree object
	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# If you want to allow non-ascii filenames set this variable to true.
allownonascii=$(git config hooks.allownonascii)

# Redirect output to stderr.
exec 1>&2

# Cross platform projects tend to avoid non-ascii filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
	# Note that the use of brackets around a tr range is ok here, (it's
	# even required, for portability to Solaris 10's /usr/bin/tr), since
	# the square bracket bytes happen to fall in the designated range.
	test $(git diff --cached --name-only --diff-filter=A -z $against |
	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
	echo "Error: Attempt to add a non-ascii file name."
	echo
	echo "This can cause problems if you want to work"
	echo "with people on other platforms."
	echo
	echo "To be portable it is advisable to rename the file ..."
	echo
	echo "If you know what you are doing you can disable this"
	echo "check using:"
	echo
	echo "  git config hooks.allownonascii true"
	echo
	exit 1
fi

# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --


================================================
FILE: levels/find_old_branch/.githug/hooks/pre-rebase.sample
================================================
#!/bin/sh
#
# Copyright (c) 2006, 2008 Junio C Hamano
#
# The "pre-rebase" hook is run just before "git rebase" starts doing
# its job, and can prevent the command from running by exiting with
# non-zero status.
#
# The hook is called with the following parameters:
#
# $1 -- the upstream the series was forked from.
# $2 -- the branch being rebased (or empty when rebasing the current branch).
#
# This sample shows how to prevent topic branches that are already
# merged to 'next' branch from getting rebased, because allowing it
# would result in rebasing already published history.

publish=next
basebranch="$1"
if test "$#" = 2
then
	topic="refs/heads/$2"
else
	topic=`git symbolic-ref HEAD` ||
	exit 0 ;# we do not interrupt rebasing detached HEAD
fi

case "$topic" in
refs/heads/??/*)
	;;
*)
	exit 0 ;# we do not interrupt others.
	;;
esac

# Now we are dealing with a topic branch being rebased
# on top of master.  Is it OK to rebase it?

# Does the topic really exist?
git show-ref -q "$topic" || {
	echo >&2 "No such branch $topic"
	exit 1
}

# Is topic fully merged to master?
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
if test -z "$not_in_master"
then
	echo >&2 "$topic is fully merged to master; better remove it."
	exit 1 ;# we could allow it, but there is no point.
fi

# Is topic ever merged to next?  If so you should not be rebasing it.
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
only_next_2=`git rev-list ^master           ${publish} | sort`
if test "$only_next_1" = "$only_next_2"
then
	not_in_topic=`git rev-list "^$topic" master`
	if test -z "$not_in_topic"
	then
		echo >&2 "$topic is already up-to-date with master"
		exit 1 ;# we could allow it, but there is no point.
	else
		exit 0
	fi
else
	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
	/usr/bin/perl -e '
		my $topic = $ARGV[0];
		my $msg = "* $topic has commits already merged to public branch:\n";
		my (%not_in_next) = map {
			/^([0-9a-f]+) /;
			($1 => 1);
		} split(/\n/, $ARGV[1]);
		for my $elem (map {
				/^([0-9a-f]+) (.*)$/;
				[$1 => $2];
			} split(/\n/, $ARGV[2])) {
			if (!exists $not_in_next{$elem->[0]}) {
				if ($msg) {
					print STDERR $msg;
					undef $msg;
				}
				print STDERR " $elem->[1]\n";
			}
		}
	' "$topic" "$not_in_next" "$not_in_master"
	exit 1
fi

exit 0

################################################################

This sample hook safeguards topic branches that have been
published from being rewound.

The workflow assumed here is:

 * Once a topic branch forks from "master", "master" is never
   merged into it again (either directly or indirectly).

 * Once a topic branch is fully cooked and merged into "master",
   it is deleted.  If you need to build on top of it to correct
   earlier mistakes, a new topic branch is created by forking at
   the tip of the "master".  This is not strictly necessary, but
   it makes it easier to keep your history simple.

 * Whenever you need to test or publish your changes to topic
   branches, merge them into "next" branch.

The script, being an example, hardcodes the publish branch name
to be "next", but it is trivial to make it configurable via
$GIT_DIR/config mechanism.

With this workflow, you would want to know:

(1) ... if a topic branch has ever been merged to "next".  Young
    topic branches can have stupid mistakes you would rather
    clean up before publishing, and things that have not been
    merged into other branches can be easily rebased without
    affecting other people.  But once it is published, you would
    not want to rewind it.

(2) ... if a topic branch has been fully merged to "master".
    Then you can delete it.  More importantly, you should not
    build on top of it -- other people may already want to
    change things related to the topic as patches against your
    "master", so if you need further changes, it is better to
    fork the topic (perhaps with the same name) afresh from the
    tip of "master".

Let's look at this example:

		   o---o---o---o---o---o---o---o---o---o "next"
		  /       /           /           /
		 /   a---a---b A     /           /
		/   /               /           /
	       /   /   c---c---c---c B         /
	      /   /   /             \         /
	     /   /   /   b---b C     \       /
	    /   /   /   /             \     /
    ---o---o---o---o---o---o---o---o---o---o---o "master"


A, B and C are topic branches.

 * A has one fix since it was merged up to "next".

 * B has finished.  It has been fully merged up to "master" and "next",
   and is ready to be deleted.

 * C has not merged to "next" at all.

We would want to allow C to be rebased, refuse A, and encourage
B to be deleted.

To compute (1):

	git rev-list ^master ^topic next
	git rev-list ^master        next

	if these match, topic has not merged in next at all.

To compute (2):

	git rev-list master..topic

	if this is empty, it is fully merged to "master".


================================================
FILE: levels/find_old_branch/.githug/hooks/prepare-commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to prepare the commit log message.
# Called by "git commit" with the name of the file that has the
# commit message, followed by the description of the commit
# message's source.  The hook's purpose is to edit the commit
# message file.  If the hook fails with a non-zero status,
# the commit is aborted.
#
# To enable this hook, rename this file to "prepare-commit-msg".

# This hook includes three examples.  The first comments out the
# "Conflicts:" part of a merge commit.
#
# The second includes the output of "git diff --name-status -r"
# into the message, just before the "git status" output.  It is
# commented because it doesn't cope with --amend or with squashed
# commits.
#
# The third example adds a Signed-off-by line to the message, that can
# still be edited.  This is rarely a good idea.

case "$2,$3" in
  merge,)
    /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;

# ,|template,)
#   /usr/bin/perl -i.bak -pe '
#      print "\n" . `git diff --cached --name-status -r`
#	 if /^#/ && $first++ == 0' "$1" ;;

  *) ;;
esac

# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"


================================================
FILE: levels/find_old_branch/.githug/hooks/update.sample
================================================
#!/bin/sh
#
# An example hook script to blocks unannotated tags from entering.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
# Config
# ------
# hooks.allowunannotated
#   This boolean sets whether unannotated tags will be allowed into the
#   repository.  By default they won't be.
# hooks.allowdeletetag
#   This boolean sets whether deleting tags will be allowed in the
#   repository.  By default they won't be.
# hooks.allowmodifytag
#   This boolean sets whether a tag may be modified after creation. By default
#   it won't be.
# hooks.allowdeletebranch
#   This boolean sets whether deleting branches will be allowed in the
#   repository.  By default they won't be.
# hooks.denycreatebranch
#   This boolean sets whether remotely creating branches will be denied
#   in the repository.  By default this is allowed.
#

# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"

# --- Safety check
if [ -z "$GIT_DIR" ]; then
	echo "Don't run this script from the command line." >&2
	echo " (if you want, you could supply GIT_DIR then run" >&2
	echo "  $0 <ref> <oldrev> <newrev>)" >&2
	exit 1
fi

if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
	exit 1
fi

# --- Config
allowunannotated=$(git config --bool hooks.allowunannotated)
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
denycreatebranch=$(git config --bool hooks.denycreatebranch)
allowdeletetag=$(git config --bool hooks.allowdeletetag)
allowmodifytag=$(git config --bool hooks.allowmodifytag)

# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
case "$projectdesc" in
"Unnamed repository"* | "")
	echo "*** Project description file hasn't been set" >&2
	exit 1
	;;
esac

# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero="0000000000000000000000000000000000000000"
if [ "$newrev" = "$zero" ]; then
	newrev_type=delete
else
	newrev_type=$(git cat-file -t $newrev)
fi

case "$refname","$newrev_type" in
	refs/tags/*,commit)
		# un-annotated tag
		short_refname=${refname##refs/tags/}
		if [ "$allowunannotated" != "true" ]; then
			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
			exit 1
		fi
		;;
	refs/tags/*,delete)
		# delete tag
		if [ "$allowdeletetag" != "true" ]; then
			echo "*** Deleting a tag is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/tags/*,tag)
		# annotated tag
		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
		then
			echo "*** Tag '$refname' already exists." >&2
			echo "*** Modifying a tag is not allowed in this repository." >&2
			exit 1
		fi
		;;
	refs/heads/*,commit)
		# branch
		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
			echo "*** Creating a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/heads/*,delete)
		# delete branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/remotes/*,commit)
		# tracking branch
		;;
	refs/remotes/*,delete)
		# delete tracking branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	*)
		# Anything else (is there anything else?)
		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
		exit 1
		;;
esac

# --- Finished
exit 0


================================================
FILE: levels/find_old_branch/.githug/info/exclude
================================================
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
.DS_Store


================================================
FILE: levels/find_old_branch/.githug/logs/HEAD
================================================
0000000000000000000000000000000000000000 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283192 -0600	commit (initial): initial commit
6876e5b41fb693190df76b1baef6ef98623b4f1a 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283224 -0600	checkout: moving from cure_common_cold to kill_the_batman
6876e5b41fb693190df76b1baef6ef98623b4f1a 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283240 -0600	checkout: moving from kill_the_batman to blowup_sun_for_ransom
6876e5b41fb693190df76b1baef6ef98623b4f1a 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283272 -0600	checkout: moving from blowup_sun_for_ransom to solve_world_hunger
6876e5b41fb693190df76b1baef6ef98623b4f1a 324336a8401afc8ca384eaafe6615c84d552dd2c mcramm <GMCramm@gmail.com> 1332283302 -0600	commit: commit todo
324336a8401afc8ca384eaafe6615c84d552dd2c 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283316 -0600	checkout: moving from solve_world_hunger to kill_the_batman
6876e5b41fb693190df76b1baef6ef98623b4f1a 894a16d6f1a48224e9006b4a6f0fe3846da19bec mcramm <GMCramm@gmail.com> 1332283505 -0600	commit: commit another todo


================================================
FILE: levels/find_old_branch/.githug/logs/refs/heads/blowup_sun_for_ransom
================================================
0000000000000000000000000000000000000000 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283240 -0600	branch: Created from HEAD


================================================
FILE: levels/find_old_branch/.githug/logs/refs/heads/cure_common_cold
================================================
0000000000000000000000000000000000000000 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283192 -0600	commit (initial): initial commit
6876e5b41fb693190df76b1baef6ef98623b4f1a 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283208 -0600	Branch: renamed refs/heads/master to refs/heads/cure_common_cold


================================================
FILE: levels/find_old_branch/.githug/logs/refs/heads/kill_the_batman
================================================
0000000000000000000000000000000000000000 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283224 -0600	branch: Created from HEAD
6876e5b41fb693190df76b1baef6ef98623b4f1a 05e9c01bd3c9264761dd0cde477400a2c3104642 mcramm <GMCramm@gmail.com> 1332283348 -0600	commit: commit todo
05e9c01bd3c9264761dd0cde477400a2c3104642 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283385 -0600	reset: moving to HEAD~
6876e5b41fb693190df76b1baef6ef98623b4f1a 894a16d6f1a48224e9006b4a6f0fe3846da19bec mcramm <GMCramm@gmail.com> 1332283505 -0600	commit: commit another todo


================================================
FILE: levels/find_old_branch/.githug/logs/refs/heads/solve_world_hunger
================================================
0000000000000000000000000000000000000000 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283272 -0600	branch: Created from HEAD
6876e5b41fb693190df76b1baef6ef98623b4f1a 324336a8401afc8ca384eaafe6615c84d552dd2c mcramm <GMCramm@gmail.com> 1332283302 -0600	commit: commit todo


================================================
FILE: levels/find_old_branch/.githug/refs/heads/blowup_sun_for_ransom
================================================
6876e5b41fb693190df76b1baef6ef98623b4f1a


================================================
FILE: levels/find_old_branch/.githug/refs/heads/cure_common_cold
================================================
6876e5b41fb693190df76b1baef6ef98623b4f1a


================================================
FILE: levels/find_old_branch/.githug/refs/heads/kill_the_batman
================================================
894a16d6f1a48224e9006b4a6f0fe3846da19bec


================================================
FILE: levels/find_old_branch/.githug/refs/heads/solve_world_hunger
================================================
324336a8401afc8ca384eaafe6615c84d552dd2c


================================================
FILE: levels/find_old_branch/TODO
================================================
FIND THE JOKER


================================================
FILE: levels/find_old_branch/myfile.txt
================================================
THIS TEXT DOESN'T MATTER


================================================
FILE: levels/find_old_branch.rb
================================================
difficulty 4
description "You have been working on a branch but got distracted by a major issue. Switch back to that branch even though you forgot the name of it."

setup do
  init_from_level
  system "git branch -m master"
end

solution do
  return false unless repo.head.name == "solve_world_hunger"
  true
end

hint do
  puts "Ever played with the `git reflog` command?"
end


================================================
FILE: levels/grep/.githug/COMMIT_EDITMSG
================================================
Add application files.


================================================
FILE: levels/grep/.githug/HEAD
================================================
ref: refs/heads/master


================================================
FILE: levels/grep/.githug/config
================================================
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true


================================================
FILE: levels/grep/.githug/description
================================================
Unnamed repository; edit this file 'description' to name the repository.


================================================
FILE: levels/grep/.githug/hooks/applypatch-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message taken by
# applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.  The hook is
# allowed to edit the commit message file.
#
# To enable this hook, rename this file to "applypatch-msg".

. git-sh-setup
test -x "$GIT_DIR/hooks/commit-msg" &&
	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
:


================================================
FILE: levels/grep/.githug/hooks/commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message.  The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit.  The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".

# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

# This example catches duplicate Signed-off-by lines.

test "" = "$(grep '^Signed-off-by: ' "$1" |
	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
	echo >&2 Duplicate Signed-off-by lines.
	exit 1
}


================================================
FILE: levels/grep/.githug/hooks/post-commit.sample
================================================
#!/bin/sh
#
# An example hook script that is called after a successful
# commit is made.
#
# To enable this hook, rename this file to "post-commit".

: Nothing


================================================
FILE: levels/grep/.githug/hooks/post-receive.sample
================================================
#!/bin/sh
#
# An example hook script for the "post-receive" event.
#
# The "post-receive" script is run after receive-pack has accepted a pack
# and the repository has been updated.  It is passed arguments in through
# stdin in the form
#  <oldrev> <newrev> <refname>
# For example:
#  aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
#
# see contrib/hooks/ for a sample, or uncomment the next line and
# rename the file to "post-receive".

#. /usr/share/doc/git-core/contrib/hooks/post-receive-email


================================================
FILE: levels/grep/.githug/hooks/post-update.sample
================================================
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".

exec git update-server-info


================================================
FILE: levels/grep/.githug/hooks/pre-applypatch.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed
# by applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-applypatch".

. git-sh-setup
test -x "$GIT_DIR/hooks/pre-commit" &&
	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
:


================================================
FILE: levels/grep/.githug/hooks/pre-commit.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
	against=HEAD
else
	# Initial commit: diff against an empty tree object
	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# If you want to allow non-ascii filenames set this variable to true.
allownonascii=$(git config hooks.allownonascii)

# Cross platform projects tend to avoid non-ascii filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
	# Note that the use of brackets around a tr range is ok here, (it's
	# even required, for portability to Solaris 10's /usr/bin/tr), since
	# the square bracket bytes happen to fall in the designated range.
	test "$(git diff --cached --name-only --diff-filter=A -z $against |
	  LC_ALL=C tr -d '[ -~]\0')"
then
	echo "Error: Attempt to add a non-ascii file name."
	echo
	echo "This can cause problems if you want to work"
	echo "with people on other platforms."
	echo
	echo "To be portable it is advisable to rename the file ..."
	echo
	echo "If you know what you are doing you can disable this"
	echo "check using:"
	echo
	echo "  git config hooks.allownonascii true"
	echo
	exit 1
fi

exec git diff-index --check --cached $against --


================================================
FILE: levels/grep/.githug/hooks/pre-rebase.sample
================================================
#!/bin/sh
#
# Copyright (c) 2006, 2008 Junio C Hamano
#
# The "pre-rebase" hook is run just before "git rebase" starts doing
# its job, and can prevent the command from running by exiting with
# non-zero status.
#
# The hook is called with the following parameters:
#
# $1 -- the upstream the series was forked from.
# $2 -- the branch being rebased (or empty when rebasing the current branch).
#
# This sample shows how to prevent topic branches that are already
# merged to 'next' branch from getting rebased, because allowing it
# would result in rebasing already published history.

publish=next
basebranch="$1"
if test "$#" = 2
then
	topic="refs/heads/$2"
else
	topic=`git symbolic-ref HEAD` ||
	exit 0 ;# we do not interrupt rebasing detached HEAD
fi

case "$topic" in
refs/heads/??/*)
	;;
*)
	exit 0 ;# we do not interrupt others.
	;;
esac

# Now we are dealing with a topic branch being rebased
# on top of master.  Is it OK to rebase it?

# Does the topic really exist?
git show-ref -q "$topic" || {
	echo >&2 "No such branch $topic"
	exit 1
}

# Is topic fully merged to master?
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
if test -z "$not_in_master"
then
	echo >&2 "$topic is fully merged to master; better remove it."
	exit 1 ;# we could allow it, but there is no point.
fi

# Is topic ever merged to next?  If so you should not be rebasing it.
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
only_next_2=`git rev-list ^master           ${publish} | sort`
if test "$only_next_1" = "$only_next_2"
then
	not_in_topic=`git rev-list "^$topic" master`
	if test -z "$not_in_topic"
	then
		echo >&2 "$topic is already up-to-date with master"
		exit 1 ;# we could allow it, but there is no point.
	else
		exit 0
	fi
else
	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
	/usr/bin/perl -e '
		my $topic = $ARGV[0];
		my $msg = "* $topic has commits already merged to public branch:\n";
		my (%not_in_next) = map {
			/^([0-9a-f]+) /;
			($1 => 1);
		} split(/\n/, $ARGV[1]);
		for my $elem (map {
				/^([0-9a-f]+) (.*)$/;
				[$1 => $2];
			} split(/\n/, $ARGV[2])) {
			if (!exists $not_in_next{$elem->[0]}) {
				if ($msg) {
					print STDERR $msg;
					undef $msg;
				}
				print STDERR " $elem->[1]\n";
			}
		}
	' "$topic" "$not_in_next" "$not_in_master"
	exit 1
fi

exit 0

################################################################

This sample hook safeguards topic branches that have been
published from being rewound.

The workflow assumed here is:

 * Once a topic branch forks from "master", "master" is never
   merged into it again (either directly or indirectly).

 * Once a topic branch is fully cooked and merged into "master",
   it is deleted.  If you need to build on top of it to correct
   earlier mistakes, a new topic branch is created by forking at
   the tip of the "master".  This is not strictly necessary, but
   it makes it easier to keep your history simple.

 * Whenever you need to test or publish your changes to topic
   branches, merge them into "next" branch.

The script, being an example, hardcodes the publish branch name
to be "next", but it is trivial to make it configurable via
$GIT_DIR/config mechanism.

With this workflow, you would want to know:

(1) ... if a topic branch has ever been merged to "next".  Young
    topic branches can have stupid mistakes you would rather
    clean up before publishing, and things that have not been
    merged into other branches can be easily rebased without
    affecting other people.  But once it is published, you would
    not want to rewind it.

(2) ... if a topic branch has been fully merged to "master".
    Then you can delete it.  More importantly, you should not
    build on top of it -- other people may already want to
    change things related to the topic as patches against your
    "master", so if you need further changes, it is better to
    fork the topic (perhaps with the same name) afresh from the
    tip of "master".

Let's look at this example:

		   o---o---o---o---o---o---o---o---o---o "next"
		  /       /           /           /
		 /   a---a---b A     /           /
		/   /               /           /
	       /   /   c---c---c---c B         /
	      /   /   /             \         /
	     /   /   /   b---b C     \       /
	    /   /   /   /             \     /
    ---o---o---o---o---o---o---o---o---o---o---o "master"


A, B and C are topic branches.

 * A has one fix since it was merged up to "next".

 * B has finished.  It has been fully merged up to "master" and "next",
   and is ready to be deleted.

 * C has not merged to "next" at all.

We would want to allow C to be rebased, refuse A, and encourage
B to be deleted.

To compute (1):

	git rev-list ^master ^topic next
	git rev-list ^master        next

	if these match, topic has not merged in next at all.

To compute (2):

	git rev-list master..topic

	if this is empty, it is fully merged to "master".


================================================
FILE: levels/grep/.githug/hooks/prepare-commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to prepare the commit log message.
# Called by "git commit" with the name of the file that has the
# commit message, followed by the description of the commit
# message's source.  The hook's purpose is to edit the commit
# message file.  If the hook fails with a non-zero status,
# the commit is aborted.
#
# To enable this hook, rename this file to "prepare-commit-msg".

# This hook includes three examples.  The first comments out the
# "Conflicts:" part of a merge commit.
#
# The second includes the output of "git diff --name-status -r"
# into the message, just before the "git status" output.  It is
# commented because it doesn't cope with --amend or with squashed
# commits.
#
# The third example adds a Signed-off-by line to the message, that can
# still be edited.  This is rarely a good idea.

case "$2,$3" in
  merge,)
    /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;

# ,|template,)
#   /usr/bin/perl -i.bak -pe '
#      print "\n" . `git diff --cached --name-status -r`
#	 if /^#/ && $first++ == 0' "$1" ;;

  *) ;;
esac

# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"


================================================
FILE: levels/grep/.githug/hooks/update.sample
================================================
#!/bin/sh
#
# An example hook script to blocks unannotated tags from entering.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
# Config
# ------
# hooks.allowunannotated
#   This boolean sets whether unannotated tags will be allowed into the
#   repository.  By default they won't be.
# hooks.allowdeletetag
#   This boolean sets whether deleting tags will be allowed in the
#   repository.  By default they won't be.
# hooks.allowmodifytag
#   This boolean sets whether a tag may be modified after creation. By default
#   it won't be.
# hooks.allowdeletebranch
#   This boolean sets whether deleting branches will be allowed in the
#   repository.  By default they won't be.
# hooks.denycreatebranch
#   This boolean sets whether remotely creating branches will be denied
#   in the repository.  By default this is allowed.
#

# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"

# --- Safety check
if [ -z "$GIT_DIR" ]; then
	echo "Don't run this script from the command line." >&2
	echo " (if you want, you could supply GIT_DIR then run" >&2
	echo "  $0 <ref> <oldrev> <newrev>)" >&2
	exit 1
fi

if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
	exit 1
fi

# --- Config
allowunannotated=$(git config --bool hooks.allowunannotated)
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
denycreatebranch=$(git config --bool hooks.denycreatebranch)
allowdeletetag=$(git config --bool hooks.allowdeletetag)
allowmodifytag=$(git config --bool hooks.allowmodifytag)

# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
case "$projectdesc" in
"Unnamed repository"* | "")
	echo "*** Project description file hasn't been set" >&2
	exit 1
	;;
esac

# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero="0000000000000000000000000000000000000000"
if [ "$newrev" = "$zero" ]; then
	newrev_type=delete
else
	newrev_type=$(git cat-file -t $newrev)
fi

case "$refname","$newrev_type" in
	refs/tags/*,commit)
		# un-annotated tag
		short_refname=${refname##refs/tags/}
		if [ "$allowunannotated" != "true" ]; then
			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
			exit 1
		fi
		;;
	refs/tags/*,delete)
		# delete tag
		if [ "$allowdeletetag" != "true" ]; then
			echo "*** Deleting a tag is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/tags/*,tag)
		# annotated tag
		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
		then
			echo "*** Tag '$refname' already exists." >&2
			echo "*** Modifying a tag is not allowed in this repository." >&2
			exit 1
		fi
		;;
	refs/heads/*,commit)
		# branch
		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
			echo "*** Creating a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/heads/*,delete)
		# delete branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/remotes/*,commit)
		# tracking branch
		;;
	refs/remotes/*,delete)
		# delete tracking branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	*)
		# Anything else (is there anything else?)
		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
		exit 1
		;;
esac

# --- Finished
exit 0


================================================
FILE: levels/grep/.githug/info/exclude
================================================
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~


================================================
FILE: levels/grep/.githug/logs/HEAD
================================================
0000000000000000000000000000000000000000 12c702f8b25b6b528cf904670b854dba3eba0f45 Thibaud Colas <thibaudcolas@gmail.com> 1384229258 +0100	commit (initial): Add application files.


================================================
FILE: levels/grep/.githug/logs/refs/heads/master
================================================
0000000000000000000000000000000000000000 12c702f8b25b6b528cf904670b854dba3eba0f45 Thibaud Colas <thibaudcolas@gmail.com> 1384229258 +0100	commit (initial): Add application files.


================================================
FILE: levels/grep/.githug/objects/12/c702f8b25b6b528cf904670b854dba3eba0f45
================================================
xK
0@]JЀdj)mz+{՚;O}f[1:Dޙ,D)rd}n+<L'x\KW\n
ƍhgmV=]/{JR2c
S.
DB"

================================================
FILE: levels/grep/.githug/objects/6f/45753f4a16b69f5b2215f2dbe8245f073353cc
================================================
xe1k0;W:K!CC@]n%E>Eg,ن8!dB}FXQ]lŧoJkrNViL/M*ecf=u$`X+s|>#\u/PiQq*6G\dYQ&%4jh)}N)QlGmh

================================================
FILE: levels/grep/.githug/refs/heads/master
================================================
12c702f8b25b6b528cf904670b854dba3eba0f45


================================================
FILE: levels/grep/app.rb
================================================
require 'sinatra'
require 'oauth2'
require 'json'
enable :sessions

# TODO Make site url variable.
def client
  OAuth2::Client.new("mTeZFqkCmzc8JnjKXaSww95bFFxhUpp1wwmSi8vG", "a9OMyEdW7JvWThHmmvFcShR9P2dyad3EGuA2ULDh", :site => "http://localhost:3000")
end

get "/auth/test" do
  redirect 
Download .txt
gitextract_yw6bj_tb/

├── .gitignore
├── .rspec
├── .travis.yml
├── Dockerfile
├── Gemfile
├── LICENCE.txt
├── README.md
├── Rakefile
├── bin/
│   └── githug
├── githug.gemspec
├── levels/
│   ├── add.rb
│   ├── bisect/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── ORIG_HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── gitk.cache
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-commit.sample
│   │   │   │   ├── post-receive.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   ├── exclude
│   │   │   │   └── refs
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── info/
│   │   │   │   │   └── packs
│   │   │   │   └── pack/
│   │   │   │       ├── pack-59fab357f3158a9640633de6a3326ed79a2b4fe6.idx
│   │   │   │       └── pack-59fab357f3158a9640633de6a3326ed79a2b4fe6.pack
│   │   │   └── packed-refs
│   │   ├── makefile
│   │   ├── prog.rb
│   │   └── test.rb
│   ├── bisect.rb
│   ├── blame/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-commit.sample
│   │   │   │   ├── post-receive.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── 00/
│   │   │   │   │   └── d6bf5341b263ccaf32e7973be55126eb30a343
│   │   │   │   ├── 05/
│   │   │   │   │   └── 07c26fed4d111a8344763be9af68af90f0ecf2
│   │   │   │   ├── 09/
│   │   │   │   │   └── 4094808dc6dc336c93c8602190a9e5f7bd6a11
│   │   │   │   ├── 21/
│   │   │   │   │   └── 15d78864000292628872941b14521f90187eed
│   │   │   │   ├── 31/
│   │   │   │   │   └── 11dda1f5b08d50ac44b99acabfa54f1e6e72b0
│   │   │   │   ├── 50/
│   │   │   │   │   └── 8db115ba34a0e4e8667653aebe0265bb4f7e80
│   │   │   │   ├── 5e/
│   │   │   │   │   └── 8863df752e3b7f2150df7c78f12bef6f1ff00e
│   │   │   │   ├── 67/
│   │   │   │   │   └── 788a4b90180c7588d7bd0ad8032957b0f429ba
│   │   │   │   ├── 70/
│   │   │   │   │   └── d00535a3a25b0ac1736dd3d306d6271e5427ed
│   │   │   │   ├── 97/
│   │   │   │   │   └── bdd0cccf9f4b8730f78cb53a81a74f205dbcc2
│   │   │   │   ├── ab/
│   │   │   │   │   └── 08819ba3ffaeba17d4f870dc3a458a904519f4
│   │   │   │   ├── be/
│   │   │   │   │   └── 96fe46de646f6a5c728f90cc884aef96fa1d6f
│   │   │   │   ├── cd/
│   │   │   │   │   └── 9c6b9ab1a6f56cccc69b6aa661f1d67ba5fb46
│   │   │   │   ├── dd/
│   │   │   │   │   └── df1d8ebd60eec169c15a5b23cb49a58d2ed5a0
│   │   │   │   └── ff/
│   │   │   │       └── d39c2dbfd94bdbca06d48686e0cbda642f3de7
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           └── master
│   │   └── config.rb
│   ├── blame.rb
│   ├── branch.rb
│   ├── branch_at.rb
│   ├── checkout.rb
│   ├── checkout_file.rb
│   ├── checkout_tag.rb
│   ├── checkout_tag_over_branch.rb
│   ├── cherry-pick/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           ├── master
│   │   │   │           └── new-feature
│   │   │   ├── objects/
│   │   │   │   ├── 05/
│   │   │   │   │   └── aa97588aff673dcf00e0e1b835d6ec6207a7d9
│   │   │   │   ├── 14/
│   │   │   │   │   └── ad8f1413c40e0e5be6f6cbdec392a783c1d754
│   │   │   │   ├── 1b/
│   │   │   │   │   └── 912962174dd58fbbf1627ec816fa6672c70854
│   │   │   │   ├── 22/
│   │   │   │   │   └── f99f3abfd02190a760388c8845c190247859fe
│   │   │   │   ├── 23/
│   │   │   │   │   └── 2d266a78d5ef7196f1ede14972ccf7ee19e587
│   │   │   │   ├── 31/
│   │   │   │   │   └── 68bdc3ae7e0ab987dda238beab9c0582c7fc07
│   │   │   │   ├── 49/
│   │   │   │   │   └── 4fa3fc1c15986f9a950aba8607da591223614c
│   │   │   │   ├── 4a/
│   │   │   │   │   └── 1961bce62840eaef9c4392fe5cc799e38c9b7b
│   │   │   │   ├── 54/
│   │   │   │   │   ├── 22c2405527c05c23b243b2535a97b6cefa1427
│   │   │   │   │   └── f3308533fd4400c94c4cd5827cd38036a67a76
│   │   │   │   ├── 58/
│   │   │   │   │   └── a8c8edcfdd00c6d8cce9aada8f987a1677571f
│   │   │   │   ├── 6e/
│   │   │   │   │   └── dea632d9540e060bca97dda0897df2b7da0ec0
│   │   │   │   ├── 85/
│   │   │   │   │   └── 4e7ac38b3e8df02ea1480ec45aa9e7865f03d7
│   │   │   │   ├── 93/
│   │   │   │   │   └── 3a97260a11a5ee49bb8a4b7b097cb2fb38f85c
│   │   │   │   ├── 9a/
│   │   │   │   │   └── e59e88e6af362c069847e621b971bafff158ac
│   │   │   │   ├── a2/
│   │   │   │   │   └── 14badc644facc4722083aedf91d9339ffdffbf
│   │   │   │   ├── b3/
│   │   │   │   │   └── 0c6a965415df6aef5f2903f9892fa5481152fc
│   │   │   │   ├── c6/
│   │   │   │   │   └── 0c612734f25b9c989d954621491e9ca3c9e061
│   │   │   │   ├── ca/
│   │   │   │   │   └── 32a6dac7b6f97975edbe19a4296c2ee7682f68
│   │   │   │   ├── cf/
│   │   │   │   │   └── d8ce38c22c5fe83cc04e23f94646464f20d990
│   │   │   │   ├── d5/
│   │   │   │   │   ├── 02e68bfe397140e4ac2a819b138545abca604e
│   │   │   │   │   └── 123e58b37fd886dff2b96bfe5ec08a498192aa
│   │   │   │   └── ea/
│   │   │   │       ├── 2a47c19b85fc321e2737ddc49db3deeba3a1b5
│   │   │   │       └── 3dbcc5e2d2359698c3606b0ec44af9f76def54
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           ├── master
│   │   │           └── new-feature
│   │   ├── README.md
│   │   ├── hardcore-math.js
│   │   └── nokia.js
│   ├── cherry-pick.rb
│   ├── clone.rb
│   ├── clone_to_folder.rb
│   ├── commit.rb
│   ├── commit_amend.rb
│   ├── commit_in_future.rb
│   ├── config.rb
│   ├── conflict/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           ├── master
│   │   │   │           └── mybranch
│   │   │   ├── objects/
│   │   │   │   ├── 1d/
│   │   │   │   │   └── b9aa5013e47f1482ec90323d926171a99c28af
│   │   │   │   ├── 25/
│   │   │   │   │   └── b3f9c339430b35ae5822b2ef90e763284dc007
│   │   │   │   ├── 2d/
│   │   │   │   │   └── 0d90051e320215f54f357e746c9838490557e7
│   │   │   │   ├── 30/
│   │   │   │   │   ├── 6868e3258be1f35ae43db71e3a6d7edf42ffe7
│   │   │   │   │   └── cc28e66966109bb5bfbe96d6c817c367d2050a
│   │   │   │   ├── 38/
│   │   │   │   │   └── 21e4362c5a76db1112b46b9210670cd5bab482
│   │   │   │   ├── 3c/
│   │   │   │   │   └── b65bef44ae724ddf9e89640e7e2754dea1a47f
│   │   │   │   ├── 3d/
│   │   │   │   │   └── 7aec017559be2b61cab850dafdcb2b6212f1c3
│   │   │   │   ├── 40/
│   │   │   │   │   └── e20a455ac2731ad25c297b03aa543d7eedf6ab
│   │   │   │   ├── 44/
│   │   │   │   │   └── 30fd3f45c832e685350417600a9862c94d20f1
│   │   │   │   ├── 46/
│   │   │   │   │   └── 677964e679f3e727356d0860c643a12a87902b
│   │   │   │   ├── 50/
│   │   │   │   │   └── a127cb066eb903a6fa59d71802c10cb442fb3b
│   │   │   │   ├── 55/
│   │   │   │   │   └── ad5af2a93afa778971e3d04faf20f6c368b6ba
│   │   │   │   ├── 6b/
│   │   │   │   │   └── 0c0b32bdca3af9beb831744cb755d6fdc7c7c0
│   │   │   │   ├── 75/
│   │   │   │   │   └── 179304f4fab00613f08a9412b6cb0965bfa564
│   │   │   │   ├── 7c/
│   │   │   │   │   └── 36daf29660ae4a2f09345427ef76f1d38f902f
│   │   │   │   ├── 88/
│   │   │   │   │   └── e0473c9da347c6311f5f8eca8d256bf25402b6
│   │   │   │   ├── bd/
│   │   │   │   │   └── c7bec8acae9b3eabf0a15b223a48211b7a89a1
│   │   │   │   ├── c7/
│   │   │   │   │   └── 97f979cf24ba148bf10d5e26f5d7402dd5f2e1
│   │   │   │   └── da/
│   │   │   │       └── ae380200ed6eeaafd926177018e8ff3009b988
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           ├── master
│   │   │           └── mybranch
│   │   └── poem.txt
│   ├── conflict.rb
│   ├── contribute.rb
│   ├── delete_branch/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-push.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           ├── delete_me
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── b6/
│   │   │   │   │   └── 0afe294eb3c200d646995c9e0234470157c1b0
│   │   │   │   ├── e6/
│   │   │   │   │   └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│   │   │   │   └── e8/
│   │   │   │       └── 0ad49ace82167de62e498622d70377d913c79e
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           ├── delete_me
│   │   │           └── master
│   │   └── readme
│   ├── delete_branch.rb
│   ├── diff/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-commit.sample
│   │   │   │   ├── post-receive.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── 1b/
│   │   │   │   │   └── 6582364621c92707b587409cedbc4f77fc0cee
│   │   │   │   ├── 4f/
│   │   │   │   │   └── 703ca9bd25781b6758eeb3c42ed5348610ba6d
│   │   │   │   └── dc/
│   │   │   │       └── aa55e97af34402e84d5336da37abcccc23cba6
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           └── master
│   │   └── app.rb
│   ├── diff.rb
│   ├── fetch.rb
│   ├── find_old_branch/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── ORIG_HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-commit.sample
│   │   │   │   ├── post-receive.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           ├── blowup_sun_for_ransom
│   │   │   │           ├── cure_common_cold
│   │   │   │           ├── kill_the_batman
│   │   │   │           └── solve_world_hunger
│   │   │   ├── objects/
│   │   │   │   ├── 05/
│   │   │   │   │   └── e9c01bd3c9264761dd0cde477400a2c3104642
│   │   │   │   ├── 1f/
│   │   │   │   │   └── 0a136ddd98f61934d15eb00444df32d8e8254b
│   │   │   │   ├── 32/
│   │   │   │   │   └── 4336a8401afc8ca384eaafe6615c84d552dd2c
│   │   │   │   ├── 50/
│   │   │   │   │   └── 72aab6bd73accec89ad3aa077f43aab8a5e507
│   │   │   │   ├── 5d/
│   │   │   │   │   └── 130caf89f1a4bba6a1fffe72c484f3ab659e08
│   │   │   │   ├── 68/
│   │   │   │   │   └── 76e5b41fb693190df76b1baef6ef98623b4f1a
│   │   │   │   ├── 6a/
│   │   │   │   │   └── 7702145d1eb91c9f79583eabb984027b12e60c
│   │   │   │   ├── 89/
│   │   │   │   │   └── 4a16d6f1a48224e9006b4a6f0fe3846da19bec
│   │   │   │   ├── b8/
│   │   │   │   │   └── c67b45e5fe9e4b39ac7ade725673f7c90bdfc3
│   │   │   │   └── bf/
│   │   │   │       └── 76434bc7e7346c6fef5a98aee0f7cfc0788f34
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           ├── blowup_sun_for_ransom
│   │   │           ├── cure_common_cold
│   │   │           ├── kill_the_batman
│   │   │           └── solve_world_hunger
│   │   ├── TODO
│   │   └── myfile.txt
│   ├── find_old_branch.rb
│   ├── grep/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-commit.sample
│   │   │   │   ├── post-receive.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── 12/
│   │   │   │   │   └── c702f8b25b6b528cf904670b854dba3eba0f45
│   │   │   │   ├── 6f/
│   │   │   │   │   └── 45753f4a16b69f5b2215f2dbe8245f073353cc
│   │   │   │   ├── a4/
│   │   │   │   │   └── 1fe0c342be5c9930328cbb4315acebbd9c94b2
│   │   │   │   └── d3/
│   │   │   │       └── f53e82aa015d1eea3b06c3b62dfbacee83bbe1
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           └── master
│   │   ├── app.rb
│   │   └── config.rb
│   ├── grep.rb
│   ├── ignore.rb
│   ├── include.rb
│   ├── init.rb
│   ├── log.rb
│   ├── merge/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-commit.sample
│   │   │   │   ├── post-receive.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           ├── feature
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── ad/
│   │   │   │   │   └── 24149d789e59d4b5f9ce41cda90110ca0f98b7
│   │   │   │   ├── ae/
│   │   │   │   │   └── fde3a01f6e10d72fd4899ce14c8b2654d3eb45
│   │   │   │   ├── cc/
│   │   │   │   │   └── 8ea5a233df119d025eb240b9470e1ca76a151c
│   │   │   │   ├── e1/
│   │   │   │   │   └── 2277fe88657a072f1c4eb7d9320e4e6a74ba95
│   │   │   │   └── e6/
│   │   │   │       └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           ├── feature
│   │   │           └── master
│   │   └── file1
│   ├── merge.rb
│   ├── merge_squash.rb
│   ├── number_of_files_committed.rb
│   ├── pull.rb
│   ├── push.rb
│   ├── push_branch.rb
│   ├── push_tags.rb
│   ├── rebase/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── ORIG_HEAD
│   │   │   ├── config
│   │   │   ├── index
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           ├── feature
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── 0c/
│   │   │   │   │   └── d212c5b28da2e65ed4900712dd36c8adce48ad
│   │   │   │   ├── 44/
│   │   │   │   │   └── 19b972c0cd1b346ac90332aa7c5cc949589f78
│   │   │   │   ├── 54/
│   │   │   │   │   └── 3b9bebdc6bd5c4b22136034a95dd097a57d3dd
│   │   │   │   ├── 81/
│   │   │   │   │   └── 78c76d627cade75005b40711b92f4177bc6cfc
│   │   │   │   ├── 98/
│   │   │   │   │   └── 205e9faf10cf33d2ef7c0f66e402540c62613a
│   │   │   │   ├── a7/
│   │   │   │   │   └── 8bcab6232e9382a86436cdfcb2ed0391b1f0ac
│   │   │   │   ├── b7/
│   │   │   │   │   └── 7313d7be366609dd2e77aa96d7fd73f4e27853
│   │   │   │   ├── b9/
│   │   │   │   │   └── 2d5d55d379cfb90b750e6472fc983f32ad9a71
│   │   │   │   ├── e6/
│   │   │   │   │   └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│   │   │   │   └── ed/
│   │   │   │       └── 0fdcf366b21b8984fb37ea34106978a2e5c5ba
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           ├── feature
│   │   │           └── master
│   │   └── README
│   ├── rebase.rb
│   ├── rebase_onto.rb
│   ├── remote.rb
│   ├── remote_add.rb
│   ├── remote_url.rb
│   ├── rename.rb
│   ├── rename_commit.rb
│   ├── reorder.rb
│   ├── repack.rb
│   ├── reset.rb
│   ├── reset_soft.rb
│   ├── restore.rb
│   ├── restructure.rb
│   ├── revert.rb
│   ├── rm.rb
│   ├── rm_cached.rb
│   ├── squash.rb
│   ├── stage_lines.rb
│   ├── stash/
│   │   ├── .githug/
│   │   │   ├── COMMIT_EDITMSG
│   │   │   ├── HEAD
│   │   │   ├── config
│   │   │   ├── description
│   │   │   ├── hooks/
│   │   │   │   ├── applypatch-msg.sample
│   │   │   │   ├── commit-msg.sample
│   │   │   │   ├── post-update.sample
│   │   │   │   ├── pre-applypatch.sample
│   │   │   │   ├── pre-commit.sample
│   │   │   │   ├── pre-rebase.sample
│   │   │   │   ├── prepare-commit-msg.sample
│   │   │   │   └── update.sample
│   │   │   ├── index
│   │   │   ├── info/
│   │   │   │   └── exclude
│   │   │   ├── logs/
│   │   │   │   ├── HEAD
│   │   │   │   └── refs/
│   │   │   │       └── heads/
│   │   │   │           └── master
│   │   │   ├── objects/
│   │   │   │   ├── 02/
│   │   │   │   │   └── 060592b31c9e12ffe1b282addf9537c5ef8e1f
│   │   │   │   ├── 4b/
│   │   │   │   │   └── 825dc642cb6eb9a060e54bf8d69288fbee4904
│   │   │   │   ├── 7f/
│   │   │   │   │   └── 82d7e4fba66980af16da540e18d8955518cdc2
│   │   │   │   └── 85/
│   │   │   │       └── e560abcd7e3255dcd91982476e432f4d3d1b51
│   │   │   └── refs/
│   │   │       └── heads/
│   │   │           └── master
│   │   └── lyrics.txt
│   ├── stash.rb
│   ├── status.rb
│   ├── submodule.rb
│   └── tag.rb
├── lib/
│   ├── githug/
│   │   ├── cli.rb
│   │   ├── extensions/
│   │   │   └── grit/
│   │   │       └── ruby1.9.rb
│   │   ├── game.rb
│   │   ├── level.rb
│   │   ├── profile.rb
│   │   ├── repository.rb
│   │   ├── ui.rb
│   │   └── version.rb
│   └── githug.rb
└── spec/
    ├── githug/
    │   ├── cli_spec.rb
    │   ├── game_spec.rb
    │   ├── level_spec.rb
    │   ├── profile_spec.rb
    │   ├── repository_spec.rb
    │   └── ui_spec.rb
    ├── githug_spec.rb
    ├── spec_helper.rb
    └── support/
        └── files/
            └── test_level.rb
Download .txt
SYMBOL INDEX (89 symbols across 13 files)

FILE: levels/blame/config.rb
  class Config (line 1) | class Config
    method initialize (line 3) | def initialize(name, password = nil, options = {})

FILE: levels/diff/app.rb
  function client (line 6) | def client
  function get_response (line 30) | def get_response(url)
  function redirect_uri (line 36) | def redirect_uri

FILE: levels/grep/app.rb
  function client (line 7) | def client
  function get_response (line 33) | def get_response(url)
  function redirect_uri (line 39) | def redirect_uri

FILE: levels/grep/config.rb
  class Config (line 1) | class Config
    method initialize (line 3) | def initialize(name, password = nil, options = {})

FILE: lib/githug/cli.rb
  type Githug (line 3) | module Githug
    class CLI (line 4) | class CLI < Thor
      method play (line 11) | def play
      method test (line 20) | def test(path)
      method hint (line 29) | def hint
      method reset (line 45) | def reset(path = nil)
      method levels (line 59) | def levels
      method load_level (line 68) | def load_level(path = nil)
      method load_level_from_number (line 75) | def load_level_from_number(number)
      method load_level_from_name (line 80) | def load_level_from_name(name)
      method load_level_from_profile (line 86) | def load_level_from_profile
      method make_directory! (line 92) | def make_directory!
      method check_githug_directory! (line 99) | def check_githug_directory!
      method prompt_githug_directory! (line 106) | def prompt_githug_directory!
      method make_githug_directory! (line 113) | def make_githug_directory!

FILE: lib/githug/extensions/grit/ruby1.9.rb
  class String (line 1) | class String
    method getord (line 3) | def getord(offset); self[offset].ord; end
    method b (line 10) | def b; self.dup.force_encoding(Encoding::ASCII_8BIT); end
    method b (line 12) | def b; self.dup; end

FILE: lib/githug/game.rb
  type Githug (line 1) | module Githug
    class Game (line 2) | class Game
      method initialize (line 6) | def initialize
      method play_level (line 10) | def play_level
      method test_level (line 37) | def test_level(level, errors = nil)
      method level_bump (line 48) | def level_bump

FILE: lib/githug/level.rb
  type Githug (line 1) | module Githug
    class Level (line 2) | class Level
      method load (line 21) | def load(level_name)
      method load_from_file (line 26) | def load_from_file(path)
      method list (line 30) | def list
      method setup (line 34) | def setup(path)
      method init_from_level (line 49) | def init_from_level
      method difficulty (line 54) | def difficulty(num)
      method description (line 58) | def description(description)
      method solution (line 62) | def solution(&block)
      method setup (line 67) | def setup(&block)
      method hint (line 71) | def hint(&hint)
      method hints (line 75) | def hints(hints)
      method full_description (line 79) | def full_description
      method setup_level (line 89) | def setup_level
      method repo (line 94) | def repo(location = "")
      method solve (line 98) | def solve
      method test (line 104) | def test
      method show_hint (line 108) | def show_hint

FILE: lib/githug/profile.rb
  type Githug (line 2) | module Githug
    class Profile (line 3) | class Profile
      method load (line 9) | def load
      method settings (line 15) | def settings
      method defaults (line 20) | def defaults
      method method_missing (line 33) | def method_missing(method, *args, &block)
      method initialize (line 42) | def initialize(settings)
      method save (line 46) | def save
      method set_level (line 52) | def set_level(name)
      method level_bump (line 58) | def level_bump
      method levels (line 66) | def levels
      method next_level (line 70) | def next_level
      method reset! (line 74) | def reset!

FILE: lib/githug/repository.rb
  type Githug (line 1) | module Githug
    class Repository (line 2) | class Repository
      method initialize (line 6) | def initialize(location = ".")
      method reset (line 12) | def reset
      method create_gitignore (line 22) | def create_gitignore
      method valid? (line 30) | def valid?
      method init (line 35) | def init(location = ".")
      method method_missing (line 39) | def method_missing(method, *args, &block)

FILE: lib/githug/ui.rb
  type Githug (line 1) | module Githug
    type UI (line 2) | module UI
      function puts (line 11) | def puts(string = "")
      function print (line 15) | def print(string)
      function gets (line 19) | def gets
      function word_box (line 23) | def word_box(string,width=80,char='*')
      function request (line 29) | def request(msg)
      function ask (line 34) | def ask(msg)
      function colorize (line 38) | def colorize(text, color_code)
      function error (line 43) | def error(text)
      function success (line 47) | def success(text)
      function method_missing (line 53) | def method_missing(method, *args, &block)

FILE: lib/githug/version.rb
  type Githug (line 1) | module Githug

FILE: spec/githug_spec.rb
  function skip_level (line 9) | def skip_level
Condensed preview — 413 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (307K chars).
[
  {
    "path": ".gitignore",
    "chars": 68,
    "preview": "*.gem\n.bundle\nGemfile.lock\npkg/*\n*.swp\n.rvmrc\ngit_hug/*\n.profile.yml"
  },
  {
    "path": ".rspec",
    "chars": 24,
    "preview": "--color\n--order default\n"
  },
  {
    "path": ".travis.yml",
    "chars": 286,
    "preview": "language: ruby\ndist: focal\nrvm:\n  - 2.4.10\n  - 2.5.9\n  - 2.6.8\n  - 2.7.4\n  - 3.0.1\n  - ruby-head\n\nmatrix:\n  allow_failur"
  },
  {
    "path": "Dockerfile",
    "chars": 2292,
    "preview": "FROM ruby:slim\n\nLABEL org.opencontainers.image.authors=\"diraneyya@ip.rwth-aachen.de\"\n\n# This is in order to have the man"
  },
  {
    "path": "Gemfile",
    "chars": 90,
    "preview": "source \"http://rubygems.org\"\n\n# Specify your gem's dependencies in githug.gemspec\ngemspec\n"
  },
  {
    "path": "LICENCE.txt",
    "chars": 1078,
    "preview": "Copyright (c) 2013  Gary 'Gazler' Rennie\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtai"
  },
  {
    "path": "README.md",
    "chars": 5918,
    "preview": "# Githug\nGit Your Game On \n\n[![Build Status](https://travis-ci.org/Gazler/githug.svg?branch=master)](https://travis-ci.o"
  },
  {
    "path": "Rakefile",
    "chars": 119,
    "preview": "require \"bundler/gem_tasks\"\nrequire 'rspec/core/rake_task'\n\nRSpec::Core::RakeTask.new(:spec)\n\ntask :default => [:spec]\n"
  },
  {
    "path": "bin/githug",
    "chars": 60,
    "preview": "#!/usr/bin/env ruby\nrequire 'githug/cli'\n\nGithug::CLI.start\n"
  },
  {
    "path": "githug.gemspec",
    "chars": 903,
    "preview": "# -*- encoding: utf-8 -*-\n$:.push File.expand_path(\"../lib\", __FILE__)\nrequire \"githug/version\"\n\nGem::Specification.new "
  },
  {
    "path": "levels/add.rb",
    "chars": 513,
    "preview": "difficulty 1\ndescription \"There is a file in your folder called `README`; add it to your staging area.\nNote: Each level "
  },
  {
    "path": "levels/bisect/.githug/COMMIT_EDITMSG",
    "chars": 15,
    "preview": "Another Commit\n"
  },
  {
    "path": "levels/bisect/.githug/HEAD",
    "chars": 23,
    "preview": "ref: refs/heads/master\n"
  },
  {
    "path": "levels/bisect/.githug/ORIG_HEAD",
    "chars": 41,
    "preview": "f351ca63a759f56bb26924fd566294eb23455c71\n"
  },
  {
    "path": "levels/bisect/.githug/config",
    "chars": 119,
    "preview": "[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = false\n\tlogallrefupdates = true\n[pack]\n\tdeltaCacheSize = 1\n"
  },
  {
    "path": "levels/bisect/.githug/description",
    "chars": 73,
    "preview": "Unnamed repository; edit this file 'description' to name the repository.\n"
  },
  {
    "path": "levels/bisect/.githug/gitk.cache",
    "chars": 623,
    "preview": "1 1\nf351ca63a759f56bb26924fd566294eb23455c71 f608824888b83bbedc1f658be7496ffea467a8fb {7f8406e742c5281ec2c9bc3c6cc69dc6b"
  },
  {
    "path": "levels/bisect/.githug/hooks/applypatch-msg.sample",
    "chars": 452,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message taken by\n# applypatch from an e-mail message.\n#\n# T"
  },
  {
    "path": "levels/bisect/.githug/hooks/commit-msg.sample",
    "chars": 896,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message.\n# Called by \"git commit\" with one argument, the na"
  },
  {
    "path": "levels/bisect/.githug/hooks/post-commit.sample",
    "chars": 160,
    "preview": "#!/bin/sh\n#\n# An example hook script that is called after a successful\n# commit is made.\n#\n# To enable this hook, rename"
  },
  {
    "path": "levels/bisect/.githug/hooks/post-receive.sample",
    "chars": 552,
    "preview": "#!/bin/sh\n#\n# An example hook script for the \"post-receive\" event.\n#\n# The \"post-receive\" script is run after receive-pa"
  },
  {
    "path": "levels/bisect/.githug/hooks/post-update.sample",
    "chars": 189,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare a packed repository for use over\n# dumb transports.\n#\n# To enable this h"
  },
  {
    "path": "levels/bisect/.githug/hooks/pre-applypatch.sample",
    "chars": 398,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed\n# by applypatch from an e-mail message.\n#\n#"
  },
  {
    "path": "levels/bisect/.githug/hooks/pre-commit.sample",
    "chars": 1578,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed.\n# Called by \"git commit\" with no arguments"
  },
  {
    "path": "levels/bisect/.githug/hooks/pre-rebase.sample",
    "chars": 4971,
    "preview": "#!/bin/sh\n#\n# Copyright (c) 2006, 2008 Junio C Hamano\n#\n# The \"pre-rebase\" hook is run just before \"git rebase\" starts d"
  },
  {
    "path": "levels/bisect/.githug/hooks/prepare-commit-msg.sample",
    "chars": 1239,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare the commit log message.\n# Called by \"git commit\" with the name of the fi"
  },
  {
    "path": "levels/bisect/.githug/hooks/update.sample",
    "chars": 3611,
    "preview": "#!/bin/sh\n#\n# An example hook script to blocks unannotated tags from entering.\n# Called by \"git receive-pack\" with argum"
  },
  {
    "path": "levels/bisect/.githug/info/exclude",
    "chars": 240,
    "preview": "# git ls-files --others --exclude-from=.git/info/exclude\n# Lines that start with '#' are comments.\n# For a project mostl"
  },
  {
    "path": "levels/bisect/.githug/info/refs",
    "chars": 661,
    "preview": "94e162b505bc2290fb67764357a625192f8a4e8a\trefs/bisect/bad\nbfb16eec1081387b586dc8009ef422cfff60b622\trefs/bisect/good-bfb16"
  },
  {
    "path": "levels/bisect/.githug/logs/HEAD",
    "chars": 3420,
    "preview": "f351ca63a759f56bb26924fd566294eb23455c71 f608824888b83bbedc1f658be7496ffea467a8fb Florian Sesser <fs@it-agenten.com> 134"
  },
  {
    "path": "levels/bisect/.githug/logs/refs/heads/master",
    "chars": 3404,
    "preview": "0000000000000000000000000000000000000000 f608824888b83bbedc1f658be7496ffea467a8fb Florian Sesser <fs@it-agenten.com> 134"
  },
  {
    "path": "levels/bisect/.githug/objects/info/packs",
    "chars": 54,
    "preview": "P pack-59fab357f3158a9640633de6a3326ed79a2b4fe6.pack\n\n"
  },
  {
    "path": "levels/bisect/.githug/packed-refs",
    "chars": 644,
    "preview": "# pack-refs with: peeled \n94e162b505bc2290fb67764357a625192f8a4e8a refs/bisect/bad\nbfb16eec1081387b586dc8009ef422cfff60b"
  },
  {
    "path": "levels/bisect/makefile",
    "chars": 37,
    "preview": "test:\n\truby prog.rb 5 | ruby test.rb\n"
  },
  {
    "path": "levels/bisect/prog.rb",
    "chars": 60,
    "preview": "#!/usr/bin/env ruby\n\nputs Integer((Integer(ARGV[0])-3)*9)-1\n"
  },
  {
    "path": "levels/bisect/test.rb",
    "chars": 58,
    "preview": "#!/usr/bin/env ruby\n\nline = gets\nexit 1 if line != \"15\\n\"\n"
  },
  {
    "path": "levels/bisect.rb",
    "chars": 648,
    "preview": "difficulty 3\ndescription \"A bug was introduced somewhere along the way. You know that running `ruby prog.rb 5` should ou"
  },
  {
    "path": "levels/blame/.githug/COMMIT_EDITMSG",
    "chars": 31,
    "preview": "added more options (no really)\n"
  },
  {
    "path": "levels/blame/.githug/HEAD",
    "chars": 23,
    "preview": "ref: refs/heads/master\n"
  },
  {
    "path": "levels/blame/.githug/config",
    "chars": 92,
    "preview": "[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = false\n\tlogallrefupdates = true\n"
  },
  {
    "path": "levels/blame/.githug/description",
    "chars": 73,
    "preview": "Unnamed repository; edit this file 'description' to name the repository.\n"
  },
  {
    "path": "levels/blame/.githug/hooks/applypatch-msg.sample",
    "chars": 452,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message taken by\n# applypatch from an e-mail message.\n#\n# T"
  },
  {
    "path": "levels/blame/.githug/hooks/commit-msg.sample",
    "chars": 896,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message.\n# Called by \"git commit\" with one argument, the na"
  },
  {
    "path": "levels/blame/.githug/hooks/post-commit.sample",
    "chars": 160,
    "preview": "#!/bin/sh\n#\n# An example hook script that is called after a successful\n# commit is made.\n#\n# To enable this hook, rename"
  },
  {
    "path": "levels/blame/.githug/hooks/post-receive.sample",
    "chars": 552,
    "preview": "#!/bin/sh\n#\n# An example hook script for the \"post-receive\" event.\n#\n# The \"post-receive\" script is run after receive-pa"
  },
  {
    "path": "levels/blame/.githug/hooks/post-update.sample",
    "chars": 189,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare a packed repository for use over\n# dumb transports.\n#\n# To enable this h"
  },
  {
    "path": "levels/blame/.githug/hooks/pre-applypatch.sample",
    "chars": 398,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed\n# by applypatch from an e-mail message.\n#\n#"
  },
  {
    "path": "levels/blame/.githug/hooks/pre-commit.sample",
    "chars": 1578,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed.\n# Called by \"git commit\" with no arguments"
  },
  {
    "path": "levels/blame/.githug/hooks/pre-rebase.sample",
    "chars": 4951,
    "preview": "#!/bin/sh\n#\n# Copyright (c) 2006, 2008 Junio C Hamano\n#\n# The \"pre-rebase\" hook is run just before \"git rebase\" starts d"
  },
  {
    "path": "levels/blame/.githug/hooks/prepare-commit-msg.sample",
    "chars": 1239,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare the commit log message.\n# Called by \"git commit\" with the name of the fi"
  },
  {
    "path": "levels/blame/.githug/hooks/update.sample",
    "chars": 3611,
    "preview": "#!/bin/sh\n#\n# An example hook script to blocks unannotated tags from entering.\n# Called by \"git receive-pack\" with argum"
  },
  {
    "path": "levels/blame/.githug/info/exclude",
    "chars": 240,
    "preview": "# git ls-files --others --exclude-from=.git/info/exclude\n# Lines that start with '#' are comments.\n# For a project mostl"
  },
  {
    "path": "levels/blame/.githug/logs/HEAD",
    "chars": 825,
    "preview": "0000000000000000000000000000000000000000 5e8863df752e3b7f2150df7c78f12bef6f1ff00e Gary Rennie <webmaster@gazler.com> 133"
  },
  {
    "path": "levels/blame/.githug/logs/refs/heads/master",
    "chars": 825,
    "preview": "0000000000000000000000000000000000000000 5e8863df752e3b7f2150df7c78f12bef6f1ff00e Gary Rennie <webmaster@gazler.com> 133"
  },
  {
    "path": "levels/blame/.githug/objects/09/4094808dc6dc336c93c8602190a9e5f7bd6a11",
    "chars": 86,
    "preview": "x\u0001NK\u00021\u0010tS^\u0001\u0011/\u0013d\u0002N2$qW.*m\u0003\u0010a\u0012jjK6褧\u000eH\u001aDа\f0UVGR\u0018>]t\\,\t\"Α\r\u001e{N\u001e\n\\WO\u001dK9yuPJH\u0016'L1_m`!%LPk\u0003dM"
  },
  {
    "path": "levels/blame/.githug/objects/31/11dda1f5b08d50ac44b99acabfa54f1e6e72b0",
    "chars": 69,
    "preview": "x\u00015\n\u00021\fD=\u0015MAD/\u001e\u0016\u0004\u0010l7@MdS\u0010\u0014ݶ\u001e&Cz\u001cEH䎋i\u0012;6Szr\u0003GJ\u0016Ju[+oSJ\u0006V@\u0012\u001b쭁o-\u0016\u001ae\u001d[\u0007#3"
  },
  {
    "path": "levels/blame/.githug/objects/97/bdd0cccf9f4b8730f78cb53a81a74f205dbcc2",
    "chars": 96,
    "preview": "x\u0001Kj\u00031\u0010DS$t`L.UN\u0003\u001ei(\u000b>\u0015((-u\u000elͩ7U`\"'!Fo\u0011\u0013{1p4uL?\t)\u0006Uܴt\b(θl2\u0019Bx\u0011#\u0006x\u000er\u0018\u001f6\u0002_\u001fCZϡϥnW cm<@p\u001ac߇)VBZ1\u0001nK"
  },
  {
    "path": "levels/blame/.githug/objects/dd/df1d8ebd60eec169c15a5b23cb49a58d2ed5a0",
    "chars": 102,
    "preview": "x\u0001eA\n0\u0010E]\u0014cW\nŅ.Ģ x\f\u0011IT\u0006LI\u0005w7I(]$T+X7\u0013isp`\u0001\bYHc\u000b%.l\u0002ӲU\u0001P\u0006$(\f>\u0007\u001ev@h\n#\u000bk\u001e$}\u0004c\u001d>qcAە\u0013.RqKR8}JgbH)դxkZIэ\r?X"
  },
  {
    "path": "levels/blame/.githug/objects/ff/d39c2dbfd94bdbca06d48686e0cbda642f3de7",
    "chars": 100,
    "preview": "x\u0001MJD1\u0010]\u0014t\u0010$t`\u0018ܹ\u0006NG\u001f$C&\"\u0019\u0007Ž}i\u000e\u0011x\u000b\u0001|ڠ!搲ٸ1Ґ6!.53X|t\tis/Vo91[E?\u000fqOim\u00178Jt2޿ʽ^8gG\u0010^Zf\u000fيr\f\u000f~{o7xn\u001dqO\u001fdbO["
  },
  {
    "path": "levels/blame/.githug/refs/heads/master",
    "chars": 41,
    "preview": "ffd39c2dbfd94bdbca06d48686e0cbda642f3de7\n"
  },
  {
    "path": "levels/blame/config.rb",
    "chars": 275,
    "preview": "class Config\n  attr_accessor :name, :password\n  def initialize(name, password = nil, options = {})\n    @name = name\n    "
  },
  {
    "path": "levels/blame.rb",
    "chars": 402,
    "preview": "difficulty 2\ndescription \"Identify who put a password inside the file `config.rb`.\"\n\nsetup do\n  init_from_level\n  system"
  },
  {
    "path": "levels/branch.rb",
    "chars": 401,
    "preview": "difficulty 1\ndescription \"To work on a piece of code that has the potential to break things, create the branch test_code"
  },
  {
    "path": "levels/branch_at.rb",
    "chars": 835,
    "preview": "difficulty 3\ndescription \"You forgot to branch at the previous commit and made a commit on top of it. Create the branch "
  },
  {
    "path": "levels/checkout.rb",
    "chars": 437,
    "preview": "difficulty 2\ndescription \"Create and switch to a new branch called my_branch. You will need to create a branch like you "
  },
  {
    "path": "levels/checkout_file.rb",
    "chars": 666,
    "preview": "difficulty 3\n\ndescription \"A file has been modified, but you don't want to keep the modification. Checkout the `config.r"
  },
  {
    "path": "levels/checkout_tag.rb",
    "chars": 988,
    "preview": "difficulty 2\n\ndescription \"You need to fix a bug in the version 1.2 of your app. Checkout the tag `v1.2`.\"\n\nsetup do\n  r"
  },
  {
    "path": "levels/checkout_tag_over_branch.rb",
    "chars": 1250,
    "preview": "difficulty 2\n\ndescription \"You need to fix a bug in the version 1.2 of your app. Checkout the tag `v1.2` (Note: There is"
  },
  {
    "path": "levels/cherry-pick/.githug/COMMIT_EDITMSG",
    "chars": 17,
    "preview": "some small fixes\n"
  },
  {
    "path": "levels/cherry-pick/.githug/HEAD",
    "chars": 23,
    "preview": "ref: refs/heads/master\n"
  },
  {
    "path": "levels/cherry-pick/.githug/config",
    "chars": 111,
    "preview": "[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = false\n\tlogallrefupdates = true\n\tignorecase = true\n"
  },
  {
    "path": "levels/cherry-pick/.githug/description",
    "chars": 73,
    "preview": "Unnamed repository; edit this file 'description' to name the repository.\n"
  },
  {
    "path": "levels/cherry-pick/.githug/hooks/applypatch-msg.sample",
    "chars": 452,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message taken by\n# applypatch from an e-mail message.\n#\n# T"
  },
  {
    "path": "levels/cherry-pick/.githug/hooks/commit-msg.sample",
    "chars": 896,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message.\n# Called by \"git commit\" with one argument, the na"
  },
  {
    "path": "levels/cherry-pick/.githug/hooks/post-update.sample",
    "chars": 189,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare a packed repository for use over\n# dumb transports.\n#\n# To enable this h"
  },
  {
    "path": "levels/cherry-pick/.githug/hooks/pre-applypatch.sample",
    "chars": 398,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed\n# by applypatch from an e-mail message.\n#\n#"
  },
  {
    "path": "levels/cherry-pick/.githug/hooks/pre-commit.sample",
    "chars": 1704,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed.\n# Called by \"git commit\" with no arguments"
  },
  {
    "path": "levels/cherry-pick/.githug/hooks/pre-rebase.sample",
    "chars": 4961,
    "preview": "#!/bin/sh\n#\n# Copyright (c) 2006, 2008 Junio C Hamano\n#\n# The \"pre-rebase\" hook is run just before \"git rebase\" starts d"
  },
  {
    "path": "levels/cherry-pick/.githug/hooks/prepare-commit-msg.sample",
    "chars": 1259,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare the commit log message.\n# Called by \"git commit\" with the name of the fi"
  },
  {
    "path": "levels/cherry-pick/.githug/hooks/update.sample",
    "chars": 3611,
    "preview": "#!/bin/sh\n#\n# An example hook script to blocks unannotated tags from entering.\n# Called by \"git receive-pack\" with argum"
  },
  {
    "path": "levels/cherry-pick/.githug/info/exclude",
    "chars": 240,
    "preview": "# git ls-files --others --exclude-from=.git/info/exclude\n# Lines that start with '#' are comments.\n# For a project mostl"
  },
  {
    "path": "levels/cherry-pick/.githug/logs/HEAD",
    "chars": 2378,
    "preview": "0000000000000000000000000000000000000000 ea3dbcc5e2d2359698c3606b0ec44af9f76def54 Andrey <aslushnikov@gmail.com> 1332886"
  },
  {
    "path": "levels/cherry-pick/.githug/logs/refs/heads/master",
    "chars": 672,
    "preview": "0000000000000000000000000000000000000000 ea3dbcc5e2d2359698c3606b0ec44af9f76def54 Andrey <aslushnikov@gmail.com> 1332886"
  },
  {
    "path": "levels/cherry-pick/.githug/logs/refs/heads/new-feature",
    "chars": 962,
    "preview": "0000000000000000000000000000000000000000 ea3dbcc5e2d2359698c3606b0ec44af9f76def54 Andrey <aslushnikov@gmail.com> 1332887"
  },
  {
    "path": "levels/cherry-pick/.githug/objects/6e/dea632d9540e060bca97dda0897df2b7da0ec0",
    "chars": 88,
    "preview": "x\u0001A\u000e \u0010E]s\n&\u0018{\u0014\fтAj\u001ey/,ܤ̩Uf\t\u0007\u0006쉌Kj`-ʙ^C|\u0001\u001d\u0019N\b&`bnƄ8\u0014amSrTyy)?0.,7\t]C<^)_K1\u00101\u0014rXC>VY{m\u0007[K("
  },
  {
    "path": "levels/cherry-pick/.githug/refs/heads/master",
    "chars": 41,
    "preview": "6edea632d9540e060bca97dda0897df2b7da0ec0\n"
  },
  {
    "path": "levels/cherry-pick/.githug/refs/heads/new-feature",
    "chars": 41,
    "preview": "ea2a47c19b85fc321e2737ddc49db3deeba3a1b5\n"
  },
  {
    "path": "levels/cherry-pick/README.md",
    "chars": 41,
    "preview": "I'll fill in the file some time later..\n\n"
  },
  {
    "path": "levels/cherry-pick/hardcore-math.js",
    "chars": 57,
    "preview": "for(var i = 0; i < 10; i++) {\n    console.log(42 * i);\n}\n"
  },
  {
    "path": "levels/cherry-pick/nokia.js",
    "chars": 42,
    "preview": "console.log(\"[NOKIA] Connecting people\");\n"
  },
  {
    "path": "levels/cherry-pick.rb",
    "chars": 598,
    "preview": "difficulty 3\ndescription \"Your new feature isn't worth the time and you're going to delete it. But it has one commit tha"
  },
  {
    "path": "levels/clone.rb",
    "chars": 266,
    "preview": "difficulty 1\ndescription \"Clone the repository at https://github.com/Gazler/cloneme.\"\n\nsolution do\n  repo(\"cloneme\").com"
  },
  {
    "path": "levels/clone_to_folder.rb",
    "chars": 301,
    "preview": "difficulty 1\ndescription \"Clone the repository at https://github.com/Gazler/cloneme into the folder `my_cloned_repo`.\"\n\n"
  },
  {
    "path": "levels/commit.rb",
    "chars": 332,
    "preview": "difficulty 1\ndescription \"The `README` file has been added to your staging area, now commit it.\"\n\nsetup do\n  repo.init\n "
  },
  {
    "path": "levels/commit_amend.rb",
    "chars": 757,
    "preview": "difficulty 2\ndescription \"The `README` file has been committed, but it looks like the file `forgotten_file.rb` was missi"
  },
  {
    "path": "levels/commit_in_future.rb",
    "chars": 403,
    "preview": "require 'time'\n\ndifficulty 2\ndescription \"Commit your changes with the future date (e.g. tomorrow).\"\n\nsetup do\n  repo.in"
  },
  {
    "path": "levels/config.rb",
    "chars": 812,
    "preview": "difficulty 1\ndescription \"Set up your git name and email; this is important so that your commits can be identified.\"\n\nse"
  },
  {
    "path": "levels/conflict/.githug/COMMIT_EDITMSG",
    "chars": 385,
    "preview": "Updated the poem\n\n# Please enter the commit message for your changes. Lines starting\n# with '#' will be ignored, and an "
  },
  {
    "path": "levels/conflict/.githug/HEAD",
    "chars": 23,
    "preview": "ref: refs/heads/master\n"
  },
  {
    "path": "levels/conflict/.githug/config",
    "chars": 92,
    "preview": "[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = false\n\tlogallrefupdates = true\n"
  },
  {
    "path": "levels/conflict/.githug/description",
    "chars": 73,
    "preview": "Unnamed repository; edit this file 'description' to name the repository.\n"
  },
  {
    "path": "levels/conflict/.githug/hooks/applypatch-msg.sample",
    "chars": 452,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message taken by\n# applypatch from an e-mail message.\n#\n# T"
  },
  {
    "path": "levels/conflict/.githug/hooks/commit-msg.sample",
    "chars": 896,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message.\n# Called by \"git commit\" with one argument, the na"
  },
  {
    "path": "levels/conflict/.githug/hooks/post-update.sample",
    "chars": 189,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare a packed repository for use over\n# dumb transports.\n#\n# To enable this h"
  },
  {
    "path": "levels/conflict/.githug/hooks/pre-applypatch.sample",
    "chars": 398,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed\n# by applypatch from an e-mail message.\n#\n#"
  },
  {
    "path": "levels/conflict/.githug/hooks/pre-commit.sample",
    "chars": 1704,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed.\n# Called by \"git commit\" with no arguments"
  },
  {
    "path": "levels/conflict/.githug/hooks/pre-rebase.sample",
    "chars": 4898,
    "preview": "#!/bin/sh\n#\n# Copyright (c) 2006, 2008 Junio C Hamano\n#\n# The \"pre-rebase\" hook is run just before \"git rebase\" starts d"
  },
  {
    "path": "levels/conflict/.githug/hooks/prepare-commit-msg.sample",
    "chars": 1239,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare the commit log message.\n# Called by \"git commit\" with the name of the fi"
  },
  {
    "path": "levels/conflict/.githug/hooks/update.sample",
    "chars": 3611,
    "preview": "#!/bin/sh\n#\n# An example hook script to blocks unannotated tags from entering.\n# Called by \"git receive-pack\" with argum"
  },
  {
    "path": "levels/conflict/.githug/info/exclude",
    "chars": 240,
    "preview": "# git ls-files --others --exclude-from=.git/info/exclude\n# Lines that start with '#' are comments.\n# For a project mostl"
  },
  {
    "path": "levels/conflict/.githug/logs/HEAD",
    "chars": 2041,
    "preview": "0000000000000000000000000000000000000000 306868e3258be1f35ae43db71e3a6d7edf42ffe7 Thameera Senanayaka <thameera123@gmail"
  },
  {
    "path": "levels/conflict/.githug/logs/refs/heads/master",
    "chars": 669,
    "preview": "0000000000000000000000000000000000000000 306868e3258be1f35ae43db71e3a6d7edf42ffe7 Thameera Senanayaka <thameera123@gmail"
  },
  {
    "path": "levels/conflict/.githug/logs/refs/heads/mybranch",
    "chars": 825,
    "preview": "0000000000000000000000000000000000000000 306868e3258be1f35ae43db71e3a6d7edf42ffe7 Thameera Senanayaka <thameera123@gmail"
  },
  {
    "path": "levels/conflict/.githug/objects/2d/0d90051e320215f54f357e746c9838490557e7",
    "chars": 36,
    "preview": "x\u0001+)JMU06c040031Q(O+(apKLyVi.G1Z\u0013\u0001>\u000f"
  },
  {
    "path": "levels/conflict/.githug/objects/3d/7aec017559be2b61cab850dafdcb2b6212f1c3",
    "chars": 108,
    "preview": "x\u0001=[JC1\u0014E(\u0004,'\u0007\u00148\u0004ISz4:z/R,XZ/\u0013QOs0C\"bQ!rD9\u0005es(=5b{qm[\u000b\u001aM6\":`v\u0018\u00123-\b\u000f(T\u0007;7jMW|@\\\u001d^_@jZkxF(v<u/8[?~^hYaB\tfau\u0017M\u0004"
  },
  {
    "path": "levels/conflict/.githug/objects/6b/0c0b32bdca3af9beb831744cb755d6fdc7c7c0",
    "chars": 60,
    "preview": "x\u0001U\t0\u0010EQשU \n \u0016`\u0003\u00133~`\t\bvop'\\cE-acyྙE\u0001\u0004\"\u000b\u0006Gb*ةY+ET\u0005QكoN\u0006F>0Л\u0017&"
  },
  {
    "path": "levels/conflict/.githug/objects/75/179304f4fab00613f08a9412b6cb0965bfa564",
    "chars": 96,
    "preview": "x\u0001Kn@\f@Y)@瓤\u0010=\u0003\\q j'AtI^b\u0016O֩~V3=\u00058GRQ\"b\rI\u0007&L\u001d\u0012U4 \u0010wY1%\u0001QP:3a\u0010xTN~mYrj\nmY\u001e% ?]L߇#a\u00010zt\u001bbqX_۶yV8D\u0004b"
  },
  {
    "path": "levels/conflict/.githug/objects/88/e0473c9da347c6311f5f8eca8d256bf25402b6",
    "chars": 36,
    "preview": "x\u0001+)JMU06c040031Q(O+(ap1kzY)x\u0002׌\n\u001f\u0001/\u000e"
  },
  {
    "path": "levels/conflict/.githug/objects/bd/c7bec8acae9b3eabf0a15b223a48211b7a89a1",
    "chars": 94,
    "preview": "x\u0001A\n0\u0010@Q9\\@dd\u0002\"'4\u0013[h\u001b\u0011\u000b=y,S\u0003Gth*d\u0011%F٫\u001c!eR\b1l 6D®tE\u0012T%v%?$OEz\u0019ynp\u0003Z:A汾i\\\u0017\u000bXbǞ\b\u0018\u0010Ͱ?6O(C3QYu1?6lJ"
  },
  {
    "path": "levels/conflict/.githug/refs/heads/master",
    "chars": 41,
    "preview": "c797f979cf24ba148bf10d5e26f5d7402dd5f2e1\n"
  },
  {
    "path": "levels/conflict/.githug/refs/heads/mybranch",
    "chars": 41,
    "preview": "3d7aec017559be2b61cab850dafdcb2b6212f1c3\n"
  },
  {
    "path": "levels/conflict/poem.txt",
    "chars": 73,
    "preview": "Humpty dumpty\nCategorized shoes by color\nHumpty dumpty\nHad a great fall\n\n"
  },
  {
    "path": "levels/conflict.rb",
    "chars": 823,
    "preview": "difficulty 4\ndescription \"You need to merge mybranch into the current branch (master). But there may be some incorrect c"
  },
  {
    "path": "levels/contribute.rb",
    "chars": 901,
    "preview": "difficulty 3\ndescription \"This is the final level, the goal is to contribute to this repository by making a pull request"
  },
  {
    "path": "levels/delete_branch/.githug/COMMIT_EDITMSG",
    "chars": 17,
    "preview": "delete_me branch\n"
  },
  {
    "path": "levels/delete_branch/.githug/HEAD",
    "chars": 23,
    "preview": "ref: refs/heads/master\n"
  },
  {
    "path": "levels/delete_branch/.githug/config",
    "chars": 138,
    "preview": "[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = false\n\tlogallrefupdates = true\n\tignorecase = true\n\tprecompo"
  },
  {
    "path": "levels/delete_branch/.githug/description",
    "chars": 73,
    "preview": "Unnamed repository; edit this file 'description' to name the repository.\n"
  },
  {
    "path": "levels/delete_branch/.githug/hooks/applypatch-msg.sample",
    "chars": 452,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message taken by\n# applypatch from an e-mail message.\n#\n# T"
  },
  {
    "path": "levels/delete_branch/.githug/hooks/commit-msg.sample",
    "chars": 896,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message.\n# Called by \"git commit\" with one argument, the na"
  },
  {
    "path": "levels/delete_branch/.githug/hooks/post-update.sample",
    "chars": 189,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare a packed repository for use over\n# dumb transports.\n#\n# To enable this h"
  },
  {
    "path": "levels/delete_branch/.githug/hooks/pre-applypatch.sample",
    "chars": 398,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed\n# by applypatch from an e-mail message.\n#\n#"
  },
  {
    "path": "levels/delete_branch/.githug/hooks/pre-commit.sample",
    "chars": 1635,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed.\n# Called by \"git commit\" with no arguments"
  },
  {
    "path": "levels/delete_branch/.githug/hooks/pre-push.sample",
    "chars": 1348,
    "preview": "#!/bin/sh\n\n# An example hook script to verify what is about to be pushed.  Called by \"git\n# push\" after it has checked t"
  },
  {
    "path": "levels/delete_branch/.githug/hooks/pre-rebase.sample",
    "chars": 4951,
    "preview": "#!/bin/sh\n#\n# Copyright (c) 2006, 2008 Junio C Hamano\n#\n# The \"pre-rebase\" hook is run just before \"git rebase\" starts d"
  },
  {
    "path": "levels/delete_branch/.githug/hooks/prepare-commit-msg.sample",
    "chars": 1239,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare the commit log message.\n# Called by \"git commit\" with the name of the fi"
  },
  {
    "path": "levels/delete_branch/.githug/hooks/update.sample",
    "chars": 3611,
    "preview": "#!/bin/sh\n#\n# An example hook script to blocks unannotated tags from entering.\n# Called by \"git receive-pack\" with argum"
  },
  {
    "path": "levels/delete_branch/.githug/info/exclude",
    "chars": 240,
    "preview": "# git ls-files --others --exclude-from=.git/info/exclude\n# Lines that start with '#' are comments.\n# For a project mostl"
  },
  {
    "path": "levels/delete_branch/.githug/logs/HEAD",
    "chars": 710,
    "preview": "0000000000000000000000000000000000000000 b60afe294eb3c200d646995c9e0234470157c1b0 Daniel Smilansky <dsmilansky@gmail.com"
  },
  {
    "path": "levels/delete_branch/.githug/logs/refs/heads/delete_me",
    "chars": 167,
    "preview": "0000000000000000000000000000000000000000 b60afe294eb3c200d646995c9e0234470157c1b0 Daniel Smilansky <dsmilansky@gmail.com"
  },
  {
    "path": "levels/delete_branch/.githug/logs/refs/heads/master",
    "chars": 170,
    "preview": "0000000000000000000000000000000000000000 b60afe294eb3c200d646995c9e0234470157c1b0 Daniel Smilansky <dsmilansky@gmail.com"
  },
  {
    "path": "levels/delete_branch/.githug/objects/b6/0afe294eb3c200d646995c9e0234470157c1b0",
    "chars": 75,
    "preview": "x\u0001\r\u0002!\u0010aT1\rh\u0018'\u0018\u000fv`\u0005\u0013\u0018\bK\u0002x{\u0018+=<_\u0001q7\u001a3\u0014'OBc#\u001bœwFh6zz\u0016\u001cLk\f2%>\n|\b\u001c\u0001ǘgNJx\u001f\u0007|%\u00061?Q"
  },
  {
    "path": "levels/delete_branch/.githug/refs/heads/delete_me",
    "chars": 41,
    "preview": "b60afe294eb3c200d646995c9e0234470157c1b0\n"
  },
  {
    "path": "levels/delete_branch/.githug/refs/heads/master",
    "chars": 41,
    "preview": "b60afe294eb3c200d646995c9e0234470157c1b0\n"
  },
  {
    "path": "levels/delete_branch/readme",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "levels/delete_branch.rb",
    "chars": 400,
    "preview": "difficulty 2\n\ndescription \"You have created too many branches for your project. There is an old branch in your repo call"
  },
  {
    "path": "levels/diff/.githug/COMMIT_EDITMSG",
    "chars": 13,
    "preview": "added app.rb\n"
  },
  {
    "path": "levels/diff/.githug/HEAD",
    "chars": 23,
    "preview": "ref: refs/heads/master\n"
  },
  {
    "path": "levels/diff/.githug/config",
    "chars": 92,
    "preview": "[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = false\n\tlogallrefupdates = true\n"
  },
  {
    "path": "levels/diff/.githug/description",
    "chars": 73,
    "preview": "Unnamed repository; edit this file 'description' to name the repository.\n"
  },
  {
    "path": "levels/diff/.githug/hooks/applypatch-msg.sample",
    "chars": 452,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message taken by\n# applypatch from an e-mail message.\n#\n# T"
  },
  {
    "path": "levels/diff/.githug/hooks/commit-msg.sample",
    "chars": 896,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message.\n# Called by \"git commit\" with one argument, the na"
  },
  {
    "path": "levels/diff/.githug/hooks/post-commit.sample",
    "chars": 160,
    "preview": "#!/bin/sh\n#\n# An example hook script that is called after a successful\n# commit is made.\n#\n# To enable this hook, rename"
  },
  {
    "path": "levels/diff/.githug/hooks/post-receive.sample",
    "chars": 552,
    "preview": "#!/bin/sh\n#\n# An example hook script for the \"post-receive\" event.\n#\n# The \"post-receive\" script is run after receive-pa"
  },
  {
    "path": "levels/diff/.githug/hooks/post-update.sample",
    "chars": 189,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare a packed repository for use over\n# dumb transports.\n#\n# To enable this h"
  },
  {
    "path": "levels/diff/.githug/hooks/pre-applypatch.sample",
    "chars": 398,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed\n# by applypatch from an e-mail message.\n#\n#"
  },
  {
    "path": "levels/diff/.githug/hooks/pre-commit.sample",
    "chars": 1578,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed.\n# Called by \"git commit\" with no arguments"
  },
  {
    "path": "levels/diff/.githug/hooks/pre-rebase.sample",
    "chars": 4951,
    "preview": "#!/bin/sh\n#\n# Copyright (c) 2006, 2008 Junio C Hamano\n#\n# The \"pre-rebase\" hook is run just before \"git rebase\" starts d"
  },
  {
    "path": "levels/diff/.githug/hooks/prepare-commit-msg.sample",
    "chars": 1239,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare the commit log message.\n# Called by \"git commit\" with the name of the fi"
  },
  {
    "path": "levels/diff/.githug/hooks/update.sample",
    "chars": 3611,
    "preview": "#!/bin/sh\n#\n# An example hook script to blocks unannotated tags from entering.\n# Called by \"git receive-pack\" with argum"
  },
  {
    "path": "levels/diff/.githug/info/exclude",
    "chars": 240,
    "preview": "# git ls-files --others --exclude-from=.git/info/exclude\n# Lines that start with '#' are comments.\n# For a project mostl"
  },
  {
    "path": "levels/diff/.githug/logs/HEAD",
    "chars": 165,
    "preview": "0000000000000000000000000000000000000000 dcaa55e97af34402e84d5336da37abcccc23cba6 Gary Rennie <webmaster@gazler.com> 133"
  },
  {
    "path": "levels/diff/.githug/logs/refs/heads/master",
    "chars": 165,
    "preview": "0000000000000000000000000000000000000000 dcaa55e97af34402e84d5336da37abcccc23cba6 Gary Rennie <webmaster@gazler.com> 133"
  },
  {
    "path": "levels/diff/.githug/objects/4f/703ca9bd25781b6758eeb3c42ed5348610ba6d",
    "chars": 292,
    "preview": "x\u0001Sn0\u00143_a\u0007\u0012\u0002jZiQtKfj\u0012uZU!o\u001b6tڿ\u001aeos=Dǯ$<\\\u0002q\u0014ϩԱ~W\u0004-u2\u0015\u001e\u001d\u000br\u001a@\u0002\u0005Jq+bpGC-B3\u0015\u0004M͡\u001a\u001a\u001fs|\u001f.UUMDS)QUe+~;M'/\u0019~]YǫjujʎxCo\u00035;b'Z\u0017\"i\"\u000e}"
  },
  {
    "path": "levels/diff/.githug/objects/dc/aa55e97af34402e84d5336da37abcccc23cba6",
    "chars": 77,
    "preview": "x\u0001M\n0\u0010F]\u0014\u0017J&?M\nEܹ\u0006d\u0005Ӕ\u0018\u0011=9\u001e\u001f\u0006*3`\u001cWz4B.ZS$8$f\u0011^^*\\Bme\u001csx6[>\u000eT\tPk*p}ٵj\u0011R\u0004a߇\u001a\u000f+:"
  },
  {
    "path": "levels/diff/.githug/refs/heads/master",
    "chars": 41,
    "preview": "dcaa55e97af34402e84d5336da37abcccc23cba6\n"
  },
  {
    "path": "levels/diff/app.rb",
    "chars": 1004,
    "preview": "require 'sinatra'\nrequire 'oauth2'\nrequire 'json'\nenable :sessions\n\ndef client\n  OAuth2::Client.new(\"mTeZFqkCmzc8JnjKXaS"
  },
  {
    "path": "levels/diff.rb",
    "chars": 461,
    "preview": "difficulty 2\ndescription \"Since your last commit, file `app.rb` was modified. Find out which line has changed.\"\n\nsetup d"
  },
  {
    "path": "levels/fetch.rb",
    "chars": 1881,
    "preview": "difficulty 2\ndescription \"Looks like a new branch was pushed into our remote repository. Get the changes without merging"
  },
  {
    "path": "levels/find_old_branch/.githug/COMMIT_EDITMSG",
    "chars": 20,
    "preview": "commit another todo\n"
  },
  {
    "path": "levels/find_old_branch/.githug/HEAD",
    "chars": 32,
    "preview": "ref: refs/heads/kill_the_batman\n"
  },
  {
    "path": "levels/find_old_branch/.githug/ORIG_HEAD",
    "chars": 41,
    "preview": "05e9c01bd3c9264761dd0cde477400a2c3104642\n"
  },
  {
    "path": "levels/find_old_branch/.githug/config",
    "chars": 111,
    "preview": "[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = false\n\tlogallrefupdates = true\n\tignorecase = true\n"
  },
  {
    "path": "levels/find_old_branch/.githug/description",
    "chars": 73,
    "preview": "Unnamed repository; edit this file 'description' to name the repository.\n"
  },
  {
    "path": "levels/find_old_branch/.githug/hooks/applypatch-msg.sample",
    "chars": 452,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message taken by\n# applypatch from an e-mail message.\n#\n# T"
  },
  {
    "path": "levels/find_old_branch/.githug/hooks/commit-msg.sample",
    "chars": 896,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message.\n# Called by \"git commit\" with one argument, the na"
  },
  {
    "path": "levels/find_old_branch/.githug/hooks/post-commit.sample",
    "chars": 160,
    "preview": "#!/bin/sh\n#\n# An example hook script that is called after a successful\n# commit is made.\n#\n# To enable this hook, rename"
  },
  {
    "path": "levels/find_old_branch/.githug/hooks/post-receive.sample",
    "chars": 552,
    "preview": "#!/bin/sh\n#\n# An example hook script for the \"post-receive\" event.\n#\n# The \"post-receive\" script is run after receive-pa"
  },
  {
    "path": "levels/find_old_branch/.githug/hooks/post-update.sample",
    "chars": 189,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare a packed repository for use over\n# dumb transports.\n#\n# To enable this h"
  },
  {
    "path": "levels/find_old_branch/.githug/hooks/pre-applypatch.sample",
    "chars": 398,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed\n# by applypatch from an e-mail message.\n#\n#"
  },
  {
    "path": "levels/find_old_branch/.githug/hooks/pre-commit.sample",
    "chars": 1704,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed.\n# Called by \"git commit\" with no arguments"
  },
  {
    "path": "levels/find_old_branch/.githug/hooks/pre-rebase.sample",
    "chars": 4951,
    "preview": "#!/bin/sh\n#\n# Copyright (c) 2006, 2008 Junio C Hamano\n#\n# The \"pre-rebase\" hook is run just before \"git rebase\" starts d"
  },
  {
    "path": "levels/find_old_branch/.githug/hooks/prepare-commit-msg.sample",
    "chars": 1239,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare the commit log message.\n# Called by \"git commit\" with the name of the fi"
  },
  {
    "path": "levels/find_old_branch/.githug/hooks/update.sample",
    "chars": 3611,
    "preview": "#!/bin/sh\n#\n# An example hook script to blocks unannotated tags from entering.\n# Called by \"git receive-pack\" with argum"
  },
  {
    "path": "levels/find_old_branch/.githug/info/exclude",
    "chars": 250,
    "preview": "# git ls-files --others --exclude-from=.git/info/exclude\n# Lines that start with '#' are comments.\n# For a project mostl"
  },
  {
    "path": "levels/find_old_branch/.githug/logs/HEAD",
    "chars": 1210,
    "preview": "0000000000000000000000000000000000000000 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283192 "
  },
  {
    "path": "levels/find_old_branch/.githug/logs/refs/heads/blowup_sun_for_ransom",
    "chars": 152,
    "preview": "0000000000000000000000000000000000000000 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283240 "
  },
  {
    "path": "levels/find_old_branch/.githug/logs/refs/heads/cure_common_cold",
    "chars": 350,
    "preview": "0000000000000000000000000000000000000000 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283192 "
  },
  {
    "path": "levels/find_old_branch/.githug/logs/refs/heads/kill_the_batman",
    "chars": 601,
    "preview": "0000000000000000000000000000000000000000 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283224 "
  },
  {
    "path": "levels/find_old_branch/.githug/logs/refs/heads/solve_world_hunger",
    "chars": 298,
    "preview": "0000000000000000000000000000000000000000 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283272 "
  },
  {
    "path": "levels/find_old_branch/.githug/refs/heads/blowup_sun_for_ransom",
    "chars": 41,
    "preview": "6876e5b41fb693190df76b1baef6ef98623b4f1a\n"
  },
  {
    "path": "levels/find_old_branch/.githug/refs/heads/cure_common_cold",
    "chars": 41,
    "preview": "6876e5b41fb693190df76b1baef6ef98623b4f1a\n"
  },
  {
    "path": "levels/find_old_branch/.githug/refs/heads/kill_the_batman",
    "chars": 41,
    "preview": "894a16d6f1a48224e9006b4a6f0fe3846da19bec\n"
  },
  {
    "path": "levels/find_old_branch/.githug/refs/heads/solve_world_hunger",
    "chars": 41,
    "preview": "324336a8401afc8ca384eaafe6615c84d552dd2c\n"
  },
  {
    "path": "levels/find_old_branch/TODO",
    "chars": 15,
    "preview": "FIND THE JOKER\n"
  },
  {
    "path": "levels/find_old_branch/myfile.txt",
    "chars": 25,
    "preview": "THIS TEXT DOESN'T MATTER\n"
  },
  {
    "path": "levels/find_old_branch.rb",
    "chars": 378,
    "preview": "difficulty 4\ndescription \"You have been working on a branch but got distracted by a major issue. Switch back to that bra"
  },
  {
    "path": "levels/grep/.githug/COMMIT_EDITMSG",
    "chars": 23,
    "preview": "Add application files.\n"
  },
  {
    "path": "levels/grep/.githug/HEAD",
    "chars": 23,
    "preview": "ref: refs/heads/master\n"
  },
  {
    "path": "levels/grep/.githug/config",
    "chars": 111,
    "preview": "[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = false\n\tlogallrefupdates = true\n\tignorecase = true\n"
  }
]

// ... and 213 more files (download for full content)

About this extraction

This page contains the full source code of the Gazler/githug GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 413 files (261.7 KB), approximately 96.9k tokens, and a symbol index with 89 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!