{"thread":{"id":"19430","subject":"[PATCH v0 1/3] doc/git-rebase.txt: remove mention of multiple strategies","startedAt":"2009-05-21T09:47:07Z","lastAt":"2009-05-25T07:39:44Z","messageCount":21,"participants":["Nguyễn Thái Ngọc Duy","Jakub Narebski","Nguyen Thai Ngoc Duy","Junio C Hamano","Johannes Sixt"],"isPatch":true,"patchVersion":0,"patchTotal":3},"messages":[{"id":"114402","messageId":"1242899229-27603-1-git-send-email-pclouds@gmail.com","threadId":"19430","inReplyTo":null,"subject":"[PATCH v0 1/3] doc/git-rebase.txt: remove mention of multiple strategies","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2009-05-21T09:47:07Z","receivedAt":"2009-05-21T09:47:07Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"git-rebase.sh does not seem to support this.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n I have starred at git-rebase.sh many times and still don't know how\n it can do multiple strategies. So assume it's wrong, remove it.\n\n Documentation/git-rebase.txt |    3 +--\n 1 files changed, 1 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 3d5a066..26f3b7b 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -231,8 +231,7 @@ OPTIONS\n \n -s <strategy>::\n --strategy=<strategy>::\n-\tUse the given merge strategy; can be supplied more than\n-\tonce to specify them in the order they should be tried.\n+\tUse the given merge strategy.\n \tIf there is no `-s` option, a built-in list of strategies\n \tis used instead ('git-merge-recursive' when merging a single\n \thead, 'git-merge-octopus' otherwise).  This implies --merge.\n-- \ntest\n"},{"id":"114403","messageId":"1242899229-27603-2-git-send-email-pclouds@gmail.com","threadId":"19430","inReplyTo":"1242899229-27603-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v0 2/3] t/t3400-rebase.sh: add more tests to help migrating git-rebase.sh to C","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2009-05-21T09:47:08Z","receivedAt":"2009-05-21T09:47:08Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"These new tests make sure I don't miss any check being performed before\nrebase is proceeded (which is well tested by other tests)\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n t/t3400-rebase.sh |   28 ++++++++++++++++++++++++++++\n 1 files changed, 28 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh\nindex 6e391a3..37f86ab 100755\n--- a/t/t3400-rebase.sh\n+++ b/t/t3400-rebase.sh\n@@ -41,9 +41,37 @@ test_expect_success \\\n      git tag topic\n '\n \n+test_expect_success 'rebase on dirty worktree' '\n+     echo dirty >> A &&\n+     ! git rebase master'\n+\n+test_expect_success 'rebase on dirty cache' '\n+     git add  A &&\n+     ! git rebase master'\n+\n test_expect_success 'rebase against master' '\n+     git reset HEAD &&\n+     git checkout -f &&\n      git rebase master'\n \n+test_expect_success 'rebase against master twice' '\n+\tgit rebase master 2>&1|grep \"Current branch my-topic-branch is up to date\\\\.\"\n+'\n+\n+test_expect_success 'rebase against master twice with --force' '\n+\tgit rebase --force-rebase master 2>&1|grep \"Current branch my-topic-branch is up to date, rebase forced\"\n+'\n+\n+test_expect_success 'rebase against master twice from another branch' '\n+\tgit checkout my-topic-branch^ &&\n+\tgit rebase master my-topic-branch 2>&1|grep \"Current branch my-topic-branch is up to date\\\\.\"\n+'\n+\n+test_expect_success 'rebase fast-forward to master' '\n+\tgit checkout my-topic-branch^ &&\n+\tgit rebase my-topic-branch 2>&1|grep \"Fast-forwarded HEAD to my-topic-branch\"\n+'\n+\n test_expect_success \\\n     'the rebase operation should not have destroyed author information' \\\n     '! (git log | grep \"Author:\" | grep \"<>\")'\n-- \ntest\n"},{"id":"114404","messageId":"1242899229-27603-3-git-send-email-pclouds@gmail.com","threadId":"19430","inReplyTo":"1242899229-27603-2-git-send-email-pclouds@gmail.com","subject":"[PATCH v0 3/3] Build in git-rebase.sh","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2009-05-21T09:47:09Z","receivedAt":"2009-05-21T09:47:09Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Regression: \"-M\" is gone. Don't really want to mess up struct option for \"-M\"\n\n Makefile                       |    2 +-\n builtin-rebase.c               |  992 ++++++++++++++++++++++++++++++++++++++++\n builtin.h                      |    1 +\n contrib/examples/git-rebase.sh |  530 +++++++++++++++++++++\n git-rebase.sh                  |  530 ---------------------\n git.c                          |    1 +\n 6 files changed, 1525 insertions(+), 531 deletions(-)\n create mode 100644 builtin-rebase.c\n create mode 100755 contrib/examples/git-rebase.sh\n delete mode 100755 git-rebase.sh\n\ndiff --git a/Makefile b/Makefile\nindex fdb39fa..fec6c40 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -302,7 +302,6 @@ SCRIPT_SH += git-parse-remote.sh\n SCRIPT_SH += git-pull.sh\n SCRIPT_SH += git-quiltimport.sh\n 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-sh-setup.sh\n@@ -597,6 +596,7 @@ BUILTIN_OBJS += builtin-prune-packed.o\n BUILTIN_OBJS += builtin-prune.o\n BUILTIN_OBJS += builtin-push.o\n BUILTIN_OBJS += builtin-read-tree.o\n+BUILTIN_OBJS += builtin-rebase.o\n BUILTIN_OBJS += builtin-receive-pack.o\n BUILTIN_OBJS += builtin-reflog.o\n BUILTIN_OBJS += builtin-remote.o\ndiff --git a/builtin-rebase.c b/builtin-rebase.c\nnew file mode 100644\nindex 0000000..51c3121\n--- /dev/null\n+++ b/builtin-rebase.c\n@@ -0,0 +1,992 @@\n+#include \"builtin.h\"\n+#include \"cache.h\"\n+#include \"parse-options.h\"\n+#include \"diff.h\"\n+#include \"diffcore.h\"\n+#include \"revision.h\"\n+#include \"commit.h\"\n+#include \"run-command.h\"\n+#include \"dir.h\"\n+#include \"refs.h\"\n+#include \"quote.h\"\n+#include \"log-tree.h\"\n+\n+static char const * const rebase_usage[] = {\n+\t\"git rebase [-i | --interactive] [options] [--onto <newbase>]\\n\"\n+\t\"\t<upstream> [<branch>]\",\n+\t\"git rebase [-i | --interactive] [options] --onto <newbase>\\n\"\n+\t\"\t--root [<branch>]\",\n+\t\"git rebase --continue | --skip | --abort\",\n+\tNULL\n+};\n+\n+static const char *resolve_msg =\n+\t\"When you have resolved this problem, run \\\"git rebase --continue\\\".\\n\"\n+\t\"If you would prefer to skip this patch, instead run \\\"git rebase --skip\\\".\\n\"\n+\t\"To restore the original branch and stop rebasing run \\\"git rebase --abort\\\".\\n\";\n+\n+#define REBASE_ABORT\t\t0x0001\n+#define REBASE_CONTINUE\t\t0x0002\n+#define REBASE_FORCE\t\t0x0004\n+#define REBASE_IGNORE_DATE\t0x0008\n+#define REBASE_INTERACTIVE\t0x0010\n+#define REBASE_MERGE\t\t0x0020\n+#define REBASE_STAT\t\t0x0040\n+#define REBASE_NO_VERIFY\t0x0080\n+#define REBASE_PRESERVE_MERGES\t0x0100\n+#define REBASE_ROOT\t\t0x0200\n+#define REBASE_SKIP\t\t0x0400\n+#define REBASE_VERBOSE\t\t0x0800\n+\n+struct rebase_opt {\n+\tint flags;\n+\tint context;\n+\tconst char *onto;\n+\tconst char *upstream;\n+\tconst char *branch;\n+\tconst char *strategy;\n+\tconst char *whitespace;\n+};\n+\n+static int rebase_config(const char *var, const char *value, void *data)\n+{\n+\tif (!strcmp(var, \"rebase.stat\")) {\n+\t\tif (git_config_bool(var, value))\n+\t\t\t((struct rebase_opt*)data)->flags |= REBASE_STAT;\n+\t\treturn 0;\n+\t}\n+\treturn 0;\n+}\n+\n+/* utility functions */\n+\n+static char *load_string(char *git_pathname)\n+{\n+\tstruct strbuf sb = STRBUF_INIT;\n+\tconst char *path = git_path(git_pathname);\n+\n+\tif (strbuf_read_file(&sb, path,  41) == -1)\n+\t\tdie(\"Could not read %s\", path);\n+\n+\twhile (sb.len && sb.buf[sb.len-1] == '\\n') {\n+\t\tsb.len--;\n+\t\tsb.buf[sb.len] = '\\0';\n+\t}\n+\n+\treturn sb.buf;\n+}\n+\n+static void save_string(char *git_pathname, const char *str)\n+{\n+\tconst char *path = git_path(git_pathname);\n+\tint fd = open(path, O_CREAT | O_WRONLY, 0600);\n+\tif (fd < 0)\n+\t\tdie(\"Could not open %s for writing\", path);\n+\twrite_in_full(fd, str, strlen(str));\n+\twrite_in_full(fd, \"\\n\", 1);\n+\tclose(fd);\n+}\n+\n+static void load_sha1(char *git_pathname, unsigned char *sha1)\n+{\n+\tchar *buf = load_string(git_pathname);\n+\tif (get_sha1_hex(buf, sha1) == -1)\n+\t\tdie(\"Invalid SHA-1 in %s\", git_path(git_pathname));\n+\tfree(buf);\n+}\n+\n+static void save_sha1(char *git_pathname, const unsigned char *sha1)\n+{\n+\tsave_string(git_pathname, sha1_to_hex(sha1));\n+}\n+\n+static int load_int(char *git_pathname)\n+{\n+\tchar *buf = load_string(git_pathname);\n+\tint ret;\n+\n+\tif (sscanf(buf, \"%d\", &ret) != 1)\n+\t\tdie(\"Failed to read number from %s\", git_path(git_pathname));\n+\tfree(buf);\n+\treturn ret;\n+}\n+\n+static void save_int(char *git_pathname, int number)\n+{\n+\tconst char *path = git_path(git_pathname);\n+\tFILE *fp = fopen(path, \"w\");\n+\tif (!fp)\n+\t\tdie(\"Could not open %s for writing\", path);\n+\tfprintf(fp, \"%d\\n\", number);\n+\tfclose(fp);\n+}\n+\n+static void get_commit(const char *name, unsigned char *sha1, struct commit **cmt)\n+{\n+\tif (get_sha1(name, sha1))\n+\t\tdie(\"Failed to resolve SHA-1 from %s\", name);\n+\t*cmt = lookup_commit(sha1);\n+\tif (!*cmt)\n+\t\tdie(\"%s is not a commitish\", name);\n+}\n+\n+static int continue_merge(int msgnum, unsigned char *prev_head)\n+{\n+\tconst char *argv_diff[] = { \"--quiet\", \"--ignore-submodules\", \"HEAD\", \"--\", NULL };\n+\tstruct strbuf result_line = STRBUF_INIT;\n+\tunsigned char cmt[20];\n+\tstruct rev_info rev;\n+\tstruct stat st;\n+\tint i, result;\n+\n+\tif (stat(git_path(\"rebase-merge\"), &st) || !S_ISDIR(st.st_mode))\n+\t\tdie(\"%s directory does not exist\", git_path(\"rebase-merge\"));\n+\n+\t/* git-am or git-merge-* may have been run, can no longer trust the old cache */\n+\tdiscard_cache();\n+\tif (read_cache() < 0)\n+\t\tdie(\"Could not read the index\");\n+\n+\tfor (i = 0;i < active_nr;i++)\n+\t\tif (ce_stage(active_cache[i]))\n+\t\t\tdie(\"You still have unmerged paths in your index\\n\"\n+\t\t\t    \"did you forget to use git add?\\n\"\n+\t\t\t    \"%s\",\n+\t\t\t    resolve_msg);\n+\n+\tinit_revisions(&rev, NULL);\n+\trev.abbrev = 0;\n+\tsetup_revisions(4, argv_diff, &rev, NULL);\n+\tresult = run_diff_index(&rev, 0);\n+\tload_sha1(\"rebase-merge/current\", cmt);\n+\n+\tif (DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES)) {\n+\t\tstruct child_process cp;\n+\t\tconst char *argv[5] = {\"commit\", \"--no-verify\", \"-C\", sha1_to_hex(cmt), NULL };\n+\n+\t\tmemset(&cp, 0, sizeof(cp));\n+\t\tcp.git_cmd = 1;\n+\t\tcp.argv = argv;\n+\t\tif (run_command(&cp))\n+\t\t\tdie(\"Commit failed, please do not call \\\"git commit\\\"\\n\"\n+\t\t\t    \"directly, but instead do one of the following:\\n\"\n+\t\t\t    \"%s\", resolve_msg);\n+\t\tstrbuf_addf(&result_line, \"Committed: %04d \", msgnum);\n+\t}\n+\telse\n+\t\tstrbuf_addf(&result_line, \"Already applied: %04d \", msgnum);\n+\n+\tparse_commit(lookup_commit(cmt));\n+\tformat_commit_message(lookup_commit(cmt), \"%f\", &result_line, 0);\n+\tputs(result_line.buf);\n+\tstrbuf_release(&result_line);\n+\n+\tif (get_sha1(\"HEAD^0\", prev_head))\n+\t\tdie(\"Could not resolve HEAD commit\");\n+\tsave_sha1(\"rebase-merge/prev_head\", prev_head);\n+\tmsgnum++;\n+\tsave_int(\"rebase-merge/msgnum\", msgnum);\n+\treturn msgnum;\n+}\n+\n+static void call_merge(const char *strategy, int msgnum)\n+{\n+\tstruct strbuf sb = STRBUF_INIT;\n+\tstruct strbuf sb2 = STRBUF_INIT;\n+\tstruct strbuf sb_env1 = STRBUF_INIT;\n+\tstruct strbuf sb_env2 = STRBUF_INIT;\n+\tunsigned char cmt[20];\n+\tunsigned char head[20];\n+\tstruct child_process cp;\n+\tconst char *full_ref;\n+\tint end, result, type;\n+\tconst char *argv[5];\n+\tchar *onto_name, *head_hex, *cmt_hex;\n+\n+\tstrbuf_addf(&sb, \"rebase-merge/cmt.%d\", msgnum);\n+\tload_sha1(sb.buf, cmt);\n+\tsave_sha1(\"rebase-merge/current\", cmt);\n+\n+\tfull_ref = resolve_ref(\"HEAD\", head, 1, &type);\n+\tif (!lookup_commit(head))\n+\t\tdie(\"HEAD does not point to a commit\");\n+\tmsgnum = load_int(\"rebase-merge/msgnum\");\n+\tend = load_int(\"rebase-merge/end\");\n+\n+\tstrbuf_setlen(&sb, 0);\n+\tstrbuf_addf(&sb, \"%s~%d\",\n+\t\t    !strncmp(full_ref, \"refs/heads/\", 11) ? full_ref + 11 : full_ref,\n+\t\t    end - msgnum);\n+\tstrbuf_addf(&sb_env1, \"GITHEAD_%s\", sha1_to_hex(cmt));\n+\tsetenv(sb_env1.buf, sb.buf, 1);\n+\n+\tonto_name = load_string(\"rebase-merge/onto_name\");\n+\tstrbuf_setlen(&sb, 0);\n+\tstrbuf_addf(&sb_env2, \"GITHEAD_%s\", sha1_to_hex(head));\n+\tsetenv(sb_env2.buf, onto_name, 1);\n+\tfree(onto_name);\n+\n+\tstrbuf_setlen(&sb, 0);\n+\tstrbuf_addf(&sb, \"merge-%s\", strategy);\n+\tstrbuf_addf(&sb2, \"%s^\", sha1_to_hex(cmt));\n+\thead_hex = xstrdup(sha1_to_hex(head));\n+\tcmt_hex = xstrdup(sha1_to_hex(cmt));\n+\targv[0] = sb.buf;\n+\targv[1] = sb2.buf;\n+\targv[2] = \"--\";\n+\targv[3] = head_hex;\n+\targv[4] = cmt_hex;\n+\targv[5] = NULL;\n+\tmemset(&cp, 0, sizeof(cp));\n+\tcp.git_cmd = 1;\n+\tcp.argv = argv;\n+\tresult = run_command(&cp);\n+\tfree(head_hex);\n+\tfree(cmt_hex);\n+\tstrbuf_release(&sb);\n+\tstrbuf_release(&sb2);\n+\tswitch (result) {\n+\tcase 0:\n+\t\tunsetenv(sb_env1.buf);\n+\t\tstrbuf_release(&sb_env1);\n+\t\tunsetenv(sb_env2.buf);\n+\t\tstrbuf_release(&sb_env2);\n+\t\tbreak;\n+\tcase -1:\n+\t\targv[0] = \"rerere\";\n+\t\targv[1] = NULL;\n+\t\trun_command(&cp);\n+\t\tdie(resolve_msg);\n+\n+\tcase -2:\n+\t\tfprintf(stderr, \"Strategy: %d %s failed, try another\", result, strategy);\n+\t\tdie(resolve_msg);\n+\n+\tdefault:\n+\t\tcmt_hex = xstrdup(sha1_to_hex(cmt));\n+\t\tdie(\"Unknown exit code (%d) from command: git-merge-%s %s^ -- HEAD %s\",\n+\t\t    result, strategy, cmt_hex, cmt_hex);\n+\t}\n+}\n+\n+static void move_to_original_branch(const unsigned char *onto,\n+\t\t\t\t    const unsigned char *orig_head,\n+\t\t\t\t    const char *head_name)\n+{\n+\tstruct strbuf sb = STRBUF_INIT;\n+\tunsigned char head[20];\n+\n+\tif (strncmp(head_name, \"refs/\", 5))\n+\t\treturn;\n+\n+\tstrbuf_addf(&sb, \"rebase finished: %s onto %s\", head_name, sha1_to_hex(onto));\n+\tif (get_sha1(\"HEAD\", head))\n+\t\tdie(\"Could not resolve HEAD\");\n+\tupdate_ref(sb.buf, head_name, head, orig_head, 0, DIE_ON_ERR);\n+\tcreate_symref(\"HEAD\", head_name, NULL);\n+\tstrbuf_release(&sb);\n+}\n+\n+static int finish_rebase_merge(const unsigned char *onto,\n+\t\t\t       const unsigned char *orig_head,\n+\t\t\t       const char *head_name)\n+{\n+\tstruct strbuf sb = STRBUF_INIT;\n+\tmove_to_original_branch(onto, orig_head, head_name);\n+\tstrbuf_addstr(&sb, git_path(\"rebase-merge\"));\n+\tremove_dir_recursively(&sb, 0);\n+\tstrbuf_release(&sb);\n+\tputs(\"All done.\");\n+\treturn 0;\n+}\n+\n+static void check_rebase_in_progress()\n+{\n+\tstruct stat st;\n+\tif ((!stat(git_path(\"rebase-merge\"), &st) && S_ISDIR(st.st_mode)) ||\n+\t    (!stat(git_path(\"rebase-apply\"), &st) && S_ISDIR(st.st_mode)))\n+\t\treturn;\n+\tdie(\"No rebase in progress?\");\n+}\n+\n+static int cmd_continue(const struct rebase_opt *opt)\n+{\n+\tstruct stat st;\n+\tstruct rev_info rev;\n+\tstruct child_process cp;\n+\tconst char *argv_am[] = { \"am\", \"--resolved\", \"--3way\", \"--resolvemsg\", resolve_msg, NULL };\n+\tchar *head_name;\n+\tunsigned char onto[20], orig_head[20];\n+\tint ret;\n+\n+\tcheck_rebase_in_progress();\n+\n+\tif (read_cache() < 0)\n+\t\tdie(\"Could not read the index\");\n+\n+\tinit_revisions(&rev, NULL);\n+\trev.abbrev = 0;\n+\tDIFF_OPT_SET(&rev.diffopt, QUIET);\n+\tDIFF_OPT_SET(&rev.diffopt, IGNORE_SUBMODULES);\n+\trun_diff_files(&rev, DIFF_SILENT_ON_REMOVED);\n+\tif (DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES)) {\n+\t\tprintf(\"You must edit all merge conflicts and then\\n\"\n+\t\t       \"mark them as resolved using git add\\n\");\n+\t\treturn 1;\n+\t}\n+\n+\tif (!stat(git_path(\"rebase-merge\"), &st) && S_ISDIR(st.st_mode)) {\n+\t\tunsigned char prev_head[20], onto[20], orig_head[20];\n+\t\tchar *head_name;\n+\t\tint msgnum, end;\n+\n+\t\tload_sha1(\"rebase-merge/prev_head\", prev_head);\n+\t\tload_sha1(\"rebase-merge/onto\", onto);\n+\t\tend = load_int(\"rebase-merge/end\");\n+\t\tmsgnum = load_int(\"rebase-merge/msgnum\");\n+\n+\t\tmsgnum = continue_merge(msgnum, prev_head);\n+\t\twhile (msgnum <= end) {\n+\t\t\tcall_merge(opt->strategy, msgnum);\n+\t\t\tmsgnum = continue_merge(msgnum, prev_head);\n+\t\t}\n+\n+\t\tload_sha1(\"rebase-merge/orig-head\", orig_head);\n+\t\thead_name = load_string(\"rebase-merge/head-name\");\n+\n+\t\tret = finish_rebase_merge(onto, orig_head, head_name);\n+\t\tfree(head_name);\n+\t\treturn ret;\n+\t}\n+\n+\thead_name = load_string(\"rebase-apply/head-name\");\n+\tload_sha1(\"rebase-apply/onto\", onto);\n+\tload_sha1(\"rebase-apply/orig-head\", orig_head);\n+\n+\tmemset(&cp, 0, sizeof(cp));\n+\tcp.git_cmd = 1;\n+\tcp.argv = argv_am;\n+\tret = run_command(&cp);\n+\tif (IS_RUN_COMMAND_ERR(ret))\n+\t\tdie(\"Could not run git am\");\n+\tif (!ret)\n+\t\tmove_to_original_branch(onto, orig_head, head_name);\n+\tfree(head_name);\n+\treturn ret < 0 ? -ret : 0;\n+}\n+\n+static int cmd_abort()\n+{\n+\tconst char *argv_rerere[] = { \"rerere\", \"clear\", NULL };\n+\tconst char *argv_reset[] = { \"reset\", \"--hard\", NULL /* placeholder */, NULL };\n+\tstruct child_process cp;\n+\tstruct stat st;\n+\tunsigned char onto[20], orig_head[20];\n+\tchar *head_name;\n+\tstruct strbuf sb = STRBUF_INIT;\n+\n+\tcheck_rebase_in_progress();\n+\tmemset(&cp, 0, sizeof(cp));\n+\tcp.git_cmd = 1;\n+\tcp.argv = argv_rerere;\n+\trun_command(&cp);\n+\n+\tif (!stat(git_path(\"rebase-merge\"), &st) && S_ISDIR(st.st_mode)) {\n+\t\tstrbuf_addstr(&sb, git_path(\"rebase-merge\"));\n+\t\thead_name = load_string(\"rebase-merge/head-name\");\n+\t\tload_sha1(\"rebase-merge/onto\", onto);\n+\t\tload_sha1(\"rebase-merge/orig-head\", orig_head);\n+\t\tmove_to_original_branch(onto, orig_head, head_name);\n+\t}\n+\telse {\n+\t\tstrbuf_addstr(&sb, git_path(\"rebase-apply\"));\n+\t\thead_name = load_string(\"rebase-apply/head-name\");\n+\t\tload_sha1(\"rebase-apply/onto\", onto);\n+\t\tload_sha1(\"rebase-apply/orig-head\", orig_head);\n+\t\tmove_to_original_branch(onto, orig_head, head_name);\n+\t}\n+\tfree(head_name);\n+\n+\tcp.argv = argv_reset;\n+\targv_reset[2] = sha1_to_hex(orig_head);\n+\tif (run_command(&cp))\n+\t\tdie(\"Failed running git reset\");\n+\tremove_dir_recursively(&sb, 0);\n+\tstrbuf_release(&sb);\n+\treturn 0;\n+}\n+\n+static int cmd_skip(const struct rebase_opt *opt)\n+{\n+\tconst char *argv_reset[] = { \"reset\", \"--hard\", \"HEAD\", NULL };\n+\tconst char *argv_am[] = { \"am\", \"-3\", \"--skip\", \"--resolvemsg\", resolve_msg, NULL };\n+\tstruct child_process cp;\n+\tchar *head_name;\n+\tunsigned char orig_head[20], onto[20];\n+\tstruct stat st;\n+\tint ret;\n+\n+\tcheck_rebase_in_progress();\n+\tmemset(&cp, 0, sizeof(cp));\n+\tcp.git_cmd = 1;\n+\tcp.argv = argv_reset;\n+\tret = run_command(&cp);\n+\tif (IS_RUN_COMMAND_ERR(ret))\n+\t\tdie(\"Failed to run git reset\");\n+\tif (ret)\n+\t\treturn -ret;\n+\tif (!stat(git_path(\"rebase-merge\"), &st) && S_ISDIR(st.st_mode)) {\n+\t\tconst char *argv_rerere[] = { \"rerere\", \"clear\", NULL };\n+\t\tunsigned char prev_head[20], onto[20], orig_head[20];\n+\t\tint msgnum, end;\n+\t\tchar *head_name;\n+\n+\t\tcp.argv = argv_rerere;\n+\t\trun_command(&cp);\n+\t\tload_sha1(\"rebase-merge/prev_head\", prev_head);\n+\t\tend = load_int(\"rebase-merge/end\");\n+\t\tmsgnum = load_int(\"rebase-merge/msgnum\") + 1;\n+\t\tload_sha1(\"rebase-merge/onto\", onto);\n+\t\twhile (msgnum <= end) {\n+\t\t\tcall_merge(opt->strategy, msgnum);\n+\t\t\tmsgnum = continue_merge(msgnum, prev_head);\n+\t\t}\n+\n+\t\tload_sha1(\"rebase-merge/orig-head\", orig_head);\n+\t\thead_name = load_string(\"rebase-merge/head-name\");\n+\n+\t\tret = finish_rebase_merge(onto, orig_head, head_name);\n+\t\tfree(head_name);\n+\t\treturn ret;\n+\t}\n+\n+\thead_name = load_string(\"rebase-apply/head-name\");\n+\tload_sha1(\"rebase-apply/onto\", onto);\n+\tload_sha1(\"rebase-apply/orig-head\", orig_head);\n+\n+\tcp.argv = argv_am;\n+\tret = run_command(&cp);\n+\tif (IS_RUN_COMMAND_ERR(ret))\n+\t\tdie(\"Failed to run git am\");\n+\tif (ret)\n+\t\treturn -ret;\n+\n+\tmove_to_original_branch(onto, orig_head, head_name);\n+\tfree(head_name);\n+\treturn ret < 0 ? -ret : 0;\n+}\n+\n+static void run_interactive(int argc, const char **argv)\n+{\n+\tint ret, i;\n+\tstruct child_process cp;\n+\tfor (i = 1;i < argc;i++) {\n+\t\tif (!strcmp(argv[i], \"-i\") || !strcmp(argv[i], \"--interactive\"))\n+\t\t\tbreak;\n+\t\tif (!strcmp(argv[i], \"-p\") || !strcmp(argv[i], \"--preserve-merges\")) {\n+\t\t\tsetenv(\"GIT_EDITOR\", \":\", 1);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tif (i == argc) {\n+\t\tstruct stat st;\n+\t\tif (stat(git_path(\"rebase-merge/interactive\"), &st) ||\n+\t\t    !S_ISREG(st.st_mode))\n+\t\t\treturn;\n+\t}\n+\n+\tmemset(&cp, 0, sizeof(cp));\n+\tcp.git_cmd = 1;\n+\tcp.argv = argv;\n+\targv[0] = \"rebase--interactive\";\n+\tret = run_command(&cp);\n+\tif (IS_RUN_COMMAND_ERR(ret))\n+\t\tdie(\"Failed to run git rebase--interactive\");\n+\texit(ret);\n+}\n+\n+/* from diff.c */\n+static void strip_prefix(int prefix_length, const char **namep, const char **otherp)\n+{\n+\t/* Strip the prefix but do not molest /dev/null and absolute paths */\n+\tif (*namep && **namep != '/')\n+\t\t*namep += prefix_length;\n+\tif (*otherp && **otherp != '/')\n+\t\t*otherp += prefix_length;\n+}\n+\n+static void die_dirty_cache(struct diff_queue_struct *q,\n+\t\t\t    struct diff_options *opt,\n+\t\t\t    void *data)\n+{\n+\tint i;\n+\n+\tif (!q->nr)\n+\t\treturn;\n+\n+\tfprintf(stderr,\"cannot rebase: your index contains uncommitted changes\\n\");\n+\n+\tfor (i = 0; i < q->nr; i++) {\n+\t\tstruct diff_filepair *p = q->queue[i];\n+\n+\t\tfprintf(stderr, \"%c \",p->status);\n+\n+\t\tif (p->status == DIFF_STATUS_COPIED ||\n+\t\t    p->status == DIFF_STATUS_RENAMED) {\n+\t\t\tconst char *name_a, *name_b;\n+\t\t\tname_a = p->one->path;\n+\t\t\tname_b = p->two->path;\n+\t\t\tstrip_prefix(opt->prefix_length, &name_a, &name_b);\n+\t\t\twrite_name_quoted(name_a, stderr, '\\t');\n+\t\t\twrite_name_quoted(name_b, stderr, '\\n');\n+\t\t} else {\n+\t\t\tconst char *name_a, *name_b;\n+\t\t\tname_a = p->one->mode ? p->one->path : p->two->path;\n+\t\t\tname_b = NULL;\n+\t\t\tstrip_prefix(opt->prefix_length, &name_a, &name_b);\n+\t\t\twrite_name_quoted(name_a, stderr, '\\n');\n+\t\t}\n+\t}\n+\texit(1);\n+}\n+\n+static void abort_continue_skip(const struct rebase_opt *opt)\n+{\n+\tint count = 0;\n+\tif (opt->flags & REBASE_CONTINUE) count++;\n+\tif (opt->flags & REBASE_SKIP) count++;\n+\tif (opt->flags & REBASE_ABORT) count++;\n+\tif (count > 1)\n+\t\tdie(\"--continue, --skip and --abort are mutually exclusive\");\n+\tif (!count)\n+\t\treturn;\n+\n+\t/* REBASE_STAT may be set by git config */\n+\tif (opt->flags & ~(REBASE_CONTINUE | REBASE_SKIP | REBASE_ABORT | REBASE_STAT))\n+\t\tdie(\"--continue, --skip and --abort do not take any other argument\");\n+\n+\tif (opt->flags & REBASE_CONTINUE) exit(cmd_continue(opt));\n+\tif (opt->flags & REBASE_ABORT) exit(cmd_abort());\n+\tif (opt->flags & REBASE_SKIP) exit(cmd_skip(opt));\n+\n+\tdie(\"Unexpected operation\");\n+}\n+\n+static int cmd_apply_rebase(const struct rebase_opt *opt,\n+\t\t\t    struct object *onto,\n+\t\t\t    struct object *upstream,\n+\t\t\t    struct object *orig_head,\n+\t\t\t    const char *onto_name,\n+\t\t\t    const char *head_name)\n+{\n+\tstruct strbuf sb = STRBUF_INIT;\n+\tconst char *argv_fp[] = { \"format-patch\", \"-k\", \"--stdout\", \"--full-index\",\n+\t\t\t\t  \"--ignore-if-in-upstream\", NULL /* placeholder */, NULL };\n+\tconst char *argv_am[] = { \"am\", \"--rebasing\", \"--resolvemsg\", resolve_msg,\n+\t\t\t\t  NULL, NULL, /* --whitespace */\n+\t\t\t\t  NULL,\t      /* -Cn */\n+\t\t\t\t  NULL,\t      /* --ignore-date */\n+\t\t\t\t  NULL };\n+\tconst char **argp;\n+\tstruct child_process cp_fp, cp_am;\n+\tint fd[2], ret;\n+\tchar context_buf[10];\n+\n+\tstrbuf_addstr(&sb, sha1_to_hex(upstream->sha1));\n+\tstrbuf_addstr(&sb, \"..\");\n+\tstrbuf_addstr(&sb, sha1_to_hex(orig_head->sha1));\n+\n+\tmemset(&cp_fp, 0, sizeof(cp_fp));\n+\tmemset(&cp_am, 0, sizeof(cp_am));\n+\n+\tif (pipe(fd))\n+\t\tdie(\"Failed to make pipe\");\n+\n+\tcp_fp.git_cmd = 1;\n+\tcp_fp.argv = argv_fp;\n+\tcp_fp.out = fd[1];\n+\targv_fp[5] = sb.buf;\n+\n+\targp = argv_am+4;\n+\tif (opt->whitespace) {\n+\t\t*argp++ = \"--whitespace\";\n+\t\t*argp++ = opt->whitespace;\n+\t}\n+\tif (opt->flags & REBASE_IGNORE_DATE)\n+\t\t*argp++ = \"--ignore-date\";\n+\tif (opt->context >= 0) {\n+\t\tsnprintf(context_buf, 10, \"-C%d\", opt->context);\n+\t\t*argp++ = context_buf;\n+\t}\n+\tcp_am.git_cmd = 1;\n+\tcp_am.argv = argv_am;\n+\tcp_am.in = fd[0];\n+\n+\tif (start_command(&cp_fp))\n+\t\tdie(\"Could not run git format-patch\");\n+\tif (start_command(&cp_am))\n+\t\tdie(\"Could not run git am\");\n+\n+\tret = finish_command(&cp_am);\n+\tstrbuf_release(&sb);\n+\tclose(fd[0]);\n+\tclose(fd[1]);\n+\n+\tif (IS_RUN_COMMAND_ERR(ret))\n+\t\tdie(\"Failed to run 'git format-patch|git am'\");\n+\tif (!ret)\n+\t\tmove_to_original_branch(onto->sha1, orig_head->sha1, head_name);\n+\telse {\n+\t\tstruct stat st;\n+\n+\t\tif (!stat(git_path(\"rebase-apply\"), &st) && S_ISDIR(st.st_mode)) {\n+\t\t\tsave_string(\"rebase-apply/head-name\", head_name);\n+\t\t\tsave_sha1(\"rebase-apply/onto\", onto->sha1);\n+\t\t\tsave_sha1(\"rebase-apply/orig-head\", orig_head->sha1);\n+\t\t}\n+\t}\n+\treturn ret;\n+}\n+\n+static int cmd_merge_rebase(const struct rebase_opt *opt,\n+\t\t\t    struct object *onto,\n+\t\t\t    struct object *upstream,\n+\t\t\t    struct object *orig_head,\n+\t\t\t    const char *onto_name,\n+\t\t\t    const char *head_name)\n+{\n+\tint msgnum, end = 0;\n+\tstruct rev_info revs;\n+\tstruct commit *cmt;\n+\tstruct strbuf sb = STRBUF_INIT;\n+\tunsigned char prev_head[20];\n+\n+\t/* git rev-list --reverse --no-merges $onto..$orig_head */\n+\tinit_revisions(&revs, NULL);\n+\trevs.abbrev = 0;\n+\trevs.reverse = 1;\n+\trevs.no_merges = 1;\n+\tupstream->flags |= UNINTERESTING;\n+\tadd_pending_object(&revs, upstream, NULL);\n+\torig_head->flags &= ~UNINTERESTING;\n+\tadd_pending_object(&revs, orig_head, NULL);\n+\n+\tif (prepare_revision_walk(&revs))\n+\t\tdie(\"revision walk setup failed\");\n+\n+\tmemcpy(prev_head, orig_head->sha1, 20);\n+\n+\tmkdir(git_path(\"rebase-merge\"), 0700);\n+\tsave_sha1  (\"rebase-merge/onto\",      onto->sha1);\n+\tsave_string(\"rebase-merge/onto_name\", onto_name);\n+\tsave_sha1  (\"rebase-merge/prev_head\", prev_head);\n+\tsave_sha1  (\"rebase-merge/orig-head\", orig_head->sha1);\n+\tsave_string(\"rebase-merge/head-name\", head_name);\n+\n+\tstrbuf_addstr(&sb, \"rebase-merge/cmt.\");\n+\twhile ((cmt = get_revision(&revs)) != NULL) {\n+\t\tend++;\n+\t\tstrbuf_addf(&sb, \"%d\", end);\n+\t\tsave_sha1(sb.buf, cmt->object.sha1);\n+\t\tstrbuf_setlen(&sb, 17);\n+\t}\n+\tstrbuf_release(&sb);\n+\n+\tmsgnum = 1;\n+\n+\tsave_int(\"rebase-merge/msgnum\", msgnum);\n+\tsave_int(\"rebase-merge/end\", end);\n+\n+\twhile (msgnum <= end) {\n+\t\tcall_merge(opt->strategy, msgnum);\n+\t\tmsgnum = continue_merge(msgnum, prev_head);\n+\t}\n+\n+\treturn finish_rebase_merge(onto->sha1, orig_head->sha1, head_name);\n+}\n+\n+int cmd_rebase(int argc, const char **argv, const char *prefix)\n+{\n+\tstruct rebase_opt opt;\n+\tstruct option options[] = {\n+\t\tOPT_STRING(0,\"onto\",           &opt.onto, \"newbase\", \"starting point at which to create new commits\"),\n+\t\tOPT_STRING('s',\"strategy\",     &opt.strategy, \"strategy\", \"merge strategy to be used\"),\n+\t\tOPT_STRING(0,\"whitespace\",     &opt.whitespace, \"action\", \"to be passed to \\\"git apply\\\"\"),\n+\t\tOPT_INTEGER('C', NULL,         &opt.context, \"surrounding context lines to be matched\"),\n+\t\tOPT_BIT   ('i', \"interactive\", &opt.flags, \"interactive mode\", REBASE_INTERACTIVE),\n+\t\tOPT_BIT   ('v', \"verbose\",     &opt.flags, \"be verbose\", REBASE_VERBOSE | REBASE_STAT),\n+\t\tOPT_BIT   ('f', \"force-rebase\",&opt.flags, \"force rebase\", REBASE_FORCE),\n+\t\tOPT_BIT   ('p', \"preserve-merges\",&opt.flags, \"preserve merges during rebase\", REBASE_PRESERVE_MERGES),\n+\t\tOPT_BIT   ('m', \"merge\",       &opt.flags, \"use merge strategies to rebase\", REBASE_MERGE),\n+\t\tOPT_BIT   (0,   \"no-verify\",   &opt.flags, \"bypass pre-rebase hook\", REBASE_NO_VERIFY),\n+\t\tOPT_NEGBIT('n', \"no-stat\",     &opt.flags, \"do not show diffstat as part of rebase process\", REBASE_STAT),\n+\t\tOPT_BIT   (0,   \"committer-date-is-author-date\", &opt.flags, \"to be passed to \\\"git am\\\"\", REBASE_IGNORE_DATE),\n+\t\tOPT_BIT   (0,   \"ignore-date\", &opt.flags, \"to be passed to \\\"git am\\\"\", REBASE_IGNORE_DATE),\n+\t\tOPT_BIT   (0,   \"stat\",        &opt.flags, \"show diffstat as part of rebase process\", REBASE_STAT),\n+\t\tOPT_BIT   (0,   \"root\",        &opt.flags, \"rebase all reachable commits from <branch>\", REBASE_ROOT),\n+\t\tOPT_BIT   (0,   \"continue\",    &opt.flags, \"restart rebase after having resolved a merge conflict\", REBASE_CONTINUE),\n+\t\tOPT_BIT   (0,   \"skip\",        &opt.flags, \"restart rebase by skipping the current patch\", REBASE_SKIP),\n+\t\tOPT_BIT   (0,   \"abort\",       &opt.flags, \"restore original branch and abort rebase\", REBASE_ABORT),\n+\t\tOPT_END()\n+\t};\n+\n+\tunsigned char upstream_sha1[20], branch_sha1[20], onto_sha1[20], head_sha1[20];\n+\tstruct commit *upstream_cmt, *branch_cmt, *onto_cmt, *head_cmt;\n+\tconst char *argv_checkout_onto[] = { \"checkout\", \"-q\", NULL /* placeholder */, NULL };\n+\tint (*rebase_func)(const struct rebase_opt *, struct object *,\n+\t\t\t   struct object *, struct object *,\n+\t\t\t   const char *, const char *);\n+\tconst char *switch_to = NULL;\n+\tstruct commit_list *mb_cmts;\n+\tstruct child_process cp;\n+\tstruct rev_info revs;\n+\tstruct stat st;\n+\tchar *head_name;\n+\tchar *buf;\n+\tint do_merge;\n+\n+\tif (!stat(git_path(\"rebase-apply/applying\"), &st) && S_ISREG(st.st_mode))\n+\t\tdie(\"It looks like git-am is in progress. Cannot rebase.\");\n+\n+\tsetenv(\"GIT_REFLOG_ACTION\", \"rebase\", 1);\n+\tmemset(&opt, 0, sizeof(opt));\n+\topt.context = -1;\n+\tgit_config(rebase_config, &opt);\n+\n+\trun_interactive(argc, argv);\n+\n+\tif (argc == 1) {\n+\t\tint rebase_merge_exists = !stat(git_path(\"rebase-merge\"), &st) && S_ISDIR(st.st_mode);\n+\t\tint rebase_apply_exists = !stat(git_path(\"rebase-apply\"), &st) && S_ISDIR(st.st_mode);\n+\t\tif (rebase_merge_exists || rebase_apply_exists) {\n+\t\t\tif (rebase_merge_exists ||\n+\t\t\t    (!stat(git_path(\"rebase-apply/rebasing\"), &st) && S_ISREG(st.st_mode)))\n+\t\t\t\tdie(\"A rebase is in progress, try --continue, --skip or --abort.\");\n+\t\t\tdie(\"No arguments given and %s already exists.\", git_path(\"rebase-apply\"));\n+\t\t}\n+\t\telse\n+\t\t\tusage_with_options(rebase_usage, options);\n+\t}\n+\n+\targc = parse_options(argc, argv, options, rebase_usage, 0);\n+\n+\tdo_merge = (opt.flags & REBASE_MERGE) || opt.strategy;\n+\tif (!opt.strategy)\n+\t\topt.strategy = \"recursive\";\n+\n+\tabort_continue_skip(&opt);\n+\n+\tif (opt.whitespace &&\n+\t    (!strcmp(opt.whitespace, \"fix\") ||\n+\t     !strcmp(opt.whitespace, \"strip\")))\n+\t\topt.flags |= REBASE_FORCE;\n+\n+\tif (opt.flags & REBASE_ROOT) {\n+\t\tif (argc > 1)\n+\t\t\tdie(\"Invalid argument\");\n+\t\tif (argc)\n+\t\t\topt.branch = *argv;\n+\t\tif (!opt.onto)\n+\t\t\tdie(\"--root must be used with --onto\");\n+\t}\n+\telse {\n+\t\t/* without --root only takes either 1 or 2 arguments */\n+\t\tif (argc == 0 || argc > 2 ||\n+\t\t    (argc == 2 && (opt.flags & REBASE_ROOT)))\n+\t\t\tdie(\"Invalid argument\");\n+\t\tif (argc) {\n+\t\t\topt.upstream = *argv++;\n+\t\t\tif (argc)\n+\t\t\t\topt.branch = *argv;\n+\t\t}\n+\t}\n+\n+\t/* No rebase ongoing */\n+\tif (do_merge) {\n+\t\tif (!stat(git_path(\"rebase-merge\"), &st) && S_ISREG(st.st_mode))\n+\t\t\tdie(\"previous rebase directory rebase-merge still exists.\"\n+\t\t\t    \"Try git rebase (--continue | --abort | --skip)\");\n+\t}\n+\telse {\n+\t\tif (!mkdir(git_path(\"rebase-apply\"), 0700))\n+\t\t\trmdir(git_path(\"rebase-apply\"));\n+\t\telse\n+\t\t\tdie(\"It seems that I cannot create a rebase-apply directory, and\\n\"\n+\t\t\t    \"I wonder if you are in the middle of the patch application or another\\n\"\n+\t\t\t    \"rebase. If that is not the case, please\\n\"\n+\t\t\t    \"\\trm -fr \\\"%s\\\"/rebase_apply\\n\"\n+\t\t\t    \"and run me again. I am stopping in case you still have something\\n\"\n+\t\t\t    \"valuable there.\",\n+\t\t\t    get_git_dir());\n+\t}\n+\n+\t/* worktree clean */\n+\tif (read_cache() < 0)\n+\t\tdie(\"Could not read the index\");\n+\tif (refresh_cache(REFRESH_IGNORE_SUBMODULES))\n+\t\tdie(\"cannot rebase: you have unstaged changes\");\n+\n+\t/* cache clean */\n+\tinit_revisions(&revs, NULL);\n+\trevs.abbrev = 0;\n+\trevs.diffopt.output_format = DIFF_FORMAT_CALLBACK;\n+\trevs.diffopt.format_callback = die_dirty_cache;\n+\tDIFF_OPT_SET(&revs.diffopt, IGNORE_SUBMODULES);\n+\tDIFF_OPT_SET(&revs.diffopt, RECURSIVE);\n+\tif (get_sha1(\"HEAD\", head_sha1))\n+\t\tdie(\"Could not resolve HEAD\");\n+\thead_cmt = lookup_commit(head_sha1);\n+\tadd_pending_object(&revs, &head_cmt->object, NULL);\n+\trun_diff_index(&revs, 1);\n+\n+\tif (!(opt.flags & REBASE_NO_VERIFY) &&\n+\t    run_hook(NULL, \"pre-rebase\", opt.flags & REBASE_ROOT ? \"--root\" : opt.upstream, opt.branch, NULL)) {\n+\t\tdie(\"The pre-rebase hook refused to rebase.\");\n+\t}\n+\n+\t/* commit validation */\n+\tif (!(opt.flags & REBASE_ROOT))\n+\t\tget_commit(opt.upstream, upstream_sha1, &upstream_cmt);\n+\tget_commit(\"HEAD\", head_sha1, &head_cmt);\n+\tif (opt.onto)\n+\t\tget_commit(opt.onto, onto_sha1, &onto_cmt);\n+\telse {\n+\t\topt.onto = opt.upstream;\n+\t\tmemcpy(onto_sha1, upstream_sha1, 20);\n+\t\tonto_cmt = upstream_cmt;\n+\t}\n+\n+\tif (opt.branch) {\n+\t\tstruct strbuf sb = STRBUF_INIT;\n+\t\tconst char *full_ref;\n+\t\tint type;\n+\n+\t\tswitch_to = opt.branch;\n+\t\tstrbuf_addf(&sb, \"refs/heads/%s\", opt.branch);\n+\t\tfull_ref = resolve_ref(sb.buf, branch_sha1, 1, &type);\n+\t\tif (full_ref)\n+\t\t\thead_name = xstrdup(full_ref);\n+\t\telse {\n+\t\t\tif (!get_sha1(opt.branch, branch_sha1))\n+\t\t\t\thead_name = xstrdup(\"detached HEAD\");\n+\t\t\telse\n+\t\t\t\tdie(\"Failed to parse %s\", opt.branch);\n+\t\t}\n+\t\tstrbuf_release(&sb);\n+\t}\n+\telse {\n+\t\tconst char *full_ref;\n+\t\tint type;\n+\n+\t\topt.branch = \"HEAD\";\n+\t\tfull_ref = resolve_ref(opt.branch, branch_sha1, 1, &type);\n+\t\tif (full_ref) {\n+\t\t\thead_name = xstrdup(full_ref);\n+\t\t\tif (!strncmp(full_ref, \"refs/heads/\", 11))\n+\t\t\t\topt.branch = head_name+11;\n+\t\t}\n+\t\telse {\n+\t\t\thead_name = xstrdup(\"detached HEAD\");\n+\t\t\tif (get_sha1(opt.branch, branch_sha1))\n+\t\t\t\tdie(\"Could not resolve HEAD\");\n+\t\t}\n+\t}\n+\n+\tbranch_cmt = lookup_commit(branch_sha1);\n+\tif (!branch_cmt)\n+\t\tdie(\"Failed to lookup commit for %s\", branch_sha1);\n+\n+\tmemset(&cp, 0, sizeof(cp));\n+\tcp.git_cmd = 1;\n+\n+\t/*\n+\t * Now we are rebasing commits upstream_sha1..branch_sha1\n+\t * (or with --root, everything leading up to branch_sha1)\n+\t * on top of onto_sha1\n+\t */\n+\n+\t/*\n+\t * Check if we are already based on onto_sha1 with linear history,\n+\t * but this should be done only when upstream and onto are the same.\n+\t */\n+\tif (!(opt.flags & REBASE_ROOT) && !memcmp(upstream_sha1, onto_sha1, 20)) {\n+\t\tstruct commit *cmt = branch_cmt;\n+\t\twhile (1) {\n+\t\t\tif (parse_commit(cmt))\n+\t\t\t\tdie(\"Could not parse commit\");\n+\n+\t\t\tif (!cmt->parents || cmt->parents->next)\n+\t\t\t\tbreak;\n+\n+\t\t\tif (cmt->parents->item != onto_cmt) {\n+\t\t\t\tcmt = cmt->parents->item;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tif (opt.flags & REBASE_FORCE) {\n+\t\t\t\tprintf(\"Current branch %s is up to date, rebase forced.\\n\", opt.branch);\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (switch_to) {\n+\t\t\t\tconst char *argv_checkout[] = { \"checkout\", switch_to, NULL };\n+\t\t\t\tcp.argv = argv_checkout;\n+\t\t\t\tif (run_command(&cp))\n+\t\t\t\t\tdie(\"Failed to switch to branch %s\", switch_to);\n+\t\t\t}\n+\t\t\tfprintf(stderr, \"Current branch %s is up to date.\\n\", opt.branch);\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\n+\t/* Detach HEAD and reset the tree */\n+\tprintf(\"First, rewinding head to replay your work on top of it...\\n\");\n+\tbuf = xmalloc(43);\n+\tmemcpy(buf, sha1_to_hex(onto_sha1), 40);\n+\tbuf[40] = '^';\n+\tbuf[41] = '0';\n+\tbuf[42] = '\\0';\n+\targv_checkout_onto[2] = buf;\n+\tcp.argv = argv_checkout_onto;\n+\tif (run_command(&cp))\n+\t\tdie(\"could not detach HEAD\");\n+\tupdate_ref(NULL, \"ORIG_HEAD\", branch_sha1, NULL, REF_NODEREF, DIE_ON_ERR);\n+\n+\t/* diffstat */\n+\tmb_cmts = get_merge_bases(onto_cmt, branch_cmt, 0);\n+\tif (mb_cmts && (opt.flags & REBASE_STAT)) {\n+\t\tstruct rev_info diffrev;\n+\t\tstruct commit *mb_cmt = mb_cmts->item;\n+\n+\t\tif (opt.flags & REBASE_VERBOSE)\n+\t\t\tprintf(\"Changes from %s to %s:\\n\", sha1_to_hex(mb_cmt->object.sha1), opt.onto);\n+\t\tinit_revisions(&diffrev, NULL);\n+\t\tdiffrev.abbrev = 0;\n+\t\tDIFF_OPT_SET(&diffrev.diffopt, RECURSIVE);\n+\t\tdiffrev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY;\n+\t\tif (parse_commit(mb_cmt) || parse_commit(onto_cmt))\n+\t\t\tdie(\"Could not parse commits\");\n+\t\tdiff_tree_sha1(mb_cmt->tree->object.sha1, onto_cmt->tree->object.sha1, \"\", &diffrev.diffopt);\n+\t\tlog_tree_diff_flush(&diffrev);\n+\t}\n+\n+\t/*\n+\t * If the opt.onto is a proper descendant of the tip of the branch,\n+\t * then we just fast forward it.\n+\t */\n+\tif (mb_cmts && mb_cmts->item == branch_cmt) {\n+\t\tfprintf(stderr, \"Fast-forwarded %s to %s\", opt.branch, opt.onto);\n+\t\tmove_to_original_branch(onto_sha1, branch_sha1, head_name);\n+\t\treturn 0;\n+\t}\n+\n+\t/*\n+\t * if --root, revision range will be onto..orig_head\n+\t * otherwise upstream..orig_head\n+\t */\n+\n+\trebase_func = do_merge ? cmd_merge_rebase : cmd_apply_rebase;\n+\treturn rebase_func(&opt, &onto_cmt->object,\n+\t\t\t   opt.flags & REBASE_ROOT ? &onto_cmt->object : &upstream_cmt->object,\n+\t\t\t   &branch_cmt->object, opt.onto, head_name);\n+}\ndiff --git a/builtin.h b/builtin.h\nindex 425ff8e..53bf2b0 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -80,6 +80,7 @@ extern int cmd_prune(int argc, const char **argv, const char *prefix);\n extern int cmd_prune_packed(int argc, const char **argv, const char *prefix);\n extern int cmd_push(int argc, const char **argv, const char *prefix);\n extern int cmd_read_tree(int argc, const char **argv, const char *prefix);\n+extern int cmd_rebase(int argc, const char **argv, const char *prefix);\n extern int cmd_receive_pack(int argc, const char **argv, const char *prefix);\n extern int cmd_reflog(int argc, const char **argv, const char *prefix);\n extern int cmd_remote(int argc, const char **argv, const char *prefix);\ndiff --git a/contrib/examples/git-rebase.sh b/contrib/examples/git-rebase.sh\nnew file mode 100755\nindex 0000000..b83fd3f\n--- /dev/null\n+++ b/contrib/examples/git-rebase.sh\n@@ -0,0 +1,530 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2005 Junio C Hamano.\n+#\n+\n+USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--onto <newbase>] [<upstream>|--root] [<branch>]'\n+LONG_USAGE='git-rebase replaces <branch> with a new branch of the\n+same name.  When the --onto option is provided the new branch starts\n+out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>\n+It then attempts to create a new commit for each commit from the original\n+<branch> that does not exist in the <upstream> branch.\n+\n+It is possible that a merge failure will prevent this process from being\n+completely automatic.  You will have to resolve any such merge failure\n+and run git rebase --continue.  Another option is to bypass the commit\n+that caused the merge failure with git rebase --skip.  To restore the\n+original <branch> and remove the .git/rebase-apply working files, use the\n+command git rebase --abort instead.\n+\n+Note that if <branch> is not specified on the command line, the\n+currently checked out branch is used.\n+\n+Example:       git-rebase master~1 topic\n+\n+        A---B---C topic                   A'\\''--B'\\''--C'\\'' topic\n+       /                   -->           /\n+  D---E---F---G master          D---E---F---G master\n+'\n+\n+SUBDIRECTORY_OK=Yes\n+OPTIONS_SPEC=\n+. git-sh-setup\n+set_reflog_action rebase\n+require_work_tree\n+cd_to_toplevel\n+\n+OK_TO_SKIP_PRE_REBASE=\n+RESOLVEMSG=\"\n+When you have resolved this problem run \\\"git rebase --continue\\\".\n+If you would prefer to skip this patch, instead run \\\"git rebase --skip\\\".\n+To restore the original branch and stop rebasing run \\\"git rebase --abort\\\".\n+\"\n+unset newbase\n+strategy=recursive\n+do_merge=\n+dotest=\"$GIT_DIR\"/rebase-merge\n+prec=4\n+verbose=\n+diffstat=$(git config --bool rebase.stat)\n+git_am_opt=\n+rebase_root=\n+force_rebase=\n+\n+continue_merge () {\n+\ttest -n \"$prev_head\" || die \"prev_head must be defined\"\n+\ttest -d \"$dotest\" || die \"$dotest directory does not exist\"\n+\n+\tunmerged=$(git ls-files -u)\n+\tif test -n \"$unmerged\"\n+\tthen\n+\t\techo \"You still have unmerged paths in your index\"\n+\t\techo \"did you forget to use git add?\"\n+\t\tdie \"$RESOLVEMSG\"\n+\tfi\n+\n+\tcmt=`cat \"$dotest/current\"`\n+\tif ! git diff-index --quiet --ignore-submodules HEAD --\n+\tthen\n+\t\tif ! git commit --no-verify -C \"$cmt\"\n+\t\tthen\n+\t\t\techo \"Commit failed, please do not call \\\"git commit\\\"\"\n+\t\t\techo \"directly, but instead do one of the following: \"\n+\t\t\tdie \"$RESOLVEMSG\"\n+\t\tfi\n+\t\tprintf \"Committed: %0${prec}d \" $msgnum\n+\telse\n+\t\tprintf \"Already applied: %0${prec}d \" $msgnum\n+\tfi\n+\tgit rev-list --pretty=oneline -1 \"$cmt\" | sed -e 's/^[^ ]* //'\n+\n+\tprev_head=`git rev-parse HEAD^0`\n+\t# save the resulting commit so we can read-tree on it later\n+\techo \"$prev_head\" > \"$dotest/prev_head\"\n+\n+\t# onto the next patch:\n+\tmsgnum=$(($msgnum + 1))\n+\techo \"$msgnum\" >\"$dotest/msgnum\"\n+}\n+\n+call_merge () {\n+\tcmt=\"$(cat \"$dotest/cmt.$1\")\"\n+\techo \"$cmt\" > \"$dotest/current\"\n+\thd=$(git rev-parse --verify HEAD)\n+\tcmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD)\n+\tmsgnum=$(cat \"$dotest/msgnum\")\n+\tend=$(cat \"$dotest/end\")\n+\teval GITHEAD_$cmt='\"${cmt_name##refs/heads/}~$(($end - $msgnum))\"'\n+\teval GITHEAD_$hd='$(cat \"$dotest/onto_name\")'\n+\texport GITHEAD_$cmt GITHEAD_$hd\n+\tgit-merge-$strategy \"$cmt^\" -- \"$hd\" \"$cmt\"\n+\trv=$?\n+\tcase \"$rv\" in\n+\t0)\n+\t\tunset GITHEAD_$cmt GITHEAD_$hd\n+\t\treturn\n+\t\t;;\n+\t1)\n+\t\tgit rerere\n+\t\tdie \"$RESOLVEMSG\"\n+\t\t;;\n+\t2)\n+\t\techo \"Strategy: $rv $strategy failed, try another\" 1>&2\n+\t\tdie \"$RESOLVEMSG\"\n+\t\t;;\n+\t*)\n+\t\tdie \"Unknown exit code ($rv) from command:\" \\\n+\t\t\t\"git-merge-$strategy $cmt^ -- HEAD $cmt\"\n+\t\t;;\n+\tesac\n+}\n+\n+move_to_original_branch () {\n+\ttest -z \"$head_name\" &&\n+\t\thead_name=\"$(cat \"$dotest\"/head-name)\" &&\n+\t\tonto=\"$(cat \"$dotest\"/onto)\" &&\n+\t\torig_head=\"$(cat \"$dotest\"/orig-head)\"\n+\tcase \"$head_name\" in\n+\trefs/*)\n+\t\tmessage=\"rebase finished: $head_name onto $onto\"\n+\t\tgit update-ref -m \"$message\" \\\n+\t\t\t$head_name $(git rev-parse HEAD) $orig_head &&\n+\t\tgit symbolic-ref HEAD $head_name ||\n+\t\tdie \"Could not move back to $head_name\"\n+\t\t;;\n+\tesac\n+}\n+\n+finish_rb_merge () {\n+\tmove_to_original_branch\n+\trm -r \"$dotest\"\n+\techo \"All done.\"\n+}\n+\n+is_interactive () {\n+\twhile test $# != 0\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t\t-i|--interactive)\n+\t\t\t\tinteractive_rebase=explicit\n+\t\t\t\tbreak\n+\t\t\t;;\n+\t\t\t-p|--preserve-merges)\n+\t\t\t\tinteractive_rebase=implied\n+\t\t\t;;\n+\t\tesac\n+\t\tshift\n+\tdone\n+\n+\tif [ \"$interactive_rebase\" = implied ]; then\n+\t\tGIT_EDITOR=:\n+\t\texport GIT_EDITOR\n+\tfi\n+\n+\ttest -n \"$interactive_rebase\" || test -f \"$dotest\"/interactive\n+}\n+\n+run_pre_rebase_hook () {\n+\tif test -z \"$OK_TO_SKIP_PRE_REBASE\" &&\n+\t   test -x \"$GIT_DIR/hooks/pre-rebase\"\n+\tthen\n+\t\t\"$GIT_DIR/hooks/pre-rebase\" ${1+\"$@\"} || {\n+\t\t\techo >&2 \"The pre-rebase hook refused to rebase.\"\n+\t\t\texit 1\n+\t\t}\n+\tfi\n+}\n+\n+test -f \"$GIT_DIR\"/rebase-apply/applying &&\n+\tdie 'It looks like git-am is in progress. Cannot rebase.'\n+\n+is_interactive \"$@\" && exec git-rebase--interactive \"$@\"\n+\n+if test $# -eq 0\n+then\n+\ttest -d \"$dotest\" -o -d \"$GIT_DIR\"/rebase-apply || usage\n+\ttest -d \"$dotest\" -o -f \"$GIT_DIR\"/rebase-apply/rebasing &&\n+\t\tdie 'A rebase is in progress, try --continue, --skip or --abort.'\n+\tdie \"No arguments given and $GIT_DIR/rebase-apply already exists.\"\n+fi\n+\n+while test $# != 0\n+do\n+\tcase \"$1\" in\n+\t--no-verify)\n+\t\tOK_TO_SKIP_PRE_REBASE=yes\n+\t\t;;\n+\t--continue)\n+\t\ttest -d \"$dotest\" -o -d \"$GIT_DIR\"/rebase-apply ||\n+\t\t\tdie \"No rebase in progress?\"\n+\n+\t\tgit diff-files --quiet --ignore-submodules || {\n+\t\t\techo \"You must edit all merge conflicts and then\"\n+\t\t\techo \"mark them as resolved using git add\"\n+\t\t\texit 1\n+\t\t}\n+\t\tif test -d \"$dotest\"\n+\t\tthen\n+\t\t\tprev_head=$(cat \"$dotest/prev_head\")\n+\t\t\tend=$(cat \"$dotest/end\")\n+\t\t\tmsgnum=$(cat \"$dotest/msgnum\")\n+\t\t\tonto=$(cat \"$dotest/onto\")\n+\t\t\tcontinue_merge\n+\t\t\twhile test \"$msgnum\" -le \"$end\"\n+\t\t\tdo\n+\t\t\t\tcall_merge \"$msgnum\"\n+\t\t\t\tcontinue_merge\n+\t\t\tdone\n+\t\t\tfinish_rb_merge\n+\t\t\texit\n+\t\tfi\n+\t\thead_name=$(cat \"$GIT_DIR\"/rebase-apply/head-name) &&\n+\t\tonto=$(cat \"$GIT_DIR\"/rebase-apply/onto) &&\n+\t\torig_head=$(cat \"$GIT_DIR\"/rebase-apply/orig-head) &&\n+\t\tgit am --resolved --3way --resolvemsg=\"$RESOLVEMSG\" &&\n+\t\tmove_to_original_branch\n+\t\texit\n+\t\t;;\n+\t--skip)\n+\t\ttest -d \"$dotest\" -o -d \"$GIT_DIR\"/rebase-apply ||\n+\t\t\tdie \"No rebase in progress?\"\n+\n+\t\tgit reset --hard HEAD || exit $?\n+\t\tif test -d \"$dotest\"\n+\t\tthen\n+\t\t\tgit rerere clear\n+\t\t\tprev_head=$(cat \"$dotest/prev_head\")\n+\t\t\tend=$(cat \"$dotest/end\")\n+\t\t\tmsgnum=$(cat \"$dotest/msgnum\")\n+\t\t\tmsgnum=$(($msgnum + 1))\n+\t\t\tonto=$(cat \"$dotest/onto\")\n+\t\t\twhile test \"$msgnum\" -le \"$end\"\n+\t\t\tdo\n+\t\t\t\tcall_merge \"$msgnum\"\n+\t\t\t\tcontinue_merge\n+\t\t\tdone\n+\t\t\tfinish_rb_merge\n+\t\t\texit\n+\t\tfi\n+\t\thead_name=$(cat \"$GIT_DIR\"/rebase-apply/head-name) &&\n+\t\tonto=$(cat \"$GIT_DIR\"/rebase-apply/onto) &&\n+\t\torig_head=$(cat \"$GIT_DIR\"/rebase-apply/orig-head) &&\n+\t\tgit am -3 --skip --resolvemsg=\"$RESOLVEMSG\" &&\n+\t\tmove_to_original_branch\n+\t\texit\n+\t\t;;\n+\t--abort)\n+\t\ttest -d \"$dotest\" -o -d \"$GIT_DIR\"/rebase-apply ||\n+\t\t\tdie \"No rebase in progress?\"\n+\n+\t\tgit rerere clear\n+\t\tif test -d \"$dotest\"\n+\t\tthen\n+\t\t\tmove_to_original_branch\n+\t\telse\n+\t\t\tdotest=\"$GIT_DIR\"/rebase-apply\n+\t\t\tmove_to_original_branch\n+\t\tfi\n+\t\tgit reset --hard $(cat \"$dotest/orig-head\")\n+\t\trm -r \"$dotest\"\n+\t\texit\n+\t\t;;\n+\t--onto)\n+\t\ttest 2 -le \"$#\" || usage\n+\t\tnewbase=\"$2\"\n+\t\tshift\n+\t\t;;\n+\t-M|-m|--m|--me|--mer|--merg|--merge)\n+\t\tdo_merge=t\n+\t\t;;\n+\t-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\\\n+\t\t--strateg=*|--strategy=*|\\\n+\t-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)\n+\t\tcase \"$#,$1\" in\n+\t\t*,*=*)\n+\t\t\tstrategy=`expr \"z$1\" : 'z-[^=]*=\\(.*\\)'` ;;\n+\t\t1,*)\n+\t\t\tusage ;;\n+\t\t*)\n+\t\t\tstrategy=\"$2\"\n+\t\t\tshift ;;\n+\t\tesac\n+\t\tdo_merge=t\n+\t\t;;\n+\t-n|--no-stat)\n+\t\tdiffstat=\n+\t\t;;\n+\t--stat)\n+\t\tdiffstat=t\n+\t\t;;\n+\t-v|--verbose)\n+\t\tverbose=t\n+\t\tdiffstat=t\n+\t\t;;\n+\t--whitespace=*)\n+\t\tgit_am_opt=\"$git_am_opt $1\"\n+\t\tcase \"$1\" in\n+\t\t--whitespace=fix|--whitespace=strip)\n+\t\t\tforce_rebase=t\n+\t\t\t;;\n+\t\tesac\n+\t\t;;\n+\t--committer-date-is-author-date|--ignore-date)\n+\t\tgit_am_opt=\"$git_am_opt $1\"\n+\t\tforce_rebase=t\n+\t\t;;\n+\t-C*)\n+\t\tgit_am_opt=\"$git_am_opt $1\"\n+\t\t;;\n+\t--root)\n+\t\trebase_root=t\n+\t\t;;\n+\t-f|--f|--fo|--for|--forc|force|--force-r|--force-re|--force-reb|--force-reba|--force-rebas|--force-rebase)\n+\t\tforce_rebase=t\n+\t\t;;\n+\t-*)\n+\t\tusage\n+\t\t;;\n+\t*)\n+\t\tbreak\n+\t\t;;\n+\tesac\n+\tshift\n+done\n+test $# -gt 2 && usage\n+\n+# Make sure we do not have $GIT_DIR/rebase-apply\n+if test -z \"$do_merge\"\n+then\n+\tif mkdir \"$GIT_DIR\"/rebase-apply 2>/dev/null\n+\tthen\n+\t\trmdir \"$GIT_DIR\"/rebase-apply\n+\telse\n+\t\techo >&2 '\n+It seems that I cannot create a rebase-apply directory, and\n+I wonder if you are in the middle of patch application or another\n+rebase.  If that is not the case, please\n+\trm -fr '\"$GIT_DIR\"'/rebase-apply\n+and run me again.  I am stopping in case you still have something\n+valuable there.'\n+\t\texit 1\n+\tfi\n+else\n+\tif test -d \"$dotest\"\n+\tthen\n+\t\tdie \"previous rebase directory $dotest still exists.\" \\\n+\t\t\t'Try git rebase (--continue | --abort | --skip)'\n+\tfi\n+fi\n+\n+# The tree must be really really clean.\n+if ! git update-index --ignore-submodules --refresh; then\n+\techo >&2 \"cannot rebase: you have unstaged changes\"\n+\texit 1\n+fi\n+diff=$(git diff-index --cached --name-status -r --ignore-submodules HEAD --)\n+case \"$diff\" in\n+?*)\techo >&2 \"cannot rebase: your index contains uncommitted changes\"\n+\techo >&2 \"$diff\"\n+\texit 1\n+\t;;\n+esac\n+\n+if test -z \"$rebase_root\"\n+then\n+\t# The upstream head must be given.  Make sure it is valid.\n+\tupstream_name=\"$1\"\n+\tshift\n+\tupstream=`git rev-parse --verify \"${upstream_name}^0\"` ||\n+\tdie \"invalid upstream $upstream_name\"\n+\tunset root_flag\n+\tupstream_arg=\"$upstream_name\"\n+else\n+\ttest -z \"$newbase\" && die \"--root must be used with --onto\"\n+\tunset upstream_name\n+\tunset upstream\n+\troot_flag=\"--root\"\n+\tupstream_arg=\"$root_flag\"\n+fi\n+\n+# Make sure the branch to rebase onto is valid.\n+onto_name=${newbase-\"$upstream_name\"}\n+onto=$(git rev-parse --verify \"${onto_name}^0\") || exit\n+\n+# If a hook exists, give it a chance to interrupt\n+run_pre_rebase_hook \"$upstream_arg\" \"$@\"\n+\n+# If the branch to rebase is given, that is the branch we will rebase\n+# $branch_name -- branch being rebased, or HEAD (already detached)\n+# $orig_head -- commit object name of tip of the branch before rebasing\n+# $head_name -- refs/heads/<that-branch> or \"detached HEAD\"\n+switch_to=\n+case \"$#\" in\n+1)\n+\t# Is it \"rebase other $branchname\" or \"rebase other $commit\"?\n+\tbranch_name=\"$1\"\n+\tswitch_to=\"$1\"\n+\n+\tif git show-ref --verify --quiet -- \"refs/heads/$1\" &&\n+\t   branch=$(git rev-parse -q --verify \"refs/heads/$1\")\n+\tthen\n+\t\thead_name=\"refs/heads/$1\"\n+\telif branch=$(git rev-parse -q --verify \"$1\")\n+\tthen\n+\t\thead_name=\"detached HEAD\"\n+\telse\n+\t\tusage\n+\tfi\n+\t;;\n+*)\n+\t# Do not need to switch branches, we are already on it.\n+\tif branch_name=`git symbolic-ref -q HEAD`\n+\tthen\n+\t\thead_name=$branch_name\n+\t\tbranch_name=`expr \"z$branch_name\" : 'zrefs/heads/\\(.*\\)'`\n+\telse\n+\t\thead_name=\"detached HEAD\"\n+\t\tbranch_name=HEAD ;# detached\n+\tfi\n+\tbranch=$(git rev-parse --verify \"${branch_name}^0\") || exit\n+\t;;\n+esac\n+orig_head=$branch\n+\n+# Now we are rebasing commits $upstream..$branch (or with --root,\n+# everything leading up to $branch) on top of $onto\n+\n+# Check if we are already based on $onto with linear history,\n+# but this should be done only when upstream and onto are the same.\n+mb=$(git merge-base \"$onto\" \"$branch\")\n+if test \"$upstream\" = \"$onto\" && test \"$mb\" = \"$onto\" &&\n+\t# linear history?\n+\t! (git rev-list --parents \"$onto\"..\"$branch\" | grep \" .* \") > /dev/null\n+then\n+\tif test -z \"$force_rebase\"\n+\tthen\n+\t\t# Lazily switch to the target branch if needed...\n+\t\ttest -z \"$switch_to\" || git checkout \"$switch_to\"\n+\t\techo >&2 \"Current branch $branch_name is up to date.\"\n+\t\texit 0\n+\telse\n+\t\techo \"Current branch $branch_name is up to date, rebase forced.\"\n+\tfi\n+fi\n+\n+# Detach HEAD and reset the tree\n+echo \"First, rewinding head to replay your work on top of it...\"\n+git checkout -q \"$onto^0\" || die \"could not detach HEAD\"\n+git update-ref ORIG_HEAD $branch\n+\n+if test -n \"$diffstat\"\n+then\n+\tif test -n \"$verbose\"\n+\tthen\n+\t\techo \"Changes from $mb to $onto:\"\n+\tfi\n+\t# We want color (if set), but no pager\n+\tGIT_PAGER='' git diff --stat --summary \"$mb\" \"$onto\"\n+fi\n+\n+# If the $onto is a proper descendant of the tip of the branch, then\n+# we just fast forwarded.\n+if test \"$mb\" = \"$branch\"\n+then\n+\techo >&2 \"Fast-forwarded $branch_name to $onto_name.\"\n+\tmove_to_original_branch\n+\texit 0\n+fi\n+\n+if test -n \"$rebase_root\"\n+then\n+\trevisions=\"$onto..$orig_head\"\n+else\n+\trevisions=\"$upstream..$orig_head\"\n+fi\n+\n+if test -z \"$do_merge\"\n+then\n+\tgit format-patch -k --stdout --full-index --ignore-if-in-upstream \\\n+\t\t$root_flag \"$revisions\" |\n+\tgit am $git_am_opt --rebasing --resolvemsg=\"$RESOLVEMSG\" &&\n+\tmove_to_original_branch\n+\tret=$?\n+\ttest 0 != $ret -a -d \"$GIT_DIR\"/rebase-apply &&\n+\t\techo $head_name > \"$GIT_DIR\"/rebase-apply/head-name &&\n+\t\techo $onto > \"$GIT_DIR\"/rebase-apply/onto &&\n+\t\techo $orig_head > \"$GIT_DIR\"/rebase-apply/orig-head\n+\texit $ret\n+fi\n+\n+# start doing a rebase with git-merge\n+# this is rename-aware if the recursive (default) strategy is used\n+\n+mkdir -p \"$dotest\"\n+echo \"$onto\" > \"$dotest/onto\"\n+echo \"$onto_name\" > \"$dotest/onto_name\"\n+prev_head=$orig_head\n+echo \"$prev_head\" > \"$dotest/prev_head\"\n+echo \"$orig_head\" > \"$dotest/orig-head\"\n+echo \"$head_name\" > \"$dotest/head-name\"\n+\n+msgnum=0\n+for cmt in `git rev-list --reverse --no-merges \"$revisions\"`\n+do\n+\tmsgnum=$(($msgnum + 1))\n+\techo \"$cmt\" > \"$dotest/cmt.$msgnum\"\n+done\n+\n+echo 1 >\"$dotest/msgnum\"\n+echo $msgnum >\"$dotest/end\"\n+\n+end=$msgnum\n+msgnum=1\n+\n+while test \"$msgnum\" -le \"$end\"\n+do\n+\tcall_merge \"$msgnum\"\n+\tcontinue_merge\n+done\n+\n+finish_rb_merge\ndiff --git a/git-rebase.sh b/git-rebase.sh\ndeleted file mode 100755\nindex b83fd3f..0000000\n--- a/git-rebase.sh\n+++ /dev/null\n@@ -1,530 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright (c) 2005 Junio C Hamano.\n-#\n-\n-USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--onto <newbase>] [<upstream>|--root] [<branch>]'\n-LONG_USAGE='git-rebase replaces <branch> with a new branch of the\n-same name.  When the --onto option is provided the new branch starts\n-out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>\n-It then attempts to create a new commit for each commit from the original\n-<branch> that does not exist in the <upstream> branch.\n-\n-It is possible that a merge failure will prevent this process from being\n-completely automatic.  You will have to resolve any such merge failure\n-and run git rebase --continue.  Another option is to bypass the commit\n-that caused the merge failure with git rebase --skip.  To restore the\n-original <branch> and remove the .git/rebase-apply working files, use the\n-command git rebase --abort instead.\n-\n-Note that if <branch> is not specified on the command line, the\n-currently checked out branch is used.\n-\n-Example:       git-rebase master~1 topic\n-\n-        A---B---C topic                   A'\\''--B'\\''--C'\\'' topic\n-       /                   -->           /\n-  D---E---F---G master          D---E---F---G master\n-'\n-\n-SUBDIRECTORY_OK=Yes\n-OPTIONS_SPEC=\n-. git-sh-setup\n-set_reflog_action rebase\n-require_work_tree\n-cd_to_toplevel\n-\n-OK_TO_SKIP_PRE_REBASE=\n-RESOLVEMSG=\"\n-When you have resolved this problem run \\\"git rebase --continue\\\".\n-If you would prefer to skip this patch, instead run \\\"git rebase --skip\\\".\n-To restore the original branch and stop rebasing run \\\"git rebase --abort\\\".\n-\"\n-unset newbase\n-strategy=recursive\n-do_merge=\n-dotest=\"$GIT_DIR\"/rebase-merge\n-prec=4\n-verbose=\n-diffstat=$(git config --bool rebase.stat)\n-git_am_opt=\n-rebase_root=\n-force_rebase=\n-\n-continue_merge () {\n-\ttest -n \"$prev_head\" || die \"prev_head must be defined\"\n-\ttest -d \"$dotest\" || die \"$dotest directory does not exist\"\n-\n-\tunmerged=$(git ls-files -u)\n-\tif test -n \"$unmerged\"\n-\tthen\n-\t\techo \"You still have unmerged paths in your index\"\n-\t\techo \"did you forget to use git add?\"\n-\t\tdie \"$RESOLVEMSG\"\n-\tfi\n-\n-\tcmt=`cat \"$dotest/current\"`\n-\tif ! git diff-index --quiet --ignore-submodules HEAD --\n-\tthen\n-\t\tif ! git commit --no-verify -C \"$cmt\"\n-\t\tthen\n-\t\t\techo \"Commit failed, please do not call \\\"git commit\\\"\"\n-\t\t\techo \"directly, but instead do one of the following: \"\n-\t\t\tdie \"$RESOLVEMSG\"\n-\t\tfi\n-\t\tprintf \"Committed: %0${prec}d \" $msgnum\n-\telse\n-\t\tprintf \"Already applied: %0${prec}d \" $msgnum\n-\tfi\n-\tgit rev-list --pretty=oneline -1 \"$cmt\" | sed -e 's/^[^ ]* //'\n-\n-\tprev_head=`git rev-parse HEAD^0`\n-\t# save the resulting commit so we can read-tree on it later\n-\techo \"$prev_head\" > \"$dotest/prev_head\"\n-\n-\t# onto the next patch:\n-\tmsgnum=$(($msgnum + 1))\n-\techo \"$msgnum\" >\"$dotest/msgnum\"\n-}\n-\n-call_merge () {\n-\tcmt=\"$(cat \"$dotest/cmt.$1\")\"\n-\techo \"$cmt\" > \"$dotest/current\"\n-\thd=$(git rev-parse --verify HEAD)\n-\tcmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD)\n-\tmsgnum=$(cat \"$dotest/msgnum\")\n-\tend=$(cat \"$dotest/end\")\n-\teval GITHEAD_$cmt='\"${cmt_name##refs/heads/}~$(($end - $msgnum))\"'\n-\teval GITHEAD_$hd='$(cat \"$dotest/onto_name\")'\n-\texport GITHEAD_$cmt GITHEAD_$hd\n-\tgit-merge-$strategy \"$cmt^\" -- \"$hd\" \"$cmt\"\n-\trv=$?\n-\tcase \"$rv\" in\n-\t0)\n-\t\tunset GITHEAD_$cmt GITHEAD_$hd\n-\t\treturn\n-\t\t;;\n-\t1)\n-\t\tgit rerere\n-\t\tdie \"$RESOLVEMSG\"\n-\t\t;;\n-\t2)\n-\t\techo \"Strategy: $rv $strategy failed, try another\" 1>&2\n-\t\tdie \"$RESOLVEMSG\"\n-\t\t;;\n-\t*)\n-\t\tdie \"Unknown exit code ($rv) from command:\" \\\n-\t\t\t\"git-merge-$strategy $cmt^ -- HEAD $cmt\"\n-\t\t;;\n-\tesac\n-}\n-\n-move_to_original_branch () {\n-\ttest -z \"$head_name\" &&\n-\t\thead_name=\"$(cat \"$dotest\"/head-name)\" &&\n-\t\tonto=\"$(cat \"$dotest\"/onto)\" &&\n-\t\torig_head=\"$(cat \"$dotest\"/orig-head)\"\n-\tcase \"$head_name\" in\n-\trefs/*)\n-\t\tmessage=\"rebase finished: $head_name onto $onto\"\n-\t\tgit update-ref -m \"$message\" \\\n-\t\t\t$head_name $(git rev-parse HEAD) $orig_head &&\n-\t\tgit symbolic-ref HEAD $head_name ||\n-\t\tdie \"Could not move back to $head_name\"\n-\t\t;;\n-\tesac\n-}\n-\n-finish_rb_merge () {\n-\tmove_to_original_branch\n-\trm -r \"$dotest\"\n-\techo \"All done.\"\n-}\n-\n-is_interactive () {\n-\twhile test $# != 0\n-\tdo\n-\t\tcase \"$1\" in\n-\t\t\t-i|--interactive)\n-\t\t\t\tinteractive_rebase=explicit\n-\t\t\t\tbreak\n-\t\t\t;;\n-\t\t\t-p|--preserve-merges)\n-\t\t\t\tinteractive_rebase=implied\n-\t\t\t;;\n-\t\tesac\n-\t\tshift\n-\tdone\n-\n-\tif [ \"$interactive_rebase\" = implied ]; then\n-\t\tGIT_EDITOR=:\n-\t\texport GIT_EDITOR\n-\tfi\n-\n-\ttest -n \"$interactive_rebase\" || test -f \"$dotest\"/interactive\n-}\n-\n-run_pre_rebase_hook () {\n-\tif test -z \"$OK_TO_SKIP_PRE_REBASE\" &&\n-\t   test -x \"$GIT_DIR/hooks/pre-rebase\"\n-\tthen\n-\t\t\"$GIT_DIR/hooks/pre-rebase\" ${1+\"$@\"} || {\n-\t\t\techo >&2 \"The pre-rebase hook refused to rebase.\"\n-\t\t\texit 1\n-\t\t}\n-\tfi\n-}\n-\n-test -f \"$GIT_DIR\"/rebase-apply/applying &&\n-\tdie 'It looks like git-am is in progress. Cannot rebase.'\n-\n-is_interactive \"$@\" && exec git-rebase--interactive \"$@\"\n-\n-if test $# -eq 0\n-then\n-\ttest -d \"$dotest\" -o -d \"$GIT_DIR\"/rebase-apply || usage\n-\ttest -d \"$dotest\" -o -f \"$GIT_DIR\"/rebase-apply/rebasing &&\n-\t\tdie 'A rebase is in progress, try --continue, --skip or --abort.'\n-\tdie \"No arguments given and $GIT_DIR/rebase-apply already exists.\"\n-fi\n-\n-while test $# != 0\n-do\n-\tcase \"$1\" in\n-\t--no-verify)\n-\t\tOK_TO_SKIP_PRE_REBASE=yes\n-\t\t;;\n-\t--continue)\n-\t\ttest -d \"$dotest\" -o -d \"$GIT_DIR\"/rebase-apply ||\n-\t\t\tdie \"No rebase in progress?\"\n-\n-\t\tgit diff-files --quiet --ignore-submodules || {\n-\t\t\techo \"You must edit all merge conflicts and then\"\n-\t\t\techo \"mark them as resolved using git add\"\n-\t\t\texit 1\n-\t\t}\n-\t\tif test -d \"$dotest\"\n-\t\tthen\n-\t\t\tprev_head=$(cat \"$dotest/prev_head\")\n-\t\t\tend=$(cat \"$dotest/end\")\n-\t\t\tmsgnum=$(cat \"$dotest/msgnum\")\n-\t\t\tonto=$(cat \"$dotest/onto\")\n-\t\t\tcontinue_merge\n-\t\t\twhile test \"$msgnum\" -le \"$end\"\n-\t\t\tdo\n-\t\t\t\tcall_merge \"$msgnum\"\n-\t\t\t\tcontinue_merge\n-\t\t\tdone\n-\t\t\tfinish_rb_merge\n-\t\t\texit\n-\t\tfi\n-\t\thead_name=$(cat \"$GIT_DIR\"/rebase-apply/head-name) &&\n-\t\tonto=$(cat \"$GIT_DIR\"/rebase-apply/onto) &&\n-\t\torig_head=$(cat \"$GIT_DIR\"/rebase-apply/orig-head) &&\n-\t\tgit am --resolved --3way --resolvemsg=\"$RESOLVEMSG\" &&\n-\t\tmove_to_original_branch\n-\t\texit\n-\t\t;;\n-\t--skip)\n-\t\ttest -d \"$dotest\" -o -d \"$GIT_DIR\"/rebase-apply ||\n-\t\t\tdie \"No rebase in progress?\"\n-\n-\t\tgit reset --hard HEAD || exit $?\n-\t\tif test -d \"$dotest\"\n-\t\tthen\n-\t\t\tgit rerere clear\n-\t\t\tprev_head=$(cat \"$dotest/prev_head\")\n-\t\t\tend=$(cat \"$dotest/end\")\n-\t\t\tmsgnum=$(cat \"$dotest/msgnum\")\n-\t\t\tmsgnum=$(($msgnum + 1))\n-\t\t\tonto=$(cat \"$dotest/onto\")\n-\t\t\twhile test \"$msgnum\" -le \"$end\"\n-\t\t\tdo\n-\t\t\t\tcall_merge \"$msgnum\"\n-\t\t\t\tcontinue_merge\n-\t\t\tdone\n-\t\t\tfinish_rb_merge\n-\t\t\texit\n-\t\tfi\n-\t\thead_name=$(cat \"$GIT_DIR\"/rebase-apply/head-name) &&\n-\t\tonto=$(cat \"$GIT_DIR\"/rebase-apply/onto) &&\n-\t\torig_head=$(cat \"$GIT_DIR\"/rebase-apply/orig-head) &&\n-\t\tgit am -3 --skip --resolvemsg=\"$RESOLVEMSG\" &&\n-\t\tmove_to_original_branch\n-\t\texit\n-\t\t;;\n-\t--abort)\n-\t\ttest -d \"$dotest\" -o -d \"$GIT_DIR\"/rebase-apply ||\n-\t\t\tdie \"No rebase in progress?\"\n-\n-\t\tgit rerere clear\n-\t\tif test -d \"$dotest\"\n-\t\tthen\n-\t\t\tmove_to_original_branch\n-\t\telse\n-\t\t\tdotest=\"$GIT_DIR\"/rebase-apply\n-\t\t\tmove_to_original_branch\n-\t\tfi\n-\t\tgit reset --hard $(cat \"$dotest/orig-head\")\n-\t\trm -r \"$dotest\"\n-\t\texit\n-\t\t;;\n-\t--onto)\n-\t\ttest 2 -le \"$#\" || usage\n-\t\tnewbase=\"$2\"\n-\t\tshift\n-\t\t;;\n-\t-M|-m|--m|--me|--mer|--merg|--merge)\n-\t\tdo_merge=t\n-\t\t;;\n-\t-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\\\n-\t\t--strateg=*|--strategy=*|\\\n-\t-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)\n-\t\tcase \"$#,$1\" in\n-\t\t*,*=*)\n-\t\t\tstrategy=`expr \"z$1\" : 'z-[^=]*=\\(.*\\)'` ;;\n-\t\t1,*)\n-\t\t\tusage ;;\n-\t\t*)\n-\t\t\tstrategy=\"$2\"\n-\t\t\tshift ;;\n-\t\tesac\n-\t\tdo_merge=t\n-\t\t;;\n-\t-n|--no-stat)\n-\t\tdiffstat=\n-\t\t;;\n-\t--stat)\n-\t\tdiffstat=t\n-\t\t;;\n-\t-v|--verbose)\n-\t\tverbose=t\n-\t\tdiffstat=t\n-\t\t;;\n-\t--whitespace=*)\n-\t\tgit_am_opt=\"$git_am_opt $1\"\n-\t\tcase \"$1\" in\n-\t\t--whitespace=fix|--whitespace=strip)\n-\t\t\tforce_rebase=t\n-\t\t\t;;\n-\t\tesac\n-\t\t;;\n-\t--committer-date-is-author-date|--ignore-date)\n-\t\tgit_am_opt=\"$git_am_opt $1\"\n-\t\tforce_rebase=t\n-\t\t;;\n-\t-C*)\n-\t\tgit_am_opt=\"$git_am_opt $1\"\n-\t\t;;\n-\t--root)\n-\t\trebase_root=t\n-\t\t;;\n-\t-f|--f|--fo|--for|--forc|force|--force-r|--force-re|--force-reb|--force-reba|--force-rebas|--force-rebase)\n-\t\tforce_rebase=t\n-\t\t;;\n-\t-*)\n-\t\tusage\n-\t\t;;\n-\t*)\n-\t\tbreak\n-\t\t;;\n-\tesac\n-\tshift\n-done\n-test $# -gt 2 && usage\n-\n-# Make sure we do not have $GIT_DIR/rebase-apply\n-if test -z \"$do_merge\"\n-then\n-\tif mkdir \"$GIT_DIR\"/rebase-apply 2>/dev/null\n-\tthen\n-\t\trmdir \"$GIT_DIR\"/rebase-apply\n-\telse\n-\t\techo >&2 '\n-It seems that I cannot create a rebase-apply directory, and\n-I wonder if you are in the middle of patch application or another\n-rebase.  If that is not the case, please\n-\trm -fr '\"$GIT_DIR\"'/rebase-apply\n-and run me again.  I am stopping in case you still have something\n-valuable there.'\n-\t\texit 1\n-\tfi\n-else\n-\tif test -d \"$dotest\"\n-\tthen\n-\t\tdie \"previous rebase directory $dotest still exists.\" \\\n-\t\t\t'Try git rebase (--continue | --abort | --skip)'\n-\tfi\n-fi\n-\n-# The tree must be really really clean.\n-if ! git update-index --ignore-submodules --refresh; then\n-\techo >&2 \"cannot rebase: you have unstaged changes\"\n-\texit 1\n-fi\n-diff=$(git diff-index --cached --name-status -r --ignore-submodules HEAD --)\n-case \"$diff\" in\n-?*)\techo >&2 \"cannot rebase: your index contains uncommitted changes\"\n-\techo >&2 \"$diff\"\n-\texit 1\n-\t;;\n-esac\n-\n-if test -z \"$rebase_root\"\n-then\n-\t# The upstream head must be given.  Make sure it is valid.\n-\tupstream_name=\"$1\"\n-\tshift\n-\tupstream=`git rev-parse --verify \"${upstream_name}^0\"` ||\n-\tdie \"invalid upstream $upstream_name\"\n-\tunset root_flag\n-\tupstream_arg=\"$upstream_name\"\n-else\n-\ttest -z \"$newbase\" && die \"--root must be used with --onto\"\n-\tunset upstream_name\n-\tunset upstream\n-\troot_flag=\"--root\"\n-\tupstream_arg=\"$root_flag\"\n-fi\n-\n-# Make sure the branch to rebase onto is valid.\n-onto_name=${newbase-\"$upstream_name\"}\n-onto=$(git rev-parse --verify \"${onto_name}^0\") || exit\n-\n-# If a hook exists, give it a chance to interrupt\n-run_pre_rebase_hook \"$upstream_arg\" \"$@\"\n-\n-# If the branch to rebase is given, that is the branch we will rebase\n-# $branch_name -- branch being rebased, or HEAD (already detached)\n-# $orig_head -- commit object name of tip of the branch before rebasing\n-# $head_name -- refs/heads/<that-branch> or \"detached HEAD\"\n-switch_to=\n-case \"$#\" in\n-1)\n-\t# Is it \"rebase other $branchname\" or \"rebase other $commit\"?\n-\tbranch_name=\"$1\"\n-\tswitch_to=\"$1\"\n-\n-\tif git show-ref --verify --quiet -- \"refs/heads/$1\" &&\n-\t   branch=$(git rev-parse -q --verify \"refs/heads/$1\")\n-\tthen\n-\t\thead_name=\"refs/heads/$1\"\n-\telif branch=$(git rev-parse -q --verify \"$1\")\n-\tthen\n-\t\thead_name=\"detached HEAD\"\n-\telse\n-\t\tusage\n-\tfi\n-\t;;\n-*)\n-\t# Do not need to switch branches, we are already on it.\n-\tif branch_name=`git symbolic-ref -q HEAD`\n-\tthen\n-\t\thead_name=$branch_name\n-\t\tbranch_name=`expr \"z$branch_name\" : 'zrefs/heads/\\(.*\\)'`\n-\telse\n-\t\thead_name=\"detached HEAD\"\n-\t\tbranch_name=HEAD ;# detached\n-\tfi\n-\tbranch=$(git rev-parse --verify \"${branch_name}^0\") || exit\n-\t;;\n-esac\n-orig_head=$branch\n-\n-# Now we are rebasing commits $upstream..$branch (or with --root,\n-# everything leading up to $branch) on top of $onto\n-\n-# Check if we are already based on $onto with linear history,\n-# but this should be done only when upstream and onto are the same.\n-mb=$(git merge-base \"$onto\" \"$branch\")\n-if test \"$upstream\" = \"$onto\" && test \"$mb\" = \"$onto\" &&\n-\t# linear history?\n-\t! (git rev-list --parents \"$onto\"..\"$branch\" | grep \" .* \") > /dev/null\n-then\n-\tif test -z \"$force_rebase\"\n-\tthen\n-\t\t# Lazily switch to the target branch if needed...\n-\t\ttest -z \"$switch_to\" || git checkout \"$switch_to\"\n-\t\techo >&2 \"Current branch $branch_name is up to date.\"\n-\t\texit 0\n-\telse\n-\t\techo \"Current branch $branch_name is up to date, rebase forced.\"\n-\tfi\n-fi\n-\n-# Detach HEAD and reset the tree\n-echo \"First, rewinding head to replay your work on top of it...\"\n-git checkout -q \"$onto^0\" || die \"could not detach HEAD\"\n-git update-ref ORIG_HEAD $branch\n-\n-if test -n \"$diffstat\"\n-then\n-\tif test -n \"$verbose\"\n-\tthen\n-\t\techo \"Changes from $mb to $onto:\"\n-\tfi\n-\t# We want color (if set), but no pager\n-\tGIT_PAGER='' git diff --stat --summary \"$mb\" \"$onto\"\n-fi\n-\n-# If the $onto is a proper descendant of the tip of the branch, then\n-# we just fast forwarded.\n-if test \"$mb\" = \"$branch\"\n-then\n-\techo >&2 \"Fast-forwarded $branch_name to $onto_name.\"\n-\tmove_to_original_branch\n-\texit 0\n-fi\n-\n-if test -n \"$rebase_root\"\n-then\n-\trevisions=\"$onto..$orig_head\"\n-else\n-\trevisions=\"$upstream..$orig_head\"\n-fi\n-\n-if test -z \"$do_merge\"\n-then\n-\tgit format-patch -k --stdout --full-index --ignore-if-in-upstream \\\n-\t\t$root_flag \"$revisions\" |\n-\tgit am $git_am_opt --rebasing --resolvemsg=\"$RESOLVEMSG\" &&\n-\tmove_to_original_branch\n-\tret=$?\n-\ttest 0 != $ret -a -d \"$GIT_DIR\"/rebase-apply &&\n-\t\techo $head_name > \"$GIT_DIR\"/rebase-apply/head-name &&\n-\t\techo $onto > \"$GIT_DIR\"/rebase-apply/onto &&\n-\t\techo $orig_head > \"$GIT_DIR\"/rebase-apply/orig-head\n-\texit $ret\n-fi\n-\n-# start doing a rebase with git-merge\n-# this is rename-aware if the recursive (default) strategy is used\n-\n-mkdir -p \"$dotest\"\n-echo \"$onto\" > \"$dotest/onto\"\n-echo \"$onto_name\" > \"$dotest/onto_name\"\n-prev_head=$orig_head\n-echo \"$prev_head\" > \"$dotest/prev_head\"\n-echo \"$orig_head\" > \"$dotest/orig-head\"\n-echo \"$head_name\" > \"$dotest/head-name\"\n-\n-msgnum=0\n-for cmt in `git rev-list --reverse --no-merges \"$revisions\"`\n-do\n-\tmsgnum=$(($msgnum + 1))\n-\techo \"$cmt\" > \"$dotest/cmt.$msgnum\"\n-done\n-\n-echo 1 >\"$dotest/msgnum\"\n-echo $msgnum >\"$dotest/end\"\n-\n-end=$msgnum\n-msgnum=1\n-\n-while test \"$msgnum\" -le \"$end\"\n-do\n-\tcall_merge \"$msgnum\"\n-\tcontinue_merge\n-done\n-\n-finish_rb_merge\ndiff --git a/git.c b/git.c\nindex 5a00726..39456a0 100644\n--- a/git.c\n+++ b/git.c\n@@ -336,6 +336,7 @@ static void handle_internal_command(int argc, const char **argv)\n \t\t{ \"prune-packed\", cmd_prune_packed, RUN_SETUP },\n \t\t{ \"push\", cmd_push, RUN_SETUP },\n \t\t{ \"read-tree\", cmd_read_tree, RUN_SETUP },\n+\t\t{ \"rebase\", cmd_rebase, RUN_SETUP | NEED_WORK_TREE },\n \t\t{ \"receive-pack\", cmd_receive_pack },\n \t\t{ \"reflog\", cmd_reflog, RUN_SETUP },\n \t\t{ \"remote\", cmd_remote, RUN_SETUP },\n-- \ntest\n"},{"id":"114405","messageId":"m3ab56kb7y.fsf@localhost.localdomain","threadId":"19430","inReplyTo":"1242899229-27603-2-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v0 2/3] t/t3400-rebase.sh: add more tests to help migrating git-rebase.sh to C","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-05-21T10:22:28Z","receivedAt":"2009-05-21T10:22:28Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Nguyễn Thái Ngọc Duy    <pclouds@gmail.com> writes:\n\n> These new tests make sure I don't miss any check being performed before\n> rebase is proceeded (which is well tested by other tests)\n> \n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  t/t3400-rebase.sh |   28 ++++++++++++++++++++++++++++\n>  1 files changed, 28 insertions(+), 0 deletions(-)\n> \n> diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh\n> index 6e391a3..37f86ab 100755\n> --- a/t/t3400-rebase.sh\n> +++ b/t/t3400-rebase.sh\n> @@ -41,9 +41,37 @@ test_expect_success \\\n>       git tag topic\n>  '\n>  \n> +test_expect_success 'rebase on dirty worktree' '\n> +     echo dirty >> A &&\n> +     ! git rebase master'\n\nShouldn't you use test_must_fail instead? From t/test-lib.sh\n(paraphrasing):\n\n  Writing this as \"! git rebase master\" is wrong, because\n  the failure could be due to a segv.  We want a controlled failure.\n\n> +\n> +test_expect_success 'rebase on dirty cache' '\n> +     git add  A &&\n> +     ! git rebase master'\n> +\n>  test_expect_success 'rebase against master' '\n> +     git reset HEAD &&\n> +     git checkout -f &&\n>       git rebase master'\n>  \n> +test_expect_success 'rebase against master twice' '\n> +\tgit rebase master 2>&1|grep \"Current branch my-topic-branch is up to date\\\\.\"\n> +'\n\nIt would be more readable to split this line on '|', i.e.:\n\n+test_expect_success 'rebase against master twice' '\n+\tgit rebase master 2>&1 |\n+\tgrep \"Current branch my-topic-branch is up to date\\\\.\"\n+'\n\nI think we prefer to save output to a file, and compare this file with\nexpected output (using test_cmp).  Additionally you can check if the\nmessage you want is in correct stream (is in STDERR, and STDOUT is\nempty).\n\n> +\n> +test_expect_success 'rebase against master twice with --force' '\n> +\tgit rebase --force-rebase master 2>&1|grep \"Current branch my-topic-branch is up to date, rebase forced\"\n> +'\n> +\n> +test_expect_success 'rebase against master twice from another branch' '\n> +\tgit checkout my-topic-branch^ &&\n> +\tgit rebase master my-topic-branch 2>&1|grep \"Current branch my-topic-branch is up to date\\\\.\"\n> +'\n> +\n> +test_expect_success 'rebase fast-forward to master' '\n> +\tgit checkout my-topic-branch^ &&\n> +\tgit rebase my-topic-branch 2>&1|grep \"Fast-forwarded HEAD to my-topic-branch\"\n> +'\n\nSame as above.\n\n> +\n>  test_expect_success \\\n>      'the rebase operation should not have destroyed author information' \\\n>      '! (git log | grep \"Author:\" | grep \"<>\")'\n\nErrrr... what?  Why git-log and not git-cat-file?  Why grep twice?\nAdditionally you do not check here that author is unchanged, only that\nis not destroyed.\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"114406","messageId":"m363fukb3j.fsf@localhost.localdomain","threadId":"19430","inReplyTo":"1242899229-27603-3-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v0 3/3] Build in git-rebase.sh","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-05-21T10:25:14Z","receivedAt":"2009-05-21T10:25:14Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Nguyễn Thái Ngọc Duy    <pclouds@gmail.com> writes:\n\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  Regression: \"-M\" is gone. Don't really want to mess up struct option for \"-M\"\n> \n>  Makefile                       |    2 +-\n>  builtin-rebase.c               |  992 ++++++++++++++++++++++++++++++++++++++++\n>  builtin.h                      |    1 +\n>  contrib/examples/git-rebase.sh |  530 +++++++++++++++++++++\n>  git-rebase.sh                  |  530 ---------------------\n>  git.c                          |    1 +\n>  6 files changed, 1525 insertions(+), 531 deletions(-)\n>  create mode 100644 builtin-rebase.c\n>  create mode 100755 contrib/examples/git-rebase.sh\n>  delete mode 100755 git-rebase.sh\n\nYou should have used -M option to git-format-patch to make it clear\nthat this patch moves git-rebase.sh to contrib/examples/git-rebase.sh\nwithout changes.\n \n\n[...]\n> +#define REBASE_ABORT\t\t0x0001\n> +#define REBASE_CONTINUE\t\t0x0002\n> +#define REBASE_FORCE\t\t0x0004\n> +#define REBASE_IGNORE_DATE\t0x0008\n> +#define REBASE_INTERACTIVE\t0x0010\n> +#define REBASE_MERGE\t\t0x0020\n> +#define REBASE_STAT\t\t0x0040\n> +#define REBASE_NO_VERIFY\t0x0080\n> +#define REBASE_PRESERVE_MERGES\t0x0100\n> +#define REBASE_ROOT\t\t0x0200\n> +#define REBASE_SKIP\t\t0x0400\n> +#define REBASE_VERBOSE\t\t0x0800\n\nI see misaligns here...\n\n[...]\n\nCouldn't you use parseopt also in subcommands?\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"114407","messageId":"fcaeb9bf0905210339t44e09c93r1b125dbded8be79@mail.gmail.com","threadId":"19430","inReplyTo":"m3ab56kb7y.fsf@localhost.localdomain","subject":"Re: [PATCH v0 2/3] t/t3400-rebase.sh: add more tests to help migrating git-rebase.sh to C","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2009-05-21T10:39:28Z","receivedAt":"2009-05-21T10:39:28Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2009/5/21 Jakub Narebski <jnareb@gmail.com>:\n> Nguyễn Thái Ngọc Duy    <pclouds@gmail.com> writes:\n>\n>> These new tests make sure I don't miss any check being performed before\n>> rebase is proceeded (which is well tested by other tests)\n>>\n>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n>> ---\n>>  t/t3400-rebase.sh |   28 ++++++++++++++++++++++++++++\n>>  1 files changed, 28 insertions(+), 0 deletions(-)\n>>\n>> diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh\n>> index 6e391a3..37f86ab 100755\n>> --- a/t/t3400-rebase.sh\n>> +++ b/t/t3400-rebase.sh\n>> @@ -41,9 +41,37 @@ test_expect_success \\\n>>       git tag topic\n>>  '\n>>\n>> +test_expect_success 'rebase on dirty worktree' '\n>> +     echo dirty >> A &&\n>> +     ! git rebase master'\n>\n> Shouldn't you use test_must_fail instead? From t/test-lib.sh\n> (paraphrasing):\n>\n>  Writing this as \"! git rebase master\" is wrong, because\n>  the failure could be due to a segv.  We want a controlled failure.\n\nRight. Shouldn't we have another patch to fix this once and for all? I\ndid \"grep -F '! git'\" and find a few places applicable too.\n\n>> +\n>>  test_expect_success \\\n>>      'the rebase operation should not have destroyed author information' \\\n>>      '! (git log | grep \"Author:\" | grep \"<>\")'\n>\n> Errrr... what?  Why git-log and not git-cat-file?  Why grep twice?\n> Additionally you do not check here that author is unchanged, only that\n> is not destroyed.\n\nErrr.. this is not from me. No idea why.\n-- \nDuy\n"},{"id":"114408","messageId":"fcaeb9bf0905210344h7ac8e10bx311bf9d714573eeb@mail.gmail.com","threadId":"19430","inReplyTo":"m363fukb3j.fsf@localhost.localdomain","subject":"Re: [PATCH v0 3/3] Build in git-rebase.sh","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2009-05-21T10:44:08Z","receivedAt":"2009-05-21T10:44:08Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2009/5/21 Jakub Narebski <jnareb@gmail.com>:\n> Nguyễn Thái Ngọc Duy    <pclouds@gmail.com> writes:\n>\n>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n>> ---\n>>  Regression: \"-M\" is gone. Don't really want to mess up struct option for \"-M\"\n>>\n>>  Makefile                       |    2 +-\n>>  builtin-rebase.c               |  992 ++++++++++++++++++++++++++++++++++++++++\n>>  builtin.h                      |    1 +\n>>  contrib/examples/git-rebase.sh |  530 +++++++++++++++++++++\n>>  git-rebase.sh                  |  530 ---------------------\n>>  git.c                          |    1 +\n>>  6 files changed, 1525 insertions(+), 531 deletions(-)\n>>  create mode 100644 builtin-rebase.c\n>>  create mode 100755 contrib/examples/git-rebase.sh\n>>  delete mode 100755 git-rebase.sh\n>\n> You should have used -M option to git-format-patch to make it clear\n> that this patch moves git-rebase.sh to contrib/examples/git-rebase.sh\n> without changes.\n\nYes, much shorter patch. I recall some issues about reversable patch\nlong ago so I did not bother finding this option.\n\n> [...]\n>> +#define REBASE_ABORT         0x0001\n>> +#define REBASE_CONTINUE              0x0002\n>> +#define REBASE_FORCE         0x0004\n>> +#define REBASE_IGNORE_DATE   0x0008\n>> +#define REBASE_INTERACTIVE   0x0010\n>> +#define REBASE_MERGE         0x0020\n>> +#define REBASE_STAT          0x0040\n>> +#define REBASE_NO_VERIFY     0x0080\n>> +#define REBASE_PRESERVE_MERGES       0x0100\n>> +#define REBASE_ROOT          0x0200\n>> +#define REBASE_SKIP          0x0400\n>> +#define REBASE_VERBOSE               0x0800\n>\n> I see misaligns here...\n\nHmm.. it's perfectly aligned in complete source form. Probably because of TABs.\n\n> [...]\n>\n> Couldn't you use parseopt also in subcommands?\n\nI don't understand. You mean parseopt for --continue, --skip and --abort?\n-- \nDuy\n"},{"id":"114410","messageId":"200905211429.13831.jnareb@gmail.com","threadId":"19430","inReplyTo":"fcaeb9bf0905210344h7ac8e10bx311bf9d714573eeb@mail.gmail.com","subject":"Re: [PATCH v0 3/3] Build in git-rebase.sh","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-05-21T12:29:12Z","receivedAt":"2009-05-21T12:29:12Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Thu, 21 May 2009, Nguyen Thai Ngoc Duy wrote:\n> 2009/5/21 Jakub Narebski <jnareb@gmail.com>:\n>> Nguyễn Thái Ngọc Duy    <pclouds@gmail.com> writes:\n\n>> [...]\n>>> +#define REBASE_ABORT         0x0001\n>>> +#define REBASE_CONTINUE              0x0002\n>>> +#define REBASE_FORCE         0x0004\n>>> +#define REBASE_IGNORE_DATE   0x0008\n>>> +#define REBASE_INTERACTIVE   0x0010\n>>> +#define REBASE_MERGE         0x0020\n>>> +#define REBASE_STAT          0x0040\n>>> +#define REBASE_NO_VERIFY     0x0080\n>>> +#define REBASE_PRESERVE_MERGES       0x0100\n>>> +#define REBASE_ROOT          0x0200\n>>> +#define REBASE_SKIP          0x0400\n>>> +#define REBASE_VERBOSE               0x0800\n>>\n>> I see misaligns here...\n> \n> Hmm.. it's perfectly aligned in complete source form. Probably\n> because of TABs. \n\nYes, it is because of using TABs to align (and not only to indent),\nand probably because of changing tabstop because of extra character\n('+' at beginning).  I don't know good solution for this problem.\n \n>> [...]\n>>\n>> Couldn't you use parseopt also in subcommands?\n> \n> I don't understand. You mean parseopt for --continue, --skip and\n> --abort? \n\nYes. I don't know if it possible, and if it would make sense, but it\nseems strange to me having both parseopts in main, and strcmp\ncomparisons for other parts...\n\n-- \nJakub Narebski\nPoland\n"},{"id":"114419","messageId":"7vr5yibknm.fsf@alter.siamese.dyndns.org","threadId":"19430","inReplyTo":"1242899229-27603-2-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v0 2/3] t/t3400-rebase.sh: add more tests to help migrating git-rebase.sh to C","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-05-21T14:22:37Z","receivedAt":"2009-05-21T14:22:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:\n\n> +test_expect_success 'rebase on dirty worktree' '\n> +     echo dirty >> A &&\n> +     ! git rebase master'\n\nIt is a good defensive way to use \"test_must_fail\" instead of \"!\" when\ntesting git itself; test_must_fail does not allow the program to terminate\nwith non-zero value by segfaulting, while \"!\" does.\n\n> +test_expect_success 'rebase on dirty cache' '\n> +     git add  A &&\n\nTwo-spaces?\n\n> +     ! git rebase master'\n> +\n>  test_expect_success 'rebase against master' '\n> +     git reset HEAD &&\n> +     git checkout -f &&\n\nHmm, why not \"reset --hard HEAD\".  Not asking to change (yet), but just\nasking if there is a reason.\n\n>       git rebase master'\n>  \n> +test_expect_success 'rebase against master twice' '\n> +\tgit rebase master 2>&1|grep \"Current branch my-topic-branch is up to date\\\\.\"\n> +'\n> +\n> +test_expect_success 'rebase against master twice with --force' '\n> +\tgit rebase --force-rebase master 2>&1|grep \"Current branch my-topic-branch is up to date, rebase forced\"\n\nDo not to use any pipe while testing, i.e.\n\n\tgit rebase >out 2>err &&\n        grep \"what you expect in 'out'\" out &&\n        grep \"what you expect in 'err'\" err\n\nso that you can catch exit status from the command you placed in the\nupstream of the pipe.\n"},{"id":"114423","messageId":"7vhbzebjvh.fsf@alter.siamese.dyndns.org","threadId":"19430","inReplyTo":"1242899229-27603-3-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v0 3/3] Build in git-rebase.sh","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-05-21T14:39:30Z","receivedAt":"2009-05-21T14:39:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  Regression: \"-M\" is gone. Don't really want to mess up struct option for \"-M\"\n\nGood riddance ;-).  It's not documented, nor I even knew it existed.\n"},{"id":"114444","messageId":"fcaeb9bf0905211557i4b586ecay83d3f160e6b19f3a@mail.gmail.com","threadId":"19430","inReplyTo":"200905211429.13831.jnareb@gmail.com","subject":"Re: [PATCH v0 3/3] Build in git-rebase.sh","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2009-05-21T22:57:49Z","receivedAt":"2009-05-21T22:57:49Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, May 21, 2009 at 10:29 PM, Jakub Narebski <jnareb@gmail.com> wrote:\n>>> [...]\n>>>\n>>> Couldn't you use parseopt also in subcommands?\n>>\n>> I don't understand. You mean parseopt for --continue, --skip and\n>> --abort?\n>\n> Yes. I don't know if it possible, and if it would make sense, but it\n> seems strange to me having both parseopts in main, and strcmp\n> comparisons for other parts...\n\nAh you meant --interactive. It's because git-rebase--interactive.sh is\na separate command and it needs full arguments. parseopts eats\narguments. I'm too lazy to rebuild argv after being eaten by\nparseopts. So just search for \"interactive\" sign, then pass them all\nto git-rebase--interactive.sh (until git-rebase--interactive.sh is\nbuilt in)\n-- \nDuy\n"},{"id":"114450","messageId":"4A164C85.3000703@viscovery.net","threadId":"19430","inReplyTo":"1242899229-27603-3-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v0 3/3] Build in git-rebase.sh","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2009-05-22T06:56:05Z","receivedAt":"2009-05-22T06:56:05Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Nguyễn Thái Ngọc Duy schrieb:\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n\nIs it possible for you to test this series on Windows? Many rebase tests\nfail, but I haven't investigated why.\n\n-- Hannes\n"},{"id":"114452","messageId":"fcaeb9bf0905220030l45e1b7dfqd30f35b7c8e43b51@mail.gmail.com","threadId":"19430","inReplyTo":"4A164C85.3000703@viscovery.net","subject":"Re: [PATCH v0 3/3] Build in git-rebase.sh","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2009-05-22T07:30:31Z","receivedAt":"2009-05-22T07:30:31Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2009/5/22 Johannes Sixt <j.sixt@viscovery.net>:\n> Nguyễn Thái Ngọc Duy schrieb:\n>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n>\n> Is it possible for you to test this series on Windows? Many rebase tests\n> fail, but I haven't investigated why.\n\nI'll try it this weekend.\n-- \nDuy\n"},{"id":"114505","messageId":"20090523092603.GA7420@dektop","threadId":"19430","inReplyTo":"fcaeb9bf0905220030l45e1b7dfqd30f35b7c8e43b51@mail.gmail.com","subject":"Re: [PATCH v0 3/3] Build in git-rebase.sh","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2009-05-23T09:26:03Z","receivedAt":"2009-05-23T09:26:03Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, May 22, 2009 at 05:30:31PM +1000, Nguyen Thai Ngoc Duy wrote:\n> 2009/5/22 Johannes Sixt <j.sixt@viscovery.net>:\n> > Nguyễn Thái Ngọc Duy schrieb:\n> >> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> >\n> > Is it possible for you to test this series on Windows? Many rebase tests\n> > fail, but I haven't investigated why.\n> \n> I'll try it this weekend.\n\nThis patch makes t3*rebase*.sh pass for me except t3412 (more exactly\nt3412.8). That test failed even with git-rebase.sh. Hmm... Anyway\ncould you try again to see what tests still fail?\n\n--<--\ndiff --git a/builtin-rebase.c b/builtin-rebase.c\nindex 2acea59..5582f1d 100644\n--- a/builtin-rebase.c\n+++ b/builtin-rebase.c\n@@ -56,7 +56,8 @@ static int rebase_config(const char *var, const char *value, void *data)\n \t\t\t((struct rebase_opt*)data)->flags |= REBASE_STAT;\n \t\treturn 0;\n \t}\n-\treturn 0;\n+\n+\treturn git_default_config(var, value, data);\n }\n \n /* utility functions */\n@@ -504,7 +505,7 @@ static void run_interactive(int argc, const char **argv)\n \tret = run_command(&cp);\n \tif (IS_RUN_COMMAND_ERR(ret))\n \t\tdie(\"Failed to run git rebase--interactive\");\n-\texit(ret);\n+\texit(-ret);\n }\n \n /* from diff.c */\n--<--\n"},{"id":"114544","messageId":"20090523145042.GA13139@dektop","threadId":"19430","inReplyTo":"20090523092603.GA7420@dektop","subject":"Re: [PATCH v0 3/3] Build in git-rebase.sh","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2009-05-23T14:50:42Z","receivedAt":"2009-05-23T14:50:42Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, May 23, 2009 at 07:26:03PM +1000, Nguyen Thai Ngoc Duy wrote:\n> On Fri, May 22, 2009 at 05:30:31PM +1000, Nguyen Thai Ngoc Duy wrote:\n> > 2009/5/22 Johannes Sixt <j.sixt@viscovery.net>:\n> > > Nguyễn Thái Ngọc Duy schrieb:\n> > >> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> > >\n> > > Is it possible for you to test this series on Windows? Many rebase tests\n> > > fail, but I haven't investigated why.\n> > \n> > I'll try it this weekend.\n> \n> This patch makes t3*rebase*.sh pass for me except t3412 (more exactly\n> t3412.8). That test failed even with git-rebase.sh. Hmm... Anyway\n> could you try again to see what tests still fail?\n\nSomeone with better Windows knowledge than me should explain how this works. Windows'\nsnprintf() just cuts out the last character in this statement:\n\nsnprintf(buf, 8, \"--%s\", \"onto\"); // result: '--ont', expected: '--onto'\n\nAll rebase tests now pass for me on Windows (Vista something, I have\nyet to find where it hides its \"uname\" command)\n\n-->--\ndiff --git a/compat/snprintf.c b/compat/snprintf.c\nindex 357e733..1cea768 100644\n--- a/compat/snprintf.c\n+++ b/compat/snprintf.c\n@@ -13,7 +13,7 @@\n int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)\n {\n \tchar *s;\n-\tint ret = -1;\n+\tint size, ret = -1;\n \n \tif (maxsize > 0) {\n \t\tret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);\n@@ -26,18 +26,19 @@ int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)\n \t\treturn ret;\n \n \ts = NULL;\n-\tif (maxsize < 128)\n-\t\tmaxsize = 128;\n+\tsize = maxsize < 128 ? 128 : maxsize;\n \n \twhile (ret == -1) {\n-\t\tmaxsize *= 4;\n-\t\tstr = realloc(s, maxsize);\n-\t\tif (! str)\n+\t\tsize *= 4;\n+\t\ts = realloc(s, size);\n+\t\tif (!s)\n \t\t\tbreak;\n-\t\ts = str;\n-\t\tret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);\n-\t\tif (ret == maxsize-1)\n+\t\ts = s;\n+\t\tret = vsnprintf(s, size-SNPRINTF_SIZE_CORR, format, ap);\n+\t\tif (ret == size-1)\n \t\t\tret = -1;\n+\t\telse\n+\t\t\tmemcpy(str, s, maxsize-1);\n \t}\n \tfree(s);\n \treturn ret;\n-->--\n"},{"id":"114546","messageId":"1243092662-19897-1-git-send-email-pclouds@gmail.com","threadId":"19430","inReplyTo":"7vr5yibknm.fsf@alter.siamese.dyndns.org","subject":"[PATCH 2/3] t/t3400-rebase.sh: add more tests to help migrating git-rebase.sh to C","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2009-05-23T15:31:02Z","receivedAt":"2009-05-23T15:31:02Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"These new tests make sure I don't miss any check being performed before\nrebase is proceeded (which is well tested by other tests)\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Fixed pipe stuff, test_must_fail and spaces\n\n t/t3400-rebase.sh |   31 +++++++++++++++++++++++++++++++\n 1 files changed, 31 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh\nindex 6e391a3..7f62bfb 100755\n--- a/t/t3400-rebase.sh\n+++ b/t/t3400-rebase.sh\n@@ -41,9 +41,40 @@ test_expect_success \\\n      git tag topic\n '\n \n+test_expect_success 'rebase on dirty worktree' '\n+     echo dirty >> A &&\n+     test_must_fail git rebase master'\n+\n+test_expect_success 'rebase on dirty cache' '\n+     git add A &&\n+     test_must_fail git rebase master'\n+\n test_expect_success 'rebase against master' '\n+     git reset --hard HEAD &&\n      git rebase master'\n \n+test_expect_success 'rebase against master twice' '\n+     git rebase master 2>err &&\n+     grep \"Current branch my-topic-branch is up to date\" err\n+'\n+\n+test_expect_success 'rebase against master twice with --force' '\n+     git rebase --force-rebase master >out &&\n+     grep \"Current branch my-topic-branch is up to date, rebase forced\" out\n+'\n+\n+test_expect_success 'rebase against master twice from another branch' '\n+     git checkout my-topic-branch^ &&\n+     git rebase master my-topic-branch 2>err &&\n+     grep \"Current branch my-topic-branch is up to date\" err\n+'\n+\n+test_expect_success 'rebase fast-forward to master' '\n+     git checkout my-topic-branch^ &&\n+     git rebase my-topic-branch 2>err &&\n+     grep \"Fast-forwarded HEAD to my-topic-branch\" err\n+'\n+\n test_expect_success \\\n     'the rebase operation should not have destroyed author information' \\\n     '! (git log | grep \"Author:\" | grep \"<>\")'\n-- \ntest\n"},{"id":"114621","messageId":"4A1A37AD.4080309@viscovery.net","threadId":"19430","inReplyTo":"20090523145042.GA13139@dektop","subject":"Re: [PATCH v0 3/3] Build in git-rebase.sh","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2009-05-25T06:16:13Z","receivedAt":"2009-05-25T06:16:13Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Nguyen Thai Ngoc Duy schrieb:\n> On Sat, May 23, 2009 at 07:26:03PM +1000, Nguyen Thai Ngoc Duy wrote:\n>> On Fri, May 22, 2009 at 05:30:31PM +1000, Nguyen Thai Ngoc Duy wrote:\n>>> 2009/5/22 Johannes Sixt <j.sixt@viscovery.net>:\n>>>> Nguyễn Thái Ngọc Duy schrieb:\n>>>>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n>>>> Is it possible for you to test this series on Windows? Many rebase tests\n>>>> fail, but I haven't investigated why.\n>>> I'll try it this weekend.\n>> This patch makes t3*rebase*.sh pass for me except t3412 (more exactly\n>> t3412.8). That test failed even with git-rebase.sh. Hmm... Anyway\n>> could you try again to see what tests still fail?\n> \n> Someone with better Windows knowledge than me should explain how this works. Windows'\n> snprintf() just cuts out the last character in this statement:\n> \n> snprintf(buf, 8, \"--%s\", \"onto\"); // result: '--ont', expected: '--onto'\n\nThis doesn't happen for me: neither with Windows's original snprintf nor\nwith the version from compat/. Are you using the latest msysgit\nenvironment to compile, i.e. gcc 4.4? There was a change regarding\nSNPRINTF_SIZE_CORR; perhaps that's the culprit?\n\nI don't undertand what this patch does, anyway. Where is the detail that I\nam missing?\n\n> All rebase tests now pass for me on Windows (Vista something, I have\n> yet to find where it hides its \"uname\" command)\n\nThey also pass for me with your earlier fix-up patch, but with or without\nthis patch to compat/snprintf.c.\n\n> diff --git a/compat/snprintf.c b/compat/snprintf.c\n> index 357e733..1cea768 100644\n> --- a/compat/snprintf.c\n> +++ b/compat/snprintf.c\n> @@ -13,7 +13,7 @@\n>  int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)\n>  {\n>  \tchar *s;\n> -\tint ret = -1;\n> +\tint size, ret = -1;\n>  \n>  \tif (maxsize > 0) {\n>  \t\tret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);\n> @@ -26,18 +26,19 @@ int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)\n>  \t\treturn ret;\n>  \n>  \ts = NULL;\n> -\tif (maxsize < 128)\n> -\t\tmaxsize = 128;\n> +\tsize = maxsize < 128 ? 128 : maxsize;\n>  \n>  \twhile (ret == -1) {\n> -\t\tmaxsize *= 4;\n> -\t\tstr = realloc(s, maxsize);\n> -\t\tif (! str)\n> +\t\tsize *= 4;\n> +\t\ts = realloc(s, size);\n> +\t\tif (!s)\n>  \t\t\tbreak;\n> -\t\ts = str;\n> -\t\tret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);\n> -\t\tif (ret == maxsize-1)\n> +\t\ts = s;\n> +\t\tret = vsnprintf(s, size-SNPRINTF_SIZE_CORR, format, ap);\n> +\t\tif (ret == size-1)\n>  \t\t\tret = -1;\n> +\t\telse\n> +\t\t\tmemcpy(str, s, maxsize-1);\n>  \t}\n>  \tfree(s);\n>  \treturn ret;\n"},{"id":"114623","messageId":"fcaeb9bf0905242334q37ef9a05xa05315639af4daf3@mail.gmail.com","threadId":"19430","inReplyTo":"4A1A37AD.4080309@viscovery.net","subject":"Re: [PATCH v0 3/3] Build in git-rebase.sh","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2009-05-25T06:34:52Z","receivedAt":"2009-05-25T06:34:52Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, May 25, 2009 at 4:16 PM, Johannes Sixt <j.sixt@viscovery.net> wrote:\n> Nguyen Thai Ngoc Duy schrieb:\n>> On Sat, May 23, 2009 at 07:26:03PM +1000, Nguyen Thai Ngoc Duy wrote:\n>>> On Fri, May 22, 2009 at 05:30:31PM +1000, Nguyen Thai Ngoc Duy wrote:\n>>>> 2009/5/22 Johannes Sixt <j.sixt@viscovery.net>:\n>>>>> Nguyễn Thái Ngọc Duy schrieb:\n>>>>>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n>>>>> Is it possible for you to test this series on Windows? Many rebase tests\n>>>>> fail, but I haven't investigated why.\n>>>> I'll try it this weekend.\n>>> This patch makes t3*rebase*.sh pass for me except t3412 (more exactly\n>>> t3412.8). That test failed even with git-rebase.sh. Hmm... Anyway\n>>> could you try again to see what tests still fail?\n>>\n>> Someone with better Windows knowledge than me should explain how this works. Windows'\n>> snprintf() just cuts out the last character in this statement:\n>>\n>> snprintf(buf, 8, \"--%s\", \"onto\"); // result: '--ont', expected: '--onto'\n>\n> This doesn't happen for me: neither with Windows's original snprintf nor\n> with the version from compat/. Are you using the latest msysgit\n> environment to compile, i.e. gcc 4.4? There was a change regarding\n> SNPRINTF_SIZE_CORR; perhaps that's the culprit?\n\nIt could be. I used git.git's next branch, not msys4git or mingw.git\nrepositories.\n\n> I don't undertand what this patch does, anyway. Where is the detail that I\n> am missing?\n\nThe first vsnprintf() in \"onto\" case above did not produce \" --onto\"\nas it should have been. I tried to recover by filling \"str\" with the\nsecond vsnprintf() in the loop.\n\n>> All rebase tests now pass for me on Windows (Vista something, I have\n>> yet to find where it hides its \"uname\" command)\n>\n> They also pass for me with your earlier fix-up patch, but with or without\n> this patch to compat/snprintf.c.\n\nGood to know.\n-- \nDuy\n"},{"id":"114625","messageId":"4A1A3EF6.1050405@viscovery.net","threadId":"19430","inReplyTo":"fcaeb9bf0905242334q37ef9a05xa05315639af4daf3@mail.gmail.com","subject":"Re: [PATCH v0 3/3] Build in git-rebase.sh","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2009-05-25T06:47:18Z","receivedAt":"2009-05-25T06:47:18Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Nguyen Thai Ngoc Duy schrieb:\n> On Mon, May 25, 2009 at 4:16 PM, Johannes Sixt <j.sixt@viscovery.net> wrote:\n>> Nguyen Thai Ngoc Duy schrieb:\n>>> Someone with better Windows knowledge than me should explain how this works. Windows'\n>>> snprintf() just cuts out the last character in this statement:\n>>>\n>>> snprintf(buf, 8, \"--%s\", \"onto\"); // result: '--ont', expected: '--onto'\n>> This doesn't happen for me: neither with Windows's original snprintf nor\n>> with the version from compat/. Are you using the latest msysgit\n>> environment to compile, i.e. gcc 4.4? There was a change regarding\n>> SNPRINTF_SIZE_CORR; perhaps that's the culprit?\n> \n> It could be. I used git.git's next branch, not msys4git or mingw.git\n> repositories.\n\nOK. Assuming you are using the latest msysgit compiler, which is gcc 4.4,\nthen you need the SNPRINTF_SIZE_CORR related patch from 4msysgit.git.\n\n-- Hannes\n"},{"id":"114626","messageId":"fcaeb9bf0905250000n299f599fp3738e5385add075a@mail.gmail.com","threadId":"19430","inReplyTo":"4A1A3EF6.1050405@viscovery.net","subject":"Re: [PATCH v0 3/3] Build in git-rebase.sh","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2009-05-25T07:00:44Z","receivedAt":"2009-05-25T07:00:44Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, May 25, 2009 at 4:47 PM, Johannes Sixt <j.sixt@viscovery.net> wrote:\n> Nguyen Thai Ngoc Duy schrieb:\n>> On Mon, May 25, 2009 at 4:16 PM, Johannes Sixt <j.sixt@viscovery.net> wrote:\n>>> Nguyen Thai Ngoc Duy schrieb:\n>>>> Someone with better Windows knowledge than me should explain how this works. Windows'\n>>>> snprintf() just cuts out the last character in this statement:\n>>>>\n>>>> snprintf(buf, 8, \"--%s\", \"onto\"); // result: '--ont', expected: '--onto'\n>>> This doesn't happen for me: neither with Windows's original snprintf nor\n>>> with the version from compat/. Are you using the latest msysgit\n>>> environment to compile, i.e. gcc 4.4? There was a change regarding\n>>> SNPRINTF_SIZE_CORR; perhaps that's the culprit?\n>>\n>> It could be. I used git.git's next branch, not msys4git or mingw.git\n>> repositories.\n>\n> OK. Assuming you are using the latest msysgit compiler, which is gcc 4.4,\n> then you need the SNPRINTF_SIZE_CORR related patch from 4msysgit.git.\n\nIt's cross compiler 4.3. Will try the patch.\n-- \nDuy\n"},{"id":"114631","messageId":"fcaeb9bf0905250039gcc0d8c1h788f726a13281452@mail.gmail.com","threadId":"19430","inReplyTo":"fcaeb9bf0905250000n299f599fp3738e5385add075a@mail.gmail.com","subject":"Re: [PATCH v0 3/3] Build in git-rebase.sh","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2009-05-25T07:39:44Z","receivedAt":"2009-05-25T07:39:44Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, May 25, 2009 at 5:00 PM, Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:\n> On Mon, May 25, 2009 at 4:47 PM, Johannes Sixt <j.sixt@viscovery.net> wrote:\n>> Nguyen Thai Ngoc Duy schrieb:\n>>> On Mon, May 25, 2009 at 4:16 PM, Johannes Sixt <j.sixt@viscovery.net> wrote:\n>>>> Nguyen Thai Ngoc Duy schrieb:\n>>>>> Someone with better Windows knowledge than me should explain how this works. Windows'\n>>>>> snprintf() just cuts out the last character in this statement:\n>>>>>\n>>>>> snprintf(buf, 8, \"--%s\", \"onto\"); // result: '--ont', expected: '--onto'\n>>>> This doesn't happen for me: neither with Windows's original snprintf nor\n>>>> with the version from compat/. Are you using the latest msysgit\n>>>> environment to compile, i.e. gcc 4.4? There was a change regarding\n>>>> SNPRINTF_SIZE_CORR; perhaps that's the culprit?\n>>>\n>>> It could be. I used git.git's next branch, not msys4git or mingw.git\n>>> repositories.\n>>\n>> OK. Assuming you are using the latest msysgit compiler, which is gcc 4.4,\n>> then you need the SNPRINTF_SIZE_CORR related patch from 4msysgit.git.\n>\n> It's cross compiler 4.3. Will try the patch.\n\nIt is because of SNPRINTF_SIZE_CORR. Thank you.\n-- \nDuy\n"}]}