checkout: split part of it to new command 'restore'
Previously the switching branch business of 'git checkout' becomes a new command 'switch'. This adds the restore command for the checking out paths path. Similar to git-switch, a new man page is added to describe what the command will become. The implementation will be updated shortly to match the man page. A couple main differences from 'git checkout <paths>': - 'restore' by default will only update worktree. This matters more when --source is specified ('checkout <tree> <paths>' updates both worktree and index). - 'restore --staged' can be used to restore the index. This command overlaps with 'git reset <paths>'. - both worktree and index could also be restored at the same time (from a tree) when both --staged and --worktree are specified. This overlaps with 'git checkout <tree> <paths>' - default source for restoring worktree and index is the index and HEAD respectively. A different (tree) source could be specified as with --source (*). - when both index and worktree are restored, --source must be specified since the default source for these two individual targets are different (**) - --no-overlay is enabled by default, if an entry is missing in the source, restoring means deleting the entry (*) I originally went with --from instead of --source. I still think --from is a better name. The short option -f however is already taken by force. And I do think short option is good to have, e.g. to write -s@ or -s@^ instead of --source=HEAD. (**) If you sit down and think about it, moving worktree's source from the index to HEAD makes sense, but nobody is really thinking it through when they type the commands. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
328c6cb853
commit
46e91b663b
1
.gitignore
vendored
1
.gitignore
vendored
@ -143,6 +143,7 @@
|
|||||||
/git-request-pull
|
/git-request-pull
|
||||||
/git-rerere
|
/git-rerere
|
||||||
/git-reset
|
/git-reset
|
||||||
|
/git-restore
|
||||||
/git-rev-list
|
/git-rev-list
|
||||||
/git-rev-parse
|
/git-rev-parse
|
||||||
/git-revert
|
/git-revert
|
||||||
|
@ -2,7 +2,8 @@ interactive.singleKey::
|
|||||||
In interactive commands, allow the user to provide one-letter
|
In interactive commands, allow the user to provide one-letter
|
||||||
input with a single key (i.e., without hitting enter).
|
input with a single key (i.e., without hitting enter).
|
||||||
Currently this is used by the `--patch` mode of
|
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
|
linkgit:git-reset[1], and linkgit:git-stash[1]. Note that this
|
||||||
setting is silently ignored if portable keystroke input
|
setting is silently ignored if portable keystroke input
|
||||||
is not available; requires the Perl module Term::ReadKey.
|
is not available; requires the Perl module Term::ReadKey.
|
||||||
|
@ -570,7 +570,8 @@ $ git add frotz
|
|||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
linkgit:git-switch[1]
|
linkgit:git-switch[1],
|
||||||
|
linkgit:git-restore[1]
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
---
|
---
|
||||||
|
@ -25,7 +25,8 @@ The `<tree-ish>`/`<commit>` defaults to `HEAD` in all forms.
|
|||||||
the current branch.)
|
the current branch.)
|
||||||
+
|
+
|
||||||
This means that `git reset <paths>` is the opposite of `git add
|
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
|
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
|
use linkgit:git-checkout[1] to check the contents out of the index to
|
||||||
@ -86,8 +87,8 @@ but carries forward unmerged index entries.
|
|||||||
changes, reset is aborted.
|
changes, reset is aborted.
|
||||||
--
|
--
|
||||||
|
|
||||||
If you want to undo a commit other than the latest on a branch,
|
See "Reset, restore and revert" in linkgit:git[1] for the differences
|
||||||
linkgit:git-revert[1] is your friend.
|
between the three commands.
|
||||||
|
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
|
183
Documentation/git-restore.txt
Normal file
183
Documentation/git-restore.txt
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
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.
|
||||||
|
|
||||||
|
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
|
@ -30,6 +30,9 @@ should see linkgit:git-checkout[1], specifically the `git checkout
|
|||||||
<commit> -- <filename>` syntax. Take care with these alternatives as
|
<commit> -- <filename>` syntax. Take care with these alternatives as
|
||||||
both will discard uncommitted changes in your working directory.
|
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
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
<commit>...::
|
<commit>...::
|
||||||
|
@ -210,6 +210,26 @@ people via patch over e-mail.
|
|||||||
|
|
||||||
include::cmds-foreignscminterface.txt[]
|
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)
|
Low-level commands (plumbing)
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
@ -209,6 +209,18 @@ See also http://marc.info/?l=git&m=116563135620359 and
|
|||||||
http://marc.info/?l=git&m=119150393620273 for further
|
http://marc.info/?l=git&m=119150393620273 for further
|
||||||
information.
|
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
|
GIT
|
||||||
---
|
---
|
||||||
Part of the linkgit:git[1] suite
|
Part of the linkgit:git[1] suite
|
||||||
|
1
Makefile
1
Makefile
@ -799,6 +799,7 @@ BUILT_INS += git-format-patch$X
|
|||||||
BUILT_INS += git-fsck-objects$X
|
BUILT_INS += git-fsck-objects$X
|
||||||
BUILT_INS += git-init$X
|
BUILT_INS += git-init$X
|
||||||
BUILT_INS += git-merge-subtree$X
|
BUILT_INS += git-merge-subtree$X
|
||||||
|
BUILT_INS += git-restore$X
|
||||||
BUILT_INS += git-show$X
|
BUILT_INS += git-show$X
|
||||||
BUILT_INS += git-stage$X
|
BUILT_INS += git-stage$X
|
||||||
BUILT_INS += git-status$X
|
BUILT_INS += git-status$X
|
||||||
|
@ -214,6 +214,7 @@ extern int cmd_remote_fd(int argc, const char **argv, const char *prefix);
|
|||||||
extern int cmd_repack(int argc, const char **argv, const char *prefix);
|
extern int cmd_repack(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_rerere(int argc, const char **argv, const char *prefix);
|
extern int cmd_rerere(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_reset(int argc, const char **argv, const char *prefix);
|
extern int cmd_reset(int argc, const char **argv, const char *prefix);
|
||||||
|
extern int cmd_restore(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
|
extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
|
extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_revert(int argc, const char **argv, const char *prefix);
|
extern int cmd_revert(int argc, const char **argv, const char *prefix);
|
||||||
|
@ -38,6 +38,11 @@ static const char * const switch_branch_usage[] = {
|
|||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char * const restore_usage[] = {
|
||||||
|
N_("git restore [<options>] [<branch>] -- <file>..."),
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
struct checkout_opts {
|
struct checkout_opts {
|
||||||
int patch_mode;
|
int patch_mode;
|
||||||
int quiet;
|
int quiet;
|
||||||
@ -1622,3 +1627,24 @@ int cmd_switch(int argc, const char **argv, const char *prefix)
|
|||||||
FREE_AND_NULL(options);
|
FREE_AND_NULL(options);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cmd_restore(int argc, const char **argv, const char *prefix)
|
||||||
|
{
|
||||||
|
struct checkout_opts opts;
|
||||||
|
struct option *options = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
memset(&opts, 0, sizeof(opts));
|
||||||
|
opts.dwim_new_local_branch = 1;
|
||||||
|
opts.switch_branch_doing_nothing_is_ok = 0;
|
||||||
|
opts.accept_pathspec = 1;
|
||||||
|
|
||||||
|
options = parse_options_dup(options);
|
||||||
|
options = add_common_options(&opts, options);
|
||||||
|
options = add_checkout_path_options(&opts, options);
|
||||||
|
|
||||||
|
ret = checkout_main(argc, argv, prefix, &opts,
|
||||||
|
options, restore_usage);
|
||||||
|
FREE_AND_NULL(options);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -151,6 +151,7 @@ git-replace ancillarymanipulators complete
|
|||||||
git-request-pull foreignscminterface complete
|
git-request-pull foreignscminterface complete
|
||||||
git-rerere ancillaryinterrogators
|
git-rerere ancillaryinterrogators
|
||||||
git-reset mainporcelain worktree
|
git-reset mainporcelain worktree
|
||||||
|
git-restore mainporcelain worktree
|
||||||
git-revert mainporcelain
|
git-revert mainporcelain
|
||||||
git-rev-list plumbinginterrogators
|
git-rev-list plumbinginterrogators
|
||||||
git-rev-parse plumbinginterrogators
|
git-rev-parse plumbinginterrogators
|
||||||
|
1
git.c
1
git.c
@ -558,6 +558,7 @@ static struct cmd_struct commands[] = {
|
|||||||
{ "replace", cmd_replace, RUN_SETUP },
|
{ "replace", cmd_replace, RUN_SETUP },
|
||||||
{ "rerere", cmd_rerere, RUN_SETUP },
|
{ "rerere", cmd_rerere, RUN_SETUP },
|
||||||
{ "reset", cmd_reset, RUN_SETUP },
|
{ "reset", cmd_reset, RUN_SETUP },
|
||||||
|
{ "restore", cmd_restore, RUN_SETUP | NEED_WORK_TREE },
|
||||||
{ "rev-list", cmd_rev_list, RUN_SETUP | NO_PARSEOPT },
|
{ "rev-list", cmd_rev_list, RUN_SETUP | NO_PARSEOPT },
|
||||||
{ "rev-parse", cmd_rev_parse, NO_PARSEOPT },
|
{ "rev-parse", cmd_rev_parse, NO_PARSEOPT },
|
||||||
{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
|
{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
|
||||||
|
Loading…
Reference in New Issue
Block a user