mirror of
https://github.com/martinvonz/jj.git
synced 2024-09-11 05:45:30 +03:00
demos: replace asciinema by screenshots
The demos don't need to be animated - the user wouldn't miss anything if they skipped to the end. So let's just show the full output so the user can read through it at their own pace. We could use plain text, but I think the colors are helpful, so I went with screenshots. Closes #166.
This commit is contained in:
parent
305cb3a7ee
commit
986fced69e
22
README.md
22
README.md
@ -52,9 +52,7 @@ backend (the only minor reason might be
|
||||
The backend exists mainly to make sure that it's possible to eventually add
|
||||
functionality that cannot easily be added to the Git backend.
|
||||
|
||||
<a href="https://asciinema.org/a/dY2XBEEplPacf25Vv9K8oRFPk" target="_blank">
|
||||
<img src="https://asciinema.org/a/dY2XBEEplPacf25Vv9K8oRFPk.svg" />
|
||||
</a>
|
||||
<img src="demos/git_compat.png" />
|
||||
|
||||
### The working copy is automatically committed
|
||||
|
||||
@ -64,9 +62,7 @@ working copy or any other commit. It also means that you can always check out a
|
||||
different commit without first explicitly committing the working copy changes
|
||||
(you can even check out a different commit while resolving merge conflicts).
|
||||
|
||||
<a href="https://asciinema.org/a/Jdl9xjbVXlbvUd3qS0410IHtL" target="_blank">
|
||||
<img src="https://asciinema.org/a/Jdl9xjbVXlbvUd3qS0410IHtL.svg" />
|
||||
</a>
|
||||
<img src="demos/working_copy.png" />
|
||||
|
||||
### Operations update the repo first, then possibly the working copy
|
||||
|
||||
@ -81,9 +77,7 @@ the repo state after the operation. This means that you can easily revert to an
|
||||
earlier repo state, or to simply undo a particular operation (which does not
|
||||
necessarily have to be the most recent operation).
|
||||
|
||||
<a href="https://asciinema.org/a/oR7ME5dz8T6UmZ9nXOcPs14YZ" target="_blank">
|
||||
<img src="https://asciinema.org/a/oR7ME5dz8T6UmZ9nXOcPs14YZ.svg" />
|
||||
</a>
|
||||
<img src="demos/operation_log.png" />
|
||||
|
||||
### Conflicts can be recorded in commits
|
||||
|
||||
@ -95,14 +89,12 @@ resolving conflicts, regardless of which command caused them. This design also
|
||||
lets Jujutsu rebase merge commits correctly (unlike both Git and Mercurial).
|
||||
|
||||
Basic conflict resolution:
|
||||
<a href="https://asciinema.org/a/CmW8lBnypVuxCxvCcxhLDyUUL" target="_blank">
|
||||
<img src="https://asciinema.org/a/CmW8lBnypVuxCxvCcxhLDyUUL.svg" />
|
||||
</a>
|
||||
|
||||
<img src="demos/resolve_conflicts.png" />
|
||||
|
||||
Juggling conflicts:
|
||||
<a href="https://asciinema.org/a/Havui1xG7x95MhzTJU0Ei1WfZ" target="_blank">
|
||||
<img src="https://asciinema.org/a/Havui1xG7x95MhzTJU0Ei1WfZ.svg" />
|
||||
</a>
|
||||
|
||||
<img src="demos/juggle_conflicts.png" />
|
||||
|
||||
### Automatic rebase
|
||||
|
||||
|
@ -1,21 +1,16 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
. "$(dirname "$0")"/demo_helpers.sh
|
||||
parse_args "$@"
|
||||
|
||||
new_tmp_dir
|
||||
|
||||
run_demo 'Clone a Git repo' '
|
||||
run_command "# Clone a Git repo:"
|
||||
comment "Clone a Git repo:"
|
||||
run_command "jj git clone https://github.com/octocat/Hello-World"
|
||||
run_command "cd Hello-World"
|
||||
pause 1
|
||||
run_command "# Inspect it:"
|
||||
pause 1
|
||||
run_command "jj log -r '\''all()'\''"
|
||||
pause 5
|
||||
|
||||
comment "Inspect it:"
|
||||
run_command "jj log -r 'all()'"
|
||||
run_command "jj diff -r b1"
|
||||
pause 2
|
||||
run_command "# The repo is backed by the actual Git repo:"
|
||||
|
||||
comment "The repo is backed by the actual Git repo:"
|
||||
run_command "git --git-dir=.jj/repo/store/git log --graph --all --decorate --oneline"
|
||||
'
|
||||
|
@ -1,43 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
BASE_DIR=$(realpath "$(dirname "$0")")
|
||||
|
||||
UPLOAD=false
|
||||
PREVIEW=false
|
||||
DEBUG=false
|
||||
FAST=false
|
||||
parse_args() {
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
-h|--help)
|
||||
echo 'Run a given demo.
|
||||
Arguments:
|
||||
--preview: Preview the asciicast.
|
||||
--upload: Upload to asciinema (after previewing, if necessary).
|
||||
--debug: Show the asciicast as it is being recorded. Note that what you see
|
||||
will not be exactly the same as what is recorded.
|
||||
'
|
||||
exit
|
||||
;;
|
||||
--upload)
|
||||
UPLOAD=true
|
||||
;;
|
||||
--preview)
|
||||
PREVIEW=true
|
||||
;;
|
||||
--debug)
|
||||
DEBUG=true
|
||||
;;
|
||||
--fast)
|
||||
FAST=true
|
||||
;;
|
||||
*)
|
||||
echo "Unrecognized argument: $arg"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
new_tmp_dir() {
|
||||
local dirname
|
||||
@ -47,45 +9,18 @@ new_tmp_dir() {
|
||||
trap "rm -rf '$dirname'" EXIT
|
||||
}
|
||||
|
||||
run_demo() {
|
||||
local title="$1"
|
||||
local test_script="$2"
|
||||
local fast=""
|
||||
if [[ "$FAST" == true ]]; then
|
||||
fast="set send_human {0.005 0.01 1 0.005 0.1}
|
||||
proc pause {duration} {
|
||||
sleep [expr \$duration / 10.0]
|
||||
run_command() {
|
||||
echo "\$ $@"
|
||||
eval "$@"
|
||||
}
|
||||
"
|
||||
fi
|
||||
local expect_script="source $BASE_DIR/demo_helpers.tcl
|
||||
$fast
|
||||
spawn asciinema rec -c \"PS1='$ ' bash --norc\" --title \"$title\"
|
||||
expect_prompt
|
||||
$test_script
|
||||
quit_and_dump_asciicast_path
|
||||
"
|
||||
|
||||
if [[ "$DEBUG" == true ]]; then
|
||||
echo "$expect_script" | /usr/bin/env expect
|
||||
return
|
||||
fi
|
||||
|
||||
echo "Recording demo (terminal size is $(tput cols)x$(tput lines))..."
|
||||
if [[ "$PREVIEW" == 'false' ]]; then
|
||||
echo '(Pass --preview to play the demo automatically once done)'
|
||||
fi
|
||||
local asciicast_path
|
||||
asciicast_path=$(echo "$expect_script" | /usr/bin/env expect | tail -1)
|
||||
echo "$asciicast_path"
|
||||
|
||||
if [[ "$PREVIEW" == 'true' ]]; then
|
||||
asciinema play "$asciicast_path"
|
||||
fi
|
||||
if [[ "$UPLOAD" == 'true' ]]; then
|
||||
if [[ "$PREVIEW" == 'true' ]] && ! confirm "Upload?"; then
|
||||
return
|
||||
fi
|
||||
: asciinema upload "$asciicast_path"
|
||||
fi
|
||||
blank() {
|
||||
echo ""
|
||||
}
|
||||
|
||||
comment() {
|
||||
indented="$(echo "$@"| sed 's/^/# /g')"
|
||||
blank
|
||||
echo -e "\033[0;32m${indented}\033[0m"
|
||||
blank
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
set send_human {0.05 0.1 1 0.05 1}
|
||||
set timeout 2
|
||||
|
||||
proc pause {duration} {
|
||||
sleep $duration
|
||||
}
|
||||
|
||||
proc expect_prompt {} {
|
||||
expect "$ "
|
||||
}
|
||||
|
||||
proc run_command {cmd} {
|
||||
send -h "$cmd"
|
||||
send "\r"
|
||||
expect -timeout 5 "$ "
|
||||
}
|
||||
|
||||
proc quit_and_dump_asciicast_path {} {
|
||||
set CTRLC \003
|
||||
set CTRLD \004
|
||||
set ESC \033
|
||||
|
||||
send $CTRLD
|
||||
expect "asciinema: recording finished"
|
||||
sleep 1
|
||||
send $CTRLC
|
||||
expect -re "asciicast saved to (.+)$ESC.*\r" {
|
||||
send_user "$expect_out(1,string)\n"
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
. "$(dirname "$0")"/demo_helpers.sh
|
||||
parse_args "$@"
|
||||
|
||||
new_tmp_dir
|
||||
jj init
|
||||
@ -15,46 +14,33 @@ echo "third" > file
|
||||
jj branch create third
|
||||
jj close -m 'third'
|
||||
|
||||
run_demo 'Juggling conflicts' '
|
||||
run_command "# We are in a repo with three commits, all"
|
||||
run_command "# editing the same line:"
|
||||
comment "We are in a repo with three commits, all
|
||||
editing the same line:"
|
||||
run_command "jj log"
|
||||
pause 3
|
||||
|
||||
run_command "jj diff -r first"
|
||||
pause 1
|
||||
run_command "jj diff -r second"
|
||||
pause 1
|
||||
run_command "jj diff -r third"
|
||||
run_command ""
|
||||
pause 2
|
||||
|
||||
run_command "# Let'\''s reorder the second and third commits:"
|
||||
comment "Let's reorder the second and third commits:"
|
||||
run_command "jj rebase -s third -d first"
|
||||
run_command "jj rebase -s second -d third"
|
||||
run_command "jj log"
|
||||
pause 3
|
||||
run_command "# The commit labeled \"third\" has a conflict,"
|
||||
run_command "# as expected. What'\''s more interesting is"
|
||||
run_command "# that the top commit has no conflict! That'\''s"
|
||||
run_command "# because it has the changes from all three"
|
||||
run_command "# commits applied to it."
|
||||
run_command ""
|
||||
pause 5
|
||||
comment "The commit labeled \"third\" has a conflict,
|
||||
as expected. What's more interesting is
|
||||
that the top commit has no conflict! That's
|
||||
because it has the changes from all three
|
||||
commits applied to it."
|
||||
|
||||
run_command "# Let'\''s verify that by looking at its contents:"
|
||||
comment "Let's verify that by looking at its contents:"
|
||||
run_command "jj co second"
|
||||
run_command "cat file"
|
||||
run_command ""
|
||||
pause 3
|
||||
|
||||
run_command "# Let'\''s now instead make \"second\" and \"third\""
|
||||
run_command "# sibling and merge them:"
|
||||
comment "Let's now instead make \"second\" and \"third\"
|
||||
sibling and merge them:"
|
||||
run_command "jj rebase -s second -d first"
|
||||
run_command "jj merge second third -m merged"
|
||||
run_command "jj log"
|
||||
pause 3
|
||||
run_command "# Again, because the merge commit has the"
|
||||
run_command "# changes from all three commits, it has no"
|
||||
run_command "# conflict."
|
||||
'
|
||||
comment "Again, because the merge commit has the
|
||||
changes from all three commits, it has no
|
||||
conflict."
|
||||
|
@ -1,67 +1,53 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
. "$(dirname "$0")"/demo_helpers.sh
|
||||
parse_args "$@"
|
||||
|
||||
new_tmp_dir
|
||||
jj git clone https://github.com/octocat/Hello-World
|
||||
cd Hello-World
|
||||
|
||||
run_demo 'The entire repo is under version control' '
|
||||
run_command "# We are in the octocat/Hello-World repo."
|
||||
run_command "# The \"operation log\" shows the operations"
|
||||
run_command "# so far:"
|
||||
comment "We are in the octocat/Hello-World repo.
|
||||
The \"operation log\" shows the operations
|
||||
so far:"
|
||||
run_command "jj op log"
|
||||
pause 7
|
||||
run_command "# We are going to make some changes to show"
|
||||
run_command "# how the operation log works."
|
||||
run_command "# We are currently working off of the \"master\""
|
||||
run_command "# branch:"
|
||||
|
||||
comment "We are going to make some changes to show
|
||||
how the operation log works.
|
||||
We are currently working off of the \"master\"
|
||||
branch:"
|
||||
run_command "jj log"
|
||||
pause 5
|
||||
run_command "# Let'\''s add a file, set a description, and"
|
||||
run_command "# rebase onto the \"test\" branch:"
|
||||
|
||||
comment "Let's add a file, set a description, and
|
||||
rebase onto the \"test\" branch:"
|
||||
run_command "echo stuff > new-file"
|
||||
pause 2
|
||||
run_command "jj describe -m stuff"
|
||||
pause 2
|
||||
run_command "jj rebase -d test"
|
||||
pause 2
|
||||
run_command ""
|
||||
run_command "# We are now going to make another change off of"
|
||||
run_command "# master:"
|
||||
|
||||
comment "We are now going to make another change off of
|
||||
master:"
|
||||
sleep 1
|
||||
run_command "jj co master"
|
||||
pause 1
|
||||
run_command "jj describe -m \"other stuff\""
|
||||
pause 2
|
||||
run_command "# The repo now looks like this:"
|
||||
|
||||
comment "The repo now looks like this:"
|
||||
run_command "jj log"
|
||||
pause 5
|
||||
run_command "# And the operation log looks like this:"
|
||||
send -h "jj op log\r"
|
||||
# Capture the third latest operation id (skipping color codes around it)
|
||||
expect -re "o ..34m(.*?)..0m "
|
||||
expect -re "o ..34m(.*?)..0m "
|
||||
set rebase_op $expect_out(1,string)
|
||||
expect_prompt
|
||||
pause 7
|
||||
run_command ""
|
||||
run_command "# Let'\''s undo that rebase operation:"
|
||||
|
||||
comment "Let's undo that rebase operation:"
|
||||
rebase_op=$(jj --color=never op log | grep 'o ' | sed '3q;d' | cut -b3-15)
|
||||
run_command "jj undo $rebase_op"
|
||||
pause 3
|
||||
run_command "# The \"stuff\" change is now back on master as"
|
||||
run_command "# expected:"
|
||||
|
||||
comment "The \"stuff\" change is now back on master as
|
||||
expected:"
|
||||
run_command "jj log"
|
||||
pause 5
|
||||
run_command "# We can also see what the repo looked like"
|
||||
run_command "# after the rebase operation:"
|
||||
|
||||
comment "We can also see what the repo looked like
|
||||
after the rebase operation:"
|
||||
run_command "jj --at-op $rebase_op log"
|
||||
pause 5
|
||||
run_command "# Looks nice, let'\''s go back to that point:"
|
||||
|
||||
comment "Looks nice, let's go back to that point:"
|
||||
run_command "jj op restore $rebase_op"
|
||||
pause 2
|
||||
run_command ""
|
||||
run_command "# We'\''re now back to before the \"other stuff\""
|
||||
run_command "# change existed:"
|
||||
|
||||
comment "We're now back to before the \"other stuff\"
|
||||
change existed:"
|
||||
run_command "jj log"
|
||||
'
|
||||
|
@ -1,50 +1,40 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
. "$(dirname "$0")"/demo_helpers.sh
|
||||
parse_args "$@"
|
||||
|
||||
new_tmp_dir
|
||||
jj git clone https://github.com/octocat/Hello-World
|
||||
cd Hello-World
|
||||
|
||||
run_demo 'Basic conflict resolution flow' '
|
||||
run_command "# We are on the master branch of the"
|
||||
run_command "# octocat/Hello-World repo:"
|
||||
run_command "jj log -r '\''all()'\''"
|
||||
pause 7
|
||||
run_command "# Let'\''s make an edit that will conflict"
|
||||
run_command "# when we rebase it:"
|
||||
comment "We are on the master branch of the
|
||||
octocat/Hello-World repo:"
|
||||
run_command "jj log -r 'all()'"
|
||||
|
||||
comment "Let's make an edit that will conflict
|
||||
when we rebase it:"
|
||||
run_command "jj describe -m \"README: say which world\""
|
||||
run_command "echo \"Hello Earth!\" > README"
|
||||
run_command "jj diff"
|
||||
pause 2
|
||||
run_command ""
|
||||
run_command "# We'\''re going to rebase it onto commit b1."
|
||||
run_command "# That commit looks like this:"
|
||||
|
||||
comment "We're going to rebase it onto commit b1.
|
||||
That commit looks like this:"
|
||||
run_command "jj diff -r b1"
|
||||
pause 2
|
||||
run_command ""
|
||||
run_command "# Now rebase:"
|
||||
|
||||
comment "Now rebase:"
|
||||
run_command "jj rebase -d b1"
|
||||
run_command ""
|
||||
run_command "# Huh, that seemed to succeed. Let'\''s take a"
|
||||
run_command "# look at the repo:"
|
||||
pause 2
|
||||
run_command "jj log -r '\''all()'\''"
|
||||
pause 4
|
||||
|
||||
comment "Huh, that seemed to succeed. Let's take a
|
||||
look at the repo:"
|
||||
run_command "jj log -r 'all()'"
|
||||
run_command "jj status"
|
||||
pause 3
|
||||
run_command "# As you can see, the rebased commit has a"
|
||||
run_command "# conflict. The file in the working copy looks"
|
||||
run_command "# like this:"
|
||||
|
||||
comment "As you can see, the rebased commit has a
|
||||
conflict. The file in the working copy looks
|
||||
like this:"
|
||||
run_command "cat README"
|
||||
pause 5
|
||||
run_command ""
|
||||
run_command "# Now we will resolve the conflict:"
|
||||
|
||||
comment "Now we will resolve the conflict:"
|
||||
run_command "echo \"Hello earth!\" > README"
|
||||
pause 2
|
||||
run_command ""
|
||||
run_command "# The status command no longer reports it:"
|
||||
|
||||
comment "The status command no longer reports it:"
|
||||
run_command "jj status"
|
||||
pause 2
|
||||
'
|
||||
|
@ -1,59 +1,49 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
. "$(dirname "$0")"/demo_helpers.sh
|
||||
parse_args "$@"
|
||||
|
||||
new_tmp_dir
|
||||
jj git clone https://github.com/octocat/Hello-World
|
||||
cd Hello-World
|
||||
|
||||
run_demo 'The working copy is automatically committed' '
|
||||
run_command "# We are in the octocat/Hello-World repo."
|
||||
run_command "# We have an empty working copy on top of master:"
|
||||
comment "We are in the octocat/Hello-World repo.
|
||||
We have an empty working copy on top of master:"
|
||||
run_command "jj status"
|
||||
pause 2
|
||||
run_command "jj log"
|
||||
pause 5
|
||||
run_command "# Now make some changes in the working copy:"
|
||||
|
||||
comment "Now make some changes in the working copy:"
|
||||
run_command "echo \"Goodbye World!\" > README"
|
||||
run_command "echo stuff > new-file"
|
||||
run_command ""
|
||||
run_command "# Our working copy'\''s commit ID changed"
|
||||
run_command "# because we made changes:"
|
||||
|
||||
comment "Our working copy's commit ID changed
|
||||
because we made changes:"
|
||||
run_command "jj status"
|
||||
pause 2
|
||||
run_command "jj log"
|
||||
pause 5
|
||||
run_command "# Add a branch so we can easily refer to this"
|
||||
run_command "# commit:"
|
||||
|
||||
comment "Add a branch so we can easily refer to this
|
||||
commit:"
|
||||
run_command "jj branch create goodbye"
|
||||
pause 2
|
||||
run_command "jj log"
|
||||
pause 3
|
||||
run_command "# Start working on a new change off of master:"
|
||||
|
||||
comment "Start working on a new change off of master:"
|
||||
sleep 1
|
||||
run_command "jj co master"
|
||||
pause 2
|
||||
run_command "jj log"
|
||||
pause 3
|
||||
run_command "# Note that the working copy is now clean; the"
|
||||
run_command "# \"goodbye\" change stayed in its own commit:"
|
||||
|
||||
comment "Note that the working copy is now clean; the
|
||||
\"goodbye\" change stayed in its own commit:"
|
||||
run_command "jj status"
|
||||
pause 2
|
||||
run_command ""
|
||||
run_command "# Modify a file in this new change:"
|
||||
|
||||
comment "Modify a file in this new change:"
|
||||
run_command "echo \"Hello everyone!\" > README"
|
||||
pause 2
|
||||
run_command ""
|
||||
run_command "# The working copy is not special; we can, for"
|
||||
run_command "# example, set the description of any commit."
|
||||
run_command "# First, set it on the working copy:"
|
||||
|
||||
comment "The working copy is not special; we can, for
|
||||
example, set the description of any commit.
|
||||
First, set it on the working copy:"
|
||||
run_command "jj describe -m everyone"
|
||||
pause 2
|
||||
run_command ""
|
||||
run_command "# Now set it on the change we worked on before:"
|
||||
|
||||
comment "Now set it on the change we worked on before:"
|
||||
run_command "jj describe goodbye -m goodbye"
|
||||
pause 2
|
||||
run_command ""
|
||||
run_command "# Inspect the result:"
|
||||
|
||||
comment "Inspect the result:"
|
||||
run_command "jj log"
|
||||
'
|
||||
|
BIN
demos/git_compat.png
Normal file
BIN
demos/git_compat.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 136 KiB |
BIN
demos/juggle_conflicts.png
Normal file
BIN
demos/juggle_conflicts.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 251 KiB |
BIN
demos/operation_log.png
Normal file
BIN
demos/operation_log.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 297 KiB |
BIN
demos/resolve_conflicts.png
Normal file
BIN
demos/resolve_conflicts.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 265 KiB |
BIN
demos/working_copy.png
Normal file
BIN
demos/working_copy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 270 KiB |
Loading…
Reference in New Issue
Block a user