├── .gitignore ├── .rspec ├── .travis.yml ├── Dockerfile ├── Gemfile ├── LICENCE.txt ├── README.md ├── Rakefile ├── bin └── githug ├── githug.gemspec ├── levels ├── add.rb ├── bisect.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 ├── blame.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 │ │ │ ├── 21 │ │ │ │ └── 15d78864000292628872941b14521f90187eed │ │ │ ├── 31 │ │ │ │ └── 11dda1f5b08d50ac44b99acabfa54f1e6e72b0 │ │ │ ├── 50 │ │ │ │ └── 8db115ba34a0e4e8667653aebe0265bb4f7e80 │ │ │ ├── 67 │ │ │ │ └── 788a4b90180c7588d7bd0ad8032957b0f429ba │ │ │ ├── 70 │ │ │ │ └── d00535a3a25b0ac1736dd3d306d6271e5427ed │ │ │ ├── 97 │ │ │ │ └── bdd0cccf9f4b8730f78cb53a81a74f205dbcc2 │ │ │ ├── 00 │ │ │ │ └── d6bf5341b263ccaf32e7973be55126eb30a343 │ │ │ ├── 05 │ │ │ │ └── 07c26fed4d111a8344763be9af68af90f0ecf2 │ │ │ ├── 09 │ │ │ │ └── 4094808dc6dc336c93c8602190a9e5f7bd6a11 │ │ │ ├── 5e │ │ │ │ └── 8863df752e3b7f2150df7c78f12bef6f1ff00e │ │ │ ├── ab │ │ │ │ └── 08819ba3ffaeba17d4f870dc3a458a904519f4 │ │ │ ├── be │ │ │ │ └── 96fe46de646f6a5c728f90cc884aef96fa1d6f │ │ │ ├── cd │ │ │ │ └── 9c6b9ab1a6f56cccc69b6aa661f1d67ba5fb46 │ │ │ ├── dd │ │ │ │ └── df1d8ebd60eec169c15a5b23cb49a58d2ed5a0 │ │ │ └── ff │ │ │ │ └── d39c2dbfd94bdbca06d48686e0cbda642f3de7 │ │ └── refs │ │ │ └── heads │ │ │ └── master │ └── config.rb ├── branch.rb ├── branch_at.rb ├── checkout.rb ├── checkout_file.rb ├── checkout_tag.rb ├── checkout_tag_over_branch.rb ├── cherry-pick.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 │ │ │ ├── 14 │ │ │ │ └── ad8f1413c40e0e5be6f6cbdec392a783c1d754 │ │ │ ├── 22 │ │ │ │ └── f99f3abfd02190a760388c8845c190247859fe │ │ │ ├── 23 │ │ │ │ └── 2d266a78d5ef7196f1ede14972ccf7ee19e587 │ │ │ ├── 31 │ │ │ │ └── 68bdc3ae7e0ab987dda238beab9c0582c7fc07 │ │ │ ├── 49 │ │ │ │ └── 4fa3fc1c15986f9a950aba8607da591223614c │ │ │ ├── 54 │ │ │ │ ├── 22c2405527c05c23b243b2535a97b6cefa1427 │ │ │ │ └── f3308533fd4400c94c4cd5827cd38036a67a76 │ │ │ ├── 58 │ │ │ │ └── a8c8edcfdd00c6d8cce9aada8f987a1677571f │ │ │ ├── 85 │ │ │ │ └── 4e7ac38b3e8df02ea1480ec45aa9e7865f03d7 │ │ │ ├── 93 │ │ │ │ └── 3a97260a11a5ee49bb8a4b7b097cb2fb38f85c │ │ │ ├── 05 │ │ │ │ └── aa97588aff673dcf00e0e1b835d6ec6207a7d9 │ │ │ ├── 1b │ │ │ │ └── 912962174dd58fbbf1627ec816fa6672c70854 │ │ │ ├── 4a │ │ │ │ └── 1961bce62840eaef9c4392fe5cc799e38c9b7b │ │ │ ├── 6e │ │ │ │ └── dea632d9540e060bca97dda0897df2b7da0ec0 │ │ │ ├── 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 ├── clone.rb ├── clone_to_folder.rb ├── commit.rb ├── commit_amend.rb ├── commit_in_future.rb ├── config.rb ├── conflict.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 │ │ │ ├── 25 │ │ │ │ └── b3f9c339430b35ae5822b2ef90e763284dc007 │ │ │ ├── 30 │ │ │ │ ├── 6868e3258be1f35ae43db71e3a6d7edf42ffe7 │ │ │ │ └── cc28e66966109bb5bfbe96d6c817c367d2050a │ │ │ ├── 38 │ │ │ │ └── 21e4362c5a76db1112b46b9210670cd5bab482 │ │ │ ├── 40 │ │ │ │ └── e20a455ac2731ad25c297b03aa543d7eedf6ab │ │ │ ├── 44 │ │ │ │ └── 30fd3f45c832e685350417600a9862c94d20f1 │ │ │ ├── 46 │ │ │ │ └── 677964e679f3e727356d0860c643a12a87902b │ │ │ ├── 50 │ │ │ │ └── a127cb066eb903a6fa59d71802c10cb442fb3b │ │ │ ├── 55 │ │ │ │ └── ad5af2a93afa778971e3d04faf20f6c368b6ba │ │ │ ├── 75 │ │ │ │ └── 179304f4fab00613f08a9412b6cb0965bfa564 │ │ │ ├── 88 │ │ │ │ └── e0473c9da347c6311f5f8eca8d256bf25402b6 │ │ │ ├── 1d │ │ │ │ └── b9aa5013e47f1482ec90323d926171a99c28af │ │ │ ├── 2d │ │ │ │ └── 0d90051e320215f54f357e746c9838490557e7 │ │ │ ├── 3c │ │ │ │ └── b65bef44ae724ddf9e89640e7e2754dea1a47f │ │ │ ├── 3d │ │ │ │ └── 7aec017559be2b61cab850dafdcb2b6212f1c3 │ │ │ ├── 6b │ │ │ │ └── 0c0b32bdca3af9beb831744cb755d6fdc7c7c0 │ │ │ ├── 7c │ │ │ │ └── 36daf29660ae4a2f09345427ef76f1d38f902f │ │ │ ├── bd │ │ │ │ └── c7bec8acae9b3eabf0a15b223a48211b7a89a1 │ │ │ ├── c7 │ │ │ │ └── 97f979cf24ba148bf10d5e26f5d7402dd5f2e1 │ │ │ └── da │ │ │ │ └── ae380200ed6eeaafd926177018e8ff3009b988 │ │ └── refs │ │ │ └── heads │ │ │ ├── master │ │ │ └── mybranch │ └── poem.txt ├── contribute.rb ├── delete_branch.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 ├── diff.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 ├── fetch.rb ├── find_old_branch.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 │ │ │ ├── 32 │ │ │ │ └── 4336a8401afc8ca384eaafe6615c84d552dd2c │ │ │ ├── 50 │ │ │ │ └── 72aab6bd73accec89ad3aa077f43aab8a5e507 │ │ │ ├── 68 │ │ │ │ └── 76e5b41fb693190df76b1baef6ef98623b4f1a │ │ │ ├── 89 │ │ │ │ └── 4a16d6f1a48224e9006b4a6f0fe3846da19bec │ │ │ ├── 05 │ │ │ │ └── e9c01bd3c9264761dd0cde477400a2c3104642 │ │ │ ├── 1f │ │ │ │ └── 0a136ddd98f61934d15eb00444df32d8e8254b │ │ │ ├── 5d │ │ │ │ └── 130caf89f1a4bba6a1fffe72c484f3ab659e08 │ │ │ ├── 6a │ │ │ │ └── 7702145d1eb91c9f79583eabb984027b12e60c │ │ │ ├── b8 │ │ │ │ └── c67b45e5fe9e4b39ac7ade725673f7c90bdfc3 │ │ │ └── bf │ │ │ │ └── 76434bc7e7346c6fef5a98aee0f7cfc0788f34 │ │ └── refs │ │ │ └── heads │ │ │ ├── blowup_sun_for_ransom │ │ │ ├── cure_common_cold │ │ │ ├── kill_the_batman │ │ │ └── solve_world_hunger │ ├── TODO │ └── myfile.txt ├── grep.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 ├── ignore.rb ├── include.rb ├── init.rb ├── log.rb ├── merge.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_squash.rb ├── number_of_files_committed.rb ├── pull.rb ├── push.rb ├── push_branch.rb ├── push_tags.rb ├── rebase.rb ├── rebase │ ├── .githug │ │ ├── COMMIT_EDITMSG │ │ ├── HEAD │ │ ├── ORIG_HEAD │ │ ├── config │ │ ├── index │ │ ├── logs │ │ │ ├── HEAD │ │ │ └── refs │ │ │ │ └── heads │ │ │ │ ├── feature │ │ │ │ └── master │ │ ├── objects │ │ │ ├── 44 │ │ │ │ └── 19b972c0cd1b346ac90332aa7c5cc949589f78 │ │ │ ├── 54 │ │ │ │ └── 3b9bebdc6bd5c4b22136034a95dd097a57d3dd │ │ │ ├── 81 │ │ │ │ └── 78c76d627cade75005b40711b92f4177bc6cfc │ │ │ ├── 98 │ │ │ │ └── 205e9faf10cf33d2ef7c0f66e402540c62613a │ │ │ ├── 0c │ │ │ │ └── d212c5b28da2e65ed4900712dd36c8adce48ad │ │ │ ├── a7 │ │ │ │ └── 8bcab6232e9382a86436cdfcb2ed0391b1f0ac │ │ │ ├── b7 │ │ │ │ └── 7313d7be366609dd2e77aa96d7fd73f4e27853 │ │ │ ├── b9 │ │ │ │ └── 2d5d55d379cfb90b750e6472fc983f32ad9a71 │ │ │ ├── e6 │ │ │ │ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391 │ │ │ └── ed │ │ │ │ └── 0fdcf366b21b8984fb37ea34106978a2e5c5ba │ │ └── refs │ │ │ └── heads │ │ │ ├── feature │ │ │ └── master │ └── README ├── 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.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 │ │ │ ├── 85 │ │ │ │ └── e560abcd7e3255dcd91982476e432f4d3d1b51 │ │ │ ├── 02 │ │ │ │ └── 060592b31c9e12ffe1b282addf9537c5ef8e1f │ │ │ ├── 4b │ │ │ │ └── 825dc642cb6eb9a060e54bf8d69288fbee4904 │ │ │ └── 7f │ │ │ │ └── 82d7e4fba66980af16da540e18d8955518cdc2 │ │ └── refs │ │ │ └── heads │ │ │ └── master │ └── lyrics.txt ├── status.rb ├── submodule.rb └── tag.rb ├── lib ├── githug.rb └── githug │ ├── cli.rb │ ├── extensions │ └── grit │ │ └── ruby1.9.rb │ ├── game.rb │ ├── level.rb │ ├── profile.rb │ ├── repository.rb │ ├── ui.rb │ └── version.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 /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | Gemfile.lock 4 | pkg/* 5 | *.swp 6 | .rvmrc 7 | git_hug/* 8 | .profile.yml -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --order default 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | dist: focal 3 | rvm: 4 | - 2.4.10 5 | - 2.5.9 6 | - 2.6.8 7 | - 2.7.4 8 | - 3.0.1 9 | - ruby-head 10 | 11 | matrix: 12 | allow_failures: 13 | - rvm: ruby-head 14 | 15 | before_install: 16 | - gem update --system 17 | - git config --global user.email 'user@example.com' 18 | - git config --global user.name 'Test User' 19 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | # Specify your gem's dependencies in githug.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /LICENCE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Gary 'Gazler' Rennie 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require 'rspec/core/rake_task' 3 | 4 | RSpec::Core::RakeTask.new(:spec) 5 | 6 | task :default => [:spec] 7 | -------------------------------------------------------------------------------- /bin/githug: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'githug/cli' 3 | 4 | Githug::CLI.start 5 | -------------------------------------------------------------------------------- /githug.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "githug/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "githug" 7 | s.version = Githug::VERSION 8 | s.authors = ["Gary Rennie"] 9 | s.email = ["gazler@gmail.com"] 10 | s.homepage = "https://github.com/Gazler/githug" 11 | s.summary = %q{An interactive way to learn git.} 12 | s.description = %q{An interactive way to learn git.} 13 | 14 | s.rubyforge_project = "githug" 15 | 16 | s.files = `git ls-files`.split("\n") 17 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 18 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 19 | s.require_paths = ["lib"] 20 | 21 | # specify any dependencies here; for example: 22 | s.add_development_dependency "rspec", "~>2.8.0" 23 | 24 | s.add_dependency "grit", "~>2.3.0" 25 | s.add_dependency "thor", "~>0.14.6" 26 | s.add_dependency "rake", "<11" 27 | end 28 | -------------------------------------------------------------------------------- /levels/add.rb: -------------------------------------------------------------------------------- 1 | difficulty 1 2 | description "There is a file in your folder called `README`; add it to your staging area. 3 | Note: Each level starts with a new repo. Don't look for files of the previous one." 4 | 5 | setup do 6 | repo.init 7 | FileUtils.touch("README") 8 | system "git branch -m master" 9 | end 10 | 11 | solution do 12 | return false unless repo.status.files.keys.include?("README") 13 | return false if repo.status.files["README"].untracked 14 | true 15 | end 16 | 17 | hint do 18 | puts "You can type `git` in your shell to get a list of available git commands." 19 | end 20 | -------------------------------------------------------------------------------- /levels/bisect.rb: -------------------------------------------------------------------------------- 1 | difficulty 3 2 | 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?" 3 | 4 | setup do 5 | init_from_level 6 | repo.init 7 | system "git branch -m master" 8 | end 9 | 10 | solution do 11 | "18ed2ac" == request("What are the first 7 characters of the hash of the commit that introduced the bug?")[0..6] 12 | end 13 | 14 | hint do 15 | 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`."] 16 | end 17 | -------------------------------------------------------------------------------- /levels/bisect/.githug/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | Another Commit 2 | -------------------------------------------------------------------------------- /levels/bisect/.githug/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /levels/bisect/.githug/ORIG_HEAD: -------------------------------------------------------------------------------- 1 | f351ca63a759f56bb26924fd566294eb23455c71 2 | -------------------------------------------------------------------------------- /levels/bisect/.githug/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | [pack] 7 | deltaCacheSize = 1 8 | -------------------------------------------------------------------------------- /levels/bisect/.githug/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /levels/bisect/.githug/gitk.cache: -------------------------------------------------------------------------------- 1 | 1 1 2 | f351ca63a759f56bb26924fd566294eb23455c71 f608824888b83bbedc1f658be7496ffea467a8fb {7f8406e742c5281ec2c9bc3c6cc69dc6ba5311fd 36da01fb0571360b0e1170f0cb46e74f72927cda c1b80f5ed4995cda8e19027f0776351af6b76703 4145057e11ab90109c95882b1f40d560da408bfa 94e162b505bc2290fb67764357a625192f8a4e8a bfb16eec1081387b586dc8009ef422cfff60b622 c0a1cdff8dd63948a5fc41f5871681c5b133c053 e8dd08d5aabb62b56c80320672cd8d42e2b8954d 89d27c5f4680cd21028947be75c33a68511decb9 98d617d3bdf0b6c59d6177233acb4b9fd54b7aac 0b194f30d6867522d1666590087e6c0b5e20dc93 d406b1b8bc269c9aef9127299e83947220e7a9b0 f608824888b83bbedc1f658be7496ffea467a8fb} 3 | 1 4 | -------------------------------------------------------------------------------- /levels/bisect/.githug/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /levels/bisect/.githug/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by "git commit" with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /levels/bisect/.githug/hooks/post-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script that is called after a successful 4 | # commit is made. 5 | # 6 | # To enable this hook, rename this file to "post-commit". 7 | 8 | : Nothing 9 | -------------------------------------------------------------------------------- /levels/bisect/.githug/hooks/post-receive.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script for the "post-receive" event. 4 | # 5 | # The "post-receive" script is run after receive-pack has accepted a pack 6 | # and the repository has been updated. It is passed arguments in through 7 | # stdin in the form 8 | # <oldrev> <newrev> <refname> 9 | # For example: 10 | # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master 11 | # 12 | # see contrib/hooks/ for a sample, or uncomment the next line and 13 | # rename the file to "post-receive". 14 | 15 | #. /usr/share/doc/git-core/contrib/hooks/post-receive-email 16 | -------------------------------------------------------------------------------- /levels/bisect/.githug/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git update-server-info 9 | -------------------------------------------------------------------------------- /levels/bisect/.githug/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /levels/bisect/.githug/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by "git commit" with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Cross platform projects tend to avoid non-ascii filenames; prevent 22 | # them from being added to the repository. We exploit the fact that the 23 | # printable range starts at the space character and ends with tilde. 24 | if [ "$allownonascii" != "true" ] && 25 | # Note that the use of brackets around a tr range is ok here, (it's 26 | # even required, for portability to Solaris 10's /usr/bin/tr), since 27 | # the square bracket bytes happen to fall in the designated range. 28 | test "$(git diff --cached --name-only --diff-filter=A -z $against | 29 | LC_ALL=C tr -d '[ -~]\0')" 30 | then 31 | echo "Error: Attempt to add a non-ascii file name." 32 | echo 33 | echo "This can cause problems if you want to work" 34 | echo "with people on other platforms." 35 | echo 36 | echo "To be portable it is advisable to rename the file ..." 37 | echo 38 | echo "If you know what you are doing you can disable this" 39 | echo "check using:" 40 | echo 41 | echo " git config hooks.allownonascii true" 42 | echo 43 | exit 1 44 | fi 45 | 46 | exec git diff-index --check --cached $against -- 47 | -------------------------------------------------------------------------------- /levels/bisect/.githug/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by "git commit" with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # /usr/bin/perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /levels/bisect/.githug/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/bisect/.githug/index -------------------------------------------------------------------------------- /levels/bisect/.githug/info/exclude: -------------------------------------------------------------------------------- 1 | # git ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /levels/bisect/.githug/info/refs: -------------------------------------------------------------------------------- 1 | 94e162b505bc2290fb67764357a625192f8a4e8a refs/bisect/bad 2 | bfb16eec1081387b586dc8009ef422cfff60b622 refs/bisect/good-bfb16eec1081387b586dc8009ef422cfff60b622 3 | c0a1cdff8dd63948a5fc41f5871681c5b133c053 refs/bisect/good-c0a1cdff8dd63948a5fc41f5871681c5b133c053 4 | f608824888b83bbedc1f658be7496ffea467a8fb refs/bisect/good-f608824888b83bbedc1f658be7496ffea467a8fb 5 | 12628f463f4c722695bf0e9d603c9411287885db refs/heads/master 6 | 32ae79196bd49a3416264970b0cd873e26bd1824 refs/tags/graetsch 7 | 89d27c5f4680cd21028947be75c33a68511decb9 refs/tags/graetsch^{} 8 | 2a5197909a0a1575145e0a40bb13dd54f5d6a9f7 refs/tags/orig_head 9 | f351ca63a759f56bb26924fd566294eb23455c71 refs/tags/orig_head^{} 10 | -------------------------------------------------------------------------------- /levels/bisect/.githug/objects/info/packs: -------------------------------------------------------------------------------- 1 | P pack-59fab357f3158a9640633de6a3326ed79a2b4fe6.pack 2 | 3 | -------------------------------------------------------------------------------- /levels/bisect/.githug/objects/pack/pack-59fab357f3158a9640633de6a3326ed79a2b4fe6.idx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/bisect/.githug/objects/pack/pack-59fab357f3158a9640633de6a3326ed79a2b4fe6.idx -------------------------------------------------------------------------------- /levels/bisect/.githug/objects/pack/pack-59fab357f3158a9640633de6a3326ed79a2b4fe6.pack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/bisect/.githug/objects/pack/pack-59fab357f3158a9640633de6a3326ed79a2b4fe6.pack -------------------------------------------------------------------------------- /levels/bisect/.githug/packed-refs: -------------------------------------------------------------------------------- 1 | # pack-refs with: peeled 2 | 94e162b505bc2290fb67764357a625192f8a4e8a refs/bisect/bad 3 | bfb16eec1081387b586dc8009ef422cfff60b622 refs/bisect/good-bfb16eec1081387b586dc8009ef422cfff60b622 4 | c0a1cdff8dd63948a5fc41f5871681c5b133c053 refs/bisect/good-c0a1cdff8dd63948a5fc41f5871681c5b133c053 5 | f608824888b83bbedc1f658be7496ffea467a8fb refs/bisect/good-f608824888b83bbedc1f658be7496ffea467a8fb 6 | 12628f463f4c722695bf0e9d603c9411287885db refs/heads/master 7 | 32ae79196bd49a3416264970b0cd873e26bd1824 refs/tags/graetsch 8 | ^89d27c5f4680cd21028947be75c33a68511decb9 9 | 2a5197909a0a1575145e0a40bb13dd54f5d6a9f7 refs/tags/orig_head 10 | ^f351ca63a759f56bb26924fd566294eb23455c71 11 | -------------------------------------------------------------------------------- /levels/bisect/makefile: -------------------------------------------------------------------------------- 1 | test: 2 | ruby prog.rb 5 | ruby test.rb 3 | -------------------------------------------------------------------------------- /levels/bisect/prog.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | puts Integer((Integer(ARGV[0])-3)*9)-1 4 | -------------------------------------------------------------------------------- /levels/bisect/test.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | line = gets 4 | exit 1 if line != "15\n" 5 | -------------------------------------------------------------------------------- /levels/blame.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | description "Identify who put a password inside the file `config.rb`." 3 | 4 | setup do 5 | init_from_level 6 | system "git branch -m master" 7 | end 8 | 9 | solution do 10 | offender = repo.commit("97bdd0cccf9f4b8730f78cb53a81a74f205dbcc2").author.name 11 | request("Who made the commit with the password?").downcase.strip == offender.downcase 12 | end 13 | 14 | hint do 15 | puts "You want to research the `git blame` command." 16 | end 17 | -------------------------------------------------------------------------------- /levels/blame/.githug/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | added more options (no really) 2 | -------------------------------------------------------------------------------- /levels/blame/.githug/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /levels/blame/.githug/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | -------------------------------------------------------------------------------- /levels/blame/.githug/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /levels/blame/.githug/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /levels/blame/.githug/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by "git commit" with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /levels/blame/.githug/hooks/post-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script that is called after a successful 4 | # commit is made. 5 | # 6 | # To enable this hook, rename this file to "post-commit". 7 | 8 | : Nothing 9 | -------------------------------------------------------------------------------- /levels/blame/.githug/hooks/post-receive.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script for the "post-receive" event. 4 | # 5 | # The "post-receive" script is run after receive-pack has accepted a pack 6 | # and the repository has been updated. It is passed arguments in through 7 | # stdin in the form 8 | # <oldrev> <newrev> <refname> 9 | # For example: 10 | # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master 11 | # 12 | # see contrib/hooks/ for a sample, or uncomment the next line and 13 | # rename the file to "post-receive". 14 | 15 | #. /usr/share/doc/git-core/contrib/hooks/post-receive-email 16 | -------------------------------------------------------------------------------- /levels/blame/.githug/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git update-server-info 9 | -------------------------------------------------------------------------------- /levels/blame/.githug/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /levels/blame/.githug/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by "git commit" with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Cross platform projects tend to avoid non-ascii filenames; prevent 22 | # them from being added to the repository. We exploit the fact that the 23 | # printable range starts at the space character and ends with tilde. 24 | if [ "$allownonascii" != "true" ] && 25 | # Note that the use of brackets around a tr range is ok here, (it's 26 | # even required, for portability to Solaris 10's /usr/bin/tr), since 27 | # the square bracket bytes happen to fall in the designated range. 28 | test "$(git diff --cached --name-only --diff-filter=A -z $against | 29 | LC_ALL=C tr -d '[ -~]\0')" 30 | then 31 | echo "Error: Attempt to add a non-ascii file name." 32 | echo 33 | echo "This can cause problems if you want to work" 34 | echo "with people on other platforms." 35 | echo 36 | echo "To be portable it is advisable to rename the file ..." 37 | echo 38 | echo "If you know what you are doing you can disable this" 39 | echo "check using:" 40 | echo 41 | echo " git config hooks.allownonascii true" 42 | echo 43 | exit 1 44 | fi 45 | 46 | exec git diff-index --check --cached $against -- 47 | -------------------------------------------------------------------------------- /levels/blame/.githug/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by "git commit" with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # /usr/bin/perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /levels/blame/.githug/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/index -------------------------------------------------------------------------------- /levels/blame/.githug/info/exclude: -------------------------------------------------------------------------------- 1 | # git ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /levels/blame/.githug/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 5e8863df752e3b7f2150df7c78f12bef6f1ff00e Gary Rennie <webmaster@gazler.com> 1331247924 +0000 commit (initial): added config with name 2 | 5e8863df752e3b7f2150df7c78f12bef6f1ff00e 094094808dc6dc336c93c8602190a9e5f7bd6a11 Spider Man <spidey-sense@tingling.com> 1331247978 +0000 commit: added options 3 | 094094808dc6dc336c93c8602190a9e5f7bd6a11 70d00535a3a25b0ac1736dd3d306d6271e5427ed Bruce Banner <hulk@smash.com> 1331248061 +0000 commit: added password 4 | 70d00535a3a25b0ac1736dd3d306d6271e5427ed 97bdd0cccf9f4b8730f78cb53a81a74f205dbcc2 Spider Man <spidey-sense@tingling.com> 1331248095 +0000 commit: added more options 5 | 97bdd0cccf9f4b8730f78cb53a81a74f205dbcc2 ffd39c2dbfd94bdbca06d48686e0cbda642f3de7 Gary Rennie <webmaster@gazler.com> 1331248138 +0000 commit: added more options (no really) 6 | -------------------------------------------------------------------------------- /levels/blame/.githug/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 5e8863df752e3b7f2150df7c78f12bef6f1ff00e Gary Rennie <webmaster@gazler.com> 1331247924 +0000 commit (initial): added config with name 2 | 5e8863df752e3b7f2150df7c78f12bef6f1ff00e 094094808dc6dc336c93c8602190a9e5f7bd6a11 Spider Man <spidey-sense@tingling.com> 1331247978 +0000 commit: added options 3 | 094094808dc6dc336c93c8602190a9e5f7bd6a11 70d00535a3a25b0ac1736dd3d306d6271e5427ed Bruce Banner <hulk@smash.com> 1331248061 +0000 commit: added password 4 | 70d00535a3a25b0ac1736dd3d306d6271e5427ed 97bdd0cccf9f4b8730f78cb53a81a74f205dbcc2 Spider Man <spidey-sense@tingling.com> 1331248095 +0000 commit: added more options 5 | 97bdd0cccf9f4b8730f78cb53a81a74f205dbcc2 ffd39c2dbfd94bdbca06d48686e0cbda642f3de7 Gary Rennie <webmaster@gazler.com> 1331248138 +0000 commit: added more options (no really) 6 | -------------------------------------------------------------------------------- /levels/blame/.githug/objects/00/d6bf5341b263ccaf32e7973be55126eb30a343: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/objects/00/d6bf5341b263ccaf32e7973be55126eb30a343 -------------------------------------------------------------------------------- /levels/blame/.githug/objects/05/07c26fed4d111a8344763be9af68af90f0ecf2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/objects/05/07c26fed4d111a8344763be9af68af90f0ecf2 -------------------------------------------------------------------------------- /levels/blame/.githug/objects/09/4094808dc6dc336c93c8602190a9e5f7bd6a11: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/objects/09/4094808dc6dc336c93c8602190a9e5f7bd6a11 -------------------------------------------------------------------------------- /levels/blame/.githug/objects/21/15d78864000292628872941b14521f90187eed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/objects/21/15d78864000292628872941b14521f90187eed -------------------------------------------------------------------------------- /levels/blame/.githug/objects/31/11dda1f5b08d50ac44b99acabfa54f1e6e72b0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/objects/31/11dda1f5b08d50ac44b99acabfa54f1e6e72b0 -------------------------------------------------------------------------------- /levels/blame/.githug/objects/50/8db115ba34a0e4e8667653aebe0265bb4f7e80: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/objects/50/8db115ba34a0e4e8667653aebe0265bb4f7e80 -------------------------------------------------------------------------------- /levels/blame/.githug/objects/5e/8863df752e3b7f2150df7c78f12bef6f1ff00e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/objects/5e/8863df752e3b7f2150df7c78f12bef6f1ff00e -------------------------------------------------------------------------------- /levels/blame/.githug/objects/67/788a4b90180c7588d7bd0ad8032957b0f429ba: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/objects/67/788a4b90180c7588d7bd0ad8032957b0f429ba -------------------------------------------------------------------------------- /levels/blame/.githug/objects/70/d00535a3a25b0ac1736dd3d306d6271e5427ed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/objects/70/d00535a3a25b0ac1736dd3d306d6271e5427ed -------------------------------------------------------------------------------- /levels/blame/.githug/objects/97/bdd0cccf9f4b8730f78cb53a81a74f205dbcc2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/objects/97/bdd0cccf9f4b8730f78cb53a81a74f205dbcc2 -------------------------------------------------------------------------------- /levels/blame/.githug/objects/ab/08819ba3ffaeba17d4f870dc3a458a904519f4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/objects/ab/08819ba3ffaeba17d4f870dc3a458a904519f4 -------------------------------------------------------------------------------- /levels/blame/.githug/objects/be/96fe46de646f6a5c728f90cc884aef96fa1d6f: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/objects/be/96fe46de646f6a5c728f90cc884aef96fa1d6f -------------------------------------------------------------------------------- /levels/blame/.githug/objects/cd/9c6b9ab1a6f56cccc69b6aa661f1d67ba5fb46: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/objects/cd/9c6b9ab1a6f56cccc69b6aa661f1d67ba5fb46 -------------------------------------------------------------------------------- /levels/blame/.githug/objects/dd/df1d8ebd60eec169c15a5b23cb49a58d2ed5a0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/objects/dd/df1d8ebd60eec169c15a5b23cb49a58d2ed5a0 -------------------------------------------------------------------------------- /levels/blame/.githug/objects/ff/d39c2dbfd94bdbca06d48686e0cbda642f3de7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/blame/.githug/objects/ff/d39c2dbfd94bdbca06d48686e0cbda642f3de7 -------------------------------------------------------------------------------- /levels/blame/.githug/refs/heads/master: -------------------------------------------------------------------------------- 1 | ffd39c2dbfd94bdbca06d48686e0cbda642f3de7 2 | -------------------------------------------------------------------------------- /levels/blame/config.rb: -------------------------------------------------------------------------------- 1 | class Config 2 | attr_accessor :name, :password 3 | def initialize(name, password = nil, options = {}) 4 | @name = name 5 | @password = password || "i<3evil" 6 | 7 | if options[:downcase] 8 | @name.downcase! 9 | end 10 | 11 | if options[:upcase] 12 | @name.upcase! 13 | end 14 | 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /levels/branch.rb: -------------------------------------------------------------------------------- 1 | difficulty 1 2 | description "To work on a piece of code that has the potential to break things, create the branch test_code." 3 | 4 | setup do 5 | repo.init 6 | FileUtils.touch("README") 7 | repo.add "README" 8 | repo.commit_all("Initial commit") 9 | system "git branch -m master" 10 | end 11 | 12 | solution do 13 | repo.branches.map(&:name).include?("test_code") 14 | end 15 | 16 | hint do 17 | puts "`git branch` is what you want to investigate." 18 | end 19 | 20 | -------------------------------------------------------------------------------- /levels/branch_at.rb: -------------------------------------------------------------------------------- 1 | difficulty 3 2 | 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." 3 | 4 | setup do 5 | repo.init 6 | FileUtils.touch("file1") 7 | repo.add("file1") 8 | repo.commit_all("Adding file1") 9 | File.open("file1", 'w') { |f| f.write("content") } 10 | repo.add("file1") 11 | repo.commit_all("Updating file1") 12 | File.open("file1", 'a') { |f| f.write("\nAdding some more text") } 13 | repo.add("file1") 14 | repo.commit_all("Updating file1 again") 15 | system "git branch -m master" 16 | end 17 | 18 | solution do 19 | return false unless repo.branches.map(&:name).include?("test_branch") 20 | repo.commits("test_branch").each { |commit| return false if commit.message == "Updating file1 again" } 21 | true 22 | end 23 | 24 | hint do 25 | puts "Just like creating a branch, but you have to pass an extra argument." 26 | end 27 | -------------------------------------------------------------------------------- /levels/checkout.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 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." 3 | 4 | setup do 5 | repo.init 6 | FileUtils.touch("README") 7 | repo.add("README") 8 | repo.commit_all("initial commit") 9 | system "git branch -m master" 10 | end 11 | 12 | solution do 13 | return false unless repo.head.name == "my_branch" 14 | true 15 | end 16 | 17 | hint do 18 | puts "Try looking up `git checkout` and `git branch`." 19 | end 20 | -------------------------------------------------------------------------------- /levels/checkout_file.rb: -------------------------------------------------------------------------------- 1 | difficulty 3 2 | 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." 4 | 5 | setup do 6 | repo.init 7 | File.open("config.rb", "w") do |file| 8 | file.puts("This is the initial config file") 9 | end 10 | 11 | repo.add("config.rb") 12 | repo.commit_all("Added initial config file") 13 | 14 | File.open("config.rb", "a") do |file| 15 | file.puts("These are changed you don't want to keep!") 16 | end 17 | system "git branch -m master" 18 | end 19 | 20 | solution do 21 | repo.status.files["config.rb"].type != "M" && repo.commits.length == 1 22 | end 23 | 24 | hint do 25 | puts "You will need to do some research on the checkout command for this one." 26 | end 27 | -------------------------------------------------------------------------------- /levels/checkout_tag.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | 3 | description "You need to fix a bug in the version 1.2 of your app. Checkout the tag `v1.2`." 4 | 5 | setup do 6 | repo.init 7 | FileUtils.touch("app.rb") 8 | repo.add("app.rb") 9 | repo.commit_all("Initial commit") 10 | 11 | `echo "Some code" >> app.rb` 12 | repo.add("app.rb") 13 | repo.commit_all("Some changes") 14 | repo.git.tag( { 'f' => true }, "v1.0" ) 15 | 16 | `echo "Buggy code" >> app.rb` 17 | repo.add("app.rb") 18 | repo.commit_all("Some more changes") 19 | repo.git.tag( { 'f' => true }, "v1.2" ) 20 | 21 | `echo "More code" >> app.rb` 22 | repo.add("app.rb") 23 | repo.commit_all("Yet more changes") 24 | 25 | `echo "Some more code" >> app.rb` 26 | repo.add("app.rb") 27 | repo.commit_all("Changes galore") 28 | repo.git.tag( { 'f' => true }, "v1.5" ) 29 | 30 | system "git branch -m master" 31 | end 32 | 33 | solution do 34 | return false unless repo.commits.length == 5 35 | return false unless `git show HEAD --format=%s` =~ /Some more changes/ 36 | true 37 | end 38 | 39 | hint do 40 | puts "There's no big difference between checking out a branch and checking out a tag." 41 | end 42 | -------------------------------------------------------------------------------- /levels/checkout_tag_over_branch.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | 3 | 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`)." 4 | 5 | setup do 6 | repo.init 7 | FileUtils.touch("app.rb") 8 | repo.add("app.rb") 9 | repo.commit_all("Initial commit") 10 | system "git branch -m master" 11 | 12 | `echo "Some code" >> app.rb` 13 | repo.add("app.rb") 14 | repo.commit_all("Some changes") 15 | repo.git.tag( { 'f' => true }, "v1.0" ) 16 | 17 | `echo "Buggy code" >> app.rb` 18 | repo.add("app.rb") 19 | repo.commit_all("Some more changes") 20 | repo.git.tag( { 'f' => true }, "v1.2" ) 21 | 22 | `echo "More code" >> app.rb` 23 | repo.add("app.rb") 24 | repo.commit_all("Yet more changes") 25 | 26 | `echo "Some more code" >> app.rb` 27 | repo.add("app.rb") 28 | repo.commit_all("Changes galore") 29 | repo.git.tag( { 'f' => true }, "v1.5" ) 30 | 31 | repo.git.native :checkout, {"b" => true}, 'v1.2' 32 | File.open("file3", 'w') { |f| f << "some feature\n" } 33 | repo.add "file3" 34 | repo.commit_all "Developing new features" 35 | 36 | repo.git.native :checkout, {}, 'master' 37 | end 38 | 39 | solution do 40 | return false unless repo.commits.length == 5 41 | return false unless `git show HEAD --format=%s` =~ /Some more changes/ 42 | true 43 | end 44 | 45 | hint do 46 | puts "You should think about specifying you're after the tag named `v1.2` (think `tags/`)." 47 | end 48 | -------------------------------------------------------------------------------- /levels/cherry-pick.rb: -------------------------------------------------------------------------------- 1 | difficulty 3 2 | 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." 3 | 4 | setup do 5 | init_from_level 6 | `git stash` # fix for README.md being in githug root an the level 7 | system "git branch -m master" 8 | end 9 | 10 | solution do 11 | return false unless repo.commits[1].message == "Added fancy branded output" 12 | return false unless repo.commits[0].message == "Filled in README.md with proper input" 13 | true 14 | end 15 | 16 | hint do 17 | puts "Sneak a peek at the `git help cherry-pick` command." 18 | end 19 | -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | some small fixes 2 | -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | ignorecase = true 7 | -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by "git commit" with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git update-server-info 9 | -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by "git commit" with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Redirect output to stderr. 22 | exec 1>&2 23 | 24 | # Cross platform projects tend to avoid non-ascii filenames; prevent 25 | # them from being added to the repository. We exploit the fact that the 26 | # printable range starts at the space character and ends with tilde. 27 | if [ "$allownonascii" != "true" ] && 28 | # Note that the use of brackets around a tr range is ok here, (it's 29 | # even required, for portability to Solaris 10's /usr/bin/tr), since 30 | # the square bracket bytes happen to fall in the designated range. 31 | test $(git diff --cached --name-only --diff-filter=A -z $against | 32 | LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 33 | then 34 | echo "Error: Attempt to add a non-ascii file name." 35 | echo 36 | echo "This can cause problems if you want to work" 37 | echo "with people on other platforms." 38 | echo 39 | echo "To be portable it is advisable to rename the file ..." 40 | echo 41 | echo "If you know what you are doing you can disable this" 42 | echo "check using:" 43 | echo 44 | echo " git config hooks.allownonascii true" 45 | echo 46 | exit 1 47 | fi 48 | 49 | # If there are whitespace errors, print the offending file names and fail. 50 | exec git diff-index --check --cached $against -- 51 | -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by "git commit" with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | /opt/local/bin/perl5.12 -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # /opt/local/bin/perl5.12 -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/index -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/info/exclude: -------------------------------------------------------------------------------- 1 | # git ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 ea3dbcc5e2d2359698c3606b0ec44af9f76def54 Andrey <aslushnikov@gmail.com> 1332886832 +0400 commit (initial): Initial commit 2 | ea3dbcc5e2d2359698c3606b0ec44af9f76def54 b30c6a965415df6aef5f2903f9892fa5481152fc Andrey <aslushnikov@gmail.com> 1332886882 +0400 commit: Added a hardcore math module 3 | b30c6a965415df6aef5f2903f9892fa5481152fc 232d266a78d5ef7196f1ede14972ccf7ee19e587 Andrey <aslushnikov@gmail.com> 1332886949 +0400 commit: Renamed project.js -> herdcore-math.js 4 | 232d266a78d5ef7196f1ede14972ccf7ee19e587 6edea632d9540e060bca97dda0897df2b7da0ec0 Andrey <aslushnikov@gmail.com> 1332887008 +0400 commit: Added fancy branded output 5 | -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/logs/refs/heads/new-feature: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 ea3dbcc5e2d2359698c3606b0ec44af9f76def54 Andrey <aslushnikov@gmail.com> 1332887030 +0400 branch: Created from HEAD 2 | ea3dbcc5e2d2359698c3606b0ec44af9f76def54 58a8c8edcfdd00c6d8cce9aada8f987a1677571f Andrey <aslushnikov@gmail.com> 1332887081 +0400 commit: Added a stub for the feature 3 | 58a8c8edcfdd00c6d8cce9aada8f987a1677571f cfd8ce38c22c5fe83cc04e23f94646464f20d990 Andrey <aslushnikov@gmail.com> 1332887151 +0400 commit: README.md 4 | cfd8ce38c22c5fe83cc04e23f94646464f20d990 ca32a6dac7b6f97975edbe19a4296c2ee7682f68 Andrey <aslushnikov@gmail.com> 1332887177 +0400 commit (amend): Filled in README.md with proper input 5 | ca32a6dac7b6f97975edbe19a4296c2ee7682f68 4a1961bce62840eaef9c4392fe5cc799e38c9b7b Andrey <aslushnikov@gmail.com> 1332887238 +0400 commit: Fixed feature 6 | 4a1961bce62840eaef9c4392fe5cc799e38c9b7b ea2a47c19b85fc321e2737ddc49db3deeba3a1b5 Andrey <aslushnikov@gmail.com> 1332887315 +0400 commit: some small fixes 7 | -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/05/aa97588aff673dcf00e0e1b835d6ec6207a7d9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/05/aa97588aff673dcf00e0e1b835d6ec6207a7d9 -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/14/ad8f1413c40e0e5be6f6cbdec392a783c1d754: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/14/ad8f1413c40e0e5be6f6cbdec392a783c1d754 -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/1b/912962174dd58fbbf1627ec816fa6672c70854: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/1b/912962174dd58fbbf1627ec816fa6672c70854 -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/22/f99f3abfd02190a760388c8845c190247859fe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/22/f99f3abfd02190a760388c8845c190247859fe -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/23/2d266a78d5ef7196f1ede14972ccf7ee19e587: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/23/2d266a78d5ef7196f1ede14972ccf7ee19e587 -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/31/68bdc3ae7e0ab987dda238beab9c0582c7fc07: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/31/68bdc3ae7e0ab987dda238beab9c0582c7fc07 -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/49/4fa3fc1c15986f9a950aba8607da591223614c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/49/4fa3fc1c15986f9a950aba8607da591223614c -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/4a/1961bce62840eaef9c4392fe5cc799e38c9b7b: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/4a/1961bce62840eaef9c4392fe5cc799e38c9b7b -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/54/22c2405527c05c23b243b2535a97b6cefa1427: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/54/22c2405527c05c23b243b2535a97b6cefa1427 -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/54/f3308533fd4400c94c4cd5827cd38036a67a76: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/54/f3308533fd4400c94c4cd5827cd38036a67a76 -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/58/a8c8edcfdd00c6d8cce9aada8f987a1677571f: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/58/a8c8edcfdd00c6d8cce9aada8f987a1677571f -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/6e/dea632d9540e060bca97dda0897df2b7da0ec0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/6e/dea632d9540e060bca97dda0897df2b7da0ec0 -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/85/4e7ac38b3e8df02ea1480ec45aa9e7865f03d7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/85/4e7ac38b3e8df02ea1480ec45aa9e7865f03d7 -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/93/3a97260a11a5ee49bb8a4b7b097cb2fb38f85c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/93/3a97260a11a5ee49bb8a4b7b097cb2fb38f85c -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/9a/e59e88e6af362c069847e621b971bafff158ac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/9a/e59e88e6af362c069847e621b971bafff158ac -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/a2/14badc644facc4722083aedf91d9339ffdffbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/a2/14badc644facc4722083aedf91d9339ffdffbf -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/b3/0c6a965415df6aef5f2903f9892fa5481152fc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/b3/0c6a965415df6aef5f2903f9892fa5481152fc -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/c6/0c612734f25b9c989d954621491e9ca3c9e061: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/c6/0c612734f25b9c989d954621491e9ca3c9e061 -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/ca/32a6dac7b6f97975edbe19a4296c2ee7682f68: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/ca/32a6dac7b6f97975edbe19a4296c2ee7682f68 -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/cf/d8ce38c22c5fe83cc04e23f94646464f20d990: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/cf/d8ce38c22c5fe83cc04e23f94646464f20d990 -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/d5/02e68bfe397140e4ac2a819b138545abca604e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/d5/02e68bfe397140e4ac2a819b138545abca604e -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/d5/123e58b37fd886dff2b96bfe5ec08a498192aa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/d5/123e58b37fd886dff2b96bfe5ec08a498192aa -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/ea/2a47c19b85fc321e2737ddc49db3deeba3a1b5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/ea/2a47c19b85fc321e2737ddc49db3deeba3a1b5 -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/objects/ea/3dbcc5e2d2359698c3606b0ec44af9f76def54: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/cherry-pick/.githug/objects/ea/3dbcc5e2d2359698c3606b0ec44af9f76def54 -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/refs/heads/master: -------------------------------------------------------------------------------- 1 | 6edea632d9540e060bca97dda0897df2b7da0ec0 2 | -------------------------------------------------------------------------------- /levels/cherry-pick/.githug/refs/heads/new-feature: -------------------------------------------------------------------------------- 1 | ea2a47c19b85fc321e2737ddc49db3deeba3a1b5 2 | -------------------------------------------------------------------------------- /levels/cherry-pick/README.md: -------------------------------------------------------------------------------- 1 | I'll fill in the file some time later.. 2 | 3 | -------------------------------------------------------------------------------- /levels/cherry-pick/hardcore-math.js: -------------------------------------------------------------------------------- 1 | for(var i = 0; i < 10; i++) { 2 | console.log(42 * i); 3 | } 4 | -------------------------------------------------------------------------------- /levels/cherry-pick/nokia.js: -------------------------------------------------------------------------------- 1 | console.log("[NOKIA] Connecting people"); 2 | -------------------------------------------------------------------------------- /levels/clone.rb: -------------------------------------------------------------------------------- 1 | difficulty 1 2 | description "Clone the repository at https://github.com/Gazler/cloneme." 3 | 4 | solution do 5 | repo("cloneme").commit("157b2b61f29ab9df45f31c7cd9cb5d8ff06ecde4") 6 | end 7 | 8 | hint do 9 | puts "You should have a look at this site: https://github.com/Gazler/cloneme." 10 | end 11 | -------------------------------------------------------------------------------- /levels/clone_to_folder.rb: -------------------------------------------------------------------------------- 1 | difficulty 1 2 | description "Clone the repository at https://github.com/Gazler/cloneme into the folder `my_cloned_repo`." 3 | 4 | solution do 5 | repo("my_cloned_repo").commit("157b2b61f29ab9df45f31c7cd9cb5d8ff06ecde4") 6 | end 7 | 8 | hint do 9 | puts "This is like the last level, `git clone` has an optional argument." 10 | end 11 | -------------------------------------------------------------------------------- /levels/commit.rb: -------------------------------------------------------------------------------- 1 | difficulty 1 2 | description "The `README` file has been added to your staging area, now commit it." 3 | 4 | setup do 5 | repo.init 6 | system "git branch -m master" 7 | FileUtils.touch("README") 8 | repo.add("README") 9 | end 10 | 11 | solution do 12 | return false if repo.commits.empty? 13 | true 14 | end 15 | 16 | hint do 17 | puts "You must include a message when you commit." 18 | end 19 | -------------------------------------------------------------------------------- /levels/commit_amend.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 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." 3 | 4 | setup do 5 | repo.init 6 | FileUtils.touch("README") 7 | repo.add("README") 8 | repo.commit_all("Initial commit") 9 | FileUtils.touch("forgotten_file.rb") 10 | system "git branch -m master" 11 | end 12 | 13 | solution do 14 | # Reset config - see issue #74 15 | file = File.open(".git/config", "w") do |file| 16 | file.puts("[format]") 17 | file.puts(" pretty = medium") 18 | end 19 | repo.commits.length == 1 && Grit::CommitStats.find_all(repo, repo.commits.first.sha).first[1].files.length == 2 20 | end 21 | 22 | hint do 23 | puts "Running `git commit --help` will display the man page and possible flags." 24 | end 25 | -------------------------------------------------------------------------------- /levels/commit_in_future.rb: -------------------------------------------------------------------------------- 1 | require 'time' 2 | 3 | difficulty 2 4 | description "Commit your changes with the future date (e.g. tomorrow)." 5 | 6 | setup do 7 | repo.init 8 | 9 | FileUtils.touch("README") 10 | repo.add("README") 11 | system "git branch -m master" 12 | end 13 | 14 | solution do 15 | repo.commits.length == 1 && repo.commits.first.authored_date > Time.now 16 | end 17 | 18 | hint do 19 | puts "Build a time format, and commit your code using --date parameter for \"future\"." 20 | end 21 | -------------------------------------------------------------------------------- /levels/config.rb: -------------------------------------------------------------------------------- 1 | difficulty 1 2 | description "Set up your git name and email; this is important so that your commits can be identified." 3 | 4 | setup do 5 | repo.init 6 | end 7 | 8 | solution do 9 | valid = false 10 | 11 | name = request("What is your name?") 12 | email = request("What is your email?") 13 | config_name = repo.config["user.name"] 14 | config_email = repo.config["user.email"] 15 | 16 | if name.respond_to?(:force_encoding) 17 | config_name = config_name.force_encoding("UTF-8") 18 | config_email = config_email.force_encoding("UTF-8") 19 | end 20 | 21 | if name == config_name && email == config_email 22 | valid = true 23 | end 24 | 25 | puts "Your config has the following name: #{config_name}" 26 | puts "Your config has the following email: #{config_email}" 27 | 28 | valid 29 | end 30 | 31 | hint do 32 | puts "These settings are config settings. You should run `git help config` if you are stuck." 33 | end 34 | -------------------------------------------------------------------------------- /levels/conflict.rb: -------------------------------------------------------------------------------- 1 | difficulty 4 2 | 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." 3 | 4 | setup do 5 | init_from_level 6 | system "git branch -m master" 7 | end 8 | 9 | solution do 10 | solved = true 11 | 12 | solved = false unless repo.head.name == "master" 13 | solved = false unless repo.commits("master")[0].parents.length == 2 14 | 15 | txt = File.read("poem.txt") 16 | solved = false if txt =~ /[<>=|]/ 17 | solved = false unless txt =~ /Sat on a wall/ 18 | 19 | solved 20 | end 21 | 22 | hint do 23 | 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."] 24 | end 25 | -------------------------------------------------------------------------------- /levels/conflict/.githug/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | Updated the poem 2 | 3 | # Please enter the commit message for your changes. Lines starting 4 | # with '#' will be ignored, and an empty message aborts the commit. 5 | # 6 | # Author: Thameera Senanayaka <thameera123@gmail.com> 7 | # Committer: Alex <snooz@localhost.localdomain> 8 | # 9 | # On branch master 10 | # Changes to be committed: 11 | # (use "git reset HEAD^1 <file>..." to unstage) 12 | # 13 | # modified: poem.txt 14 | # 15 | -------------------------------------------------------------------------------- /levels/conflict/.githug/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /levels/conflict/.githug/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | -------------------------------------------------------------------------------- /levels/conflict/.githug/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /levels/conflict/.githug/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /levels/conflict/.githug/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by "git commit" with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /levels/conflict/.githug/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git update-server-info 9 | -------------------------------------------------------------------------------- /levels/conflict/.githug/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /levels/conflict/.githug/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by "git commit" with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Redirect output to stderr. 22 | exec 1>&2 23 | 24 | # Cross platform projects tend to avoid non-ascii filenames; prevent 25 | # them from being added to the repository. We exploit the fact that the 26 | # printable range starts at the space character and ends with tilde. 27 | if [ "$allownonascii" != "true" ] && 28 | # Note that the use of brackets around a tr range is ok here, (it's 29 | # even required, for portability to Solaris 10's /usr/bin/tr), since 30 | # the square bracket bytes happen to fall in the designated range. 31 | test $(git diff --cached --name-only --diff-filter=A -z $against | 32 | LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 33 | then 34 | echo "Error: Attempt to add a non-ascii file name." 35 | echo 36 | echo "This can cause problems if you want to work" 37 | echo "with people on other platforms." 38 | echo 39 | echo "To be portable it is advisable to rename the file ..." 40 | echo 41 | echo "If you know what you are doing you can disable this" 42 | echo "check using:" 43 | echo 44 | echo " git config hooks.allownonascii true" 45 | echo 46 | exit 1 47 | fi 48 | 49 | # If there are whitespace errors, print the offending file names and fail. 50 | exec git diff-index --check --cached $against -- 51 | -------------------------------------------------------------------------------- /levels/conflict/.githug/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by "git commit" with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # /usr/bin/perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /levels/conflict/.githug/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/index -------------------------------------------------------------------------------- /levels/conflict/.githug/info/exclude: -------------------------------------------------------------------------------- 1 | # git ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /levels/conflict/.githug/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 306868e3258be1f35ae43db71e3a6d7edf42ffe7 Thameera Senanayaka <thameera123@gmail.com> 1352041121 +0530 commit (initial): Initial commit 2 | 306868e3258be1f35ae43db71e3a6d7edf42ffe7 40e20a455ac2731ad25c297b03aa543d7eedf6ab Thameera Senanayaka <thameera123@gmail.com> 1352041153 +0530 commit: Added two lines 3 | 40e20a455ac2731ad25c297b03aa543d7eedf6ab 306868e3258be1f35ae43db71e3a6d7edf42ffe7 Thameera Senanayaka <thameera123@gmail.com> 1352041162 +0530 checkout: moving from master to mybranch 4 | 306868e3258be1f35ae43db71e3a6d7edf42ffe7 50a127cb066eb903a6fa59d71802c10cb442fb3b Thameera Senanayaka <thameera123@gmail.com> 1352041213 +0530 commit: Added lines 5 | 50a127cb066eb903a6fa59d71802c10cb442fb3b 75179304f4fab00613f08a9412b6cb0965bfa564 Thameera Senanayaka <thameera123@gmail.com> 1352041234 +0530 commit: Added comment 6 | 75179304f4fab00613f08a9412b6cb0965bfa564 40e20a455ac2731ad25c297b03aa543d7eedf6ab Thameera Senanayaka <thameera123@gmail.com> 1352041240 +0530 checkout: moving from mybranch to master 7 | 40e20a455ac2731ad25c297b03aa543d7eedf6ab 75179304f4fab00613f08a9412b6cb0965bfa564 Alex <snooz@localhost.localdomain> 1382868220 -0700 checkout: moving from master to mybranch 8 | 75179304f4fab00613f08a9412b6cb0965bfa564 bdc7bec8acae9b3eabf0a15b223a48211b7a89a1 Alex <snooz@localhost.localdomain> 1382868333 -0700 commit: Changed the poem 9 | bdc7bec8acae9b3eabf0a15b223a48211b7a89a1 3d7aec017559be2b61cab850dafdcb2b6212f1c3 Alex <snooz@localhost.localdomain> 1382868450 -0700 commit (amend): Changed the poem 10 | 3d7aec017559be2b61cab850dafdcb2b6212f1c3 40e20a455ac2731ad25c297b03aa543d7eedf6ab Alex <snooz@localhost.localdomain> 1382868483 -0700 checkout: moving from mybranch to master 11 | 40e20a455ac2731ad25c297b03aa543d7eedf6ab 30cc28e66966109bb5bfbe96d6c817c367d2050a Alex <snooz@localhost.localdomain> 1382868518 -0700 commit: Updated the poem 12 | 30cc28e66966109bb5bfbe96d6c817c367d2050a c797f979cf24ba148bf10d5e26f5d7402dd5f2e1 Alex <snooz@localhost.localdomain> 1382868533 -0700 commit (amend): Updated the poem 13 | -------------------------------------------------------------------------------- /levels/conflict/.githug/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 306868e3258be1f35ae43db71e3a6d7edf42ffe7 Thameera Senanayaka <thameera123@gmail.com> 1352041121 +0530 commit (initial): Initial commit 2 | 306868e3258be1f35ae43db71e3a6d7edf42ffe7 40e20a455ac2731ad25c297b03aa543d7eedf6ab Thameera Senanayaka <thameera123@gmail.com> 1352041153 +0530 commit: Added two lines 3 | 40e20a455ac2731ad25c297b03aa543d7eedf6ab 30cc28e66966109bb5bfbe96d6c817c367d2050a Alex <snooz@localhost.localdomain> 1382868518 -0700 commit: Updated the poem 4 | 30cc28e66966109bb5bfbe96d6c817c367d2050a c797f979cf24ba148bf10d5e26f5d7402dd5f2e1 Alex <snooz@localhost.localdomain> 1382868533 -0700 commit (amend): Updated the poem 5 | -------------------------------------------------------------------------------- /levels/conflict/.githug/logs/refs/heads/mybranch: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 306868e3258be1f35ae43db71e3a6d7edf42ffe7 Thameera Senanayaka <thameera123@gmail.com> 1352041133 +0530 branch: Created from master 2 | 306868e3258be1f35ae43db71e3a6d7edf42ffe7 50a127cb066eb903a6fa59d71802c10cb442fb3b Thameera Senanayaka <thameera123@gmail.com> 1352041213 +0530 commit: Added lines 3 | 50a127cb066eb903a6fa59d71802c10cb442fb3b 75179304f4fab00613f08a9412b6cb0965bfa564 Thameera Senanayaka <thameera123@gmail.com> 1352041234 +0530 commit: Added comment 4 | 75179304f4fab00613f08a9412b6cb0965bfa564 bdc7bec8acae9b3eabf0a15b223a48211b7a89a1 Alex <snooz@localhost.localdomain> 1382868333 -0700 commit: Changed the poem 5 | bdc7bec8acae9b3eabf0a15b223a48211b7a89a1 3d7aec017559be2b61cab850dafdcb2b6212f1c3 Alex <snooz@localhost.localdomain> 1382868450 -0700 commit (amend): Changed the poem 6 | -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/1d/b9aa5013e47f1482ec90323d926171a99c28af: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/1d/b9aa5013e47f1482ec90323d926171a99c28af -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/25/b3f9c339430b35ae5822b2ef90e763284dc007: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/25/b3f9c339430b35ae5822b2ef90e763284dc007 -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/2d/0d90051e320215f54f357e746c9838490557e7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/2d/0d90051e320215f54f357e746c9838490557e7 -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/30/6868e3258be1f35ae43db71e3a6d7edf42ffe7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/30/6868e3258be1f35ae43db71e3a6d7edf42ffe7 -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/30/cc28e66966109bb5bfbe96d6c817c367d2050a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/30/cc28e66966109bb5bfbe96d6c817c367d2050a -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/38/21e4362c5a76db1112b46b9210670cd5bab482: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/38/21e4362c5a76db1112b46b9210670cd5bab482 -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/3c/b65bef44ae724ddf9e89640e7e2754dea1a47f: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/3c/b65bef44ae724ddf9e89640e7e2754dea1a47f -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/3d/7aec017559be2b61cab850dafdcb2b6212f1c3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/3d/7aec017559be2b61cab850dafdcb2b6212f1c3 -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/40/e20a455ac2731ad25c297b03aa543d7eedf6ab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/40/e20a455ac2731ad25c297b03aa543d7eedf6ab -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/44/30fd3f45c832e685350417600a9862c94d20f1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/44/30fd3f45c832e685350417600a9862c94d20f1 -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/46/677964e679f3e727356d0860c643a12a87902b: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/46/677964e679f3e727356d0860c643a12a87902b -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/50/a127cb066eb903a6fa59d71802c10cb442fb3b: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/50/a127cb066eb903a6fa59d71802c10cb442fb3b -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/55/ad5af2a93afa778971e3d04faf20f6c368b6ba: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/55/ad5af2a93afa778971e3d04faf20f6c368b6ba -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/6b/0c0b32bdca3af9beb831744cb755d6fdc7c7c0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/6b/0c0b32bdca3af9beb831744cb755d6fdc7c7c0 -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/75/179304f4fab00613f08a9412b6cb0965bfa564: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/75/179304f4fab00613f08a9412b6cb0965bfa564 -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/7c/36daf29660ae4a2f09345427ef76f1d38f902f: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/7c/36daf29660ae4a2f09345427ef76f1d38f902f -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/88/e0473c9da347c6311f5f8eca8d256bf25402b6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/88/e0473c9da347c6311f5f8eca8d256bf25402b6 -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/bd/c7bec8acae9b3eabf0a15b223a48211b7a89a1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/bd/c7bec8acae9b3eabf0a15b223a48211b7a89a1 -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/c7/97f979cf24ba148bf10d5e26f5d7402dd5f2e1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/c7/97f979cf24ba148bf10d5e26f5d7402dd5f2e1 -------------------------------------------------------------------------------- /levels/conflict/.githug/objects/da/ae380200ed6eeaafd926177018e8ff3009b988: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/conflict/.githug/objects/da/ae380200ed6eeaafd926177018e8ff3009b988 -------------------------------------------------------------------------------- /levels/conflict/.githug/refs/heads/master: -------------------------------------------------------------------------------- 1 | c797f979cf24ba148bf10d5e26f5d7402dd5f2e1 2 | -------------------------------------------------------------------------------- /levels/conflict/.githug/refs/heads/mybranch: -------------------------------------------------------------------------------- 1 | 3d7aec017559be2b61cab850dafdcb2b6212f1c3 2 | -------------------------------------------------------------------------------- /levels/conflict/poem.txt: -------------------------------------------------------------------------------- 1 | Humpty dumpty 2 | Categorized shoes by color 3 | Humpty dumpty 4 | Had a great fall 5 | 6 | -------------------------------------------------------------------------------- /levels/contribute.rb: -------------------------------------------------------------------------------- 1 | difficulty 3 2 | 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." 3 | 4 | solution do 5 | location = "/tmp/githug" 6 | FileUtils.rm_rf(location) 7 | puts "Cloning repository to #{location}" 8 | `git clone https://github.com/Gazler/githug #{location}` 9 | 10 | contributor = false 11 | 12 | repo = Grit::Repo.new(location) 13 | repo.commits('master', false).each do |commit| 14 | if commit.author.name == repo.config["user.name"] 15 | if commit.author.email == repo.config["user.email"] 16 | contributor = true 17 | end 18 | end 19 | end 20 | contributor 21 | end 22 | 23 | hint do 24 | puts "Forking the repository would be a good start!" 25 | end 26 | -------------------------------------------------------------------------------- /levels/delete_branch.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | 3 | 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." 4 | 5 | setup do 6 | init_from_level 7 | system "git branch -m master" 8 | end 9 | 10 | solution do 11 | return true unless repo.branches.map(&:name).include?('delete_me') 12 | end 13 | 14 | hint do 15 | puts "Running 'git --help branch' will give you a list of branch commands." 16 | end 17 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | delete_me branch 2 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | ignorecase = true 7 | precomposeunicode = false 8 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by "git commit" with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git update-server-info 9 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by "git commit" with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ASCII filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Redirect output to stderr. 22 | exec 1>&2 23 | 24 | # Cross platform projects tend to avoid non-ASCII filenames; prevent 25 | # them from being added to the repository. We exploit the fact that the 26 | # printable range starts at the space character and ends with tilde. 27 | if [ "$allownonascii" != "true" ] && 28 | # Note that the use of brackets around a tr range is ok here, (it's 29 | # even required, for portability to Solaris 10's /usr/bin/tr), since 30 | # the square bracket bytes happen to fall in the designated range. 31 | test $(git diff --cached --name-only --diff-filter=A -z $against | 32 | LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 33 | then 34 | cat <<\EOF 35 | Error: Attempt to add a non-ASCII file name. 36 | 37 | This can cause problems if you want to work with people on other platforms. 38 | 39 | To be portable it is advisable to rename the file. 40 | 41 | If you know what you are doing you can disable this check using: 42 | 43 | git config hooks.allownonascii true 44 | EOF 45 | exit 1 46 | fi 47 | 48 | # If there are whitespace errors, print the offending file names and fail. 49 | exec git diff-index --check --cached $against -- 50 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/hooks/pre-push.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # An example hook script to verify what is about to be pushed. Called by "git 4 | # push" after it has checked the remote status, but before anything has been 5 | # pushed. If this script exits with a non-zero status nothing will be pushed. 6 | # 7 | # This hook is called with the following parameters: 8 | # 9 | # $1 -- Name of the remote to which the push is being done 10 | # $2 -- URL to which the push is being done 11 | # 12 | # If pushing without using a named remote those arguments will be equal. 13 | # 14 | # Information about the commits which are being pushed is supplied as lines to 15 | # the standard input in the form: 16 | # 17 | # <local ref> <local sha1> <remote ref> <remote sha1> 18 | # 19 | # This sample shows how to prevent push of commits where the log message starts 20 | # with "WIP" (work in progress). 21 | 22 | remote="$1" 23 | url="$2" 24 | 25 | z40=0000000000000000000000000000000000000000 26 | 27 | IFS=' ' 28 | while read local_ref local_sha remote_ref remote_sha 29 | do 30 | if [ "$local_sha" = $z40 ] 31 | then 32 | # Handle delete 33 | else 34 | if [ "$remote_sha" = $z40 ] 35 | then 36 | # New branch, examine all commits 37 | range="$local_sha" 38 | else 39 | # Update to existing branch, examine new commits 40 | range="$remote_sha..$local_sha" 41 | fi 42 | 43 | # Check for WIP commit 44 | commit=`git rev-list -n 1 --grep '^WIP' "$range"` 45 | if [ -n "$commit" ] 46 | then 47 | echo "Found WIP commit in $local_ref, not pushing" 48 | exit 1 49 | fi 50 | fi 51 | done 52 | 53 | exit 0 54 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by "git commit" with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # /usr/bin/perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/delete_branch/.githug/index -------------------------------------------------------------------------------- /levels/delete_branch/.githug/info/exclude: -------------------------------------------------------------------------------- 1 | # git ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 b60afe294eb3c200d646995c9e0234470157c1b0 Daniel Smilansky <dsmilansky@gmail.com> 1386225561 -0800 commit (initial): first commit 2 | b60afe294eb3c200d646995c9e0234470157c1b0 b60afe294eb3c200d646995c9e0234470157c1b0 Daniel Smilansky <dsmilansky@gmail.com> 1386225573 -0800 checkout: moving from master to master 3 | b60afe294eb3c200d646995c9e0234470157c1b0 b60afe294eb3c200d646995c9e0234470157c1b0 Daniel Smilansky <dsmilansky@gmail.com> 1386225580 -0800 checkout: moving from master to delete_me 4 | b60afe294eb3c200d646995c9e0234470157c1b0 b60afe294eb3c200d646995c9e0234470157c1b0 Daniel Smilansky <dsmilansky@gmail.com> 1386225584 -0800 checkout: moving from delete_me to master 5 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/logs/refs/heads/delete_me: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 b60afe294eb3c200d646995c9e0234470157c1b0 Daniel Smilansky <dsmilansky@gmail.com> 1386225568 -0800 branch: Created from master 2 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 b60afe294eb3c200d646995c9e0234470157c1b0 Daniel Smilansky <dsmilansky@gmail.com> 1386225561 -0800 commit (initial): first commit 2 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/objects/b6/0afe294eb3c200d646995c9e0234470157c1b0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/delete_branch/.githug/objects/b6/0afe294eb3c200d646995c9e0234470157c1b0 -------------------------------------------------------------------------------- /levels/delete_branch/.githug/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/delete_branch/.githug/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 -------------------------------------------------------------------------------- /levels/delete_branch/.githug/objects/e8/0ad49ace82167de62e498622d70377d913c79e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/delete_branch/.githug/objects/e8/0ad49ace82167de62e498622d70377d913c79e -------------------------------------------------------------------------------- /levels/delete_branch/.githug/refs/heads/delete_me: -------------------------------------------------------------------------------- 1 | b60afe294eb3c200d646995c9e0234470157c1b0 2 | -------------------------------------------------------------------------------- /levels/delete_branch/.githug/refs/heads/master: -------------------------------------------------------------------------------- 1 | b60afe294eb3c200d646995c9e0234470157c1b0 2 | -------------------------------------------------------------------------------- /levels/delete_branch/readme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/delete_branch/readme -------------------------------------------------------------------------------- /levels/diff.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | description "Since your last commit, file `app.rb` was modified. Find out which line has changed." 3 | 4 | setup do 5 | init_from_level 6 | system "git branch -m master" 7 | end 8 | 9 | solution do 10 | line = request "What is the number of the line which has changed?" 11 | return false unless line == "26" 12 | true 13 | end 14 | 15 | hint do 16 | 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." 17 | end 18 | -------------------------------------------------------------------------------- /levels/diff/.githug/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | added app.rb 2 | -------------------------------------------------------------------------------- /levels/diff/.githug/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /levels/diff/.githug/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | -------------------------------------------------------------------------------- /levels/diff/.githug/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /levels/diff/.githug/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /levels/diff/.githug/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by "git commit" with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /levels/diff/.githug/hooks/post-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script that is called after a successful 4 | # commit is made. 5 | # 6 | # To enable this hook, rename this file to "post-commit". 7 | 8 | : Nothing 9 | -------------------------------------------------------------------------------- /levels/diff/.githug/hooks/post-receive.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script for the "post-receive" event. 4 | # 5 | # The "post-receive" script is run after receive-pack has accepted a pack 6 | # and the repository has been updated. It is passed arguments in through 7 | # stdin in the form 8 | # <oldrev> <newrev> <refname> 9 | # For example: 10 | # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master 11 | # 12 | # see contrib/hooks/ for a sample, or uncomment the next line and 13 | # rename the file to "post-receive". 14 | 15 | #. /usr/share/doc/git-core/contrib/hooks/post-receive-email 16 | -------------------------------------------------------------------------------- /levels/diff/.githug/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git update-server-info 9 | -------------------------------------------------------------------------------- /levels/diff/.githug/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /levels/diff/.githug/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by "git commit" with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Cross platform projects tend to avoid non-ascii filenames; prevent 22 | # them from being added to the repository. We exploit the fact that the 23 | # printable range starts at the space character and ends with tilde. 24 | if [ "$allownonascii" != "true" ] && 25 | # Note that the use of brackets around a tr range is ok here, (it's 26 | # even required, for portability to Solaris 10's /usr/bin/tr), since 27 | # the square bracket bytes happen to fall in the designated range. 28 | test "$(git diff --cached --name-only --diff-filter=A -z $against | 29 | LC_ALL=C tr -d '[ -~]\0')" 30 | then 31 | echo "Error: Attempt to add a non-ascii file name." 32 | echo 33 | echo "This can cause problems if you want to work" 34 | echo "with people on other platforms." 35 | echo 36 | echo "To be portable it is advisable to rename the file ..." 37 | echo 38 | echo "If you know what you are doing you can disable this" 39 | echo "check using:" 40 | echo 41 | echo " git config hooks.allownonascii true" 42 | echo 43 | exit 1 44 | fi 45 | 46 | exec git diff-index --check --cached $against -- 47 | -------------------------------------------------------------------------------- /levels/diff/.githug/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by "git commit" with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # /usr/bin/perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /levels/diff/.githug/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/diff/.githug/index -------------------------------------------------------------------------------- /levels/diff/.githug/info/exclude: -------------------------------------------------------------------------------- 1 | # git ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /levels/diff/.githug/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 dcaa55e97af34402e84d5336da37abcccc23cba6 Gary Rennie <webmaster@gazler.com> 1331585213 +0000 commit (initial): added app.rb 2 | -------------------------------------------------------------------------------- /levels/diff/.githug/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 dcaa55e97af34402e84d5336da37abcccc23cba6 Gary Rennie <webmaster@gazler.com> 1331585213 +0000 commit (initial): added app.rb 2 | -------------------------------------------------------------------------------- /levels/diff/.githug/objects/1b/6582364621c92707b587409cedbc4f77fc0cee: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/diff/.githug/objects/1b/6582364621c92707b587409cedbc4f77fc0cee -------------------------------------------------------------------------------- /levels/diff/.githug/objects/4f/703ca9bd25781b6758eeb3c42ed5348610ba6d: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/diff/.githug/objects/4f/703ca9bd25781b6758eeb3c42ed5348610ba6d -------------------------------------------------------------------------------- /levels/diff/.githug/objects/dc/aa55e97af34402e84d5336da37abcccc23cba6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/diff/.githug/objects/dc/aa55e97af34402e84d5336da37abcccc23cba6 -------------------------------------------------------------------------------- /levels/diff/.githug/refs/heads/master: -------------------------------------------------------------------------------- 1 | dcaa55e97af34402e84d5336da37abcccc23cba6 2 | -------------------------------------------------------------------------------- /levels/diff/app.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra' 2 | require 'oauth2' 3 | require 'json' 4 | enable :sessions 5 | 6 | def client 7 | OAuth2::Client.new("mTeZFqkCmzc8JnjKXaSww95bFFxhUpp1wwmSi8vG", "a9OMyEdW7JvWThHmmvFcShR9P2dyad3EGuA2ULDh", :site => "http://localhost:3000") 8 | end 9 | 10 | get "/auth/test" do 11 | redirect client.auth_code.authorize_url(:redirect_uri => redirect_uri) 12 | end 13 | 14 | get '/auth/test/callback' do 15 | access_token = client.auth_code.get_token(params[:code], :redirect_uri => redirect_uri) 16 | session[:access_token] = access_token.token 17 | @message = "Successfully authenticated with the server" 18 | erb :success 19 | end 20 | 21 | get '/yet_another' do 22 | @message = get_response('data.json') 23 | erb :success 24 | end 25 | get '/another_page' do 26 | @message = get_response('server.json') 27 | erb :another 28 | end 29 | 30 | def get_response(url) 31 | access_token = OAuth2::AccessToken.new(client, session[:access_token]) 32 | JSON.parse(access_token.get("/api/v1/#{url}").body) 33 | end 34 | 35 | 36 | def redirect_uri 37 | uri = URI.parse(request.url) 38 | uri.path = '/auth/test/callback' 39 | uri.query = nil 40 | uri.to_s 41 | end 42 | 43 | -------------------------------------------------------------------------------- /levels/fetch.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | description "Looks like a new branch was pushed into our remote repository. Get the changes without merging them with the local repository " 3 | 4 | setup do 5 | # remember the working directory so we can come back to it later 6 | cwd = Dir.pwd 7 | # initialize another git repo to be used as a "remote" 8 | tmpdir = Dir.mktmpdir 9 | 10 | # local repo 11 | repo.init 12 | system "git branch -m master" 13 | 14 | # adds a file to origin/master 15 | FileUtils.touch "master_file" 16 | repo.add "master_file" 17 | repo.commit_all 'Commits master_file' 18 | 19 | # remote repo 20 | Dir.chdir tmpdir 21 | repo.init 22 | 23 | # adds a file to origin/master 24 | FileUtils.touch "master_file" 25 | repo.add "master_file" 26 | repo.commit_all 'Commits master_file' 27 | 28 | # adds remote repo 29 | Dir.chdir cwd 30 | `git remote add origin #{tmpdir}/.git` 31 | `git fetch origin --quiet` 32 | `git branch -u origin/master master 2> /dev/null` 33 | 34 | Dir.chdir tmpdir 35 | # create a new branch in the remote repo 36 | `git checkout -b new_branch --quiet` 37 | 38 | # adds a file into the new branch. Should not be pulled into the local 39 | FileUtils.touch "file1" 40 | repo.add "file1" 41 | repo.commit_all 'Commits file 1' 42 | 43 | end 44 | 45 | solution do 46 | repo.init 47 | result = true 48 | 49 | # counts the number of local branches. Should equal 1 50 | local_branches = repo.branches.size 51 | 52 | # after a git fetch command, each branch will be stored in in the .git/FETCH_HEAD file. Each branch is on its own line 53 | # This command will count the number of lines, which will give the number of branches 54 | if File.file?('.git/FETCH_HEAD') # checks for file existence 55 | num_remote = File.read(".git/FETCH_HEAD").split("\n").count 56 | else 57 | num_remote = 0 58 | end 59 | 60 | # there should be 1 local branch and 2 remote branches for a success condition 61 | if local_branches == 1 and num_remote == 2 62 | result = true 63 | else 64 | result = false 65 | end 66 | end 67 | 68 | hint do 69 | puts "Look up the 'git fetch' command" 70 | end 71 | -------------------------------------------------------------------------------- /levels/find_old_branch.rb: -------------------------------------------------------------------------------- 1 | difficulty 4 2 | 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." 3 | 4 | setup do 5 | init_from_level 6 | system "git branch -m master" 7 | end 8 | 9 | solution do 10 | return false unless repo.head.name == "solve_world_hunger" 11 | true 12 | end 13 | 14 | hint do 15 | puts "Ever played with the `git reflog` command?" 16 | end 17 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | commit another todo 2 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/kill_the_batman 2 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/ORIG_HEAD: -------------------------------------------------------------------------------- 1 | 05e9c01bd3c9264761dd0cde477400a2c3104642 2 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | ignorecase = true 7 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by "git commit" with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/hooks/post-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script that is called after a successful 4 | # commit is made. 5 | # 6 | # To enable this hook, rename this file to "post-commit". 7 | 8 | : Nothing 9 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/hooks/post-receive.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script for the "post-receive" event. 4 | # 5 | # The "post-receive" script is run after receive-pack has accepted a pack 6 | # and the repository has been updated. It is passed arguments in through 7 | # stdin in the form 8 | # <oldrev> <newrev> <refname> 9 | # For example: 10 | # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master 11 | # 12 | # see contrib/hooks/ for a sample, or uncomment the next line and 13 | # rename the file to "post-receive". 14 | 15 | #. /usr/share/doc/git-core/contrib/hooks/post-receive-email 16 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git update-server-info 9 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by "git commit" with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Redirect output to stderr. 22 | exec 1>&2 23 | 24 | # Cross platform projects tend to avoid non-ascii filenames; prevent 25 | # them from being added to the repository. We exploit the fact that the 26 | # printable range starts at the space character and ends with tilde. 27 | if [ "$allownonascii" != "true" ] && 28 | # Note that the use of brackets around a tr range is ok here, (it's 29 | # even required, for portability to Solaris 10's /usr/bin/tr), since 30 | # the square bracket bytes happen to fall in the designated range. 31 | test $(git diff --cached --name-only --diff-filter=A -z $against | 32 | LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 33 | then 34 | echo "Error: Attempt to add a non-ascii file name." 35 | echo 36 | echo "This can cause problems if you want to work" 37 | echo "with people on other platforms." 38 | echo 39 | echo "To be portable it is advisable to rename the file ..." 40 | echo 41 | echo "If you know what you are doing you can disable this" 42 | echo "check using:" 43 | echo 44 | echo " git config hooks.allownonascii true" 45 | echo 46 | exit 1 47 | fi 48 | 49 | # If there are whitespace errors, print the offending file names and fail. 50 | exec git diff-index --check --cached $against -- 51 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by "git commit" with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # /usr/bin/perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/find_old_branch/.githug/index -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/info/exclude: -------------------------------------------------------------------------------- 1 | # git ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | .DS_Store 8 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283192 -0600 commit (initial): initial commit 2 | 6876e5b41fb693190df76b1baef6ef98623b4f1a 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283224 -0600 checkout: moving from cure_common_cold to kill_the_batman 3 | 6876e5b41fb693190df76b1baef6ef98623b4f1a 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283240 -0600 checkout: moving from kill_the_batman to blowup_sun_for_ransom 4 | 6876e5b41fb693190df76b1baef6ef98623b4f1a 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283272 -0600 checkout: moving from blowup_sun_for_ransom to solve_world_hunger 5 | 6876e5b41fb693190df76b1baef6ef98623b4f1a 324336a8401afc8ca384eaafe6615c84d552dd2c mcramm <GMCramm@gmail.com> 1332283302 -0600 commit: commit todo 6 | 324336a8401afc8ca384eaafe6615c84d552dd2c 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283316 -0600 checkout: moving from solve_world_hunger to kill_the_batman 7 | 6876e5b41fb693190df76b1baef6ef98623b4f1a 894a16d6f1a48224e9006b4a6f0fe3846da19bec mcramm <GMCramm@gmail.com> 1332283505 -0600 commit: commit another todo 8 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/logs/refs/heads/blowup_sun_for_ransom: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283240 -0600 branch: Created from HEAD 2 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/logs/refs/heads/cure_common_cold: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283192 -0600 commit (initial): initial commit 2 | 6876e5b41fb693190df76b1baef6ef98623b4f1a 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283208 -0600 Branch: renamed refs/heads/master to refs/heads/cure_common_cold 3 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/logs/refs/heads/kill_the_batman: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283224 -0600 branch: Created from HEAD 2 | 6876e5b41fb693190df76b1baef6ef98623b4f1a 05e9c01bd3c9264761dd0cde477400a2c3104642 mcramm <GMCramm@gmail.com> 1332283348 -0600 commit: commit todo 3 | 05e9c01bd3c9264761dd0cde477400a2c3104642 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283385 -0600 reset: moving to HEAD~ 4 | 6876e5b41fb693190df76b1baef6ef98623b4f1a 894a16d6f1a48224e9006b4a6f0fe3846da19bec mcramm <GMCramm@gmail.com> 1332283505 -0600 commit: commit another todo 5 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/logs/refs/heads/solve_world_hunger: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 6876e5b41fb693190df76b1baef6ef98623b4f1a mcramm <GMCramm@gmail.com> 1332283272 -0600 branch: Created from HEAD 2 | 6876e5b41fb693190df76b1baef6ef98623b4f1a 324336a8401afc8ca384eaafe6615c84d552dd2c mcramm <GMCramm@gmail.com> 1332283302 -0600 commit: commit todo 3 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/objects/05/e9c01bd3c9264761dd0cde477400a2c3104642: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/find_old_branch/.githug/objects/05/e9c01bd3c9264761dd0cde477400a2c3104642 -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/objects/1f/0a136ddd98f61934d15eb00444df32d8e8254b: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/find_old_branch/.githug/objects/1f/0a136ddd98f61934d15eb00444df32d8e8254b -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/objects/32/4336a8401afc8ca384eaafe6615c84d552dd2c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/find_old_branch/.githug/objects/32/4336a8401afc8ca384eaafe6615c84d552dd2c -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/objects/50/72aab6bd73accec89ad3aa077f43aab8a5e507: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/find_old_branch/.githug/objects/50/72aab6bd73accec89ad3aa077f43aab8a5e507 -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/objects/5d/130caf89f1a4bba6a1fffe72c484f3ab659e08: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/find_old_branch/.githug/objects/5d/130caf89f1a4bba6a1fffe72c484f3ab659e08 -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/objects/68/76e5b41fb693190df76b1baef6ef98623b4f1a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/find_old_branch/.githug/objects/68/76e5b41fb693190df76b1baef6ef98623b4f1a -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/objects/6a/7702145d1eb91c9f79583eabb984027b12e60c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/find_old_branch/.githug/objects/6a/7702145d1eb91c9f79583eabb984027b12e60c -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/objects/89/4a16d6f1a48224e9006b4a6f0fe3846da19bec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/find_old_branch/.githug/objects/89/4a16d6f1a48224e9006b4a6f0fe3846da19bec -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/objects/b8/c67b45e5fe9e4b39ac7ade725673f7c90bdfc3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/find_old_branch/.githug/objects/b8/c67b45e5fe9e4b39ac7ade725673f7c90bdfc3 -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/objects/bf/76434bc7e7346c6fef5a98aee0f7cfc0788f34: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/find_old_branch/.githug/objects/bf/76434bc7e7346c6fef5a98aee0f7cfc0788f34 -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/refs/heads/blowup_sun_for_ransom: -------------------------------------------------------------------------------- 1 | 6876e5b41fb693190df76b1baef6ef98623b4f1a 2 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/refs/heads/cure_common_cold: -------------------------------------------------------------------------------- 1 | 6876e5b41fb693190df76b1baef6ef98623b4f1a 2 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/refs/heads/kill_the_batman: -------------------------------------------------------------------------------- 1 | 894a16d6f1a48224e9006b4a6f0fe3846da19bec 2 | -------------------------------------------------------------------------------- /levels/find_old_branch/.githug/refs/heads/solve_world_hunger: -------------------------------------------------------------------------------- 1 | 324336a8401afc8ca384eaafe6615c84d552dd2c 2 | -------------------------------------------------------------------------------- /levels/find_old_branch/TODO: -------------------------------------------------------------------------------- 1 | FIND THE JOKER 2 | -------------------------------------------------------------------------------- /levels/find_old_branch/myfile.txt: -------------------------------------------------------------------------------- 1 | THIS TEXT DOESN'T MATTER 2 | -------------------------------------------------------------------------------- /levels/grep.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | description "Your project's deadline approaches, you should evaluate how many TODOs are left in your code" 3 | 4 | setup do 5 | init_from_level 6 | system "git branch -m master" 7 | end 8 | 9 | solution do 10 | request("How many items are there in your todolist?") == "4" 11 | end 12 | 13 | hint do 14 | puts "You want to research the `git grep` command." 15 | end 16 | -------------------------------------------------------------------------------- /levels/grep/.githug/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | Add application files. 2 | -------------------------------------------------------------------------------- /levels/grep/.githug/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /levels/grep/.githug/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | ignorecase = true 7 | -------------------------------------------------------------------------------- /levels/grep/.githug/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /levels/grep/.githug/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /levels/grep/.githug/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by "git commit" with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /levels/grep/.githug/hooks/post-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script that is called after a successful 4 | # commit is made. 5 | # 6 | # To enable this hook, rename this file to "post-commit". 7 | 8 | : Nothing 9 | -------------------------------------------------------------------------------- /levels/grep/.githug/hooks/post-receive.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script for the "post-receive" event. 4 | # 5 | # The "post-receive" script is run after receive-pack has accepted a pack 6 | # and the repository has been updated. It is passed arguments in through 7 | # stdin in the form 8 | # <oldrev> <newrev> <refname> 9 | # For example: 10 | # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master 11 | # 12 | # see contrib/hooks/ for a sample, or uncomment the next line and 13 | # rename the file to "post-receive". 14 | 15 | #. /usr/share/doc/git-core/contrib/hooks/post-receive-email 16 | -------------------------------------------------------------------------------- /levels/grep/.githug/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git update-server-info 9 | -------------------------------------------------------------------------------- /levels/grep/.githug/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /levels/grep/.githug/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by "git commit" with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Cross platform projects tend to avoid non-ascii filenames; prevent 22 | # them from being added to the repository. We exploit the fact that the 23 | # printable range starts at the space character and ends with tilde. 24 | if [ "$allownonascii" != "true" ] && 25 | # Note that the use of brackets around a tr range is ok here, (it's 26 | # even required, for portability to Solaris 10's /usr/bin/tr), since 27 | # the square bracket bytes happen to fall in the designated range. 28 | test "$(git diff --cached --name-only --diff-filter=A -z $against | 29 | LC_ALL=C tr -d '[ -~]\0')" 30 | then 31 | echo "Error: Attempt to add a non-ascii file name." 32 | echo 33 | echo "This can cause problems if you want to work" 34 | echo "with people on other platforms." 35 | echo 36 | echo "To be portable it is advisable to rename the file ..." 37 | echo 38 | echo "If you know what you are doing you can disable this" 39 | echo "check using:" 40 | echo 41 | echo " git config hooks.allownonascii true" 42 | echo 43 | exit 1 44 | fi 45 | 46 | exec git diff-index --check --cached $against -- 47 | -------------------------------------------------------------------------------- /levels/grep/.githug/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by "git commit" with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # /usr/bin/perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /levels/grep/.githug/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/grep/.githug/index -------------------------------------------------------------------------------- /levels/grep/.githug/info/exclude: -------------------------------------------------------------------------------- 1 | # git ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /levels/grep/.githug/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 12c702f8b25b6b528cf904670b854dba3eba0f45 Thibaud Colas <thibaudcolas@gmail.com> 1384229258 +0100 commit (initial): Add application files. 2 | -------------------------------------------------------------------------------- /levels/grep/.githug/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 12c702f8b25b6b528cf904670b854dba3eba0f45 Thibaud Colas <thibaudcolas@gmail.com> 1384229258 +0100 commit (initial): Add application files. 2 | -------------------------------------------------------------------------------- /levels/grep/.githug/objects/12/c702f8b25b6b528cf904670b854dba3eba0f45: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/grep/.githug/objects/12/c702f8b25b6b528cf904670b854dba3eba0f45 -------------------------------------------------------------------------------- /levels/grep/.githug/objects/6f/45753f4a16b69f5b2215f2dbe8245f073353cc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/grep/.githug/objects/6f/45753f4a16b69f5b2215f2dbe8245f073353cc -------------------------------------------------------------------------------- /levels/grep/.githug/objects/a4/1fe0c342be5c9930328cbb4315acebbd9c94b2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/grep/.githug/objects/a4/1fe0c342be5c9930328cbb4315acebbd9c94b2 -------------------------------------------------------------------------------- /levels/grep/.githug/objects/d3/f53e82aa015d1eea3b06c3b62dfbacee83bbe1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/grep/.githug/objects/d3/f53e82aa015d1eea3b06c3b62dfbacee83bbe1 -------------------------------------------------------------------------------- /levels/grep/.githug/refs/heads/master: -------------------------------------------------------------------------------- 1 | 12c702f8b25b6b528cf904670b854dba3eba0f45 2 | -------------------------------------------------------------------------------- /levels/grep/app.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra' 2 | require 'oauth2' 3 | require 'json' 4 | enable :sessions 5 | 6 | # TODO Make site url variable. 7 | def client 8 | OAuth2::Client.new("mTeZFqkCmzc8JnjKXaSww95bFFxhUpp1wwmSi8vG", "a9OMyEdW7JvWThHmmvFcShR9P2dyad3EGuA2ULDh", :site => "http://localhost:3000") 9 | end 10 | 11 | get "/auth/test" do 12 | redirect client.auth_code.authorize_url(:redirect_uri => redirect_uri) 13 | end 14 | 15 | get '/auth/test/callback' do 16 | access_token = client.auth_code.get_token(params[:code], :redirect_uri => redirect_uri) 17 | session[:access_token] = access_token.token 18 | @message = "Successfully authenticated with the server" 19 | erb :success 20 | end 21 | 22 | get '/yet_another' do 23 | @message = get_response('data.json') 24 | erb :success 25 | end 26 | 27 | get '/another_page' do 28 | @message = get_response('server.json') 29 | erb :another 30 | end 31 | 32 | # TODO Make API version variable. 33 | def get_response(url) 34 | access_token = OAuth2::AccessToken.new(client, session[:access_token]) 35 | JSON.parse(access_token.get("/api/v1/#{url}").body) 36 | end 37 | 38 | # TODO Redirecting queries could be useful. 39 | def redirect_uri 40 | uri = URI.parse(request.url) 41 | uri.path = '/auth/test/callback' 42 | uri.query = nil 43 | uri.to_s 44 | end 45 | 46 | -------------------------------------------------------------------------------- /levels/grep/config.rb: -------------------------------------------------------------------------------- 1 | class Config 2 | attr_accessor :name, :password 3 | def initialize(name, password = nil, options = {}) 4 | @name = name 5 | # TODO Move password to a configuration file. 6 | @password = password || "i<3evil" 7 | 8 | if options[:downcase] 9 | @name.downcase! 10 | end 11 | 12 | if options[:upcase] 13 | @name.upcase! 14 | end 15 | 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /levels/ignore.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | description "The text editor 'vim' creates files ending in `.swp` (swap files) for all files that are currently open. We don't want them creeping into the repository. Make this repository ignore those swap files which are ending in `.swp`." 3 | 4 | setup do 5 | repo.init 6 | FileUtils.touch("README.swp") 7 | system "git branch -m master" 8 | file = File.open(".git/config", "w") do |file| 9 | file.puts "[core]\nexcludesfile=" 10 | end 11 | end 12 | 13 | solution do 14 | 15 | valid = false 16 | 17 | 18 | File.open(".gitignore", "r") do |file| 19 | while line = file.gets 20 | if line.chomp == "*.swp" 21 | valid = true 22 | end 23 | end 24 | end 25 | 26 | valid 27 | end 28 | 29 | hint do 30 | puts "You may have noticed there is a file named `.gitignore` in the repository." 31 | end 32 | -------------------------------------------------------------------------------- /levels/include.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | description "Notice a few files with the '.a' extension. We want git to ignore all the files except the 'lib.a' file." 3 | 4 | setup do 5 | repo.init 6 | FileUtils.touch("first.a") 7 | FileUtils.touch("second.a") 8 | FileUtils.touch("lib.a") 9 | system "git branch -m master" 10 | file = File.open(".git/config", "w") do |file| 11 | file.puts "[core]\nexcludesfile=" 12 | end 13 | end 14 | 15 | solution do 16 | entries = File.readlines('.gitignore').map(&:chomp) 17 | entries.include? '*.a' and entries.include? '!lib.a' 18 | end 19 | 20 | hint do 21 | puts "Using `git help ignore`, read about the optional prefix to negate a pattern." 22 | end 23 | -------------------------------------------------------------------------------- /levels/init.rb: -------------------------------------------------------------------------------- 1 | difficulty 1 2 | description "A new directory, `git_hug`, has been created; initialize an empty repository in it." 3 | 4 | solution do 5 | repo.valid? 6 | end 7 | 8 | hint do 9 | puts "You can type `git --help` or `git` in your shell to get a list of available git commands." 10 | end 11 | -------------------------------------------------------------------------------- /levels/log.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | 3 | description "Identify the hash of the latest commit." 4 | 5 | setup do 6 | repo.init 7 | file = File.new("newfile.rb", "w") 8 | repo.add("newfile.rb") 9 | repo.commit_all("THIS IS THE COMMIT YOU ARE LOOKING FOR!") 10 | system "git branch -m master" 11 | end 12 | 13 | solution do 14 | repo.commits.last.id_abbrev == request("What is the hash of the most recent commit?")[0..6] 15 | end 16 | 17 | hint do 18 | puts "You need to investigate the logs. There is probably a command for doing that!" 19 | end 20 | -------------------------------------------------------------------------------- /levels/merge.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | description "We have a file in the branch 'feature'. Let's merge it with the master branch." 3 | 4 | setup do 5 | init_from_level 6 | system "git branch -m master" 7 | end 8 | 9 | solution do 10 | File.exists?("file1") && File.exists?("file2") 11 | end 12 | 13 | hint do 14 | puts "You want to research the `git merge` command." 15 | end 16 | -------------------------------------------------------------------------------- /levels/merge/.githug/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | added file2 2 | -------------------------------------------------------------------------------- /levels/merge/.githug/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /levels/merge/.githug/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | ignorecase = true 7 | -------------------------------------------------------------------------------- /levels/merge/.githug/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /levels/merge/.githug/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /levels/merge/.githug/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by "git commit" with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /levels/merge/.githug/hooks/post-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script that is called after a successful 4 | # commit is made. 5 | # 6 | # To enable this hook, rename this file to "post-commit". 7 | 8 | : Nothing 9 | -------------------------------------------------------------------------------- /levels/merge/.githug/hooks/post-receive.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script for the "post-receive" event. 4 | # 5 | # The "post-receive" script is run after receive-pack has accepted a pack 6 | # and the repository has been updated. It is passed arguments in through 7 | # stdin in the form 8 | # <oldrev> <newrev> <refname> 9 | # For example: 10 | # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master 11 | # 12 | # see contrib/hooks/ for a sample, or uncomment the next line and 13 | # rename the file to "post-receive". 14 | 15 | #. /usr/share/doc/git-core/contrib/hooks/post-receive-email 16 | -------------------------------------------------------------------------------- /levels/merge/.githug/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git update-server-info 9 | -------------------------------------------------------------------------------- /levels/merge/.githug/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /levels/merge/.githug/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by "git commit" with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Cross platform projects tend to avoid non-ascii filenames; prevent 22 | # them from being added to the repository. We exploit the fact that the 23 | # printable range starts at the space character and ends with tilde. 24 | if [ "$allownonascii" != "true" ] && 25 | # Note that the use of brackets around a tr range is ok here, (it's 26 | # even required, for portability to Solaris 10's /usr/bin/tr), since 27 | # the square bracket bytes happen to fall in the designated range. 28 | test "$(git diff --cached --name-only --diff-filter=A -z $against | 29 | LC_ALL=C tr -d '[ -~]\0')" 30 | then 31 | echo "Error: Attempt to add a non-ascii file name." 32 | echo 33 | echo "This can cause problems if you want to work" 34 | echo "with people on other platforms." 35 | echo 36 | echo "To be portable it is advisable to rename the file ..." 37 | echo 38 | echo "If you know what you are doing you can disable this" 39 | echo "check using:" 40 | echo 41 | echo " git config hooks.allownonascii true" 42 | echo 43 | exit 1 44 | fi 45 | 46 | exec git diff-index --check --cached $against -- 47 | -------------------------------------------------------------------------------- /levels/merge/.githug/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by "git commit" with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | /opt/local/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # /opt/local/bin/perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /levels/merge/.githug/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/merge/.githug/index -------------------------------------------------------------------------------- /levels/merge/.githug/info/exclude: -------------------------------------------------------------------------------- 1 | # git ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /levels/merge/.githug/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 e12277fe88657a072f1c4eb7d9320e4e6a74ba95 Dustin Rodrigues <dust.rod@gmail.com> 1331884867 -0700 commit (initial): added file1 2 | e12277fe88657a072f1c4eb7d9320e4e6a74ba95 e12277fe88657a072f1c4eb7d9320e4e6a74ba95 Dustin Rodrigues <dust.rod@gmail.com> 1331884877 -0700 checkout: moving from master to feature 3 | e12277fe88657a072f1c4eb7d9320e4e6a74ba95 cc8ea5a233df119d025eb240b9470e1ca76a151c Dustin Rodrigues <dust.rod@gmail.com> 1331884901 -0700 commit: added file2 4 | cc8ea5a233df119d025eb240b9470e1ca76a151c e12277fe88657a072f1c4eb7d9320e4e6a74ba95 Dustin Rodrigues <dust.rod@gmail.com> 1331884911 -0700 checkout: moving from feature to master 5 | -------------------------------------------------------------------------------- /levels/merge/.githug/logs/refs/heads/feature: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 e12277fe88657a072f1c4eb7d9320e4e6a74ba95 Dustin Rodrigues <dust.rod@gmail.com> 1331884877 -0700 branch: Created from HEAD 2 | e12277fe88657a072f1c4eb7d9320e4e6a74ba95 cc8ea5a233df119d025eb240b9470e1ca76a151c Dustin Rodrigues <dust.rod@gmail.com> 1331884901 -0700 commit: added file2 3 | -------------------------------------------------------------------------------- /levels/merge/.githug/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 e12277fe88657a072f1c4eb7d9320e4e6a74ba95 Dustin Rodrigues <dust.rod@gmail.com> 1331884867 -0700 commit (initial): added file1 2 | -------------------------------------------------------------------------------- /levels/merge/.githug/objects/ad/24149d789e59d4b5f9ce41cda90110ca0f98b7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/merge/.githug/objects/ad/24149d789e59d4b5f9ce41cda90110ca0f98b7 -------------------------------------------------------------------------------- /levels/merge/.githug/objects/ae/fde3a01f6e10d72fd4899ce14c8b2654d3eb45: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/merge/.githug/objects/ae/fde3a01f6e10d72fd4899ce14c8b2654d3eb45 -------------------------------------------------------------------------------- /levels/merge/.githug/objects/cc/8ea5a233df119d025eb240b9470e1ca76a151c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/merge/.githug/objects/cc/8ea5a233df119d025eb240b9470e1ca76a151c -------------------------------------------------------------------------------- /levels/merge/.githug/objects/e1/2277fe88657a072f1c4eb7d9320e4e6a74ba95: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/merge/.githug/objects/e1/2277fe88657a072f1c4eb7d9320e4e6a74ba95 -------------------------------------------------------------------------------- /levels/merge/.githug/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/merge/.githug/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 -------------------------------------------------------------------------------- /levels/merge/.githug/refs/heads/feature: -------------------------------------------------------------------------------- 1 | cc8ea5a233df119d025eb240b9470e1ca76a151c 2 | -------------------------------------------------------------------------------- /levels/merge/.githug/refs/heads/master: -------------------------------------------------------------------------------- 1 | e12277fe88657a072f1c4eb7d9320e4e6a74ba95 2 | -------------------------------------------------------------------------------- /levels/merge/file1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/merge/file1 -------------------------------------------------------------------------------- /levels/merge_squash.rb: -------------------------------------------------------------------------------- 1 | difficulty 3 2 | description "Merge all commits from the long-feature-branch as a single commit." 3 | 4 | setup do 5 | repo.init 6 | 7 | FileUtils.touch "file1" 8 | repo.add "file1" 9 | repo.commit_all "First commit" 10 | system "git branch -m master" 11 | 12 | repo.git.native :checkout, {"b" => true}, 'long-feature-branch' 13 | File.open("file3", 'w') { |f| f << "some feature\n" } 14 | repo.add "file3" 15 | repo.commit_all "Developing new features" 16 | 17 | File.open("file3", 'a') { |f| f << "getting awesomer\n" } 18 | repo.add "file3" 19 | repo.commit_all "Takes" 20 | 21 | File.open("file3", 'a') { |f| f << "and awesomer!\n" } 22 | repo.add "file3" 23 | repo.commit_all "Time" 24 | 25 | repo.git.native :checkout, {}, 'master' 26 | 27 | FileUtils.touch "file2" 28 | repo.add "file2" 29 | repo.commit_all "Second commit" 30 | end 31 | 32 | solution do 33 | result = true 34 | 35 | # Check the number of commits in the repo (should be 4 - including initial .gitignore). 36 | result = false unless repo.commits.size == 3 37 | 38 | # Check if changes from all the commits from long-feature-branch are included. 39 | file = File.open('file3') 40 | result = false unless file.readline =~ /some feature/ 41 | result = false unless file.readline =~ /getting awesomer/ 42 | result = false unless file.readline =~ /and awesomer!/ 43 | file.close 44 | 45 | result 46 | end 47 | 48 | hint do 49 | puts "Take a look at the `--squash` option of the merge command. Don't forget to commit the merge!" 50 | end 51 | -------------------------------------------------------------------------------- /levels/number_of_files_committed.rb: -------------------------------------------------------------------------------- 1 | difficulty 1 2 | description "There are some files in this repository; how many of them are staged for a commit?" 3 | 4 | setup do 5 | repo.init 6 | 7 | # Modified files 8 | %w{rubyfile4.rb rubyfile5.rb}.each do |file| 9 | FileUtils.touch(file) 10 | repo.add(file) 11 | system "git branch -m master" 12 | end 13 | repo.commit_all "Commit" 14 | 15 | # Staged file 16 | File.open("rubyfile4.rb", 'w') { |f| f << "#Changes" } 17 | repo.add("rubyfile4.rb") 18 | 19 | # Not staged file 20 | File.open("rubyfile5.rb", 'w') { |f| f << "#Changes" } 21 | 22 | # Changes to be committed 23 | %w{rubyfile1.rb}.each do |file| 24 | FileUtils.touch(file) 25 | repo.add(file) 26 | end 27 | 28 | # Untracked files 29 | %w{rubyfile6.rb rubyfile7.rb}.each do |file| 30 | FileUtils.touch(file) 31 | end 32 | end 33 | 34 | solution do 35 | numberOfFilesThereWillBeCommit = request("How many files are going to be committed?") 36 | 37 | isInteger = !!(numberOfFilesThereWillBeCommit =~ /^[-+]?[0-9]+$/) 38 | 39 | if !isInteger 40 | return false 41 | end 42 | 43 | if numberOfFilesThereWillBeCommit.to_i == 2 44 | return true 45 | end 46 | 47 | return false 48 | end 49 | 50 | hint do 51 | puts "You are looking for a command to identify the status of the repository (resembles a Linux command)." 52 | end 53 | -------------------------------------------------------------------------------- /levels/pull.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | 3 | description "You need to pull changes from your origin repository." 4 | 5 | setup do 6 | repo.init 7 | repo.remote_add("origin", "https://github.com/pull-this/thing-to-pull") 8 | system "git branch -m master" 9 | end 10 | 11 | solution do 12 | repo.commits.last.id_abbrev == "1797a7c" 13 | end 14 | 15 | hint do 16 | puts "Check out the remote repositories and research `git pull`." 17 | end 18 | -------------------------------------------------------------------------------- /levels/push.rb: -------------------------------------------------------------------------------- 1 | difficulty 3 2 | description "Your local master branch has diverged from " + 3 | "the remote origin/master branch. Rebase your branch onto " + 4 | "origin/master and push it to remote." 5 | 6 | setup do 7 | # remember the working directory so we can come back to it later 8 | cwd = Dir.pwd 9 | # initialize another git repo to be used as a "remote" 10 | tmpdir = Dir.mktmpdir 11 | 12 | # local repo 13 | repo.init 14 | 15 | FileUtils.touch "file1" 16 | repo.add "file1" 17 | repo.commit_all "First commit" 18 | 19 | FileUtils.touch "file2" 20 | repo.add "file2" 21 | repo.commit_all "Second commit" 22 | 23 | # copy the repo to remote 24 | FileUtils.cp "file1", tmpdir 25 | FileUtils.cp "file2", tmpdir 26 | 27 | # add another file 28 | FileUtils.touch "file3" 29 | repo.add "file3" 30 | repo.commit_all "Third commit" 31 | system "git branch -m master" 32 | 33 | # remote repo 34 | Dir.chdir tmpdir 35 | repo.init 36 | # make a 'non-bare' repo accept pushes 37 | `git config receive.denyCurrentBranch ignore` 38 | 39 | # add a different file and commit so remote and local would diverge 40 | FileUtils.touch "file4" 41 | repo.add "file4" 42 | repo.commit_all "Fourth commit" 43 | system "git branch -m master" # tentative addition 44 | 45 | # change back to original repo to set up a remote 46 | Dir.chdir cwd 47 | `git remote add origin #{tmpdir}/.git` 48 | `git fetch origin` 49 | `git branch -u origin/master master 2> /dev/null` 50 | end 51 | 52 | solution do 53 | repo.init 54 | result = true 55 | 56 | # Check the commits of the local branch and the branch are the same. 57 | local_commits = repo.commits("master") 58 | remote_commits = repo.commits("origin/master") 59 | result = false unless local_commits.size == 4 60 | local_commits.each_with_index do |commit, idx| 61 | result &&= (commit.id == remote_commits[idx].id) 62 | end 63 | 64 | result 65 | end 66 | 67 | hint do 68 | puts "Take a look at `git fetch`, `git pull`, and `git push`." 69 | end 70 | -------------------------------------------------------------------------------- /levels/push_tags.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | description "A tag in the local repository isn't pushed into remote repository. Push it now." 3 | 4 | setup do 5 | # remember the working directory so we can come back to it later 6 | cwd = Dir.pwd 7 | # initialize another git repo to be used as a "remote" 8 | tmpdir = Dir.mktmpdir 9 | 10 | # local repo 11 | repo.init 12 | 13 | FileUtils.touch "file1" 14 | repo.add "file1" 15 | repo.commit_all "First commit" 16 | repo.git.tag({'f' => true}, "tag_to_be_pushed") 17 | system "git branch -m master" 18 | 19 | FileUtils.touch "file2" 20 | repo.add "file2" 21 | repo.commit_all "Second commit" 22 | 23 | # copy the repo to remote 24 | FileUtils.cp_r ".", tmpdir 25 | 26 | # remote repo 27 | Dir.chdir tmpdir 28 | repo.init 29 | # make a 'non-bare' repo accept pushes 30 | `git config receive.denyCurrentBranch ignore` 31 | 32 | # change back to original repo to set up a remote 33 | Dir.chdir cwd 34 | `git remote add origin #{tmpdir}/.git` 35 | `git fetch origin` 36 | 37 | # delete tags from remote 38 | Dir.chdir tmpdir 39 | repo.git.tag({'d' => true}, "tag_to_be_pushed") 40 | 41 | # change back to local repo 42 | Dir.chdir cwd 43 | end 44 | 45 | solution do 46 | solved = false 47 | 48 | # a bit hacky solution to get tags from remote 49 | remote_tags= 50 | repo.git.raw_git_call("git ls-remote --tags .", repo.git.git_file_index). 51 | first. 52 | split("\n") 53 | 54 | # see if we have the correct tag in the remote 55 | remote_tags.each do |t| 56 | solved=true if t.include?("refs/tags/tag_to_be_pushed") 57 | end 58 | 59 | solved 60 | end 61 | 62 | hint do 63 | puts "Take a look at `--tags` flag of `git push`" 64 | end 65 | -------------------------------------------------------------------------------- /levels/rebase.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | 3 | description "We are using a git rebase workflow and the feature branch is ready to go into master. Let's rebase the feature branch onto our master branch." 4 | 5 | setup do 6 | init_from_level 7 | system "git branch -m master" 8 | end 9 | 10 | solution do 11 | return repo.commits('feature').last.id_abbrev != "ed0fdcf" && 12 | repo.commits("feature").map(&:message) == ['add feature','add content','init commit'] 13 | end 14 | 15 | hint do 16 | puts "You want to research the `git rebase` command" 17 | end 18 | -------------------------------------------------------------------------------- /levels/rebase/.githug/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | add content 2 | -------------------------------------------------------------------------------- /levels/rebase/.githug/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /levels/rebase/.githug/ORIG_HEAD: -------------------------------------------------------------------------------- 1 | 4419b972c0cd1b346ac90332aa7c5cc949589f78 2 | -------------------------------------------------------------------------------- /levels/rebase/.githug/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | ignorecase = true 7 | precomposeunicode = true 8 | -------------------------------------------------------------------------------- /levels/rebase/.githug/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/rebase/.githug/index -------------------------------------------------------------------------------- /levels/rebase/.githug/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 a78bcab6232e9382a86436cdfcb2ed0391b1f0ac ipmsteven <steven.lyl147@gmail.com> 1418373185 -0800 commit (initial): init commit 2 | a78bcab6232e9382a86436cdfcb2ed0391b1f0ac a78bcab6232e9382a86436cdfcb2ed0391b1f0ac ipmsteven <steven.lyl147@gmail.com> 1418373194 -0800 checkout: moving from master to feature 3 | a78bcab6232e9382a86436cdfcb2ed0391b1f0ac ed0fdcf366b21b8984fb37ea34106978a2e5c5ba ipmsteven <steven.lyl147@gmail.com> 1418373239 -0800 commit: add feature 4 | ed0fdcf366b21b8984fb37ea34106978a2e5c5ba a78bcab6232e9382a86436cdfcb2ed0391b1f0ac ipmsteven <steven.lyl147@gmail.com> 1418373246 -0800 checkout: moving from feature to master 5 | a78bcab6232e9382a86436cdfcb2ed0391b1f0ac 98205e9faf10cf33d2ef7c0f66e402540c62613a ipmsteven <steven.lyl147@gmail.com> 1418373270 -0800 commit: add content 6 | 98205e9faf10cf33d2ef7c0f66e402540c62613a ed0fdcf366b21b8984fb37ea34106978a2e5c5ba ipmsteven <steven.lyl147@gmail.com> 1418373282 -0800 checkout: moving from master to feature 7 | ed0fdcf366b21b8984fb37ea34106978a2e5c5ba 98205e9faf10cf33d2ef7c0f66e402540c62613a ipmsteven <steven.lyl147@gmail.com> 1418373314 -0800 rebase: checkout master 8 | 98205e9faf10cf33d2ef7c0f66e402540c62613a 4419b972c0cd1b346ac90332aa7c5cc949589f78 ipmsteven <steven.lyl147@gmail.com> 1418373314 -0800 rebase: add feature 9 | 4419b972c0cd1b346ac90332aa7c5cc949589f78 4419b972c0cd1b346ac90332aa7c5cc949589f78 ipmsteven <steven.lyl147@gmail.com> 1418373314 -0800 rebase finished: returning to refs/heads/feature 10 | 4419b972c0cd1b346ac90332aa7c5cc949589f78 98205e9faf10cf33d2ef7c0f66e402540c62613a ipmsteven <steven.lyl147@gmail.com> 1418373423 -0800 checkout: moving from feature to master 11 | 98205e9faf10cf33d2ef7c0f66e402540c62613a 4419b972c0cd1b346ac90332aa7c5cc949589f78 ipmsteven <steven.lyl147@gmail.com> 1418373435 -0800 checkout: moving from master to feature 12 | 4419b972c0cd1b346ac90332aa7c5cc949589f78 ed0fdcf366b21b8984fb37ea34106978a2e5c5ba ipmsteven <steven.lyl147@gmail.com> 1418373492 -0800 reset: moving to ed0fdcf 13 | ed0fdcf366b21b8984fb37ea34106978a2e5c5ba 98205e9faf10cf33d2ef7c0f66e402540c62613a ipmsteven <steven.lyl147@gmail.com> 1418373509 -0800 checkout: moving from feature to master 14 | -------------------------------------------------------------------------------- /levels/rebase/.githug/logs/refs/heads/feature: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 a78bcab6232e9382a86436cdfcb2ed0391b1f0ac ipmsteven <steven.lyl147@gmail.com> 1418373194 -0800 branch: Created from HEAD 2 | a78bcab6232e9382a86436cdfcb2ed0391b1f0ac ed0fdcf366b21b8984fb37ea34106978a2e5c5ba ipmsteven <steven.lyl147@gmail.com> 1418373239 -0800 commit: add feature 3 | ed0fdcf366b21b8984fb37ea34106978a2e5c5ba 4419b972c0cd1b346ac90332aa7c5cc949589f78 ipmsteven <steven.lyl147@gmail.com> 1418373314 -0800 rebase finished: refs/heads/feature onto 98205e9faf10cf33d2ef7c0f66e402540c62613a 4 | 4419b972c0cd1b346ac90332aa7c5cc949589f78 ed0fdcf366b21b8984fb37ea34106978a2e5c5ba ipmsteven <steven.lyl147@gmail.com> 1418373492 -0800 reset: moving to ed0fdcf 5 | -------------------------------------------------------------------------------- /levels/rebase/.githug/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 a78bcab6232e9382a86436cdfcb2ed0391b1f0ac ipmsteven <steven.lyl147@gmail.com> 1418373185 -0800 commit (initial): init commit 2 | a78bcab6232e9382a86436cdfcb2ed0391b1f0ac 98205e9faf10cf33d2ef7c0f66e402540c62613a ipmsteven <steven.lyl147@gmail.com> 1418373270 -0800 commit: add content 3 | -------------------------------------------------------------------------------- /levels/rebase/.githug/objects/0c/d212c5b28da2e65ed4900712dd36c8adce48ad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/rebase/.githug/objects/0c/d212c5b28da2e65ed4900712dd36c8adce48ad -------------------------------------------------------------------------------- /levels/rebase/.githug/objects/44/19b972c0cd1b346ac90332aa7c5cc949589f78: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/rebase/.githug/objects/44/19b972c0cd1b346ac90332aa7c5cc949589f78 -------------------------------------------------------------------------------- /levels/rebase/.githug/objects/54/3b9bebdc6bd5c4b22136034a95dd097a57d3dd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/rebase/.githug/objects/54/3b9bebdc6bd5c4b22136034a95dd097a57d3dd -------------------------------------------------------------------------------- /levels/rebase/.githug/objects/81/78c76d627cade75005b40711b92f4177bc6cfc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/rebase/.githug/objects/81/78c76d627cade75005b40711b92f4177bc6cfc -------------------------------------------------------------------------------- /levels/rebase/.githug/objects/98/205e9faf10cf33d2ef7c0f66e402540c62613a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/rebase/.githug/objects/98/205e9faf10cf33d2ef7c0f66e402540c62613a -------------------------------------------------------------------------------- /levels/rebase/.githug/objects/a7/8bcab6232e9382a86436cdfcb2ed0391b1f0ac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/rebase/.githug/objects/a7/8bcab6232e9382a86436cdfcb2ed0391b1f0ac -------------------------------------------------------------------------------- /levels/rebase/.githug/objects/b7/7313d7be366609dd2e77aa96d7fd73f4e27853: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/rebase/.githug/objects/b7/7313d7be366609dd2e77aa96d7fd73f4e27853 -------------------------------------------------------------------------------- /levels/rebase/.githug/objects/b9/2d5d55d379cfb90b750e6472fc983f32ad9a71: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/rebase/.githug/objects/b9/2d5d55d379cfb90b750e6472fc983f32ad9a71 -------------------------------------------------------------------------------- /levels/rebase/.githug/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/rebase/.githug/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 -------------------------------------------------------------------------------- /levels/rebase/.githug/objects/ed/0fdcf366b21b8984fb37ea34106978a2e5c5ba: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/rebase/.githug/objects/ed/0fdcf366b21b8984fb37ea34106978a2e5c5ba -------------------------------------------------------------------------------- /levels/rebase/.githug/refs/heads/feature: -------------------------------------------------------------------------------- 1 | ed0fdcf366b21b8984fb37ea34106978a2e5c5ba 2 | -------------------------------------------------------------------------------- /levels/rebase/.githug/refs/heads/master: -------------------------------------------------------------------------------- 1 | 98205e9faf10cf33d2ef7c0f66e402540c62613a 2 | -------------------------------------------------------------------------------- /levels/rebase/README: -------------------------------------------------------------------------------- 1 | readme 2 | -------------------------------------------------------------------------------- /levels/rebase_onto.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | 3 | description "You have created your branch from `wrong_branch` and already made some commits, \ 4 | and you realise that you needed to create your branch from `master`. \ 5 | Rebase your commits onto `master` branch so that you don't have `wrong_branch` commits." 6 | 7 | setup do 8 | readme_file = "README.md" 9 | authors_file = "authors.md" 10 | 11 | repo.init 12 | FileUtils.touch(authors_file) 13 | File.open(authors_file, "w") { |f| f << "https://github.com/janis-vitols\n" } 14 | repo.add(authors_file) 15 | repo.commit_all("Create authors file") 16 | system "git branch -m master" 17 | 18 | repo.git.native :checkout, { "b" => true }, "wrong_branch" 19 | File.open(authors_file, "w") { |f| f << "None\n" } 20 | repo.add(authors_file) 21 | repo.commit_all("Wrong changes") 22 | 23 | repo.git.native :checkout, { "b" => true }, "readme-update" 24 | FileUtils.touch(readme_file) 25 | File.open(readme_file, "a") { |f| f << "# SuperApp\n" } 26 | repo.add(readme_file) 27 | repo.commit_all("Add app name in readme") 28 | File.open(readme_file, "a") { |f| f << "## About\n" } 29 | repo.add(readme_file) 30 | repo.commit_all("Add `About` header in readme") 31 | File.open(readme_file, "a") { |f| f << "## Install\n" } 32 | repo.add(readme_file) 33 | repo.commit_all("Add `Install` header in readme") 34 | end 35 | 36 | solution do 37 | repo.commits("readme-update").each { |commit| return false if commit.message == "Wrong changes" } 38 | return false unless repo.commits("readme-update").length == 4 39 | return false unless File.readlines("authors.md").include?("https://github.com/janis-vitols\n") 40 | 41 | true 42 | end 43 | 44 | hint do 45 | puts "You want to research the `git rebase` commands `--onto` argument" 46 | end 47 | -------------------------------------------------------------------------------- /levels/remote.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | 3 | description "This project has a remote repository. Identify it." 4 | 5 | setup do 6 | repo.init 7 | repo.remote_add("my_remote_repo", "https://github.com/Gazler/githug") 8 | system "git branch -m master" 9 | end 10 | 11 | solution do 12 | "my_remote_repo" == request("What is the name of the remote repository?") 13 | end 14 | 15 | hint do 16 | puts "You are looking for a remote. You can run `git` for a list of commands." 17 | end 18 | -------------------------------------------------------------------------------- /levels/remote_add.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | 3 | description "Add a remote repository called `origin` with the url https://github.com/githug/githug" 4 | 5 | setup do 6 | repo.init 7 | system "git branch -m master" 8 | end 9 | 10 | solution do 11 | result = `git remote -v` 12 | result.include?("https://github.com/githug/githug") 13 | end 14 | 15 | hint do 16 | puts "You can run `git remote --help` for the man pages." 17 | end 18 | -------------------------------------------------------------------------------- /levels/remote_url.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | 3 | description "The remote repositories have a url associated to them. Please enter the url of remote_location." 4 | 5 | setup do 6 | repo.init 7 | repo.remote_add("my_remote_repo", "https://github.com/Gazler/githug") 8 | repo.remote_add("remote_location", "https://github.com/githug/not_a_repo") 9 | system "git branch -m master" 10 | end 11 | 12 | solution do 13 | !!(request("What is the url of the remote repository?") =~ /https:\/\/github.com\/githug\/not_a_repo\/?/) 14 | end 15 | 16 | hint do 17 | puts "You can run `git remote --help` for the man pages." 18 | end 19 | -------------------------------------------------------------------------------- /levels/rename.rb: -------------------------------------------------------------------------------- 1 | difficulty 3 2 | 3 | description "We have a file called `oldfile.txt`. We want to rename it to `newfile.txt` and stage this change." 4 | 5 | setup do 6 | repo.init 7 | FileUtils.touch("oldfile.txt") 8 | repo.add("oldfile.txt") 9 | repo.commit_all("Commited oldfile.txt") 10 | system "git branch -m master" 11 | end 12 | 13 | solution do 14 | repo.status["oldfile.txt"].type == "D" && repo.status["newfile.txt"].type == "A" && repo.status["oldfile.txt"].stage.nil? 15 | end 16 | 17 | hint do 18 | puts "Take a look at `git mv`." 19 | end 20 | -------------------------------------------------------------------------------- /levels/rename_commit.rb: -------------------------------------------------------------------------------- 1 | difficulty 3 2 | description "Correct the typo in the message of your first (non-root) commit." 3 | 4 | setup do 5 | repo.init 6 | FileUtils.touch "README" 7 | repo.add "README" 8 | repo.commit_all "Initial commit" 9 | system "git branch -m master" 10 | 11 | FileUtils.touch "file1" 12 | repo.add "file1" 13 | repo.commit_all "First coommit" 14 | 15 | FileUtils.touch "file2" 16 | repo.add "file2" 17 | repo.commit_all "Second commit" 18 | end 19 | 20 | solution do 21 | repo.commits.first.parents[0].message == "First commit" 22 | end 23 | 24 | hint do 25 | puts "Take a look the `-i` flag of the rebase command." 26 | end 27 | -------------------------------------------------------------------------------- /levels/reorder.rb: -------------------------------------------------------------------------------- 1 | difficulty 4 2 | description "You have committed several times but in the wrong order. Please reorder your commits." 3 | 4 | setup do 5 | repo.init 6 | 7 | FileUtils.touch "README" 8 | repo.add "README" 9 | repo.commit_all "Initial Setup" 10 | system "git branch -m master" 11 | 12 | FileUtils.touch "file1" 13 | repo.add "file1" 14 | repo.commit_all "First commit" 15 | 16 | FileUtils.touch "file3" 17 | repo.add "file3" 18 | repo.commit_all "Third commit" 19 | 20 | FileUtils.touch "file2" 21 | repo.add "file2" 22 | repo.commit_all "Second commit" 23 | end 24 | 25 | solution do 26 | `git log --format="%s"`.split.join("").match /Third.*Second.*First.*Initial/ 27 | end 28 | 29 | hint do 30 | puts "Take a look the `-i` flag of the rebase command." 31 | end 32 | -------------------------------------------------------------------------------- /levels/repack.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | description "Optimise how your repository is packaged ensuring that redundant packs are removed." 3 | 4 | setup do 5 | repo.init 6 | FileUtils.touch("foo") 7 | repo.add("foo") 8 | repo.commit_all("Added foo") 9 | system "git branch -m master" 10 | end 11 | 12 | solution do 13 | result = `git count-objects -v` 14 | required = ["count: 0", "prune-packable: 0"]; 15 | required.all? { |r| result.include?(r) } 16 | end 17 | 18 | hint do 19 | puts "You want to research the `git repack` command." 20 | end 21 | -------------------------------------------------------------------------------- /levels/reset.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | description "There are two files to be committed. The goal was to add each file as a separate commit, however both were added by accident. Unstage the file `to_commit_second.rb` using the reset command (don't commit anything)." 3 | 4 | setup do 5 | repo.init 6 | FileUtils.touch("README") 7 | repo.add("README") 8 | repo.commit_all("Initial commit") 9 | FileUtils.touch("to_commit_first.rb") 10 | FileUtils.touch("to_commit_second.rb") 11 | repo.add(".") 12 | system "git branch -m master" 13 | end 14 | 15 | solution do 16 | return false unless (repo.status.files["to_commit_second.rb"].nil? || repo.status.files["to_commit_second.rb"].stage.nil?) && File.exists?("to_commit_second.rb") 17 | return false if (repo.status.files["to_commit_first.rb"].nil? || repo.status.files["to_commit_first.rb"].stage.nil?) 18 | true 19 | end 20 | 21 | hint do 22 | puts "You can get some useful information for git status, it will tell you the command you need to run." 23 | end 24 | -------------------------------------------------------------------------------- /levels/reset_soft.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | description "You committed too soon. Now you want to undo the last commit, while keeping the index." 3 | 4 | setup do 5 | repo.init 6 | FileUtils.touch("README") 7 | repo.add("README") 8 | repo.commit_all("Initial commit") 9 | FileUtils.touch("newfile.rb") 10 | repo.add("newfile.rb") 11 | repo.commit_all("Premature commit") 12 | system "git branch -m master" 13 | end 14 | 15 | solution do 16 | return false unless File.exists?("newfile.rb") && repo.status.files.keys.include?("newfile.rb") 17 | return false if repo.status.files["newfile.rb"].untracked || repo.commit_count > 1 18 | true 19 | end 20 | 21 | hint do 22 | puts "What are some options you can use with `git reset`?" 23 | end 24 | -------------------------------------------------------------------------------- /levels/restore.rb: -------------------------------------------------------------------------------- 1 | difficulty 4 2 | description "You decided to delete your latest commit by running `git reset --hard HEAD^` (not a smart thing to do). Now you changed your mind and want that commit back. Restore the deleted commit." 3 | 4 | setup do 5 | repo.init 6 | FileUtils.touch 'file1' 7 | repo.add 'file1' 8 | repo.commit_all 'Initial commit' 9 | system "git branch -m master" 10 | 11 | FileUtils.touch 'file2' 12 | repo.add 'file2' 13 | repo.commit_all 'First commit' 14 | 15 | FileUtils.touch 'file3' 16 | repo.add 'file3' 17 | repo.commit_all 'Restore this commit' 18 | 19 | repo.git.native :reset, { "hard" => true }, 'HEAD^' 20 | end 21 | 22 | solution do 23 | return false unless File.exists?('file3') 24 | true 25 | end 26 | 27 | hint do 28 | puts "The commit is still floating around somewhere. Have you checked out `git reflog`?" 29 | end 30 | -------------------------------------------------------------------------------- /levels/restructure.rb: -------------------------------------------------------------------------------- 1 | difficulty 3 2 | 3 | description "You added some files to your repository, but now realize that your project needs to be restructured. Make a new folder named `src` and use Git move all of the .html files into this folder." 4 | 5 | setup do 6 | repo.init 7 | 8 | FileUtils.touch("about.html") 9 | FileUtils.touch("contact.html") 10 | FileUtils.touch("index.html") 11 | 12 | repo.add("about.html") 13 | repo.add("contact.html") 14 | repo.add("index.html") 15 | 16 | system "git branch -m master" 17 | 18 | repo.commit_all("adding web content.") 19 | end 20 | 21 | solution do 22 | index = 23 | repo.status["index.html"].type == "D" && 24 | repo.status["index.html"].stage.nil? && 25 | repo.status["src/index.html"].type == "A" 26 | 27 | about = 28 | repo.status["about.html"].type == "D" && 29 | repo.status["about.html"].stage.nil? && 30 | repo.status["src/about.html"].type == "A" 31 | 32 | contact = 33 | repo.status["contact.html"].type == "D" && 34 | repo.status["contact.html"].stage.nil? && 35 | repo.status["src/contact.html"].type == "A" 36 | 37 | index && about && contact 38 | end 39 | 40 | hint do 41 | puts "You'll have to use mkdir, and `git mv`." 42 | end 43 | -------------------------------------------------------------------------------- /levels/revert.rb: -------------------------------------------------------------------------------- 1 | difficulty 4 2 | description "You have committed several times but want to undo the middle commit. All commits have been pushed, so you can't change existing history." 3 | 4 | setup do 5 | repo.init 6 | 7 | FileUtils.touch "file1" 8 | repo.add "file1" 9 | repo.commit_all "First commit" 10 | system "git branch -m master" 11 | 12 | FileUtils.touch "file3" 13 | repo.add "file3" 14 | repo.commit_all "Bad commit" 15 | 16 | FileUtils.touch "file2" 17 | repo.add "file2" 18 | repo.commit_all "Second commit" 19 | end 20 | 21 | solution do 22 | valid = false 23 | commit_messages = repo.commits.map(&:message) 24 | valid = true if repo.commits.length > 3 && 25 | commit_messages.any? { |e| e =~ /(Revert )?"Bad commit"/ } 26 | valid 27 | end 28 | 29 | hint do 30 | puts "Try the revert command." 31 | end 32 | -------------------------------------------------------------------------------- /levels/rm.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | 3 | description "A file has been removed from the working tree, but not from the repository. Identify this file and remove it." 4 | 5 | setup do 6 | repo.init 7 | file = File.new("deleteme.rb", "w") 8 | file.close 9 | system "git branch -m master" 10 | repo.add("deleteme.rb") 11 | repo.commit_all("Added a temp file") 12 | File.delete("deleteme.rb") 13 | end 14 | 15 | solution do 16 | repo.status.files["deleteme.rb"].nil? || repo.status.files["deleteme.rb"].stage.nil? 17 | end 18 | 19 | hint do 20 | puts ["You may need to use more than one command to complete this.", 21 | "You have checked your staging area in a previous level.", 22 | "Don't forget to run `git` for a list of commands."] 23 | end 24 | -------------------------------------------------------------------------------- /levels/rm_cached.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | 3 | description "A file has accidentally been added to your staging area. Identify and remove it from the staging area. *NOTE* Do not remove the file from the file system, only from git." 4 | 5 | setup do 6 | repo.init 7 | FileUtils.touch("deleteme.rb") 8 | system "git branch -m master" 9 | repo.add(".gitignore") 10 | repo.add("deleteme.rb") 11 | end 12 | 13 | solution do 14 | (repo.status.files["deleteme.rb"].nil? || repo.status.files["deleteme.rb"].stage.nil?) && File.exists?("deleteme.rb") 15 | end 16 | 17 | hint do 18 | puts "You may need to use more than one command to complete this. You have checked your staging area in a previous level. Don't forget to run `git` for a list of commands." 19 | end 20 | -------------------------------------------------------------------------------- /levels/squash.rb: -------------------------------------------------------------------------------- 1 | difficulty 4 2 | description "You have committed several times but would like all those changes to be one commit." 3 | 4 | setup do 5 | repo.init 6 | FileUtils.touch(".hidden") 7 | repo.add(".hidden") 8 | repo.commit_all("Initial Commit") 9 | system "git branch -m master" 10 | FileUtils.touch("README") 11 | repo.add("README") 12 | repo.commit_all("Adding README") 13 | File.open("README", 'w') { |f| f.write("hey there") } 14 | repo.add("README") 15 | repo.commit_all("Updating README (squash this commit into Adding README)") 16 | File.open("README", 'a') { |f| f.write("\nAdding some more text") } 17 | repo.add("README") 18 | repo.commit_all("Updating README (squash this commit into Adding README)") 19 | File.open("README", 'a') { |f| f.write("\neven more text") } 20 | repo.add("README") 21 | repo.commit_all("Updating README (squash this commit into Adding README)") 22 | end 23 | 24 | solution do 25 | repo.commits.length == 2 26 | end 27 | 28 | hint do 29 | puts "Take a look at the `-i` flag of the rebase command." 30 | end 31 | -------------------------------------------------------------------------------- /levels/stage_lines.rb: -------------------------------------------------------------------------------- 1 | difficulty 4 2 | 3 | description "You've made changes within a single file that belong to two different features, but neither of the changes are yet staged. Stage only the changes belonging to the first feature." 4 | 5 | setup do 6 | repo.init 7 | File.open("feature.rb", "w") do |file| 8 | file.puts("this is the class of my feature") 9 | end 10 | system "git branch -m master" 11 | 12 | repo.add("feature.rb") 13 | repo.commit_all("Added initial feature file") 14 | 15 | File.open("feature.rb", "a") do |file| 16 | file.puts("This change belongs to the first feature") 17 | end 18 | 19 | File.open("feature.rb", "a") do |file| 20 | file.puts("This change belongs to the second feature") 21 | end 22 | end 23 | 24 | solution do 25 | `git diff --no-ext-diff --no-color --staged` =~ /\+This change belongs to the first feature/ && `git diff --no-ext-diff --no-color` =~ /\+This change belongs to the second feature/ 26 | end 27 | 28 | hint do 29 | puts "You might want to try to manipulate the hunks of the diff to choose which lines of the diff get staged. Read about the flags which can be passed to the `add` command; `git --help add`." 30 | end 31 | -------------------------------------------------------------------------------- /levels/stash.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | description "You've made some changes and want to work on them later. You should save them, but don't commit them." 3 | 4 | setup do 5 | init_from_level 6 | system "git branch -m master" 7 | end 8 | 9 | solution do 10 | return false if `git stash list` !~ /stash@\{0\}/ 11 | return false if repo.status.changed.to_a.flatten.include? "lyrics.txt" 12 | true 13 | end 14 | 15 | hint do 16 | puts "It's like stashing. Try finding an appropriate git command." 17 | end 18 | -------------------------------------------------------------------------------- /levels/stash/.githug/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | Add some lyrics 2 | -------------------------------------------------------------------------------- /levels/stash/.githug/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /levels/stash/.githug/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = true 4 | bare = false 5 | logallrefupdates = true 6 | ignorecase = true 7 | precomposeunicode = false 8 | -------------------------------------------------------------------------------- /levels/stash/.githug/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /levels/stash/.githug/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | test -x "$GIT_DIR/hooks/commit-msg" && 14 | exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /levels/stash/.githug/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by "git commit" with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /levels/stash/.githug/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git update-server-info 9 | -------------------------------------------------------------------------------- /levels/stash/.githug/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | test -x "$GIT_DIR/hooks/pre-commit" && 13 | exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /levels/stash/.githug/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by "git commit" with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ascii filenames set this variable to true. 19 | allownonascii=$(git config hooks.allownonascii) 20 | 21 | # Redirect output to stderr. 22 | exec 1>&2 23 | 24 | # Cross platform projects tend to avoid non-ascii filenames; prevent 25 | # them from being added to the repository. We exploit the fact that the 26 | # printable range starts at the space character and ends with tilde. 27 | if [ "$allownonascii" != "true" ] && 28 | # Note that the use of brackets around a tr range is ok here, (it's 29 | # even required, for portability to Solaris 10's /usr/bin/tr), since 30 | # the square bracket bytes happen to fall in the designated range. 31 | test $(git diff --cached --name-only --diff-filter=A -z $against | 32 | LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 33 | then 34 | echo "Error: Attempt to add a non-ascii file name." 35 | echo 36 | echo "This can cause problems if you want to work" 37 | echo "with people on other platforms." 38 | echo 39 | echo "To be portable it is advisable to rename the file ..." 40 | echo 41 | echo "If you know what you are doing you can disable this" 42 | echo "check using:" 43 | echo 44 | echo " git config hooks.allownonascii true" 45 | echo 46 | exit 1 47 | fi 48 | 49 | # If there are whitespace errors, print the offending file names and fail. 50 | exec git diff-index --check --cached $against -- 51 | -------------------------------------------------------------------------------- /levels/stash/.githug/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by "git commit" with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # /usr/bin/perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /levels/stash/.githug/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/stash/.githug/index -------------------------------------------------------------------------------- /levels/stash/.githug/info/exclude: -------------------------------------------------------------------------------- 1 | # git ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /levels/stash/.githug/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 02060592b31c9e12ffe1b282addf9537c5ef8e1f Anton Vasin <magnumsmail@gmail.com> 1354518787 +0400 commit (initial): Add some lyrics 2 | -------------------------------------------------------------------------------- /levels/stash/.githug/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 02060592b31c9e12ffe1b282addf9537c5ef8e1f Anton Vasin <magnumsmail@gmail.com> 1354518787 +0400 commit (initial): Add some lyrics 2 | -------------------------------------------------------------------------------- /levels/stash/.githug/objects/02/060592b31c9e12ffe1b282addf9537c5ef8e1f: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/stash/.githug/objects/02/060592b31c9e12ffe1b282addf9537c5ef8e1f -------------------------------------------------------------------------------- /levels/stash/.githug/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904: -------------------------------------------------------------------------------- 1 | x+)JMU0`�� 2 | , -------------------------------------------------------------------------------- /levels/stash/.githug/objects/7f/82d7e4fba66980af16da540e18d8955518cdc2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/stash/.githug/objects/7f/82d7e4fba66980af16da540e18d8955518cdc2 -------------------------------------------------------------------------------- /levels/stash/.githug/objects/85/e560abcd7e3255dcd91982476e432f4d3d1b51: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gazler/githug/a613718f56256e785301a9d9c0b400ac84c47166/levels/stash/.githug/objects/85/e560abcd7e3255dcd91982476e432f4d3d1b51 -------------------------------------------------------------------------------- /levels/stash/.githug/refs/heads/master: -------------------------------------------------------------------------------- 1 | 02060592b31c9e12ffe1b282addf9537c5ef8e1f 2 | -------------------------------------------------------------------------------- /levels/stash/lyrics.txt: -------------------------------------------------------------------------------- 1 | Down in Louisiana in that sunny clime, 2 | They play a class of music that is super fine, 3 | And it makes no difference if its rain or shine, 4 | You can hear that that jazz band music playing all the time. 5 | It sounds so peculiar cause the music's queer. 6 | How its sweet vibration seem to fill the air. 7 | Then to you the whole world seems to be in rhyme. 8 | You want nothing else but blues-band music all the time. 9 | 10 | Ev'ry one that's nigh 11 | Never seems to sigh, 12 | Hear them loudly cry: 13 | Hey! 14 | -------------------------------------------------------------------------------- /levels/status.rb: -------------------------------------------------------------------------------- 1 | difficulty 1 2 | description "Among the files in this repository, which of them is untracked?" 3 | 4 | setup do 5 | repo.init 6 | %w{config.rb README setup.rb deploy.rb Guardfile}.each do |file| 7 | FileUtils.touch(file) 8 | system "git branch -m master" 9 | repo.add(file) 10 | end 11 | FileUtils.touch("database.yml") 12 | end 13 | 14 | solution do 15 | 16 | name = request("What is the full file name of the untracked file?") 17 | 18 | if name != "database.yml" 19 | return false 20 | end 21 | 22 | true 23 | end 24 | 25 | hint do 26 | puts "You are looking for a command to identify the status of the repository." 27 | end 28 | -------------------------------------------------------------------------------- /levels/submodule.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | description "You want to include the files from the following repo: `https://github.com/jackmaney/githug-include-me` into the folder `./githug-include-me`. Do this without manually cloning the repo or copying the files from the repo into this repo." 3 | 4 | setup do 5 | repo.init 6 | system "git branch -m master" 7 | end 8 | 9 | solution do 10 | return false if not File.directory?("./githug-include-me") 11 | return false if not File.exist?("./githug-include-me/README.md") 12 | return false if not File.exist?("./githug-include-me/.git") 13 | return false if File.directory?("./githug-include-me/.git") 14 | return false if not File.exist?(".gitmodules") 15 | 16 | return true 17 | end 18 | 19 | hint do 20 | puts "Take a look at `git submodule`." 21 | end 22 | -------------------------------------------------------------------------------- /levels/tag.rb: -------------------------------------------------------------------------------- 1 | difficulty 2 2 | 3 | description "We have a git repo and we want to tag the current commit with `new_tag`." 4 | 5 | setup do 6 | repo.init 7 | FileUtils.touch("somefile.txt") 8 | repo.add("somefile.txt") 9 | repo.commit_all("Added some file to the repo") 10 | system "git branch -m master" 11 | end 12 | 13 | solution do 14 | repo.tags.first.name == "new_tag" 15 | end 16 | 17 | hint do 18 | puts "Take a look at `git tag`." 19 | end 20 | -------------------------------------------------------------------------------- /lib/githug.rb: -------------------------------------------------------------------------------- 1 | require 'grit' 2 | 3 | require "githug/extensions/grit/ruby1.9" 4 | 5 | 6 | require "githug/version" 7 | 8 | require 'githug/ui' 9 | require 'githug/game' 10 | require 'githug/profile' 11 | require 'githug/level' 12 | require 'githug/repository' 13 | 14 | Githug::UI.in_stream = STDIN 15 | Githug::UI.out_stream = STDOUT 16 | STDIN.sync = true 17 | -------------------------------------------------------------------------------- /lib/githug/extensions/grit/ruby1.9.rb: -------------------------------------------------------------------------------- 1 | class String 2 | if self.method_defined?(:ord) 3 | def getord(offset); self[offset].ord; end 4 | else 5 | alias :getord :[] 6 | end 7 | 8 | unless self.method_defined?(:b) 9 | if self.method_defined?(:force_encoding) 10 | def b; self.dup.force_encoding(Encoding::ASCII_8BIT); end 11 | else 12 | def b; self.dup; end 13 | end 14 | end 15 | end 16 | 17 | if Object.const_defined?(:PACK_IDX_SIGNATURE) 18 | Object.send(:remove_const, :PACK_IDX_SIGNATURE) 19 | end 20 | 21 | PACK_IDX_SIGNATURE = "\377tOc".b 22 | -------------------------------------------------------------------------------- /lib/githug/game.rb: -------------------------------------------------------------------------------- 1 | module Githug 2 | class Game 3 | 4 | attr_accessor :profile 5 | 6 | def initialize 7 | @profile = Profile.load 8 | end 9 | 10 | def play_level 11 | solve = true 12 | if profile.level.nil? 13 | UI.puts("Welcome to Githug!") 14 | solve = false 15 | level_bump 16 | else 17 | level = Level.load(profile.level) 18 | if solve && level 19 | if level.solve 20 | UI.success "Congratulations, you have solved the level!" 21 | level_bump 22 | else 23 | UI.error "Sorry, this solution is not quite right!" 24 | profile.current_attempts += 1 25 | profile.save 26 | 27 | if (profile.current_attempts > 2 && profile.current_attempts % 3 == 0) 28 | UI.error "Don't forget you can type `githug hint` for a hint and `githug reset` to reset the current level." 29 | end 30 | 31 | UI.puts level.full_description 32 | end 33 | end 34 | end 35 | end 36 | 37 | def test_level(level, errors = nil) 38 | UI.puts level.full_description 39 | method = :solve 40 | method = :test if errors 41 | if level.send(method) 42 | UI.success "Valid solution" 43 | else 44 | UI.error "Invalid solution" 45 | end 46 | end 47 | 48 | def level_bump 49 | profile.level_bump 50 | if level = Level.load(profile.level) 51 | UI.puts(level.full_description) 52 | level.setup_level 53 | end 54 | end 55 | 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /lib/githug/profile.rb: -------------------------------------------------------------------------------- 1 | require 'yaml' 2 | module Githug 3 | class Profile 4 | PROFILE_FILE = ".profile.yml" 5 | 6 | attr_accessor :settings 7 | 8 | class << self 9 | def load 10 | self.new(settings) 11 | end 12 | 13 | private 14 | 15 | def settings 16 | return defaults unless File.exists?(PROFILE_FILE) 17 | defaults.merge(YAML::load(File.open(PROFILE_FILE))) 18 | end 19 | 20 | def defaults 21 | { 22 | :level => nil, 23 | :current_attempts => 0, 24 | :current_hint_index => 0, 25 | :current_levels => [], 26 | :completed_levels => [] 27 | } 28 | end 29 | 30 | end 31 | 32 | 33 | def method_missing(method, *args, &block) 34 | if method.to_s.end_with?("=") 35 | method = method.to_s.chop.to_sym 36 | return settings[method] = args[0] if settings.include?(method) 37 | end 38 | return(settings[method]) if settings.include?(method) 39 | super 40 | end 41 | 42 | def initialize(settings) 43 | @settings = settings 44 | end 45 | 46 | def save 47 | File.open(PROFILE_FILE, 'w') do |out| 48 | YAML.dump(settings, out) 49 | end 50 | end 51 | 52 | def set_level(name) 53 | settings[:level] = name 54 | reset! 55 | save 56 | end 57 | 58 | def level_bump 59 | settings[:completed_levels] << level 60 | settings[:current_levels] = levels 61 | set_level(next_level) 62 | end 63 | 64 | private 65 | 66 | def levels 67 | Level::LEVELS 68 | end 69 | 70 | def next_level 71 | (levels - settings[:completed_levels]).first || levels.last 72 | end 73 | 74 | def reset! 75 | settings[:current_attempts] = 0 76 | settings[:current_hint_index] = 0 77 | end 78 | 79 | end 80 | end 81 | -------------------------------------------------------------------------------- /lib/githug/repository.rb: -------------------------------------------------------------------------------- 1 | module Githug 2 | class Repository 3 | 4 | attr_accessor :grit 5 | 6 | def initialize(location = ".") 7 | @grit = Grit::Repo.new(location) 8 | rescue Grit::InvalidGitRepositoryError 9 | @grit = nil 10 | end 11 | 12 | def reset 13 | dont_delete = ["..", ".", ".profile.yml"] 14 | if File.basename(Dir.pwd) == "git_hug" 15 | Dir.entries(Dir.pwd).each do |file| 16 | FileUtils.rm_rf(file) unless dont_delete.include?(file) 17 | end 18 | end 19 | create_gitignore 20 | end 21 | 22 | def create_gitignore 23 | Dir.chdir("git_hug") if File.exists?("./git_hug") 24 | File.open(".gitignore", "w") do |file| 25 | file.puts(".profile.yml") 26 | file.puts(".gitignore") 27 | end 28 | end 29 | 30 | def valid? 31 | !@grit.nil? 32 | end 33 | 34 | # Initialize a Git repo. If the repo already exists, do nothing. 35 | def init(location = ".") 36 | @grit = Grit::Repo.init(location) 37 | end 38 | 39 | def method_missing(method, *args, &block) 40 | if @grit && @grit.respond_to?(method) 41 | return @grit.send(method, *args, &block) 42 | end 43 | super 44 | end 45 | 46 | 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /lib/githug/ui.rb: -------------------------------------------------------------------------------- 1 | module Githug 2 | module UI 3 | 4 | class << self 5 | 6 | attr_accessor :out_stream, :in_stream 7 | 8 | @out_stream = STDOUT 9 | @in_stream = STDIN 10 | 11 | def puts(string = "") 12 | out_stream.puts(string) 13 | end 14 | 15 | def print(string) 16 | out_stream.print(string) 17 | end 18 | 19 | def gets 20 | in_stream.gets 21 | end 22 | 23 | def word_box(string,width=80,char='*') 24 | puts char*width 25 | puts "#{char}#{string.center(width-2)}#{char}" 26 | puts char*width 27 | end 28 | 29 | def request(msg) 30 | print("#{msg} ") 31 | gets.chomp 32 | end 33 | 34 | def ask(msg) 35 | request("#{msg} [yn] ") == 'y' 36 | end 37 | 38 | def colorize(text, color_code) 39 | return puts text if ENV['OS'] && ENV['OS'].downcase.include?("windows") 40 | puts "#{color_code}#{text}\033[0m" 41 | end 42 | 43 | def error(text) 44 | colorize(text, "\033[31m") 45 | end 46 | 47 | def success(text) 48 | colorize(text, "\033[32m") 49 | end 50 | 51 | end 52 | 53 | def method_missing(method, *args, &block) 54 | return UI.send(method, *args) if UI.methods(false).include?(method.to_s) || UI.methods(false).include?(method) 55 | super 56 | end 57 | 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /lib/githug/version.rb: -------------------------------------------------------------------------------- 1 | module Githug 2 | VERSION = "0.5.1" 3 | end 4 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require './lib/githug.rb' 2 | -------------------------------------------------------------------------------- /spec/support/files/test_level.rb: -------------------------------------------------------------------------------- 1 | difficulty 1 2 | description "A test description" 3 | setup do 4 | "test" 5 | end 6 | solution do 7 | Grit::Repo.new("githug/notadir") 8 | end 9 | 10 | hints [ 11 | "this is hint 1", 12 | "this is hint 2"] 13 | 14 | hint do 15 | puts "this is a hint" 16 | end 17 | --------------------------------------------------------------------------------