THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Browse Source

Merge branch 'nd/switch-and-restore'

Two new commands "git switch" and "git restore" are introduced to
split "checking out a branch to work on advancing its history" and
"checking out paths out of the index and/or a tree-ish to work on
advancing the current history" out of the single "git checkout"
command.

* nd/switch-and-restore: (46 commits)
  completion: disable dwim on "git switch -d"
  switch: allow to switch in the middle of bisect
  t2027: use test_must_be_empty
  Declare both git-switch and git-restore experimental
  help: move git-diff and git-reset to different groups
  doc: promote "git restore"
  user-manual.txt: prefer 'merge --abort' over 'reset --hard'
  completion: support restore
  t: add tests for restore
  restore: support --patch
  restore: replace --force with --ignore-unmerged
  restore: default to --source=HEAD when only --staged is specified
  restore: reject invalid combinations with --staged
  restore: add --worktree and --staged
  checkout: factor out worktree checkout code
  restore: disable overlay mode by default
  restore: make pathspec mandatory
  restore: take tree-ish from --source option instead
  checkout: split part of it to new command 'restore'
  doc: promote "git switch"
  ...
tags/v2.23.0-rc0
Junio C Hamano 3 months ago
parent
commit
f496b064fc
65 changed files with 1917 additions and 661 deletions
  1. 2
    0
      .gitignore
  2. 8
    5
      Documentation/config/advice.txt
  3. 2
    2
      Documentation/config/branch.txt
  4. 6
    11
      Documentation/config/checkout.txt
  5. 2
    1
      Documentation/config/diff.txt
  6. 2
    1
      Documentation/config/interactive.txt
  7. 6
    6
      Documentation/git-branch.txt
  8. 2
    1
      Documentation/git-check-ref-format.txt
  9. 122
    100
      Documentation/git-checkout.txt
  10. 1
    1
      Documentation/git-clean.txt
  11. 1
    1
      Documentation/git-commit.txt
  12. 2
    2
      Documentation/git-format-patch.txt
  13. 1
    1
      Documentation/git-merge-base.txt
  14. 5
    0
      Documentation/git-merge.txt
  15. 1
    1
      Documentation/git-rebase.txt
  16. 1
    1
      Documentation/git-remote.txt
  17. 5
    5
      Documentation/git-rerere.txt
  18. 17
    16
      Documentation/git-reset.txt
  19. 185
    0
      Documentation/git-restore.txt
  20. 5
    2
      Documentation/git-revert.txt
  21. 5
    4
      Documentation/git-stash.txt
  22. 273
    0
      Documentation/git-switch.txt
  23. 20
    0
      Documentation/git.txt
  24. 2
    1
      Documentation/gitattributes.txt
  25. 14
    2
      Documentation/gitcli.txt
  26. 9
    10
      Documentation/gitcore-tutorial.txt
  27. 14
    15
      Documentation/giteveryday.txt
  28. 5
    3
      Documentation/githooks.txt
  29. 2
    2
      Documentation/gittutorial-2.txt
  30. 3
    3
      Documentation/gittutorial.txt
  31. 1
    2
      Documentation/gitworkflows.txt
  32. 1
    1
      Documentation/revisions.txt
  33. 34
    36
      Documentation/user-manual.txt
  34. 2
    0
      Makefile
  35. 13
    4
      advice.c
  36. 2
    2
      branch.c
  37. 1
    1
      branch.h
  38. 2
    0
      builtin.h
  39. 1
    1
      builtin/am.c
  40. 584
    320
      builtin/checkout.c
  41. 1
    1
      builtin/clone.c
  42. 2
    2
      builtin/commit.c
  43. 2
    2
      builtin/rebase.c
  44. 1
    1
      builtin/reset.c
  45. 1
    1
      builtin/revert.c
  46. 5
    3
      command-list.txt
  47. 55
    1
      contrib/completion/git-completion.bash
  48. 52
    0
      git-add--interactive.perl
  49. 2
    0
      git.c
  50. 17
    0
      parse-options-cb.c
  51. 1
    0
      parse-options.h
  52. 5
    3
      sequencer.c
  53. 1
    1
      sequencer.h
  54. 1
    1
      sha1-name.c
  55. 12
    0
      t/lib-patch-mode.sh
  56. 0
    14
      t/t1090-sparse-checkout-scope.sh
  57. 0
    0
      t/t2014-checkout-switch.sh
  58. 20
    8
      t/t2020-checkout-detach.sh
  59. 96
    0
      t/t2060-switch.sh
  60. 98
    0
      t/t2070-restore.sh
  61. 110
    0
      t/t2071-restore-patch.sh
  62. 41
    41
      t/t7508-status.sh
  63. 10
    10
      t/t7512-status-help.sh
  64. 1
    1
      unpack-trees.c
  65. 19
    7
      wt-status.c

+ 2
- 0
.gitignore View File

@@ -139,6 +139,7 @@
/git-request-pull
/git-rerere
/git-reset
/git-restore
/git-rev-list
/git-rev-parse
/git-revert
@@ -163,6 +164,7 @@
/git-submodule
/git-submodule--helper
/git-svn
/git-switch
/git-symbolic-ref
/git-tag
/git-unpack-file

+ 8
- 5
Documentation/config/advice.txt View File

@@ -42,7 +42,8 @@ advice.*::
state in the output of linkgit:git-status[1], in
the template shown when writing commit messages in
linkgit:git-commit[1], and in the help message shown
by linkgit:git-checkout[1] when switching branch.
by linkgit:git-switch[1] or
linkgit:git-checkout[1] when switching branch.
statusUoption::
Advise to consider using the `-u` option to linkgit:git-status[1]
when the command takes more than 2 seconds to enumerate untracked
@@ -62,12 +63,14 @@ advice.*::
your information is guessed from the system username and
domain name.
detachedHead::
Advice shown when you used linkgit:git-checkout[1] to
move to the detach HEAD state, to instruct how to create
a local branch after the fact.
Advice shown when you used
linkgit:git-switch[1] or linkgit:git-checkout[1]
to move to the detach HEAD state, to instruct how to
create a local branch after the fact.
checkoutAmbiguousRemoteBranchName::
Advice shown when the argument to
linkgit:git-checkout[1] ambiguously resolves to a
linkgit:git-checkout[1] and linkgit:git-switch[1]
ambiguously resolves to a
remote tracking branch on more than one remote in
situations where an unambiguous argument would have
otherwise caused a remote-tracking branch to be

+ 2
- 2
Documentation/config/branch.txt View File

@@ -1,5 +1,5 @@
branch.autoSetupMerge::
Tells 'git branch' and 'git checkout' to set up new branches
Tells 'git branch', 'git switch' and 'git checkout' to set up new branches
so that linkgit:git-pull[1] will appropriately merge from the
starting point branch. Note that even if this option is not set,
this behavior can be chosen per-branch using the `--track`
@@ -11,7 +11,7 @@ branch.autoSetupMerge::
branch. This option defaults to true.

branch.autoSetupRebase::
When a new branch is created with 'git branch' or 'git checkout'
When a new branch is created with 'git branch', 'git switch' or 'git checkout'
that tracks another branch, this variable tells Git to set
up pull to rebase instead of merge (see "branch.<name>.rebase").
When `never`, rebase is never automatically set to true.

+ 6
- 11
Documentation/config/checkout.txt View File

@@ -1,5 +1,6 @@
checkout.defaultRemote::
When you run 'git checkout <something>' and only have one
When you run 'git checkout <something>'
or 'git switch <something>' and only have one
remote, it may implicitly fall back on checking out and
tracking e.g. 'origin/<something>'. This stops working as soon
as you have more than one remote with a '<something>'
@@ -8,16 +9,10 @@ checkout.defaultRemote::
disambiguation. The typical use-case is to set this to
`origin`.
+
Currently this is used by linkgit:git-checkout[1] when 'git checkout
<something>' will checkout the '<something>' branch on another remote,
Currently this is used by linkgit:git-switch[1] and
linkgit:git-checkout[1] when 'git checkout <something>'
or 'git switch <something>'
will checkout the '<something>' branch on another remote,
and by linkgit:git-worktree[1] when 'git worktree add' refers to a
remote branch. This setting might be used for other checkout-like
commands or functionality in the future.

checkout.optimizeNewBranch::
Optimizes the performance of "git checkout -b <new_branch>" when
using sparse-checkout. When set to true, git will not update the
repo based on the current sparse-checkout settings. This means it
will not update the skip-worktree bit in the index nor add/remove
files in the working directory to reflect the current sparse checkout
settings nor will it show the local changes.

+ 2
- 1
Documentation/config/diff.txt View File

@@ -78,7 +78,8 @@ diff.external::
diff.ignoreSubmodules::
Sets the default value of --ignore-submodules. Note that this
affects only 'git diff' Porcelain, and not lower level 'diff'
commands such as 'git diff-files'. 'git checkout' also honors
commands such as 'git diff-files'. 'git checkout'
and 'git switch' also honor
this setting when reporting uncommitted changes. Setting it to
'all' disables the submodule summary normally shown by 'git commit'
and 'git status' when `status.submoduleSummary` is set unless it is

+ 2
- 1
Documentation/config/interactive.txt View File

@@ -2,7 +2,8 @@ interactive.singleKey::
In interactive commands, allow the user to provide one-letter
input with a single key (i.e., without hitting enter).
Currently this is used by the `--patch` mode of
linkgit:git-add[1], linkgit:git-checkout[1], linkgit:git-commit[1],
linkgit:git-add[1], linkgit:git-checkout[1],
linkgit:git-restore[1], linkgit:git-commit[1],
linkgit:git-reset[1], and linkgit:git-stash[1]. Note that this
setting is silently ignored if portable keystroke input
is not available; requires the Perl module Term::ReadKey.

+ 6
- 6
Documentation/git-branch.txt View File

@@ -60,7 +60,7 @@ can leave out at most one of `A` and `B`, in which case it defaults to
`HEAD`.

Note that this will create the new branch, but it will not switch the
working tree to it; use "git checkout <newbranch>" to switch to the
working tree to it; use "git switch <newbranch>" to switch to the
new branch.

When a local branch is started off a remote-tracking branch, Git sets up the
@@ -214,7 +214,7 @@ This option is only applicable in non-verbose mode.
+
This behavior is the default when the start point is a remote-tracking branch.
Set the branch.autoSetupMerge configuration variable to `false` if you
want `git checkout` and `git branch` to always behave as if `--no-track`
want `git switch`, `git checkout` and `git branch` to always behave as if `--no-track`
were given. Set it to `always` if you want this behavior when the
start-point is either a local or remote-tracking branch.

@@ -313,7 +313,7 @@ Start development from a known tag::
$ git clone git://git.kernel.org/pub/scm/.../linux-2.6 my2.6
$ cd my2.6
$ git branch my2.6.14 v2.6.14 <1>
$ git checkout my2.6.14
$ git switch my2.6.14
------------
+
<1> This step and the next one could be combined into a single step with
@@ -350,9 +350,9 @@ Patterns will normally need quoting.
NOTES
-----

If you are creating a branch that you want to checkout immediately, it is
easier to use the git checkout command with its `-b` option to create
a branch and check it out with a single command.
If you are creating a branch that you want to switch to immediately,
it is easier to use the "git switch" command with its `-c` option to
do the same thing with a single command.

The options `--contains`, `--no-contains`, `--merged` and `--no-merged`
serve four related but different purposes:

+ 2
- 1
Documentation/git-check-ref-format.txt View File

@@ -88,7 +88,8 @@ but it is explicitly forbidden at the beginning of a branch name).
When run with `--branch` option in a repository, the input is first
expanded for the ``previous checkout syntax''
`@{-n}`. For example, `@{-1}` is a way to refer the last thing that
was checked out using "git checkout" operation. This option should be
was checked out using "git switch" or "git checkout" operation.
This option should be
used by porcelains to accept this syntax anywhere a branch name is
expected, so they can act as if you typed the branch name. As an
exception note that, the ``previous checkout operation'' might result

+ 122
- 100
Documentation/git-checkout.txt View File

@@ -23,31 +23,22 @@ or the specified tree. If no paths are given, 'git checkout' will
also update `HEAD` to set the specified branch as the current
branch.

'git checkout' <branch>::
To prepare for working on <branch>, switch to it by updating
'git checkout' [<branch>]::
To prepare for working on `<branch>`, switch to it by updating
the index and the files in the working tree, and by pointing
HEAD at the branch. Local modifications to the files in the
`HEAD` at the branch. Local modifications to the files in the
working tree are kept, so that they can be committed to the
<branch>.
`<branch>`.
+
If <branch> is not found but there does exist a tracking branch in
exactly one remote (call it <remote>) with a matching name, treat as
equivalent to
If `<branch>` is not found but there does exist a tracking branch in
exactly one remote (call it `<remote>`) with a matching name and
`--no-guess` is not specified, treat as equivalent to
+
------------
$ git checkout -b <branch> --track <remote>/<branch>
------------
+
If the branch exists in multiple remotes and one of them is named by
the `checkout.defaultRemote` configuration variable, we'll use that
one for the purposes of disambiguation, even if the `<branch>` isn't
unique across all remotes. Set it to
e.g. `checkout.defaultRemote=origin` to always checkout remote
branches from there if `<branch>` is ambiguous but exists on the
'origin' remote. See also `checkout.defaultRemote` in
linkgit:git-config[1].
+
You could omit <branch>, in which case the command degenerates to
You could omit `<branch>`, in which case the command degenerates to
"check out the current branch", which is a glorified no-op with
rather expensive side-effects to show only the tracking information,
if exists, for the current branch.
@@ -61,7 +52,7 @@ if exists, for the current branch.
`--track` without `-b` implies branch creation; see the
description of `--track` below.
+
If `-B` is given, <new_branch> is created if it doesn't exist; otherwise, it
If `-B` is given, `<new_branch>` is created if it doesn't exist; otherwise, it
is reset. This is the transactional equivalent of
+
------------
@@ -75,25 +66,25 @@ successful.
'git checkout' --detach [<branch>]::
'git checkout' [--detach] <commit>::

Prepare to work on top of <commit>, by detaching HEAD at it
Prepare to work on top of `<commit>`, by detaching `HEAD` at it
(see "DETACHED HEAD" section), and updating the index and the
files in the working tree. Local modifications to the files
in the working tree are kept, so that the resulting working
tree will be the state recorded in the commit plus the local
modifications.
+
When the <commit> argument is a branch name, the `--detach` option can
be used to detach HEAD at the tip of the branch (`git checkout
<branch>` would check out that branch without detaching HEAD).
When the `<commit>` argument is a branch name, the `--detach` option can
be used to detach `HEAD` at the tip of the branch (`git checkout
<branch>` would check out that branch without detaching `HEAD`).
+
Omitting <branch> detaches HEAD at the tip of the current branch.
Omitting `<branch>` detaches `HEAD` at the tip of the current branch.

'git checkout' [<tree-ish>] [--] <pathspec>...::

Overwrite paths in the working tree by replacing with the
contents in the index or in the <tree-ish> (most often a
commit). When a <tree-ish> is given, the paths that
match the <pathspec> are updated both in the index and in
contents in the index or in the `<tree-ish>` (most often a
commit). When a `<tree-ish>` is given, the paths that
match the `<pathspec>` are updated both in the index and in
the working tree.
+
The index may contain unmerged entries because of a previous failed merge.
@@ -118,7 +109,8 @@ OPTIONS
--quiet::
Quiet, suppress feedback messages.

--[no-]progress::
--progress::
--no-progress::
Progress status is reported on the standard error stream
by default when it is attached to a terminal, unless `--quiet`
is specified. This flag enables progress reporting even if not
@@ -127,7 +119,7 @@ OPTIONS
-f::
--force::
When switching branches, proceed even if the index or the
working tree differs from HEAD. This is used to throw away
working tree differs from `HEAD`. This is used to throw away
local changes.
+
When checking out paths from the index, do not fail upon unmerged
@@ -154,12 +146,12 @@ on your side branch as `theirs` (i.e. "one contributor's work on top
of it").

-b <new_branch>::
Create a new branch named <new_branch> and start it at
<start_point>; see linkgit:git-branch[1] for details.
Create a new branch named `<new_branch>` and start it at
`<start_point>`; see linkgit:git-branch[1] for details.

-B <new_branch>::
Creates the branch <new_branch> and start it at <start_point>;
if it already exists, then reset it to <start_point>. This is
Creates the branch `<new_branch>` and start it at `<start_point>`;
if it already exists, then reset it to `<start_point>`. This is
equivalent to running "git branch" with "-f"; see
linkgit:git-branch[1] for details.

@@ -172,15 +164,36 @@ If no `-b` option is given, the name of the new branch will be
derived from the remote-tracking branch, by looking at the local part of
the refspec configured for the corresponding remote, and then stripping
the initial part up to the "*".
This would tell us to use "hack" as the local branch when branching
off of "origin/hack" (or "remotes/origin/hack", or even
"refs/remotes/origin/hack"). If the given name has no slash, or the above
This would tell us to use `hack` as the local branch when branching
off of `origin/hack` (or `remotes/origin/hack`, or even
`refs/remotes/origin/hack`). If the given name has no slash, or the above
guessing results in an empty name, the guessing is aborted. You can
explicitly give a name with `-b` in such a case.

--no-track::
Do not set up "upstream" configuration, even if the
branch.autoSetupMerge configuration variable is true.
`branch.autoSetupMerge` configuration variable is true.

--guess::
--no-guess::
If `<branch>` is not found but there does exist a tracking
branch in exactly one remote (call it `<remote>`) with a
matching name, treat as equivalent to
+
------------
$ git checkout -b <branch> --track <remote>/<branch>
------------
+
If the branch exists in multiple remotes and one of them is named by
the `checkout.defaultRemote` configuration variable, we'll use that
one for the purposes of disambiguation, even if the `<branch>` isn't
unique across all remotes. Set it to
e.g. `checkout.defaultRemote=origin` to always checkout remote
branches from there if `<branch>` is ambiguous but exists on the
'origin' remote. See also `checkout.defaultRemote` in
linkgit:git-config[1].
+
Use `--no-guess` to disable this.

-l::
Create the new branch's reflog; see linkgit:git-branch[1] for
@@ -189,21 +202,21 @@ explicitly give a name with `-b` in such a case.
--detach::
Rather than checking out a branch to work on it, check out a
commit for inspection and discardable experiments.
This is the default behavior of "git checkout <commit>" when
<commit> is not a branch name. See the "DETACHED HEAD" section
This is the default behavior of `git checkout <commit>` when
`<commit>` is not a branch name. See the "DETACHED HEAD" section
below for details.

--orphan <new_branch>::
Create a new 'orphan' branch, named <new_branch>, started from
<start_point> and switch to it. The first commit made on this
Create a new 'orphan' branch, named `<new_branch>`, started from
`<start_point>` and switch to it. The first commit made on this
new branch will have no parents and it will be the root of a new
history totally disconnected from all the other branches and
commits.
+
The index and the working tree are adjusted as if you had previously run
"git checkout <start_point>". This allows you to start a new history
that records a set of paths similar to <start_point> by easily running
"git commit -a" to make the root commit.
`git checkout <start_point>`. This allows you to start a new history
that records a set of paths similar to `<start_point>` by easily running
`git commit -a` to make the root commit.
+
This can be useful when you want to publish the tree from a commit
without exposing its full history. You might want to do this to publish
@@ -212,17 +225,17 @@ whose full history contains proprietary or otherwise encumbered bits of
code.
+
If you want to start a disconnected history that records a set of paths
that is totally different from the one of <start_point>, then you should
that is totally different from the one of `<start_point>`, then you should
clear the index and the working tree right after creating the orphan
branch by running "git rm -rf ." from the top level of the working tree.
branch by running `git rm -rf .` from the top level of the working tree.
Afterwards you will be ready to prepare your new files, repopulating the
working tree, by copying them from elsewhere, extracting a tarball, etc.

--ignore-skip-worktree-bits::
In sparse checkout mode, `git checkout -- <paths>` would
update only entries matched by <paths> and sparse patterns
in $GIT_DIR/info/sparse-checkout. This option ignores
the sparse patterns and adds back any files in <paths>.
update only entries matched by `<paths>` and sparse patterns
in `$GIT_DIR/info/sparse-checkout`. This option ignores
the sparse patterns and adds back any files in `<paths>`.

-m::
--merge::
@@ -246,25 +259,25 @@ the conflicted merge in the specified paths.
When switching branches with `--merge`, staged changes may be lost.

--conflict=<style>::
The same as --merge option above, but changes the way the
The same as `--merge` option above, but changes the way the
conflicting hunks are presented, overriding the
merge.conflictStyle configuration variable. Possible values are
`merge.conflictStyle` configuration variable. Possible values are
"merge" (default) and "diff3" (in addition to what is shown by
"merge" style, shows the original contents).

-p::
--patch::
Interactively select hunks in the difference between the
<tree-ish> (or the index, if unspecified) and the working
`<tree-ish>` (or the index, if unspecified) and the working
tree. The chosen hunks are then applied in reverse to the
working tree (and if a <tree-ish> was specified, the index).
working tree (and if a `<tree-ish>` was specified, the index).
+
This means that you can use `git checkout -p` to selectively discard
edits from your current working tree. See the ``Interactive Mode''
section of linkgit:git-add[1] to learn how to operate the `--patch` mode.
+
Note that this option uses the no overlay mode by default (see also
`--[no-]overlay`), and currently doesn't support overlay mode.
`--overlay`), and currently doesn't support overlay mode.

--ignore-other-worktrees::
`git checkout` refuses when the wanted ref is already checked
@@ -272,38 +285,42 @@ Note that this option uses the no overlay mode by default (see also
out anyway. In other words, the ref can be held by more than one
worktree.

--[no-]recurse-submodules::
Using --recurse-submodules will update the content of all initialized
--overwrite-ignore::
--no-overwrite-ignore::
Silently overwrite ignored files when switching branches. This
is the default behavior. Use `--no-overwrite-ignore` to abort
the operation when the new branch contains ignored files.

--recurse-submodules::
--no-recurse-submodules::
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.

--no-guess::
Do not attempt to create a branch if a remote tracking branch
of the same name exists.
Just like linkgit:git-submodule[1], this will detach `HEAD` of the
submodule.

--[no-]overlay::
--overlay::
--no-overlay::
In the default overlay mode, `git checkout` never
removes files from the index or the working tree. When
specifying `--no-overlay`, files that appear in the index and
working tree, but not in <tree-ish> are removed, to make them
match <tree-ish> exactly.
working tree, but not in `<tree-ish>` are removed, to make them
match `<tree-ish>` exactly.

<branch>::
Branch to checkout; if it refers to a branch (i.e., a name that,
when prepended with "refs/heads/", is a valid ref), then that
branch is checked out. Otherwise, if it refers to a valid
commit, your HEAD becomes "detached" and you are no longer on
commit, your `HEAD` becomes "detached" and you are no longer on
any branch (see below for details).
+
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 checked out using "git checkout" operation. You may
also specify `-` which is synonymous to `"@{-1}"`.
also specify `-` which is synonymous to `@{-1}`.
+
As a special case, you may use `"A...B"` as a shortcut for the
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`.

@@ -312,7 +329,7 @@ leave out at most one of `A` and `B`, in which case it defaults to `HEAD`.

<start_point>::
The name of a commit at which to start the new branch; see
linkgit:git-branch[1] for details. Defaults to HEAD.
linkgit:git-branch[1] for details. Defaults to `HEAD`.
+
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
@@ -326,9 +343,9 @@ leave out at most one of `A` and `B`, in which case it defaults to `HEAD`.

DETACHED HEAD
-------------
HEAD normally refers to a named branch (e.g. 'master'). Meanwhile, each
`HEAD` normally refers to a named branch (e.g. `master`). Meanwhile, each
branch refers to a specific commit. Let's look at a repo with three
commits, one of them tagged, and with branch 'master' checked out:
commits, one of them tagged, and with branch `master` checked out:

------------
HEAD (refers to branch 'master')
@@ -341,10 +358,10 @@ a---b---c branch 'master' (refers to commit 'c')
------------

When a commit is created in this state, the branch is updated to refer to
the new commit. Specifically, 'git commit' creates a new commit 'd', whose
parent is commit 'c', and then updates branch 'master' to refer to new
commit 'd'. HEAD still refers to branch 'master' and so indirectly now refers
to commit 'd':
the new commit. Specifically, 'git commit' creates a new commit `d`, whose
parent is commit `c`, and then updates branch `master` to refer to new
commit `d`. `HEAD` still refers to branch `master` and so indirectly now refers
to commit `d`:

------------
$ edit; git add; git commit
@@ -361,7 +378,7 @@ a---b---c---d branch 'master' (refers to commit 'd')
It is sometimes useful to be able to checkout a commit that is not at
the tip of any named branch, or even to create a new commit that is not
referenced by a named branch. Let's look at what happens when we
checkout commit 'b' (here we show two ways this may be done):
checkout commit `b` (here we show two ways this may be done):

------------
$ git checkout v2.0 # or
@@ -376,9 +393,9 @@ a---b---c---d branch 'master' (refers to commit 'd')
tag 'v2.0' (refers to commit 'b')
------------

Notice that regardless of which checkout command we use, HEAD now refers
directly to commit 'b'. This is known as being in detached HEAD state.
It means simply that HEAD refers to a specific commit, as opposed to
Notice that regardless of which checkout command we use, `HEAD` now refers
directly to commit `b`. This is known as being in detached `HEAD` state.
It means simply that `HEAD` refers to a specific commit, as opposed to
referring to a named branch. Let's see what happens when we create a commit:

------------
@@ -395,7 +412,7 @@ a---b---c---d branch 'master' (refers to commit 'd')
tag 'v2.0' (refers to commit 'b')
------------

There is now a new commit 'e', but it is referenced only by HEAD. We can
There is now a new commit `e`, but it is referenced only by `HEAD`. We can
of course add yet another commit in this state:

------------
@@ -413,7 +430,7 @@ a---b---c---d branch 'master' (refers to commit 'd')
------------

In fact, we can perform all the normal Git operations. But, let's look
at what happens when we then checkout master:
at what happens when we then checkout `master`:

------------
$ git checkout master
@@ -428,9 +445,9 @@ a---b---c---d branch 'master' (refers to commit 'd')
------------

It is important to realize that at this point nothing refers to commit
'f'. Eventually commit 'f' (and by extension commit 'e') will be deleted
`f`. Eventually commit `f` (and by extension commit `e`) will be deleted
by the routine Git garbage collection process, unless we create a reference
before that happens. If we have not yet moved away from commit 'f',
before that happens. If we have not yet moved away from commit `f`,
any of these will create a reference to it:

------------
@@ -439,19 +456,19 @@ $ git branch foo <2>
$ git tag foo <3>
------------

<1> creates a new branch 'foo', which refers to commit 'f', and then
updates HEAD to refer to branch 'foo'. In other words, we'll no longer
be in detached HEAD state after this command.
<1> creates a new branch `foo`, which refers to commit `f`, and then
updates `HEAD` to refer to branch `foo`. In other words, we'll no longer
be in detached `HEAD` state after this command.

<2> similarly creates a new branch 'foo', which refers to commit 'f',
but leaves HEAD detached.
<2> similarly creates a new branch `foo`, which refers to commit `f`,
but leaves `HEAD` detached.

<3> creates a new tag 'foo', which refers to commit 'f',
leaving HEAD detached.
<3> creates a new tag `foo`, which refers to commit `f`,
leaving `HEAD` detached.

If we have moved away from commit 'f', then we must first recover its object
If we have moved away from commit `f`, then we must first recover its object
name (typically by using git reflog), and then we can create a reference to
it. For example, to see the last two commits to which HEAD referred, we
it. For example, to see the last two commits to which `HEAD` referred, we
can use either of these commands:

------------
@@ -462,12 +479,12 @@ $ git log -g -2 HEAD
ARGUMENT DISAMBIGUATION
-----------------------

When there is only one argument given and it is not `--` (e.g. "git
checkout abc"), and when the argument is both a valid `<tree-ish>`
(e.g. a branch "abc" exists) and a valid `<pathspec>` (e.g. a file
When there is only one argument given and it is not `--` (e.g. `git
checkout abc`), and when the argument is both a valid `<tree-ish>`
(e.g. a branch `abc` exists) and a valid `<pathspec>` (e.g. a file
or a directory whose name is "abc" exists), Git would usually ask
you to disambiguate. Because checking out a branch is so common an
operation, however, "git checkout abc" takes "abc" as a `<tree-ish>`
operation, however, `git checkout abc` takes "abc" as a `<tree-ish>`
in such a situation. Use `git checkout -- <pathspec>` if you want
to checkout these paths out of the index.

@@ -475,7 +492,7 @@ EXAMPLES
--------

. The following sequence checks out the `master` branch, reverts
the `Makefile` to two revisions back, deletes hello.c by
the `Makefile` to two revisions back, deletes `hello.c` by
mistake, and gets it back from the index.
+
------------
@@ -487,7 +504,7 @@ $ git checkout hello.c <3>
+
<1> switch branch
<2> take a file out of another commit
<3> restore hello.c from the index
<3> restore `hello.c` from the index
+
If you want to check out _all_ C source files out of the index,
you can say
@@ -516,7 +533,7 @@ $ git checkout -- hello.c
$ git checkout mytopic
------------
+
However, your "wrong" branch and correct "mytopic" branch may
However, your "wrong" branch and correct `mytopic` branch may
differ in files that you have modified locally, in which case
the above checkout would fail like this:
+
@@ -557,6 +574,11 @@ $ edit frotz
$ git add frotz
------------

SEE ALSO
--------
linkgit:git-switch[1],
linkgit:git-restore[1]

GIT
---
Part of the linkgit:git[1] suite

+ 1
- 1
Documentation/git-clean.txt View File

@@ -63,7 +63,7 @@ OPTIONS
still use the ignore rules given with `-e` options from the command
line. This allows removing all untracked
files, including build products. This can be used (possibly in
conjunction with 'git reset') to create a pristine
conjunction with 'git restore' or 'git reset') to create a pristine
working directory to test a clean build.

-X::

+ 1
- 1
Documentation/git-commit.txt View File

@@ -359,7 +359,7 @@ When recording your own work, the contents of modified files in
your working tree are temporarily stored to a staging area
called the "index" with 'git add'. A file can be
reverted back, only in the index but not in the working tree,
to that of the last commit with `git reset HEAD -- <file>`,
to that of the last commit with `git restore --staged <file>`,
which effectively reverts 'git add' and prevents the changes to
this file from participating in the next commit. After building
the state to be committed incrementally with these commands,

+ 2
- 2
Documentation/git-format-patch.txt View File

@@ -426,8 +426,8 @@ One way to test if your MUA is set up correctly is:
* Apply it:

$ git fetch <project> master:test-apply
$ git checkout test-apply
$ git reset --hard
$ git switch test-apply
$ git restore --source=HEAD --staged --worktree :/
$ git am a.patch

If it does not apply correctly, there can be various reasons.

+ 1
- 1
Documentation/git-merge-base.txt View File

@@ -149,7 +149,7 @@ instead.
Discussion on fork-point mode
-----------------------------

After working on the `topic` branch created with `git checkout -b
After working on the `topic` branch created with `git switch -c
topic origin/master`, the history of remote-tracking branch
`origin/master` may have been rewound and rebuilt, leading to a
history of this shape:

+ 5
- 0
Documentation/git-merge.txt View File

@@ -87,6 +87,11 @@ will be appended to the specified message.
Allow the rerere mechanism to update the index with the
result of auto-conflict resolution if possible.

--overwrite-ignore::
--no-overwrite-ignore::
Silently overwrite ignored files from the merge result. This
is the default behavior. Use `--no-overwrite-ignore` to abort.

--abort::
Abort the current conflict resolution process, and
try to reconstruct the pre-merge state.

+ 1
- 1
Documentation/git-rebase.txt View File

@@ -17,7 +17,7 @@ SYNOPSIS
DESCRIPTION
-----------
If <branch> is specified, 'git rebase' will perform an automatic
`git checkout <branch>` before doing anything else. Otherwise
`git switch <branch>` before doing anything else. Otherwise
it remains on the current branch.

If <upstream> is not specified, the upstream configured in

+ 1
- 1
Documentation/git-remote.txt View File

@@ -230,7 +230,7 @@ $ git branch -r
staging/master
staging/staging-linus
staging/staging-next
$ git checkout -b staging staging/master
$ git switch -c staging staging/master
...
------------


+ 5
- 5
Documentation/git-rerere.txt View File

@@ -91,7 +91,7 @@ For such a test, you need to merge master and topic somehow.
One way to do it is to pull master into the topic branch:

------------
$ git checkout topic
$ git switch topic
$ git merge master

o---*---o---+ topic
@@ -113,10 +113,10 @@ the upstream might have been advanced since the test merge `+`,
in which case the final commit graph would look like this:

------------
$ git checkout topic
$ git switch topic
$ git merge master
$ ... work on both topic and master branches
$ git checkout master
$ git switch master
$ git merge topic

o---*---o---+---o---o topic
@@ -136,11 +136,11 @@ merges, you could blow away the test merge, and keep building on
top of the tip before the test merge:

------------
$ git checkout topic
$ git switch topic
$ git merge master
$ git reset --hard HEAD^ ;# rewind the test merge
$ ... work on both topic and master branches
$ git checkout master
$ git switch master
$ git merge topic

o---*---o-------o---o topic

+ 17
- 16
Documentation/git-reset.txt View File

@@ -25,12 +25,13 @@ The `<tree-ish>`/`<commit>` defaults to `HEAD` in all forms.
the current branch.)
+
This means that `git reset <paths>` is the opposite of `git add
<paths>`.
<paths>`. This command is equivalent to
`git restore [--source=<tree-ish>] --staged <paths>...`.
+
After running `git reset <paths>` to update the index entry, you can
use linkgit:git-checkout[1] to check the contents out of the index to
the working tree.
Alternatively, using linkgit:git-checkout[1] and specifying a commit, you
use linkgit:git-restore[1] to check the contents out of the index to
the working tree. Alternatively, using linkgit:git-restore[1]
and specifying a commit with `--source`, you
can copy the contents of a path out of a commit to the index and to the
working tree in one go.

@@ -86,8 +87,8 @@ but carries forward unmerged index entries.
changes, reset is aborted.
--

If you want to undo a commit other than the latest on a branch,
linkgit:git-revert[1] is your friend.
See "Reset, restore and revert" in linkgit:git[1] for the differences
between the three commands.


OPTIONS
@@ -149,9 +150,9 @@ See also the `--amend` option to linkgit:git-commit[1].
Undo a commit, making it a topic branch::
+
------------
$ git branch topic/wip <1>
$ git reset --hard HEAD~3 <2>
$ git checkout topic/wip <3>
$ git branch topic/wip <1>
$ git reset --hard HEAD~3 <2>
$ git switch topic/wip <3>
------------
+
<1> You have made some commits, but realize they were premature
@@ -232,13 +233,13 @@ working tree are not in any shape to be committed yet, but you
need to get to the other branch for a quick bugfix.
+
------------
$ git checkout feature ;# you were working in "feature" branch and
$ work work work ;# got interrupted
$ git switch feature ;# you were working in "feature" branch and
$ work work work ;# got interrupted
$ git commit -a -m "snapshot WIP" <1>
$ git checkout master
$ git switch master
$ fix fix fix
$ git commit ;# commit with real log
$ git checkout feature
$ git switch feature
$ git reset --soft HEAD^ ;# go back to WIP state <2>
$ git reset <3>
------------
@@ -279,18 +280,18 @@ reset it while keeping the changes in your working tree.
+
------------
$ git tag start
$ git checkout -b branch1
$ git switch -c branch1
$ edit
$ git commit ... <1>
$ edit
$ git checkout -b branch2 <2>
$ git switch -c branch2 <2>
$ git reset --keep start <3>
------------
+
<1> This commits your first edits in `branch1`.
<2> In the ideal world, you could have realized that the earlier
commit did not belong to the new topic when you created and switched
to `branch2` (i.e. `git checkout -b branch2 start`), but nobody is
to `branch2` (i.e. `git switch -c branch2 start`), but nobody is
perfect.
<3> But you can use `reset --keep` to remove the unwanted commit after
you switched to `branch2`.

+ 185
- 0
Documentation/git-restore.txt View File

@@ -0,0 +1,185 @@
git-restore(1)
==============

NAME
----
git-restore - Restore working tree files

SYNOPSIS
--------
[verse]
'git restore' [<options>] [--source=<tree>] [--staged] [--worktree] <pathspec>...
'git restore' (-p|--patch) [<options>] [--source=<tree>] [--staged] [--worktree] [<pathspec>...]

DESCRIPTION
-----------
Restore specified paths in the working tree with some contents from a
restore source. If a path is tracked but does not exist in the restore
source, it will be removed to match the source.

The command can also be used to restore the content in the index with
`--staged`, or restore both the working tree and the index with
`--staged --worktree`.

By default, the restore sources for working tree and the index are the
index and `HEAD` respectively. `--source` could be used to specify a
commit as the restore source.

See "Reset, restore and revert" in linkgit:git[1] for the differences
between the three commands.

THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.

OPTIONS
-------
-s <tree>::
--source=<tree>::
Restore the working tree files with the content from the given
tree. It is common to specify the source tree by naming a
commit, branch or tag associated with it.
+
If not specified, the default restore source for the working tree is
the index, and the default restore source for the index index is
`HEAD`. When both `--staged` and `--worktree` are specified,
`--source` must also be specified.

-p::
--patch::
Interactively select hunks in the difference between the
restore source and the restore location. See the ``Interactive
Mode'' section of linkgit:git-add[1] to learn how to operate
the `--patch` mode.
+
Note that `--patch` can accept no pathspec and will prompt to restore
all modified paths.

-W::
--worktree::
-S::
--staged::
Specify the restore location. If neither option is specified,
by default the working tree is restored. Specifying `--staged`
will only restore the index. Specifying both restores both.

-q::
--quiet::
Quiet, suppress feedback messages. Implies `--no-progress`.

--progress::
--no-progress::
Progress status is reported on the standard error stream
by default when it is attached to a terminal, unless `--quiet`
is specified. This flag enables progress reporting even if not
attached to a terminal, regardless of `--quiet`.

--ours::
--theirs::
When restoring files in the working tree from the index, use
stage #2 ('ours') or #3 ('theirs') for unmerged paths.
+
Note that during `git rebase` and `git pull --rebase`, 'ours' and
'theirs' may appear swapped. See the explanation of the same options
in linkgit:git-checkout[1] for details.

-m::
--merge::
When restoring files on the working tree from the index,
recreate the conflicted merge in the unmerged paths.

--conflict=<style>::
The same as `--merge` option above, but changes the way the
conflicting hunks are presented, overriding the
`merge.conflictStyle` configuration variable. Possible values
are "merge" (default) and "diff3" (in addition to what is
shown by "merge" style, shows the original contents).

--ignore-unmerged::
When restoring files on the working tree from the index, do
not abort the operation if there are unmerged entries and
neither `--ours`, `--theirs`, `--merge` or `--conflict` is
specified. Unmerged paths on the working tree are left alone.

--ignore-skip-worktree-bits::
In sparse checkout mode, by default is to only update entries
matched by `<pathspec>` and sparse patterns in
$GIT_DIR/info/sparse-checkout. This option ignores the sparse
patterns and unconditionally restores any files in
`<pathspec>`.

--overlay::
--no-overlay::
In overlay mode, the command never removes files when
restoring. In no-overlay mode, tracked files that do not
appear in the `--source` tree are removed, to make them match
`<tree>` exactly. The default is no-overlay mode.

EXAMPLES
--------

The following sequence switches to the `master` branch, reverts the
`Makefile` to two revisions back, deletes hello.c by mistake, and gets
it back from the index.

------------
$ git switch master
$ git restore --source master~2 Makefile <1>
$ rm -f hello.c
$ git restore hello.c <2>
------------

<1> take a file out of another commit
<2> restore hello.c from the index

If you want to restore _all_ C source files to match the version in
the index, you can say

------------
$ git restore '*.c'
------------

Note the quotes around `*.c`. The file `hello.c` will also be
restored, even though it is no longer in the working tree, because the
file globbing is used to match entries in the index (not in the
working tree by the shell).

To restore all files in the current directory

------------
$ git restore .
------------

or to restore all working tree files with 'top' pathspec magic (see
linkgit:gitglossary[7])

------------
$ git restore :/
------------

To restore a file in the index to match the version in `HEAD` (this is
the same as using linkgit:git-reset[1])

------------
$ git restore --staged hello.c
------------

or you can restore both the index and the working tree (this the same
as using linkgit:git-checkout[1])

------------
$ git restore --source=HEAD --staged --worktree hello.c
------------

or the short form which is more practical but less readable:

------------
$ git restore -s@ -SW hello.c
------------

SEE ALSO
--------
linkgit:git-checkout[1],
linkgit:git-reset[1]

GIT
---
Part of the linkgit:git[1] suite

+ 5
- 2
Documentation/git-revert.txt View File

@@ -26,10 +26,13 @@ effect of some earlier commits (often only a faulty one). If you want to
throw away all uncommitted changes in your working directory, you
should see linkgit:git-reset[1], particularly the `--hard` option. If
you want to extract specific files as they were in another commit, you
should see linkgit:git-checkout[1], specifically the `git checkout
<commit> -- <filename>` syntax. Take care with these alternatives as
should see linkgit:git-restore[1], specifically the `--source`
option. Take care with these alternatives as
both will discard uncommitted changes in your working directory.

See "Reset, restore and revert" in linkgit:git[1] for the differences
between the three commands.

OPTIONS
-------
<commit>...::

+ 5
- 4
Documentation/git-stash.txt View File

@@ -235,12 +235,12 @@ return to your original branch to make the emergency fix, like this:
+
----------------------------------------------------------------
# ... hack hack hack ...
$ git checkout -b my_wip
$ git switch -c my_wip
$ git commit -a -m "WIP"
$ git checkout master
$ git switch master
$ edit emergency fix
$ git commit -a -m "Fix in a hurry"
$ git checkout my_wip
$ git switch my_wip
$ git reset --soft HEAD^
# ... continue hacking ...
----------------------------------------------------------------
@@ -293,7 +293,8 @@ SEE ALSO
linkgit:git-checkout[1],
linkgit:git-commit[1],
linkgit:git-reflog[1],
linkgit:git-reset[1]
linkgit:git-reset[1],
linkgit:git-switch[1]

GIT
---

+ 273
- 0
Documentation/git-switch.txt View File

@@ -0,0 +1,273 @@
git-switch(1)
=============

NAME
----
git-switch - Switch branches

SYNOPSIS
--------
[verse]
'git switch' [<options>] [--no-guess] <branch>
'git switch' [<options>] --detach [<start-point>]
'git switch' [<options>] (-c|-C) <new-branch> [<start-point>]
'git switch' [<options>] --orphan <new-branch>

DESCRIPTION
-----------
Switch to a specified branch. The working tree and the index are
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`, `-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
however if the operation leads to loss of local changes, unless told
otherwise with `--discard-changes` or `--merge`.

THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.

OPTIONS
-------
<branch>::
Branch to switch to.

<new-branch>::
Name for the new branch.

<start-point>::
The starting point for the new branch. Specifying a
`<start-point>` 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
branch/commit switched to using "git switch" or "git checkout"
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
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`.

-c <new-branch>::
--create <new-branch>::
Create a new branch named `<new-branch>` starting at
`<start-point>` before switching to the branch. This is a
convenient shortcut for:
+
------------
$ git branch <new-branch>
$ git switch <new-branch>
------------

-C <new-branch>::
--force-create <new-branch>::
Similar to `--create` except that if `<new-branch>` already
exists, it will be reset to `<start-point>`. This is a
convenient shortcut for:
+
------------
$ git branch -f <new-branch>
$ git switch <new-branch>
------------

-d::
--detach::
Switch to a commit for inspection and discardable
experiments. See the "DETACHED HEAD" section in
linkgit:git-checkout[1] for details.

--guess::
--no-guess::
If `<branch>` is not found but there does exist a tracking
branch in exactly one remote (call it `<remote>`) with a
matching name, treat as equivalent to
+
------------
$ git switch -c <branch> --track <remote>/<branch>
------------
+
If the branch exists in multiple remotes and one of them is named by
the `checkout.defaultRemote` configuration variable, we'll use that
one for the purposes of disambiguation, even if the `<branch>` isn't
unique across all remotes. Set it to e.g. `checkout.defaultRemote=origin`
to always checkout remote branches from there if `<branch>` is
ambiguous but exists on the 'origin' remote. See also
`checkout.defaultRemote` in linkgit:git-config[1].
+
`--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
the switching target. If `--recurse-submodules` is specified,
submodule content is also 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=<style>::
The same as `--merge` option above, but changes the way the
conflicting hunks are presented, overriding the
`merge.conflictStyle` configuration variable. Possible values are
"merge" (default) and "diff3" (in addition to what is shown by
"merge" style, shows the original contents).

-q::
--quiet::
Quiet, suppress feedback messages.

--progress::
--no-progress::
Progress status is reported on the standard error stream
by default when it is attached to a terminal, unless `--quiet`
is specified. This flag enables progress reporting even if not
attached to a terminal, regardless of `--quiet`.

-t::
--track::
When creating a new branch, set up "upstream" configuration.
`-c` is implied. See `--track` in linkgit:git-branch[1] for
details.
+
If no `-c` option is given, the name of the new branch will be derived
from the remote-tracking branch, by looking at the local part of the
refspec configured for the corresponding remote, and then stripping
the initial part up to the "*". This would tell us to use `hack` as
the local branch when branching off of `origin/hack` (or
`remotes/origin/hack`, or even `refs/remotes/origin/hack`). If the
given name has no slash, or the above guessing results in an empty
name, the guessing is aborted. You can explicitly give a name with
`-c` in such a case.

--no-track::
Do not set up "upstream" configuration, even if the
`branch.autoSetupMerge` configuration variable is true.

--orphan <new-branch>::
Create a new 'orphan' branch, named `<new-branch>`. All
tracked files are removed.

--ignore-other-worktrees::
`git switch` refuses when the wanted ref is already
checked out by another worktree. This option makes it check
the ref out anyway. In other words, the ref can be held by
more than one worktree.

--recurse-submodules::
--no-recurse-submodules::
Using `--recurse-submodules` will update the content of all
initialized submodules according to the commit recorded in the
superproject. 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 `HEAD` of the
submodules.

EXAMPLES
--------

The following command switches to the "master" branch:

------------
$ git switch master
------------

After working in the wrong branch, switching to the correct branch
would be done using:

------------
$ git switch mytopic
------------

However, your "wrong" branch and correct "mytopic" branch may differ
in files that you have modified locally, in which case the above
switch would fail like this:

------------
$ git switch mytopic
error: You have local changes to 'frotz'; not switching branches.
------------

You can give the `-m` flag to the command, which would try a three-way
merge:

------------
$ git switch -m mytopic
Auto-merging frotz
------------

After this three-way merge, the local modifications are _not_
registered in your index file, so `git diff` would show you what
changes you made since the tip of the new branch.

To switch back to the previous branch before we switched to mytopic
(i.e. "master" branch):

------------
$ git switch -
------------

You can grow a new branch from any commit. For example, switch to
"HEAD~3" and create branch "fixup":

------------
$ git switch -c fixup HEAD~3
Switched to a new branch 'fixup'
------------

If you want to start a new branch from a remote branch of the same
name:

------------
$ git switch new-topic
Branch 'new-topic' set up to track remote branch 'new-topic' from 'origin'
Switched to a new branch 'new-topic'
------------

To check out commit `HEAD~3` for temporary inspection or experiment
without creating a new branch:

------------
$ git switch --detach HEAD~3
HEAD is now at 9fc9555312 Merge branch 'cc/shared-index-permbits'
------------

If it turns out whatever you have done is worth keeping, you can
always create a new name for it (without switching away):

------------
$ git switch -c good-surprises
------------

SEE ALSO
--------
linkgit:git-checkout[1],
linkgit:git-branch[1]

GIT
---
Part of the linkgit:git[1] suite

+ 20
- 0
Documentation/git.txt View File

@@ -211,6 +211,26 @@ people via patch over e-mail.

include::cmds-foreignscminterface.txt[]

Reset, restore and revert
~~~~~~~~~~~~~~~~~~~~~~~~~
There are three commands with similar names: `git reset`,
`git restore` and `git revert`.

* linkgit:git-revert[1] is about making a new commit that reverts the
changes made by other commits.

* linkgit:git-restore[1] is about restoring files in the working tree
from either the index or another commit. This command does not
update your branch. The command can also be used to restore files in
the index from another commit.

* linkgit:git-reset[1] is about updating your branch, moving the tip
in order to add or remove commits from the branch. This operation
changes the commit history.
+
`git reset` can also be used to restore the index, overlapping with
`git restore`.


Low-level commands (plumbing)
-----------------------------

+ 2
- 1
Documentation/gitattributes.txt View File

@@ -112,7 +112,8 @@ Checking-out and checking-in

These attributes affect how the contents stored in the
repository are copied to the working tree files when commands
such as 'git checkout' and 'git merge' run. They also affect how
such as 'git switch', 'git checkout' and 'git merge' run.
They also affect how
Git stores the contents you prepare in the working tree in the
repository upon 'git add' and 'git commit'.


+ 14
- 2
Documentation/gitcli.txt View File

@@ -47,8 +47,8 @@ disambiguating `--` at appropriate places.
things:
+
--------------------------------
$ git checkout -- *.c
$ git checkout -- \*.c
$ git restore *.c
$ git restore \*.c
--------------------------------
+
The former lets your shell expand the fileglob, and you are asking
@@ -209,6 +209,18 @@ See also http://marc.info/?l=git&m=116563135620359 and
http://marc.info/?l=git&m=119150393620273 for further
information.

Some other commands that also work on files in the working tree and/or
in the index can take `--staged` and/or `--worktree`.

* `--staged` is exactly like `--cached`, which is used to ask a
command to only work on the index, not the working tree.

* `--worktree` is the opposite, to ask a command to work on the
working tree only, not the index.

* The two options can be specified together to ask a command to work
on both the index and the working tree.

GIT
---
Part of the linkgit:git[1] suite

+ 9
- 10
Documentation/gitcore-tutorial.txt View File

@@ -741,7 +741,7 @@ used earlier, and create a branch in it. You do that by simply just
saying that you want to check out a new branch:

------------
$ git checkout -b mybranch
$ git switch -c mybranch
------------

will create a new branch based at the current `HEAD` position, and switch
@@ -755,7 +755,7 @@ just telling 'git checkout' what the base of the checkout would be.
In other words, if you have an earlier tag or branch, you'd just do

------------
$ git checkout -b mybranch earlier-commit
$ git switch -c mybranch earlier-commit
------------

and it would create the new branch `mybranch` at the earlier commit,
@@ -765,7 +765,7 @@ and check out the state at that time.
You can always just jump back to your original `master` branch by doing

------------
$ git checkout master
$ git switch master
------------

(or any other branch-name, for that matter) and if you forget which
@@ -794,7 +794,7 @@ $ git branch <branchname> [startingpoint]

which will simply _create_ the branch, but will not do anything further.
You can then later -- once you decide that you want to actually develop
on that branch -- switch to that branch with a regular 'git checkout'
on that branch -- switch to that branch with a regular 'git switch'
with the branchname as the argument.


@@ -808,7 +808,7 @@ being the same as the original `master` branch, let's make sure we're in
that branch, and do some work there.

------------------------------------------------
$ git checkout mybranch
$ git switch mybranch
$ echo "Work, work, work" >>hello
$ git commit -m "Some work." -i hello
------------------------------------------------
@@ -825,7 +825,7 @@ does some work in the original branch, and simulate that by going back
to the master branch, and editing the same file differently there:

------------
$ git checkout master
$ git switch master
------------

Here, take a moment to look at the contents of `hello`, and notice how they
@@ -958,7 +958,7 @@ to the `master` branch. Let's go back to `mybranch`, and run
'git merge' to get the "upstream changes" back to your branch.

------------
$ git checkout mybranch
$ git switch mybranch
$ git merge -m "Merge upstream changes." master
------------

@@ -1133,9 +1133,8 @@ Remember, before running 'git merge', our `master` head was at
work." commit.

------------
$ git checkout mybranch
$ git reset --hard master^2
$ git checkout master
$ git switch -C mybranch master^2
$ git switch master
$ git reset --hard master^
------------


+ 14
- 15
Documentation/giteveryday.txt View File

@@ -41,7 +41,7 @@ following commands.

* linkgit:git-log[1] to see what happened.

* linkgit:git-checkout[1] and linkgit:git-branch[1] to switch
* linkgit:git-switch[1] and linkgit:git-branch[1] to switch
branches.

* linkgit:git-add[1] to manage the index file.
@@ -51,8 +51,7 @@ following commands.

* linkgit:git-commit[1] to advance the current branch.

* linkgit:git-reset[1] and linkgit:git-checkout[1] (with
pathname parameters) to undo changes.
* linkgit:git-restore[1] to undo changes.

* linkgit:git-merge[1] to merge between local branches.

@@ -80,9 +79,9 @@ $ git tag v2.43 <2>
Create a topic branch and develop.::
+
------------
$ git checkout -b alsa-audio <1>
$ git switch -c alsa-audio <1>
$ edit/compile/test
$ git checkout -- curses/ux_audio_oss.c <2>
$ git restore curses/ux_audio_oss.c <2>
$ git add curses/ux_audio_alsa.c <3>
$ edit/compile/test
$ git diff HEAD <4>
@@ -90,7 +89,7 @@ $ git commit -a -s <5>
$ edit/compile/test
$ git diff HEAD^ <6>
$ git commit -a --amend <7>
$ git checkout master <8>
$ git switch master <8>
$ git merge alsa-audio <9>
$ git log --since='3 days ago' <10>
$ git log v2.43.. curses/ <11>
@@ -148,11 +147,11 @@ Clone the upstream and work on it. Feed changes to upstream.::
------------
$ git clone git://git.kernel.org/pub/scm/.../torvalds/linux-2.6 my2.6
$ cd my2.6
$ git checkout -b mine master <1>
$ git switch -c mine master <1>
$ edit/compile/test; git commit -a -s <2>
$ git format-patch master <3>
$ git send-email --to="person <email@example.com>" 00*.patch <4>
$ git checkout master <5>
$ git switch master <5>
$ git pull <6>
$ git log -p ORIG_HEAD.. arch/i386 include/asm-i386 <7>
$ git ls-remote --heads http://git.kernel.org/.../jgarzik/libata-dev.git <8>
@@ -194,7 +193,7 @@ satellite$ edit/compile/test/commit
satellite$ git push origin <4>

mothership$ cd frotz
mothership$ git checkout master
mothership$ git switch master
mothership$ git merge satellite/master <5>
------------
+
@@ -216,7 +215,7 @@ machine into the master branch.
Branch off of a specific tag.::
+
------------
$ git checkout -b private2.6.14 v2.6.14 <1>
$ git switch -c private2.6.14 v2.6.14 <1>
$ edit/compile/test; git commit -a
$ git checkout master
$ git cherry-pick v2.6.14..private2.6.14 <2>
@@ -274,14 +273,14 @@ $ mailx <3>
& s 2 3 4 5 ./+to-apply
& s 7 8 ./+hold-linus
& q
$ git checkout -b topic/one master
$ git switch -c topic/one master
$ git am -3 -i -s ./+to-apply <4>
$ compile/test
$ git checkout -b hold/linus && git am -3 -i -s ./+hold-linus <5>
$ git checkout topic/one && git rebase master <6>
$ git checkout pu && git reset --hard next <7>
$ git switch -c hold/linus && git am -3 -i -s ./+hold-linus <5>
$ git switch topic/one && git rebase master <6>
$ git switch -C pu next <7>
$ git merge topic/one topic/two && git merge hold/linus <8>
$ git checkout maint
$ git switch maint
$ git cherry-pick master~4 <9>
$ compile/test
$ git tag -s -m "GIT 0.99.9x" v0.99.9x <10>

+ 5
- 3
Documentation/githooks.txt View File

@@ -165,12 +165,13 @@ rebased, and is not set when rebasing the current branch.
post-checkout
~~~~~~~~~~~~~

This hook is invoked when a linkgit:git-checkout[1] is run after having updated the
This hook is invoked when a linkgit:git-checkout[1] or
linkgit:git-switch[1] is run after having updated the
worktree. The hook is given three parameters: the ref of the previous HEAD,
the ref of the new HEAD (which may or may not have changed), and a flag
indicating whether the checkout was a branch checkout (changing branches,
flag=1) or a file checkout (retrieving a file from the index, flag=0).
This hook cannot affect the outcome of `git checkout`.
This hook cannot affect the outcome of `git switch` or `git checkout`.

It is also run after linkgit:git-clone[1], unless the `--no-checkout` (`-n`) option is
used. The first parameter given to the hook is the null-ref, the second the
@@ -406,7 +407,8 @@ exit with a zero status.
For example, the hook can simply run `git read-tree -u -m HEAD "$1"`
in order to emulate `git fetch` that is run in the reverse direction
with `git push`, as the two-tree form of `git read-tree -u -m` is
essentially the same as `git checkout` that switches branches while
essentially the same as `git switch` or `git checkout`
that switches branches while
keeping the local changes in the working tree that do not interfere
with the difference between the branches.


+ 2
- 2
Documentation/gittutorial-2.txt View File

@@ -370,13 +370,13 @@ situation:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
(use "git restore --staged <file>..." to unstage)

new file: closing.txt

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
(use "git restore <file>..." to discard changes in working directory)

modified: file.txt


+ 3
- 3
Documentation/gittutorial.txt View File

@@ -110,7 +110,7 @@ $ git status
On branch master
Changes to be committed:
Your branch is up to date with 'origin/master'.
(use "git reset HEAD <file>..." to unstage)
(use "git restore --staged <file>..." to unstage)

modified: file1
modified: file2
@@ -207,7 +207,7 @@ automatically. The asterisk marks the branch you are currently on;
type

------------------------------------------------
$ git checkout experimental
$ git switch experimental
------------------------------------------------

to switch to the experimental branch. Now edit a file, commit the
@@ -216,7 +216,7 @@ change, and switch back to the master branch:
------------------------------------------------
(edit file)
$ git commit -a
$ git checkout master
$ git switch master
------------------------------------------------

Check that the change you made is no longer visible, since it was

+ 1
- 2
Documentation/gitworkflows.txt View File

@@ -301,8 +301,7 @@ topics on 'next':
.Rewind and rebuild next
[caption="Recipe: "]
=====================================
* `git checkout next`
* `git reset --hard master`
* `git switch -C next master`
* `git merge ai/topic_in_next1`
* `git merge ai/topic_in_next2`
* ...

+ 1
- 1
Documentation/revisions.txt View File

@@ -115,7 +115,7 @@ Here's an example to make it more clear:
------------------------------
$ git config push.default current
$ git config remote.pushdefault myfork
$ git checkout -b mybranch origin/master
$ git switch -c mybranch origin/master

$ git rev-parse --symbolic-full-name @{upstream}
refs/remotes/origin/master

+ 34
- 36
Documentation/user-manual.txt View File

@@ -122,10 +122,10 @@ Tags are expected to always point at the same version of a project,
while heads are expected to advance as development progresses.

Create a new branch head pointing to one of these versions and check it
out using linkgit:git-checkout[1]:
out using linkgit:git-switch[1]:

------------------------------------------------
$ git checkout -b new v2.6.13
$ git switch -c new v2.6.13
------------------------------------------------

The working directory then reflects the contents that the project had
@@ -282,10 +282,10 @@ a summary of the commands:
this command will fail with a warning.
`git branch -D <branch>`::
delete the branch `<branch>` irrespective of its merged status.
`git checkout <branch>`::
`git switch <branch>`::
make the current branch `<branch>`, updating the working
directory to reflect the version referenced by `<branch>`.
`git checkout -b <new> <start-point>`::
`git switch -c <new> <start-point>`::
create a new branch `<new>` referencing `<start-point>`, and
check it out.

@@ -302,22 +302,22 @@ ref: refs/heads/master
Examining an old version without creating a new branch
------------------------------------------------------

The `git checkout` command normally expects a branch head, but will also
accept an arbitrary commit; for example, you can check out the commit
referenced by a tag:
The `git switch` command normally expects a branch head, but will also
accept an arbitrary commit when invoked with --detach; for example,
you can check out the commit referenced by a tag:

------------------------------------------------
$ git checkout v2.6.17
$ git switch --detach v2.6.17
Note: checking out 'v2.6.17'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
state without impacting any branches by performing another switch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
do so (now or later) by using -c with the switch command again. Example:

git checkout -b new_branch_name
git switch -c new_branch_name

HEAD is now at 427abfa Linux v2.6.17
------------------------------------------------
@@ -373,7 +373,7 @@ You might want to build on one of these remote-tracking branches
on a branch of your own, just as you would for a tag:

------------------------------------------------
$ git checkout -b my-todo-copy origin/todo
$ git switch -c my-todo-copy origin/todo
------------------------------------------------

You can also check out `origin/todo` directly to examine it or
@@ -1408,7 +1408,7 @@ If you get stuck and decide to just give up and throw the whole mess
away, you can always return to the pre-merge state with

-------------------------------------------------
$ git reset --hard HEAD
$ git merge --abort
-------------------------------------------------

Or, if you've already committed the merge that you want to throw away,
@@ -1446,7 +1446,7 @@ mistake, you can return the entire working tree to the last committed
state with

-------------------------------------------------
$ git reset --hard HEAD
$ git restore --staged --worktree :/
-------------------------------------------------

If you make a commit that you later wish you hadn't, there are two
@@ -1523,12 +1523,10 @@ Checking out an old version of a file

In the process of undoing a previous bad change, you may find it
useful to check out an older version of a particular file using
linkgit:git-checkout[1]. We've used `git checkout` before to switch
branches, but it has quite different behavior if it is given a path
name: the command
linkgit:git-restore[1]. The command

-------------------------------------------------
$ git checkout HEAD^ path/to/file
$ git restore --source=HEAD^ path/to/file
-------------------------------------------------

replaces path/to/file by the contents it had in the commit HEAD^, and
@@ -2211,8 +2209,8 @@ $ git branch --track release origin/master
These can be easily kept up to date using linkgit:git-pull[1].

-------------------------------------------------
$ git checkout test && git pull
$ git checkout release && git pull
$ git switch test && git pull
$ git switch release && git pull
-------------------------------------------------

Important note! If you have any local changes in these branches, then
@@ -2264,7 +2262,7 @@ tested changes
2) help future bug hunters that use `git bisect` to find problems

-------------------------------------------------
$ git checkout -b speed-up-spinlocks v2.6.35
$ git switch -c speed-up-spinlocks v2.6.35
-------------------------------------------------

Now you apply the patch(es), run some tests, and commit the change(s). If
@@ -2279,7 +2277,7 @@ When you are happy with the state of this change, you can merge it into the
"test" branch in preparation to make it public:

-------------------------------------------------
$ git checkout test && git merge speed-up-spinlocks
$ git switch test && git merge speed-up-spinlocks
-------------------------------------------------

It is unlikely that you would have any conflicts here ... but you might if you
@@ -2291,7 +2289,7 @@ see the value of keeping each patch (or patch series) in its own branch. It
means that the patches can be moved into the `release` tree in any order.

-------------------------------------------------
$ git checkout release && git merge speed-up-spinlocks
$ git switch release && git merge speed-up-spinlocks
-------------------------------------------------

After a while, you will have a number of branches, and despite the
@@ -2512,7 +2510,7 @@ Suppose that you create a branch `mywork` on a remote-tracking branch
`origin`, and create some commits on top of it:

-------------------------------------------------
$ git checkout -b mywork origin
$ git switch -c mywork origin
$ vi file.txt
$ git commit
$ vi otherfile.txt
@@ -2552,7 +2550,7 @@ commits without any merges, you may instead choose to use
linkgit:git-rebase[1]:

-------------------------------------------------
$ git checkout mywork
$ git switch mywork
$ git rebase origin
-------------------------------------------------

@@ -3668,13 +3666,13 @@ change within the submodule, and then update the superproject to reference the
new commit:

-------------------------------------------------
$ git checkout master
$ git switch master
-------------------------------------------------

or

-------------------------------------------------
$ git checkout -b fix-up
$ git switch -c fix-up
-------------------------------------------------

then
@@ -3800,8 +3798,8 @@ use linkgit:git-tag[1] for both.
The Workflow
------------

High-level operations such as linkgit:git-commit[1],
linkgit:git-checkout[1] and linkgit:git-reset[1] work by moving data
High-level operations such as linkgit:git-commit[1] and
linkgit:git-restore[1] work by moving data
between the working tree, the index, and the object database. Git
provides low-level operations which perform each of these steps
individually.
@@ -4194,7 +4192,7 @@ start.
A good place to start is with the contents of the initial commit, with:

----------------------------------------------------
$ git checkout e83c5163
$ git switch --detach e83c5163
----------------------------------------------------

The initial revision lays the foundation for almost everything Git has
@@ -4437,10 +4435,10 @@ Managing branches
-----------------

-----------------------------------------------
$ git branch # list all local branches in this repo
$ git checkout test # switch working directory to branch "test"
$ git branch new # create branch "new" starting at current HEAD
$ git branch -d new # delete branch "new"
$ git branch # list all local branches in this repo
$ git switch test # switch working directory to branch "test"
$ git branch new # create branch "new" starting at current HEAD
$ git branch -d new # delete branch "new"
-----------------------------------------------

Instead of basing a new branch on current HEAD (the default), use:
@@ -4456,7 +4454,7 @@ $ git branch new test~10 # ten commits before tip of branch "test"
Create and switch to a new branch at the same time:

-----------------------------------------------
$ git checkout -b new v2.6.15
$ git switch -c new v2.6.15
-----------------------------------------------

Update and examine branches from the repository you cloned from:
@@ -4467,7 +4465,7 @@ $ git branch -r # list
origin/master
origin/next
...
$ git checkout -b masterwork origin/master
$ git switch -c masterwork origin/master
-----------------------------------------------

Fetch a branch from a different repository, and give it a new

+ 2
- 0
Makefile View File

@@ -771,9 +771,11 @@ BUILT_INS += git-format-patch$X
BUILT_INS += git-fsck-objects$X
BUILT_INS += git-init$X
BUILT_INS += git-merge-subtree$X
BUILT_INS += git-restore$X
BUILT_INS += git-show$X
BUILT_INS += git-stage$X
BUILT_INS += git-status$X
BUILT_INS += git-switch$X
BUILT_INS += git-whatchanged$X

# what 'all' will build and 'install' will install in gitexecdir,

+ 13
- 4
advice.c View File

@@ -193,13 +193,22 @@ void NORETURN die_conclude_merge(void)
void detach_advice(const char *new_name)
{
const char *fmt =
_("Note: checking out '%s'.\n\n"
_("Note: switching to '%s'.\n"
"\n"
"You are in 'detached HEAD' state. You can look around, make experimental\n"
"changes and commit them, and you can discard any commits you make in this\n"
"state without impacting any branches by performing another checkout.\n\n"
"state without impacting any branches by switching back to a branch.\n"
"\n"
"If you want to create a new branch to retain commits you create, you may\n"
"do so (now or later) by using -b with the checkout command again. Example:\n\n"
" git checkout -b <new-branch-name>\n\n");
"do so (now or later) by using -c with the switch command. Example:\n"
"\n"
" git switch -c <new-branch-name>\n"
"\n"
"Or undo this operation with:\n"
"\n"
" git switch -\n"
"\n"
"Turn off this advice by setting config variable advice.detachedHead to false\n\n");

fprintf(stderr, fmt, new_name);
}

+ 2
- 2
branch.c View File

@@ -346,9 +346,9 @@ void remove_merge_branch_state(struct repository *r)
unlink(git_path_merge_mode(r));
}

void remove_branch_state(struct repository *r)
void remove_branch_state(struct repository *r, int verbose)
{
sequencer_post_commit_cleanup(r);
sequencer_post_commit_cleanup(r, verbose);
unlink(git_path_squash_msg(r));
remove_merge_branch_state(r);
}

+ 1
- 1
branch.h View File

@@ -70,7 +70,7 @@ void remove_merge_branch_state(struct repository *r);
* Remove information about the state of working on the current
* branch. (E.g., MERGE_HEAD)