diff options
Diffstat (limited to 'third_party/git/Documentation/git-rebase.txt')
-rw-r--r-- | third_party/git/Documentation/git-rebase.txt | 219 |
1 files changed, 30 insertions, 189 deletions
diff --git a/third_party/git/Documentation/git-rebase.txt b/third_party/git/Documentation/git-rebase.txt index f7a6033607fa..6156609cf714 100644 --- a/third_party/git/Documentation/git-rebase.txt +++ b/third_party/git/Documentation/git-rebase.txt @@ -8,8 +8,8 @@ git-rebase - Reapply commits on top of another base tip SYNOPSIS -------- [verse] -'git rebase' [-i | --interactive] [<options>] [--exec <cmd>] - [--onto <newbase> | --keep-base] [<upstream> [<branch>]] +'git rebase' [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>] + [<upstream> [<branch>]] 'git rebase' [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>] --root [<branch>] 'git rebase' (--continue | --skip | --abort | --quit | --edit-todo | --show-current-patch) @@ -217,24 +217,6 @@ As a special case, you may use "A\...B" as a shortcut for the merge base of A and B if there is exactly one merge base. You can leave out at most one of A and B, in which case it defaults to HEAD. ---keep-base:: - Set the starting point at which to create the new commits to the - merge base of <upstream> <branch>. Running - 'git rebase --keep-base <upstream> <branch>' is equivalent to - running 'git rebase --onto <upstream>... <upstream>'. -+ -This option is useful in the case where one is developing a feature on -top of an upstream branch. While the feature is being worked on, the -upstream branch may advance and it may not be the best idea to keep -rebasing on top of the upstream but to keep the base commit as-is. -+ -Although both this option and --fork-point find the merge base between -<upstream> and <branch>, this option uses the merge base as the _starting -point_ on which new commits will be created, whereas --fork-point uses -the merge base to determine the _set of commits_ which will be rebased. -+ -See also INCOMPATIBLE OPTIONS below. - <upstream>:: Upstream branch to compare against. May be any valid commit, not just an existing branch name. Defaults to the configured @@ -258,45 +240,16 @@ See also INCOMPATIBLE OPTIONS below. original branch. The index and working tree are also left unchanged as a result. ---apply: - Use applying strategies to rebase (calling `git-am` - internally). This option may become a no-op in the future - once the merge backend handles everything the apply one does. -+ -See also INCOMPATIBLE OPTIONS below. - ---empty={drop,keep,ask}:: - How to handle commits that are not empty to start and are not - clean cherry-picks of any upstream commit, but which become - empty after rebasing (because they contain a subset of already - upstream changes). With drop (the default), commits that - become empty are dropped. With keep, such commits are kept. - With ask (implied by --interactive), the rebase will halt when - an empty commit is applied allowing you to choose whether to - drop it, edit files more, or just commit the empty changes. - Other options, like --exec, will use the default of drop unless - -i/--interactive is explicitly specified. -+ -Note that commits which start empty are kept, and commits which are -clean cherry-picks (as determined by `git log --cherry-mark ...`) are -always dropped. -+ -See also INCOMPATIBLE OPTIONS below. - --keep-empty:: - No-op. Rebasing commits that started empty (had no change - relative to their parent) used to fail and this option would - override that behavior, allowing commits with empty changes to - be rebased. Now commits with no changes do not cause rebasing - to halt. + Keep the commits that do not change anything from its + parents in the result. + -See also BEHAVIORAL DIFFERENCES and INCOMPATIBLE OPTIONS below. +See also INCOMPATIBLE OPTIONS below. --allow-empty-message:: - No-op. Rebasing commits with an empty message used to fail - and this option would override that behavior, allowing commits - with empty messages to be rebased. Now commits with an empty - message do not cause rebasing to halt. + By default, rebasing commits with an empty message will fail. + This option overrides that behavior, allowing commits with empty + messages to be rebased. + See also INCOMPATIBLE OPTIONS below. @@ -315,7 +268,7 @@ See also INCOMPATIBLE OPTIONS below. --merge:: Use merging strategies to rebase. When the recursive (default) merge strategy is used, this allows rebase to be aware of renames on the - upstream side. This is the default. + upstream side. + Note that a rebase merge works by replaying each commit from the working branch on top of the <upstream> branch. Because of this, when a merge @@ -385,7 +338,7 @@ See also INCOMPATIBLE OPTIONS below. Ensure at least <n> lines of surrounding context match before and after each change. When fewer lines of surrounding context exist they all must match. By default no context is - ever ignored. Implies --apply. + ever ignored. + See also INCOMPATIBLE OPTIONS below. @@ -416,16 +369,11 @@ ends up being empty, the <upstream> will be used as a fallback. + If either <upstream> or --root is given on the command line, then the default is `--no-fork-point`, otherwise the default is `--fork-point`. -+ -If your branch was based on <upstream> but <upstream> was rewound and -your branch contains commits which were dropped, this option can be used -with `--keep-base` in order to drop those commits from your branch. --ignore-whitespace:: --whitespace=<option>:: - These flags are passed to the 'git apply' program + These flag are passed to the 'git apply' program (see linkgit:git-apply[1]) that applies the patch. - Implies --apply. + See also INCOMPATIBLE OPTIONS below. @@ -473,8 +421,8 @@ the `rebase-cousins` mode is turned on, such commits are instead rebased onto `<upstream>` (or `<onto>`, if specified). + The `--rebase-merges` mode is similar in spirit to the deprecated -`--preserve-merges` but works with interactive rebases, -where commits can be reordered, inserted and dropped at will. +`--preserve-merges`, but in contrast to that option works well in interactive +rebases: commits can be reordered, inserted and dropped at will. + It is currently only possible to recreate the merge commits using the `recursive` merge strategy; Different merge strategies can be used only via @@ -569,11 +517,10 @@ INCOMPATIBLE OPTIONS The following options: - * --apply * --committer-date-is-author-date * --ignore-date - * --ignore-whitespace * --whitespace + * --ignore-whitespace * -C are incompatible with the following options: @@ -588,7 +535,6 @@ are incompatible with the following options: * --interactive * --exec * --keep-empty - * --empty= * --edit-todo * --root when used in combination with --onto @@ -597,137 +543,33 @@ In addition, the following pairs of options are incompatible: * --preserve-merges and --interactive * --preserve-merges and --signoff * --preserve-merges and --rebase-merges - * --preserve-merges and --empty= - * --keep-base and --onto - * --keep-base and --root + * --rebase-merges and --strategy + * --rebase-merges and --strategy-option BEHAVIORAL DIFFERENCES ----------------------- -git rebase has two primary backends: apply and merge. (The apply -backend used to known as the 'am' backend, but the name led to -confusion as it looks like a verb instead of a noun. Also, the merge -backend used to be known as the interactive backend, but it is now -used for non-interactive cases as well. Both were renamed based on -lower-level functionality that underpinned each.) There are some -subtle differences in how these two backends behave: +There are some subtle differences how the backends behave. Empty commits ~~~~~~~~~~~~~ -The apply backend unfortunately drops intentionally empty commits, i.e. -commits that started empty, though these are rare in practice. It -also drops commits that become empty and has no option for controlling -this behavior. +The am backend drops any "empty" commits, regardless of whether the +commit started empty (had no changes relative to its parent to +start with) or ended empty (all changes were already applied +upstream in other commits). -The merge backend keeps intentionally empty commits. Similar to the -apply backend, by default the merge backend drops commits that become -empty unless -i/--interactive is specified (in which case it stops and -asks the user what to do). The merge backend also has an ---empty={drop,keep,ask} option for changing the behavior of handling -commits that become empty. +The interactive backend drops commits by default that +started empty and halts if it hits a commit that ended up empty. +The `--keep-empty` option exists for the interactive backend to allow +it to keep commits that started empty. Directory rename detection ~~~~~~~~~~~~~~~~~~~~~~~~~~ -Due to the lack of accurate tree information (arising from -constructing fake ancestors with the limited information available in -patches), directory rename detection is disabled in the apply backend. -Disabled directory rename detection means that if one side of history -renames a directory and the other adds new files to the old directory, -then the new files will be left behind in the old directory without -any warning at the time of rebasing that you may want to move these -files into the new directory. - -Directory rename detection works with the merge backend to provide you -warnings in such cases. - -Context -~~~~~~~ - -The apply backend works by creating a sequence of patches (by calling -`format-patch` internally), and then applying the patches in sequence -(calling `am` internally). Patches are composed of multiple hunks, -each with line numbers, a context region, and the actual changes. The -line numbers have to be taken with some fuzz, since the other side -will likely have inserted or deleted lines earlier in the file. The -context region is meant to help find how to adjust the line numbers in -order to apply the changes to the right lines. However, if multiple -areas of the code have the same surrounding lines of context, the -wrong one can be picked. There are real-world cases where this has -caused commits to be reapplied incorrectly with no conflicts reported. -Setting diff.context to a larger value may prevent such types of -problems, but increases the chance of spurious conflicts (since it -will require more lines of matching context to apply). - -The merge backend works with a full copy of each relevant file, -insulating it from these types of problems. - -Labelling of conflicts markers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When there are content conflicts, the merge machinery tries to -annotate each side's conflict markers with the commits where the -content came from. Since the apply backend drops the original -information about the rebased commits and their parents (and instead -generates new fake commits based off limited information in the -generated patches), those commits cannot be identified; instead it has -to fall back to a commit summary. Also, when merge.conflictStyle is -set to diff3, the apply backend will use "constructed merge base" to -label the content from the merge base, and thus provide no information -about the merge base commit whatsoever. - -The merge backend works with the full commits on both sides of history -and thus has no such limitations. - -Hooks -~~~~~ - -The apply backend has not traditionally called the post-commit hook, -while the merge backend has. However, this was by accident of -implementation rather than by design. Both backends should have the -same behavior, though it is not clear which one is correct. - -Interruptability -~~~~~~~~~~~~~~~~ - -The apply backend has safety problems with an ill-timed interrupt; if -the user presses Ctrl-C at the wrong time to try to abort the rebase, -the rebase can enter a state where it cannot be aborted with a -subsequent `git rebase --abort`. The merge backend does not appear to -suffer from the same shortcoming. (See -https://lore.kernel.org/git/20200207132152.GC2868@szeder.dev/ for -details.) - -Commit Rewording -~~~~~~~~~~~~~~~~ - -When a conflict occurs while rebasing, rebase stops and asks the user -to resolve. Since the user may need to make notable changes while -resolving conflicts, after conflicts are resolved and the user has run -`git rebase --continue`, the rebase should open an editor and ask the -user to update the commit message. The merge backend does this, while -the apply backend blindly applies the original commit message. - -Miscellaneous differences -~~~~~~~~~~~~~~~~~~~~~~~~~ - -There are a few more behavioral differences that most folks would -probably consider inconsequential but which are mentioned for -completeness: - -* Reflog: The two backends will use different wording when describing - the changes made in the reflog, though both will make use of the - word "rebase". - -* Progress, informational, and error messages: The two backends - provide slightly different progress and informational messages. - Also, the apply backend writes error messages (such as "Your files - would be overwritten...") to stdout, while the merge backend writes - them to stderr. - -* State directories: The two backends keep their state in different - directories under .git/ +Directory rename heuristics are enabled in the merge and interactive +backends. Due to the lack of accurate tree information, directory +rename detection is disabled in the am backend. include::merge-strategies.txt[] @@ -990,8 +832,7 @@ Hard case: The changes are not the same.:: This happens if the 'subsystem' rebase had conflicts, or used `--interactive` to omit, edit, squash, or fixup commits; or if the upstream used one of `commit --amend`, `reset`, or - a full history rewriting command like - https://github.com/newren/git-filter-repo[`filter-repo`]. + `filter-branch`. The easy case @@ -1029,7 +870,7 @@ NOTE: While an "easy case recovery" sometimes appears to be successful --interactive` will be **resurrected**! The idea is to manually tell 'git rebase' "where the old 'subsystem' -ended and your 'topic' began", that is, what the old merge base +ended and your 'topic' began", that is, what the old merge-base between them was. You will have to find a way to name the last commit of the old 'subsystem', for example: |