From: Nguyễn Thái Ngọc Duy Date: Sun, 17 Mar 2019 12:49:00 GMT Subject: [PATCH v4 00/26] Add new command 'switch' Message-ID: <20190317124926.17137-1-pclouds@gmail.com> In-Reply-To: <20190308095752.8574-1-pclouds@gmail.com> Thanks for all the comments from v3 (and before), I didn't expect feedback from so many people. v4 fixes most of them, but still leaves a couple for v5. - -C remains because people seem to need it - --recreate vs --force-create: there was no strong preference for either, so I stick with --force-create - --guess (dwim mode) is now made default - --orphan by default switches to an empty tree instead of current HEAD (this is Elijah's alternative approach). This allows you to start fresh, but you can still keep "HEAD" content or even switch to another tree. - advice.detachedHead text is updated to suggest a way out (currently it only suggests a way forward with 'checkout -b') - --force has a new alias --discard-changes - the error message when we expect a branch is improved to help point out why the given argument is not a branch - more docs update and reorganization, and other silly bugs I made in v3 The two things I'm aware of but have not done: - the bug in 'git checkout -m' and 'git switch -m' that could lead to loss of staged changes. - better suggestion when dwim fails (e.g. when there are multiple dwim candidates, we could show them all). There have been lots of discussions back and forth. If I miss anything else, please let me know. Nguyễn Thái Ngọc Duy (26): git-checkout.txt: spell out --no-option git-checkout.txt: fix one syntax line doc: document --overwrite-ignore git-checkout.txt: fix monospace typeset t: rename t2014-switch.sh to t2014-checkout-switch.sh checkout: advice how to get out of detached HEAD mode checkout: keep most #include sorted checkout: factor out some code in parse_branchname_arg() checkout: make "opts" in cmd_checkout() a pointer checkout: move 'confict_style' and 'dwim_..' to checkout_opts checkout: split options[] array in three pieces checkout: split part of it to new command 'switch' switch: better names for -b and -B switch: add --discard-changes switch: remove -l switch: stop accepting pathspec switch: reject "do nothing" case switch: only allow explicit detached HEAD switch: add short option for --detach switch: implicit dwim, use --no-guess to disable it switch: no worktree status unless real branch switch happens switch: reject if some operation is in progress switch: --orphan defaults to empty tree as HEAD t: add tests for switch completion: support switch doc: promote "git switch" .gitignore | 1 + Documentation/config/advice.txt | 13 +- Documentation/config/branch.txt | 4 +- Documentation/config/checkout.txt | 17 +- Documentation/config/diff.txt | 3 +- Documentation/git-branch.txt | 12 +- Documentation/git-check-ref-format.txt | 3 +- Documentation/git-checkout.txt | 221 ++++--- Documentation/git-format-patch.txt | 2 +- Documentation/git-merge-base.txt | 2 +- Documentation/git-merge.txt | 5 + Documentation/git-rebase.txt | 2 +- Documentation/git-remote.txt | 2 +- Documentation/git-rerere.txt | 10 +- Documentation/git-reset.txt | 20 +- Documentation/git-stash.txt | 9 +- Documentation/git-switch.txt (new) | 277 ++++++++ Documentation/gitattributes.txt | 3 +- Documentation/gitcore-tutorial.txt | 19 +- Documentation/giteveryday.txt | 24 +- Documentation/githooks.txt | 8 +- Documentation/gittutorial.txt | 4 +- Documentation/gitworkflows.txt | 3 +- Documentation/revisions.txt | 2 +- Documentation/user-manual.txt | 56 +- Makefile | 1 + advice.c | 17 +- builtin.h | 1 + builtin/checkout.c | 597 ++++++++++-------- command-list.txt | 1 + contrib/completion/git-completion.bash | 37 +- git.c | 1 + parse-options-cb.c | 17 + parse-options.h | 1 + sha1-name.c | 2 +- t/t1090-sparse-checkout-scope.sh | 14 - ...014-switch.sh => t2014-checkout-switch.sh} | 0 t/t2020-checkout-detach.sh | 28 +- t/t2060-switch.sh (new +x) | 97 +++ 39 files changed, 1043 insertions(+), 493 deletions(-) create mode 100644 Documentation/git-switch.txt rename t/{t2014-switch.sh => t2014-checkout-switch.sh} (100%) create mode 100755 t/t2060-switch.sh Range-diff dựa trên v3: 1: b0cb2372db ! 1: 535dc1f310 doc: document --overwrite-ignore @@ -22,7 +22,20 @@ + --recurse-submodules:: --no-recurse-submodules:: - Using --recurse-submodules will update the content of all initialized +- Using --recurse-submodules will update the content of all initialized ++ Using `--recurse-submodules` will update the content of all initialized + submodules according to the commit recorded in the superproject. If + local modifications in a submodule would be overwritten the checkout +- will fail unless `-f` is used. If nothing (or --no-recurse-submodules) ++ will fail unless `-f` is used. If nothing (or `--no-recurse-submodules`) + is used, the work trees of submodules will not be updated. +- Just like linkgit:git-submodule[1], this will detach the +- submodules HEAD. ++ Just like linkgit:git-submodule[1], this will detach `HEAD` of the ++ submodule. + + --no-guess:: + Do not attempt to create a branch if a remote tracking branch diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt --- a/Documentation/git-merge.txt 2: 5b165524d1 < -: ---------- git-checkout.txt: fix monospace typeset -: ---------- > 2: b6305d2871 git-checkout.txt: fix monospace typeset 3: a4240a888e = 3: bb56e45457 t: rename t2014-switch.sh to t2014-checkout-switch.sh -: ---------- > 4: 123392757a checkout: advice how to get out of detached HEAD mode -: ---------- > 5: d1ec6b4ce0 checkout: keep most #include sorted 4: dc4a8e8933 = 6: 4b1742672b checkout: factor out some code in parse_branchname_arg() 5: f0d933c2ac = 7: e0bcc3a4dd checkout: make "opts" in cmd_checkout() a pointer 6: 0aa541689c = 8: ca5b4d7db0 checkout: move 'confict_style' and 'dwim_..' to checkout_opts 7: 84ca42bb26 = 9: 13c03997f0 checkout: split options[] array in three pieces 8: e983c8bb2c ! 10: 24d532b276 checkout: split part of it to new command 'switch' @@ -4,9 +4,9 @@ "git checkout" doing too many things is a source of confusion for many users (and it even bites old timers sometimes). To remedy that, the - command will be split into two new ones: switch and - something-to-checkout-paths. The good old "git checkout" command is - still here and will be until all (or most of users) are sick of it. + command will be split into two new ones: switch and restore. The good + old "git checkout" command is still here and will be until all (or most + of users) are sick of it. See the new man page for the final design of switch. The actual implementation though is still pretty much the same as "git checkout" @@ -157,12 +157,13 @@ +updated to match the branch. All new commits will be added to the tip +of this branch. + -+Optionally a new branch could be created with either `-c` or `-C`, or ++Optionally a new branch could be created with either `-c`, `-C`, ++automatically from a remote branch of same name (see `--guess`), or +detach the working tree from any branch with `--detach`, along with +switching. + +Switching branches does not require a clean index and working tree -+(i.e. no differences compared to 'HEAD'). The operation is aborted ++(i.e. no differences compared to `HEAD`). The operation is aborted +however if the switch leads to loss of local changes, unless told +otherwise. + @@ -175,14 +176,19 @@ + Name for the new branch. + +:: -+ The name of a commit at which to switch to before creating a -+ new branch or detach from. ++ The starting point for the new branch. Specifying a ++ `` allows you to create a branch based on some ++ other point in history than where HEAD currently points. (Or, ++ in the case of `--detach`, allows you to inspect and detach ++ from some other point.) ++ -+You can use the `"@{-N}"` syntax to refer to the N-th last ++You can use the `@{-N}` syntax to refer to the N-th last +branch/commit switched to "git switch" or "git checkout" -+operation. You may also specify `-` which is synonymous to `"@{-1}"`. ++operation. You may also specify `-` which is synonymous to `@{-1}`. ++This is often used to switch quickly between two branches, or to undo ++a branch switch by mistake. ++ -+As a special case, you may use `"A...B"` as a shortcut for the merge ++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`. + @@ -214,8 +220,8 @@ + experiments. See the "DETACHED HEAD" section in + linkgit:git-checkout[1] for details. + -+-g:: +--guess:: ++--no-guess:: + If `` is not found but there does exist a tracking + branch in exactly one remote (call it ``) with a + matching name, treat as equivalent to @@ -231,18 +237,45 @@ +to always checkout remote branches from there if `` is +ambiguous but exists on the 'origin' remote. See also +`checkout.defaultRemote` in linkgit:git-config[1]. -+ -+-q:: -+--quiet:: -+ Quiet, suppress feedback messages. +++ ++`--guess` is the default behavior. Use `--no-guess` to disable it. + +-f:: +--force:: ++ An alias for `--discard-changes`. ++ ++--discard-changes:: + Proceed even if the index or the working tree differs from -+ HEAD. Both the index and working tree are restored to match ++ `HEAD`. Both the index and working tree are restored to match + the switching target. This is used to throw away local + changes. + ++-m:: ++--merge:: ++ If you have local modifications to one or more files that are ++ different between the current branch and the branch to which ++ you are switching, the command refuses to switch branches in ++ order to preserve your modifications in context. However, ++ with this option, a three-way merge between the current ++ branch, your working tree contents, and the new branch is ++ done, and you will be on the new branch. +++ ++When a merge conflict happens, the index entries for conflicting ++paths are left unmerged, and you need to resolve the conflicts ++and mark the resolved paths with `git add` (or `git rm` if the merge ++should result in deletion of the path). ++ ++--conflict=