{"thread":{"id":"14496","subject":"[PATCH 1/3] Add git-sequencer shell prototype","startedAt":"2008-07-16T20:45:16Z","lastAt":"2008-07-16T20:45:16Z","messageCount":1,"participants":["Stephan Beyer"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"83590","messageId":"cfa3b96d13488d57caf8b758367cdf0679126462.1216233914.git.s-beyer@gmx.net","threadId":"14496","inReplyTo":null,"subject":"[PATCH 1/3] Add git-sequencer shell prototype","fromName":"Stephan Beyer","fromEmail":"s-beyer@gmx.net","sentAt":"2008-07-16T20:45:16Z","receivedAt":"2008-07-16T20:45:16Z","isPatch":true,"sender":{"key":"s-beyer@gmx.net","avatar":"https://avatars.githubusercontent.com/u/143889?v=4"},"body":"git-sequencer is planned as a backend for user scripts\nthat execute a sequence of git instructions and perhaps\nneed manual intervention, for example git-rebase or git-am.\n\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nMentored-by: Daniel Barkalow <barkalow@iabervon.org>\nSigned-off-by: Stephan Beyer <s-beyer@gmx.net>\n---\n .gitignore       |    1 +\n Makefile         |    1 +\n command-list.txt |    1 +\n git-sequencer.sh | 2064 ++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 2067 insertions(+), 0 deletions(-)\n create mode 100755 git-sequencer.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex a213e8e..a617039 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -110,6 +110,7 @@ git-revert\n git-rm\n git-send-email\n git-send-pack\n+git-sequencer\n git-sh-setup\n git-shell\n git-shortlog\ndiff --git a/Makefile b/Makefile\nindex 9b52071..391a4ac 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -248,6 +248,7 @@ SCRIPT_SH += git-rebase--interactive.sh\n SCRIPT_SH += git-rebase.sh\n SCRIPT_SH += git-repack.sh\n SCRIPT_SH += git-request-pull.sh\n+SCRIPT_SH += git-sequencer.sh\n SCRIPT_SH += git-sh-setup.sh\n SCRIPT_SH += git-stash.sh\n SCRIPT_SH += git-submodule.sh\ndiff --git a/command-list.txt b/command-list.txt\nindex 3583a33..44bb5b0 100644\n--- a/command-list.txt\n+++ b/command-list.txt\n@@ -101,6 +101,7 @@ git-rev-parse                           ancillaryinterrogators\n git-rm                                  mainporcelain common\n git-send-email                          foreignscminterface\n git-send-pack                           synchingrepositories\n+git-sequencer                           plumbingmanipulators\n git-shell                               synchelpers\n git-shortlog                            mainporcelain\n git-show                                mainporcelain common\ndiff --git a/git-sequencer.sh b/git-sequencer.sh\nnew file mode 100755\nindex 0000000..6c406dc\n--- /dev/null\n+++ b/git-sequencer.sh\n@@ -0,0 +1,2064 @@\n+#!/bin/sh\n+# A git sequencer prototype.\n+\n+SUBDIRECTORY_OK=Yes\n+OPTIONS_KEEPDASHDASH=\n+OPTIONS_SPEC=\"\\\n+git sequencer [options] [--] [<file>]\n+git sequencer (--continue | --abort | --skip | --edit | --status)\n+--\n+ Options to start a sequencing process\n+B,batch        run in batch-mode\n+onto=          checkout the given commit or branch first\n+no-advice      suppress advice when pausing (conflicts, etc)\n+q,quiet        suppress output\n+v,verbose      be more verbose\n+ Options to restart/change a sequencing process or show information\n+continue       continue paused sequencer process\n+abort          restore original branch and abort\n+skip           skip current patch and continue\n+status         show the status of the sequencing process\n+edit           invoke editor to let user edit the remaining insns\n+ Options to be used by user scripts\n+caller=        provide information string: name|abort|cont|skip\n+\"\n+\n+. git-sh-setup\n+require_work_tree\n+\n+git var GIT_COMMITTER_IDENT >/dev/null ||\n+\tdie 'You need to set your committer info first'\n+\n+SEQ_DIR=\"$GIT_DIR/sequencer\"\n+TODO=\"$SEQ_DIR/todo\"\n+DONE=\"$SEQ_DIR/done\"\n+MSG=\"$SEQ_DIR/message\"\n+PATCH=\"$SEQ_DIR/patch\"\n+AUTHOR_SCRIPT=\"$SEQ_DIR/author-script\"\n+ORIG_AUTHOR_SCRIPT=\"$SEQ_DIR/author-script.orig\"\n+CALLER_SCRIPT=\"$SEQ_DIR/caller-script\"\n+WHY_FILE=\"$SEQ_DIR/why\"\n+MARK_PREFIX='refs/sequencer-marks'\n+\n+warn () {\n+\techo \"$*\" >&2\n+}\n+\n+cleanup () {\n+\tfor ref in $(git for-each-ref --format='%(refname)' \"$MARK_PREFIX\")\n+\tdo\n+\t\tgit update-ref -d \"$ref\" \"$ref\" || return\n+\tdone\n+\trm -rf \"$SEQ_DIR\"\n+}\n+\n+print_advice () {\n+\tcase \"$ADVICE,$WHY\" in\n+\tt,conflict)\n+\t\techo \"\n+After resolving the conflicts, mark the corrected paths with\n+\n+\tgit add <paths>\n+\n+and run\n+\n+\t$(print_caller --continue)\n+\n+Note, that your working tree must match the index.\"\n+\t\t;;\n+\tt,pause)\n+\t\techo \"\n+You can now edit files and add them to the index.\n+Once you are satisfied with your changes, run\n+\n+\t$(print_caller --continue)\n+\n+If you only want to change the commit message, run\n+git commit --amend before.\"\n+\t\t;;\n+\tt,run)\n+\t\techo \"\n+Running failed:\n+\t$@\n+\n+You can now fix the problem.  When manual runs pass,\n+add the changes to the index and invoke\n+\n+\t$(print_caller --continue)\"\n+\t\t;;\n+\tt,todo)\n+\t\techo \"\n+Fix with git sequencer --edit or abort with $(print_caller --abort).\"\n+\t\t;;\n+\tesac\n+}\n+\n+# Die if there has been a conflict\n+die_to_continue () {\n+\twarn \"$*\"\n+\ttest -z \"$BATCHMODE\" ||\n+\t\tdie_abort 'Aborting, because of batch mode.'\n+\ttest -n \"$WHY\" || WHY=conflict\n+\techo \"$WHY\" >\"$WHY_FILE\"\n+\tprint_advice\n+\texit 3\n+}\n+\n+die_abort () {\n+\trestore\n+\tcleanup\n+\tdie \"$1\"\n+}\n+\n+quit () {\n+\tcleanup\n+\ttest -z \"$*\" ||\n+\t\techo \"$*\"\n+\texit 0\n+}\n+\n+perform () {\n+\tcase \"$VERBOSE\" in\n+\t0)\n+\t\t\"$@\" >/dev/null\n+\t\t;;\n+\t1)\n+\t\toutput=$(\"$@\" 2>&1 )\n+\t\tstatus=$?\n+\t\ttest $status -ne 0 && printf '%s\\n' \"$output\"\n+\t\treturn $status\n+\t\t;;\n+\t2)\n+\t\t\"$@\"\n+\t\t;;\n+\tesac\n+}\n+\n+require_clean_work_tree () {\n+\t# test if working tree is dirty\n+\tgit rev-parse --verify HEAD >/dev/null &&\n+\tgit update-index --ignore-submodules --refresh &&\n+\tgit diff-files --quiet --ignore-submodules &&\n+\tgit diff-index --cached --quiet HEAD --ignore-submodules -- ||\n+\tdie 'Working tree is dirty'\n+}\n+\n+ORIG_REFLOG_ACTION=\"$GIT_REFLOG_ACTION\"\n+\n+comment_for_reflog () {\n+\tif test -z \"$ORIG_REFLOG_ACTION\"\n+\tthen\n+\t\tGIT_REFLOG_ACTION='sequencer'\n+\t\ttest -z \"$CALLER\" ||\n+\t\t\tGIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION ($CALLER)\"\n+\t\texport GIT_REFLOG_ACTION\n+\tfi\n+}\n+\n+# Get commit message from commit $1\n+commit_message () {\n+\tgit cat-file commit \"$1\" | sed -e '1,/^$/d'\n+}\n+\n+LAST_COUNT=\n+mark_action_done () {\n+\tsed -e 1q <\"$TODO\" >>\"$DONE\"\n+\tsed -e 1d <\"$TODO\" >\"$TODO.new\"\n+\tmv -f \"$TODO.new\" \"$TODO\"\n+\ttodo_ack \"$TODO\"\n+\tif test \"$VERBOSE\" -gt 0\n+\tthen\n+\t\tcount=$(grep -c '^[^#]' <\"$DONE\")\n+\t\ttotal=$(expr \"$count\" + \"$(grep -c '^[^#]' <\"$TODO\")\")\n+\t\tif test \"$LAST_COUNT\" != \"$count\"\n+\t\tthen\n+\t\t\tLAST_COUNT=\"$count\"\n+\t\t\ttest \"$VERBOSE\" -lt 1 ||\n+\t\t\t\tprintf 'Sequencing (%d/%d)\\r' \"$count\" \"$total\"\n+\t\t\ttest \"$VERBOSE\" -lt 2 || echo\n+\t\tfi\n+\tfi\n+}\n+\n+# Generate message, patch and author script files\n+make_patch () {\n+\tparent_sha1=$(git rev-parse --verify \"$1^\" 2>/dev/null ||\n+\t\techo '--root')\n+\tgit diff-tree -p \"$parent_sha1\" \"$1\" >\"$PATCH\"\n+\ttest -f \"$MSG\" ||\n+\t\tcommit_message \"$1\" >\"$MSG\"\n+\ttest -f \"$AUTHOR_SCRIPT\" ||\n+\t\tget_author_ident_from_commit \"$1\" >\"$AUTHOR_SCRIPT\"\n+}\n+\n+# Generate a patch and die with \"conflict\" status code\n+die_with_patch () {\n+\tmake_patch \"$1\"\n+\tgit rerere\n+\tdie_to_continue \"$2\"\n+}\n+\n+restore () {\n+\tgit rerere clear\n+\n+\tread HEADNAME <\"$SEQ_DIR/head-name\"\n+\tread HEAD <\"$SEQ_DIR/head\"\n+\tcase $HEADNAME in\n+\trefs/*)\n+\t\tgit symbolic-ref HEAD \"$HEADNAME\"\n+\t\t;;\n+\tesac &&\n+\tperform git reset --hard \"$HEAD\"\n+}\n+\n+has_action () {\n+\tgrep '^[^#]' \"$1\" >/dev/null\n+}\n+\n+# Check if text file $1 contains a commit message\n+has_message () {\n+\ttest -n \"$(sed -n -e '/^Signed-off-by:/d;/^[^#]/p' <\"$1\")\"\n+}\n+\n+# Count parents of commit $1\n+count_parents() {\n+\tgit cat-file commit \"$1\" | sed -n -e '1,/^$/p' | grep -c '^parent'\n+}\n+\n+# Evaluate the author script to get author information to\n+# apply it with \"with_author git foo\" then.\n+get_current_author () {\n+\tif test -f \"$AUTHOR_SCRIPT\"\n+\tthen\n+\t\t. \"$AUTHOR_SCRIPT\"\n+\telse\n+\t\t. \"$ORIG_AUTHOR_SCRIPT\"\n+\tfi || die_abort 'Author script is damaged. This must not happen!'\n+}\n+\n+# Run command with author information\n+with_author () {\n+\tGIT_AUTHOR_NAME=\"$GIT_AUTHOR_NAME\" \\\n+\tGIT_AUTHOR_EMAIL=\"$GIT_AUTHOR_EMAIL\" \\\n+\tGIT_AUTHOR_DATE=\"$GIT_AUTHOR_DATE\" \\\n+\t\t\"$@\"\n+}\n+\n+# clean WHY_FILE and reset WHY\n+clean_why () {\n+\trm -f \"$WHY_FILE\"\n+\tWHY=\n+}\n+\n+# Usage: pick_one (cherry-pick|revert) [-*|--edit] sha1\n+pick_one () {\n+\twhat=\"$1\"\n+\tshift\n+\n+\tcase \"$what,$1\" in\n+\trevert,*)\n+\t\ttest \"$1\" != '--edit' &&\n+\t\t\twhat='revert --no-edit'\n+\t\t;;\n+\tcherry-pick,-*)\n+\t\t;;\n+\tcherry-pick,*)\n+\t\t# fast forward\n+\t\tif test \"$(git rev-parse --verify \"$1^\" 2>/dev/null)\" = \\\n+\t\t\t\"$(git rev-parse --verify HEAD)\"\n+\t\tthen\n+\t\t\tperform git reset --hard \"$1\"\n+\t\t\treturn\n+\t\tfi\n+\t\t;;\n+\tesac\n+\t$use_perform git $what \"$@\"\n+}\n+\n+nth_string () {\n+\tcase \"$1\" in\n+\t*1[0-9]|*[04-9])\n+\t\techo \"$1th\"\n+\t\t;;\n+\t*1)\n+\t\techo \"$1st\"\n+\t\t;;\n+\t*2)\n+\t\techo \"$1nd\"\n+\t\t;;\n+\t*3)\n+\t\techo \"$1rd\"\n+\t\t;;\n+\tesac\n+}\n+\n+make_squash_message () {\n+\tif test -f \"$squash_msg\"\n+\tthen\n+\t\tcount=$(($(sed -n -e 's/^# This is [^0-9]*\\([1-9][0-9]*\\).*/\\1/p' \\\n+\t\t\t<\"$squash_msg\" | sed -n -e '$p')+1))\n+\t\techo \"# This is a combination of $count commits.\"\n+\t\tsed -e '1d' -e '2,/^./{\n+\t\t\t/^$/d\n+\t\t}' <\"$squash_msg\"\n+\telse\n+\t\tcount=2\n+\t\techo '# This is a combination of 2 commits.'\n+\t\techo '# The first commit message is:'\n+\t\techo\n+\t\tcommit_message HEAD\n+\tfi\n+\techo\n+\techo \"# This is the $(nth_string \"$count\") commit message:\"\n+\techo\n+\tcommit_message \"$1\"\n+}\n+\n+make_squash_message_multiple () {\n+\trevlist=$(git rev-list --reverse \"$sha1..HEAD\")\n+\tcount=$(echo \"$revlist\" | wc -l)\n+\tsquash_i=0\n+\techo \"# This is a combination of $count commits.\"\n+\tfor cur_sha1 in $revlist\n+\tdo\n+\t\tsquash_i=$(($squash_i+1))\n+\t\tif test -f \"$squash_msg\"\n+\t\tthen\n+\t\t\tcount=$(($count + $(sed -n -e \\\n+\t\t\t\t's/^# This is [^0-9]*\\([1-9][0-9]*\\).*/\\1/p' \\\n+\t\t\t\t<\"$squash_msg\" | sed -n -e '$p')+1))\n+\t\t\tsed -e '1d' -e '2,/^./{\n+\t\t\t\t/^$/d\n+\t\t\t}' <\"$squash_msg\"\n+\t\tfi\n+\t\techo\n+\t\techo \"# This is the $(nth_string \"$squash_i\") commit message:\"\n+\t\techo\n+\t\tcommit_message \"$cur_sha1\"\n+\tdone\n+}\n+\n+peek_next_command () {\n+\tsed -n -e '/^#/d' -e '1s/ .*$//p' <\"$TODO\"\n+}\n+\n+# If $1 is a mark, make a ref from it; otherwise keep it.\n+# Note on marks:\n+#  * :0 is allowed\n+#  * :01 is the same as :1\n+mark_to_ref () {\n+\targ=\"$1\"\n+\tref=$(expr \"x$arg\" : 'x:0*\\([0-9][0-9]*\\)$')\n+\ttest -n \"$ref\" &&\n+\t\targ=\"$MARK_PREFIX/$ref\"\n+\tprintf '%s\\n' \"$arg\"\n+}\n+\n+mark_to_commit () {\n+\tgit rev-parse --verify \"$(mark_to_ref \"$1\")\"\n+}\n+\n+\n+cannot_fallback () {\n+\techo \"$1\"\n+\tdie_to_continue 'Cannot fall back to three-way merge. Please hand-edit.'\n+}\n+\n+\n+fallback_3way () {\n+\tO_OBJECT=$(cd \"$GIT_OBJECT_DIRECTORY\" && pwd)\n+\n+\trm -fr \"$PATCH-merge-\"*\n+\tmkdir \"$PATCH-merge-tmp-dir\"\n+\n+\t# First see if the patch records the index info that we can use.\n+\tgit apply --build-fake-ancestor \"$PATCH-merge-tmp-index\" \"$PATCH\" &&\n+\tGIT_INDEX_FILE=\"$PATCH-merge-tmp-index\" \\\n+\t\tgit write-tree >\"$PATCH-merge-base+\" ||\n+\tcannot_fallback 'Repository lacks necessary blobs to fall back on 3-way merge.'\n+\n+\techo 'Using index info to reconstruct a base tree...'\n+\tif GIT_INDEX_FILE=\"$PATCH-merge-tmp-index\" \\\n+\t\tgit apply --cached \"$PATCH\"\n+\tthen\n+\t\tmv \"$PATCH-merge-base+\" \"$PATCH-merge-base\"\n+\t\tmv \"$PATCH-merge-tmp-index\" \"$PATCH-merge-index\"\n+\telse\n+\t\tcannot_fallback \"Did you hand edit your patch?\n+It does not apply to blobs recorded in its index.\"\n+\tfi\n+\n+\ttest -f \"$PATCH-merge-index\" &&\n+\this_tree=$(GIT_INDEX_FILE=\"$PATCH-merge-index\" git write-tree) &&\n+\torig_tree=$(cat \"$PATCH-merge-base\") &&\n+\trm -fr \"$PATCH-merge-\"* || exit 1\n+\n+\techo 'Falling back to patching base and 3-way merge...'\n+\n+\t# This is not so wrong.  Depending on which base we picked,\n+\t# orig_tree may be wildly different from ours, but his_tree\n+\t# has the same set of wildly different changes in parts the\n+\t# patch did not touch, so recursive ends up canceling them,\n+\t# saying that we reverted all those changes.\n+\n+\teval GITHEAD_$his_tree='\"$firstline\"'\n+\texport GITHEAD_$his_tree\n+\tgit merge-recursive \"$orig_tree\" -- HEAD \"$his_tree\" || {\n+\t\tgit rerere\n+\t\tdie 'Failed to merge in the changes.'\n+\t}\n+}\n+\n+# Run hook \"$@\" (with arguments) if executable\n+run_hook () {\n+\ttest -z \"$1\" || return\n+\thookname=\"$1\"\n+\thook=\"$GIT_DIR/hooks/$hookname\"\n+\tshift\n+\tif test -x \"$hook\"\n+\tthen\n+\t\t\"$hook\" \"$@\" ||\n+\t\t\tdie_to_continue \"Hook $hookname failed.\"\n+\tfi\n+}\n+\n+# Add Signed-off-by: line if general option --signoff is given\n+dashdash_signoff () {\n+\tadd_signoff=\n+\tif test -n \"$SIGNOFF\"\n+\tthen\n+\t\tlast_signed_off_by=$(\n+\t\t\tsed -n -e '/^Signed-off-by: /p' <\"$MSG\" | sed -n -e '$p'\n+\t\t)\n+\t\ttest \"$last_signed_off_by\" = \"$SIGNOFF\" ||\n+\t\t\tadd_signoff=$(\n+\t\t\t\ttest '' = \"$last_signed_off_by\" && echo\n+\t\t\t\techo \"$SIGNOFF\"\n+\t\t\t)\n+\tfi\n+\t{\n+\t\ttest -s \"$MSG\" && cat \"$MSG\"\n+\t\ttest -n \"$add_signoff\" && echo \"$add_signoff\"\n+\t} >\"$MSG.new\"\n+\tmv \"$MSG.new\" \"$MSG\"\n+}\n+\n+\n+### --caller-related functions\n+\n+# Show string for caller invocation for --abort/--continue/--skip\n+print_caller_info () {\n+\tcase \"$1\" in\n+\t--abort)\n+\t\techo \"$CALLER_ABRT\"\n+\t\t;;\n+\t--continue)\n+\t\techo \"$CALLER_CONT\"\n+\t\t;;\n+\t--skip)\n+\t\techo \"$CALLER_SKIP\"\n+\t\t;;\n+\t*)\n+\t\twarn 'Internal error: Unknown print_caller argument!'\n+\t\t;;\n+\tesac\n+}\n+\n+# Print the program to invoke to (--)abort/continue/skip\n+print_caller() {\n+\tcaller_info=$(print_caller_info \"$1\")\n+\tif test -n \"$CALLERCOMPARE\" -a -n \"$caller_info\"\n+\tthen\n+\t\ttest -n \"$CALLER\" && printf \"$CALLER \"\n+\t\techo \"$caller_info\"\n+\telse\n+\t\techo \"git sequencer $1\"\n+\tfi\n+}\n+\n+# Test if --caller was set correctly\n+# $1 must be abort/continue/skip\n+test_caller () {\n+\tcaller_info=$(print_caller_info \"--$1\")\n+\ttest -n \"$CALLERCOMPARE\" -a \\\n+\t\t\"$CALLERCOMPARE\" != \"$CALLERSTRING\" -a \\\n+\t\t-n \"$caller_info\" &&\n+\t\tdie \"You must use '$CALLER $caller_info' to $1!\"\n+}\n+\n+# Generate $CALLER_SCRIPT file from \"git foo|--abort|--continue|--skip\"\n+# string $1\n+generate_caller_script () {\n+\techo \"$1\" | sed -e 's/^\\(.*\\)|\\(.*\\)|\\(.*\\)|\\(.*\\)$/\\\n+CALLERCOMPARE=\"\\0\"\\\n+CALLER=\"\\1\"\\\n+CALLER_ABRT=\"\\2\"\\\n+CALLER_CONT=\"\\3\"\\\n+CALLER_SKIP=\"\\4\"/' >\"$CALLER_SCRIPT\"\n+}\n+\n+# Run caller script and set GIT_CHERRY_PICK_HELP\n+assure_caller () {\n+\ttest -r \"$CALLER_SCRIPT\" &&\n+\t\t. \"$CALLER_SCRIPT\"\n+\n+\t# we do not want cherry-pick to print *any* help\n+\tGIT_CHERRY_PICK_HELP=\"\"\n+\texport GIT_CHERRY_PICK_HELP\n+}\n+\n+\n+### Helpers for check_* functions:\n+\n+# Print a warning on todo checking\n+todo_warn () {\n+\tprintf 'Warning at line %d, %s: %s\\n' \"$line\" \"$command\" \"$*\"\n+}\n+\n+# Raise an error on todo checking\n+todo_error () {\n+\tprintf 'Error at line %d, %s: %s\\n' \"$line\" \"$command\" \"$*\"\n+\tretval=1\n+}\n+\n+# Test if $1 is a commit on todo checking\n+commit_check () {\n+\ttest \"$(git cat-file -t \"$1\" 2>/dev/null)\" = commit ||\n+\t\ttodo_error \"'$1' is not a commit.\"\n+}\n+\n+# A helper function to check if $1 is a an available mark during check_*\n+arg_is_mark_check () {\n+\tfor cur_mark in $available_marks\n+\tdo\n+\t\ttest \"$cur_mark\" -eq \"${1#:}\" && return\n+\tdone\n+\ttodo_error \"Mark $1 is not yet defined.\"\n+}\n+\n+# A helper function for check_* and mark usage:\n+# check if \"$1\" is a commit or a defined mark\n+arg_is_mark_or_commit_check () {\n+\tif expr \"x$1\" : 'x:[0-9][0-9]*$' >/dev/null\n+\tthen\n+\t\targ_is_mark_check \"$1\"\n+\telse\n+\t\tcommit_check \"$1\"\n+\tfi\n+}\n+\n+\n+### Author script functions\n+\n+# Take \"Name <e-mail>\" in stdin and outputs author script\n+make_author_script_from_string () {\n+\tsed -e \"s/'/'\"'\\\\'\"''/g\" \\\n+\t    -e 's/^\\(.*\\) <\\(.*\\)>.*$/GIT_AUTHOR_NAME='\\''\\1'\\''\\\n+GIT_AUTHOR_EMAIL='\\''\\2'\\''\\\n+GIT_AUTHOR_DATE=/'\n+}\n+\n+\n+### General option functions (and options spec)\n+\n+OPTIONS_GENERAL=' General options:\n+author= Override author\n+C,reuse-commit= Reuse message and authorship data from commit\n+F,file= Take commit message from given file\n+m,message= Specify commit message\n+M,reuse-message= Reuse message from commit\n+signoff Add signoff\n+e,edit Invoke editor to edit commit message'\n+\n+# Check if option is a general option\n+check_general_option () {\n+\tgeneral_shift=1\n+\tcase \"$1\" in\n+\t--signoff)\n+\t\treturn 0\n+\t\t;;\n+\t--author)\n+\t\tgeneral_shift=2\n+\t\tauthor_opt=\"t$author_opt\"\n+\t\texpr \"x$2\" : 'x.* <.*>' >/dev/null ||\n+\t\t\ttodo_error \"Author \\\"$2\\\" not in the correct format \\\"Name <e-mail>\\\".\"\n+\t\t;;\n+\t-m)\n+\t\tgeneral_shift=2\n+\t\tmsg_opt=\"t$msg_opt\"\n+\t\t;;\n+\t-C)\n+\t\tgeneral_shift=2\n+\t\tmsg_opt=\"t$msg_opt\"\n+\t\tauthor_opt=\"t$author_opt\"\n+\t\tcommit_check \"$2\"\n+\t\t;;\n+\t-M)\n+\t\tgeneral_shift=2\n+\t\tmsg_opt=\"t$msg_opt\"\n+\t\tcommit_check \"$2\"\n+\t\t;;\n+\t-F)\n+\t\tgeneral_shift=2\n+\t\tmsg_opt=\"t$msg_opt\"\n+\t\ttest -r \"$2\" ||\n+\t\t\ttodo_error \"Cannot read file '$2'.\"\n+\t\t;;\n+\t-e)\n+\t\ttest -z \"$BATCHMODE\" ||\n+\t\t\ttodo_error '--batch and --edit options do not make sense together.'\n+\t\t;;\n+\t*)\n+\t\treturn 1\n+\t\t;;\n+\tesac\n+}\n+\n+# Set a general option variable or return 1\n+handle_general_option () {\n+\tgeneral_shift=1\n+\tcase \"$1\" in\n+\t--signoff)\n+\t\tSIGNOFF=$(git var GIT_COMMITTER_IDENT | sed -e '\n+\t\t\t\ts/>.*/>/\n+\t\t\t\ts/^/Signed-off-by: /')\n+\t\t;;\n+\t--author)\n+\t\tgeneral_shift=2\n+\t\tAUTHOR=t\n+\t\techo \"$2\" |\n+\t\t\tmake_author_script_from_string >\"$AUTHOR_SCRIPT\"\n+\t\t;;\n+\t-m)\n+\t\tgeneral_shift=2\n+\t\tMESSAGE=\"$2\"\n+\t\t;;\n+\t-C)\n+\t\tgeneral_shift=2\n+\t\tAUTHOR=t\n+\t\tget_author_ident_from_commit \"$2\" >\"$AUTHOR_SCRIPT\"\n+\t\tMESSAGE=$(commit_message \"$2\")\n+\t\t;;\n+\t-M)\n+\t\tgeneral_shift=2\n+\t\tMESSAGE=$(commit_message \"$2\")\n+\t\t;;\n+\t-F)\n+\t\tgeneral_shift=2\n+\t\tMESSAGE=$(cat \"$2\")\n+\t\t;;\n+\t-e)\n+\t\tEDIT=--edit\n+\t\t;;\n+\t*)\n+\t\treturn 1\n+\t\t;;\n+\tesac\n+}\n+\n+\n+### Functions for checking and realizing TODO instructions\n+# Note that options_*, check_* and insn_* function names are reserved.\n+\n+options_pause=\"\\\n+pause\n+--\n+\"\n+\n+# Check the \"pause\" instruction\n+check_pause () {\n+\tshift\n+\ttest -z \"$BATCHMODE\" ||\n+\t\ttodo_error '\"pause\" instruction and --batch do not make sense together.'\n+\ttest $# -eq 0 ||\n+\t\ttodo_error 'The pause instruction takes no arguments.'\n+\treturn 0\n+}\n+\n+# Realize the \"pause\" instruction\n+insn_pause () {\n+\tmark_action_done\n+\tmake_patch HEAD\n+\techo 'pause' >\"$WHY_FILE\"\n+\tWHY=pause print_advice\n+\texit 2\n+}\n+\n+\n+options_run=\"\\\n+run [--dir=<path>] [--] <cmd> <args>...::\n+--\n+dir= Change directory before running command\n+\"\n+\n+# Check the \"run\" instruction\n+check_run () {\n+\twhile test $# -gt 0\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t--dir)\n+\t\t\ttest -e \"$2\" ||\n+\t\t\t\ttodo_error \"Path $2 does not exist.\"\n+\t\t\ttest -d \"$2\" ||\n+\t\t\t\ttodo_error \"Path $2 is not a directory.\"\n+\t\t\tshift 2\n+\t\t\t;;\n+\t\t--)\n+\t\t\tshift\n+\t\t\tbreak\n+\t\t\t;;\n+\t\t-*)\n+\t\t\ttodo_error \"Unknown option $1\"\n+\t\t\t;;\n+\t\tesac\n+\tdone\n+\t# we don't check if cmd exists\n+\treturn 0\n+}\n+\n+# Realize the \"run\" instruction\n+insn_run () {\n+\trunpath=./\n+\twhile test $# -gt 0\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t--dir)\n+\t\t\trunpath=\"$2\"\n+\t\t\tshift 2\n+\t\t\t;;\n+\t\t--)\n+\t\t\tshift\n+\t\t\tbreak\n+\t\t\t;;\n+\t\tesac\n+\tdone\n+\n+\tmark_action_done\n+\n+\tsavepath=\"$PWD\"\n+\tcd \"$runpath\"\n+\t\"$@\"\n+\tsuccess=\"$?\"\n+\tcd \"$savepath\"\n+\n+\tif test \"$success\" -ne 0\n+\tthen\n+\t\ttest -z \"$BATCHMODE\" ||\n+\t\t\tdie_abort \"Running $1 failed. Aborting because of batch mode.\"\n+\t\tmake_patch HEAD\n+\t\techo 'run' >\"$WHY_FILE\"\n+\t\tWHY=run print_advice \"$@\"\n+\t\texit 3\n+\tfi\n+}\n+\n+\n+options_patch=\"\\\n+patch [options] <file>\n+--\n+3,3way Fall back to 3-way merge\n+k Pass to git-mailinfo (keep subject)\n+n Pass to git-mailinfo (no utf8)\n+$OPTIONS_GENERAL\n+ Options passed to git-apply:\n+R,reverse Reverse changes\n+context= Ensure context of ... lines\n+p= Remove ... leading slashes\n+unidiff-zero Bypass unidiff checks\n+exclude= Do not apply changes to given files\n+no-add Ignore additions of patch\n+whitespace= Set whitespace error behavior\n+inaccurate-eof Support inaccurate EOFs\n+u no-op (backward compatibility)\n+binary no-op (backward compatibility)\n+\"\n+\n+# Check the \"file\" instruction\n+check_patch () {\n+\twhile test $# -gt 1\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t-3|-k|-n|-u|--binary|-R|--reverse|--unidiff-zero|--no-add|--inaccurate-eof)\n+\t\t\t:\n+\t\t\t;;\n+\t\t-p|--whitespace|--exclude|--context)\n+\t\t\tshift\n+\t\t\t;;\n+\t\t--)\n+\t\t\tshift\n+\t\t\tbreak\n+\t\t\t;;\n+\t\t-*)\n+\t\t\tcheck_general_option \"$@\" ||\n+\t\t\t\ttodo_warn \"Unknown option $1\"\n+\t\t\t;;\n+\t\t*)\n+\t\t\ttodo_error \"Wrong number of arguments. ($# given, 1 wanted)\"\n+\t\t\tbreak\n+\t\t\t;;\n+\t\tesac\n+\t\tshift $general_shift\n+\tdone\n+\n+\tif test -f \"$1\" -a -r \"$1\"\n+\tthen\n+\t\tgrep -e '^diff' \"$1\" >/dev/null ||\n+\t\t\ttodo_error \"File '$1' contains no patch.\"\n+\telse\n+\t\ttodo_error \"Cannot open file '$1'.\"\n+\tfi\n+\treturn 0\n+}\n+\n+# Realize the \"patch\" instruction\n+insn_patch () {\n+\tcomment_for_reflog patch\n+\n+\tapply_opts=\n+\tmailinfo_opts=\n+\tthreeway=\n+\n+\t# temporary files\n+\tinfofile=\"$SEQ_DIR/patch-info\"\n+\tmsgfile=\"$SEQ_DIR/patch-msg\"\n+\n+\twhile test \"$#\" -gt 1\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t-3)\n+\t\t\tthreeway=t\n+\t\t\t;;\n+\t\t-k|-n)\n+\t\t\tmailinfo_opts=\"$mailinfo_opts $1\"\n+\t\t\t;;\n+\t\t-u|--binary)\n+\t\t\t: Do nothing. It is there due to b/c only.\n+\t\t\t;;\n+\t\t-R|--reverse|--unidiff-zero|--no-add|--inaccurate-eof)\n+\t\t\tapply_opts=\"$apply_opts $1\"\n+\t\t\t;;\n+\t\t-p)\n+\t\t\tshift\n+\t\t\tapply_opts=\"$apply_opts -p$1\"\n+\t\t\t;;\n+\t\t--whitespace|--exclude)\n+\t\t\tapply_opts=\"$apply_opts $1=$2\"\n+\t\t\tshift\n+\t\t\t;;\n+\t\t--context)\n+\t\t\tshift\n+\t\t\tapply_opts=\"$apply_opts -C$1\"\n+\t\t\t;;\n+\t\t--)\n+\t\t\tshift\n+\t\t\tbreak\n+\t\t\t;;\n+\t\t*)\n+\t\t\thandle_general_option \"$@\"\n+\t\t\t;;\n+\t\tesac\n+\t\tshift $general_shift\n+\tdone\n+\n+\tfilename=\"$1\"\n+\n+\tmark_action_done\n+\n+\tgit mailinfo $mailinfo_opts \"$msgfile\" \"$PATCH\" \\\n+\t\t<\"$filename\" >\"$infofile\" ||\n+\t\tdie_abort 'Could not read or parse mail'\n+\n+\t# if author not set by option, read author information of patch\n+\tif test -z \"$AUTHOR\"\n+\tthen\n+\t\tcp \"$ORIG_AUTHOR_SCRIPT\" \"$AUTHOR_SCRIPT\"\n+\t\tsed -e \"s/'/'\"'\\\\'\"''/g\" -n -e '\n+\t\t\ts/^Author: \\(.*\\)$/GIT_AUTHOR_NAME='\\''\\1'\\''/p;\n+\t\t\ts/^Email: \\(.*\\)$/GIT_AUTHOR_EMAIL='\\''\\1'\\''/p;\n+\t\t\ts/^Date: \\(.*\\)$/GIT_AUTHOR_DATE='\\''\\1'\\''/p\n+\t\t' <\"$infofile\" >>\"$AUTHOR_SCRIPT\"\n+\t\t# If sed's result is empty, we keep the original\n+\t\t# author script by appending.\n+\tfi\n+\n+\t# Ignore every mail that's not containing a patch\n+\ttest -s \"$PATCH\" || {\n+\t\twarn 'Does not contain patch!'\n+\t\treturn 0\n+\t}\n+\n+\tedit_msg=\n+\tif grep -e '^Subject:' \"$infofile\" >/dev/null\n+\tthen\n+\t\t# add subject to commit message\n+\t\tsed -n -e '/^Subject:/ s/Subject: //p' <\"$infofile\"\n+\t\techo\n+\t\techo\n+\t\tcat \"$msgfile\"\n+\telse\n+\t\tcat \"$msgfile\"\n+\t\tedit_msg=t\n+\tfi | git stripspace >\"$MSG\"\n+\trm -f \"$infofile\" \"$msgfile\"\n+\n+\tfirstline=$(sed -e '1q' <\"$MSG\")\n+\n+\tget_current_author\n+\n+\ttest -n \"$MESSAGE\" && printf '%s\\n' \"$MESSAGE\" >\"$MSG\"\n+\ttest -z \"$firstline\" && firstline=$(sed -e '1q' <\"$MSG\")\n+\n+\tdashdash_signoff\n+\n+\twith_author run_hook applypatch-msg \"$MSG\"\n+\tfailed=\n+\tgit apply $apply_opts --index \"$PATCH\" || failed=t\n+\n+\tif test -n \"$failed\" -a -n \"$threeway\" && (with_author fallback_3way)\n+\tthen\n+\t\t# Applying the patch to an earlier tree and merging the\n+\t\t# result may have produced the same tree as ours.\n+\t\tgit diff-index --quiet --cached HEAD -- && {\n+\t\t\techo 'No changes -- Patch already applied.'\n+\t\t\treturn 0\n+\t\t\t# XXX: do we want that?\n+\t\t}\n+\t\t# clear apply_status -- we have successfully merged.\n+\t\tfailed=\n+\tfi\n+\n+\tif test -n \"$failed\"\n+\tthen\n+\t\tdie_to_continue 'Patch failed.'\n+\t\t# XXX: We actually needed a git-apply flag that creates\n+\t\t# conflict markers and sets the DIFF_STATUS_UNMERGED flag.\n+\tfi\n+\n+\twith_author run_hook pre-applypatch\n+\n+\ttest -n \"$EDIT\" && edit_msg=t\n+\tif ! has_message \"$MSG\" || test -n \"$edit_msg\"\n+\tthen\n+\t\techo \"\n+# Please enter the commit message for the applied patch.\n+# (Comment lines starting with '#' will not be included)\" >>\"$MSG\"\n+\n+\t\tgit_editor \"$MSG\" ||\n+\t\t\tdie_with_patch 'Editor returned error.'\n+\t\thas_message \"$MSG\" ||\n+\t\t\tdie_with_patch 'No commit message given.'\n+\tfi\n+\n+\ttree=$(git write-tree) &&\n+\tparent=$(git rev-parse --verify HEAD) &&\n+\tcommit=$(with_author git commit-tree \"$tree\" -p \"$parent\" <\"$MSG\") &&\n+\tgit update-ref -m \"$GIT_REFLOG_ACTION: $firstline\" HEAD \"$commit\" \"$parent\" ||\n+\t\tdie_to_continue 'Could not commit tree.'\n+\n+\ttest -x \"$GIT_DIR/hooks/post-applypatch\" &&\n+\t\twith_author \"$GIT_DIR/hooks/post-applypatch\"\n+\n+\treturn 0\n+}\n+\n+\n+options_pick=\"\\\n+pick [options] <commit>\n+--\n+R,reverse Revert introduced changes\n+mainline= Specify parent number to use for merge commits\n+$OPTIONS_GENERAL\n+\"\n+\n+# Check the \"pick\" instruction\n+check_pick () {\n+\tmainline=\n+\twhile test $# -gt 1\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t-R)\n+\t\t\t;;\n+\t\t--mainline)\n+\t\t\tshift\n+\t\t\tmainline=\"$1\"\n+\t\t\ttest \"$mainline\" -gt 0 || {\n+\t\t\t\ttodo_error '--mainline needs an integer beginning from 1.'\n+\t\t\t\tmainline=\n+\t\t\t}\n+\t\t\t;;\n+\t\t--)\n+\t\t\tshift\n+\t\t\tbreak\n+\t\t\t;;\n+\t\t-*)\n+\t\t\tcheck_general_option \"$@\" ||\n+\t\t\t\ttodo_warn \"Unknown option $1\"\n+\t\t\t;;\n+\t\t*)\n+\t\t\ttodo_error \"Wrong number of arguments. ($# given, 1 wanted)\"\n+\t\t\tbreak\n+\t\t\t;;\n+\t\tesac\n+\t\tshift $general_shift\n+\tdone\n+\n+\tif test -n \"$mainline\"\n+\tthen\n+\t\tparents=$(count_parents \"$1\")\n+\t\ttest \"$parents\" -lt \"$mainline\" &&\n+\t\t\ttodo_error \"Commit has only $parents (less than $mainline) parents.\"\n+\t\ttest \"$parents\" -eq 1 &&\n+\t\t\ttodo_warn 'Commit is not a merge at all.'\n+\tfi\n+\n+\tcommit_check \"$1\"\n+\n+\treturn 0\n+}\n+\n+# Realize the \"pick\" instruction\n+insn_pick () {\n+\top=cherry-pick\n+\tmainline=\n+\twhile test $# -gt 1\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t-R)\n+\t\t\top=revert\n+\t\t\t;;\n+\t\t--mainline)\n+\t\t\tmainline=\"$1 $2\"\n+\t\t\tshift\n+\t\t\t;;\n+\t\t--)\n+\t\t\tshift\n+\t\t\tbreak\n+\t\t\t;;\n+\t\t-*)\n+\t\t\thandle_general_option \"$@\"\n+\t\t\t;;\n+\t\tesac\n+\t\tshift $general_shift\n+\tdone\n+\n+\tsha1=$(git rev-parse --verify \"$1\")\n+\n+\tcomment_for_reflog pick\n+\n+\tmark_action_done\n+\n+\tedit_msg=\"$EDIT\"\n+\n+\t# Don't edit on pick, but later, if author or message given.\n+\ttest -n \"$AUTHOR\" -o -n \"$MESSAGE\" && edit_msg=\n+\n+\t# Be kind to users and ignore --mainline=1 on non-merge commits\n+\ttest -n \"$mainline\" -a 2 -gt $(count_parents \"$sha1\") && mainline=\n+\n+\tuse_perform=\n+\ttest -n \"$edit_msg\" ||\n+\t\tuse_perform=perform\n+\n+\tpick_one \"$op\" $edit_msg $mainline $sha1 ||\n+\t\tdie_with_patch $sha1 \"Could not apply $sha1\"\n+\n+\ttest -n \"$EDIT\" ||\n+\t\tuse_perform=perform\n+\n+\tget_current_author\n+\tsignoff=\n+\ttest -n \"$SIGNOFF\" && signoff=-s\n+\tif test -n \"$AUTHOR\" -a -n \"$MESSAGE\"\n+\tthen\n+\t\t# this is just because we only want to do ONE amending commit\n+\t\t$use_perform git commit --amend $EDIT $signoff --no-verify \\\n+\t\t\t--author \"$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>\" \\\n+\t\t\t--message=\"$MESSAGE\"\n+\telif test -n \"$AUTHOR\"\n+\tthen\n+\t\t# correct author if AUTHOR is set\n+\t\t$use_perform git commit --amend $EDIT --no-verify -C HEAD \\\n+\t\t\t--author \"$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>\"\n+\telif test -n \"$MESSAGE\"\n+\tthen\n+\t\t# correct commit message if MESSAGE is set\n+\t\t$use_perform git commit --amend $EDIT $signoff --no-verify \\\n+\t\t\t-C HEAD --message=\"$MESSAGE\"\n+\telif test -n \"$SIGNOFF\"\n+\tthen\n+\t\t# only add signoff\n+\t\t$use_perform git commit --amend $EDIT $signoff --no-verify \\\n+\t\t\t-C HEAD\n+\tfi\n+\n+\treturn 0\n+}\n+\n+options_edit=\"\\\n+edit <commit>\n+--\n+\"\n+\n+# Check the \"edit\" instruction\n+check_edit () {\n+\tshift\n+\ttest -z \"$BATCHMODE\" ||\n+\t\ttodo_error '\"edit\" instruction and --batch do not make sense together.'\n+\ttest $# -eq 1 ||\n+\t\ttodo_error \"Wrong number of arguments. ($# given, 1 wanted)\"\n+\treturn 0\n+}\n+\n+# Realize the \"edit\" instruction\n+insn_edit () {\n+\tshift\n+\tinsn_pick \"$1\"\n+\n+\t# work around mark_action_done in insn_pause\n+\techo '# pausing' >\"$TODO.new\"\n+\tcat \"$TODO\" >>\"$TODO.new\"\n+\tmv -f \"$TODO.new\" \"$TODO\"\n+\tinsn_pause\n+}\n+\n+\n+options_squash=\"\\\n+squash <commit>\n+squash [options] --from <mark>\n+--\n+from Squash all commits from <mark>\n+collect-signoffs Collect Signed-off-by: lines\n+include-merges Do not fail on merge commits\n+$OPTIONS_GENERAL\n+\"\n+\n+# Check the \"squash\" instruction\n+check_squash () {\n+\tfrom=\n+\tcollect=\n+\tmerges=\n+\twhile test $# -gt 1\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t--from)\n+\t\t\tfrom=t\n+\t\t\t;;\n+\t\t--collect-signoffs)\n+\t\t\tcollect=t\n+\t\t\ttodo_warn 'Not yet implemented.'\n+\t\t\t;;\n+\t\t--include-merges)\n+\t\t\tmerges=t\n+\t\t\t;;\n+\t\t--)\n+\t\t\tshift\n+\t\t\tbreak\n+\t\t\t;;\n+\t\t*)\n+\t\t\tcheck_general_option \"$@\" ||\n+\t\t\t\ttodo_error \"Unknown option $1\"\n+\t\t\t;;\n+\t\tesac\n+\t\tshift $general_shift\n+\tdone\n+\n+\t# in --from mode?\n+\tif test -n \"$from\"\n+\tthen\n+\t\ttest -z \"$merges\" &&\n+\t\t\tcat \"$DONE\" \"$TODO\" |\n+\t\t\tsed -n -e '/^[ \\t]*mark[ \\t]*:\\{0,1\\}'\"${1#:}\"'\\($\\|[^0-9]\\)/,'\"$line\"'p' |\n+\t\t\tgrep '^[ \\t]*merge' >/dev/null &&\n+\t\t\ttodo_error \"$1..HEAD contains a merge commit. You may try --include-merges.\"\n+\n+\t\targ_is_mark_check \"$1\"\n+\telse\n+\t\ttest -n \"$merges\" &&\n+\t\t\ttodo_error '--include-merges only makes sense with --from <mark>.'\n+\t\ttest -n \"$collect\" &&\n+\t\t\ttodo_error '--collect-signoffs only makes sense with --from <mark>.'\n+\n+\t\tcommit_check \"$1\"\n+\tfi\n+\n+\treturn 0\n+}\n+\n+# Realize the \"squash\" instruction\n+insn_squash () {\n+\tsquash_msg=\"$MSG-squash\"\n+\tfrom=\n+\twhile test $# -gt 1\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t--from)\n+\t\t\tfrom=t\n+\t\t\t;;\n+\t\t--collect-signoffs)\n+\t\t\twarn '--collect-signoffs is not implemented.'\n+\t\t\t# XXX\n+\t\t\t;;\n+\t\t--include-merges)\n+\t\t\t: # This has to be done during check_squash\n+\t\t\t;;\n+\t\t--)\n+\t\t\tshift\n+\t\t\tbreak\n+\t\t\t;;\n+\t\t*)\n+\t\t\thandle_general_option \"$@\"\n+\t\t\t;;\n+\t\tesac\n+\t\tshift $general_shift\n+\tdone\n+\n+\tif test -n \"$from\"\n+\tthen\n+\t\tsha1=$(mark_to_commit \":${1#:}\")\n+\telse\n+\t\tsha1=$(git rev-parse --verify \"$1\")\n+\tfi\n+\n+\tcomment_for_reflog squash\n+\n+\t# Hm, somehow I don't think --skip on a conflicting squash\n+\t# may be useful, but if someone wants to do it, it should\n+\t# do the obvious: skip what squash would do.\n+\techo \"$(git rev-parse HEAD)\" >\"$SEQ_DIR/skiphead\"\n+\n+\tmark_action_done\n+\n+\tif test -n \"$MESSAGE\"\n+\tthen\n+\t\tprintf '%s\\n' \"$MESSAGE\" >\"$MSG\"\n+\telse\n+\t\tif test -n \"$from\"\n+\t\tthen\n+\t\t\tmake_squash_message_multiple \"$sha1\" >\"$MSG\"\n+\t\telse\n+\t\t\tmake_squash_message \"$sha1\" >\"$MSG\"\n+\t\tfi\n+\tfi\n+\n+\tcase \"$(peek_next_command)\" in\n+\tsquash)\n+\t\tedit_commit=\n+\t\tuse_perform=perform\n+\t\tcp \"$MSG\" \"$squash_msg\"\n+\t\t;;\n+\t*)\n+\t\tedit_commit=-e\n+\t\tuse_perform=\n+\t\trm -f \"$squash_msg\" || exit\n+\t\t;;\n+\tesac\n+\n+\ttest -n \"$MESSAGE\" && edit_commit=\n+\ttest -n \"$EDIT\" && edit_commit=-e\n+\n+\t# is --author (or equivalent) set?\n+\tif test -n \"$AUTHOR\"\n+\tthen\n+\t\t# evaluate author script\n+\t\tget_current_author\n+\telse\n+\t\t# if --author is not given, we get the authorship\n+\t\t# information from the commit before.\n+\t\teval \"$(get_author_ident_from_commit HEAD)\"\n+\t\t# but we do not write an author script\n+\tfi\n+\n+\t# --from or not\n+\tfailed=\n+\tif test -n \"$from\"\n+\tthen\n+\t\tperform git reset --soft \"$sha1\"\n+\telse\n+\t\tperform git reset --soft HEAD^\n+\n+\t\tpick_one cherry-pick -n \"$sha1\" || failed=t\n+\tfi\n+\n+\tdashdash_signoff\n+\n+\tif test -z \"$failed\"\n+\tthen\n+\t\t# This is like --amend, but with a different message\n+\t\twith_author $use_perform git commit --no-verify \\\n+\t\t\t-F \"$MSG\" $edit_commit || failed=t\n+\telse\n+\t\tcp \"$MSG\" \"$GIT_DIR/MERGE_MSG\"\n+\t\twarn\n+\t\twarn \"Could not apply $sha1...\"\n+\t\tdie_with_patch $sha1 \"\"\n+\tfi\n+\n+\treturn 0\n+}\n+\n+\n+options_mark=\"\\\n+mark <mark>\n+--\n+\"\n+\n+# Check the \"mark\" instruction\n+check_mark () {\n+\tshift\n+\ttest $# -eq 1 ||\n+\t\ttodo_error \"Wrong number of arguments. ($# given, 1 wanted)\"\n+\tmy_mark=$(expr \"x${1#:}\" : 'x0*\\([0-9][0-9]*\\)$')\n+\ttest -n \"$my_mark\" ||\n+\t\ttodo_error \"Mark $1 not an integer.\"\n+\texpr \"x$available_marks \" : \" $my_mark \" >/dev/null &&\n+\t\ttodo_error \"Mark :$my_mark already defined. Choose another integer.\"\n+\tavailable_marks=\"$available_marks $my_mark\"\n+\n+\treturn 0\n+}\n+\n+# Realize the \"mark\" instruction\n+insn_mark () {\n+\tshift\n+\tgiven=\"$1\"\n+\n+\tmark_action_done\n+\n+\tmark=$(mark_to_ref \":${given#:}\")\n+\tgit update-ref \"$mark\" HEAD\n+\treturn 0\n+}\n+\n+\n+options_merge=\"\\\n+merge [options] <commit-ish> ...\n+--\n+standard Generate default commit message\n+s,strategy= Use merge strategy ...\n+$OPTIONS_GENERAL\n+\"\n+\n+# Check the \"merge\" instruction\n+check_merge () {\n+\twhile test $# -gt 1\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t--standard)\n+\t\t\tmsg_opt=\"t$msg_opt\"\n+\t\t\t;;\n+\t\t-s)\n+\t\t\tshift\n+\t\t\t;;\n+\t\t--)\n+\t\t\tshift\n+\t\t\tbreak\n+\t\t\t;;\n+\t\t-*)\n+\t\t\tcheck_general_option \"$@\" ||\n+\t\t\t\ttodo_error \"Unknown option $1\"\n+\t\t\t;;\n+\t\tesac\n+\t\tshift $general_shift\n+\tdone\n+\n+\ttest $# -gt 0 ||\n+\t\ttodo_error 'What are my parents? Need new parents!'\n+\n+\twhile test $# -gt 0\n+\tdo\n+\t\targ_is_mark_or_commit_check \"$1\"\n+\t\tshift\n+\tdone\n+\treturn 0\n+}\n+\n+# Realize the \"merge\" instruction\n+insn_merge () {\n+\tcomment_for_reflog merge\n+\n+\tstandard=\n+\n+\twhile test $# -gt 1\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t--standard)\n+\t\t\tstandard=t\n+\t\t\t;;\n+\t\t-s)\n+\t\t\tshift\n+\t\t\tstrategy=\"-s $1\"\n+\t\t\t;;\n+\t\t--)\n+\t\t\tshift\n+\t\t\tbreak\n+\t\t\t;;\n+\t\t-*)\n+\t\t\thandle_general_option \"$@\"\n+\t\t\t;;\n+\t\tesac\n+\t\tshift $general_shift\n+\tdone\n+\n+\tnew_parents=\n+\tfor p in \"$@\"\n+\tdo\n+\t\tnew_parents=\"$new_parents $(mark_to_ref $p)\"\n+\tdone\n+\tnew_parents=\"${new_parents# }\"\n+\n+\tget_current_author\n+\n+\tif test -n \"$standard\"\n+\tthen\n+\t\tfor cur_parent in $new_parents\n+\t\tdo\n+\t\t\tprintf '%s\\t\\t%s' \\\n+\t\t\t\t\"$(git rev-parse \"$cur_parent\")\" \"$cur_parent\"\n+\t\tdone | git fmt-merge-msg >\"$MSG\"\n+\tfi\n+\n+\ttest -n \"$MESSAGE\" &&\n+\t\tprintf '%s\\n' \"$MESSAGE\" >\"$MSG\"\n+\n+\tdashdash_signoff\n+\tif ! has_message \"$MSG\" || test -n \"$EDIT\"\n+\tthen\n+\t\techo \"\n+# Please enter the merge commit message.\n+# (Comment lines starting with '#' will not be included)\" >>\"$MSG\"\n+\n+\t\tgit_editor \"$MSG\" ||\n+\t\t\tdie_with_patch 'Editor returned error.'\n+\t\thas_message \"$MSG\" ||\n+\t\t\tdie_with_patch 'No commit message given.'\n+\tfi\n+\n+\tmark_action_done\n+\tif ! with_author perform git merge $strategy -m junk $new_parents\n+\tthen\n+\t\tgit rerere\n+\t\tcp \"$MSG\" \"$GIT_DIR/MERGE_MSG\"\n+\t\tdie_to_continue 'Error merging'\n+\tfi\n+\twith_author perform git commit --amend -F \"$MSG\" --no-verify\n+\treturn 0\n+}\n+\n+\n+options_reset=\"\\\n+reset <commit-ish>\n+--\n+\"\n+\n+# Check the \"reset\" instruction\n+check_reset () {\n+\tshift\n+\ttest $# -eq 1 ||\n+\t\ttodo_error \"Wrong number of arguments. ($# given, 1 wanted)\"\n+\targ_is_mark_or_commit_check \"$1\"\n+\n+\treturn 0\n+}\n+\n+# Realize the \"reset\" instruction\n+insn_reset () {\n+\tshift\n+\tcomment_for_reflog reset\n+\n+\tmark_action_done\n+\tperform git reset --hard \"$(mark_to_commit \"$1\")\"\n+}\n+\n+\n+options_ref=\"\\\n+ref <ref>\n+--\n+\"\n+\n+# Check the \"ref\" instruction\n+check_ref () {\n+\tshift\n+\ttest $# -eq 1 ||\n+\t\ttodo_error \"Wrong number of arguments. ($# given, 1 wanted)\"\n+\treturn 0\n+}\n+\n+# Realize the \"ref\" instruction\n+insn_ref () {\n+\tshift\n+\tcomment_for_reflog ref\n+\n+\tmark_action_done\n+\tperform git update-ref \"$1\" HEAD\n+}\n+\n+\n+### Instruction main loop\n+\n+# Run check_* or insn_* with massaged options\n+# Usage: run_insn (check|do) <insn> <insn options>\n+run_insn () {\n+\tc_or_i=\"$1\"\n+\tinsn=\"$2\"\n+\tshift\n+\tshift\n+\teval \"option_spec=\\\"\\$options_$insn\\\"\"\n+\teval \"$(printf \"%s\" \"$option_spec\" |\n+\t\tgit rev-parse --parseopt -- \"$@\" ||\n+\t\techo return 1)\"\n+\tcase \"$c_or_i\" in\n+\tcheck)\n+\t\tcheck_$insn \"$@\"\n+\t\t;;\n+\tdo)\n+\t\tinsn_$insn \"$@\"\n+\t\t;;\n+\tesac\n+}\n+\n+# Execute the first line of the current TODO file\n+execute_next () {\n+\tread -r command rol <\"$TODO\"\n+\ttest \"$VERBOSE\" -gt 1 &&\n+\t\tprintf 'Next line: %s\\n' \"$command $rol\"\n+\n+\tcase \"$command\" in\n+\t'#'*|'')\n+\t\tmark_action_done\n+\t\t;;\n+\t*)\n+\t\t# reset general options\n+\t\trm -f \"$AUTHOR_SCRIPT\" \"$MSG\"\n+\t\techo 'HEAD' >\"$SEQ_DIR/skiphead\"\n+\t\tgeneral_shift=1\n+\t\tAUTHOR=\n+\t\tEDIT=\n+\t\tMESSAGE=\n+\t\tSIGNOFF=\n+\t\t# XXX: eval is evil!\n+\t\teval \"run_insn do $command $rol\" ||\n+\t\t\tdie_to_continue 'An unexpected error occured.'\n+\t\t;;\n+\tesac\n+}\n+\n+# Execute the rest of the TODO file and finish\n+execute_rest () {\n+\twhile has_action \"$TODO\"\n+\tdo\n+\t\texecute_next\n+\tdone\n+\n+\tcomment_for_reflog finish\n+\tif test -n \"$ONTO\"\n+\tthen\n+\t\tgit update-ref -m \"$GIT_REFLOG_ACTION: $ONTO\" \"$ONTO\" HEAD &&\n+\t\tgit symbolic-ref HEAD \"$ONTO\"\n+\tfi &&\n+\tquit\n+}\n+\n+# We don't need to check a todo file if it has not changed\n+# since it has last been acknowledged to be sane.\n+todo_has_changed () {\n+\ttest -f \"$1.sum\" || return 0\n+\ttest \"$(git hash-object \"$1\")\" != \"$(cat \"$1.sum\")\"\n+}\n+\n+# acknowledge todo file to be sane\n+todo_ack () {\n+\tgit hash-object \"$1\" >\"$1.sum\"\n+}\n+\n+# Main loop to check instructions\n+todo_check () {\n+\ttodo=\"$TODO\"\n+\ttest -n \"$1\" && todo=\"$1\"\n+\ttodo_has_changed \"$todo\" || return 0\n+\n+\ttest \"$VERBOSE\" -lt 1 || printf 'Checking...\\r'\n+\tavailable_marks=' '\n+\tfor cur_mark in $(git for-each-ref --format='%(refname)' \"$MARK_PREFIX\")\n+\tdo\n+\t\tavailable_marks=\"$available_marks ${cur_mark##*/}\"\n+\tdone\n+\n+\tretval=0\n+\tline=1\n+\twhile read -r command rol\n+\tdo\n+\t\tcase \"$command\" in\n+\t\t'#'*|'')\n+\t\t\t;;\n+\t\t*)\n+\t\t\teval 'test -n \"$options_'\"$command\"'\"' || {\n+\t\t\t\tretval=1\n+\t\t\t\ttodo_error \"Unknown $command instruction\"\n+\t\t\t\tcontinue\n+\t\t\t}\n+\n+\t\t\tgeneral_shift=1\n+\t\t\tmsg_opt=\n+\t\t\tauthor_opt=\n+\t\t\teval \"run_insn check $command $rol\" ||\n+\t\t\t\ttodo_error \"Unknown option used\"\n+\t\t\texpr \"$msg_opt\" : 'ttt*' >/dev/null &&\n+\t\t\t\ttodo_error 'You can only provide one commit message option.'\n+\t\t\texpr \"$author_opt\" : 'ttt*' >/dev/null &&\n+\t\t\t\ttodo_error 'You can only provide one author option.'\n+\t\t\t;;\n+\t\tesac\n+\t\tline=$(expr \"$line\" + 1)\n+\tdone <\"$todo\"\n+\ttest $retval -ne 0 || todo_ack \"$todo\"\n+\treturn $retval\n+}\n+\n+prepare_editable_todo () {\n+\techo '# ALREADY DONE:'\n+\tsed -e 's/^/#  /' <\"$DONE\"\n+\techo '# '\n+\techo \"$markline\"\n+\tcat \"$TODO\"\n+}\n+\n+# expand shortcuts in TODO file $1\n+expand_shortcuts () {\n+\tsed -e '\n+\t\ts/^[ \\t]*p\\>/pick/;\n+\t\ts/^[ \\t]*e\\>/edit/;\n+\t\ts/^[ \\t]*s\\>/squash/;\n+\t' <\"$1\" >\"$TODO.cut\"\n+\tmv \"$TODO.cut\" \"$1\"\n+}\n+\n+get_saved_options () {\n+\tread VERBOSE <\"$SEQ_DIR/verbose\"\n+\tread ADVICE <\"$SEQ_DIR/advice\"\n+\tread ONTO <\"$SEQ_DIR/onto\"\n+\ttest -f \"$WHY_FILE\" &&\n+\t\tread WHY <\"$WHY_FILE\"\n+\treturn 0\n+}\n+\n+# Realize sequencer invocation\n+do_startup () {\n+\ttest -d \"$SEQ_DIR\" &&\n+\t\tdie 'sequencer already started'\n+\n+\trequire_clean_work_tree\n+\n+\tHEAD=$(git rev-parse --verify HEAD) ||\n+\t\tdie 'No HEAD?'\n+\n+\tmkdir \"$SEQ_DIR\" ||\n+\t\tdie \"Could not create temporary $SEQ_DIR\"\n+\n+\t# save options\n+\techo \"$VERBOSE\" >\"$SEQ_DIR/verbose\"\n+\techo \"$ADVICE\" >\"$SEQ_DIR/advice\"\n+\ttest -n \"$CALLERSTRING\" &&\n+\t\tgenerate_caller_script \"$CALLERSTRING\"\n+\t# generate empty DONE and \"onto\" file\n+\t: >\"$DONE\"\n+\t: >\"$SEQ_DIR/onto\"\n+\n+\tif test -n \"$BATCHMODE\"\n+\tthen\n+\t\tGIT_CHERRY_PICK_HELP='  Aborting (batch mode)'\n+\t\texport GIT_CHERRY_PICK_HELP\n+\telse\n+\t\tassure_caller\n+\tfi\n+\n+\tcomment_for_reflog start\n+\n+\t# save old head before checking out the given <branch>\n+\tgit symbolic-ref HEAD >\"$SEQ_DIR/head-name\" 2>/dev/null ||\n+\t\techo 'detached HEAD' >\"$SEQ_DIR/head-name\"\n+\techo $HEAD >\"$SEQ_DIR/head\"\n+\t# do it here so that die_abort can work ;)\n+\n+\tif test -n \"$ONTO\"\n+\tthen\n+\t\t# if ONTO is a branch name, then keep it, otherwise\n+\t\t# we don't care anymore and erase ONTO.\n+\t\tif git-show-ref --quiet --verify -- \"refs/heads/${ONTO##*/}\"\n+\t\tthen\n+\t\t\tONTO=\"refs/heads/${ONTO##*/}\"\n+\t\t\techo \"$ONTO\" >\"$SEQ_DIR/onto\"\n+\t\t\tperform git checkout \"$(git rev-parse \"$ONTO\")\" ||\n+\t\t\t\tdie_abort \"Could not checkout branch $ONTO\"\n+\t\telse\n+\t\t\tperform git checkout \"$ONTO\" ||\n+\t\t\t\tdie_abort \"Could not checkout commit $ONTO\"\n+\t\t\tONTO=\n+\t\tfi\n+\tfi\n+\n+\t(git var GIT_AUTHOR_IDENT || git var COMMITTER_IDENT) |\n+\t\tmake_author_script_from_string >\"$ORIG_AUTHOR_SCRIPT\"\n+\n+\t# read from file or from stdin?\n+\tif test -z \"$1\"\n+\tthen\n+\t\t: >\"$TODO\" ||\n+\t\t\tdie_abort \"Could not generate TODO file $TODO\"\n+\t\twhile read -r line\n+\t\tdo\n+\t\t\tprintf '%s\\n' \"$line\" >>\"$TODO\" ||\n+\t\t\t\tdie_abort \"Could not append to TODO file $TODO\"\n+\t\tdone\n+\telse\n+\t\tcp \"$1\" \"$TODO\" ||\n+\t\t\tdie_abort \"Could not find TODO file $1.\"\n+\tfi\n+\texpand_shortcuts \"$TODO\"\n+\n+\thas_action \"$TODO\" || die_abort 'Nothing to do'\n+\ttodo_check || WHY=todo die_to_continue \"TODO file contains errors.\"\n+\n+\texecute_rest\n+\texit\n+}\n+\n+# Realize --continue.\n+do_continue () {\n+\ttest -d \"$SEQ_DIR\" || die 'No sequencer running'\n+\ttest_caller 'continue'\n+\n+\texpand_shortcuts \"$TODO\"\n+\ttodo_check || WHY=todo die_to_continue \"TODO file contains errors.\"\n+\n+\tcomment_for_reflog continue\n+\n+\t# Sanity check\n+\tgit rev-parse --verify HEAD >/dev/null ||\n+\t\tdie_to_continue 'Cannot read HEAD'\n+\tgit update-index --ignore-submodules --refresh &&\n+\t\tgit diff-files --quiet --ignore-submodules ||\n+\t\tdie_to_continue 'Working tree is dirty. (Use git add or git stash first?)'\n+\n+\tget_saved_options\n+\n+\t# do we have anything to commit? (staged changes)\n+\tif ! git diff-index --cached --quiet --ignore-submodules HEAD --\n+\tthen\n+\t\tget_current_author\n+\n+\t\t# After \"pause\", we should amend (merge-safe!).\n+\t\t# On conflict, we do not have a commit to amend, so we\n+\t\t# should just commit.\n+\t\tcase \"$WHY\" in\n+\t\tpause|run)\n+\t\t\twith_author git commit --amend --no-verify -F \"$MSG\" -e ||\n+\t\t\t\tdie_to_continue 'Could not commit staged changes.'\n+\t\t\t;;\n+\t\tconflict)\n+\t\t\twith_author git commit --no-verify -F \"$MSG\" -e ||\n+\t\t\t\tdie_to_continue 'Could not commit staged changes.'\n+\t\t\techo '# resolved CONFLICTS of the last instruction' >>\"$DONE\"\n+\t\t\t;;\n+\t\t*)\n+\t\t\tdie_to_continue 'There are staged changes. Do not know what to do with them.'\n+\t\tesac\n+\tfi\n+\n+\trequire_clean_work_tree\n+\tclean_why\n+\texecute_rest\n+\texit\n+}\n+\n+# Realize --abort.\n+do_abort () {\n+\ttest -d \"$SEQ_DIR\" || die 'No sequencer running'\n+\ttest_caller 'abort'\n+\n+\tcomment_for_reflog abort\n+\tgit rerere clear\n+\trestore\n+\tquit\n+}\n+\n+# Realize --skip.\n+do_skip () {\n+\ttest -d \"$SEQ_DIR\" || die 'No sequencer running'\n+\ttest_caller 'skip'\n+\n+\texpand_shortcuts \"$TODO\"\n+\ttodo_check || WHY=todo die_to_continue \"TODO file contains errors.\"\n+\tget_saved_options\n+\n+\tcomment_for_reflog skip\n+\tgit rerere clear\n+\tclean_why\n+\n+\tperform git reset --hard \"$(cat \"$SEQ_DIR/skiphead\")\" &&\n+\techo '# SKIPPED the last instruction' >>\"$DONE\" &&\n+\t\texecute_rest\n+\texit\n+}\n+\n+# Realize --edit.\n+do_edit () {\n+\ttest -d \"$SEQ_DIR\" || die 'No sequencer running'\n+\n+\tmarkline='### BEGIN EDITING BELOW THIS LINE ###'\n+\tprepare_editable_todo >\"$TODO.new\"\n+\tif todo_has_changed \"$TODO\"\n+\tthen\n+\t\tsane=\n+\telse\n+\t\tsane=t\n+\t\ttodo_ack \"$TODO.new\"\n+\tfi\n+\n+\t# XXX: does not make sense\n+\t#      when input does not come from a terminal\n+\tgit_editor \"$TODO.new\" ||\n+\t\tdie 'Editor returned an error.'\n+\n+\tif test -t 0 -a -t 1\n+\tthen\n+\t\tsane=t\n+\t\techo\n+\t\t# interactive:\n+\t\tuntil has_action \"$TODO.new\" && todo_check \"$TODO.new\"\n+\t\tdo\n+\t\t\thas_action \"$TODO.new\" || echo 'TODO file empty.'\n+\t\t\tprintf 'What to do with the file? [c]orrect/[e]dit again/[r]ewind/[s]ave/[?] '\n+\t\t\tread reply\n+\t\t\tcase \"$reply\" in\n+\t\t\t[cC]*)\n+\t\t\t\tgit_editor \"$TODO.new\"\n+\t\t\t\texpand_shortcuts \"$TODO.new\"\n+\t\t\t\t;;\n+\t\t\t[eE]*)\n+\t\t\t\tprepare_editable_todo >\"$TODO.new\"\n+\t\t\t\tgit_editor \"$TODO.new\"\n+\t\t\t\texpand_shortcuts \"$TODO.new\"\n+\t\t\t\t;;\n+\t\t\t[rRxXqQ]*)\n+\t\t\t\trm -f \"$TODO.new\" \"$TODO.new.sum\"\n+\t\t\t\texit 0\n+\t\t\t\t;;\n+\t\t\t[sS]*)\n+\t\t\t\ttest \"$WHY\" != 'pause' ||\n+\t\t\t\t\techo 'todo' >\"$WHY_FILE\"\n+\t\t\t\tsane=\n+\t\t\t\tbreak\n+\t\t\t\t;;\n+\t\t\t[?hH]*)\n+\t\t\t\tcat <<EOF\n+\n+Help:\n+s - save TODO file and exit\n+c - respawn editor to correct TODO file\n+e - drop changes and respawn editor on original TODO file\n+r - drop changes and exit as if nothing happened\n+? - print this help\n+EOF\n+\t\t\t\t;;\n+\t\t\tesac\n+\t\t\techo\n+\t\tdone\n+\telse\n+\t\t# defaults:\n+\t\thas_action \"$TODO.new\" || quit \"Nothing to do\"\n+\t\ttodo_check \"$TODO.new\" ||\n+\t\t\tdie 'TODO file contains errors. Aborting.'\n+\tfi\n+\tcp \"$TODO\" \"$TODO.old\"\n+\tif grep \"^$markline\" \"$TODO.new\" >/dev/null\n+\tthen\n+\t\tsed -e \"1,/^$markline/d\" <\"$TODO.new\" >\"$TODO\"\n+\telse\n+\t\tcp \"$TODO.new\" \"$TODO\"\n+\tfi\n+\trm -f \"$TODO.new\" \"$TODO.new.sum\"\n+\ttest -z \"$sane\" || todo_ack \"$TODO\"\n+\techo\n+\techo 'TODO file contains:'\n+\techo\n+\tcat \"$TODO\"\n+\texit 0\n+}\n+\n+# Realize --status.\n+do_status () {\n+\ttest -d \"$SEQ_DIR\" || die 'No sequencer running.'\n+\tget_saved_options\n+\n+\tif has_action \"$DONE\"\n+\tthen\n+\t\techo 'Already done (or tried):'\n+\t\tsed -e 's/^/  /' <\"$DONE\"\n+\t\techo\n+\tfi\n+\tcase \"$WHY\" in\n+\tpause)\n+\t\techo 'Intentionally paused.'\n+\t\t;;\n+\trun)\n+\t\techo 'Interrupted because running failed.'\n+\t\t;;\n+\tconflict)\n+\t\techo 'Interrupted by conflict at'\n+\t\tsed -n -e 's/^/  /;$p' <\"$DONE\"\n+\t\t;;\n+\ttodo)\n+\t\techo 'Interrupted because of errors in the TODO file.'\n+\t\t;;\n+\t*)\n+\t\techo 'Current state is broken.'\n+\tesac\n+\ttest \"$VERBOSE\" -gt 1 && echo 'Running verbosely.'\n+\ttest \"$VERBOSE\" -lt 1 && echo 'Running quietly.'\n+\ttest -n \"$ONTO\" &&\n+\t\techo \"Sequencing on branch ${ONTO##*/}.\"\n+\tif has_action \"$TODO\"\n+\tthen\n+\t\techo\n+\n+\t\techo 'Still to do:'\n+\t\tsed -e 's/^/  /' <\"$TODO\"\n+\tfi\n+\tif test \"$WHY\" = todo\n+\tthen\n+\t\techo\n+\t\techo 'But there are errors. To edit, run:'\n+\t\techo '    git sequencer --edit'\n+\telse\n+\t\techo\n+\t\techo 'To abort & restore, invoke:'\n+\t\techo \"    $(print_caller --abort)\"\n+\t\techo 'To continue, invoke:'\n+\t\techo \"    $(print_caller --continue)\"\n+\t\ttest \"$WHY\" = 'pause' -o \"$WHY\" = 'run' || {\n+\t\t\techo 'To skip the current instruction, invoke:'\n+\t\t\techo \"    $(print_caller --skip)\"\n+\t\t}\n+\tfi\n+\texit 0\n+}\n+\n+is_standalone () {\n+\ttest $# -eq 2 &&\n+\ttest \"$2\" = '--' &&\n+\ttest -z \"$BATCHMODE\" &&\n+\ttest \"$ADVICE\" = t &&\n+\ttest -z \"$onto\" &&\n+\ttest \"$VERBOSE\" -eq 1\n+}\n+\n+\n+### Option handling and startup\n+\n+onto=\n+BATCHMODE=\n+CALLERSTRING=\n+VERBOSE=1\n+ADVICE=t\n+CALLER=\n+CALLER_ABRT=\n+CALLER_CONT=\n+CALLER_SKIP=\n+while test $# -gt 0\n+do\n+\tcase \"$1\" in\n+\t--continue)\n+\t\tis_standalone \"$@\" || usage\n+\t\tassure_caller\n+\t\tdo_continue\n+\t\t;;\n+\t--abort)\n+\t\tis_standalone \"$@\" || usage\n+\t\tassure_caller\n+\t\tdo_abort\n+\t\t;;\n+\t--skip)\n+\t\tis_standalone \"$@\" || usage\n+\t\tassure_caller\n+\t\tdo_skip\n+\t\t;;\n+\t--status)\n+\t\tis_standalone \"$@\" || usage\n+\t\tassure_caller\n+\t\tdo_status\n+\t\t;;\n+\t--edit)\n+\t\tis_standalone \"$@\" || usage\n+\t\tdo_edit\n+\t\t;;\n+\t--caller)\n+\t\t###############################################################\n+\t\t# This feature is for user scripts only. (Hence undocumented.)\n+\t\t# User scripts should pass an argument like:\n+\t\t# --caller=\"git foo|abrt|go|next\"\n+\t\t# on every git sequencer call. (It is only ignored on\n+\t\t# --edit and --status.)\n+\t\t# So git sequencer knows that\n+\t\t# \"git foo abrt\" will abort,\n+\t\t# \"git foo go\" will continue and\n+\t\t# \"git foo next\" will skip the sequencing process.\n+\t\t# This is useful if your user script does some extra\n+\t\t# preparations or cleanup before/after calling\n+\t\t#   git sequencer --caller=\"...\" --abort|--continue|--skip\n+\t\t#\n+\t\t# Running git-sequencer without the same --caller string\n+\t\t# fails then, until the sequencing process has finished or\n+\t\t# aborted.\n+\t\t#\n+\t\t# Btw, --caller=\"my_tiny_script.sh|-a||\" will be\n+\t\t# interpreted, that users must invoke \"my_tiny_script.sh -a\"\n+\t\t# to abort, but can invoke \"git sequencer --continue\" and\n+\t\t# \"git sequencer --skip\" to continue or skip.\n+\t\t# And it is also possible to provide three different scripts\n+\t\t# by --caller=\"|script 1|tool 2|util 3\".\n+\t\t#\n+\t\t# If your user script does not need any special\n+\t\t# abort/continue/skip behavior, then just do NOT pass\n+\t\t# the --caller option.\n+\t\t###############################################################\n+\t\tshift\n+\t\texpr \"x$1\" : 'x.*|.*|.*|.*$' >/dev/null ||\n+\t\t\tdie 'Wrong --caller format.'\n+\t\tCALLERSTRING=\"$1\"\n+\t\t;;\n+\t-B)\n+\t\tBATCHMODE=t\n+\t\t# XXX: we still have abort on editor invokations\n+\t\t;;\n+\t--no-advice)\n+\t\tADVICE=f\n+\t\t;;\n+\t--onto)\n+\t\tshift\n+\t\tONTO=\"$1\"\n+\t\ttest $(git cat-file -t \"$ONTO\") = 'commit' ||\n+\t\t\tdie \"$ONTO is no commit or branch.\"\n+\t\t;;\n+\t-q)\n+\t\tVERBOSE=0\n+\t\tADVICE=f\n+\t\t# XXX: If there were no editors,\n+\t\t# we could just do exec >/dev/null\n+\t\t;;\n+\t-v)\n+\t\tVERBOSE=2\n+\t\t# or increment it if we have several verbosity steps\n+\t\t;;\n+\t--)\n+\t\tshift\n+\t\tbreak\n+\t\t;;\n+\t*)\n+\t\tdie \"$1 currently not implemented.\"\n+\t\t;;\n+\tesac\n+\tshift\n+done\n+test $# -gt 1 && usage\n+\n+do_startup \"$1\"\n-- \n1.5.6.3.391.ge45b\n"}]}