From 53a6885ef93be69d2c8a6a99216c51a677fc532f Mon Sep 17 00:00:00 2001 From: Sebastian Morr Date: Mon, 12 Oct 2020 18:54:27 +0200 Subject: [PATCH] Convert "internal" levels to new level format --- levels/internals/basics | 26 ++++++++++ levels/internals/basics/congrats | 3 -- levels/internals/basics/description | 8 --- levels/internals/basics/start | 3 -- levels/internals/basics/win | 1 - levels/internals/blob-create | 38 ++++++++++++++ levels/internals/blob-create/congrats | 5 -- levels/internals/blob-create/description | 11 ---- levels/internals/blob-create/goal | 6 --- levels/internals/blob-create/start | 0 levels/internals/blob-create/win | 3 -- levels/internals/blob-remove | 27 ++++++++++ levels/internals/blob-remove/congrats | 3 -- levels/internals/blob-remove/description | 5 -- levels/internals/blob-remove/goal | 1 - levels/internals/blob-remove/start | 3 -- levels/internals/blob-remove/win | 3 -- levels/internals/commit-create | 37 ++++++++++++++ levels/internals/commit-create/description | 9 ---- levels/internals/commit-create/goal | 1 - levels/internals/commit-create/start | 6 --- levels/internals/commit-create/win | 3 -- levels/internals/commit-parents | 31 +++++++++++ levels/internals/commit-parents/description | 7 --- levels/internals/commit-parents/goal | 4 -- levels/internals/commit-parents/start | 0 levels/internals/commit-parents/win | 10 ---- levels/internals/commit-rhombus | 30 +++++++++++ levels/internals/commit-rhombus/description | 5 -- levels/internals/commit-rhombus/goal | 5 -- levels/internals/commit-rhombus/start | 0 levels/internals/commit-rhombus/win | 10 ---- levels/internals/conflict | 43 ++++++++++++++++ levels/internals/conflict/description | 5 -- levels/internals/conflict/goal | 5 -- levels/internals/conflict/start | 12 ----- levels/internals/index-add | 37 ++++++++++++++ levels/internals/index-add/congrats | 9 ---- levels/internals/index-add/description | 10 ---- levels/internals/index-add/goal | 4 -- levels/internals/index-add/start | 0 levels/internals/index-add/win | 1 - levels/internals/index-remove | 29 +++++++++++ levels/internals/index-remove/description | 5 -- levels/internals/index-remove/goal | 3 -- levels/internals/index-remove/start | 4 -- levels/internals/index-remove/win | 1 - levels/internals/index-update | 33 ++++++++++++ levels/internals/index-update/description | 9 ---- levels/internals/index-update/goal | 2 - levels/internals/index-update/start | 4 -- levels/internals/index-update/win | 2 - levels/internals/puzzle-apocalypse | 44 ++++++++++++++++ .../internals/puzzle-apocalypse/description | 9 ---- levels/internals/puzzle-apocalypse/goal | 4 -- levels/internals/puzzle-apocalypse/start | 9 ---- levels/internals/puzzle-apocalypse/win | 1 - .../win => puzzle-precious-blob} | 18 +++++++ .../puzzle-precious-blob/description | 1 - levels/internals/puzzle-precious-blob/goal | 7 --- .../win => puzzle-trees-all-the-way-down} | 16 ++++++ .../puzzle-trees-all-the-way-down/description | 3 -- .../puzzle-trees-all-the-way-down/goal | 3 -- levels/internals/ref-create | 42 +++++++++++++++ levels/internals/ref-create/description | 9 ---- levels/internals/ref-create/goal | 4 -- levels/internals/ref-create/start | 7 --- levels/internals/ref-create/win | 3 -- levels/internals/ref-move | 41 +++++++++++++++ levels/internals/ref-move/description | 5 -- levels/internals/ref-move/goal | 3 -- levels/internals/ref-move/start | 10 ---- levels/internals/ref-move/win | 1 - levels/internals/ref-remove | 41 +++++++++++++++ levels/internals/ref-remove/description | 5 -- levels/internals/ref-remove/goal | 3 -- levels/internals/ref-remove/start | 10 ---- levels/internals/ref-remove/win | 1 - .../description => symref-create} | 14 +++++ levels/internals/symref-create/goal | 3 -- levels/internals/symref-create/start | 0 levels/internals/symref-create/win | 1 - levels/internals/symref-no-deref | 46 +++++++++++++++++ levels/internals/symref-no-deref/congrats | 13 ----- levels/internals/symref-no-deref/description | 7 --- levels/internals/symref-no-deref/goal | 1 - levels/internals/symref-no-deref/start | 4 -- levels/internals/symref-no-deref/win | 2 - levels/internals/tree-create | 35 +++++++++++++ levels/internals/tree-create/congrats | 3 -- levels/internals/tree-create/description | 7 --- levels/internals/tree-create/goal | 1 - levels/internals/tree-create/start | 4 -- levels/internals/tree-create/win | 1 - .../{tree-nested/win => tree-nested} | 22 ++++++++ levels/internals/tree-nested/description | 5 -- levels/internals/tree-nested/goal | 7 --- levels/internals/tree-nested/start | 0 levels/internals/tree-read | 51 +++++++++++++++++++ levels/internals/tree-read/description | 7 --- levels/internals/tree-read/goal | 1 - levels/internals/tree-read/start | 15 ------ levels/internals/tree-read/win | 1 - .../{welcome/description => welcome} | 26 ++++++++++ levels/internals/welcome/congrats | 7 --- levels/internals/welcome/goal | 1 - levels/internals/welcome/start | 1 - levels/internals/welcome/win | 1 - 108 files changed, 727 insertions(+), 382 deletions(-) create mode 100644 levels/internals/basics delete mode 100644 levels/internals/basics/congrats delete mode 100644 levels/internals/basics/description delete mode 100644 levels/internals/basics/start delete mode 100644 levels/internals/basics/win create mode 100644 levels/internals/blob-create delete mode 100644 levels/internals/blob-create/congrats delete mode 100644 levels/internals/blob-create/description delete mode 100644 levels/internals/blob-create/goal delete mode 100644 levels/internals/blob-create/start delete mode 100644 levels/internals/blob-create/win create mode 100644 levels/internals/blob-remove delete mode 100644 levels/internals/blob-remove/congrats delete mode 100644 levels/internals/blob-remove/description delete mode 100644 levels/internals/blob-remove/goal delete mode 100644 levels/internals/blob-remove/start delete mode 100644 levels/internals/blob-remove/win create mode 100644 levels/internals/commit-create delete mode 100644 levels/internals/commit-create/description delete mode 100644 levels/internals/commit-create/goal delete mode 100644 levels/internals/commit-create/start delete mode 100644 levels/internals/commit-create/win create mode 100644 levels/internals/commit-parents delete mode 100644 levels/internals/commit-parents/description delete mode 100644 levels/internals/commit-parents/goal delete mode 100644 levels/internals/commit-parents/start delete mode 100644 levels/internals/commit-parents/win create mode 100644 levels/internals/commit-rhombus delete mode 100644 levels/internals/commit-rhombus/description delete mode 100644 levels/internals/commit-rhombus/goal delete mode 100644 levels/internals/commit-rhombus/start delete mode 100644 levels/internals/commit-rhombus/win create mode 100644 levels/internals/conflict delete mode 100644 levels/internals/conflict/description delete mode 100644 levels/internals/conflict/goal delete mode 100644 levels/internals/conflict/start create mode 100644 levels/internals/index-add delete mode 100644 levels/internals/index-add/congrats delete mode 100644 levels/internals/index-add/description delete mode 100644 levels/internals/index-add/goal delete mode 100644 levels/internals/index-add/start delete mode 100644 levels/internals/index-add/win create mode 100644 levels/internals/index-remove delete mode 100644 levels/internals/index-remove/description delete mode 100644 levels/internals/index-remove/goal delete mode 100644 levels/internals/index-remove/start delete mode 100644 levels/internals/index-remove/win create mode 100644 levels/internals/index-update delete mode 100644 levels/internals/index-update/description delete mode 100644 levels/internals/index-update/goal delete mode 100644 levels/internals/index-update/start delete mode 100644 levels/internals/index-update/win create mode 100644 levels/internals/puzzle-apocalypse delete mode 100644 levels/internals/puzzle-apocalypse/description delete mode 100644 levels/internals/puzzle-apocalypse/goal delete mode 100644 levels/internals/puzzle-apocalypse/start delete mode 100644 levels/internals/puzzle-apocalypse/win rename levels/internals/{puzzle-precious-blob/win => puzzle-precious-blob} (52%) delete mode 100644 levels/internals/puzzle-precious-blob/description delete mode 100644 levels/internals/puzzle-precious-blob/goal rename levels/internals/{puzzle-trees-all-the-way-down/win => puzzle-trees-all-the-way-down} (69%) delete mode 100644 levels/internals/puzzle-trees-all-the-way-down/description delete mode 100644 levels/internals/puzzle-trees-all-the-way-down/goal create mode 100644 levels/internals/ref-create delete mode 100644 levels/internals/ref-create/description delete mode 100644 levels/internals/ref-create/goal delete mode 100644 levels/internals/ref-create/start delete mode 100644 levels/internals/ref-create/win create mode 100644 levels/internals/ref-move delete mode 100644 levels/internals/ref-move/description delete mode 100644 levels/internals/ref-move/goal delete mode 100644 levels/internals/ref-move/start delete mode 100644 levels/internals/ref-move/win create mode 100644 levels/internals/ref-remove delete mode 100644 levels/internals/ref-remove/description delete mode 100644 levels/internals/ref-remove/goal delete mode 100644 levels/internals/ref-remove/start delete mode 100644 levels/internals/ref-remove/win rename levels/internals/{symref-create/description => symref-create} (57%) delete mode 100644 levels/internals/symref-create/goal delete mode 100644 levels/internals/symref-create/start delete mode 100644 levels/internals/symref-create/win create mode 100644 levels/internals/symref-no-deref delete mode 100644 levels/internals/symref-no-deref/congrats delete mode 100644 levels/internals/symref-no-deref/description delete mode 100644 levels/internals/symref-no-deref/goal delete mode 100644 levels/internals/symref-no-deref/start delete mode 100644 levels/internals/symref-no-deref/win create mode 100644 levels/internals/tree-create delete mode 100644 levels/internals/tree-create/congrats delete mode 100644 levels/internals/tree-create/description delete mode 100644 levels/internals/tree-create/goal delete mode 100644 levels/internals/tree-create/start delete mode 100644 levels/internals/tree-create/win rename levels/internals/{tree-nested/win => tree-nested} (54%) delete mode 100644 levels/internals/tree-nested/description delete mode 100644 levels/internals/tree-nested/goal delete mode 100644 levels/internals/tree-nested/start create mode 100644 levels/internals/tree-read delete mode 100644 levels/internals/tree-read/description delete mode 100644 levels/internals/tree-read/goal delete mode 100644 levels/internals/tree-read/start delete mode 100644 levels/internals/tree-read/win rename levels/internals/{welcome/description => welcome} (50%) delete mode 100644 levels/internals/welcome/congrats delete mode 100644 levels/internals/welcome/goal delete mode 100644 levels/internals/welcome/start delete mode 100644 levels/internals/welcome/win diff --git a/levels/internals/basics b/levels/internals/basics new file mode 100644 index 0000000..55374b5 --- /dev/null +++ b/levels/internals/basics @@ -0,0 +1,26 @@ +[description] + +For this prototype, we assume you have some experience with the command line. Here are some commands that will be useful: + +- ls +- echo content > file +- cat file +- mkdir dir + +Find the riddle in your current directory and put the answer into the file "answer"! + +[congrats] + +Omnomnom! + +For technical reasons, you can't use `cd` in this prototype yet. But there won't be a lot of interaction with the file system anyways. :) + +[setup] + +mkdir riddle +echo "ppl p" > riddle/consonants +echo "ae ie" > riddle/vowels + +[win] + +cat answer | grep -i "apple \\?pie" diff --git a/levels/internals/basics/congrats b/levels/internals/basics/congrats deleted file mode 100644 index 5cf8a73..0000000 --- a/levels/internals/basics/congrats +++ /dev/null @@ -1,3 +0,0 @@ -Omnomnom! - -For technical reasons, you can't use `cd` in this prototype yet. But there won't be a lot of interaction with the file system anyways. :) diff --git a/levels/internals/basics/description b/levels/internals/basics/description deleted file mode 100644 index fb73e9a..0000000 --- a/levels/internals/basics/description +++ /dev/null @@ -1,8 +0,0 @@ -For this prototype, we assume you have some experience with the command line. Here are some commands that will be useful: - -- ls -- echo content > file -- cat file -- mkdir dir - -Find the riddle in your current directory and put the answer into the file "answer"! diff --git a/levels/internals/basics/start b/levels/internals/basics/start deleted file mode 100644 index 5e68d49..0000000 --- a/levels/internals/basics/start +++ /dev/null @@ -1,3 +0,0 @@ -mkdir riddle -echo "ppl p" > riddle/consonants -echo "ae ie" > riddle/vowels diff --git a/levels/internals/basics/win b/levels/internals/basics/win deleted file mode 100644 index eeb81a9..0000000 --- a/levels/internals/basics/win +++ /dev/null @@ -1 +0,0 @@ -cat answer | grep -i "apple \\?pie" diff --git a/levels/internals/blob-create b/levels/internals/blob-create new file mode 100644 index 0000000..86f6254 --- /dev/null +++ b/levels/internals/blob-create @@ -0,0 +1,38 @@ +[description] + +At its core, Git is very simple. It stores "objects", which are basically files identified by an "identifier" (short: ID). + +There are four types of objects: blobs, trees, commits, and tags. The simplest type is a "blob", which is just a piece of text. + +Let's create some blobs! To do that, create a file with the desired content, and then use + + git hash-object -w + +The flag -w means "write", and tells Git to actually write the new blob to the disk. + +Create three new blobs! + +[congrats] + +Tip: You can also use a command like this to create a blob in a single line: + + echo "awesome content" | git hash-object -w --stdin + +Did you already notice that you can drag and drop all objects? :) + +[setup] + +[setup goal] + +echo "Hi" > file1 +echo "Ho" > file2 +echo "Hu" > file3 +git hash-object -w file1 +git hash-object -w file2 +git hash-object -w file3 + +[win] + +BLOB_COUNT=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | grep blob | wc -l) + +test "$BLOB_COUNT" -gt 2 diff --git a/levels/internals/blob-create/congrats b/levels/internals/blob-create/congrats deleted file mode 100644 index 3a30e80..0000000 --- a/levels/internals/blob-create/congrats +++ /dev/null @@ -1,5 +0,0 @@ -Tip: You can also use a command like this to create a blob in a single line: - - echo "awesome content" | git hash-object -w --stdin - -Did you already notice that you can drag and drop all objects? :) diff --git a/levels/internals/blob-create/description b/levels/internals/blob-create/description deleted file mode 100644 index 11a971e..0000000 --- a/levels/internals/blob-create/description +++ /dev/null @@ -1,11 +0,0 @@ -At its core, Git is very simple. It stores "objects", which are basically files identified by an "identifier" (short: ID). - -There are four types of objects: blobs, trees, commits, and tags. The simplest type is a "blob", which is just a piece of text. - -Let's create some blobs! To do that, create a file with the desired content, and then use - - git hash-object -w - -The flag -w means "write", and tells Git to actually write the new blob to the disk. - -Create three new blobs! diff --git a/levels/internals/blob-create/goal b/levels/internals/blob-create/goal deleted file mode 100644 index d3c66f7..0000000 --- a/levels/internals/blob-create/goal +++ /dev/null @@ -1,6 +0,0 @@ -echo "Hi" > file1 -echo "Ho" > file2 -echo "Hu" > file3 -git hash-object -w file1 -git hash-object -w file2 -git hash-object -w file3 diff --git a/levels/internals/blob-create/start b/levels/internals/blob-create/start deleted file mode 100644 index e69de29..0000000 diff --git a/levels/internals/blob-create/win b/levels/internals/blob-create/win deleted file mode 100644 index 1232d11..0000000 --- a/levels/internals/blob-create/win +++ /dev/null @@ -1,3 +0,0 @@ -BLOB_COUNT=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | grep blob | wc -l) - -test "$BLOB_COUNT" -gt 2 diff --git a/levels/internals/blob-remove b/levels/internals/blob-remove new file mode 100644 index 0000000..bbc1b30 --- /dev/null +++ b/levels/internals/blob-remove @@ -0,0 +1,27 @@ +[description] + +There's a simple command to remove all objects that are not referenced by anything: + + git prune + +Remove all blobs in this repository. + +[congrats] + +Generally, `git prune` will be useful if you want to clean up some objects you made. + +Alternatively, you can also click the "Reload" button to restart a level. + +[setup] + +echo "My master password is a1b2c3d4e5" | git hash-object -w --stdin +echo "This blob really should not exist" | git hash-object -w --stdin +echo "This is a virus" | git hash-object -w --stdin + +[setup goal] + +[win] + +OBJECT_COUNT=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | wc -l) + +test "$OBJECT_COUNT" -eq 0 diff --git a/levels/internals/blob-remove/congrats b/levels/internals/blob-remove/congrats deleted file mode 100644 index 0e6bd7b..0000000 --- a/levels/internals/blob-remove/congrats +++ /dev/null @@ -1,3 +0,0 @@ -Generally, `git prune` will be useful if you want to clean up some objects you made. - -Alternatively, you can also click the "Reload" button to restart a level. diff --git a/levels/internals/blob-remove/description b/levels/internals/blob-remove/description deleted file mode 100644 index a819ad1..0000000 --- a/levels/internals/blob-remove/description +++ /dev/null @@ -1,5 +0,0 @@ -There's a simple command to remove all objects that are not referenced by anything: - - git prune - -Remove all blobs in this repository. diff --git a/levels/internals/blob-remove/goal b/levels/internals/blob-remove/goal deleted file mode 100644 index b47980f..0000000 --- a/levels/internals/blob-remove/goal +++ /dev/null @@ -1 +0,0 @@ -git prune diff --git a/levels/internals/blob-remove/start b/levels/internals/blob-remove/start deleted file mode 100644 index 2251495..0000000 --- a/levels/internals/blob-remove/start +++ /dev/null @@ -1,3 +0,0 @@ -echo "My master password is a1b2c3d4e5" | git hash-object -w --stdin -echo "This blob really should not exist" | git hash-object -w --stdin -echo "This is a virus" | git hash-object -w --stdin diff --git a/levels/internals/blob-remove/win b/levels/internals/blob-remove/win deleted file mode 100644 index 0d5ab21..0000000 --- a/levels/internals/blob-remove/win +++ /dev/null @@ -1,3 +0,0 @@ -OBJECT_COUNT=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | wc -l) - -test "$OBJECT_COUNT" -eq 0 diff --git a/levels/internals/commit-create b/levels/internals/commit-create new file mode 100644 index 0000000..79a8e52 --- /dev/null +++ b/levels/internals/commit-create @@ -0,0 +1,37 @@ +[description] + +So a tree describes a directory structure at a specific point in time. + +It would be nice if we could remember when that state existed, and who authored it, right? + +Enter: commits. They are objects that point to a tree and contain some additional metadata. You can create a commit using + + git commit-tree -m "Description of your commit" + +Make a commit from the tree in this repository! + +[setup] + +touch empty_file +git add . +git write-tree + +rm empty_file +git update-index --remove empty_file + +[setup goal] + +touch empty_file +git add . +git write-tree + +rm empty_file +git update-index --remove empty_file + +git commit-tree 3185 -m 'Clever commit message' + +[win] + +COMMIT_COUNT=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | grep commit | wc -l) + +test "$COMMIT_COUNT" -gt 0 diff --git a/levels/internals/commit-create/description b/levels/internals/commit-create/description deleted file mode 100644 index fff32b3..0000000 --- a/levels/internals/commit-create/description +++ /dev/null @@ -1,9 +0,0 @@ -So a tree describes a directory structure at a specific point in time. - -It would be nice if we could remember when that state existed, and who authored it, right? - -Enter: commits. They are objects that point to a tree and contain some additional metadata. You can create a commit using - - git commit-tree -m "Description of your commit" - -Make a commit from the tree in this repository! diff --git a/levels/internals/commit-create/goal b/levels/internals/commit-create/goal deleted file mode 100644 index bcb010d..0000000 --- a/levels/internals/commit-create/goal +++ /dev/null @@ -1 +0,0 @@ -git commit-tree 3185 -m 'Clever commit message' diff --git a/levels/internals/commit-create/start b/levels/internals/commit-create/start deleted file mode 100644 index f4fe58c..0000000 --- a/levels/internals/commit-create/start +++ /dev/null @@ -1,6 +0,0 @@ -touch empty_file -git add . -git write-tree - -rm empty_file -git update-index --remove empty_file diff --git a/levels/internals/commit-create/win b/levels/internals/commit-create/win deleted file mode 100644 index 4bd1a81..0000000 --- a/levels/internals/commit-create/win +++ /dev/null @@ -1,3 +0,0 @@ -COMMIT_COUNT=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | grep commit | wc -l) - -test "$COMMIT_COUNT" -gt 0 diff --git a/levels/internals/commit-parents b/levels/internals/commit-parents new file mode 100644 index 0000000..a2efb11 --- /dev/null +++ b/levels/internals/commit-parents @@ -0,0 +1,31 @@ +[description] + +When using the commit-tree command, you can optionally specify a parent: + + git commit-tree -m "Description" -p + +Make a string of three commits! + +Hint: You'll need a tree object. What could be the easiest way to obtain one? + +[setup] + +[setup goal] + +git write-tree +FIRST_COMMIT=$(git commit-tree 4b82 -m 'First commit :O') +SECOND_COMMIT=$(git commit-tree 4b82 -p $FIRST_COMMIT -m 'Second commit :D') +THIRD_COMMIT=$(git commit-tree 4b82 -p $SECOND_COMMIT -m 'Third commit \o/') + +[win] + +COMMITS=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | grep commit | cut -f1 -d" ") + +for COMMIT in $COMMITS; do + echo a commit named $COMMIT + if [ $(git rev-list $COMMIT | wc -l) -ge 3 ]; then + return 0 + fi +done + +return 1 diff --git a/levels/internals/commit-parents/description b/levels/internals/commit-parents/description deleted file mode 100644 index e36bce7..0000000 --- a/levels/internals/commit-parents/description +++ /dev/null @@ -1,7 +0,0 @@ -When using the commit-tree command, you can optionally specify a parent: - - git commit-tree -m "Description" -p - -Make a string of three commits! - -Hint: You'll need a tree object. What could be the easiest way to obtain one? diff --git a/levels/internals/commit-parents/goal b/levels/internals/commit-parents/goal deleted file mode 100644 index 28249f9..0000000 --- a/levels/internals/commit-parents/goal +++ /dev/null @@ -1,4 +0,0 @@ -git write-tree -FIRST_COMMIT=$(git commit-tree 4b82 -m 'First commit :O') -SECOND_COMMIT=$(git commit-tree 4b82 -p $FIRST_COMMIT -m 'Second commit :D') -THIRD_COMMIT=$(git commit-tree 4b82 -p $SECOND_COMMIT -m 'Third commit \o/') diff --git a/levels/internals/commit-parents/start b/levels/internals/commit-parents/start deleted file mode 100644 index e69de29..0000000 diff --git a/levels/internals/commit-parents/win b/levels/internals/commit-parents/win deleted file mode 100644 index 26564b6..0000000 --- a/levels/internals/commit-parents/win +++ /dev/null @@ -1,10 +0,0 @@ -COMMITS=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | grep commit | cut -f1 -d" ") - -for COMMIT in $COMMITS; do - echo a commit named $COMMIT - if [ $(git rev-list $COMMIT | wc -l) -ge 3 ]; then - return 0 - fi -done - -return 1 diff --git a/levels/internals/commit-rhombus b/levels/internals/commit-rhombus new file mode 100644 index 0000000..e320ca0 --- /dev/null +++ b/levels/internals/commit-rhombus @@ -0,0 +1,30 @@ +[description] + +A commit can have multiple parents! You can specify the -p option multiple times, like this: + + git commit-tree -m "Description" -p -p + +Build a rhombus shape from commits, where two commits point to the same parent, and then a fourth commit points to both of them. + +[setup] + +[setup goal] + +TREE=$(git write-tree) +SOUTH=$(git commit-tree $TREE -m "South") +EAST=$(git commit-tree $TREE -m "East" -p $SOUTH) +WEST=$(git commit-tree $TREE -m "West" -p $SOUTH) +NORTH=$(git commit-tree $TREE -m "Nort" -p $EAST -p $WEST) + +[win] + +COMMITS=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | grep commit | cut -f1 -d" ") + +for COMMIT in $COMMITS; do + # My first parent's parents has to be the same as my second parent's parent. + if [ "$(git rev-parse --verify -q $COMMIT^1^)" = "$(git rev-parse --verify -q $COMMIT^2^)" ]; then + return 0 + fi +done + +return 1 diff --git a/levels/internals/commit-rhombus/description b/levels/internals/commit-rhombus/description deleted file mode 100644 index acf8162..0000000 --- a/levels/internals/commit-rhombus/description +++ /dev/null @@ -1,5 +0,0 @@ -A commit can have multiple parents! You can specify the -p option multiple times, like this: - - git commit-tree -m "Description" -p -p - -Build a rhombus shape from commits, where two commits point to the same parent, and then a fourth commit points to both of them. diff --git a/levels/internals/commit-rhombus/goal b/levels/internals/commit-rhombus/goal deleted file mode 100644 index f74e07d..0000000 --- a/levels/internals/commit-rhombus/goal +++ /dev/null @@ -1,5 +0,0 @@ -TREE=$(git write-tree) -SOUTH=$(git commit-tree $TREE -m "South") -EAST=$(git commit-tree $TREE -m "East" -p $SOUTH) -WEST=$(git commit-tree $TREE -m "West" -p $SOUTH) -NORTH=$(git commit-tree $TREE -m "Nort" -p $EAST -p $WEST) diff --git a/levels/internals/commit-rhombus/start b/levels/internals/commit-rhombus/start deleted file mode 100644 index e69de29..0000000 diff --git a/levels/internals/commit-rhombus/win b/levels/internals/commit-rhombus/win deleted file mode 100644 index 5492217..0000000 --- a/levels/internals/commit-rhombus/win +++ /dev/null @@ -1,10 +0,0 @@ -COMMITS=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | grep commit | cut -f1 -d" ") - -for COMMIT in $COMMITS; do - # My first parent's parents has to be the same as my second parent's parent. - if [ "$(git rev-parse --verify -q $COMMIT^1^)" = "$(git rev-parse --verify -q $COMMIT^2^)" ]; then - return 0 - fi -done - -return 1 diff --git a/levels/internals/conflict b/levels/internals/conflict new file mode 100644 index 0000000..cffe295 --- /dev/null +++ b/levels/internals/conflict @@ -0,0 +1,43 @@ +[description] + +(This is not a real puzzle yet.) + +Try merging the two branches together! + + git merge + +[setup] + +echo ? > bikeshed_color +git add . +git commit -m "Initial commit" + +echo green > bikeshed_color +git commit -a -m "My suggestion" + +git switch -c alternative HEAD^ +echo blue > bikeshed_color +git commit -a -m "This is way better" + +git switch main + +[setup goal] + +echo ? > bikeshed_color +git add . +git commit -m "Initial commit" + +echo green > bikeshed_color +git commit -a -m "My suggestion" + +git switch -c alternative HEAD^ +echo blue > bikeshed_color +git commit -a -m "This is way better" + +git switch main + +git merge alternative +echo blue-green > bikeshed_color +git add . +git commit -m "Merge" +git prune diff --git a/levels/internals/conflict/description b/levels/internals/conflict/description deleted file mode 100644 index af3bdc7..0000000 --- a/levels/internals/conflict/description +++ /dev/null @@ -1,5 +0,0 @@ -(This is not a real puzzle yet.) - -Try merging the two branches together! - - git merge diff --git a/levels/internals/conflict/goal b/levels/internals/conflict/goal deleted file mode 100644 index edeb2fa..0000000 --- a/levels/internals/conflict/goal +++ /dev/null @@ -1,5 +0,0 @@ -git merge alternative -echo blue-green > bikeshed_color -git add . -git commit -m "Merge" -git prune diff --git a/levels/internals/conflict/start b/levels/internals/conflict/start deleted file mode 100644 index 14de5f4..0000000 --- a/levels/internals/conflict/start +++ /dev/null @@ -1,12 +0,0 @@ -echo ? > bikeshed_color -git add . -git commit -m "Initial commit" - -echo green > bikeshed_color -git commit -a -m "My suggestion" - -git switch -c alternative HEAD^ -echo blue > bikeshed_color -git commit -a -m "This is way better" - -git switch main diff --git a/levels/internals/index-add b/levels/internals/index-add new file mode 100644 index 0000000..633245c --- /dev/null +++ b/levels/internals/index-add @@ -0,0 +1,37 @@ +[description] + +Blobs usually represent the content of a file. But on their own, they don't have any metadata, not even a name! + +Git has a very powerful concept to store metadata related to blobs: the index! It's a list that relates blobs to filenames and access permissions. + +The most convenient option to add an entry to the index is via an existing file: + + echo "my content" > file + git update-index --add file + +Add three entries to the index! For a bonus challenge: can you add a file that is inside of a directory, like "directory/file"? + +[congrats] + +There's another way to add an entry to the index directly: + + git update-index --add --cacheinfo ,, + +The first three numbers of the mode describe the type of the entry, "100" is a regular file. + +The second three number describe the permissions. Only "644" (non-executable) and "755" (executable) are supported. + +You can insert the hash of an object into the terminal by right-clicking on it! :) + +[setup] + +[setup goal] + +echo "file 1" > file1 +echo "file 2" > file2 +echo "file 3" > file3 +git add . + +[win] + +test "$(git ls-files | wc -l)" -ge 3 diff --git a/levels/internals/index-add/congrats b/levels/internals/index-add/congrats deleted file mode 100644 index 2a8259e..0000000 --- a/levels/internals/index-add/congrats +++ /dev/null @@ -1,9 +0,0 @@ -There's another way to add an entry to the index directly: - - git update-index --add --cacheinfo ,, - -The first three numbers of the mode describe the type of the entry, "100" is a regular file. - -The second three number describe the permissions. Only "644" (non-executable) and "755" (executable) are supported. - -You can insert the hash of an object into the terminal by right-clicking on it! :) diff --git a/levels/internals/index-add/description b/levels/internals/index-add/description deleted file mode 100644 index 63b9fb9..0000000 --- a/levels/internals/index-add/description +++ /dev/null @@ -1,10 +0,0 @@ -Blobs usually represent the content of a file. But on their own, they don't have any metadata, not even a name! - -Git has a very powerful concept to store metadata related to blobs: the index! It's a list that relates blobs to filenames and access permissions. - -The most convenient option to add an entry to the index is via an existing file: - - echo "my content" > file - git update-index --add file - -Add three entries to the index! For a bonus challenge: can you add a file that is inside of a directory, like "directory/file"? diff --git a/levels/internals/index-add/goal b/levels/internals/index-add/goal deleted file mode 100644 index ea458d5..0000000 --- a/levels/internals/index-add/goal +++ /dev/null @@ -1,4 +0,0 @@ -echo "file 1" > file1 -echo "file 2" > file2 -echo "file 3" > file3 -git add . diff --git a/levels/internals/index-add/start b/levels/internals/index-add/start deleted file mode 100644 index e69de29..0000000 diff --git a/levels/internals/index-add/win b/levels/internals/index-add/win deleted file mode 100644 index 419655c..0000000 --- a/levels/internals/index-add/win +++ /dev/null @@ -1 +0,0 @@ -test "$(git ls-files | wc -l)" -ge 3 diff --git a/levels/internals/index-remove b/levels/internals/index-remove new file mode 100644 index 0000000..9816126 --- /dev/null +++ b/levels/internals/index-remove @@ -0,0 +1,29 @@ +[description] + +To remove an entry from the index, use a command like this: + + git update-index --force-remove + +Remove all entries from the index! + +[setup] + +echo "file 1" > file1 +echo "file 2" > file2 +echo "file 3" > file3 +git add . + +[setup goal] + +echo "file 1" > file1 +echo "file 2" > file2 +echo "file 3" > file3 +git add . + +git update-index --force-remove file1 +git update-index --force-remove file2 +git update-index --force-remove file3 + +[win] + +test "$(git ls-files | wc -l)" -eq 0 diff --git a/levels/internals/index-remove/description b/levels/internals/index-remove/description deleted file mode 100644 index 51643cc..0000000 --- a/levels/internals/index-remove/description +++ /dev/null @@ -1,5 +0,0 @@ -To remove an entry from the index, use a command like this: - - git update-index --force-remove - -Remove all entries from the index! diff --git a/levels/internals/index-remove/goal b/levels/internals/index-remove/goal deleted file mode 100644 index b92645e..0000000 --- a/levels/internals/index-remove/goal +++ /dev/null @@ -1,3 +0,0 @@ -git update-index --force-remove file1 -git update-index --force-remove file2 -git update-index --force-remove file3 diff --git a/levels/internals/index-remove/start b/levels/internals/index-remove/start deleted file mode 100644 index ea458d5..0000000 --- a/levels/internals/index-remove/start +++ /dev/null @@ -1,4 +0,0 @@ -echo "file 1" > file1 -echo "file 2" > file2 -echo "file 3" > file3 -git add . diff --git a/levels/internals/index-remove/win b/levels/internals/index-remove/win deleted file mode 100644 index 43787fa..0000000 --- a/levels/internals/index-remove/win +++ /dev/null @@ -1 +0,0 @@ -test "$(git ls-files | wc -l)" -eq 0 diff --git a/levels/internals/index-update b/levels/internals/index-update new file mode 100644 index 0000000..047493d --- /dev/null +++ b/levels/internals/index-update @@ -0,0 +1,33 @@ +[description] + +Instead of removing an entry from the index and adding one with the same name, you can also directly update that entry! + +Put the content you want in a file with a matching name, and then run + + git update-index + +This will create a new blob, and update the hash of the entry to that blob. + +Update an entry in the index! + +[setup] + +echo "file 1" > file1 +echo "file 2" > file2 +echo "file 3" > file3 +git add . + +[setup goal] + +echo "file 1" > file1 +echo "file 2" > file2 +echo "file 3" > file3 +git add . + +echo "new content" > file1 +git update-index file1 + +[win] + +# This is not really a good test for the winning condition... +test "$(git ls-files -s | git hash-object --stdin)" != "10c4b28623e7e44e09f5a596450a50ab7ac31fbe" -a "$(git ls-files | wc -l)" -eq 3 diff --git a/levels/internals/index-update/description b/levels/internals/index-update/description deleted file mode 100644 index cae3bd3..0000000 --- a/levels/internals/index-update/description +++ /dev/null @@ -1,9 +0,0 @@ -Instead of removing an entry from the index and adding one with the same name, you can also directly update that entry! - -Put the content you want in a file with a matching name, and then run - - git update-index - -This will create a new blob, and update the hash of the entry to that blob. - -Update an entry in the index! diff --git a/levels/internals/index-update/goal b/levels/internals/index-update/goal deleted file mode 100644 index ffeadf6..0000000 --- a/levels/internals/index-update/goal +++ /dev/null @@ -1,2 +0,0 @@ -echo "new content" > file1 -git update-index file1 diff --git a/levels/internals/index-update/start b/levels/internals/index-update/start deleted file mode 100644 index ea458d5..0000000 --- a/levels/internals/index-update/start +++ /dev/null @@ -1,4 +0,0 @@ -echo "file 1" > file1 -echo "file 2" > file2 -echo "file 3" > file3 -git add . diff --git a/levels/internals/index-update/win b/levels/internals/index-update/win deleted file mode 100644 index 2eade0a..0000000 --- a/levels/internals/index-update/win +++ /dev/null @@ -1,2 +0,0 @@ -# This is not really a good test for the winning condition... -test "$(git ls-files -s | git hash-object --stdin)" != "10c4b28623e7e44e09f5a596450a50ab7ac31fbe" -a "$(git ls-files | wc -l)" -eq 3 diff --git a/levels/internals/puzzle-apocalypse b/levels/internals/puzzle-apocalypse new file mode 100644 index 0000000..7e9b6a4 --- /dev/null +++ b/levels/internals/puzzle-apocalypse @@ -0,0 +1,44 @@ +[description] + +Delete all objects in this repository using git commands only! + +Useful commands: + + git prune + git fsck + git reflog expire + +Note: I'm not sure how to beat this level. :D + +[setup] + +echo foo > foo +BLOB=$(git hash-object -w foo) +echo bar > bar +git add . +git commit -m "Initial commit" +echo blabber >> bar +git commit -a -m "Second commit" +git update-ref refs/important HEAD +git update-ref refs/interesting "$BLOB" + +[setup goal] + +echo foo > foo +BLOB=$(git hash-object -w foo) +echo bar > bar +git add . +git commit -m "Initial commit" +echo blabber >> bar +git commit -a -m "Second commit" +git update-ref refs/important HEAD +git update-ref refs/interesting "$BLOB" + +TREE=$(git mktree) +git read-tree $TREE +rm -rf .git/refs/* +rm -rf .git/objects/* + +[win] + +test "$(git cat-file --batch-check --batch-all-objects | wc -l)" -eq 0 diff --git a/levels/internals/puzzle-apocalypse/description b/levels/internals/puzzle-apocalypse/description deleted file mode 100644 index 917154d..0000000 --- a/levels/internals/puzzle-apocalypse/description +++ /dev/null @@ -1,9 +0,0 @@ -Delete all objects in this repository using git commands only! - -Useful commands: - - git prune - git fsck - git reflog expire - -Note: I'm not sure how to beat this level. :D diff --git a/levels/internals/puzzle-apocalypse/goal b/levels/internals/puzzle-apocalypse/goal deleted file mode 100644 index b24313d..0000000 --- a/levels/internals/puzzle-apocalypse/goal +++ /dev/null @@ -1,4 +0,0 @@ -TREE=$(git mktree) -git read-tree $TREE -rm -rf .git/refs/* -rm -rf .git/objects/* diff --git a/levels/internals/puzzle-apocalypse/start b/levels/internals/puzzle-apocalypse/start deleted file mode 100644 index 62fdc47..0000000 --- a/levels/internals/puzzle-apocalypse/start +++ /dev/null @@ -1,9 +0,0 @@ -echo foo > foo -BLOB=$(git hash-object -w foo) -echo bar > bar -git add . -git commit -m "Initial commit" -echo blabber >> bar -git commit -a -m "Second commit" -git update-ref refs/important HEAD -git update-ref refs/interesting "$BLOB" diff --git a/levels/internals/puzzle-apocalypse/win b/levels/internals/puzzle-apocalypse/win deleted file mode 100644 index 3409172..0000000 --- a/levels/internals/puzzle-apocalypse/win +++ /dev/null @@ -1 +0,0 @@ -test "$(git cat-file --batch-check --batch-all-objects | wc -l)" -eq 0 diff --git a/levels/internals/puzzle-precious-blob/win b/levels/internals/puzzle-precious-blob similarity index 52% rename from levels/internals/puzzle-precious-blob/win rename to levels/internals/puzzle-precious-blob index b7f955f..865cfdf 100644 --- a/levels/internals/puzzle-precious-blob/win +++ b/levels/internals/puzzle-precious-blob @@ -1,3 +1,21 @@ +[description] + +Create two trees pointing to the same blob! + +[setup] + +[setup goal] + +BLOB=$(echo "I am precious" | git hash-object -w --stdin) +git update-index --add --cacheinfo 100644,$BLOB,a +git write-tree +git update-index --force-remove a +git update-index --add --cacheinfo 100644,$BLOB,b +git write-tree +git update-index --force-remove b + +[win] + TREES=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | grep tree | cut -f1 -d" ") ALL_TREE_CHILDREN=$(for TREE in $TREES; do diff --git a/levels/internals/puzzle-precious-blob/description b/levels/internals/puzzle-precious-blob/description deleted file mode 100644 index 151d979..0000000 --- a/levels/internals/puzzle-precious-blob/description +++ /dev/null @@ -1 +0,0 @@ -Create two trees pointing to the same blob! diff --git a/levels/internals/puzzle-precious-blob/goal b/levels/internals/puzzle-precious-blob/goal deleted file mode 100644 index 6f7a3b3..0000000 --- a/levels/internals/puzzle-precious-blob/goal +++ /dev/null @@ -1,7 +0,0 @@ -BLOB=$(echo "I am precious" | git hash-object -w --stdin) -git update-index --add --cacheinfo 100644,$BLOB,a -git write-tree -git update-index --force-remove a -git update-index --add --cacheinfo 100644,$BLOB,b -git write-tree -git update-index --force-remove b diff --git a/levels/internals/puzzle-trees-all-the-way-down/win b/levels/internals/puzzle-trees-all-the-way-down similarity index 69% rename from levels/internals/puzzle-trees-all-the-way-down/win rename to levels/internals/puzzle-trees-all-the-way-down index 90fca71..bc3e58a 100644 --- a/levels/internals/puzzle-trees-all-the-way-down/win +++ b/levels/internals/puzzle-trees-all-the-way-down @@ -1,3 +1,19 @@ +[description] + +Construct a chain of three trees, which don't point to anything else. + +This is hard! The `git mktree` command might be useful. + +[setup] + +[setup goal] + +git mktree +TREE=$(echo -e "040000 tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904\tdir" | git mktree) +echo -e "040000 tree $TREE\tdir" | git mktree + +[win] + TREES=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | grep tree | cut -f1 -d" ") for TREE in $TREES; do diff --git a/levels/internals/puzzle-trees-all-the-way-down/description b/levels/internals/puzzle-trees-all-the-way-down/description deleted file mode 100644 index ddbe5b1..0000000 --- a/levels/internals/puzzle-trees-all-the-way-down/description +++ /dev/null @@ -1,3 +0,0 @@ -Construct a chain of three trees, which don't point to anything else. - -This is hard! The `git mktree` command might be useful. diff --git a/levels/internals/puzzle-trees-all-the-way-down/goal b/levels/internals/puzzle-trees-all-the-way-down/goal deleted file mode 100644 index 5e62d7d..0000000 --- a/levels/internals/puzzle-trees-all-the-way-down/goal +++ /dev/null @@ -1,3 +0,0 @@ -git mktree -TREE=$(echo -e "040000 tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904\tdir" | git mktree) -echo -e "040000 tree $TREE\tdir" | git mktree diff --git a/levels/internals/ref-create b/levels/internals/ref-create new file mode 100644 index 0000000..1cc4bcf --- /dev/null +++ b/levels/internals/ref-create @@ -0,0 +1,42 @@ +[description] + +Let's take a look at "refs" (short for "references")! Refs are not objects, but rather very simple *pointers* to objects! They can help you keep track of what's where. + +You can create or update a ref with + + git update-ref refs/ + +Make sure to always start a ref's name with "refs/"! That's a convention that helps Git find all refs you create. If you forget the "refs/", you will not see the ref. + +Create refs that point to all objects in this repository! + +[setup] + +echo hello > hello +echo world > world +BLOB1=$(git hash-object -w hello) +BLOB2=$(git hash-object -w world) +git add . +TREE=$(git write-tree) +COMMIT=$(git commit-tree $TREE -m "Initial commit") + +[setup goal] + +echo hello > hello +echo world > world +BLOB1=$(git hash-object -w hello) +BLOB2=$(git hash-object -w world) +git add . +TREE=$(git write-tree) +COMMIT=$(git commit-tree $TREE -m "Initial commit") + +git update-ref refs/a $BLOB1 +git update-ref refs/b $BLOB2 +git update-ref refs/c $TREE +git update-ref refs/d $COMMIT + +[win] + +OBJECTS=$(git cat-file --batch-check='%(objectname)' --batch-all-objects | sort) +REF_TARGETS=$(git show-ref -s | sort | uniq) +test "$OBJECTS" = "$REF_TARGETS" diff --git a/levels/internals/ref-create/description b/levels/internals/ref-create/description deleted file mode 100644 index f9aeabc..0000000 --- a/levels/internals/ref-create/description +++ /dev/null @@ -1,9 +0,0 @@ -Let's take a look at "refs" (short for "references")! Refs are not objects, but rather very simple *pointers* to objects! They can help you keep track of what's where. - -You can create or update a ref with - - git update-ref refs/ - -Make sure to always start a ref's name with "refs/"! That's a convention that helps Git find all refs you create. If you forget the "refs/", you will not see the ref. - -Create refs that point to all objects in this repository! diff --git a/levels/internals/ref-create/goal b/levels/internals/ref-create/goal deleted file mode 100644 index 01cbb43..0000000 --- a/levels/internals/ref-create/goal +++ /dev/null @@ -1,4 +0,0 @@ -git update-ref refs/a $BLOB1 -git update-ref refs/b $BLOB2 -git update-ref refs/c $TREE -git update-ref refs/d $COMMIT diff --git a/levels/internals/ref-create/start b/levels/internals/ref-create/start deleted file mode 100644 index 3d3857e..0000000 --- a/levels/internals/ref-create/start +++ /dev/null @@ -1,7 +0,0 @@ -echo hello > hello -echo world > world -BLOB1=$(git hash-object -w hello) -BLOB2=$(git hash-object -w world) -git add . -TREE=$(git write-tree) -COMMIT=$(git commit-tree $TREE -m "Initial commit") diff --git a/levels/internals/ref-create/win b/levels/internals/ref-create/win deleted file mode 100644 index 76a1f24..0000000 --- a/levels/internals/ref-create/win +++ /dev/null @@ -1,3 +0,0 @@ -OBJECTS=$(git cat-file --batch-check='%(objectname)' --batch-all-objects | sort) -REF_TARGETS=$(git show-ref -s | sort | uniq) -test "$OBJECTS" = "$REF_TARGETS" diff --git a/levels/internals/ref-move b/levels/internals/ref-move new file mode 100644 index 0000000..e3b29e3 --- /dev/null +++ b/levels/internals/ref-move @@ -0,0 +1,41 @@ +[description] + +You can point refs to a new location using the same command you use to create them: + + git update-ref refs/ + +As an exercise, make all refs in this repository point to the tree object! + +[setup] + +echo hello > hello +echo world > world +BLOB1=$(git hash-object -w hello) +BLOB2=$(git hash-object -w world) +git add . +TREE=$(git write-tree) +COMMIT=$(git commit-tree $TREE -m "Initial commit") + +git update-ref refs/a "$BLOB1" +git update-ref refs/b "$COMMIT" + +[setup goal] + +echo hello > hello +echo world > world +BLOB1=$(git hash-object -w hello) +BLOB2=$(git hash-object -w world) +git add . +TREE=$(git write-tree) +COMMIT=$(git commit-tree $TREE -m "Initial commit") + +git update-ref refs/a "$BLOB1" +git update-ref refs/b "$COMMIT" + +for REF in $(git for-each-ref --format='%(refname)'); do + git update-ref "$REF" "$TREE" +done + +[win] + +test "$(git show-ref -s | sort -u)" = "c7863f72467ed8dd44f4b8ffdb8b57ca7d91dc9e" diff --git a/levels/internals/ref-move/description b/levels/internals/ref-move/description deleted file mode 100644 index 1063cc0..0000000 --- a/levels/internals/ref-move/description +++ /dev/null @@ -1,5 +0,0 @@ -You can point refs to a new location using the same command you use to create them: - - git update-ref refs/ - -As an exercise, make all refs in this repository point to the tree object! diff --git a/levels/internals/ref-move/goal b/levels/internals/ref-move/goal deleted file mode 100644 index a412880..0000000 --- a/levels/internals/ref-move/goal +++ /dev/null @@ -1,3 +0,0 @@ -for REF in $(git for-each-ref --format='%(refname)'); do - git update-ref "$REF" "$TREE" -done diff --git a/levels/internals/ref-move/start b/levels/internals/ref-move/start deleted file mode 100644 index c7fabda..0000000 --- a/levels/internals/ref-move/start +++ /dev/null @@ -1,10 +0,0 @@ -echo hello > hello -echo world > world -BLOB1=$(git hash-object -w hello) -BLOB2=$(git hash-object -w world) -git add . -TREE=$(git write-tree) -COMMIT=$(git commit-tree $TREE -m "Initial commit") - -git update-ref refs/a "$BLOB1" -git update-ref refs/b "$COMMIT" diff --git a/levels/internals/ref-move/win b/levels/internals/ref-move/win deleted file mode 100644 index e792ccf..0000000 --- a/levels/internals/ref-move/win +++ /dev/null @@ -1 +0,0 @@ -test "$(git show-ref -s | sort -u)" = "c7863f72467ed8dd44f4b8ffdb8b57ca7d91dc9e" diff --git a/levels/internals/ref-remove b/levels/internals/ref-remove new file mode 100644 index 0000000..d1fa982 --- /dev/null +++ b/levels/internals/ref-remove @@ -0,0 +1,41 @@ +[description] + +And finally, to delete a ref, use + + git update-ref -d refs/ + +Delete all refs! :P (Well, except for HEAD. HEAD is special.) + +[setup] + +echo hello > hello +echo world > world +BLOB1=$(git hash-object -w hello) +BLOB2=$(git hash-object -w world) +git add . +TREE=$(git write-tree) +COMMIT=$(git commit-tree $TREE -m "Initial commit") + +git update-ref refs/best_blob_ever "$BLOB1" +git update-ref refs/beautiful_commit "$COMMIT" + +[setup goal] + +echo hello > hello +echo world > world +BLOB1=$(git hash-object -w hello) +BLOB2=$(git hash-object -w world) +git add . +TREE=$(git write-tree) +COMMIT=$(git commit-tree $TREE -m "Initial commit") + +git update-ref refs/best_blob_ever "$BLOB1" +git update-ref refs/beautiful_commit "$COMMIT" + +for REF in $(git for-each-ref --format='%(refname)'); do + git update-ref -d "$REF" +done + +[win] + +test "$(git show-ref | wc -l)" -eq 0 diff --git a/levels/internals/ref-remove/description b/levels/internals/ref-remove/description deleted file mode 100644 index d222012..0000000 --- a/levels/internals/ref-remove/description +++ /dev/null @@ -1,5 +0,0 @@ -And finally, to delete a ref, use - - git update-ref -d refs/ - -Delete all refs! :P (Well, except for HEAD. HEAD is special.) diff --git a/levels/internals/ref-remove/goal b/levels/internals/ref-remove/goal deleted file mode 100644 index 12b94d4..0000000 --- a/levels/internals/ref-remove/goal +++ /dev/null @@ -1,3 +0,0 @@ -for REF in $(git for-each-ref --format='%(refname)'); do - git update-ref -d "$REF" -done diff --git a/levels/internals/ref-remove/start b/levels/internals/ref-remove/start deleted file mode 100644 index c7951e3..0000000 --- a/levels/internals/ref-remove/start +++ /dev/null @@ -1,10 +0,0 @@ -echo hello > hello -echo world > world -BLOB1=$(git hash-object -w hello) -BLOB2=$(git hash-object -w world) -git add . -TREE=$(git write-tree) -COMMIT=$(git commit-tree $TREE -m "Initial commit") - -git update-ref refs/best_blob_ever "$BLOB1" -git update-ref refs/beautiful_commit "$COMMIT" diff --git a/levels/internals/ref-remove/win b/levels/internals/ref-remove/win deleted file mode 100644 index af29797..0000000 --- a/levels/internals/ref-remove/win +++ /dev/null @@ -1 +0,0 @@ -test "$(git show-ref | wc -l)" -eq 0 diff --git a/levels/internals/symref-create/description b/levels/internals/symref-create similarity index 57% rename from levels/internals/symref-create/description rename to levels/internals/symref-create index 474b184..da933cb 100644 --- a/levels/internals/symref-create/description +++ b/levels/internals/symref-create @@ -1,3 +1,5 @@ +[description] + Instead of pointing directly to objects, refs can also point to other refs! When that happens, they are called "symbolic refs". You can create or update a symbolic ref using @@ -5,3 +7,15 @@ When that happens, they are called "symbolic refs". You can create or update a s git symbolic-ref Create a symbolic ref called "refs/rainbow"! + +[setup] + +[setup goal] + +BLOB=$(git hash-object -w --stdin) +git update-ref refs/double "$BLOB" +git symbolic-ref refs/rainbow refs/double + +[win] + +git symbolic-ref refs/rainbow diff --git a/levels/internals/symref-create/goal b/levels/internals/symref-create/goal deleted file mode 100644 index c0c3531..0000000 --- a/levels/internals/symref-create/goal +++ /dev/null @@ -1,3 +0,0 @@ -BLOB=$(git hash-object -w --stdin) -git update-ref refs/double "$BLOB" -git symbolic-ref refs/rainbow refs/double diff --git a/levels/internals/symref-create/start b/levels/internals/symref-create/start deleted file mode 100644 index e69de29..0000000 diff --git a/levels/internals/symref-create/win b/levels/internals/symref-create/win deleted file mode 100644 index 5c8e5cf..0000000 --- a/levels/internals/symref-create/win +++ /dev/null @@ -1 +0,0 @@ -git symbolic-ref refs/rainbow diff --git a/levels/internals/symref-no-deref b/levels/internals/symref-no-deref new file mode 100644 index 0000000..458e669 --- /dev/null +++ b/levels/internals/symref-no-deref @@ -0,0 +1,46 @@ +[description] + +When you have a symbolic ref (a ref pointing at another ref), and you decide you want it to be a regular ref again (pointing to an object), you're in for some trouble! :) + +What happens when you try pointing the symbolic ref directly to the blob using `git update-ref`? + +Oops! Turns out that when you reference a symbolic ref, it acts as if you had specified the ref it points to. To de-symbolic-ize it, use the `--no-deref` option directly after `update-ref`! + +Weird, huh? + +[congrats] + +Whew, we've covered a lot of things: Blobs! The index! Trees! Commits! Refs! + +You now know about almost everything about how Git repositories look like on the inside! We think that's pretty cool! :) + +Everything else is just convention and high-level commands that make interacting with the objects more convenient. + +We haven't covered: + +- tag objects (they are the fourth object type - a bit like refs with a description and an author) +- configuration (allows you to specify remote repositories, for example) +- working with local files (which is, uh, arguably pretty important :P) + +Thanks for playing! You're welcome to check out the "puzzle" levels in the dropdown, some of them are more advanced! + +[setup] + +BLOB1=$(echo delicious | git hash-object -w --stdin) +BLOB2=$(echo very | git hash-object -w --stdin) +git update-ref refs/curly "$BLOB1" +git symbolic-ref refs/fries refs/curly + +[setup goal] + +BLOB1=$(echo delicious | git hash-object -w --stdin) +BLOB2=$(echo very | git hash-object -w --stdin) +git update-ref refs/curly "$BLOB1" +git symbolic-ref refs/fries refs/curly + +git update-ref --no-deref refs/fries "$BLOB2" + +[win] + +git symbolic-ref refs/fries && return 1 +test "$(git show-ref -s refs/fries)" = "035e2968dafeea08e46e8fe6743cb8123e8b9aa6" diff --git a/levels/internals/symref-no-deref/congrats b/levels/internals/symref-no-deref/congrats deleted file mode 100644 index fa78278..0000000 --- a/levels/internals/symref-no-deref/congrats +++ /dev/null @@ -1,13 +0,0 @@ -Whew, we've covered a lot of things: Blobs! The index! Trees! Commits! Refs! - -You now know about almost everything about how Git repositories look like on the inside! We think that's pretty cool! :) - -Everything else is just convention and high-level commands that make interacting with the objects more convenient. - -We haven't covered: - -- tag objects (they are the fourth object type - a bit like refs with a description and an author) -- configuration (allows you to specify remote repositories, for example) -- working with local files (which is, uh, arguably pretty important :P) - -Thanks for playing! You're welcome to check out the "puzzle" levels in the dropdown, some of them are more advanced! diff --git a/levels/internals/symref-no-deref/description b/levels/internals/symref-no-deref/description deleted file mode 100644 index dec5e69..0000000 --- a/levels/internals/symref-no-deref/description +++ /dev/null @@ -1,7 +0,0 @@ -When you have a symbolic ref (a ref pointing at another ref), and you decide you want it to be a regular ref again (pointing to an object), you're in for some trouble! :) - -What happens when you try pointing the symbolic ref directly to the blob using `git update-ref`? - -Oops! Turns out that when you reference a symbolic ref, it acts as if you had specified the ref it points to. To de-symbolic-ize it, use the `--no-deref` option directly after `update-ref`! - -Weird, huh? diff --git a/levels/internals/symref-no-deref/goal b/levels/internals/symref-no-deref/goal deleted file mode 100644 index 8a8bf8c..0000000 --- a/levels/internals/symref-no-deref/goal +++ /dev/null @@ -1 +0,0 @@ -git update-ref --no-deref refs/fries "$BLOB2" diff --git a/levels/internals/symref-no-deref/start b/levels/internals/symref-no-deref/start deleted file mode 100644 index d881ece..0000000 --- a/levels/internals/symref-no-deref/start +++ /dev/null @@ -1,4 +0,0 @@ -BLOB1=$(echo delicious | git hash-object -w --stdin) -BLOB2=$(echo very | git hash-object -w --stdin) -git update-ref refs/curly "$BLOB1" -git symbolic-ref refs/fries refs/curly diff --git a/levels/internals/symref-no-deref/win b/levels/internals/symref-no-deref/win deleted file mode 100644 index 2e3e24f..0000000 --- a/levels/internals/symref-no-deref/win +++ /dev/null @@ -1,2 +0,0 @@ -git symbolic-ref refs/fries && return 1 -test "$(git show-ref -s refs/fries)" = "035e2968dafeea08e46e8fe6743cb8123e8b9aa6" diff --git a/levels/internals/tree-create b/levels/internals/tree-create new file mode 100644 index 0000000..3da3618 --- /dev/null +++ b/levels/internals/tree-create @@ -0,0 +1,35 @@ +[description] + +After carefully building the index we want, it would be nice to save a permanent snapshot of it, right? + +This is what the second type of objects is for: trees! You can convert the index into a tree using + + git write-tree + +Try it! :) + +[congrats] + +Nice! + +Can you make a different tree? Modify the index, then call `git write-tree` again! + +[setup] + +echo "file 1" > file1 +echo "file 2" > file2 +echo "file 3" > file3 +git add . + +[setup goal] + +echo "file 1" > file1 +echo "file 2" > file2 +echo "file 3" > file3 +git add . + +git write-tree + +[win] + +git cat-file -p 21a638f28022064c1f1df20844278b494d197979 diff --git a/levels/internals/tree-create/congrats b/levels/internals/tree-create/congrats deleted file mode 100644 index 89498e5..0000000 --- a/levels/internals/tree-create/congrats +++ /dev/null @@ -1,3 +0,0 @@ -Nice! - -Can you make a different tree? Modify the index, then call `git write-tree` again! diff --git a/levels/internals/tree-create/description b/levels/internals/tree-create/description deleted file mode 100644 index c796fb3..0000000 --- a/levels/internals/tree-create/description +++ /dev/null @@ -1,7 +0,0 @@ -After carefully building the index we want, it would be nice to save a permanent snapshot of it, right? - -This is what the second type of objects is for: trees! You can convert the index into a tree using - - git write-tree - -Try it! :) diff --git a/levels/internals/tree-create/goal b/levels/internals/tree-create/goal deleted file mode 100644 index 7654925..0000000 --- a/levels/internals/tree-create/goal +++ /dev/null @@ -1 +0,0 @@ -git write-tree diff --git a/levels/internals/tree-create/start b/levels/internals/tree-create/start deleted file mode 100644 index ea458d5..0000000 --- a/levels/internals/tree-create/start +++ /dev/null @@ -1,4 +0,0 @@ -echo "file 1" > file1 -echo "file 2" > file2 -echo "file 3" > file3 -git add . diff --git a/levels/internals/tree-create/win b/levels/internals/tree-create/win deleted file mode 100644 index cc00b1c..0000000 --- a/levels/internals/tree-create/win +++ /dev/null @@ -1 +0,0 @@ -git cat-file -p 21a638f28022064c1f1df20844278b494d197979 diff --git a/levels/internals/tree-nested/win b/levels/internals/tree-nested similarity index 54% rename from levels/internals/tree-nested/win rename to levels/internals/tree-nested index e6f6488..c7afce8 100644 --- a/levels/internals/tree-nested/win +++ b/levels/internals/tree-nested @@ -1,3 +1,25 @@ +[description] + +Trees can also point to other trees! This way, they can describe nested directory structures. + +When you add a file inside of a directory to the index, and then call `git write-tree`, it will create a nested tree for the directory, and attach the blob to it. + +To solve this level, build a little stick figure, as shown on the left - a tree that points to two blobs, as well to a tree that points to two blobs. + +[setup] + +[setup goal] + +echo "I'm the left arm" > arm1 +echo "I'm the right arm" > arm2 +mkdir hip +echo "I'm the left leg" > hip/leg1 +echo "I'm the right leg" > hip/leg2 +git add . +git write-tree + +[win] + TREES=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | grep tree | cut -f1 -d" ") for OUTER_TREE in $TREES; do diff --git a/levels/internals/tree-nested/description b/levels/internals/tree-nested/description deleted file mode 100644 index b456b16..0000000 --- a/levels/internals/tree-nested/description +++ /dev/null @@ -1,5 +0,0 @@ -Trees can also point to other trees! This way, they can describe nested directory structures. - -When you add a file inside of a directory to the index, and then call `git write-tree`, it will create a nested tree for the directory, and attach the blob to it. - -To solve this level, build a little stick figure, as shown on the left - a tree that points to two blobs, as well to a tree that points to two blobs. diff --git a/levels/internals/tree-nested/goal b/levels/internals/tree-nested/goal deleted file mode 100644 index dfb9bef..0000000 --- a/levels/internals/tree-nested/goal +++ /dev/null @@ -1,7 +0,0 @@ -echo "I'm the left arm" > arm1 -echo "I'm the right arm" > arm2 -mkdir hip -echo "I'm the left leg" > hip/leg1 -echo "I'm the right leg" > hip/leg2 -git add . -git write-tree diff --git a/levels/internals/tree-nested/start b/levels/internals/tree-nested/start deleted file mode 100644 index e69de29..0000000 diff --git a/levels/internals/tree-read b/levels/internals/tree-read new file mode 100644 index 0000000..ba8c440 --- /dev/null +++ b/levels/internals/tree-read @@ -0,0 +1,51 @@ +[description] + +As soon as you have some tree objects, you can always read them and set the index exactly to their content! Unsurprisingly, the command is called + + git read-tree + +For , you can provide the hash of any tree object - you can right-click one to insert its hash into the terminal! + +Try reading some of the trees in this repository into the index! + +[setup] + +EMPTY_TREE=$(git write-tree) + +echo "file 1" > file1 +echo "file 2" > file2 +git add . +git write-tree + +rm * +echo "file A" > fileA +echo "file B" > fileB +echo "file C" > fileC +git add . +TRIPLE_TREE=$(git write-tree) + +git read-tree "$EMPTY_TREE" + +[setup goal] + +EMPTY_TREE=$(git write-tree) + +echo "file 1" > file1 +echo "file 2" > file2 +git add . +git write-tree + +rm * +echo "file A" > fileA +echo "file B" > fileB +echo "file C" > fileC +git add . +TRIPLE_TREE=$(git write-tree) + +git read-tree "$EMPTY_TREE" + +git read-tree "$TRIPLE_TREE" + +[win] + +test "$(git ls-files | wc -l)" -gt 0 diff --git a/levels/internals/tree-read/description b/levels/internals/tree-read/description deleted file mode 100644 index 49b2e0f..0000000 --- a/levels/internals/tree-read/description +++ /dev/null @@ -1,7 +0,0 @@ -As soon as you have some tree objects, you can always read them and set the index exactly to their content! Unsurprisingly, the command is called - - git read-tree - -For , you can provide the hash of any tree object - you can right-click one to insert its hash into the terminal! - -Try reading some of the trees in this repository into the index! diff --git a/levels/internals/tree-read/goal b/levels/internals/tree-read/goal deleted file mode 100644 index 886a13a..0000000 --- a/levels/internals/tree-read/goal +++ /dev/null @@ -1 +0,0 @@ -git read-tree "$TRIPLE_TREE" diff --git a/levels/internals/tree-read/start b/levels/internals/tree-read/start deleted file mode 100644 index 990418e..0000000 --- a/levels/internals/tree-read/start +++ /dev/null @@ -1,15 +0,0 @@ -EMPTY_TREE=$(git write-tree) - -echo "file 1" > file1 -echo "file 2" > file2 -git add . -git write-tree - -rm * -echo "file A" > fileA -echo "file B" > fileB -echo "file C" > fileC -git add . -TRIPLE_TREE=$(git write-tree) - -git read-tree "$EMPTY_TREE" diff --git a/levels/internals/tree-read/win b/levels/internals/tree-read/win deleted file mode 100644 index 15bbb04..0000000 --- a/levels/internals/tree-read/win +++ /dev/null @@ -1 +0,0 @@ -test "$(git ls-files | wc -l)" -gt 0 diff --git a/levels/internals/welcome/description b/levels/internals/welcome similarity index 50% rename from levels/internals/welcome/description rename to levels/internals/welcome index 72bfb8d..7a6b172 100644 --- a/levels/internals/welcome/description +++ b/levels/internals/welcome @@ -1,3 +1,5 @@ +[description] + This is prototype #1 for the Git learning game by @bleeptrack and @blinry. Thanks for checking it out! <3 You can interact with the repository on the right by typing Bash commands in the terminal below! The visualization will show you its internal status. @@ -5,3 +7,27 @@ You can interact with the repository on the right by typing Bash commands in the Let's get started by initializing an empty Git repository in the current directory by typing: git init + +[congrats] + +Well done! + +An empty Git repository is... well, quite empty. The only thing that always exists is a reference called "HEAD" - we'll learn what that is later! + +But first, let's look at some basics! + +(Click "Next Level" as soon as you're ready!) + +[setup] + +rm -rf .git + +[setup goal] + +rm -rf .git + +git init + +[win] + +test -d .git diff --git a/levels/internals/welcome/congrats b/levels/internals/welcome/congrats deleted file mode 100644 index 3fff8eb..0000000 --- a/levels/internals/welcome/congrats +++ /dev/null @@ -1,7 +0,0 @@ -Well done! - -An empty Git repository is... well, quite empty. The only thing that always exists is a reference called "HEAD" - we'll learn what that is later! - -But first, let's look at some basics! - -(Click "Next Level" as soon as you're ready!) diff --git a/levels/internals/welcome/goal b/levels/internals/welcome/goal deleted file mode 100644 index e9be2cf..0000000 --- a/levels/internals/welcome/goal +++ /dev/null @@ -1 +0,0 @@ -git init diff --git a/levels/internals/welcome/start b/levels/internals/welcome/start deleted file mode 100644 index 4405c9e..0000000 --- a/levels/internals/welcome/start +++ /dev/null @@ -1 +0,0 @@ -rm -rf .git diff --git a/levels/internals/welcome/win b/levels/internals/welcome/win deleted file mode 100644 index 714ec2c..0000000 --- a/levels/internals/welcome/win +++ /dev/null @@ -1 +0,0 @@ -test -d .git