aboutsummaryrefslogtreecommitdiff
path: root/git-rebase--interactive.sh
Commit message (Collapse)AuthorAge
* rebase -i: Abort cleanly if new base cannot be checked outIan Ward Comfort2010-06-11
| | | | | | | | | | | | | Untracked content in the working tree may prevent rebase -i from checking out the new base onto which it wants to replay commits, if the new base commit includes files at those (now untracked) paths. Currently, rebase -i dies uncleanly in this situation, updating ORIG_HEAD and leaving a useless .git/rebase-merge directory, with which the user can do nothing useful except rebase --abort. Make rebase -i abort the procedure itself instead, as non-interactive rebase already does, and add a test for this behavior. Signed-off-by: Ian Ward Comfort <icomfort@stanford.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rebase-interactive: silence warning when no commits rewrittenJeff King2010-04-18
| | | | | | | | | | | | | | | | | If you do a "rebase -i" and don't change any commits, nothing is rewritten, and we have no REWRITTEN_LIST. The shell prints out an ugly message: $ GIT_EDITOR=true git rebase -i HEAD^ /path/to/git-rebase--interactive: 1: cannot open /path/to/repo/.git/rebase-merge/rewritten-list: No such file Successfully rebased and updated refs/heads/master. We can fix it by not running "notes copy" at all if nothing was rewritten. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* Merge branch 'mb/rebase-i-no-ff'Junio C Hamano2010-04-03
|\ | | | | | | | | | | | | | | | | * mb/rebase-i-no-ff: Teach rebase the --no-ff option. Conflicts: git-rebase--interactive.sh t/t3404-rebase-interactive.sh
| * Teach rebase the --no-ff option.Marc Branchaud2010-03-24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For git-rebase.sh, --no-ff is a synonym for --force-rebase. For git-rebase--interactive.sh, --no-ff cherry-picks all the commits in the rebased branch, instead of fast-forwarding over any unchanged commits. --no-ff offers an alternative way to deal with reverted merges. Instead of "reverting the revert" you can use "rebase --no-ff" to recreate the branch with entirely new commits (they're new because at the very least the committer time is different). This obviates the need to revert the reversion, as you can re-merge the new topic branch directly. Added an addendum to revert-a-faulty-merge.txt describing the situation and how to use --no-ff to handle it. Signed-off-by: Marc Branchaud <marcnarc@xiplink.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Merge branch 'do/rebase-i-arbitrary'Junio C Hamano2010-04-03
|\ \ | | | | | | | | | | | | | | | | | | | | | * do/rebase-i-arbitrary: rebase--interactive: don't require what's rebased to be a branch Conflicts: t/t3404-rebase-interactive.sh
| * | rebase--interactive: don't require what's rebased to be a branchDave Olszewski2010-03-14
| |/ | | | | | | | | | | | | | | | | | | git rebase allows you to specify a non-branch commit-ish as the "branch" argument, which leaves HEAD detached when it's finished. This is occasionally useful, and this patch brings the same functionality to git rebase --interactive. Signed-off-by: Dave Olszewski <cxreg@pobox.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Merge branch 'cc/cherry-pick-ff'Junio C Hamano2010-03-28
|\ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * cc/cherry-pick-ff: revert: fix tiny memory leak in cherry-pick --ff rebase -i: use new --ff cherry-pick option Documentation: describe new cherry-pick --ff option cherry-pick: add tests for new --ff option revert: add --ff option to allow fast forward when cherry-picking builtin/merge: make checkout_fast_forward() non static parse-options: add parse_options_concat() to concat options
| * | rebase -i: use new --ff cherry-pick optionChristian Couder2010-03-20
| |/ | | | | | | | | | | | | This simplifies rebase -i a little bit. Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | rebase -i: make post-rewrite work for 'edit'Thomas Rast2010-03-28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The post-rewrite support, in the form of the call to 'record_in_rewritten', was hidden in the arm where we have to record a new commit for the user. This meant that it was never invoked in the case where the user has already amended the commit by herself. [The test is designed to exercise both arms of the 'if' in question.] Furthermore, recording the stopped-sha (the SHA1 of the commit before the editing) suffered from a cut&paste error from die_with_patch and used the wrong variable, hence it never recorded anything. Noticed by Junio. Signed-off-by: Thomas Rast <trast@student.ethz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Merge branch 'tr/notes-display'Junio C Hamano2010-03-24
|\ \ | |/ |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * tr/notes-display: git-notes(1): add a section about the meaning of history notes: track whether notes_trees were changed at all notes: add shorthand --ref to override GIT_NOTES_REF commit --amend: copy notes to the new commit rebase: support automatic notes copying notes: implement helpers needed for note copying during rewrite notes: implement 'git notes copy --stdin' rebase -i: invoke post-rewrite hook rebase: invoke post-rewrite hook commit --amend: invoke post-rewrite hook Documentation: document post-rewrite hook Support showing notes from more than one notes tree test-lib: unset GIT_NOTES_REF to stop it from influencing tests Conflicts: git-am.sh refs.c
| * rebase: support automatic notes copyingThomas Rast2010-03-12
| | | | | | | | | | | | | | Luckily, all the support already happens to be there. Signed-off-by: Thomas Rast <trast@student.ethz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: invoke post-rewrite hookThomas Rast2010-03-12
| | | | | | | | | | | | | | | | | | | | | | Aside from the same issue that rebase also has (remembering the original commit across a conflict resolution), rebase -i brings an extra twist: We need to defer writing the rewritten list in the case of {squash,fixup} because their rewritten result should be the last commit in the squashed group. Signed-off-by: Thomas Rast <trast@student.ethz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * commit --amend: invoke post-rewrite hookThomas Rast2010-03-12
| | | | | | | | | | | | | | | | | | | | | | | | The rough structure of run_rewrite_hook() comes from run_receive_hook() in receive-pack. We introduce a --no-post-rewrite option and use it to avoid the hook when called from git-rebase -i 'edit'. The next patch will add full support in git-rebase, and we only want to invoke the hook once. Signed-off-by: Thomas Rast <trast@student.ethz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | work around an obnoxious bash "safety feature" on OpenBSDJunio C Hamano2010-01-26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Bash (4.0.24) on OpenBSD 4.6 refuses to run this snippet: $ cat gomi.sh #!/bin/sh one="/var/tmp/1 1" rm -f /var/tmp/1 "/var/tmp/1 1" echo hello >$one $ sh gomi.sh; ls /var/tmp/1* /var/tmp/1 1 $ bash gomi.sh; ls /var/tmp/1* gomi.sh: line 4: $one: ambiguous redirect ls: /var/tmp/1*: No such file or directory Every competent shell programmer knows that a <$word in redirection is not subject to field splitting (POSIX.1 "2.7 Redirection" explicitly lists the kind of expansion performed: "... the word that follows the redirection operator shall be subjected to ...", and "Field Splitting" is not among them). Some clueless folks apparently decided that users need to be protected in the name of "security", however. Output from "git grep -e '> *\$' -- '*.sh'" indicates that rebase-i suffers from this bogus "safety". Work it around by surrounding the variable reference with a dq pair. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | fix portability issues with $ in double quotesStephen Boyd2010-01-26
| | | | | | | | | | | | | | | | Using a dollar sign in double quotes isn't portable. Escape them with a backslash or replace the double quotes with single quotes. Signed-off-by: Stephen Boyd <bebarino@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | rebase -i: Export GIT_AUTHOR_* variables explicitlyJunio C Hamano2010-01-23
|/ | | | | | | | | | | | | | | | | There is no point doing self-assignments of these variables. Instead, just export them to the environment, but do so in a sub-shell, because VAR1=VAL1 VAR2=VAL2 ... command arg1 arg2... does not mark the variables exported if command that is run is a shell function, according to POSIX.1. The callers of do_with_author do not rely on seeing the effect of any shell variable assignments that may happen inside what was called through this shell function (currently "output" is the only one), so running it in the subshell doesn't have an adverse semantic effect. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rebase -i: Avoid non-portable "test X -a Y"Michael Haggerty2010-01-22
| | | | | | | Reported by: Eric Blake <ebb9@byu.net> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* Merge branch 'mh/rebase-fixup'Junio C Hamano2010-01-20
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * mh/rebase-fixup: rebase -i: Retain user-edited commit messages after squash/fixup conflicts t3404: Set up more of the test repo in the "setup" step rebase -i: For fixup commands without squashes, do not start editor rebase -i: Change function make_squash_message into update_squash_message rebase -i: Extract function do_with_author rebase -i: Handle the author script all in one place in do_next rebase -i: Extract a function "commit_message" rebase -i: Simplify commit counting for generated commit messages rebase -i: Improve consistency of commit count in generated commit messages t3404: Test the commit count in commit messages generated by "rebase -i" rebase -i: Introduce a constant AMEND rebase -i: Introduce a constant AUTHOR_SCRIPT rebase -i: Document how temporary files are used rebase -i: Use symbolic constant $MSG consistently rebase -i: Use "test -n" instead of "test ! -z" rebase -i: Inline expression rebase -i: Remove dead code rebase -i: Make the condition for an "if" more transparent
| * rebase -i: Retain user-edited commit messages after squash/fixup conflictsMichael Haggerty2010-01-14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When a squash/fixup fails due to a conflict, the user is required to edit the commit message. Previously, if further squash/fixup commands followed the conflicting squash/fixup, this user-edited message was discarded and a new automatically-generated commit message was suggested. Change the handling of conflicts within squash/fixup command series: Whenever the user is required to intervene, consider the resulting commit to be a new basis for the following squash/fixups and use its commit message in later suggested combined commit messages. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: For fixup commands without squashes, do not start editorMichael Haggerty2010-01-14
| | | | | | | | | | | | | | | | | | | | If the "rebase -i" commands include a series of fixup commands without any squash commands, then commit the combined commit using the commit message of the corresponding "pick" without starting up the commit-message editor. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: Change function make_squash_message into update_squash_messageMichael Haggerty2010-01-14
| | | | | | | | | | | | | | | | | | Alter the file $SQUASH_MSG in place rather than outputting the new message then juggling it around. Change the function name accordingly. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: Extract function do_with_authorMichael Haggerty2010-01-14
| | | | | | | | | | | | | | Call it instead of repeating similar code blocks in several places. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: Handle the author script all in one place in do_nextMichael Haggerty2010-01-14
| | | | | | | | | | | | | | | | This change has no practical effect but makes the code easier to follow. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: Extract a function "commit_message"Michael Haggerty2010-01-14
| | | | | | | | | | | | | | | | ...instead of repeating the same short but slightly obscure blob of code in several places. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: Simplify commit counting for generated commit messagesMichael Haggerty2010-01-14
| | | | | | | | | | | | | | | | | | | | Read the old count from the first line of the old commit message rather than counting the number of commit message blocks in the file. This is simpler, faster, and more robust (e.g., it cannot be confused by strange commit message contents). Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: Improve consistency of commit count in generated commit messagesMichael Haggerty2010-01-14
| | | | | | | | | | | | | | | | | | Use the numeral "2" instead of the word "two" when two commits are being interactively squashed. This makes the treatment consistent with that for higher numbers of commits. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: Introduce a constant AMENDMichael Haggerty2010-01-14
| | | | | | | | | | | | | | | | Add a constant AMEND holding the filename of the $DOTEST/amend file, and document how this temporary file is used. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: Introduce a constant AUTHOR_SCRIPTMichael Haggerty2010-01-14
| | | | | | | | | | | | | | | | | | Add a constant AUTHOR_SCRIPT, holding the filename of the $DOTEST/author_script file, and document how this temporary file is used. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: Document how temporary files are usedMichael Haggerty2010-01-14
| | | | | | | | | | | | | | | | Add documentation, inferred by reverse-engineering, about how git-rebase--interactive.sh uses many of its temporary files. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: Use symbolic constant $MSG consistentlyMichael Haggerty2010-01-14
| | | | | | | | | | | | | | | | The filename constant $MSG was previously used in some places and written out literally in others. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: Use "test -n" instead of "test ! -z"Michael Haggerty2010-01-14
| | | | | | | | | | | | | | It is a tiny bit simpler. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: Inline expressionMichael Haggerty2010-01-14
| | | | | | | | | | | | | | | | Inline expression when generating output rather than overwriting the "sha1" local variable with a short SHA1. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: Remove dead codeMichael Haggerty2010-01-14
| | | | | | | | | | | | | | | | | | This branch of the "if" is only executed if $no_ff is empty, which only happens if $1 was not '-n'. (This code has been dead since 1d25c8cf82eead72e11287d574ef72d3ebec0db1.) Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * rebase -i: Make the condition for an "if" more transparentMichael Haggerty2010-01-14
| | | | | | | | | | | | | | | | Test $no_ff separately rather than testing it indirectly by gluing it onto a comparison of two SHA1s. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Merge branch 'ns/rebase-auto-squash'Junio C Hamano2010-01-20
|\ \ | | | | | | | | | | | | | | | | | | | | | * ns/rebase-auto-squash: rebase -i --autosquash: auto-squash commits Conflicts: git-rebase--interactive.sh
| * | rebase -i --autosquash: auto-squash commitsNanako Shiraishi2010-01-06
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Teach a new option, --autosquash, to the interactive rebase. When the commit log message begins with "!fixup ...", and there is a commit whose title begins with the same ..., automatically modify the todo list of rebase -i so that the commit marked for squashing come right after the commit to be modified, and change the action of the moved commit from pick to squash. Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | Merge branch 'mh/rebase-fixup' (early part)Junio C Hamano2010-01-20
|\ \ \ | | |/ | |/| | | | | | | | | | | | | | | | | | | * 'mh/rebase-fixup' (early part): rebase-i: Ignore comments and blank lines in peek_next_command lib-rebase: Allow comments and blank lines to be added to the rebase script lib-rebase: Provide clearer debugging info about what the editor did Add a command "fixup" to rebase --interactive t3404: Use test_commit to set up test repository
| * | rebase-i: Ignore comments and blank lines in peek_next_commandMichael Haggerty2010-01-12
| |/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, blank lines and/or comments within a series of squash/fixup commands would confuse "git rebase -i" into thinking that the series was finished. It would therefore require the user to edit the commit message for the squash/fixup commits seen so far. Then, after continuing, it would ask the user to edit the commit message again. Ignore comments and blank lines within a group of squash/fixup commands, allowing them to be processed in one go. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * Add a command "fixup" to rebase --interactiveMichael Haggerty2009-12-07
| | | | | | | | | | | | | | | | | | The command is like "squash", except that it discards the commit message of the corresponding commit. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Acked-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Merge branch 'jc/checkout-merge-base'Junio C Hamano2010-01-13
|\ \ | | | | | | | | | | | | | | | | | | | | | * jc/checkout-merge-base: rebase -i: teach --onto A...B syntax rebase: fix --onto A...B parsing and add tests "rebase --onto A...B" replays history on the merge base between A and B "checkout A...B" switches to the merge base between A and B
| * | rebase -i: teach --onto A...B syntaxNanako Shiraishi2010-01-07
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When rewriting commits on a topic branch, sometimes it is easier to compare the version of commits before and after the rewrite if they are based on the same commit that forked from the upstream. An earlier commit by Junio (fixed up by the previous commit) gives "--onto A...B" syntax to rebase command, and rebases on top of the merge base between A and B; teach the same to the interactive version, too. Signed-off-by: しらいし ななこ <nanako3@lavabit.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | rebase--interactive: Ignore comments and blank lines in peek_next_commandMichael Haggerty2010-01-11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, blank lines and/or comments within a series of squash/fixup commands would confuse "git rebase -i" into thinking that the series was finished. It would therefore require the user to edit the commit message for the squash/fixup commits seen so far. Then, after continuing, it would ask the user to edit the commit message again. Ignore comments and blank lines within a group of squash/fixup commands, allowing them to be processed in one go. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | Merge branch 'maint'Junio C Hamano2009-12-19
|\ \ \ | |_|/ |/| | | | | | | | | | | | | | * maint: rebase -i: abort cleanly if the editor fails to launch technical-docs: document hash API api-strbuf.txt: fix typos and document launch_editor()
| * | rebase -i: abort cleanly if the editor fails to launchBjörn Gustavsson2009-12-19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the user's configured editor is emacsclient, the editor will fail to launch if emacs is not running and the git command that tried to lanuch the editor will abort. For most commands, all you have to do is to start emacs and repeat the command. The "git rebase -i" command, however, aborts without cleaning the "$GIT_DIR/rebase-merge" directory if it fails to launch the editor, so you'll need to do "git rebase --abort" before repeating the rebase command. Change "git rebase -i" to terminate using "die_abort" (instead of with "die") if the initial launch of the editor fails. Signed-off-by: Björn Gustavsson <bgustavsson@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * | Merge branch 'rs/work-around-grep-opt-insanity' into maintJunio C Hamano2009-12-03
| |\ \ | | | | | | | | | | | | | | | | | | | | * rs/work-around-grep-opt-insanity: Protect scripted Porcelains from GREP_OPTIONS insanity mergetool--lib: simplify guess_merge_tool()
* | \ \ Merge branch 'rs/work-around-grep-opt-insanity'Junio C Hamano2009-11-25
|\ \ \ \ | | |/ / | |/| | | | | | | | | | | | | | | | | | | | | | | | | | * rs/work-around-grep-opt-insanity: Protect scripted Porcelains from GREP_OPTIONS insanity mergetool--lib: simplify guess_merge_tool() Conflicts: git-instaweb.sh
| * | | Protect scripted Porcelains from GREP_OPTIONS insanityJunio C Hamano2009-11-23
| | |/ | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the user has exported the GREP_OPTIONS environment variable, the output from "grep" and "egrep" in scripted Porcelains may be different from what they expect. For example, we may want to count number of matching lines, by "grep" piped to "wc -l", and GREP_OPTIONS=-C3 will break such use. The approach taken by this change to address this issue is to protect only our own use of grep/egrep. Because we do not unset it at the beginning of our scripts, hook scripts run from the scripted Porcelains are exposed to the same insanity this environment variable causes when grep/egrep is used to implement logic (e.g. "grep | wc -l"), and it is entirely up to the hook scripts to protect themselves. On the other hand, applypatch-msg hook may want to show offending words in the proposed commit log message using grep to the end user, and the user might want to set GREP_OPTIONS=--color to paint the match more visibly. The approach to protect only our own use without unsetting the environment variable globally will allow this use case. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | Merge branch 'fc/doc-fast-forward'Junio C Hamano2009-11-15
|\ \ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | * fc/doc-fast-forward: Use 'fast-forward' all over the place Conflicts: builtin-merge.c
| * | | Use 'fast-forward' all over the placeFelipe Contreras2009-10-24
| |/ / | | | | | | | | | | | | | | | | | | It's a compound word. Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | Merge branch 'maint'Junio C Hamano2009-10-28
|\ \ \ | | |/ | |/| | | | | | | | | | | | | | | | * maint: help -a: do not unnecessarily look for a repository Do not try to remove directories when removing old links rebase -i: more graceful handling of invalid commands help -i: properly error out if no info viewer can be found