mirror of
https://github.com/git-learning-game/oh-my-git.git
synced 2024-11-22 16:20:19 +01:00
Convert "internal" levels to new level format
This commit is contained in:
parent
613b1b9852
commit
53a6885ef9
108 changed files with 727 additions and 382 deletions
26
levels/internals/basics
Normal file
26
levels/internals/basics
Normal file
|
@ -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"
|
|
@ -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. :)
|
|
|
@ -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"!
|
|
|
@ -1,3 +0,0 @@
|
||||||
mkdir riddle
|
|
||||||
echo "ppl p" > riddle/consonants
|
|
||||||
echo "ae ie" > riddle/vowels
|
|
|
@ -1 +0,0 @@
|
||||||
cat answer | grep -i "apple \\?pie"
|
|
38
levels/internals/blob-create
Normal file
38
levels/internals/blob-create
Normal file
|
@ -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 <file>
|
||||||
|
|
||||||
|
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
|
|
@ -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? :)
|
|
|
@ -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 <file>
|
|
||||||
|
|
||||||
The flag -w means "write", and tells Git to actually write the new blob to the disk.
|
|
||||||
|
|
||||||
Create three new blobs!
|
|
|
@ -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
|
|
|
@ -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
|
|
27
levels/internals/blob-remove
Normal file
27
levels/internals/blob-remove
Normal file
|
@ -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
|
|
@ -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.
|
|
|
@ -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.
|
|
|
@ -1 +0,0 @@
|
||||||
git prune
|
|
|
@ -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
|
|
|
@ -1,3 +0,0 @@
|
||||||
OBJECT_COUNT=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | wc -l)
|
|
||||||
|
|
||||||
test "$OBJECT_COUNT" -eq 0
|
|
37
levels/internals/commit-create
Normal file
37
levels/internals/commit-create
Normal file
|
@ -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 <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
|
|
@ -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 <tree> -m "Description of your commit"
|
|
||||||
|
|
||||||
Make a commit from the tree in this repository!
|
|
|
@ -1 +0,0 @@
|
||||||
git commit-tree 3185 -m 'Clever commit message'
|
|
|
@ -1,6 +0,0 @@
|
||||||
touch empty_file
|
|
||||||
git add .
|
|
||||||
git write-tree
|
|
||||||
|
|
||||||
rm empty_file
|
|
||||||
git update-index --remove empty_file
|
|
|
@ -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
|
|
31
levels/internals/commit-parents
Normal file
31
levels/internals/commit-parents
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
[description]
|
||||||
|
|
||||||
|
When using the commit-tree command, you can optionally specify a parent:
|
||||||
|
|
||||||
|
git commit-tree <tree> -m "Description" -p <parent commit>
|
||||||
|
|
||||||
|
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
|
|
@ -1,7 +0,0 @@
|
||||||
When using the commit-tree command, you can optionally specify a parent:
|
|
||||||
|
|
||||||
git commit-tree <tree> -m "Description" -p <parent commit>
|
|
||||||
|
|
||||||
Make a string of three commits!
|
|
||||||
|
|
||||||
Hint: You'll need a tree object. What could be the easiest way to obtain one?
|
|
|
@ -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/')
|
|
|
@ -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
|
|
30
levels/internals/commit-rhombus
Normal file
30
levels/internals/commit-rhombus
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
[description]
|
||||||
|
|
||||||
|
A commit can have multiple parents! You can specify the -p option multiple times, like this:
|
||||||
|
|
||||||
|
git commit-tree <tree> -m "Description" -p <parent1> -p <parent2>
|
||||||
|
|
||||||
|
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
|
|
@ -1,5 +0,0 @@
|
||||||
A commit can have multiple parents! You can specify the -p option multiple times, like this:
|
|
||||||
|
|
||||||
git commit-tree <tree> -m "Description" -p <parent1> -p <parent2>
|
|
||||||
|
|
||||||
Build a rhombus shape from commits, where two commits point to the same parent, and then a fourth commit points to both of them.
|
|
|
@ -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)
|
|
|
@ -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
|
|
43
levels/internals/conflict
Normal file
43
levels/internals/conflict
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
[description]
|
||||||
|
|
||||||
|
(This is not a real puzzle yet.)
|
||||||
|
|
||||||
|
Try merging the two branches together!
|
||||||
|
|
||||||
|
git merge <otherbranch>
|
||||||
|
|
||||||
|
[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
|
|
@ -1,5 +0,0 @@
|
||||||
(This is not a real puzzle yet.)
|
|
||||||
|
|
||||||
Try merging the two branches together!
|
|
||||||
|
|
||||||
git merge <otherbranch>
|
|
|
@ -1,5 +0,0 @@
|
||||||
git merge alternative
|
|
||||||
echo blue-green > bikeshed_color
|
|
||||||
git add .
|
|
||||||
git commit -m "Merge"
|
|
||||||
git prune
|
|
|
@ -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
|
|
37
levels/internals/index-add
Normal file
37
levels/internals/index-add
Normal file
|
@ -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 <mode>,<blobhash>,<name>
|
||||||
|
|
||||||
|
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
|
|
@ -1,9 +0,0 @@
|
||||||
There's another way to add an entry to the index directly:
|
|
||||||
|
|
||||||
git update-index --add --cacheinfo <mode>,<blobhash>,<name>
|
|
||||||
|
|
||||||
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! :)
|
|
|
@ -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"?
|
|
|
@ -1,4 +0,0 @@
|
||||||
echo "file 1" > file1
|
|
||||||
echo "file 2" > file2
|
|
||||||
echo "file 3" > file3
|
|
||||||
git add .
|
|
|
@ -1 +0,0 @@
|
||||||
test "$(git ls-files | wc -l)" -ge 3
|
|
29
levels/internals/index-remove
Normal file
29
levels/internals/index-remove
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
[description]
|
||||||
|
|
||||||
|
To remove an entry from the index, use a command like this:
|
||||||
|
|
||||||
|
git update-index --force-remove <file>
|
||||||
|
|
||||||
|
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
|
|
@ -1,5 +0,0 @@
|
||||||
To remove an entry from the index, use a command like this:
|
|
||||||
|
|
||||||
git update-index --force-remove <file>
|
|
||||||
|
|
||||||
Remove all entries from the index!
|
|
|
@ -1,3 +0,0 @@
|
||||||
git update-index --force-remove file1
|
|
||||||
git update-index --force-remove file2
|
|
||||||
git update-index --force-remove file3
|
|
|
@ -1,4 +0,0 @@
|
||||||
echo "file 1" > file1
|
|
||||||
echo "file 2" > file2
|
|
||||||
echo "file 3" > file3
|
|
||||||
git add .
|
|
|
@ -1 +0,0 @@
|
||||||
test "$(git ls-files | wc -l)" -eq 0
|
|
33
levels/internals/index-update
Normal file
33
levels/internals/index-update
Normal file
|
@ -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 <file>
|
||||||
|
|
||||||
|
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
|
|
@ -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 <file>
|
|
||||||
|
|
||||||
This will create a new blob, and update the hash of the entry to that blob.
|
|
||||||
|
|
||||||
Update an entry in the index!
|
|
|
@ -1,2 +0,0 @@
|
||||||
echo "new content" > file1
|
|
||||||
git update-index file1
|
|
|
@ -1,4 +0,0 @@
|
||||||
echo "file 1" > file1
|
|
||||||
echo "file 2" > file2
|
|
||||||
echo "file 3" > file3
|
|
||||||
git add .
|
|
|
@ -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
|
|
44
levels/internals/puzzle-apocalypse
Normal file
44
levels/internals/puzzle-apocalypse
Normal file
|
@ -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
|
|
@ -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
|
|
|
@ -1,4 +0,0 @@
|
||||||
TREE=$(git mktree)
|
|
||||||
git read-tree $TREE
|
|
||||||
rm -rf .git/refs/*
|
|
||||||
rm -rf .git/objects/*
|
|
|
@ -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"
|
|
|
@ -1 +0,0 @@
|
||||||
test "$(git cat-file --batch-check --batch-all-objects | wc -l)" -eq 0
|
|
|
@ -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" ")
|
TREES=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | grep tree | cut -f1 -d" ")
|
||||||
|
|
||||||
ALL_TREE_CHILDREN=$(for TREE in $TREES; do
|
ALL_TREE_CHILDREN=$(for TREE in $TREES; do
|
|
@ -1 +0,0 @@
|
||||||
Create two trees pointing to the same blob!
|
|
|
@ -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
|
|
|
@ -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" ")
|
TREES=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | grep tree | cut -f1 -d" ")
|
||||||
|
|
||||||
for TREE in $TREES; do
|
for TREE in $TREES; do
|
|
@ -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.
|
|
|
@ -1,3 +0,0 @@
|
||||||
git mktree
|
|
||||||
TREE=$(echo -e "040000 tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904\tdir" | git mktree)
|
|
||||||
echo -e "040000 tree $TREE\tdir" | git mktree
|
|
42
levels/internals/ref-create
Normal file
42
levels/internals/ref-create
Normal file
|
@ -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/<refname> <newvalue>
|
||||||
|
|
||||||
|
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"
|
|
@ -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/<refname> <newvalue>
|
|
||||||
|
|
||||||
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!
|
|
|
@ -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
|
|
|
@ -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")
|
|
|
@ -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"
|
|
41
levels/internals/ref-move
Normal file
41
levels/internals/ref-move
Normal file
|
@ -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/<refname> <object>
|
||||||
|
|
||||||
|
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"
|
|
@ -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/<refname> <object>
|
|
||||||
|
|
||||||
As an exercise, make all refs in this repository point to the tree object!
|
|
|
@ -1,3 +0,0 @@
|
||||||
for REF in $(git for-each-ref --format='%(refname)'); do
|
|
||||||
git update-ref "$REF" "$TREE"
|
|
||||||
done
|
|
|
@ -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"
|
|
|
@ -1 +0,0 @@
|
||||||
test "$(git show-ref -s | sort -u)" = "c7863f72467ed8dd44f4b8ffdb8b57ca7d91dc9e"
|
|
41
levels/internals/ref-remove
Normal file
41
levels/internals/ref-remove
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
[description]
|
||||||
|
|
||||||
|
And finally, to delete a ref, use
|
||||||
|
|
||||||
|
git update-ref -d refs/<refname>
|
||||||
|
|
||||||
|
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
|
|
@ -1,5 +0,0 @@
|
||||||
And finally, to delete a ref, use
|
|
||||||
|
|
||||||
git update-ref -d refs/<refname>
|
|
||||||
|
|
||||||
Delete all refs! :P (Well, except for HEAD. HEAD is special.)
|
|
|
@ -1,3 +0,0 @@
|
||||||
for REF in $(git for-each-ref --format='%(refname)'); do
|
|
||||||
git update-ref -d "$REF"
|
|
||||||
done
|
|
|
@ -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"
|
|
|
@ -1 +0,0 @@
|
||||||
test "$(git show-ref | wc -l)" -eq 0
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
[description]
|
||||||
|
|
||||||
Instead of pointing directly to objects, refs can also point to other refs!
|
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
|
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 <name> <ref>
|
git symbolic-ref <name> <ref>
|
||||||
|
|
||||||
Create a symbolic ref called "refs/rainbow"!
|
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
|
|
@ -1,3 +0,0 @@
|
||||||
BLOB=$(git hash-object -w --stdin)
|
|
||||||
git update-ref refs/double "$BLOB"
|
|
||||||
git symbolic-ref refs/rainbow refs/double
|
|
|
@ -1 +0,0 @@
|
||||||
git symbolic-ref refs/rainbow
|
|
46
levels/internals/symref-no-deref
Normal file
46
levels/internals/symref-no-deref
Normal file
|
@ -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"
|
|
@ -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!
|
|
|
@ -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?
|
|
|
@ -1 +0,0 @@
|
||||||
git update-ref --no-deref refs/fries "$BLOB2"
|
|
|
@ -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
|
|
|
@ -1,2 +0,0 @@
|
||||||
git symbolic-ref refs/fries && return 1
|
|
||||||
test "$(git show-ref -s refs/fries)" = "035e2968dafeea08e46e8fe6743cb8123e8b9aa6"
|
|
35
levels/internals/tree-create
Normal file
35
levels/internals/tree-create
Normal file
|
@ -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
|
|
@ -1,3 +0,0 @@
|
||||||
Nice!
|
|
||||||
|
|
||||||
Can you make a different tree? Modify the index, then call `git write-tree` again!
|
|
|
@ -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! :)
|
|
|
@ -1 +0,0 @@
|
||||||
git write-tree
|
|
|
@ -1,4 +0,0 @@
|
||||||
echo "file 1" > file1
|
|
||||||
echo "file 2" > file2
|
|
||||||
echo "file 3" > file3
|
|
||||||
git add .
|
|
|
@ -1 +0,0 @@
|
||||||
git cat-file -p 21a638f28022064c1f1df20844278b494d197979
|
|
|
@ -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" ")
|
TREES=$(git cat-file --batch-check='%(objectname) %(objecttype)' --batch-all-objects | grep tree | cut -f1 -d" ")
|
||||||
|
|
||||||
for OUTER_TREE in $TREES; do
|
for OUTER_TREE in $TREES; do
|
|
@ -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.
|
|
|
@ -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
|
|
51
levels/internals/tree-read
Normal file
51
levels/internals/tree-read
Normal file
|
@ -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 <tree>
|
||||||
|
|
||||||
|
For <tree>, 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
|
|
@ -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 <tree>
|
|
||||||
|
|
||||||
For <tree>, 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!
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue