Git 中文参考(二)

2024-06-26 14:07:29 浏览数 (1)

原文:Git Reference 协议:CC BY-NC-SA 4.0

git-help

原文: git-scm.com/docs/git-help 贡献者:honglyua

名称

git-help - 显示有关 Git 的帮助信息

概要

代码语言:javascript复制
git help [-a|--all [--[no-]verbose]] [-g|--guide]
	   [-i|--info|-m|--man|-w|--web] [COMMAND|GUIDE]

描述

如果没有选项,也没有给出 COMMAND 或 GUIDE,则 git 命令的概要和最常用的 Git 命令列表将打印在标准输出上。

如果给出选项--all-a,则所有可用命令都将打印在标准输出上。

如果给出选项--guide-g,则标准输出上也会打印有用的 Git 指南列表。

如果给出了命令或指南,则会显示该命令或指南的手册页。默认情况下, man 程序用于此目的,但这可以被其他选项或配置变量覆盖。

如果给出了别名,git 会在标准输出上显示别名的定义。要获取别名命令的手册页,请使用git COMMAND --help

请注意,git --help ...git help ...相同,因为前者在内部转换为后者。

要显示 git [1] 手册页,请使用git help git

可以使用 git help helpgit help --help显示此页面

选项

代码语言:javascript复制
 -a 
代码语言:javascript复制
 --all 

在标准输出上打印所有可用命令。此选项会覆盖任何给定的命令或指南名称。

代码语言:javascript复制
 --verbose 

--all打印描述一起使用时,用于所有已识别的命令。这是默认值。

代码语言:javascript复制
 -c 
代码语言:javascript复制
 --config 

列出所有可用的配置变量。这是 git-config [1] 中列表的简短摘要。

代码语言:javascript复制
 -g 
代码语言:javascript复制
 --guides 

在标准输出上打印有用指南列表。此选项会覆盖任何给定的命令或指南名称。

代码语言:javascript复制
 -i 
代码语言:javascript复制
 --info 

info 格式显示命令的手册页。 info 程序将用于此目的。

代码语言:javascript复制
 -m 
代码语言:javascript复制
 --man 

man 格式显示命令的手册页。此选项可用于覆盖help.format配置变量中设置的值。

默认情况下, man 程序将用于显示手册页,但man.viewer配置变量可用于选择其他显示程序(见下文)。

代码语言:javascript复制
 -w 
代码语言:javascript复制
 --web 

Web (HTML)格式显示命令的手册页。 Web 浏览器将用于此目的。

如果未设置前者,可以使用配置变量help.browserweb.browser指定 Web 浏览器。如果没有设置这些配置变量, git web{litdd}browse 帮助程序脚本(由 git help 调用)将选择合适的默认值。有关详细信息,请参阅 git-web {litdd}浏览[1] 。

配置变量

help.format

如果未传递命令行选项,则将检查help.format配置变量。此变量支持以下值;他们使 git help 的行为与其对应的命令行选项相同:

  • “man”对应于 -m | --man
  • “info”对应 -i | --info
  • “web”或“html”对应于 -w | --web
help.browser,web.browser 和 browser..path

如果选择 web 格式(通过命令行选项或配置变量),也将检查help.browserweb.browserbrowser.<tool>.path。参见上面 OPTIONS 部分的 -w | --web 和 git-web {litdd}浏览[1] 。

man.viewer

如果选择 man 格式,将检查man.viewer配置变量。目前支持以下值:

  • “man”:像往常一样使用 man 程序,
  • “woman”:使用 emacsclient 在 emacs 中启动“woman”模式(这只适用于 emacsclient 版本 22),
  • “konqueror”:使用 kfmclient 在新的 konqueror 标签中打开手册页(参见下面的 _ 关于 konqueror_ 的注释)。

如果存在相应的man.<tool>.cmd配置条目(参见下文),则可以使用其他工具的值。

可以为man.viewer配置变量赋予多个值。将按配置文件中列出的顺序尝试相应的程序。

例如,这个配置:

代码语言:javascript复制
	[man]
		viewer = konqueror
		viewer = woman

将首先尝试使用 konqueror。但这可能会失败(例如,如果没有设置 DISPLAY),那么将尝试 emacs 的 woman 模式。

如果一切都失败,或者没有配置查看器,将尝试在GIT_MAN_VIEWER环境变量中指定的查看器。如果那也失败了,无论如何都会尝试 man 程序。

man..path

您可以通过设置配置变量man.<tool>.path显式提供首选人员查看器的完整路径。例如,您可以通过设置 man.konqueror.path 来配置 konqueror 的绝对路径。否则, git help 假定该工具在 PATH 中可用。

man..cmd

man.viewer配置变量指定的 man 查看器不在支持的那个中时,将查找相应的man.<tool>.cmd配置变量。如果此变量存在,则指定的工具将被视为自定义命令,并且将使用 shell eval 运行命令,并将手册页作为参数传递。

关于 konqueror 的注意事项

当在man.viewer配置变量中指定 konqueror 时,我们启动 kfmclient 以尝试在新选项卡中打开已打开的 konqueror 的手册页(如果可能)。

为了保持一致性,如果将 man.konqueror.path 设置为 A_PATH_TO/konqueror,我们也会尝试这样的技巧。这意味着我们将尝试启动 A_PATH_TO/kfmclient

如果你真的想使用 konqueror ,那么你可以使用如下内容:

代码语言:javascript复制
	[man]
		viewer = konq

	[man "konq"]
		cmd = A_PATH_TO/konqueror
关于 git config --global 的注意事项

请注意,可能应使用--global标志设置所​​有这些配置变量,例如:

代码语言:javascript复制
$ git config --global help.format web
$ git config --global web.browser firefox

因为它们可能比特定于存储库更具用户特性。有关此内容的详细信息,请参阅 git-config [1] 。

GIT

部分 git [1] 套件

git-init

原文: git-scm.com/docs/git-init 贡献者:honglyua

名称

git-init - 创建一个空的 Git 存储库或重新初始化现有存储库

概要

代码语言:javascript复制
git init [-q | --quiet] [--bare] [--template=<template_directory>]
	  [--separate-git-dir <git dir>]
	  [--shared[=<permissions>]] [directory]

描述

此命令创建一个空的 Git 存储库 - 基本上是一个.git目录,其中包含objectsrefs/headsrefs/tags和模板文件的子目录。还创建了引用主分支 HEAD 的初始HEAD文件。

如果设置了$GIT_DIR环境变量,则它指定要使用的路径而不是./.git作为存储库的基础。

如果通过GIT_OBJECT_DIRECTORY环境变量指定了对象存储目录,则在下面创建 sha1 目录 - 否则使用默认的GIT_DIR/objects目录。

在现有存储库中运行 git init 是安全的。它不会覆盖已存在的东西。重新运行 git init 的主要原因是获取新添加的模板(或者如果给出了–separate-git-dir,则将存储库移动到另一个地方)。

选项

代码语言:javascript复制
 -q 
代码语言:javascript复制
 --quiet 

仅打印错误和警告消息;所有其他输出都将被抑制。

代码语言:javascript复制
 --bare 

创建一个裸存储库。如果未设置GIT_DIR环境,则将其设置为当前工作目录。

代码语言:javascript复制
 --template=<template_directory> 

指定将使用模板的目录。 (参见下面的“模板目录”部分。)

代码语言:javascript复制
 --separate-git-dir=<git dir> 

不是将存储库初始化为$GIT_DIR./.git/的目录,而是在其中创建包含实际存储库路径的文本文件。此文件充当与文件系统无关的 Git 符号链接到存储库。

如果这是重新初始化,则存储库将移动到指定的路径。

代码语言:javascript复制
 --shared[=(false|true|umask|group|all|world|everybody|0xxx)] 

指定要在多个用户之间共享 Git 存储库。这允许属于同一组的用户进入该存储库。指定时,将设置配置变量“core.sharedRepository”,以便使用请求的权限创建$GIT_DIR下的文件和目录。未指定时,Git 将使用 umask(2)报告的权限。

该选项可以具有以下值,如果没有给出值,则默认为 group

代码语言:javascript复制
 umask (or false) 

使用 umask(2)报告的权限。未指定--shared时,使用默认值。

代码语言:javascript复制
 group (or true) 

使存储库可写,(和 g sx,因为 git group 可能不是所有用户的主要组)。这用于放宽其他安全的 umask(2)值的权限。请注意,umask 仍然适用于其他权限位(例如,如果 umask 是 0022 ,则使用 group 将不会删除其他(非组)用户的读取权限)。有关如何准确指定存储库权限的信息,请参见 0xxx

代码语言:javascript复制
 all (or world or everybody) 

group 相同,但使所有用户都可以读取存储库。

代码语言:javascript复制
 0xxx 

0xxx 是一个八进制数,每个文件都有模式 0xxx0xxx 将覆盖用户的 umask(2)值(并且不仅松开 groupall 的权限)。 0640 将创建一个可读取组的存储库,但不能写入组或其他人可访问的存储库。 0660 将创建一个对当前用户和组可读写的 repo,但其他人无法访问。

默认情况下,配置标志receive.denyNonFastForwards在共享存储库中启用,因此您无法强制执行非快进推送。

如果您提供 _ 目录 _,则命令在其中运行。如果此目录不存在,则将创建该目录。

模板目录

模板目录中名称不以点开头的文件和目录将在创建后复制到$GIT_DIR

模板目录将是以下之一(按顺序):

  • 使用--template选项给出的参数;
  • $GIT_TEMPLATE_DIR环境变量的内容;
  • init.templateDir配置变量;要么
  • 默认模板目录:/usr/share/git-core/templates

默认模板目录包括一些目录结构,建议“排除模式”(参见 gitignore [5] )和示例钩子文件。

默认情况下,示例钩子均已禁用。要启用其中一个示例钩子,请通过删除其.sample后缀来重命名它。

有关钩子执行的更多常规信息,请参见 githooks [5] 。

例子

代码语言:javascript复制
 基于存量代码,初始化一个新 git 库
代码语言:javascript复制
$ cd /path/to/my/codebase
$ git init      (1)
$ git add .     (2)
$ git commit    (3)
  1. 创建一个/path/to/my/codebase/.git 目录。
  2. 将所有现有文件添加到索引中。
  3. 将原始状态记录为历史记录中的第一个提交。

GIT

部分 git [1] 套件

git-clone

原文: git-scm.com/docs/git-clone 贡献者:honglyua

名称

git-clone - 将存储库克隆到新目录中

概要

代码语言:javascript复制
git clone [--template=<template_directory>]
	  [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
	  [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
	  [--dissociate] [--separate-git-dir <git dir>]
	  [--depth <depth>] [--[no-]single-branch] [--no-tags]
	  [--recurse-submodules[=<pathspec>]] [--[no-]shallow-submodules]
	  [--jobs <n>] [--] <repository> [<directory>]

描述

将存储库克隆到新创建的目录中,为克隆存储库中的每个分支创建远程跟踪分支(使用git branch -r可见),并创建并检出从克隆存储库的当前活动分支的初始分支。

在克隆之后,没有参数的普通git fetch将更新所有远程跟踪分支,并且没有参数的git pull将另外将远程主分支合并到当前主分支中(如果有"–single-branch“的话,见下文)。

通过在refs/remotes/origin下创建对远程分支头的引用并初始化remote.origin.urlremote.origin.fetch配置变量来实现此默认配置。

选项

代码语言:javascript复制
 --local 
代码语言:javascript复制
 -l 

当要克隆的存储库位于本地计算机上时,此标志会绕过正常的“Git 感知”传输机制,并通过制作 HEAD 以及对象和 refs 目录下的所有内容的副本来克隆存储库。 .git/objects/目录下的文件是硬链接的,以便在可能的情况下节省空间。

如果将存储库指定为本地路径(例如,/path/to/repo),则这是默认值,而–local 本质上是无操作。如果将存储库指定为 URL,则忽略此标志(并且我们从不使用本地优化)。当给出/path/to/repo时,指定--no-local将覆盖默认值,而是使用常规 Git 传输。

代码语言:javascript复制
 --no-hardlinks 

从本地文件系统上的存储库强制克隆进程,以复制.git/objects目录下的文件,而不是使用硬链接。如果您尝试备份存储库,则可能需要这样做。

代码语言:javascript复制
 --shared 
代码语言:javascript复制
 -s 

当要克隆的存储库位于本地计算机上而不是使用硬链接时,会自动设置.git/objects/info/alternates以与源存储库共享对象。生成的存储库在没有任何自己的对象的情况下开始。

:这可能是危险的操作;不要使用它,除非你明白它的作用。如果使用此选项克隆存储库,然后在源存储库中删除分支(或使用任何其他提交未引用的 Git 命令),则某些对象可能会变为未引用(或悬空)。这些对象可以通过自动调用git gc --auto的普通 Git 操作(例如git commit)删除。 (参见 git-gc [1] 。)如果这些对象被删除并被克隆的存储库引用,那么克隆的存储库将会损坏。

请注意,在使用-s克隆的存储库中运行没有-l选项的git repack会将源存储库中的对象复制到克隆存储库中的包中,从而节省clone -s的磁盘空间节省。但是,运行git gc是安全的,它默认使用-l选项。

如果要在其源存储库中中断使用-s克隆的存储库的依赖关系,只需运行git repack -a即可将源存储库中的所有对象复制到克隆存储库中的包中。

代码语言:javascript复制
 --reference[-if-able] <repository> 

如果引用存储库位于本地计算机上,则自动设置.git/objects/info/alternates以从引用存储库获取对象。使用现有存储库作为备用存储库,将需要从克隆的存储库中复制更少的对象,从而降低网络和本地存储成本。使用--reference-if-able时,将跳过不存在的目录,并显示警告而不是中止克隆。

:参见--shared选项的注释,以及--dissociate选项。

代码语言:javascript复制
 --dissociate 

借用--reference选项指定的引用存储库中的对象,仅减少网络传输,并在通过制作必要的借用对象本地副本进行克隆后停止从它们借用。当已经从另一个存储库借用对象的存储库本地克隆时,也可以使用此选项 - 新存储库将从同一存储库中借用对象,并且此选项可用于停止借用。

代码语言:javascript复制
 --quiet 
代码语言:javascript复制
 -q 

安静地操作。未向标准错误流报告进度。

代码语言:javascript复制
 --verbose 
代码语言:javascript复制
 -v 

详细地运行。不影响将进度状态报告给标准错误流。

代码语言:javascript复制
 --progress 

除非指定了-q,否则在将标准错误流附加到终端时,默认情况下会报告进度状态。即使标准错误流未定向到终端,此标志也会强制进度状态。

代码语言:javascript复制
 --no-checkout 
代码语言:javascript复制
 -n 

克隆完成后不会检查 HEAD。

代码语言:javascript复制
 --bare 

制作一个 bare Git 存储库。也就是说,不是创建<directory>并将管理文件放在<directory>/.git中,而是将<directory>本身设为$GIT_DIR。这显然意味着-n,因为无处可查看工作树。此外,远端上的分支头直接复制到相应的本地分支头,而不将它们映射到refs/remotes/origin/。使用此选项时,既不会创建远程跟踪分支,也不会创建相关的配置变量。

代码语言:javascript复制
 --mirror 

设置源存储库的镜像。这类似--bare。与--bare相比,--mirror不仅将源的本地分支映射到目标的本地分支,它还映射所有引用(包括远程跟踪分支,注释等)并设置 refspec 配置,以便所有这些引用被目标存储库中的git remote update覆盖。

代码语言:javascript复制
 --origin <name> 
代码语言:javascript复制
 -o <name> 

不使用远程名称origin来跟踪上游存储库,而是使用<name>

代码语言:javascript复制
 --branch <name> 
代码语言:javascript复制
 -b <name> 

而不是将新创建的 HEAD 指向克隆存储库的 HEAD 所指向的分支,而是指向<name>分支。在非裸存储库中,这是将要检出的分支。 --branch还可以在生成的存储库中的获取 tags 和分离 HEAD。

代码语言:javascript复制
 --upload-pack <upload-pack> 
代码语言:javascript复制
 -u <upload-pack> 

给定时,通过 ssh 访问要克隆的存储库,这将指定另一端运行的命令的非默认路径。

代码语言:javascript复制
 --template=<template_directory> 

指定将使用模板的目录; (参见 git-init [1] 的“TEMPLATE DIRECTORY”部分。)

代码语言:javascript复制
 --config <key>=<value> 
代码语言:javascript复制
 -c <key>=<value> 

在新创建的存储库中设置配置变量;这在初始化存储库之后,但在获取远程历史记录或检出任何文件之前立即生效。key 的格式与 git-config [1] (例如core.eol=true)的格式相同。如果为同一个键指定了多个值,则每个值都将写入配置文件。例如,这样就可以安全地向源远程添加额外的 fetch refspec。

由于当前实现的限制,一些配置变量在初始提取和检出之后才会生效。已知未生效的配置变量为:remote.<name>.mirrorremote.<name>.tagOpt。请改用相应的--mirror--no-tags选项。

代码语言:javascript复制
 --depth <depth> 

创建一个 _ 浅 _ 克隆,其历史记录被截断为指定的提交次数。除非--no-single-branch用于获取所有分支的提示附近的历史,否则意味着--single-branch。如果要浅层克隆子模块,也要传递--shallow-submodules

代码语言:javascript复制
 --shallow-since=<date> 

在指定时间后创建具有历史记录的浅层克隆。

代码语言:javascript复制
 --shallow-exclude=<revision> 

创建具有历史记录的浅层克隆,不包括可从指定的远程分支或标记访问的提交。可以多次指定此选项。

代码语言:javascript复制
 --[no-]single-branch 

仅克隆导致单个分支尖端的历史记录,由--branch选项指定或主分支远程的HEAD指向。进一步提取到生成的存储库只会更新分支的远程跟踪分支,此选项用于初始克隆。如果在进行--single-branch克隆时远程处的 HEAD 未指向任何分支,则不会创建远程跟踪分支。

代码语言:javascript复制
 --no-tags 

不要克隆任何标签,并在配置中设置remote.<remote>.tagOpt=--no-tags,确保将来的git pullgit fetch操作不会跟随任何标签。后续显式标记提取仍然有效(参见 git-fetch [1] )。

可以与--single-branch一起使用来克隆和维护一个除了单个克隆分支之外没有引用的分支。这很有用,例如维护某些存储库的默认分支的最小克隆以进行搜索索引。

代码语言:javascript复制
 --recurse-submodules[=<pathspec] 

创建克隆后,根据提供的 pathspec 初始化和克隆子模块。如果未提供 pathspec,则初始化并克隆所有子模块。对于包含多个条目的 pathspec,可以多次给出此选项。生成的克隆将submodule.active设置为提供的 pathspec,或“.” (如果没有提供 pathspec,则表示所有子模块)。

子模块使用其默认设置进行初始化和克隆。这相当于克隆完成后立即运行git submodule update --init --recursive <pathspec>。如果克隆的存储库没有工作树/检出(即,如果给出--no-checkout / -n--bare--mirror中的任何一个),则忽略此选项

代码语言:javascript复制
 --[no-]shallow-submodules 

克隆的所有子模块都是浅的,深度为 1。

代码语言:javascript复制
 --separate-git-dir=<git dir> 

不要将克隆的存储库放在应该位于的位置,而是将克隆的存储库放在指定的目录中,然后创建与文件系统无关的 Git 符号链接。结果是 Git 存储库可以与工作树分开。

代码语言:javascript复制
 -j <n> 
代码语言:javascript复制
 --jobs <n> 

同时获取的子模块数。默认为submodule.fetchJobs选项。

代码语言:javascript复制
 <repository> 

要从中克隆的(可能是远程的)存储库。有关指定存储库的更多信息,请参见下面的 GIT URL 部分。

代码语言:javascript复制
 <directory> 

要克隆到的新目录的名称。如果没有明确给出目录(/path/to/repo.git/path/to/repo.githost.xz:foo/.gitfoo),则使用源存储库的“人性化”部分。仅当目录为空时才允许克隆到现有目录中。

GIT 网址

通常,URL 包含有关传输协议,远程服务器的地址以及存储库路径的信息。根据传输协议,可能缺少某些信息。

Git 支持 ssh,git,http 和 https 协议(此外,ftp 和 ftps 可用于获取,但这是低效的并且已弃用;请勿使用它)。

本机传输(即 git:// URL)不进行身份验证,应在不安全的网络上谨慎使用。

可以使用以下语法:

  • SSH:// [用户@] host.xz [:端口] /path/to/repo.git/
  • GIT 中://host.xz [:端口] /path/to/repo.git/
  • HTTP [S]://host.xz [:端口] /path/to/repo.git/
  • FTP [S]://host.xz [:端口] /path/to/repo.git/

另一种类似 scp 的语法也可以与 ssh 协议一起使用:

  • [用户@] host.xz:path/to/ repo.git /

只有在第一个冒号之前没有斜杠时才会识别此语法。这有助于区分包含冒号的本地路径。例如,本地路径foo:bar可以指定为绝对路径或./foo:bar,以避免被误解为 ssh url。

ssh 和 git 协议还支持〜用户名扩展:

  • SSH:// [用户@] host.xz [:端口] /〜[用户] /path/to/repo.git/
  • GIT 中://host.xz [:端口] /〜[用户] /path/to/repo.git/
  • [用户@] host.xz:/〜[用户] /path/to/repo.git/

对于本地也受 Git 支持的本地存储库,可以使用以下语法:

  • /path/to/repo.git/
  • 文件:///path/to/repo.git/

这两种语法大多是等价的,除了前者暗示–local 选项。

当 Git 不知道如何处理某种传输协议时,它会尝试使用 remote- 远程助手,如果存在的话。要显式请求远程帮助程序,可以使用以下语法:

  • ::

其中

可以是路径,服务器,或者由被调用的特定远程助手识别的任意类似 URL 的字符串。有关详细信息,请参阅 gitremote-helpers [1] 。

如果存在大量具有相似名称的远程存储库,并且您希望为它们使用不同的格式(以便将您使用的 URL 重写为有效的 URL),则可以创建表单的配置部分:

代码语言:javascript复制
	[url "<actual url base>"]
		insteadOf = <other url base>

例如,有了这个:

代码语言:javascript复制
	[url "git://git.host.xz/"]
		insteadOf = host.xz:/path/to/
		insteadOf = work:

像“work:repo.git”这样的 URL 或类似“host.xz:/path/to/repo.git”的 URL 将在任何带有 URL 的上下文中被重写为“git://git.host.xz/repo.git”。

如果要为仅推送重写 URL,可以创建表单的配置部分:

代码语言:javascript复制
	[url "<actual url base>"]
		pushInsteadOf = <other url base>

例如,有了这个:

代码语言:javascript复制
	[url "ssh://example.org/"]
		pushInsteadOf = git://example.org/

像“git://example.org/path/to/repo.git”这样的网址将被重写为“ssh://example.org/path/to/repo.git”以进行推送,但是 pull 仍会使用原始网址。

例子

从上游克隆:

代码语言:javascript复制
$ git clone git://git.kernel.org/pub/scm/.../linux.git my-linux
$ cd my-linux
$ make

创建一个从当前目录借用的本地克隆,而不检查:

代码语言:javascript复制
$ git clone -l -s -n . ../copy
$ cd ../copy
$ git show-branch

从现有本地目录借用时从上游克隆:

代码语言:javascript复制
$ git clone --reference /git/linux.git 
	git://git.kernel.org/pub/scm/.../linux.git 
	my-linux
$ cd my-linux

创建一个裸存储库以将更改发布到公共:

代码语言:javascript复制
$ git clone --bare -l /home/proj/.git /pub/scm/proj.git

GIT

部分 git [1] 套件

git-add

原文: git-scm.com/docs/git-add 贡献者:yulezheng

名称

git-add - 将文件内容添加到暂存区(stage,或者叫 index)中

概要

代码语言:javascript复制
git add [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p]
	  [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]
	  [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing] [--renormalize]
	  [--chmod=( |-)x] [--] [<pathspec>…​]

描述

此命令使用工作树中当前的内容更新暂存区,为下一次提交(commit)暂存内容。它通常将现有路径的当前内容作为一个整体添加,但是通过一些选项,它还可以用于添加仅部分对于工作树的修改被应用的内容,或者删除工作树中不再存在的路径。

暂存区保存工作树内容的快照,并将此快照作为下一次提交(commit)的内容。因此,在对工作树进行任何更改之后,在运行 commit 命令之前,必须使用add命令将新的文件或有改动的文件添加到暂存区中。

在提交(commit)之前可以多次执行此命令。它只添加指定文件在 add 命令运行时刻的内容;如果您希望下次提交(commit)中包含后续更改,则必须再次运行git add以将新内容添加到暂存区中。

git status命令可用于列出改动被放入暂存区但还未提交的文件。

默认情况下,git add命令不会添加忽略的文件。如果在命令行中显式指定了任何忽略的文件,则git add将运行失败并且显示出忽略文件的列表。由 Git 执行的目录递归或文件名通配所覆盖到的忽略文件将被默认忽略。 git add 命令可使用-f(force)选项添加被忽略的文件。

有关将内容添加到提交(commit)的其他方法,请参阅 git-commit [1] 。

选项

代码语言:javascript复制
 <pathspec>… 

要添加内容的文件。可以用文件名通配符(例如*.c)来添加所有匹配的文件。还可以给出一个主目录名称(例如用dir添加dir/file1dir/file2),将整个目录的当前状态作为一个主体来更新暂存区(例如,指定dir将不仅记录工作树中修改了文件dir/file1,添加了文件dir/file2,还会记录删除了文件dir/file3)。请注意,旧版本的 Git 默认忽略已删除的文件;如果要添加已修改或新增的文件但忽略已删除的文件,请使用--no-all选项。

有关< pathspec>的详细信息,请参阅 gitglossary [7] 中的 pathspec 条目。

代码语言:javascript复制
 -n 
代码语言:javascript复制
 --dry-run 

实际上不添加文件(至暂存区),只显示文件是否存在和/或被忽略。

代码语言:javascript复制
 -v 
代码语言:javascript复制
 --verbose 

列出详细信息。

代码语言:javascript复制
 -f 
代码语言:javascript复制
 --force 

允许强制添加忽略的文件。

代码语言:javascript复制
 -i 
代码语言:javascript复制
 --interactive 

将工作树中被修改的内容以交互方式添加到暂存区中。提供可选的路径参数以将操作限制于工作树的一个子集中。详细信息请参阅“交互模式”。

代码语言:javascript复制
 -p 
代码语言:javascript复制
 --patch 

以交互方式选择暂存区和工作树之间的修改,并将它们添加到暂存区中。这使用户有机会在将修改后的内容添加到暂存区之前查看差异。

这实际上运行了add --interactive,但绕过初始命令菜单并直接跳转到patch子命令。详细信息请参阅“交互模式”。

代码语言:javascript复制
 -e 
代码语言:javascript复制
 --edit 

在编辑器中打开与暂存区不一致的内容,让用户编辑它。编辑器关闭后,调整代码块内容并将修改应用于暂存区。

此选项的目的是选择要应用哪些修改过的行,甚至修改要暂存的行的内容。这比使用交互式代码块选择器更快更灵活。但是,这很容易导致混淆从而产生不需要应用于暂存区的修改。参阅下面的 EDITING PATCHES。

代码语言:javascript复制
 -u 
代码语言:javascript复制
 --update 

只在已有的匹配< pathspec>的条目中更新暂存区。这将删除或修改暂存区条目以匹配工作树,但不添加新文件。

如果在使用-u选项时没有给出< pathspec>,将更新整个工作树中的所有跟踪文件(旧版本的 Git 将更新限定于当前目录及其子目录)。

代码语言:javascript复制
 -A 
代码语言:javascript复制
 --all 
代码语言:javascript复制
 --no-ignore-removal 

将工作树中匹配< pathspec>的文件和暂存区中已有的条目内容更新到暂存区。这将添加,修改和删除暂存区条目以匹配工作树。

如果在使用-A选项时没有给出< pathspec>,将更新当前工作树中的所有文件(旧版本的 Git 将更新限定于当前目录及其子目录)。

代码语言:javascript复制
 --no-all 
代码语言:javascript复制
 --ignore-removal 

通过添加暂存区没有的新文件和工作树中有修改的文件来更新暂存区,但忽略已从工作树中删除的文件。当没有< pathspec>时,此选项不起作用。

此选项主要用于帮助习惯了旧版本 Git 的用户,其“git add< pathspec> …”是“git add --no-all< pathspec> …”的同义词,即忽略已删除文件。

代码语言:javascript复制
 -N 
代码语言:javascript复制
 --intent-to-add 

仅记录稍后将添加路径的事实。路径的条目放在暂存区中,没有内容。除其他外,这对于使用git diff显示此类文件的未分级内容并使用git commit -a提交它们非常有用。

代码语言:javascript复制
 --refresh 

不添加文件,而只刷新它们在暂存区中的 stat()信息。

代码语言:javascript复制
 --ignore-errors 

如果由于索引错误而无法添加某些文件,不中止操作,而是继续添加其他文件。该命令仍将以非零状态退出。配置变量add.ignoreErrors可以设置为 true 以使其成为默认行为。

代码语言:javascript复制
 --ignore-missing 

此选项只能与–dry-run 一起使用。通过使用此选项,用户可以检查是否将忽略某些给定文件,无论它们是否已存在于工作树中。

代码语言:javascript复制
 --no-warn-embedded-repo 

默认情况下,若未使用git submodule add.gitmodules中创建条目时就向暂存区中添加嵌入式存储库,git add会发出警告。此选项将禁止警告(例如在子模块上手动执行操作)。

代码语言:javascript复制
 --renormalize 

对所有被跟踪的文件应用"clean"进程,以强制将它们再次添加到暂存区。在更改core.autocrlf配置或text属性以更正添加的文件中错误的 CRLF / LF 行结尾方式时,这很有用。该选项与-u同义。

代码语言:javascript复制
 --chmod=( |-)x 

覆盖被添加文件的可执行权限。可执行权限仅在暂存区中更改,磁盘上的文件保持不变。

代码语言:javascript复制
 -- 

此选项可用于将命令行选项与文件列表分开(当文件名可能被误认为是命令行选项时很有用)。

例子

添加Documentation目录及其子目录下所有*.txt文件的内容:

代码语言:javascript复制
$ git add Documentation/*.txt

请注意,在此示例中,使用了星号*;这使命令包含来自Documentation/子目录的文件。

从所有 git - * .sh 脚本添加内容:

代码语言:javascript复制
$ git add git-*.sh

因为这个例子除了星号还补充了其他条件(即明确地列出了文件),所以它不包括subdir/git-foo.sh

交互模式

当命令进入交互模式时,它显示 _ 状态 _ 子命令的输出,然后进入其交互式命令循环。

命令循环显示可用的子命令列表,并给出提示“What now>”。通常,当提示以单个 _>结束时 ,您只能选择输入给定的一个选项,如下所示:

代码语言:javascript复制
    *** Commands ***
      1: status       2: update       3: revert       4: add untracked
      5: patch        6: diff         7: quit         8: help
    What now> 1

如果符合的选项是唯一的,您也可以输入sstastatus

主命令循环有 6 个子命令(加上帮助和退出)。

代码语言:javascript复制
 status 

运行这条命令将显示每个路径中 HEAD 和暂存区之间的变化(即,如果此时git commit将会提交什么),以及暂存区和工作树文件之间的变化(即你在git commit之前可以使用git add暂存什么)。示例输出如下所示:

代码语言:javascript复制
              staged     unstaged path
     1:       binary      nothing foo.png
     2:      403/-35         1/-1 git-add--interactive.perl

它表明 foo.png 与 HEAD 有区别(但是文件为二进制因此无法显示行数)并且暂存区副本和工作树版本之间没有区别(如果工作树版本也存在不同,显示的就不是nothing而是binary)。另一个文件 git-add {litdd} interactive.perl,如果你提交了暂存区中的内容,则添加了 403 行并删除了 35 行,但工作树文件中仍有进一步修改(一次添加和一次删除)。

代码语言:javascript复制
 update 

这会显示状态信息并发出“Update>>”提示。当提示以 double >>结束时,您可以进行多个选择,用空格或逗号连接。你也可以选择范围,例如,“2-5 7,9”表示从列表中选择 2,3,4,5,7,9。如果省略范围中的第二个数字,则选中第一个数字之后的所有选项。例如。 “7-”从列表中选择 7,8,9。你可以用 * 来选择所有。

您选中的内容将用 * 标志,如下所示:

代码语言:javascript复制
           staged     unstaged path
  1:       binary      nothing foo.png
* 2:      403/-35         1/-1 git-add--interactive.perl

要删除选择,在输入的选项前添加-,如下所示:

代码语言:javascript复制
Update>> -2

完成选择后,输入空行以暂存选中路径在工作树中的内容到暂存区中。

代码语言:javascript复制
 revert 

这与 update 具有非常相似的 UI,所选路径的暂存信息被恢复为 HEAD 版本的信息。恢复新路径将使它们不被跟踪。

代码语言:javascript复制
 add untracked 

这与 updaterevert 具有非常相似的 UI,并允许您向暂存区添加未跟踪的路径。

代码语言:javascript复制
 patch 

这使您可以像选择器一样选择 status 中的一个路径。选择路径后,它会显示暂存区和工作树文件之间的差异,并询问您是否要暂存各个部分的变动。您可以选择以下选项之一并键入 return:

代码语言:javascript复制
y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help

在对所有部分进行选择之后,如果有任何部分被选中,则将所选的部分更新到暂存区。

通过将配置变量interactive.singleKey设置为true,即可不必在此处键入 return。

代码语言:javascript复制
 diff 

此命令可以查看将要提交的内容(即 HEAD 和暂存区之间)。

编辑补丁

调用git add -e或从交互式块选择器中选择e,将在编辑器中打开补丁;退出编辑器后,结果将应用于暂存区。您可以随意对修补程序进行任意更改,但请注意,某些更改可能会导致令人困惑的结果,甚至会产生无法应用的修补程序。如果要完全中止操作(即,在暂存区中不做任何更新),只需删除修补程序的所有行。以下内容列出了您可能在修补程序中看到的一些常见内容,以及哪些编辑操作对它们有意义。

代码语言:javascript复制
 added content 

添加的内容由以“ ”开头的行表示。您可以通过删除它们来阻止暂存任何添加行。

代码语言:javascript复制
 removed content 

删除的内容由以“ - ”开头的行表示。您可以通过将“ - ”转换为“ ”(空格)来阻止删除它们。

代码语言:javascript复制
 modified content 

修改后的内容由“ - ”行(删除旧内容)后跟“ ”行(添加替换内容)表示。您可以通过将“ - ”行转换为“ ”并删除“ ”行来阻止暂存修改。请注意,仅修改其中的一半可能会引入异常的更改到暂存区。

还可以执行更复杂的操作。但要注意,因为补丁仅应用于暂存区而不是工作树,所以工作树将不执行索引中的更改。例如,向暂存区中引入的 HEAD 和工作树中都不存在的新行将作用于 commit(提交),但该行将在工作树中还原。

需要避免或非常谨慎地使用这些结构。

代码语言:javascript复制
 removing untouched content 

索引和工作树之间没有差异的内容可以在上下文行中显示,以“ ”(空格)开头。您可以通过将空格转换为“ - ”来删除上下文行。生成的工作树文件将重新添加这些内容。

代码语言:javascript复制
 modifying existing content 

还可以通过删除(将“ ”转换为“ - ”)和添加添加新内容到“ ”行来修改上下文行。类似地,可以修改“ ”行以用于现有的添加或修改。在所有情况下,新修改将在工作树中还原。

代码语言:javascript复制
 new content 

您还可以添加补丁中不存在的新内容;只需添加新行,每行以“ ”开头。添加将在工作树中还原。

还有一些操作应该完全避免,因为它们会使补丁无法应用:

  • 添加上下文(“ ”)或删除(“ - ”)行
  • 删除上下文或删除行
  • 修改上下文或删除行的内容

也可以看看

git-status [1] git-rm [1] git-reset [1] git-mv [1] git-commit [1] git-update-index [1]

GIT

部分 git [1] 套件

git-status

原文: git-scm.com/docs/git-status 贡献者:honglyua

名称

git-status - 显示工作树状态

概要

代码语言:javascript复制
git status [<options>…​] [--] [<pathspec>…​]

描述

显示索引文件与当前 HEAD 提交之间存在差异的路径,工作树与索引文件之间存在差异的路径,以及工作树中未由 Git 跟踪的路径(和不会被gitignore[5]忽略的路径 )。第一个显示的是你 _ 将 _ 通过运行git commit提交的内容;第二个和第三个显示的是你在运行git commit之前运行 git add 来提交的内容。

选项

代码语言:javascript复制
 -s 
代码语言:javascript复制
 --short 

以短格式输出。

代码语言:javascript复制
 -b 
代码语言:javascript复制
 --branch 

显示分支和跟踪信息,即使是在短格式下。

代码语言:javascript复制
 --show-stash 

显示当前隐藏的条目数。

代码语言:javascript复制
 --porcelain[=<version>] 

以易于解析的格式为脚本提供输出。这类似于短输出,但在 Git 版本中保持稳定,无论用户配置如何。请参阅下文了解详情。

version 参数用于指定格式版本。这是可选的,默认为原始版本 v1 格式。

代码语言:javascript复制
 --long 

以长格式输出。这是默认值。

代码语言:javascript复制
 -v 
代码语言:javascript复制
 --verbose 

除了已更改的文件的名称之外,还显示要提交的文本更改(即,类似于git diff --cached的输出)。如果指定-v两次,则还显示工作树中尚未暂存的更改(即,类似于git diff的输出)。

代码语言:javascript复制
 -u[<mode>] 
代码语言:javascript复制
 --untracked-files[=<mode>] 

显示未跟踪的文件。

mode 参数用于指定未跟踪文件的处理。它是可选的:它默认为 all,如果指定,它必须紧跟在选项上(例如-uno,但不是-u no)。

可能的选择是:

  • no - 显示没有未跟踪的文件。
  • normal - 显示未跟踪的文件和目录。
  • all - 还显示未跟踪目录中的单个文件。

如果未使用-u选项,则会显示未跟踪的文件和目录(即与指定normal相同),以帮助您避免忘记添加新创建的文件。由于在文件系统中查找未跟踪文件需要额外的工作,因此在大型工作树中此模式可能需要一些时间。如果支持,请考虑启用未跟踪的缓存和拆分索引(请参阅git update-index --untracked-cachegit update-index --split-index),否则您可以使用nogit status更快地返回,而不显示未跟踪的文件。

可以使用 git-config [1] 中记录的 status.showUntrackedFiles 配置变量更改默认值。

代码语言:javascript复制
 --ignore-submodules[=<when>] 

在查找更改时忽略对子模块的更改。可以是“none”,“untracked”,“dirty”或“all”,这些都是默认值。使用“none”时,如果子模块包含未跟踪或修改的文件,或者其 HEAD 与超级项目中记录的提交不同,则可以使用“none”来修改子模块,并可用于覆盖git-config [1] 或 gitmodules [5]中都 ignore 选项的任何设置。当使用“untracked”时,如果子模块仅包含未跟踪的内容(但仍会扫描修改的内容),则子模块不会被视为 dirty。使用“dirty”忽略对子模块工作树的所有更改,仅显示存储在超级项目中的提交的更改(这是 1.7.0 之前的行为)。使用“all”隐藏对子模块的所有更改(并在设置配置选项status.submoduleSummary时禁止子模块摘要的输出)。

代码语言:javascript复制
 --ignored[=<mode>] 

同时显示被忽略的文件。

mode 参数用于指定忽略文件的处理。它是可选的:它默认为 traditional

可能的选择是:

  • traditional - 显示被忽略的文件和目录,除非指定了–untracked-files = all,在这种情况下,将显示被忽略目录中的单个文件。
  • no - 显示没有被忽略的文件。
  • matching - 显示与忽略模式匹配的被忽略的文件和目录。

当指定 matching 模式时,将显示与忽略模式明确匹配的路径。如果目录与忽略模式匹配,则会显示该目录,但不会显示忽略目录中包含的路径。如果目录与忽略模式不匹配,但忽略了所有内容,则不显示该目录,但会显示所有内容。

代码语言:javascript复制
 -z 

用 NUL 而不是 LF 终止条目。如果没有给出其他格式,这意味着--porcelain=v1输出格式。

代码语言:javascript复制
 --column[=<options>] 
代码语言:javascript复制
 --no-column 

在列中显示未跟踪的文件。有关选项语法,请参阅配置变量 column.status。没有选项的--column--no-column分别相当于 alwaysnever

代码语言:javascript复制
 --ahead-behind 
代码语言:javascript复制
 --no-ahead-behind 

显示或不显示分支相对于其上游分支领先或落后多少节点数。默认为 true。

代码语言:javascript复制
 --renames 
代码语言:javascript复制
 --no-renames 

无论用户配置如何,都可以打开/关闭重命名检测。另见 git-diff [1] --no-renames

代码语言:javascript复制
 --find-renames[=<n>] 

打开重命名检测,可选择设置相似性阈值。另见 git-diff [1] --find-renames

代码语言:javascript复制
 <pathspec>…​ 

参见 gitglossary [7] 中的 pathspec 条目。

输出

此命令的输出旨在用作提交模板注释。默认的长格式设计很人性化,易读,详细和可描述性。其内容和输出格式随时可更改。

与许多其他 Git 命令不同,输出中提到的路径是相对于当前目录的,如果您在子目录中工作(这是故意的,以帮助剪切和粘贴)。请参阅下面的 status.relativePaths 配置选项。

短格式

在短格式中,每个路径的状态显示为这些形式之一

代码语言:javascript复制
XY PATH
XY ORIG_PATH -> PATH

其中ORIG_PATH是重命名/复制内容的来源。只有在重命名或复制条目时才会显示ORIG_PATHXY是一个双字母状态代码。

字段(包括->)通过单个空格彼此分开。如果文件名包含空格或其他不可打印的字符,则该字段将以 C 字符串文字的方式引用:由 ASCII 双引号(34)字符包围,并使用内部特殊字符反斜杠转义。

对于具有合并冲突的路径,XY显示合并每一侧的修改状态。对于没有合并冲突的路径,X显示索引的状态,Y显示工作树的状态。对于未跟踪路径,XY??。其他状态代码可以解释如下:

  • ‘’ =未经修改
  • M =修改
  • A =已添加
  • D =已删除
  • R =重命名
  • C =复制
  • U =已更新但未合并

除非--ignored选项生效,否则不会列出忽略的文件,在这种情况下,XY!!

代码语言:javascript复制
X          Y     Meaning
-------------------------------------------------
	 [AMD]   not updated
M        [ MD]   updated in index
A        [ MD]   added to index
D                deleted from index
R        [ MD]   renamed in index
C        [ MD]   copied in index
[MARC]           index and work tree matches
[ MARC]     M    work tree changed since index
[ MARC]     D    deleted in work tree
[ D]        R    renamed in work tree
[ D]        C    copied in work tree
-------------------------------------------------
D           D    unmerged, both deleted
A           U    unmerged, added by us
U           D    unmerged, deleted by them
U           A    unmerged, added by them
D           U    unmerged, deleted by us
A           A    unmerged, both added
U           U    unmerged, both modified
-------------------------------------------------
?           ?    untracked
!           !    ignored
-------------------------------------------------

子模块具有更多状态,但是不报告 M 子模块具有不同的 HEAD,而是在子模块已修改内容的索引中记录?子模块具有未跟踪的文件,因为子模块中的修改内容或未跟踪文件无法通过超级项目中的git add添加以准备提交。

m 递归应用。例如,如果子模块中的嵌套子模块包含未跟踪的文件,则报告为 也是如此。

如果使用-b,则短格式状态前面有一行

代码语言:javascript复制
## branchname tracking info
Porcelain 格式版本 1

版本 1 中 porcelain 格式类似于短格式,但保证不会在 Git 版本之间以向后兼容的方式或基于用户配置进行更改。这使其成为脚本解析的理想选择。上面简短格式的描述也描述了 porcelain 格式,但有一些例外:

  1. 用户的 color.status 配置不受认可;颜色永远都会关闭。
  2. 用户的 status.relativePaths 配置不受认可;显示的路径始终相对于存储库根目录。

还有一种备用-z 格式建议用于机器解析。在该格式中,状态字段是相同的,但其他一些事情会发生变化。首先,-> 从重命名条目中省略, 并且字段顺序被反转(例如,from -> 到变为 from)。其次,NUL(ASCII 0)跟在每个文件名后面,将空格替换为字段分隔符和终止换行符(但空格仍然将状态字段与第一个文件名分开)。第三,包含特殊字符的文件名不是特殊格式的;不执行引用或反斜杠转义。

任何子模块更改都会报告为已修改M而不是m或单个?

Porcelain 格式版本 2

版本 2 格式添加了有关工作树状态和更改项目的更多详细信息。版本 2 还定义了一组易于解析的可扩展可选标头。

标题行以“#”开头,​​并添加以响应特定的命令行参数。解析器应该忽略它们无法识别的标头。

分支标题

如果给出--branch,则打印一系列标题行,其中包含有关当前分支的信息。

代码语言:javascript复制
Line                                     Notes
------------------------------------------------------------
# branch.oid <commit> | (initial)        Current commit.
# branch.head <branch> | (detached)      Current branch.
# branch.upstream <upstream_branch>      If upstream is set.
# branch.ab  <ahead> -<behind>           If upstream is set and
					 the commit is present.
------------------------------------------------------------
跟踪条目修改

在标题之后,为跟踪的条目打印一系列行。可以根据变化的类型在三种不同线格式中的选择一种来描述条目。跟踪的条目以未定义的顺序打印;解析器应允许以任何顺序混合使用 3 种线型。

普通更改的条目具有以下格式:

代码语言:javascript复制
1 <XY> <sub> <mH> <mI> <mW> <hH> <hI> <path>

重命名或复制的条目具有以下格式:

代码语言:javascript复制
2 <XY> <sub> <mH> <mI> <mW> <hH> <hI> <X><score> <path><sep><origPath>
代码语言:javascript复制
Field       Meaning
--------------------------------------------------------
<XY>        A 2 character field containing the staged and
	    unstaged XY values described in the short format,
	    with unchanged indicated by a "." rather than
	    a space.
<sub>       A 4 character field describing the submodule state.
	    "N..." when the entry is not a submodule.
	    "S<c><m><u>" when the entry is a submodule.
	    <c> is "C" if the commit changed; otherwise ".".
	    <m> is "M" if it has tracked changes; otherwise ".".
	    <u> is "U" if there are untracked changes; otherwise ".".
<mH>        The octal file mode in HEAD.
<mI>        The octal file mode in the index.
<mW>        The octal file mode in the worktree.
<hH>        The object name in HEAD.
<hI>        The object name in the index.
<X><score>  The rename or copy score (denoting the percentage
	    of similarity between the source and target of the
	    move or copy). For example "R100" or "C75".
<path>      The pathname.  In a renamed/copied entry, this
	    is the target path.
<sep>       When the `-z` option is used, the 2 pathnames are separated
	    with a NUL (ASCII 0x00) byte; otherwise, a tab (ASCII 0x09)
	    byte separates them.
<origPath>  The pathname in the commit at HEAD or in the index.
	    This is only present in a renamed/copied entry, and
	    tells where the renamed/copied contents came from.
--------------------------------------------------------

未合并的条目具有以下格式;第一个字符是“u”,用于区分普通的更改条目。

代码语言:javascript复制
u <xy> <sub> <m1> <m2> <m3> <mW> <h1> <h2> <h3> <path>
代码语言:javascript复制
Field       Meaning
--------------------------------------------------------
<XY>        A 2 character field describing the conflict type
	    as described in the short format.
<sub>       A 4 character field describing the submodule state
	    as described above.
<m1>        The octal file mode in stage 1.
<m2>        The octal file mode in stage 2.
<m3>        The octal file mode in stage 3.
<mW>        The octal file mode in the worktree.
<h1>        The object name in stage 1.
<h2>        The object name in stage 2.
<h3>        The object name in stage 3.
<path>      The pathname.
--------------------------------------------------------
其他项目

跟踪条目(如果需要),将打印一系列未跟踪的行,然后忽略在工作树中找到的项目。

未跟踪的项目具有以下格式:

代码语言:javascript复制
? <path>

忽略的项目具有以下格式:

代码语言:javascript复制
! <path>
路径名格式注释和-z

当给出-z选项时,路径名按原样打印,没有任何引号,行以 NUL(ASCII 0x00)字节终止。

如果没有-z选项,则会引用具有“异常”字符的路径名,如配置变量core.quotePath所述(参见 git-config [1] )。

配置

该命令符合color.status(或status.color - 它们的含义相同,后者保持向后兼容性)和color.status.<slot>配置变量以使其输出着色。

如果 config 变量status.relativePaths设置为 false,则显示的所有路径都相对于存储库根目录,而不是当前目录。

如果status.submoduleSummary设置为非零数字或为真(与-1 或无限数字相同),则将为长格式启用子模块摘要,并显示已修改子模块的提交摘要(请参阅 git-submodule [1] 的–summary-limit 选项)。请注意,当diff.ignoreSubmodules设置为 all 时,或者仅对于那些submodule.<name>.ignore=all的子模块,将禁止所有子模块的 status 命令的摘要输出。要查看被忽略的子模块的摘要,您可以使用–ignore-submodules=dirty 命令行选项或 git submodule summary 命令,该命令显示类似的输出但不遵循这些设置。

后台刷新

默认情况下,git status将自动刷新索引,从工作树更新缓存的统计信息并写出结果。写出更新的索引是一种并非严格必要的优化(status计算自身的值,但将它们写出来只是为了保证后续程序不重复的计算)。当status在后台运行时,写入期间保持的锁定可能与其他同时的进程冲突,导致它们失败。在后台运行status的脚本应考虑使用git --no-optional-locks status(详见 git [1] )。

也可以看看

gitignore [5]

GIT

部分 git [1] 套件

git-diff

原文: git-scm.com/docs/git-diff 贡献者:honglyua

名称

git-diff - 显示提交之前,提交和工作树之间的更改等

概要

代码语言:javascript复制
git diff [<options>] [<commit>] [--] [<path>…​]
git diff [<options>] --cached [<commit>] [--] [<path>…​]
git diff [<options>] <commit> <commit> [--] [<path>…​]
git diff [<options>] <blob> <blob>
git diff [<options>] --no-index [--] <path> <path>

描述

显示工作树与索引或树之间的更改,索引与树之间的更改,两个树之间的更改,两个 blob 对象之间的更改或磁盘上两个文件之间的更改。

代码语言:javascript复制
 git diff [<options>] [--] [<path>…​] 

此表单用于查看您相对于索引所做的更改(下一次提交的暂存区域)。换句话说,差异就是你 _ 可以 _ 告诉 Git 即将要添加,但还没有添加到索引的内容。您可以使用 git-add [1] 暂存这些更改。

代码语言:javascript复制
 git diff [<options>] --no-index [--] <path> <path> 

此表单用于比较文件系统上给定的两个路径。在由 Git 控制的工作树中运行命令时,可以省略--no-index选项,并且至少有一个路径指向工作树外部,或者在 Git 控制的工作树外运行命令。

代码语言:javascript复制
 git diff [<options>] --cached [<commit>] [--] [<path>…​] 

此表单用于查看您为下一次提交而暂存的内容与已经的内容之间的更改。通常,您希望与最新提交进行比较,因此如果您不提供,则默认为 HEAD。如果 HEAD 不存在(例如未出生的分支)并且没有给出,它将显示所有暂存的更改。–staged 是–cached 的同义词。

代码语言:javascript复制
 git diff [<options>] <commit> [--] [<path>…​] 

此表单用于查看工作树中相对于已经提交的更改。您可以使用 HEAD 将其与最新提交进行比较,或使用分支名称与其他分支的提示进行比较。

代码语言:javascript复制
 git diff [<options>] <commit> <commit> [--] [<path>…​] 

这是为了查看两个任意之间的更改。

代码语言:javascript复制
 git diff [<options>] <commit>..<commit> [--] [<path>…​] 

这与之前的表格同义。如果在一侧被省略,它将具有与使用 HEAD 相同的效果。

代码语言:javascript复制
 git diff [<options>] <commit>...<commit> [--] [<path>…​] 

此表单用于查看分支上的更改,从两个的共同祖先开始,包含第二个及以上的节点。 “git diff A … B”相当于“git diff $(git merge-base A B)B”。您可以省略中的任何一个,它与使用 HEAD 具有相同的效果。

如果你正在做一些特殊操作,应该注意在上面描述中的所有,除了使用“…”符号的最后两种形式之外,可以是任何。

有关拼写的更完整列表的详细列表,请参阅 gitrevisions [7] 中的“指定修订”部分。然而,“diff”是关于比较两个 _ 端点 _,而不是范围和范围符号(“…”和“ … “)并不是指 gitrevisions [7] 中”指定范围“部分中定义的范围。

代码语言:javascript复制
 git diff [<options>] <blob> <blob> 

此表单用于查看两个 blob 对象的原始内容之间的差异。

选项

代码语言:javascript复制
 -p 
代码语言:javascript复制
 -u 
代码语言:javascript复制
 --patch 

生成补丁(请参阅生成补丁的部分)。这是默认值。

代码语言:javascript复制
 -s 
代码语言:javascript复制
 --no-patch 

抑制差异输出。对于git show等默认显示补丁的命令,或取消--patch的效果很有用。

代码语言:javascript复制
 -U<n> 
代码语言:javascript复制
 --unified=<n> 

生成行的上下文差异。而不是通常的三行。意味着--patch-p

代码语言:javascript复制
--output=<file>

输出到指定文件汇总,而不是标准输出中。

代码语言:javascript复制
--output-indicator-new=<char>
代码语言:javascript复制
--output-indicator-old=<char>
代码语言:javascript复制
--output-indicator-context=<char>

在生成补丁时,用特殊字符表明哪些行时 new,old,context。通常是用 , - and ’ '。

代码语言:javascript复制
 --raw 

以原始格式生成 diff。

代码语言:javascript复制
 --patch-with-raw 

-p --raw的同义词。

代码语言:javascript复制
 --indent-heuristic 

启用改变差异块边界的启发式以使补丁更易于阅读。这是默认值。

代码语言:javascript复制
 --no-indent-heuristic 

禁用缩进启发式。

代码语言:javascript复制
 --minimal 

花些额外的时间来确保产生尽可能小的差异。

代码语言:javascript复制
 --patience 

使用“patience diff”算法生成差异。

代码语言:javascript复制
 --histogram 

使用“histogram diff”算法生成差异。

代码语言:javascript复制
 --anchored=<text> 

使用“anchored diff”算法生成差异。

可以多次指定此选项。

如果源和目标中都存在一行,只存在一次,并以此文本开头,则此算法会尝试阻止它在输出中显示为删除或添加。它在内部使用“patience diff”算法。

代码语言:javascript复制
 --diff-algorithm={patience|minimal|histogram|myers} 

选择差异算法。变体如下:

代码语言:javascript复制
 default, myers 

基本的贪心差异算法。目前,这是默认值。

代码语言:javascript复制
 minimal 

花些额外的时间来确保产生尽可能小的差异。

代码语言:javascript复制
 patience 

生成补丁时使用“patience diff”算法。

代码语言:javascript复制
 histogram 

该算法将”patience diff“算法扩展为“支持低发生的共同元素”。

例如,如果将diff.algorithm变量配置为非默认值并想要使用默认值,则必须使用--diff-algorithm=default选项。

代码语言:javascript复制
 --stat[=<width>[,<name-width>[,<count>]]] 

生成 diffstat。默认情况下,文件名部分,图形部分的其余部分将使用必要的空间。最大宽度默认为终端宽度,如果未连接到终端,则为 80 列,并且可以被<width>覆盖。可以通过在逗号后面给出另一个宽度<name-width>来限制文件名部分的宽度。可以使用--stat-graph-width=<width>(影响生成统计图的所有命令)或设置diff.statGraphWidth=<width>(不影响git format-patch)来限制图形部分的宽度。通过给出第三个参数<count>,可以将输出限制为第一个<count>行,如果有更多,则将以...表示。

也可以使用--stat-width=<width>--stat-name-width=<name-width>--stat-count=<count>单独设置这些参数。

代码语言:javascript复制
 --compact-summary 

输出扩展标题信息的精简摘要,例如文件创建或删除(“新建”或“消失”,如果是符号链接,则可选“ l”)和文件权限更改(“ x”或“-x”用于添加或删除 diffstat 中的可执行位)。信息放在文件名部分和图形部分之间。意味着--stat

代码语言:javascript复制
 --numstat 

--stat类似,但是为了更加友好,它用十进制显示添加和删除的行数以及没有缩写的路径名。对于二进制文件,输出两个-而不是0 0

代码语言:javascript复制
 --shortstat 

仅输出--stat格式的最后一行,其中包含已修改文件的总数,以及已添加和已删除行的总数。

代码语言:javascript复制
-X[<param1,param2,…​>]
代码语言:javascript复制
 --dirstat[=<param1,param2,…​>] 

输出每个子目录的相对更改量的分布。 --dirstat的行为可以通过以逗号分隔的参数列表传递来定制。默认值由diff.dirstat配置变量控制(参见 git-config [1] )。可以使用以下参数:

代码语言:javascript复制
 changes 

通过计算从源文件中删除的行或添加到目标文件的行来计算 dirstat 数。这忽略了文件中纯代码移动的数量。换句话说,重新排列文件中的行不会像其他更改那样计算。这是没有给出参数时的默认行为。

代码语言:javascript复制
 lines 

通过执行常规的基于行的差异分析来计算 dirstat 数字,并对移除/添加的行数进行求和。 (对于二进制文件,计算 64 字节块,因为二进制文件没有自然行的概念)。这是比changes行为更昂贵的--dirstat行为,但它确实计算文件中重新排列的行与其他更改一样多。结果输出与您从其他--*stat选项获得的输出一致。

代码语言:javascript复制
 files 

通过计算更改的文件数来计算 dirstat 数。在 dirstat 分析中,每个更改的文件都相同。这是计算上最便宜的--dirstat行为,因为它根本不需要查看文件内容。

代码语言:javascript复制
 cumulative 

计算父目录的子目录中的更改。请注意,使用cumulative时,报告的百分比总和可能超过 100%。可以使用noncumulative参数指定默认(非累积)行为。

代码语言:javascript复制
 <limit> 

整数参数指定截止百分比(默认为 3%)。贡献低于此百分比变化的目录不会显示在输出中。

示例:以下将计算已更改的文件,同时忽略少于已更改文件总量的 10%的目录,并在父目录中累计子目录计数:--dirstat=files,10,cumulative

代码语言:javascript复制
--cumulative

与–dirstat=cumulative 相同

代码语言:javascript复制
--dirstat-by-file[=<param1,param2>…​]

与–dirstat=files,param1,param2…相同

代码语言:javascript复制
 --summary 

输出扩展标题信息的精简摘要,例如创建,重命名和模式更改。

代码语言:javascript复制
 --patch-with-stat 

-p --stat相同。

代码语言:javascript复制
 -z 

当给出--raw--numstat--name-only--name-status时,不使用路径名和 NUL 作为输出字段终止符。

如果没有此选项,则会引用具有“异常”字符的路径名,如配置变量core.quotePath所述(参见 git-config [1] )。

代码语言:javascript复制
 --name-only 

仅显示已更改文件的名称。

代码语言:javascript复制
 --name-status 

仅显示已更改文件的名称和状态。有关状态字母的含义,请参阅--diff-filter选项的说明。

代码语言:javascript复制
 --submodule[=<format>] 

指定子模块的差异如何显示。当指定--submodule=short时,使用 short 格式。此格式仅显示范围开头和结尾的提交名称。当指定--submodule--submodule=log时,使用 log 格式。此格式列出所有 commits 的提交,类似git-submodule [1] 中summary的功能。当指定--submodule=diff时,使用 diff 格式。此格式显示提交范围之间子模块内容更改的内联差异。如果未设置配置选项,则默认为diff.submoduleshort 格式。

代码语言:javascript复制
 --color[=<when>] 

显示彩色差异。 --color(即没有 = )与--color=always相同时。 < when> 可以是alwaysneverauto之一。可以通过color.uicolor.diff配置设置进行更改。

代码语言:javascript复制
 --no-color 

关掉彩色差异。这可用于覆盖配置设置。它与--color=never相同。

代码语言:javascript复制
 --color-moved[=<mode>] 

移动的代码行的颜色不同。可以通过diff.colorMoved配置设置进行更改。如果没有给出选项,则默认值为 no ,如果给出没有模式的选项,则默认为 zebra 。模式必须是以下之一:

代码语言:javascript复制
 no 

移动的线条不会突出显示。

代码语言:javascript复制
 default 

zebra的同义词。这可能会在未来转变为更明智的模式。

代码语言:javascript复制
 plain 

在一个位置添加并在另一个位置删除的任何行都将使用 color.diff.newMoved 进行着色。类似地, color.diff.oldMoved 将用于在 diff 中的其他位置添加的已删除行。此模式选择任何已移动的行,但在检查中确定是否在没有置换的情况下移动了代码块时,它不是很有用。

代码语言:javascript复制
 blocks 

贪婪地检测至少 20 个字母数字字符的移动文本块。使用 color.diff.{old,new} Moved 颜色绘制检测到的块。相邻的块不能分开。

代码语言:javascript复制
 zebra 

block 模式中检测移动文本块。使用 color.diff.{old,new} Moved 颜色或 color.diff.{old,new} MovedAlternative 绘制块。两种颜色之间的变化表示检测到新的块。

代码语言:javascript复制
 dimmed-zebra 

zebra 类似,但表现为额外调暗了移动代码的无趣部分。两个相邻块的边界线被认为是有趣的,其余的是无趣的。不推荐使用同义词dimmed_zebra

代码语言:javascript复制
 --no-color-moved 

关闭移动检测。这可用于覆盖配置设置。它与--color-moved=no相同。

代码语言:javascript复制
 --color-moved-ws=<modes> 

这将配置在执行--color-moved的移动检测时如何忽略空白。可以通过diff.colorMovedWS配置设置进行设置。这些模式可以以逗号分隔的列表给出:

代码语言:javascript复制
 no 

执行移动检测时不要忽略空格。

代码语言:javascript复制
 ignore-space-at-eol 

忽略 EOL 中的空白更改。

代码语言:javascript复制
 ignore-space-change 

忽略空格量的变化。这会忽略行尾的空格,并将一个或多个空白字符的所有其他序列视为等效。

代码语言:javascript复制
 ignore-all-space 

比较线条时忽略空格。即使一行有空格而另一行没有空格,这也会忽略差异。

代码语言:javascript复制
 allow-indentation-change 

最初忽略移动检测中的任何空格,然后如果每行的空白变化相同,则仅将移动的代码块分组到块中。这与其他模式不兼容。

代码语言:javascript复制
 --no-color-moved-ws 

执行移动检测时不要忽略空格。这可用于覆盖配置设置。它与--color-moved-ws=no相同。

代码语言:javascript复制
 --word-diff[=<mode>] 

使用< mode>显示单词 diff。划定改变的单词。默认情况下,单词由空格分隔;见下面的--word-diff-regex。 默认为 plain ,或者是以下之一:

代码语言:javascript复制
 color 

仅使用颜色突出显示更改的单词。意味着--color

代码语言:javascript复制
 plain 

将单词显示为[-removed-]{ added }。如果它们出现在输入中,则不会尝试转义分隔符,因此输出可能不明确。

代码语言:javascript复制
 porcelain 

使用特殊的基于行的格式用于脚本使用。添加/删除/未更改的运行以通常的统一 diff 格式打印,从行开头的 / - /``字符开始并延伸到行尾。输入中的换行符由其自身行上的波浪号~表示。

代码语言:javascript复制
 none 

再次禁用字差异。

请注意,如果启用了颜色,在所有模式中将使用第一个模式的名称,颜色突出显示已更改的部分。

代码语言:javascript复制
 --word-diff-regex=<regex> 

使用决定一个单词是什么,而不是将非空格的运行视为一个单词。除非已经启用,否则还暗示--word-diff

的每个非重叠匹配被认为是一个词。这些匹配之间的任何内容都被视为空格并被忽略(!)以查找差异。您可能希望将|[^[:space:]]附加到正则表达式,以确保它匹配所有非空白字符。包含换行符的匹配项会在换行符处以静默方式截断(!)。

例如,--word-diff-regex=.会将每个字符视为一个单词,并相应地逐个字符地显示差异。

正则表达式也可以通过 diff 驱动程序或配置选项设置,参见 gitattributes [5] 或 git-config [1] 。明确地覆盖任何差异驱动程序或配置设置。 Diff 驱动程序覆盖配置设置。

代码语言:javascript复制
 --color-words[=<regex>] 

相当于--word-diff=color加(如果指定了正则表达式)--word-diff-regex=<regex>

代码语言:javascript复制
 --no-renames 

关闭重命名检测,即使配置文件提供默认值也是如此。

代码语言:javascript复制
 --check 

如果更改引入冲突标记或空白错误,则发出警告。什么被认为是空白错误由core.whitespace配置控制。默认情况下,尾随空格(包括仅由空格组成的行)和在行的初始缩进内紧跟着制表符的空格字符被视为空格错误。如果发现问题,则退出非零状态。与–exit-code 不兼容。

代码语言:javascript复制
 --ws-error-highlight=<kind> 

突出显示差异的contextoldnew行中的空白错误。多个值用逗号分隔,none重置先前的值,default将列表重置为newallold,new,context的简写。如果未指定此选项,并且未设置配置变量diff.wsErrorHighlight,则仅突出显示new行中的空白错误。空白错误用color.diff.whitespace着色。

代码语言:javascript复制
 --full-index 

在生成补丁格式输出时,在“索引”行上显示完整的前映像和后映像 blob 对象名称,而不是第一个字符。

代码语言:javascript复制
 --binary 

--full-index外,还可输出可用git-apply输出二进制差异,--patch也可以。

代码语言:javascript复制
 --abbrev[=<n>] 

不是在 diff-raw 格式输出和 diff-tree 标题行中显示完整的 40 字节十六进制对象名称,而是仅显示部分前缀。这与上面的--full-index选项无关,后者控制 diff-patch 输出格式。可以使用--abbrev=<n>指定非默认位数。

代码语言:javascript复制
 -B[<n>][/<m>] 
代码语言:javascript复制
 --break-rewrites[=[<n>][/<m>]] 

将完整的重写更改分为删除和创建对。这有两个目的:

它影响了一个更改的方式,相当于一个文件的完全重写,而不是一系列的删除和插入混合在一起,只有几行恰好与文本作为上下文匹配,而是作为单个删除所有旧的后跟一个单个插入所有新内容,数字m控制-B 选项的这一方面(默认为 60%)。 -B/70%指定少于 30%的原始文本应保留在结果中,以便 Git 将其视为完全重写(即,否则生成的修补程序将是一系列删除和插入与上下文行混合在一起)。

当与-M 一起使用时,完全重写的文件也被视为重命名的源(通常-M 只考虑作为重命名源消失的文件),并且数字n控制 B 选项的这一方面(默认为 50%)。 -B20%指定添加和删除的更改与文件大小的 20%或更多相比,有资格被选为可能的重命名源到另一个文件。

代码语言:javascript复制
 -M[<n>] 
代码语言:javascript复制
 --find-renames[=<n>] 

检测重命名。如果指定了n,则它是相似性指数的阈值(即与文件大小相比的添加/删除量)。例如,-M90%表示如果超过 90%的文件未更改,Git 应将删除/添加对视为重命名。如果没有%符号,则该数字将作为分数读取,并在其前面加上小数点。即,-M5变为 0.5,因此与-M50%相同。同样,-M05-M5%相同。要将检测限制为精确重命名,请使用-M100%。默认相似性指数为 50%。

代码语言:javascript复制
 -C[<n>] 
代码语言:javascript复制
 --find-copies[=<n>] 

检测副本以及重命名。另见--find-copies-harder。如果指定了n,则其含义与-M<n>的含义相同。

代码语言:javascript复制
 --find-copies-harder 

出于性能原因,默认情况下,仅当在同一变更集中修改了副本的原始文件时,-C选项才会查找副本。此标志使命令检查未修改的文件作为副本源的候选者。对于大型项目来说,这是一项非常昂贵的操作,因此请谨慎使用。提供多个-C选项具有相同的效果。

代码语言:javascript复制
 -D 
代码语言:javascript复制
 --irreversible-delete 

省略删除的原像,即只打印标题而不打印原像和/dev/null之间的差异。得到的 patch 不适用于patchgit apply;这仅适用于那些希望在更改后专注于检视文本的人。此外,输出显然缺乏足够的信息来反向应用这样的补丁,甚至手动,因此选项的名称。

-B一起使用时,也省略删除/创建对的删除部分中的原像。

代码语言:javascript复制
 -l<num> 

-M-C选项需要 O(n²)处理时间,其中 n 是潜在的重命名/复制目标的数量。如果重命名/复制目标的数量超过指定的数量,此选项可防止重命名/复制检测运行。

代码语言:javascript复制
 --diff-filter=[(A|C|D|M|R|T|U|X|B)…​[*]] 

仅选择已添加(A),复制(C),已删除(D),已修改(M),已重命名(R)的文件,其类型(即常规文件,符号链接,子模块,…)更改(T),未合并(U),未知(X),或已配对破碎(B)。可以使用过滤器字符的任何组合(包括无)。当*(全部或全部)添加到组合中时,如果有任何文件与比较中的其他条件匹配,则选择所有路径;如果没有与其他条件匹配的文件,则不会选择任何内容。

此外,这些大写字母可以降级为排除。例如。 --diff-filter=ad排除添加和删除的路径。

请注意,并非所有差异都可以包含所有类型。例如,从索引到工作树的差异永远不会有添加条目(因为差异中包含的路径集受限于索引中的内容)。同样,如果禁用了对这些类型的检测,则无法显示复制和重命名的条目。

代码语言:javascript复制
 -S<string> 

查找改变文件中指定字符串出现次数(即添加/删除)的差异。用于脚本编写者的使用。

当你正在寻找一个确切的代码块(比如一个结构体)时,它很有用,并且想要知道该块首次出现以来的历史:迭代地使用该特征将原始图像中的有趣块反馈回-S,继续前进,直到你获得该块的第一个版本。

也可以搜索二进制文件。

代码语言:javascript复制
 -G<regex> 

查找补丁文本包含与匹配的添加/删除行的差异。

为了说明-S<regex> --pickaxe-regex-G<regex>之间的区别,请考虑在同一文件中使用以下 diff 进行提交:

代码语言:javascript复制
     return !regexec(regexp, two->ptr, 1, &regmatch, 0);
...
-    hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0);

虽然git log -G"regexec(regexp"将显示此提交,但git log -S"regexec(regexp" --pickaxe-regex不会(因为该字符串的出现次数没有改变)。

除非提供--text,否则将忽略没有 textconv 过滤器的二进制文件的补丁。

有关详细信息,请参阅 gitdiffcore [7] 中的 pickaxe 条目。

代码语言:javascript复制
 --find-object=<object-id> 

查找更改指定对象出现次数的差异。与-S类似,只是参数的不同之处在于它不搜索特定的字符串,而是搜索特定的对象 id。

该对象可以是 blob 或子模块提交。它意味着git-log中的-t选项也可以找到树。

代码语言:javascript复制
 --pickaxe-all 

-S-G找到更改时,显示该更改集中的所有更改,而不仅仅是包含< string>中更改的文件。

代码语言:javascript复制
 --pickaxe-regex 

对待< string>赋予-S作为扩展的 POSIX 正则表达式以匹配。

代码语言:javascript复制
 -O<orderfile> 

控制文件在输出中的显示顺序。这会覆盖diff.orderFile配置变量(参见 git-config [1] )。要取消diff.orderFile,请使用-O/dev/null

输出顺序由< orderfile>中的 glob 模式的顺序决定。首先输出所有与第一个模式匹配的路径名的文件,然后输出所有与第二个模式(但不是第一个模式)匹配的路径名的文件,依此类推。路径名与任何模式都不匹配的所有文件都是最后输出的,就好像文件末尾有一个隐式匹配所有模式一样。如果多个路径名具有相同的等级(它们匹配相同的模式但没有早期模式),则它们相对于彼此的输出顺序是正常顺序。

解析如下:

  • 空行被忽略,因此可以将它们用作分隔符以提高可读性。
  • 以哈希(“#”)开头的行将被忽略,因此它们可用于注释。如果以哈希开头,则将反斜杠(“”)添加到模式的开头。
  • 每个其他行包含一个模式。

模式与没有 FNM_PATHNAME 标志的 fnmatch(3)使用模式具有相同的语法和语义,除匹配的路径名之外,如果删除任意数量的与模式匹配的最终路径名组件。例如,模式“foo*bar”匹配“fooasdfbar”和“foo/bar/baz/asdf”而不匹配“foobarx”。

代码语言:javascript复制
 -R 

交换两个输入;也就是说,显示从索引或磁盘文件到树内容的差异。

代码语言:javascript复制
 --relative[=<path>] 

从项目的子目录运行时,可以告诉它除目录外的更改并使用此选项显示相对于它的路径名。当您不在子目录中时(例如,在裸存储库中),您可以通过给出 作为一个参数来命名哪个子目录以使输出相对。

代码语言:javascript复制
 -a 
代码语言:javascript复制
 --text 

将所有文件视为文本。

代码语言:javascript复制
 --ignore-cr-at-eol 

进行比较时,忽略行尾的回车。

代码语言:javascript复制
 --ignore-space-at-eol 

忽略 EOL 中的空白更改。

代码语言:javascript复制
 -b 
代码语言:javascript复制
 --ignore-space-change 

忽略空格量的变化。这会忽略行尾的空格,并将一个或多个空白字符的所有其他序列视为等效。

代码语言:javascript复制
 -w 
代码语言:javascript复制
 --ignore-all-space 

比较线条时忽略空格。即使一行有空格而另一行没有空格,这也会忽略差异。

代码语言:javascript复制
 --ignore-blank-lines 

忽略其行全部为空的更改。

代码语言:javascript复制
 --inter-hunk-context=<lines> 

显示差异之间的上下文,直到指定的行数,从而融合彼此接近的内容。如果未设置配置选项,则默认为diff.interHunkContext或 0。

代码语言:javascript复制
 -W 
代码语言:javascript复制
 --function-context 

显示整个周围的变化功能。

代码语言:javascript复制
 --exit-code 

使用类似于 diff(1)的代码退出程序。也就是说,如果存在差异则退出 1,0 表示没有差异。

代码语言:javascript复制
 --quiet 

禁用程序的所有输出。意味着--exit-code

代码语言:javascript复制
 --ext-diff 

允许执行外部 diff 助手。如果使用 gitattributes [5] 设置外部差异驱动程序,则需要将此选项与 git-log [1] 一起友好使用。

代码语言:javascript复制
 --no-ext-diff 

禁止外部差异驱动程序。

代码语言:javascript复制
 --textconv 
代码语言:javascript复制
 --no-textconv 

在比较二进制文件时允许(或禁止)外部文本转换过滤器运行。有关详细信息,请参阅 gitattributes [5] 。由于 textconv 过滤器通常是单向转换,因此生成的差异适合人阅读,但无法应用。因此,默认情况下,textconv 过滤器仅针对 git-diff [1] 和 git-log [1] 启用,但不适用于 git-format-patch [ 1] 或差异管道命令。

代码语言:javascript复制
 --ignore-submodules[=<when>] 

忽略差异生成中子模块的更改。可以是“none”,“untracked”,“dirty”或“all”,这是默认值。使用“none”时,如果子模块包含未跟踪或修改的文件,或者其 HEAD 与超级项目中记录的提交不同,则可以使用“none”来修改子模块,并可用于覆盖git-config [1] 或 gitmodules [5]中 ignore 选项的任何设置。当使用“untracked”时,如果子模块仅包含未跟踪的内容(但仍会扫描修改的内容),则子模块不会被视为 dirty。使用“dirty”忽略对子模块工作树的所有更改,仅显示存储在超级项目中的提交的更改(这是 1.7.0 之前的行为)。使用“all”隐藏子模块的所有更改。

代码语言:javascript复制
 --src-prefix=<prefix> 

显示给定的源前缀而不是“a/”。

代码语言:javascript复制
 --dst-prefix=<prefix> 

显示给定的目标前缀而不是“b/”。

代码语言:javascript复制
 --no-prefix 

不显示任何源或目标前缀。

代码语言:javascript复制
 --line-prefix=<prefix> 

为每行输出预先附加前缀。

代码语言:javascript复制
 --ita-invisible-in-index 

默认情况下,“git add -N”添加的条目在“git diff”中显示为现有空文件,在“git diff --cached”中显示为新文件。此选项使条目在“git diff”中显示为新文件,在“git diff --cached”中不存在。可以使用--ita-visible-in-index恢复此选项。这两个选项都是实验性的,将来可以删除。

有关这些常用选项的更详细说明,另请参阅 gitdiffcore [7] 。

代码语言:javascript复制
 -1 --base 
代码语言:javascript复制
 -2 --ours 
代码语言:javascript复制
 -3 --theirs 

将工作树与“基础”版本(阶段#1),“我们的分支”(阶段#2)或“他们的分支”(阶段#3)进行比较。索引仅包含针对未合并条目的这些阶段,即在解决冲突时。有关详细信息,请参阅 git-read-tree [1] 部分“3-Way Merge”。

代码语言:javascript复制
 -0 

省略未合并条目的差异输出,只显示“未合并”。仅在将工作树与索引进行比较时才能使用。

代码语言:javascript复制
 <path>…​ 

<路径>参数,当给定时,用于将 diff 限制为命名路径(您可以为其下的所有文件提供目录名称和获取差异)。

原始输出格式

来自“git-diff-index”,“git-diff-tree”,“git-diff-files”和“git diff -raw”的原始输出格式非常相似。

这些命令都比较了两组东西;比较的不同之处是:

代码语言:javascript复制
 git-diff-index <tree-ish> 

比较以及文件系统上的文件。

代码语言:javascript复制
 git-diff-index --cached <tree-ish> 

比较和索引。

代码语言:javascript复制
 git-diff-tree [-r] <tree-ish-1> <tree-ish-2> [<pattern>…​] 

比较两个参数命名的树。

代码语言:javascript复制
 git-diff-files [<pattern>…​] 

比较索引和文件系统上的文件。

“git-diff-tree”命令通过打印正在比较的内容的哈希来开始输出。之后,所有命令都会为每个更改的文件打印一个输出行。

输出行以这种方式格式化:

代码语言:javascript复制
in-place edit  :100644 100644 bcd1234 0123456 M file0
copy-edit      :100644 100644 abcd123 1234567 C68 file1 file2
rename-edit    :100644 100644 abcd123 1234567 R86 file1 file3
create         :000000 100644 0000000 1234567 A file4
delete         :100644 000000 1234567 0000000 D file5
unmerged       :000000 000000 0000000 0000000 U file6

也就是说,从左到右:

  1. 一个冒号。
  2. “src”模式;如果创建或未合并,则为 000000。
  3. 空格。
  4. “dst”模式;如果删除或未合并,则为 000000。
  5. 空格。
  6. sha1 为“src”; 如果创建或未合并,则显示 0{40}。
  7. 空格。
  8. sha1 为“dst”; 如果创建,未合并或“查看工作树”,则显示 0{40}。
  9. 空格。
  10. 状态,后跟可选的“数字”编号。
  11. 使用-z选项时的选项卡或 NUL。
  12. “src”的路径
  13. 使用-z选项时的选项卡或 NUL;仅适用于 C 或 R.
  14. “dst”的路径;仅适用于 C 或 R.
  15. 使用-z选项时,LF 或 NUL 终止记录。

可能的状态字母是:

  • A:添加文件
  • C:将文件复制到新文件中
  • D:删除文件
  • M:修改文件的内容或模式
  • R:重命名文件
  • T:更改文件类型
  • U:文件已取消合并(您必须先完成合并才能提交)
  • X:“未知”更改类型(最有可能是错误,请报告)

状态字母 C 和 R 后面总是跟一个分数(表示移动或复制的源和目标之间的相似性百分比)。状态字母 M 之后可以是文件重写的分数(表示不相似的百分比)。

如果文件系统上的文件是新文件并且它与索引不同步,则显示为全 0。

例:

代码语言:javascript复制
:100644 100644 5be4a4a 0000000 M file.c

如果没有-z选项,则会引用具有“异常”字符的路径名,如配置变量core.quotePath所述(参见 git-config [1] )。使用-z,文件名逐字输出,行以 NUL 字节终止。

用于合并的 diff 格式

“git-diff-tree”,“git-diff-files”和“git-diff --raw”可以使用-c--cc选项为合并提交生成 diff 输出。输出与上述格式的不同之处如下:

  1. 每个父母都有一个冒号
  2. 还有更多“src”模式和“src”sha1
  3. status 是每个父级的连接状态字符
  4. 没有可选的“分数”数字
  5. 单路径,仅适用于“dst”

例:

代码语言:javascript复制
::100644 100644 100644 fabadb8 cc95eb0 4866510 MM	describe.c

请注意,_ 组合 diff_ 仅列出从所有父项修改的文件。

使用-p 生成补丁

当“git-diff-index”,“git-diff-tree”或“git-diff-files”使用-p选项运行时,“git diff”不带--raw选项或“git log”使用“-p”选项,它们不会产生上述输出;相反,他们生成一个补丁文件。您可以通过GIT_EXTERNAL_DIFFGIT_DIFF_OPTS环境变量自定义此类修补程序的创建。

-p 选项产生的内容与传统的 diff 格式略有不同:

它前面有一个“git diff”标题,如下所示:

代码语言:javascript复制
diff --git a/file1 b/file2

除非涉及重命名/复制,否则a/b/文件名是相同的。特别是,即使是创建或删除,/dev/null_ 不是用来 _ 代替a/b/的文件名。

当涉及重命名/复制时,file1file2分别显示重命名/复制的源文件的名称和重命名/复制的文件的名称。

它后跟一个或多个扩展标题行:

代码语言:javascript复制
old mode <mode>
new mode <mode>
deleted file mode <mode>
new file mode <mode>
copy from <path>
copy to <path>
rename from <path>
rename to <path>
similarity index <number>
dissimilarity index <number>
index <hash>..<hash> <mode>

文件模式打印为 6 位八进制数,包括文件类型和文件权限位。

扩展标头中的路径名不包括a/b/前缀。

相似性指数是未更改行的百分比,相异性指数是更改行的百分比。它是一个向下舍入的整数,后跟一个百分号。因此,100%的相似性索引值保留用于两个相等的文件,而 100%的相异性意味着旧文件中的任何行都不会成为新文件。

索引行包括更改前后的 SHA-1 校验和。如果文件模式没有改变,则包括在内;否则,单独的行表示旧模式和新模式。

具有“异常”字符的路径名被引用,如配置变量core.quotePath所述(参见 git-config [1] )。

输出中的所有file1文件在提交之前引用文件,并且所有file2文件在提交之后引用文件。将每个更改顺序应用于每个文件是不正确的。例如,此补丁将交换 a 和 b:

代码语言:javascript复制
diff --git a/a b/b
rename from a
rename to b
diff --git a/b b/a
rename from b
rename to a

组合差异格式

在显示合并时,任何差异生成命令都可以使用-c--cc选项生成 _ 组合差异 _。当显示与 git-diff [1] 或 git-show [1] 的合并时,这是默认格式。另请注意,您可以为这些命令中的任何一个提供-m选项,以强制使用合并的各个父项生成差异。

_ 组合 diff_ 格式如下所示:

代码语言:javascript复制
diff --combined describe.c
index fabadb8,cc95eb0..4866510
--- a/describe.c
    b/describe.c
@@@ -98,20 -98,12  98,20 @@@
	return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
  }

- static void describe(char *arg)
 -static void describe(struct commit *cmit, int last_one)
  static void describe(char *arg, int last_one)
  {
  	unsigned char sha1[20];
  	struct commit *cmit;
	struct commit_list *list;
	static int initialized = 0;
	struct commit_name *n;

  	if (get_sha1(arg, sha1) < 0)
  		usage(describe_usage);
  	cmit = lookup_commit_reference(sha1);
  	if (!cmit)
  		usage(describe_usage);
  
	if (!initialized) {
		initialized = 1;
		for_each_ref(get_name);

它前面有一个“git diff”标题,看起来像这样(当使用-c选项时):

代码语言:javascript复制
diff --combined file

或者像这样(当使用--cc选项时):

代码语言:javascript复制
diff --cc file

它后跟一个或多个扩展标题行(此示例显示了与两个父项的合并):

代码语言:javascript复制
index <hash>,<hash>..<hash>
mode <mode>,<mode>..<mode>
new file mode <mode>
deleted file mode <mode>,<mode>

只有当中的至少一个出现时,mode <mode>,<mode>..<mode>行才会出现。与其他人不同。具有关于检测到的内容移动(重命名和复制检测)的信息的扩展标题被设计为与两个的差异一起工作。并且不会被组合 diff 格式使用。

接下来是两行的文件/文件头

代码语言:javascript复制
--- a/file
    b/file

与传统 _ 统一 _ diff 格式的双行标题类似,/dev/null用于表示创建或删除的文件。

修改了块头格式以防止人们意外地将其馈送到patch -p1。创建组合差异格式用于审查合并提交更改,并不适用于应用。此更改类似于扩展 _ 索引 _ 标头中的更改:

代码语言:javascript复制
@@@ <from-file-range> <from-file-range> <to-file-range> @@@

组合 diff 格式的块头中有(父项数 1)@个字符。

与传统的 _ 统一 _ 差异格式不同,后者显示两个文件 A 和 B,其中一列具有-(减去 - 出现在 A 中但在 B 中删除), (加 - 缺少 A 但是添加到 B)或" "(空格 - 未更改)前缀,此格式将两个或多个文件 file1,file2,…与一个文件 X 进行比较,并显示 X 与每个文件 N 的不同之处。每个 fileN 的一列被添加到输出行之前,以指示 X 的行与它的不同之处。

N 列中的-字符表示该行出现在 fileN 中,但它不会出现在结果中。列 N 中的 字符表示该行出现在结果中,而 fileN 没有该行(换句话说,从该父项的角度添加了该行)。

在上面的示例输出中,函数签名已从两个文件中更改(因此,file1 和 file2 中的两个-删除加上 表示添加的一行未出现在 file1 或 file2 中)。另外八行与 file1 相同,但不出现在 file2 中(因此以 为前缀)。

当由git diff-tree -c显示时,它将合并提交的父项与合并结果进行比较(即 file1…fileN 是父项)。当由git diff-files -c显示时,它将两个未解析的合并父项与工作树文件进行比较(即 file1 是阶段 2 又名“我们的版本”,file2 是阶段 3 又名“他们的版本”)。

其他差异格式

--summary选项描述新添加,删除,重命名和复制的文件。 --stat选项将 diffstat(1)图形添加到输出。这些选项可以与其他选项结合使用,例如-p,用于人类消费。

当显示涉及重命名或副本的更改时,--stat输出通过组合路径名的公共前缀和后缀来紧凑地格式化路径名。例如,修改 4 行时将arch/i386/Makefile移动到arch/x86/Makefile的更改将显示如下:

代码语言:javascript复制
arch/{i386 => x86}/Makefile    |   4  --

--numstat选项提供 diffstat(1)信息,但设计用于更容易的机器消耗。 --numstat输出中的条目如下所示:

代码语言:javascript复制
1	2	README
3	1	arch/{i386 => x86}/Makefile

也就是说,从左到右:

  1. 添加的行数;
  2. tab;
  3. 删除的行数;
  4. tab;
  5. pathname(可能带有重命名/复制信息);
  6. 换行符。

-z输出选项生效时,输出格式为:

代码语言:javascript复制
1	2	README NUL
3	1	NUL arch/i386/Makefile NUL arch/x86/Makefile NUL

那是:

  1. 添加的行数;
  2. tab;
  3. 删除的行数;
  4. tab;
  5. NUL(仅在重命名/复制时存在);
  6. 原像中的路径名;
  7. NUL(仅在重命名/复制时存在);
  8. 新像中的路径名(仅在重命名/复制时存在);
  9. 一个 NUL。

在重命名的情况下,原像路径之前的额外NUL是允许读取输出的脚本判断正在读取的当前记录是单路径记录还是重命名/复制记录而无需提前读取。读取添加和删除的行后,读取NUL将产生路径名,但如果是NUL,则记录将显示两个路径。

例子

代码语言:javascript复制
 Various ways to check your working tree 
代码语言:javascript复制
$ git diff            (1)
$ git diff --cached   (2)
$ git diff HEAD       (3)
  1. 尚未为下次提交暂存的工作树中的更改。
  2. 索引与上次提交之间的变化;如果没有“-a”选项运行“git commit”,你会提交什么。
  3. 自上次提交以来工作树中的更改;如果你运行“git commit -a”,你会提交什么
代码语言:javascript复制
 Comparing with arbitrary commits 
代码语言:javascript复制
$ git diff test            (1)
$ git diff HEAD -- ./test  (2)
$ git diff HEAD^ HEAD      (3)
  1. 不是使用当前分支的尖端,而与“测试”分支的尖端进行比较。
  2. 不是与“test”分支的尖端进行比较,而与当前分支的尖端进行比较,但将比较限制为文件“test”。
  3. 比较上次提交和最后一次提交之前的版本。
代码语言:javascript复制
 Comparing branches 
代码语言:javascript复制
$ git diff topic master    (1)
$ git diff topic..master   (2)
$ git diff topic...master  (3)
  1. topic 与主分支之间的更改。
  2. 与上述相同。
  3. 自 topic 分支启动以来主分支上发生的更改。
代码语言:javascript复制
 Limiting the diff output 
代码语言:javascript复制
$ git diff --diff-filter=MRC            (1)
$ git diff --name-status                (2)
$ git diff arch/i386 include/asm-i386   (3)
  1. 仅显示修改,重命名和复制,但不添加或删除。
  2. 仅显示名称和更改的性质,但不显示实际的差异输出。
  3. 将 diff 输出限制为命名子树。
代码语言:javascript复制
 Munging the diff output 
代码语言:javascript复制
$ git diff --find-copies-harder -B -C  (1)
$ git diff -R                          (2)
  1. 花费额外的周期来查找重命名,复制和完成重写(非常昂贵)。
  2. 反向输出差异。

也可以看看

diff(1), git-difftool [1] , git-log [1] , gitdiffcore [7] , git-format-patch [1] , git-apply [1]

GIT

部分 git [1] 套件

git-commit

原文: git-scm.com/docs/git-commit

名称

git-commit - 记录对存储库的更改

概要

代码语言:javascript复制
git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]
	   [--dry-run] [(-c | -C | --fixup | --squash) <commit>]
	   [-F <file> | -m <msg>] [--reset-author] [--allow-empty]
	   [--allow-empty-message] [--no-verify] [-e] [--author=<author>]
	   [--date=<date>] [--cleanup=<mode>] [--[no-]status]
	   [-i | -o] [-S[<keyid>]] [--] [<file>…​]

描述

创建一个新的提交,其中包含索引的当前内容和描述更改的给定日志消息。新提交是 HEAD 的直接子代,通常是当前分支的尖端,并且分支被更新为指向它(除非没有分支与工作树相关联,在这种情况下 HEAD 是“分离的”,如 git-checkout [1] )。

要提交的内容可以通过以下几种方式指定:

  1. 通过使用 git-add [1] 在使用 commit 命令之前逐步“添加”对索引的更改(注意:甚至修改后的文件必须“添加”);
  2. 通过使用 git-rm [1] 从工作树和索引中删除文件,再次使用 commit 命令之前;
  3. 通过将文件列为 commit 命令的参数(没有–interactive 或–patch switch),在这种情况下,提交将忽略索引中暂存的更改,而是记录列出的文件的当前内容(必须已经为 Git 所知);
  4. 通过使用-a 开关和 commit 命令自动“添加”来自所有已知文件的更改(即已在索引中列出的所有文件)并自动“rm”索引中的文件已从工作树中删除,然后执行实际提交;
  5. 通过使用–interactive 或–patch 开关和 commit 命令,在完成操作之前,逐个确定哪些文件或数据库应该是提交的一部分,以及索引中的内容。请参阅 git-add [1] 的“交互模式”部分,了解如何操作这些模式。

--dry-run选项可用于通过提供相同的参数集(选项和路径)来获取上述任何内容对下一次提交所包含内容的摘要。

如果你提交然后在那之后立即发现错误,你可以使用 git reset 从中恢复。

OPTIONS

代码语言:javascript复制
 -a 
代码语言:javascript复制
 --all 

告诉命令自动暂存已修改和删除的文件,但是没有告诉 Git 的新文件不会受到影响。

代码语言:javascript复制
 -p 
代码语言:javascript复制
 --patch 

使用交互式修补程序选择界面选择要提交的更改。有关详细信息,请参阅 git-add [1] 。

代码语言:javascript复制
 -C <commit> 
代码语言:javascript复制
 --reuse-message=<commit> 

获取现有提交对象,并在创建提交时重用日志消息和作者信息(包括时间戳)。

代码语言:javascript复制
 -c <commit> 
代码语言:javascript复制
 --reedit-message=<commit> 

-C 类似,但是使用-c调用编辑器,以便用户可以进一步编辑提交消息。

代码语言:javascript复制
 --fixup=<commit> 

构造一个与rebase --autosquash一起使用的提交消息。提交消息将是指定提交的主题行,前缀为“fixup!”。有关详细信息,请参阅 git-rebase [1] 。

代码语言:javascript复制
 --squash=<commit> 

构造一个与rebase --autosquash一起使用的提交消息。提交消息主题行取自指定的提交,前缀为“squash!”。可与其他提交消息选项一起使用(-m / -c / -C / -F)。有关详细信息,请参阅 git-rebase [1] 。

代码语言:javascript复制
 --reset-author 

当与-C / -c / - 修改选项一起使用时,或者在冲突的挑选之后提交时,声明生成的提交的作者现在属于提交者。这也更新了作者的时间戳。

代码语言:javascript复制
 --short 

进行干运行时,请以短格式输出。有关详细信息,请参阅 git-status [1] 。意味着--dry-run

代码语言:javascript复制
 --branch 

即使是短格式显示分支和跟踪信息。

代码语言:javascript复制
 --porcelain 

进行干运行时,请以瓷质格式输出。有关详细信息,请参阅 git-status [1] 。意味着--dry-run

代码语言:javascript复制
 --long 

进行干运行时,请以长格式输出。意味着--dry-run

代码语言:javascript复制
 -z 
代码语言:javascript复制
 --null 

显示shortporcelain状态输出时,逐字打印文件名并使用 NUL 而不是 LF 终止输入。如果没有给出格式,则表示--porcelain输出格式。如果没有-z选项,则会按照配置变量core.quotePath的说明引用带有“异常”字符的文件名(参见 git-config [1] )。

代码语言:javascript复制
 -F <file> 
代码语言:javascript复制
 --file=<file> 

从给定文件中获取提交消息。使用 - 从标准输入读取信息。

代码语言:javascript复制
 --author=<author> 

覆盖提交作者。使用标准A U Thor &lt;author@example.com&gt;格式指定显式作者。否则< author>假定是一种模式,用于搜索该作者的现有提交(即 rev-list --all -i --author =< author>);然后从找到的第一个这样的提交中复制提交作者。

代码语言:javascript复制
 --date=<date> 

覆盖提交中使用的作者日期。

代码语言:javascript复制
 -m <msg> 
代码语言:javascript复制
 --message=<msg> 

使用给定的< msg>作为提交消息。如果给出了多个-m选项,则它们的值将作为单独的段落连接在一起。

-m选项与-c-C-F互斥。

代码语言:javascript复制
 -t <file> 
代码语言:javascript复制
 --template=<file> 

编辑提交消息时,使用给定文件中的内容启动编辑器。 commit.template配置变量通常用于向命令隐式提供此选项。希望引导参与者提供有关在消息中以什么顺序写入内容的一些提示的项目可以使用此机制。如果用户在不编辑消息的情况下退出编辑器,则中止提交。当通过其他方式给出消息时,例如,这没有效果。使用-m-F选项。

代码语言:javascript复制
 -s 
代码语言:javascript复制
 --signoff 

在提交日志消息的末尾由提交者添加逐行签名。签收的含义取决于项目,但它通常证明提交者有权在同一许可下提交此作品并同意开发者原产地证书(参见 developercertificate.org/ ] 欲获得更多信息)。

代码语言:javascript复制
 -n 
代码语言:javascript复制
 --no-verify 

此选项绕过 pre-commit 和 commit-msg 挂钩。另见 githooks [5] 。

代码语言:javascript复制
 --allow-empty 

通常记录与其唯一父提交具有完全相同的树的提交是错误的,并且该命令阻止您进行此类提交。此选项绕过安全性,主要供外部 SCM 接口脚本使用。

代码语言:javascript复制
 --allow-empty-message 

与–allow-empty 类似,此命令主要供外部 SCM 接口脚本使用。它允许您使用空提交消息创建提交,而不使用 git-commit-tree [1] 等管道命令。

代码语言:javascript复制
 --cleanup=<mode> 

此选项确定在提交之前应如何清除提供的提交消息。 < mode> 可以是stripwhitespaceverbatimscissorsdefault

代码语言:javascript复制
 strip 

剥去前导和尾随空行,尾随空格,注释和折叠连续的空行。

代码语言:javascript复制
 whitespace 

strip相同,但不删除#commentary。

代码语言:javascript复制
 verbatim 

根本不要更改消息。

代码语言:javascript复制
 scissors 

whitespace相同,但是如果要编辑消息,则截断下面找到的行的所有内容(包括)都将被截断。 “#”可以使用 core.commentChar 进行自定义。

代码语言:javascript复制
# ------------------------ >8 ------------------------
代码语言:javascript复制
 default 

如果要编辑消息,则与strip相同。否则whitespace

可以通过commit.cleanup配置变量更改默认值(参见 git-config [1] )。

代码语言:javascript复制
 -e 
代码语言:javascript复制
 --edit 

从带有-F的文件,带有-m的命令行和带有-C的提交对象获取的消息通常用作未修改的提交日志消息。此选项允许您进一步编辑从这些来源获取的消息。

代码语言:javascript复制
 --no-edit 

使用选定的提交消息而不启动编辑器。例如,git commit --amend --no-edit修改提交而不更改其提交消息。

代码语言:javascript复制
 --amend 

通过创建新提交替换当前分支的提示。记录的树像往常一样准备(包括-i-o选项和显式路径规范的效果),当没有其他消息时,原始提交的消息用作起始点而不是空消息通过-m-F-c等选项从命令行指定。新提交与当前提交具有​​相同的父级和作者(--reset-author选项可以对此进行反对)。

这是一个粗略的等价物:

代码语言:javascript复制
	$ git reset --soft HEAD^
	$ ... do something else to come up with the right tree ...
	$ git commit -c ORIG_HEAD

但可以用来修改合并提交。

如果修改已发布的提交,则应了解重写历史记录的含义。 (参见 git-rebase [1] 中的“从上游重新恢复”部分。)

代码语言:javascript复制
 --no-post-rewrite 

绕过重写后的钩子。

代码语言:javascript复制
 -i 
代码语言:javascript复制
 --include 

在到目前为止提交暂存内容之前,还要在命令行上分配路径的内容。这通常不是您想要的,除非您得出冲突的合并。

代码语言:javascript复制
 -o 
代码语言:javascript复制
 --only 

通过获取命令行上指定的路径的更新工作树内容进行提交,忽略已为其他路径暂存的任何内容。如果在命令行上给出了任何路径,这是 git commit 的默认操作模式,在这种情况下,可以省略此选项。如果此选项与--amend一起指定,则不需要指定任何路径,这可以用于修改最后一次提交而不提交已经暂存的更改。如果与--allow-empty一起使用,则也不需要路径,并且将创建空提交。

代码语言:javascript复制
 -u[<mode>] 
代码语言:javascript复制
 --untracked-files[=<mode>] 

显示未跟踪的文件。

mode 参数是可选的(默认为 all ),用于指定未跟踪文件的处理;当-u 未使用时,默认为 _ 正常 _,即显示未跟踪的文件和目录。

可能的选择是:

  • _ 没有 _ - 显示没有未跟踪的文件
  • _ 正常 _ - 显示未跟踪的文件和目录
  • _ 全部 _ - 还显示未跟踪目录中的单个文件。

可以使用 git-config [1] 中记录的 status.showUntrackedFiles 配置变量更改默认值。

代码语言:javascript复制
 -v 
代码语言:javascript复制
 --verbose 

显示 HEAD 提交与提交消息模板底部提交的内容之间的统一差异,以帮助用户通过提醒提交的更改来描述提交。请注意,此 diff 输出的行前缀不是 。此差异不会是提交消息的一部分。请参见 git-config [1] 中的commit.verbose配置变量。

如果指定了两次,则另外显示将提交的内容与 worktree 文件之间的统一差异,即对跟踪文件的未分级更改。

代码语言:javascript复制
 -q 
代码语言:javascript复制
 --quiet 

禁止提交摘要消息。

代码语言:javascript复制
 --dry-run 

不要创建提交,而是显示要提交的路径列表,具有未提交的本地更改的路径以及未跟踪的路径。

代码语言:javascript复制
 --status 

使用编辑器准备提交消息时,在提交消息模板中包含 git-status [1] 的输出。默认为 on,但可用于覆盖配置变量 commit.status。

代码语言:javascript复制
 --no-status 

使用编辑器准备默认提交消息时,请勿在提交消息模板中包含 git-status [1] 的输出。

代码语言:javascript复制
 -S[<keyid>] 
代码语言:javascript复制
 --gpg-sign[=<keyid>] 

GPG 签名提交。 keyid参数是可选的,默认为提交者标识;如果指定,它必须粘在没有空格的选项上。

代码语言:javascript复制
 --no-gpg-sign 

Countermand commit.gpgSign配置变量,设置为强制每个提交都被签名。

代码语言:javascript复制
 -- 

不要将任何更多的参数解释为选项。

代码语言:javascript复制
 <file>…​ 

在命令行上提供文件时,该命令将提交指定文件的内容,而不记录已暂存的更改。这些文件的内容也会在之前的演出之上进行下一次提交。

日期格式

GIT_AUTHOR_DATEGIT_COMMITTER_DATE环境变量和--date选项支持以下日期格式:

代码语言:javascript复制
 Git internal format 

它是&lt;unix timestamp&gt; &lt;time zone offset&gt;,其中&lt;unix timestamp&gt;是自 UNIX 纪元以来的秒数。 &lt;time zone offset&gt;是 UTC 的正偏移或负偏移。例如,CET(比 UTC 早 1 小时)是 0100

代码语言:javascript复制
 RFC 2822 

RFC 2822 描述的标准电子邮件格式,例如Thu, 07 Apr 2005 22:13:13 0200

代码语言:javascript复制
 ISO 8601 

ISO 8601 标准规定的时间和日期,例如2005-04-07T22:13:13。解析器也接受空格而不是T字符。

| 注意 | 此外,日期部分以下列格式接受:YYYY.MM.DDMM/DD/YYYYDD.MM.YYYY。 |

例子

录制自己的作品时,工作树中已修改文件的内容会暂时存储到名为“索引”的暂存区域,并带有 git add 。一个文件只能在索引中但不能在工作树中恢复为使用git reset HEAD -- &lt;file&gt;的最后一次提交的文件,这会有效地恢复 git add 并阻止对该文件的更改参与下一次提交。在使用这些命令逐步构建要提交的状态之后,git commit(没有任何路径名参数)用于记录到目前为止已经暂存的内容。这是命令的最基本形式。一个例子:

代码语言:javascript复制
$ edit hello.c
$ git rm goodbye.c
$ git add hello.c
$ git commit

您可以告诉git commit注意在工作树中跟踪其内容的文件的更改,并为您执行相应的git addgit rm,而不是在每次更改后暂存文件。也就是说,如果您的工作树中没有其他更改,则此示例与前面的示例相同:

代码语言:javascript复制
$ edit hello.c
$ rm goodbye.c
$ git commit -a

命令git commit -a首先查看您的工作树,注意您已修改了 hello.c 并删除了 goodbye.c,并为您执行必要的git addgit rm

在对多个文件进行暂存更改后,您可以通过为git commit提供路径名来更改记录更改的顺序。给出路径名时,该命令进行提交,仅记录对命名路径所做的更改:

代码语言:javascript复制
$ edit hello.c hello.h
$ git add hello.c hello.h
$ edit Makefile
$ git commit Makefile

这使得提交记录了对Makefile的修改。 hello.chello.h暂挂的更改不包含在生成的提交中。然而,他们的变化并没有丢失 - 他们仍然上演并且只是被阻止。完成上述步骤后,如果您这样做:

代码语言:javascript复制
$ git commit

第二次提交将按预期记录对hello.chello.h的更改。

合并后(由 git mergegit pull 启动)因冲突而停止,已经暂停合并的路径为您提交,并且冲突的路径保持未合并状态。你必须首先检查哪些路径与 git status 有冲突,并且在你的工作树中手动修复它们之后,你会像往常一样使用 git add 来调整结果:

代码语言:javascript复制
$ git status | grep unmerged
unmerged: hello.c
$ edit hello.c
$ git add hello.c

解决冲突并暂存结果后,git ls-files -u将停止提及冲突的路径。完成后,运行git commit以最终记录合并:

代码语言:javascript复制
$ git commit

与记录您自己的更改的情况一样,您可以使用-a选项来保存输入。一个区别是,在合并解析期间,您不能将git commit与路径名一起使用来更改提交更改的顺序,因为合并应记录为单个提交。实际上,命令拒绝在给定路径名时运行(但请参阅-i选项)。

讨论

虽然不是必需的,但最好使用一个简短(小于 50 个字符)的行来概括更改,然后是空白行,然后是更详尽的描述。提交消息中第一个空白行的文本被视为提交标题,并且该标题在整个 Git 中使用。例如, git-format-patch [1] 将提交转换为电子邮件,它使用主题行上的标题和正文中的其余提交。

Git 在某种程度上是字符编码不可知的。

  • blob 对象的内容是未解释的字节序列。核心级别没有编码转换。
  • 路径名以 UTF-8 规范化形式 C 编码。这适用于树对象,索引文件,ref 名称,以及命令行参数,环境变量和配置文件中的路径名(.git/config(参见 git) -config [1] ), gitignore [5] , gitattributes [5] 和 gitmodules [5] )。 请注意,核心级别的 Git 仅将路径名称视为非 NUL 字节序列,没有路径名称编码转换(Mac 和 Windows 除外)。因此,即使在使用传统扩展 ASCII 编码的平台和文件系统上,使用非 ASCII 路径名也会起作用。但是,在此类系统上创建的存储库将无法在基于 UTF-8 的系统(例如 Linux,Mac,Windows)上正常工作,反之亦然。此外,许多基于 Git 的工具只是假设路径名为 UTF-8,并且无法正确显示其他编码。
  • 提交日志消息通常以 UTF-8 编码,但也支持其他扩展 ASCII 编码。这包括 ISO-8859-x,CP125x 和许多其他,但 _ 不是 _ UTF-16/32,EBCDIC 和 CJK 多字节编码(GBK,Shift-JIS,Big5,EUC-x,CP9xx 等。 )。

虽然我们鼓励提交日志消息以 UTF-8 编码,但核心和 Git 瓷器都不是为了强制项目使用 UTF-8。如果特定项目的所有参与者发现使用遗留编码更方便,Git 不会禁止它。但是,有一些事情需要牢记。

git commitgit commit-tree 发出警告,如果提供给它的提交日志消息看起来不像有效的 UTF-8 字符串,除非你明确说你的项目使用了遗产编码。说这个的方法是在.git/config文件中使用 i18n.commitencoding,如下所示:

代码语言:javascript复制
[i18n]
	commitEncoding = ISO-8859-1

使用上述设置创建的提交对象在其encoding标题中记录i18n.commitEncoding的值。这是为了帮助其他人以后再看。缺少此标头意味着提交日志消息以 UTF-8 编码。

git loggit showgit blame 和朋友们查看提交对象的encoding头,并尝试将日志消息重新编码为除非另有说明,否则为 UTF-8。您可以使用.git/config文件中的i18n.logOutputEncoding指定所需的输出编码,如下所示:

代码语言:javascript复制
[i18n]
	logOutputEncoding = ISO-8859-1

如果您没有此配置变量,则使用i18n.commitEncoding的值。

请注意,我们故意选择在提交以在提交对象级别强制使用 UTF-8 时不重新编写提交日志消息,因为重新编码为 UTF-8 不一定是可逆操作。

环境和配置变量

用于编辑提交日志消息的编辑器将从GIT_EDITOR环境变量,core.editor 配置变量,VISUAL环境变量或EDITOR环境变量(按此顺序)中选择。有关详细信息,请参阅 git-var [1] 。

挂钩

该命令可以运行commit-msgprepare-commit-msgpre-commitpost-commitpost-rewrite挂钩。有关详细信息,请参阅 githooks [5] 。

FILES

代码语言:javascript复制
 $GIT_DIR/COMMIT_EDITMSG 

此文件包含正在进行的提交的提交消息。如果在创建提交之前由于错误而退出git commit,则用户提供的任何提交消息(例如,在编辑器会话中)将在此文件中可用,但将在下一次调用[COD1 时]覆盖]。

也可以看看

git-add [1] , git-rm [1] , git-mv [1] , git-merge [1] , git-commit-tree [1]

GIT

部分 git [1] 套件

git-reset

原文: git-scm.com/docs/git-reset

名称

git-reset - 将当前 HEAD 重置为指定状态

概要

代码语言:javascript复制
git reset [-q] [<tree-ish>] [--] <paths>…​
git reset (--patch | -p) [<tree-ish>] [--] [<paths>…​]
git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]

描述

在第一种和第二种形式中,将条目从<tree-ish>复制到索引。在第三种形式中,将当前分支头(HEAD)设置为<commit>,可选择修改索引和工作树以匹配。所有形式的<tree-ish> / <commit>默认为HEAD

代码语言:javascript复制
 git reset [-q] [<tree-ish>] [--] <paths>…​ 

此表单将所有<paths>的索引条目重置为<tree-ish>的状态。(它不会影响工作树或当前分支。)

这意味着git reset <paths>git add <paths>相反。

运行git reset <paths>更新索引条目后,可以使用 git-checkout [1] 检查工作树索引中的内容。或者,使用 git-checkout [1] 并指定提交,您可以一次性将提交中的路径内容复制到索引和工作树。

代码语言:javascript复制
 git reset (--patch | -p) [<tree-ish>] [--] [<paths>…​] 

在索引和<tree-ish>(默认为HEAD)之间的差异中交互式选择某块。选择的块与索引相反。

这意味着git reset -pgit add -p相反,即您可以使用它来选择性地重置代码块。请参阅 git-add [1] 的“交互模式”部分,了解如何操作--patch模式。

代码语言:javascript复制
 git reset [<mode>] [<commit>] 

此表单将当前分支头重置为<commit>,并可能根据<mode>更新索引(将其重置为<commit>的树)和工作树。如果省略<mode>,则默认为--mixed<mode>必须是以下之一:

代码语言:javascript复制
 --soft 

根本不接触索引文件或工作树(但将头节点重置为<commit>,就像所有模式一样)。这将保留所有已更改的文件“要提交的更改”,如git status所示。

代码语言:javascript复制
 --mixed 

重置索引但不重置工作树(即,保留更改的文件但未标记为提交)并报告尚未更新的内容。这是默认操作。

如果指定了-N,则删除的路径将标记为意图添加(请参阅 git-add [1] )。

代码语言:javascript复制
 --hard 

重置索引和工作树。自<commit>以来对工作树中跟踪文件的任何更改都将被丢弃。

代码语言:javascript复制
 --merge 

重置索引并更新工作树中<commit>HEAD之间不同的文件,但保留索引和工作树之间不同的文件(即具有尚未添加的更改)。如果<commit>和索引之间不同的文件具有未暂存更改,则重置将中止。

换句话说,--merge执行类似git read-tree -u -m <commit>的操作,但会继承未合并的索引条目。

代码语言:javascript复制
 --keep 

重置索引条目并更新工作树中<commit>HEAD之间不同的文件。如果<commit>HEAD之间不同的文件具有本地更改,则重置将中止。

如果你想撤消除分支上最新的提交, git-revert [1] 是你的朋友。

选项

代码语言:javascript复制
 -q 
代码语言:javascript复制
 --quiet 
代码语言:javascript复制
 --no-quiet 

保持安静,只报告错误。默认行为由reset.quiet配置选项设置。 --quiet--no-quiet将覆盖默认行为。

例子

代码语言:javascript复制
 Undo add 
代码语言:javascript复制
$ edit                                     (1)
$ git add frotz.c filfre.c
$ mailx                                    (2)
$ git reset                                (3)
$ git pull git://info.example.com/ nitfol  (4)
  1. 您正在愉快地处理某些事情,并发现这些文件中的更改处于良好状态。当您运行git diff时,您不希望看到它们,因为您计划处理其他文件,并且使用这些文件进行更改会分散注意力。
  2. 有人要求你拉更新,这些变化听起来值得合并。
  3. 但是,您已经弄脏了索引(即您的索引与HEAD提交不匹配)。但是你知道你要做的更新不会影响frotz.cfilfre.c,所以你还原这两个文件的索引变化。您在工作树中的更改仍然存在。
  4. 然后你可以更新和合并,在工作树中仍然保留frotz.cfilfre.c
代码语言:javascript复制
 Undo a commit and redo 
代码语言:javascript复制
$ git commit ...
$ git reset --soft HEAD^      (1)
$ edit                        (2)
$ git commit -a -c ORIG_HEAD  (3)
  1. 当您记得刚刚提交的内容不完整,或者拼错了提交消息,或者两者兼而有之时,通常会这样做。在“重置”之前留下工作树。
  2. 对工作树文件进行更正。
  3. “重置”将旧头复制到.git/ORIG_HEAD;通过从其日志消息开始重做提交。如果您不需要进一步编辑消息,则可以改为使用-C选项。

另请参见 git-commit [1] 的--amend选项。

代码语言:javascript复制
 Undo a commit, making it a topic branch 
代码语言:javascript复制
$ git branch topic/wip     (1)
$ git reset --hard HEAD~3  (2)
$ git checkout topic/wip   (3)
  1. 你做了一些提交,但意识到他们在master分支中还为时过早。您想在主题分支中继续抛光它们,因此从当前HEAD创建topic/wip分支。
  2. 倒回 master 分支以摆脱这三个提交。
  3. 切换到topic/wip分支并继续工作。
代码语言:javascript复制
 Undo commits permanently 
代码语言:javascript复制
$ git commit ...
$ git reset --hard HEAD~3   (1)
  1. 最后三次提交(HEADHEAD^HEAD~2)很糟糕,你不想再看到它们。如果你已经将这些提交给了其他人,那么不要这样做。 (有关这样做的含义,请参阅 git-rebase [1] 中的“从上游返回的恢复”部分。)
代码语言:javascript复制
 Undo a merge or pull 
代码语言:javascript复制
$ git pull                         (1)
Auto-merging nitfol
CONFLICT (content): Merge conflict in nitfol
Automatic merge failed; fix conflicts and then commit the result.
$ git reset --hard                 (2)
$ git pull . topic/branch          (3)
Updating from 41223... to 13134...
Fast-forward
$ git reset --hard ORIG_HEAD       (4)
  1. 尝试从上游更新导致了很多冲突;你现在还没有准备好花很多时间合并,所以你决定稍后再这样做。
  2. “pull”没有进行合并提交,因此作为git reset --hard HEAD同义词的git reset --hard清除了索引文件和工作树中的混乱。
  3. 将主题分支合并到当前分支,这导致快进。
  4. 但是你决定主题分支尚未准备好供公众使用。 “pull”或“merge”总是在ORIG_HEAD中保留当前分支的原始提示,因此重新设置它会使您的索引文件和工作树返回到该状态,并将分支的提示重置为该提交。
代码语言:javascript复制
 Undo a merge or pull inside a dirty working tree 
代码语言:javascript复制
$ git pull                         (1)
Auto-merging nitfol
Merge made by recursive.
 nitfol                |   20      ----
 ...
$ git reset --merge ORIG_HEAD      (2)
  1. 即使您可能在工作树中进行了本地修改,当您知道另一个分支中的更改与它们不重叠时,您也可以安全地说出git pull
  2. 检查合并结果后,您可能会发现另一个分支的更改不能令人满意。运行git reset --hard ORIG_HEAD将让您回到原来的位置,但它会丢弃您不想要的本地更改。 git reset --merge保留您的本地更改。
代码语言:javascript复制
 Interrupted workflow 

假设您在进行大量更改时被紧急修复请求打断。工作树中的文件尚未提交任何形状,但您需要到另一个分支进行快速修复。

代码语言:javascript复制
$ git checkout feature ;# you were working in "feature" branch and
$ work work work       ;# got interrupted
$ git commit -a -m "snapshot WIP"                 (1)
$ git checkout master
$ fix fix fix
$ git commit ;# commit with real log
$ git checkout feature
$ git reset --soft HEAD^ ;# go back to WIP state  (2)
$ git reset                                       (3)
  1. 这个提交将被吹走,所以扔掉日志消息就可以了。
  2. 这将从提交历史记录中删除 WIP 提交,并将工作树设置为创建快照之前的状态。
  3. 此时,索引文件仍然包含您作为 _ 快照 WIP_ 提交的所有 WIP 更改。这将更新索引以将您的 WIP 文件显示为未提交。

另见 git-stash [1] 。

代码语言:javascript复制
 Reset a single file in the index 

假设您已将文件添加到索引中,但后来决定不想将其添加到提交中。您可以从索引中删除文件,同时使用 git reset 保留更改。

代码语言:javascript复制
$ git reset -- frotz.c                      (1)
$ git commit -m "Commit files in index"     (2)
$ git add frotz.c                           (3)
  1. 这会将文件从索引中删除,同时将其保留在工作目录中。
  2. 这将提交索引中的所有其他更改。
  3. 再次将文件添加到索引。
代码语言:javascript复制
 Keep changes in working tree while discarding some previous commits 

假设您正在处理某些事情并且提交它,然后您继续工作,但现在您认为您工作树中的内容应该位于与您之前提交的内容无关的另一个分支中。您可以启动新分支并重置它,同时保持工作树中的更改。

代码语言:javascript复制
$ git tag start
$ git checkout -b branch1
$ edit
$ git commit ...                            (1)
$ edit
$ git checkout -b branch2                   (2)
$ git reset --keep start                    (3)
  1. 这将在branch1中提交您的第一次编辑。
  2. 在理想世界中,您可能已经意识到,当您创建并切换到branch2(即git checkout -b branch2 start)时,较早的提交不属于新主题,但没有人是完美的。
  3. 但是,切换到branch2后,可以使用reset --keep删除不需要的提交。
代码语言:javascript复制
 Split a commit apart into a sequence of commits 

假设您已经创建了许多逻辑上独立的更改并将它们一起提交。然后,稍后您决定让每个逻辑块与其自己的提交相关联可能更好。您可以使用 git reset 来回滚历史记录而不更改本地文件的内容,然后使用git add -p以交互方式选择要包含在每个提交中的数据库,使用git commit -c预先填充提交消息。

代码语言:javascript复制
$ git reset -N HEAD^                        (1)
$ git add -p                                (2)
$ git diff --cached                         (3)
$ git commit -c HEAD@{1}                    (4)
...                                         (5)
$ git add ...                               (6)
$ git diff --cached                         (7)
$ git commit ...                            (8)
  1. 首先,将历史记录重置为一次提交,以便我们删除原始提交,但保留工作树中的所有更改。 -N 确保添加HEAD的任何新文件仍然被标记,以便git add -p找到它们。
  2. 接下来,我们使用git add -p工具以交互方式选择要添加的差异。这将按顺序询问每个差异块,您可以使用简单的命令,例如“是,包括此”,“不包括此”,甚至是非常强大的“编辑”工具。
  3. 一旦对您想要包含的代码块感到满意,您应该使用git diff --cached为第一次提交准备的内容验证。这显示了已移入索引并即将提交的所有更改。
  4. 接下来,提交存储在索引中的更改。 -c选项指定从第一次提交中启动的原始消息预填充提交消息。这有助于避免重新输入。 HEAD@{1}HEAD曾经在原始重置提交之前进行的提交的特殊表示法(1 更改前)。有关详细信息,请参阅 git-reflog [1] 。您还可以使用任何其他有效的提交引用。
  5. 您可以多次重复步骤 2-4,将原始代码分解为任意数量的提交。
  6. 现在,您已将许多更改拆分为自己的提交,并且可能不再使用git add的修补程序模式,以便选择所有剩余的未提交更改。
  7. 再次检查以确认您已包含所需内容。您可能还希望验证 git diff 不会显示稍后要提交的任何剩余更改。
  8. 最后创建最终提交。

讨论

下表显示了运行时会发生什么:

代码语言:javascript复制
git reset --option target

根据文件的状态,使用不同的重置选项将HEAD重置为另一个提交(target)。

在这些表中,ABCD是文件的某些不同状态。例如,第一个表的第一行表示如果文件在工作树中处于状态A,在索引中处于状态B,在HEAD上是状态C,在目标节点中是状态Dgit reset --soft target将文件保留在状态A的工作树中和状态B的索引中。它将HEAD(即当前分支的尖端,如果你在其中)重置(即移动)到target(其文件处于状态D)。

代码语言:javascript复制
working index HEAD target         working index HEAD
----------------------------------------------------
 A       B     C    D     --soft   A       B     D
			  --mixed  A       D     D
			  --hard   D       D     D
			  --merge (disallowed)
			  --keep  (disallowed)
代码语言:javascript复制
working index HEAD target         working index HEAD
----------------------------------------------------
 A       B     C    C     --soft   A       B     C
			  --mixed  A       C     C
			  --hard   C       C     C
			  --merge (disallowed)
			  --keep   A       C     C
代码语言:javascript复制
working index HEAD target         working index HEAD
----------------------------------------------------
 B       B     C    D     --soft   B       B     D
			  --mixed  B       D     D
			  --hard   D       D     D
			  --merge  D       D     D
			  --keep  (disallowed)
代码语言:javascript复制
working index HEAD target         working index HEAD
----------------------------------------------------
 B       B     C    C     --soft   B       B     C
			  --mixed  B       C     C
			  --hard   C       C     C
			  --merge  C       C     C
			  --keep   B       C     C
代码语言:javascript复制
working index HEAD target         working index HEAD
----------------------------------------------------
 B       C     C    D     --soft   B       C     D
			  --mixed  B       D     D
			  --hard   D       D     D
			  --merge (disallowed)
			  --keep  (disallowed)
代码语言:javascript复制
working index HEAD target         working index HEAD
----------------------------------------------------
 B       C     C    C     --soft   B       C     C
			  --mixed  B       C     C
			  --hard   C       C     C
			  --merge  B       C     C
			  --keep   B       C     C

reset --merge用于在重置合并冲突时使用。任何 mergy 操作都应保证在工作树中涉及的合的文件,在开始合并之前,本地索引没有相应更改,并且它将合并结果写入工作树中。因此,如果我们看到索引和目标之间以及索引和工作树之间存在某些差异,那么这意味着当由于冲突导致合并失败后,我们不能通过 reset 操作将状态重置出来。这就是我们在这种情况下不允许--merge选项的原因。

在保留当前分支中的一些最后提交的同时保留工作树中的更改时,将使用reset --keep。如果我们要删除的提交中的更改与我们要保留的工作树中的更改之间可能存在冲突,则不允许重置。如果工作树和HEAD之间以及HEAD和目标之间存在变化,那么就不允许这样做。为了安全起见,当有未合并的条目时也不允许这样做。

下表显示了存在未合并条目时会发生什么:

代码语言:javascript复制
working index HEAD target         working index HEAD
----------------------------------------------------
 X       U     A    B     --soft  (disallowed)
			  --mixed  X       B     B
			  --hard   B       B     B
			  --merge  B       B     B
			  --keep  (disallowed)
代码语言:javascript复制
working index HEAD target         working index HEAD
----------------------------------------------------
 X       U     A    A     --soft  (disallowed)
			  --mixed  X       A     A
			  --hard   A       A     A
			  --merge  A       A     A
			  --keep  (disallowed)

X表示任何状态,U表示未合并的索引。

GIT

部分 git [1] 套件

git-rm

原文: git-scm.com/docs/git-rm

名称

git-rm - 从工作树和索引中删除文件

概要

代码语言:javascript复制
git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>…​

描述

从索引中删除文件,或从工作树和索引中删除文件。 git rm不会仅从您的工作目录中删除文件。 (没有选项能只将文件从工作树中删除而还在索引中保留;如果非要这样做,请使用/bin/rm。)要删除的文件必须与分支的尖端相同,并且虽然可以使用-f选项覆盖默认行为,但不能在索引中暂存对其内容的更新。当给出--cached时,分阶段内容必须匹配分支的尖端或磁盘上的文件,从而允许仅从索引中删除文件。

选项

代码语言:javascript复制
 <file>…​ 

要删除的文件。可以给出 Fileglobs(例如*.c)以删除所有匹配的文件。如果你想让 Git 扩展文件 glob 字符,你可能需要 shell 转义它们。可以给出一个前置目录名称(例如,删除dir/file1dir/file2dir)以删除目录中的所有文件,并递归地删除所有子目录,但这需要明确给出-r选项。

代码语言:javascript复制
 -f 
代码语言:javascript复制
 --force 

覆盖最新的检查。

代码语言:javascript复制
 -n 
代码语言:javascript复制
 --dry-run 

实际上不要删除任何文件。相反,只显示它们是否存在于索引中,否则将被命令删除。

代码语言:javascript复制
 -r 

在给出前导目录名时允许递归删除。

代码语言:javascript复制
 -- 

此选项可用于将命令行选项与文件列表分开(当文件名可能被误认为是命令行选项时很有用)。

代码语言:javascript复制
 --cached 

使用此选项仅从索引中取消暂存和删除路径。无论是否修改了工作树文件,都将保持不变。

代码语言:javascript复制
 --ignore-unmatch 

即使没有匹配的文件,也以零状态退出。

代码语言:javascript复制
 -q 
代码语言:javascript复制
 --quiet 

git rm通常为每个删除的文件输出一行(以rm命令的形式)。此选项会禁止输出。

讨论

给予命令的列表可以是精确的路径名,文件 glob 模式或前置目录名。该命令仅删除 Git 已知的路径。已知文件路径,但没有告诉 Git 的文件不会被删除。

文件通配符跨目录边界匹配。因此,给定两个目录dd2,使用git rm 'd*'git rm 'd/*'之间存在差异,因为前者也将删除所有目录d2

删除已从文件系统中消失的文件

git rm没有选项只从索引中删除从文件系统中消失的路径。但是,根据用例,有几种方法可以完成。

使用“git commit -a”

如果您打算下一次提交应记录工作树中跟踪文件的所有修改,并记录已使用rm(而不是git rm)从工作树中删除的文件的所有删除,请使用git commit -a,因为它会自动注意并记录所有删除。通过使用git add -u,您也可以在不提交的情况下获得类似的效果。

使用“git add -A”

当接受供应商分支的新代码丢弃时,您可能希望记录路径的删除和新路径的添加以及现有路径的修改。

通常,您将首先使用以下命令从工作树中删除所有跟踪的文件:

代码语言:javascript复制
git ls-files -z | xargs -0 rm -f

然后解压缩工作树中的新代码。或者你可以 rsync 对工作树进行更改。

之后,记录工作树中所有删除,添加和修改的最简单方法是:

代码语言:javascript复制
git add -A

见 git-add [1] 。

其他方法

如果您真正想要做的就是从索引中删除工作树中不再存在的文件(可能是因为您的工作树是脏的,因此您无法使用git commit -a),请使用以下命令:

代码语言:javascript复制
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached

子模块

只有使用 gitfile 的子模块(这意味着它们用 Git 1.7.8 或更新版本克隆)将从工作树中删除,因为它们的存储库位于超级项目的.git 目录中。如果子模块(或其中嵌套的子模块之一)仍然使用.git 目录,git rm会将子模块 git 目录移动到 superprojects git 目录中以保护子模块的历史记录。如果在gitmodules [5]中存在 submodule.部分,那么文件将被删除,并被暂存(除非使用了–cached 或-n)。

当 HEAD 与索引中记录的相同时,子模块被认为是最新的,未修改跟踪文件,并且子模块工作树中不存在未被忽略的未跟踪文件。忽略的文件被认为是可消耗的,并且不会阻止子模块的工作树被删除。

如果您只想从工作树中删除子模块的本地签出而不提交删除,请改用 git-submodule [1] deinit。有关子模块移除的详细信息,请参见 gitsubmodules [7] 。

例子

代码语言:javascript复制
 git rm Documentation/*.txt 

从索引中的Documentation目录及其任何子目录中删除所有*.txt文件。

请注意,在此示例中,引用了星号*;这让 Git 而不是 shell 扩展了Documentation/目录下的文件和子目录的路径名。

代码语言:javascript复制
 git rm -f git-*.sh 

因为此示例允许 shell 展开星号(即您明确列出文件),所以它不会删除subdir/git-foo.sh

BUGS

每次超级项目更新删除填充的子模块时(例如,在删除之前和之后切换提交时),旧的子模块检出将保留在旧位置。删除旧目录只有在使用 gitfile 时才是安全的,否则子模块的历史记录也将被删除。当实现递归子模块更新时,此步骤将过时。

也可以看看

git-add [1]

GIT

部分 git [1] 套件

git-mv

原文: git-scm.com/docs/git-mv

名称

git-mv - 移动或重命名文件,目录或符号链接

概要

代码语言:javascript复制
git mv <options>…​ <args>…​

描述

移动或重命名文件,目录或符号链接。

代码语言:javascript复制
git mv [-v] [-f] [-n] [-k] <source> <destination>
git mv [-v] [-f] [-n] [-k] <source> ... <destination directory>

在第一种形式中,它将重命名为,必须存在,并且可以是文件,符号链接或目录。在第二种形式中,最后一个参数必须是现有目录;给定的源将被移动到此目录中。

成功完成后会更新索引,但仍必须提交更改。

选项

代码语言:javascript复制
 -f 
代码语言:javascript复制
 --force 

即使目标存在,也强制重命名或移动文件

代码语言:javascript复制
 -k 

跳过移动或重命名可能导致错误情况的操作。当源既不存在也不由 Git 控制时,将发生错误,或者除非给出-f,覆盖现有文件时也会发生错误。

代码语言:javascript复制
 -n 
代码语言:javascript复制
 --dry-run 

没做什么;只显示会发生什么

代码语言:javascript复制
 -v 
代码语言:javascript复制
 --verbose 

在移动文件时报告文件的名称。

子模

使用 gitfile 移动子模块(这意味着它们使用 Git 1.7.8 或更高版本克隆)将更新 gitfile 和 core.worktree 设置以使子模块在新位置工作。它还将尝试更新 gitmodules [5] 文件中的子模块.path 设置并暂存该文件(除非使用-n)。

BUGS

每次超级项目更新移动填充的子模块时(例如,当在移动之前和之后切换提交时),旧的子模块检出将保留在旧位置,并且空目录将出现在新位置。要在新位置再次填充子模块,用户必须在之后运行“git submodule update”。删除旧目录只有在使用 gitfile 时才是安全的,否则子模块的历史记录也将被删除。当实现递归子模块更新时,这两个步骤都将过时。

GIT

部分 git [1] 套件

git-branch

原文: git-scm.com/docs/git-branch

名称

git-branch - 列出,创建或删除分支

概要

代码语言:javascript复制
git branch [--color[=<when>] | --no-color] [-r | -a]
	[--list] [-v [--abbrev=<length> | --no-abbrev]]
	[--column[=<options>] | --no-column] [--sort=<key>]
	[(--merged | --no-merged) [<commit>]]
	[--contains [<commit]] [--no-contains [<commit>]]
	[--points-at <object>] [--format=<format>] [<pattern>…​]
git branch [--track | --no-track] [-f] <branchname> [<start-point>]
git branch (--set-upstream-to=<upstream> | -u <upstream>) [<branchname>]
git branch --unset-upstream [<branchname>]
git branch (-m | -M) [<oldbranch>] <newbranch>
git branch (-c | -C) [<oldbranch>] <newbranch>
git branch (-d | -D) [-r] <branchname>…​
git branch --edit-description [<branchname>]

描述

如果给出--list,或者没有非选项参数,则列出现有分支;当前分支将以星号突出显示。选项-r列出远程跟踪分支,选项-a显示本地和远程分支。如果给出<pattern>,则将其用作 shell 通配符以将输出限制为匹配的分支。如果给出了多个模式,则如果它与任何模式匹配,则显示分支。注意,提供<pattern>时,必须使用--list;否则该命令被解释为创建分支。

使用--contains,仅显示包含命名提交的分支(换句话说,提示提交是指定提交的后代的分支),--no-contains将其反面。使用--merged,将仅列出已合并到命名提交的分支(即,可以从命名提交到提示提交的分支)。使用--no-merged将仅列出未合并到命名提交的分支。如果参数缺失它默认为HEAD(即当前分支的尖端)。

命令的第二个表单创建一个名为的新分支头。它指向当前的HEAD,或者是如果有给予的话。关于举一个特殊的例子,你可以使用简写的"A...B"取得 A 和 B 的共同父节点,如果他们只存在一个。你可以使用 A、B 中的一个,默认是HEAD

请注意,这将创建新分支,但不会将工作树切换到它;使用“git checkout< newbranch>”切换到新分支。

当本地分支从远程跟踪分支启动时,Git 设置分支(特别是branch.<name>.remotebranch.<name>.merge配置条目),以便 git pull 能适当地从远程跟踪分支合并本地。可以通过全局branch.autoSetupMerge配置标志更改此行为。可以使用--track--no-track选项覆盖该设置,稍后使用git branch --set-upstream-to进行更改。

使用-m-M选项,将重命名为。如果有一个相应的 reflog,它被重命名为匹配,并创建一个 reflog 条目来记住分支重命名。如果存在,-M 必须用于强制重命名发生。

-c-C选项具有与-m-M完全相同的语义,除了将分支与其配置重命名,并且 reflog 将被复制到新名称。

使用-d-D选项,<branchname>将被删除。您可以指定多个分支进行删除。如果分支当前有 reflog,那么 reflog 也将被删除。

-r-d一起使用以删除远程跟踪分支。请注意,如果远程存储库中不再存在远程跟踪分支,或者如果 git fetch 配置为不再获取它们,则删除它们才有意义。另请参阅 git-remote [1] 的 prune 子命令,了解清除所有过时的远程跟踪分支的方法。

选项

代码语言:javascript复制
 -d 
代码语言:javascript复制
 --delete 

删除分支。分支必须在其上游分支中完全合并,或者如果没有使用--track--set-upstream-to设置上游,则必须在HEAD中合并。

代码语言:javascript复制
 -D 

--delete --force的快捷方式。

代码语言:javascript复制
 --create-reflog 

创建分支的 reflog。这将激活记录对分支引用所做的所有更改,从而可以使用基于日期的 sha1 表达式,例如“ @ {yesterday}”。请注意,在非裸存储库中,默认情况下,core.logAllRefUpdates配置选项通常会启用 reflog。否定形式--no-create-reflog仅覆盖较早的--create-reflog,但目前不会否定core.logAllRefUpdates的设置。

代码语言:javascript复制
 -f 
代码语言:javascript复制
 --force 

重置到,即使已存在。没有-fgit branch 拒绝更改现有分支。与-d(或--delete)结合使用,允许删除分支,而不管其合并状态如何。与-m(或--move)结合使用,即使新分支名称已存在,也允许重命名分支,这同样适用于-c(或--copy)。

代码语言:javascript复制
 -m 
代码语言:javascript复制
 --move 

移动/重命名分支和相应的 reflog。

代码语言:javascript复制
 -M 

--move --force的快捷方式。

代码语言:javascript复制
 -c 
代码语言:javascript复制
 --copy 

复制分支和相应的 reflog。

代码语言:javascript复制
 -C 

--copy --force的快捷方式。

代码语言:javascript复制
 --color[=<when>] 

颜色分支以突出显示当前,本地和远程跟踪分支。该值必须为 always(默认值),never 或 auto。

代码语言:javascript复制
 --no-color 

即使配置文件提供默认的颜色输出,也要关闭分支颜色。与--color=never相同。

代码语言:javascript复制
 -i 
代码语言:javascript复制
 --ignore-case 

排序和过滤分支不区分大小写。

代码语言:javascript复制
 --column[=<options>] 
代码语言:javascript复制
 --no-column 

在列中显示分支列表。有关选项语法,请参阅配置变量 column.branch。没有选项的--column--no-column分别相当于 alwaysnever

此选项仅适用于非详细模式。

代码语言:javascript复制
 -r 
代码语言:javascript复制
 --remotes 

列出或删除(如果与-d 一起使用)远程跟踪分支。

代码语言:javascript复制
 -a 
代码语言:javascript复制
 --all 

列出远程跟踪分支和本地分支。

代码语言:javascript复制
 -l 
代码语言:javascript复制
 --list 

列出分支。使用可选的<pattern>...,例如git branch --list 'maint-*',仅列出与模式匹配的分支。

代码语言:javascript复制
 -v 
代码语言:javascript复制
 -vv 
代码语言:javascript复制
 --verbose 

在列表模式下,显示每个头的 sha1 和提交主题行,以及与上游分支(如果有)的关系。如果给出两次,也打印上游分支的名称(另请参见git remote show <remote>)。

代码语言:javascript复制
 -q 
代码语言:javascript复制
 --quiet 

在创建或删除分支时更安静,禁止出现非错误消息。

代码语言:javascript复制
 --abbrev=<length> 

在输出列表中更改 sha1 的最小显示长度。默认值为 7,可以通过core.abbrev配置选项覆盖。

代码语言:javascript复制
 --no-abbrev 

在输出列表中显示完整的 sha1,而不是缩写它们。

代码语言:javascript复制
 -t 
代码语言:javascript复制
 --track 

创建新分支时,设置branch.<name>.remotebranch.<name>.merge配置条目以将起点分支标记为新分支的“上游”。此配置将告诉 git 显示git statusgit branch -v中两个分支之间的关系。此外,它在没有参数的情况下指示git pull在检出新分支时从上游拉出。

当起点是远程跟踪分支时,此行为是默认行为。如果希望git checkoutgit branch始终表现得像--no-track一样,请将 branch.autoSetupMerge 配置变量设置为false。如果在起点是本地或远程跟踪分支时需要此行为,请将其设置为always

代码语言:javascript复制
 --no-track 

即使 branch.autoSetupMerge 配置变量为 true,也不要设置“上游”配置。

代码语言:javascript复制
 --set-upstream 

由于此选项具有令人困惑的语法,因此不再支持它。请改用--track--set-upstream-to

代码语言:javascript复制
 -u <upstream> 
代码语言:javascript复制
 --set-upstream-to=<upstream> 

设置的跟踪信息,以便被认为是的上游分支。如果没有指定上游分支,则默认为当前分支。

代码语言:javascript复制
 --unset-upstream 

删除的上游信息。如果未指定分支,则默认为当前分支。

代码语言:javascript复制
 --edit-description 

打开编辑器并编辑文本以解释分支的用途,供各种其他命令使用(例如format-patchrequest-pullmerge(如果已启用))。可以使用多行解释。

代码语言:javascript复制
 --contains [<commit>] 

仅列出包含指定提交的分支(如果未指定,则为 HEAD)。意味着--list

代码语言:javascript复制
 --no-contains [<commit>] 

仅列出不包含指定提交的分支(如果未指定,则为 HEAD)。意味着--list

代码语言:javascript复制
 --merged [<commit>] 

仅列出其提示可从指定提交到达的分支(如果未指定,则为 HEAD)。意味着--list,与--no-merged不兼容。

代码语言:javascript复制
 --no-merged [<commit>] 

仅列出其提示无法从指定的提交访问的分支(如果未指定,则为 HEAD)。意味着--list,与--merged不兼容。

代码语言:javascript复制
 <branchname> 

要创建或删除的分支的名称。新分支名称必须通过 git-check-ref-format [1] 定义的所有检查。其中一些检查可能会限制分支名称中允许的字符。

代码语言:javascript复制
 <start-point> 

新的分支头将指向此提交。它可以作为分支名称,commit-id 或标记给出。如果省略此选项,则将使用当前 HEAD。

代码语言:javascript复制
 <oldbranch> 

要重命名的现有分支的名称。

代码语言:javascript复制
 <newbranch> 

现有分支的新名称。与相同的限制应用。

代码语言:javascript复制
 --sort=<key> 

根据给定的密钥排序。前缀-按值的降序排序。您可以使用–sort =选项多次,在这种情况下,最后一个键成为主键。支持的键与git for-each-ref中的键相同。排序顺序默认为branch.sort变量(如果存在)配置的值,或基于完整 refname(包括refs/...前缀)的排序。这首先列出分离的 HEAD(如果存在),然后是本地分支,最后是远程跟踪分支。见 git-config [1] 。

代码语言:javascript复制
 --points-at <object> 

仅列出给定对象的分支。

代码语言:javascript复制
 --format <format> 

在分支 ref 和它指向的对象中插入显示%(fieldname)的字符串。格式与 git-for-each-ref [1] 的格式相同。

配置

仅在列出分支时,当使用或引用--list时,才会遵守pager.branch。默认是使用 pager。见 git-config [1] 。

例子

代码语言:javascript复制
 Start development from a known tag 
代码语言:javascript复制
$ 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
  1. 这一步和下一步可以通过“checkout -b my2.6.14 v2.6.14”组合成一个步骤。
代码语言:javascript复制
 Delete an unneeded branch 
代码语言:javascript复制
$ git clone git://git.kernel.org/.../git.git my.git
$ cd my.git
$ git branch -d -r origin/todo origin/html origin/man   (1)
$ git branch -D test                                    (2)
  1. 删除远程跟踪分支“todo”,“html”和“man”。下次 fetchpull 将再次创建它们,除非你不配置它们。参见 git-fetch [1] 。
  2. 即使“master”分支(或当前检出的任何分支)没有来自 test 分支的所有提交,也要删除“test”分支。

注意

如果要创建要立即签出的分支,则可以更轻松地使用 git checkout 命令及其-b选项来创建分支并使用单个命令将其签出。

选项--contains--no-contains--merged--no-merged有四个相关但不同的用途:

  • --contains <commit>用于在所有分支中查找包含指定的分支。如果是被重新定义或修改的,需要特别注意。
  • --no-contains <commit>与此相反,即不包含指定的的分支。
  • --merged用于查找可以安全删除的所有分支,因为这些分支完全被 HEAD 包含。
  • --no-merged用于查找要合入 HEAD 的候选分支,因为这些分支未被 HEAD 完全包含。

也可以看看

git-check-ref-format [1] , git-fetch [1] , git-remote [1] ,“了解历史:什么是分支?“在 Git 用户手册中。

GIT

部分 git [1] 套件

git-checkout

原文: git-scm.com/docs/git-checkout

名称

git-checkout - 切换分支或恢复工作树文件

概要

代码语言:javascript复制
git checkout [-q] [-f] [-m] [<branch>]
git checkout [-q] [-f] [-m] --detach [<branch>]
git checkout [-q] [-f] [-m] [--detach] <commit>
git checkout [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]
git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>…​
git checkout [<tree-ish>] [--] <pathspec>…​
git checkout (-p|--patch) [<tree-ish>] [--] [<paths>…​]

描述

更新工作树中的文件以匹配索引或指定树中的版本。如果没有给出路径, git checkout 也会更新HEAD以将指定的分支设置为当前分支。

代码语言:javascript复制
 git checkout <branch> 

要准备处理< branch>,请通过更新工作树中的索引和文件,并将 HEAD 指向分支来切换到它。保留对工作树中文件的本地修改,以便可以将它们提交到< branch>。

如果< branch>找不到但是在一个遥控器(称为< remote>)中确实存在一个具有匹配名称的跟踪分支,视为等同于

代码语言:javascript复制
$ git checkout -b <branch> --track <remote>/<branch>

如果分支存在于多个遥控器中,并且其中一个由checkout.defaultRemote配置变量命名,我们将使用该分支用于消除歧义,即使&lt;branch&gt;在所有遥控器中都不是唯一的。将其设置为例如如果&lt;branch&gt;不明确但存在于 _ 原点 _ 遥控器上,checkout.defaultRemote=origin总是从那里检出远程分支。另见 git-config [1] 中的checkout.defaultRemote

你可以省略< branch>,在这种情况下命令退化为“检查当前分支”,这是一个带有相当昂贵的副作用的美化无操作,只显示当前分支的跟踪信息(如果存在) 。

代码语言:javascript复制
 git checkout -b|-B <new_branch> [<start point>] 

指定-b会导致创建一个新分支,就像调用 git-branch [1] 然后检出一样。在这种情况下,您可以使用--track--no-track选项,这些选项将传递给 git branch 。为方便起见,没有-b--track意味着分支创建;请参阅下面的--track说明。

如果给出-B,则< new_branch>如果它不存在则被创建;否则,它被重置。这是交易的等价物

代码语言:javascript复制
$ git branch -f <branch> [<start point>]
$ git checkout <branch>

也就是说,除非“git checkout”成功,否则不会重置/创建分支。

代码语言:javascript复制
 git checkout --detach [<branch>] 
代码语言:javascript复制
 git checkout [--detach] <commit> 

准备在< commit>之上工作,方法是在其上分离 HEAD(参见“DETACHED HEAD”部分),并更新工作树中的索引和文件。保留对工作树中文件的本地修改,以便生成的工作树将是提交中记录的状态加上本地修改。

当< commit>参数是分支名称,--detach选项可用于在分支的末端分离 HEAD(git checkout &lt;branch&gt;将检查该分支而不分离 HEAD)。

省略< branch>将 HEAD 分离到当前分支的顶端。

代码语言:javascript复制
 git checkout [<tree-ish>] [--] <pathspec>…​ 

通过替换索引中的内容或< tree-ish>中的内容来覆盖工作树中的路径。 (通常是提交)。当< tree-ish>给出了与< pathspec>匹配的路径在索引和工作树中都会更新。

由于先前失败的合并,索引可能包含未合并的条目。默认情况下,如果您尝试从索引中检出此类条目,则结帐操作将失败,并且不会检出任何内容。使用-f将忽略这些未合并的条目。可以使用--ours--theirs从索引中检出合并的特定一侧的内容。使用-m,可以放弃对工作树文件所做的更改,以重新创建原始冲突的合并结果。

代码语言:javascript复制
 git checkout (-p|--patch) [<tree-ish>] [--] [<pathspec>…​] 

这类似于上面描述的“从索引或树状结构中检查工作树的路径”,但是允许您使用交互式界面显示“diff”输出并选择要在结果。有关--patch选项的说明,请参见下文。

OPTIONS

代码语言:javascript复制
 -q 
代码语言:javascript复制
 --quiet 

安静,抑制反馈信息。

代码语言:javascript复制
 --[no-]progress 

除非指定--quiet,否则默认情况下,标准错误流在连接到终端时会报告进度状态。无论--quiet如何,即使未连接到终端,该标志也会启用进度报告。

代码语言:javascript复制
 -f 
代码语言:javascript复制
 --force 

切换分支时,即使索引或工作树与 HEAD 不同,也要继续。这用于丢弃本地更改。

检查索引中的路径时,不要在未合并的条目上失败;相反,未合并的条目将被忽略。

代码语言:javascript复制
 --ours 
代码语言:javascript复制
 --theirs 

检查索引中的路径时,请查看阶段#2(_ 我们的 )或#3( 他们的 _)的未合并路径。

请注意,在git rebasegit pull --rebase期间,_ 我们的 _ 和 _ 他们的 _ 可能会出现交换; --ours给出了更改被重新分配到分支的版本,而--theirs给出了保留您正在重新定位的工作的分支的版本。

这是因为rebase用于将远程历史记录视为共享规范的工作流程,并将您要重新分支的分支上的工作视为要集成的第三方工作,并且您暂时假设在 rebase 期间,规范历史的守护者的角色。作为规范历史的守护者,您需要将远程历史记录视为ours(即“我们共享的规范历史记录​​”),而您在分支上所做的事情为theirs(即“一个贡献者的工作”顶部“)。

代码语言:javascript复制
 -b <new_branch> 

创建一个名为< new_branch>的新分支并在< start_point>开始;有关详细信息,请参阅 git-branch [1] 。

代码语言:javascript复制
 -B <new_branch> 

创建分支< new_branch>并在< start_point>开始;如果它已经存在,则将其重置为< start_point>。这相当于用“-f”运行“git branch”;有关详细信息,请参阅 git-branch [1] 。

代码语言:javascript复制
 -t 
代码语言:javascript复制
 --track 

创建新分支时,请设置“上游”配置。有关详细信息,请参阅 git-branch [1] 中的“–track”。

如果没有给出-b选项,则通过查看为相应远程配置的 refspec 的本地部分,从远程跟踪分支派生新分支的名称,然后将初始部分剥离到“ *”。这将告诉我们在分支“origin / hack”(或“remotes / origin / hack”,甚至“refs / remotes / origin / hack”)时使用“hack”作为本地分支。如果给定名称没有斜杠,或者上面的猜测结果为空名称,则中止猜测。在这种情况下,您可以使用-b明确指定名称。

代码语言:javascript复制
 --no-track 

即使 branch.autoSetupMerge 配置变量为 true,也不要设置“上游”配置。

代码语言:javascript复制
 -l 

创建新分支的 reflog;有关详细信息,请参阅 git-branch [1] 。

代码语言:javascript复制
 --detach 

不要检查分支机构来处理它,而是检查提交检查和可丢弃的实验。这是“git checkout< commit>”的默认行为何时< commit>不是分支名称。有关详细信息,请参阅下面的“DETACHED HEAD”部分。

代码语言:javascript复制
 --orphan <new_branch> 

创建一个名为< new_branch>的新 _ 孤儿 _ 分支,从< start_point>开始。并切换到它。在这个新分支上进行的第一次提交将没有父项,它将成为与所有其他分支和提交完全断开的新历史的根。

调整索引和工作树,就像之前运行“git checkout< start_point>”一样。这允许您开始记录一组类似于< start_point>的路径的新历史记录。通过轻松运行“git commit -a”来进行 root 提交。

当您想要从提交中发布树而不公开其完整历史记录时,这可能很有用。您可能希望这样做以发布项目的开源分支,该分支的当前树是“干净的”,但其完整历史记录包含专有或其他受阻的代码。

如果要启动记录一组与< start_point>完全不同的路径的断开连接的历史记录,则应在创建孤立分支后立即清除索引和工作树,方法是运行“git rm -rf “。从工作树的顶层。之后,您将准备好准备新文件,重新填充工作树,从其他地方复制它们,提取 tarball 等。

代码语言:javascript复制
 --ignore-skip-worktree-bits 

在稀疏检出模式中,git checkout -- &lt;paths&gt;将仅更新与< paths>匹配的条目。和$ GIT_DIR / info / sparse-checkout 中的稀疏模式。此选项忽略稀疏模式并添加< paths>中的所有文件。

代码语言:javascript复制
 -m 
代码语言:javascript复制
 --merge 

切换分支时,如果对当前分支和要切换到的分支之间的一个或多个文件进行本地修改,则该命令拒绝切换分支以保留上下文中的修改。但是,使用此选项,当前分支,工作树内容和新分支之间的三向合并已完成,您将进入新分支。

发生合并冲突时,冲突路径的索引条目将保持未合并状态,您需要解决冲突并使用git add标记已解析的路径(如果合并应导致路径删除,则为git rm)。

从索引检出路径时,此选项允许您在指定路径中重新创建冲突的合并。

代码语言:javascript复制
 --conflict=<style> 

与上面的–merge 选项相同,但更改了冲突的帅哥的呈现方式,覆盖了 merge.conflictStyle 配置变量。可能的值是“merge”(默认)和“diff3”(除了“merge”样式显示的内容外,还显示原始内容)。

代码语言:javascript复制
 -p 
代码语言:javascript复制
 --patch 

以< tree-ish>之间的差异交互式选择帅哥。 (或索引,如果未指定)和工作树。然后将所选择的帅哥反向应用于工作树(并且如果指定了< tree-ish>,则为索引)。

这意味着您可以使用git checkout -p有选择地丢弃当前工作树中的编辑内容。请参阅 git-add [1] 的“交互模式”部分,了解如何操作--patch模式。

代码语言:javascript复制
 --ignore-other-worktrees 

git checkout拒绝所需的 ref 已被另一个工作树检出。此选项使其无论如何都会检查引用。换句话说,ref 可以由多个工作树保存。

代码语言:javascript复制
 --[no-]recurse-submodules 

使用–recurse-submodules 将根据超级项目中记录的提交更新所有初始化子模块的内容。如果子模块中的局部修改将被覆盖,则除非使用-f,否则检出将失败。如果没有使用(或–no-recurse-submodules),子模块的工作树将不会更新。就像 git-submodule [1] 一样,这将分离子模块 HEAD。

代码语言:javascript复制
 --no-guess 

如果存在同名的远程跟踪分支,请勿尝试创建分支。

代码语言:javascript复制
 <branch> 

分店结帐;如果它引用了一个分支(即一个名称,当它以“refs / heads /”为前缀时,是一个有效的引用),则检查该分支。否则,如果它引用了有效的提交,则您的 HEAD 将变为“已分离”,并且您不再处于任何分支上(有关详细信息,请参阅下文)。

您可以使用"@{-N}"语法来引用使用“git checkout”操作检出的第 N 个最后一个分支/提交。您也可以指定与"@{-1}"同义的-

作为特殊情况,如果只有一个合并库,则可以使用"A...B"作为AB的合并库的快捷方式。您最多可以省略AB中的一个,在这种情况下,它默认为HEAD

代码语言:javascript复制
 <new_branch> 

新分支的名称。

代码语言:javascript复制
 <start_point> 

用于启动新分支的提交的名称;有关详细信息,请参阅 git-branch [1] 。默认为 HEAD。

代码语言:javascript复制
 <tree-ish> 

从结帐的树(当给出路径时)。如果未指定,将使用索引。

脱落的头

HEAD 通常指的是命名分支(例如 master )。同时,每个分支指的是特定的提交。让我们看一下有三个提交的 repo,其中一个被标记,并且分支 master 签出:

代码语言:javascript复制
           HEAD (refers to branch 'master')
            |
            v
a---b---c  branch 'master' (refers to commit 'c')
    ^
    |
  tag 'v2.0' (refers to commit 'b')

在此状态下创建提交时,将更新分支以引用新提交。具体来说, git commit 创建一个新提交 d ,其父级是 c ,然后更新分支 master 以引用新提交 d 。 HEAD 仍然指分支 master ,所以现在间接指的是 commit d

代码语言:javascript复制
$ edit; git add; git commit

               HEAD (refers to branch 'master')
                |
                v
a---b---c---d  branch 'master' (refers to commit 'd')
    ^
    |
  tag 'v2.0' (refers to commit 'b')

有时候能够检出不在任何命名分支尖端的提交,甚至创建一个未被命名分支引用的新提交。让我们来看看当我们签出提交 b 时会发生什么(这里我们展示了两种可能的方法):

代码语言:javascript复制
$ git checkout v2.0  # or
$ git checkout master^^

   HEAD (refers to commit 'b')
    |
    v
a---b---c---d  branch 'master' (refers to commit 'd')
    ^
    |
  tag 'v2.0' (refers to commit 'b')

请注意,无论我们使用哪个 checkout 命令,HEAD 现在直接引用 commit b 。这被称为处于分离的 HEAD 状态。它简单地表示 HEAD 引用特定的提交,而不是引用命名的分支。让我们看看创建提交时会发生什么:

代码语言:javascript复制
$ edit; git add; git commit

     HEAD (refers to commit 'e')
      |
      v
      e
     /
a---b---c---d  branch 'master' (refers to commit 'd')
    ^
    |
  tag 'v2.0' (refers to commit 'b')

现在有一个新的提交 e ,但它仅由 HEAD 引用。我们当然可以在此状态下添加另一个提交:

代码语言:javascript复制
$ edit; git add; git commit

	 HEAD (refers to commit 'f')
	  |
	  v
      e---f
     /
a---b---c---d  branch 'master' (refers to commit 'd')
    ^
    |
  tag 'v2.0' (refers to commit 'b')

实际上,我们可以执行所有正常的 Git 操作。但是,让我们来看看当我们检出大师时会发生什么:

代码语言:javascript复制
$ git checkout master

               HEAD (refers to branch 'master')
      e---f     |
     /          v
a---b---c---d  branch 'master' (refers to commit 'd')
    ^
    |
  tag 'v2.0' (refers to commit 'b')

重要的是要意识到,此时没有任何提交 f 。最终提交 f (并通过扩展提交 e )将被例程 Git 垃圾收集过程删除,除非我们在此之前创建引用。如果我们还没有离开 commit f ,那么其中任何一个都会创建对它的引用:

代码语言:javascript复制
$ git checkout -b foo   (1)
$ git branch foo        (2)
$ git tag foo           (3)
  1. 创建一个新分支 foo ,它指的是 commit f ,然后更新 HEAD 以引用分支 foo 。换句话说,在此命令之后我们将不再处于分离的 HEAD 状态。
  2. 类似地创建一个新的分支 foo ,它指的是 commit f ,但让 HEAD 分离。
  3. 创建一个新标签 foo ,它指的是 commit f ,让 HEAD 分离。

如果我们已经离开 commit f ,那么我们必须首先恢复其对象名称(通常使用 git reflog),然后我们可以创建对它的引用。例如,要查看 HEAD 引用的最后两个提交,我们可以使用以下任一命令:

代码语言:javascript复制
$ git reflog -2 HEAD # or
$ git log -g -2 HEAD

论据歧视

当只有一个参数给出且它不是--时(例如“git checkout abc”),并且当参数既是有效&lt;tree-ish&gt;(例如分支“abc”存在)又有效&lt;pathspec&gt;时(例如,文件或名称为“abc”的目录存在),Git 通常会要求您消除歧义。因为检查分支是一种常见的操作,然而,在这种情况下,“git checkout abc”将“abc”作为&lt;tree-ish&gt;。如果要从索引中检出这些路径,请使用git checkout -- &lt;pathspec&gt;

例子

以下序列检出master分支,将Makefile恢复为两个版本,错误地删除 hello.c,并从索引中取回它。

代码语言:javascript复制
$ git checkout master             (1)
$ git checkout master~2 Makefile  (2)
$ rm -f hello.c
$ git checkout hello.c            (3)
  1. 开关分支
  2. 从另一个提交中取出一个文件
  3. 从索引中恢复 hello.c

如果你想从索引中查看 _ 所有 _ C 源文件,你可以说

代码语言:javascript复制
$ git checkout -- '*.c'

注意*.c周围的引号。文件hello.c也将被检出,即使它不再在工作树中,因为文件通配符用于匹配索引中的条目(不是由 shell 在工作树中)。

如果您有一个名为hello.c的不幸分支,则此步骤将被混淆为切换到该分支的指令。你应该写:

代码语言:javascript复制
$ git checkout -- hello.c

在错误的分支中工作后,将使用以下命令切换到正确的分支:

代码语言:javascript复制
$ git checkout mytopic

但是,您的“错误”分支和正确的“mytopic”分支可能在您在本地修改的文件中有所不同,在这种情况下,上述签出将会失败,如下所示:

代码语言:javascript复制
$ git checkout mytopic
error: You have local changes to 'frotz'; not switching branches.

您可以为命令提供-m标志,该命令将尝试三向合并:

代码语言:javascript复制
$ git checkout -m mytopic
Auto-merging frotz

在这种三向合并之后,本地修改是 _ 而不是 _ 在您的索引文件中注册,因此git diff将显示自新分支的提示以来您所做的更改。

在使用-m选项切换分支期间发生合并冲突时,您会看到如下内容:

代码语言:javascript复制
$ git checkout -m mytopic
Auto-merging frotz
ERROR: Merge conflict in frotz
fatal: merge program failed

此时,git diff显示与上一个示例中一样干净地合并的更改,以及冲突文件中的更改。编辑并解决冲突,并像往常一样用git add标记它:

代码语言:javascript复制
$ edit frotz
$ git add frotz

GIT

部分 git [1] 套件

git-merge

原文: git-scm.com/docs/git-merge

名称

git-merge - 将两个或多个开发历史记录连接在一起

概要

代码语言:javascript复制
git merge [-n] [--stat] [--no-commit] [--squash] [--[no-]edit]
	[-s <strategy>] [-X <strategy-option>] [-S[<keyid>]]
	[--[no-]allow-unrelated-histories]
	[--[no-]rerere-autoupdate] [-m <msg>] [-F <file>] [<commit>…​]
git merge --abort
git merge --continue

描述

将来自命名提交的更改(自其历史记录与当前分支分开时)合并到当前分支中。 git pull 使用此命令来合并来自另一个存储库的更改,并且可以手动使用此命令将更改从一个分支合并到另一个分支。

假设存在以下历史记录,当前分支为“master”:

代码语言:javascript复制
	  A---B---C topic
	 /
    D---E---F---G master

然后“git merge topic”将重放topic分支上的更改,因为它从master(即E)转移到master之上的当前提交(C),并记录导致新提交以及两个父提交的名称和来自用户的描述更改的日志消息。

代码语言:javascript复制
	  A---B---C topic
	 /         
    D---E---F---G---H master

第二种语法(“git merge --abort”)只能在合并导致冲突后运行。 git merge --abort 将中止合并过程并尝试重建合并前状态。但是,如果在合并开始时有未提交的更改(特别是如果在合并开始后进一步修改了这些更改), git merge --abort 在某些情况下将无法重建原始(之前) - 改变。因此:

警告:不鼓励运行 git merge 并进行非平凡的未提交更改:尽管可能,但如果发生冲突,可能会使您处于难以退出的状态。

第三种语法(“git merge --continue”)只能在合并导致冲突后运行。

OPTIONS

代码语言:javascript复制
 --commit 
代码语言:javascript复制
 --no-commit 

执行合并并提交结果。此选项可用于覆盖–no-commit。

使用–no-commit 执行合并但假装合并失败并且不自动提交,以便让用户有机会在提交之前检查并进一步调整合并结果。

代码语言:javascript复制
 --edit 
代码语言:javascript复制
 -e 
代码语言:javascript复制
 --no-edit 

在提交成功的机械合并之前调用编辑器以进一步编辑自动生成的合并消息,以便用户可以解释并证明合并。 --no-edit选项可用于接受自动生成的消息(通常不鼓励这样做)。如果从命令行给出带有-m选项的草稿消息并想在编辑器中编辑它,--edit(或-e)选项仍然有用。

较旧的脚本可能取决于不允许用户编辑合并日志消息的历史行为。他们将在运行git merge时看到编辑器打开。为了便于将此类脚本调整为更新的行为,可以在环境变量GIT_MERGE_AUTOEDIT的开头设置为no

代码语言:javascript复制
 --ff 

当合并解析为快进时,仅更新分支指针,而不创建合并提交。这是默认行为。

代码语言:javascript复制
 --no-ff 

即使合并解析为快进,也要创建合并提交。这是在 refs / tags / 层次结构中合并未存储在其自然位置的带注释(且可能已签名)的标记时的默认行为。

代码语言:javascript复制
 --ff-only 

拒绝以非零状态合并和退出,除非当前HEAD已经是最新的,或者合并可以解析为快进。

代码语言:javascript复制
 -S[<keyid>] 
代码语言:javascript复制
 --gpg-sign[=<keyid>] 

GPG 签署生成的合并提交。 keyid参数是可选的,默认为提交者标识;如果指定,它必须粘在没有空格的选项上。

代码语言:javascript复制
 --log[=<n>] 
代码语言:javascript复制
 --no-log 

除了分支名称之外,还使用最多< n>的单行描述填充日志消息。正在合并的实际提交。另见 git-fmt-merge-msg [1] 。

使用–no-log 不会列出正在合并的实际提交中的单行描述。

代码语言:javascript复制
 --signoff 
代码语言:javascript复制
 --no-signoff 

在提交日志消息的末尾由提交者添加逐行签名。签收的含义取决于项目,但它通常证明提交者有权在同一许可下提交此作品并同意开发者原产地证书(参见 developercertificate.org/ ] 欲获得更多信息)。

使用–no-signoff 时不要添加 Sign-off-by 行。

代码语言:javascript复制
 --stat 
代码语言:javascript复制
 -n 
代码语言:javascript复制
 --no-stat 

在合并结束时显示 diffstat。 diffstat 也由配置选项 merge.stat 控制。

使用-n 或–no-stat 时,在合并结束时不显示 diffstat。

代码语言:javascript复制
 --squash 
代码语言:javascript复制
 --no-squash 

生成工作树和索引状态,就好像发生了真正的合并(合并信息除外),但实际上没有提交,移动HEAD或记录$GIT_DIR/MERGE_HEAD(导致下一个git commit命令到创建合并提交)。这允许您在当前分支之上创建单个提交,其效果与合并另一个分支(或章鱼的情况下更多)相同。

使用–no-squash 执行合并并提交结果。此选项可用于覆盖–squash。

代码语言:javascript复制
 -s <strategy> 
代码语言:javascript复制
 --strategy=<strategy> 

使用给定的合并策略;可以多次提供,以按照应该尝试的顺序指定它们。如果没有-s选项,则使用内置的策略列表(合并单个头时 git merge-recursive ,否则使用 git merge-octopus )。

代码语言:javascript复制
 -X <option> 
代码语言:javascript复制
 --strategy-option=<option> 

将合并策略特定选项传递给合并策略。

代码语言:javascript复制
 --verify-signatures 
代码语言:javascript复制
 --no-verify-signatures 

验证正在合并的侧分支的提示提交是否使用有效密钥签名,即具有有效 uid 的密钥:在默认信任模型中,这意味着签名密钥已由可信密钥签名。如果侧分支的提示提交未使用有效密钥签名,则合并将中止。

代码语言:javascript复制
 --summary 
代码语言:javascript复制
 --no-summary 

同义词–stat 和–no-stat;这些已被弃用,将来会被删除。

代码语言:javascript复制
 -q 
代码语言:javascript复制
 --quiet 

安静地操作。意味着 - 没有进步。

代码语言:javascript复制
 -v 
代码语言:javascript复制
 --verbose 

要冗长。

代码语言:javascript复制
 --progress 
代码语言:javascript复制
 --no-progress 

明确打开/关闭进度。如果两者都未指定,则在标准错误连接到终端时显示进度。请注意,并非所有合并策略都可以支持进度报告。

代码语言:javascript复制
 --allow-unrelated-histories 

默认情况下,git merge命令拒绝合并不共享共同祖先的历史记录。在合并独立开始生命的两个项目的历史时,此选项可用于覆盖此安全性。由于这是一种非常罕见的情况,因此默认情况下不会启用任何配置变量来启用它,也不会添加。

代码语言:javascript复制
 -m <msg> 

设置要用于合并提交的提交消息(如果创建了一个)。

如果指定了--log,则正在合并的提交的短消息将附加到指定的消息。

git fmt-merge-msg 命令可用于为自动 git merge 调用提供良好的默认值。自动消息可以包括分支描述。

代码语言:javascript复制
 -F <file> 
代码语言:javascript复制
 --file=<file> 

读取要用于合并提交的提交消息(如果创建了一个)。

如果指定了--log,则正在合并的提交的短消息将附加到指定的消息。

代码语言:javascript复制
 --[no-]rerere-autoupdate 

如果可能,允许 rerere 机制使用自动冲突解决的结果更新索引。

代码语言:javascript复制
 --abort 

中止当前的冲突解决过程,并尝试重建合并前的状态。

如果在合并开始时存在未提交的工作树更改,则 git merge --abort 在某些情况下将无法重建这些更改。因此,建议在运行 git merge 之前始终提交或存储您的更改。

MERGE_HEAD存在时, git merge --abort 相当于 git reset --merge

代码语言:javascript复制
 --continue 

git merge 因冲突而停止后,您可以通过运行 git merge --continue 来结束合并(请参阅下面的“如何解决冲突”部分)。

代码语言:javascript复制
 <commit>…​ 

提交,通常是其他分支机构,合并到我们的分支机构。指定多个提交将创建一个包含两个以上父项的合并(被亲切地称为八达通合并)。

如果未从命令行提供任何提交,请合并当前分支配置为用作其上游的远程跟踪分支。另请参见本手册页的配置部分。

当指定FETCH_HEAD(并且没有其他提交)时,通过先前调用git fetch进行合并而在.git/FETCH_HEAD文件中记录的分支被合并到当前分支。

预先检查

在应用外部变更之前,您应该使自己的工作处于良好状态并在本地进行,因此如果存在冲突,则不会被破坏。另见 git-stash [1] 。 git pullgit merge 将停止而不做任何事情当本地未提交的更改与 git pull / git merge 可能需要的文件重叠时更新。

为了避免在合并提交中记录不相关的更改,如果索引中相对于HEAD提交注册了任何更改, git pullgit merge 也将中止。 (根据正在使用的合并策略,可能存在此规则的特殊狭义异常,但通常,索引必须与 HEAD 匹配。)

如果所有已命名的提交都已经是HEAD的祖先,则 git merge 将提前退出并显示“已经是最新的”消息。

快速前进的合并

通常,当前分支头是命名提交的祖先。这是最常见的情况,尤其是从 git pull 调用时:您正在跟踪上游存储库,您没有提交本地更改,现在您想要更新到更新的上游修订版。在这种情况下,不需要新的提交来存储组合的历史记录;相反,HEAD(以及索引)更新为指向命名提交,而不创建额外的合并提交。

使用--no-ff选项可以抑制此行为。

真正的合并

除了快速合并(见上文)之外,要合并的分支必须通过合并提交绑定在一起,合并提交将它们都作为父项。

将提交一个合并版本,以协调要合并的所有分支的更改,并将HEAD,索引和工作树更新到它。只要它们不重叠,就可以在工作树中进行修改;更新将保留它们。

如果不明显如何协调更改,则会发生以下情况:

  1. HEAD指针保持不变。
  2. MERGE_HEAD ref 设置为指向另一个分支头。
  3. 干净地合并的路径在索引文件和工作树中都会更新。
  4. 对于冲突路径,索引文件最多可记录三个版本:阶段 1 存储来自共同祖先的版本,阶段 2 来自HEAD,阶段 3 来自MERGE_HEAD(您可以使用git ls-files -u检查阶段)。工作树文件包含“合并”程序的结果;即 3 路合并结果与熟悉的冲突标记&lt;&lt;&lt; === &gt;&gt;&gt;
  5. 没有进行其他更改。特别是,在开始合并之前进行的本地修改将保持不变,并且它们的索引条目保持不变,即匹配HEAD

如果您尝试合并导致复杂冲突并想重新开始,则可以使用git merge --abort进行恢复。

合并标签

合并带注释(可能已签名)的标记时,即使可以进行快进合并,Git 也会始终创建合并提交,并且使用标记消息准备提交消息模板。此外,如果标记已签名,则签名检查将在消息模板中报告为注释。另见 git-tag [1] 。

当您想要与导致恰好被标记的提交的工作集成时,例如,与上游发布点同步,您可能不希望进行不必要的合并提交。

在这种情况下,您可以在将标签送入git merge之前自行“打开”标签,或者在您自己没有任何工作时通过--ff-only。例如

代码语言:javascript复制
git fetch origin
git merge v1.2.3⁰
git merge --ff-only v1.2.3

如何提出冲突

在合并期间,将更新工作树文件以反映合并的结果。在对共同祖先版本所做的更改中,非重叠版本(即,您更改文件的某个区域而另一侧保留该区域完整,或反之亦然)将逐字汇入最终结果中。然而,当双方对同一区域进行更改时,Git 不能随意选择一侧而是另一侧,并要求您通过将双方所做的事情留在该区域来解决它。

默认情况下,Git 使用与 RCS 套件中“merge”程序使用的样式相同的样式来呈现这样一个冲突的 hunk,如下所示:

代码语言:javascript复制
Here are lines that are either unchanged from the common
ancestor, or cleanly resolved because only one side changed.
<<<<<<< yours:sample.txt
Conflict resolution is hard;
let's go shopping.
=======
Git makes conflict resolution easy.
>>>>>>> theirs:sample.txt
And here is another line that is cleanly resolved or unmodified.

发生一对冲突变化的区域标有标记&lt;&lt;&lt;&lt;&lt;&lt;&lt;=======&gt;&gt;&gt;&gt;&gt;&gt;&gt;=======之前的部分通常是你的一面,之后的部分通常是它们的一面。

默认格式不显示原始在冲突区域中所说的内容。你无法分辨出删除了多少行,取而代之的是 Barbie 的评论。你能说的唯一一件事就是你的一方想说它很难而且你更喜欢去购物,而另一方则想要说这很容易。

通过将“merge.conflictStyle”配置变量设置为“diff3”,可以使用替代样式。在“diff3”样式中,上述冲突可能如下所示:

代码语言:javascript复制
Here are lines that are either unchanged from the common
ancestor, or cleanly resolved because only one side changed.
<<<<<<< yours:sample.txt
Conflict resolution is hard;
let's go shopping.
|||||||
Conflict resolution is hard.
=======
Git makes conflict resolution easy.
>>>>>>> theirs:sample.txt
And here is another line that is cleanly resolved or unmodified.

&lt;&lt;&lt;&lt;&lt;&lt;&lt;=======&gt;&gt;&gt;&gt;&gt;&gt;&gt;标记外,它还使用另一个|||||||标记,后跟原始文本。你可以说原来只是陈述了一个事实,而你的一方只是屈服于那个陈述并放弃了,而另一方则试图采取更积极的态度。您有时可以通过查看原始分辨率来获得更好的分辨率。

如何解决冲突

看到冲突后,你可以做两件事:

  • 决定不合并。您需要的唯一清理是将索引文件重置为HEAD提交以反转 2.并清除由 2.和 3 进行的工作树更改。 git merge --abort可用于此目的。
  • 解决冲突。 Git 将标记工作树中的冲突。将文件编辑成形状, _git 将 _ 添加到索引中。使用 git commit 或 _git merge - 继续 _ 来达成交易。后一个命令在调用 git commit 之前检查是否存在正在进行的(中断)合并。

您可以使用许多工具解决冲突:

  • 使用 mergetool。 git mergetool启动图形合并工具,它将帮助您完成合并。
  • 看看差异。 git diff将显示三向差异,突出显示HEADMERGE_HEAD版本的变化。
  • 查看每个分支的差异。 git log --merge -p &lt;path&gt;将首先显示HEAD版本的差异,然后显示MERGE_HEAD版本。
  • 看看原件。 git show :1:filename显示共同的祖先,git show :2:filename显示HEAD版本,git show :3:filename显示MERGE_HEAD版本。

例子

在当前分支的顶部合并分支fixesenhancements,进行章鱼合并:

代码语言:javascript复制
$ git merge fixes enhancements

使用ours合并策略将分支obsolete合并到当前分支中:

代码语言:javascript复制
$ git merge -s ours obsolete

将分支maint合并到当前分支中,但不要自动进行新的提交:

代码语言:javascript复制
$ git merge --no-commit maint

当您想要包含对合并的进一步更改,或者想要编写自己的合并提交消息时,可以使用此方法。

您应该避免滥用此选项以将重大更改隐藏到合并提交中。像碰撞版本/版本名称这样的小修正是可以接受的。

合并战略

合并机制(git mergegit pull命令)允许使用-s选项选择后端 _ 合并策略 _。一些策略也可以采用自己的选项,可以通过向git merge和/或git pull提供-X&lt;option&gt;参数来传递。

代码语言:javascript复制
 resolve 

这只能使用 3 向合并算法解析两个头(即当前分支和您从中拉出的另一个分支)。它试图仔细检测纵横交错的合并模糊,并且通常被认为是安全和快速的。

代码语言:javascript复制
 recursive 

这只能使用 3 向合并算法解析两个磁头。当有多个可用于 3 向合并的共同祖先时,它会创建共同祖先的合并树,并将其用作 3 向合并的参考树。据报道,这会导致更少的合并冲突,而不会因为从 Linux 2.6 内核开发历史记录中进行的实际合并提交所做的测试而导致错误。此外,这可以检测和处理涉及重命名的合并,但目前无法使用检测到的副本。这是拉动或合并一个分支时的默认合并策略。

_ 递归 _ 策略可以采用以下选项:

代码语言:javascript复制
 ours 

这个选项通过支持 _ 我们的 _ 版本来强制冲突的帅哥干净地自动解决。来自与我们方不冲突的其他树的更改将反映到合并结果中。对于二进制文件,整个内容都来自我们这边。

这不应该与 _ 我们的 _ 合并策略混淆,后者甚至不会查看其他树包含的内容。它丢弃了另一棵树所做的一切,声明 _ 我们的 _ 历史记录中包含了所有发生的事情。

代码语言:javascript复制
 theirs 

这与 _ 我们的 _ 相反;请注意,与 _ 我们的 _ 不同,没有 _ 他们的 _ 合并策略来混淆这个合并选项。

代码语言:javascript复制
 patience 

使用此选项, merge-recursive 花费一点额外的时间来避免由于不重要的匹配行(例如,来自不同函数的大括号)而有时发生的错误。当要合并的分支发生疯狂分歧时使用此选项。另见 git-diff [1] --patience

代码语言:javascript复制
 diff-algorithm=[patience|minimal|histogram|myers] 

告诉 merge-recursive 使用不同的 diff 算法,这有助于避免由于不重要的匹配行(例如来自不同函数的大括号)而发生的错误。另见 git-diff [1] --diff-algorithm

代码语言:javascript复制
 ignore-space-change 
代码语言:javascript复制
 ignore-all-space 
代码语言:javascript复制
 ignore-space-at-eol 
代码语言:javascript复制
 ignore-cr-at-eol 

为了进行三向合并,将具有指示类型的空白的行更改为未更改。与空行的其他更改混合的空白更改不会被忽略。另见 git-diff [1] -b-w--ignore-space-at-eol--ignore-cr-at-eol

  • 如果 _ 他们的 _ 版本只将空格更改引入一行,_ 我们的 _ 版本被使用;
  • 如果 _ 我们的 _ 版本引入了空格更改,但 _ 他们的 _ 版本包含了实质性更改,_ 使用了他们的 _ 版本;
  • 否则,合并以通常的方式进行。
代码语言:javascript复制
 renormalize 

在解析三向合并时,这将运行虚拟签出并检入文件的所有三个阶段。此选项适用于将分支与不同的清除过滤器或行尾规范化规则合并时使用。有关详细信息,请参阅 gitattributes [5] 中的“合并具有不同签入/签出属性的分支”。

代码语言:javascript复制
 no-renormalize 

禁用renormalize选项。这会覆盖merge.renormalize配置变量。

代码语言:javascript复制
 no-renames 

关闭重命名检测。这会覆盖merge.renames配置变量。另见 git-diff [1] --no-renames

代码语言:javascript复制
 find-renames[=<n>] 

打开重命名检测,可选择设置相似性阈值。这是默认值。这会覆盖 merge.renames 配置变量。另见 git-diff [1] --find-renames

代码语言:javascript复制
 rename-threshold=<n> 

已弃用find-renames=&lt;n&gt;的同义词。

代码语言:javascript复制
 subtree[=<path>] 

此选项是 _ 子树 _ 策略的更高级形式,其中策略猜测两个树在合并时必须如何移位以相互匹配。相反,指定的路径是前缀(或从头开始剥离),以使两个树的形状匹配。

代码语言:javascript复制
 octopus 

这解决了具有两个以上磁头的情况,但拒绝执行需要手动解决的复杂合并。它主要用于将主题分支头捆绑在一起。这是拉动或合并多个分支时的默认合并策略。

代码语言:javascript复制
 ours 

这会解析任意数量的头,但合并的结果树始终是当前分支头的树,实际上忽略了所有其他分支的所有更改。它旨在用于取代侧枝的旧发展历史。请注意,这与 _ 递归 _ 合并策略的-Xours 选项不同。

代码语言:javascript复制
 subtree 

这是一种修改后的递归策略。当合并树 A 和 B 时,如果 B 对应于 A 的子树,则首先调整 B 以匹配 A 的树结构,而不是读取相同级别的树。这种调整也是对共同的祖先树进行的。

使用三向合并的策略(包括默认的 _ 递归 _),如果在两个分支上进行了更改,但稍后在其中一个分支上进行了更改,则该更改将出现在合并结果中;有些人发现这种行为令人困惑。之所以会发生这种情况,是因为在执行合并时只考虑头和合并基础,而不是单个提交。因此,合并算法将恢复的更改视为完全没有更改,而是替换更改的版本。

组态

代码语言:javascript复制
 merge.conflictStyle 

指定在合并时将冲突的帅哥写入工作树文件的样式。默认为“合并”,显示&lt;&lt;&lt;&lt;&lt;&lt;&lt;冲突标记,一侧更改,=======标记,另一侧更改,然后是&gt;&gt;&gt;&gt;&gt;&gt;&gt;标记。另一种样式“diff3”在=======标记之前添加|||||||标记和原始文本。

代码语言:javascript复制
 merge.defaultToUpstream 

如果在没有任何提交参数的情况下调用 merge,则通过使用存储在其远程跟踪分支中的最后观察值来合并为当前分支配置的上游分支。查询branch.&lt;current branch&gt;.remote命名的远程分支的branch.&lt;current branch&gt;.merge值,然后通过remote.&lt;remote&gt;.fetch将它们映射到相应的远程跟踪分支,并合并这些跟踪分支的提示。

代码语言:javascript复制
 merge.ff 

默认情况下,Git 在合并作为当前提交的后代的提交时不会创建额外的合并提交。相反,当前分支的提示是快进的。当设置为false时,此变量告诉 Git 在这种情况下创建额外的合并提交(相当于从命令行提供--no-ff选项)。设置为only时,仅允许此类快进合并(相当于从命令行提供--ff-only选项)。

代码语言:javascript复制
 merge.verifySignatures 

如果为 true,则等效于–verify-signatures 命令行选项。有关详细信息,请参阅 git-merge [1] 。

代码语言:javascript复制
 merge.branchdesc 

除分支名称外,还使用与其关联的分支描述文本填充日志消息。默认为 false。

代码语言:javascript复制
 merge.log 

除了分支名称之外,还要从正在合并的实际提交中填充最多具有指定数量的单行描述的日志消息。默认为 false,true 是 20 的同义词。

代码语言:javascript复制
 merge.renameLimit 

合并期间执行重命名检测时要考虑的文件数;如果未指定,则默认为 diff.renameLimit 的值。如果关闭重命名检测,此设置无效。

代码语言:javascript复制
 merge.renames 

Git 是否以及如何检测重命名。如果设置为“false”,则禁用重命名检测。如果设置为“true”,则启用基本重命名检测。默认为 diff.renames 的值。

代码语言:javascript复制
 merge.renormalize 

告诉 Git,存储库中文件的规范表示随着时间的推移而发生了变化(例如,早期的提交记录了带有 CRLF 行结尾的文本文件,但最近提交了使用 LF 行结尾的文本文件)。在这样的存储库中,Git 可以在执行合并之前将提交中记录的数据转换为规范形式,以减少不必要的冲突。有关详细信息,请参阅 gitattributes [5] 中的“合并具有不同签入/签出属性的分支”部分。

代码语言:javascript复制
 merge.stat 

是否在合并结束时打印 ORIG_HEAD 和合并结果之间的 diffstat。默认为 True。

代码语言:javascript复制
 merge.tool 

控制 git-mergetool [1] 使用的合并工具。下面的列表显示了有效的内置值。任何其他值都被视为自定义合并工具,并且需要定义相应的 mergetool。< tool> .cmd 变量。

代码语言:javascript复制
 merge.guitool 

当指定-g / - gui 标志时,控制 git-mergetool [1] 使用哪个合并工具。下面的列表显示了有效的内置值。任何其他值都被视为自定义合并工具,并且需要定义相应的 mergetool。< guitool> .cmd 变量。

  • araxis
  • 公元前
  • BC3
  • codecompare
  • deltawalker
  • diffmerge
  • 扩散
  • ecmerge
  • 出现
  • examdiff
  • guiffy
  • gvimdiff
  • gvimdiff2
  • gvimdiff3
  • kdiff3
  • 合并
  • 了 opendiff
  • p4merge
  • tkdiff
  • 如果 TortoiseMerge
  • vimdiff 同时
  • vimdiff2
  • vimdiff3
  • 的 WinMerge
  • xxdiff
代码语言:javascript复制
 merge.verbosity 

控制递归合并策略显示的输出量。如果检测到冲突,则 0 级除了最终错误消息外不输出任何内容。级别 1 仅输出冲突,输出 2 个冲突和文件更改。 5 级及以上输出调试信息。默认值为 2 级。可以被GIT_MERGE_VERBOSITY环境变量覆盖。

代码语言:javascript复制
 merge.<driver>.name 

为自定义低级合并驱动程序定义一个人类可读的名称。有关详细信息,请参阅 gitattributes [5] 。

代码语言:javascript复制
 merge.<driver>.driver 

定义实现自定义低级合并驱动程序的命令。有关详细信息,请参阅 gitattributes [5] 。

代码语言:javascript复制
 merge.<driver>.recursive 

命名在共同祖先之间执行内部合并时使用的低级合并驱动程序。有关详细信息,请参阅 gitattributes [5] 。

代码语言:javascript复制
 branch.<name>.mergeOptions 

设置合并到分支< name>的默认选项。语法和支持的选项与 git merge 的相同,但目前不支持包含空格字符的选项值。

也可以看看

git-fmt-merge-msg [1] , git-pull [1] , gitattributes [5] , git-reset [1] , git-diff [1] , git-ls-files [1] , git-add [1] , git- rm [1] , git-mergetool [1]

GIT

部分 git [1] 套件

0 人点赞