补丁
apply
1 | git apply [--stat] [--numstat] [--summary] [--check] [--index | --intent-to-add] [--3way] |
将补丁应用于文件和/或索引。
读取提供的diff输出并将其应用到文件中。当从存储库中的子目录运行时,将忽略该目录外已修补的路径。
使用--index
选项,补丁也会应用到索引。
而使用--cached
选项,补丁只会应用到索引。
如果没有这些选项,该命令只将补丁应用于文件,而不要求它们存在于Git存储库中。
选项
<patch>…
:要读取补丁的文件。-可用于从标准输入读取。--stat
:不应用补丁,而从输入中输出diffstat。。--summary
:不应用补丁,而是输出从git diff扩展头中获得的信息的压缩摘要,例如创建、重命名和模式更改。--check
:应用补丁,而是查看补丁是否适用于当前的工作树和/或索引文件,并检测错误。--index
:将补丁应用到索引和工作树中(或者只是检查它是否会干净地应用到这两个树中,如果--check
有效的话)。注意,树副本--index
预计索引条目和工作相关的路径是相同的(其内容和元数据等文件模式必须匹配),并将提高一个错误如果他们不是,即使补丁对双方都应用干净指数和隔离工作树。--cached
:只对索引应用补丁,而不触及工作树。如果--check
生效,只需要检查它是否完全适用于索引项。--allow-empty
:可以应用空的补丁或者只含提交文本的补丁。
cherry-pick
1 | git cherry-pick [--edit] [-n] [-m <parent-number>] [-s] [-x] [--ff] |
给定一个或多个现有提交,应用每个提交引入的更改,为每个提交记录一个新提交。这需要你的工作树是干净的(没有来自HEAD提交的修改)。
选项
<commit>…
:要提交给cherry-pick的提交。e; --edit
:通过这个选项,git cherry-pick
将允许你在提交之前编辑提交消息。
例子
git cherry-pick master
:在主分支的顶端应用提交引入的更改,并使用此更改创建一个新的提交。git cherry-pick ..master git cherry-pick ^HEAD master
应用所有提交引入的更改,这些提交是维护或下一个的祖先,而不是master或它的任何祖先。1
2
3
4
5
6
应用由master的祖先(而不是HEAD的祖先)的所有提交引入的更改来产生新的提交。
- ```bash
git cherry-pick maint next ^master
git cherry-pick maint master..nextgit cherry-pick master~4 master~2
应用由master指向的第五次和第三次提交所引入的更改,并使用这些更改创建2个新的提交。
git cherry-pick (commitid1..commitid100])
:commitid1为想复制的最老提交(不包括),commitid100为想复制的最新提交(包括)。git cherry-pick [commitid1^..commitid100]
:commitid1为想复制的最老提交(包括),commitid100为想复制的最新提交(包括)。git rev-list --reverse master -- README | git cherry-pick -n --stdin
:将涉及到README的主分支上的所有提交所引入的更改应用到工作树和索引中,这样就可以检查结果,并在合适的情况下将其转换为单个新提交。
diff
1 | git diff [<options>] [<commit>] [--] [<path>…] |
显示工作树和索引或树之间的更改、索引和树之间的更改、两棵树之间的更改、合并导致的更改、两个blob对象之间的更改或磁盘上两个文件之间的更改。
git diff [<options>] [--] [<path>…]
该形式用于查看相对于索引(下一次提交的暂存区域)所做的更改。换句话说,区别在于您可以告诉Git进一步添加到索引中的内容,但仍然还没有添加。
git diff [<options>] --no-index [--] <path> <path>
该形式用于比较文件系统中给定的两条路径。当在一个由Git控制的工作树中运行命令,并且至少有一个路径点在工作树之外时,或者当在一个由Git控制的工作树之外运行命令时,可以省略--no-index
选项。
git diff [<options>] --cached [--merge-base] [<commit>] [--] [<path>…]
该形式用于查看您为下一次提交而进行的相对于命名的<commit>
的更改。通常,您希望与最近的提交进行比较,因此,如果您没有给出<commit>
,则默认为HEAD。如果HEAD不存在(例如未出生的分支),并且<commit>
没有给出,它会显示所有的分段更改。--staging
是--cached
的同义词。
git diff [<options>] [--merge-base] <commit> [--] [<path>…]
该形式用于查看工作树中相对于命名的<commit>
的更改。您可以使用HEAD将其与最近的提交进行比较,或者使用分支名称将其与不同分支的尖端进行比较。
git diff [<options>] [--merge-base] <commit> <commit> [--] [<path>…]
该形式用于查看两个任意<commit>
之间的更改。
git diff [<options>] <commit> <commit>… <commit> [--] [<path>…]
该形式用于查看合并提交的结果。列出的第一个<commit>
必须是merge本身;剩下的两个或更多的提交应该是它的父节点。生成所需修订集的一种方便的方法是使用^@后缀。例如,如果master命名了一个合并提交,git diff master master^@
将给出与git show master
相同的diff组合。
git diff [<options>] <commit>..<commit> [--] [<path>…]
这与前面的形式(没有..)是同义的,用于查看两个任意<commit>
之间的更改。如果在一边省略<commit>
,它将具有与使用HEAD相同的效果。
git diff [<options>] <commit>...<commit> [--] [<path>…]
该形式用于查看包含第二个<commit>
的分支上的更改,从两个<commit>
的共同祖先开始。
选项
-p; -u; --patch
:生成补丁文件。这是默认值。-s; --no-patch
:禁止diff输出。对于git show
这样的命令很有用,可以默认显示补丁,或者取消--patch
的效果。--output=<file>
:输出到特定的文件,而不是标准输出。--raw
:以原始格式生成diff。--name-only
:只显示更改文件的名称。文件名通常用UTF-8编码。--name-status
:只显示更改文件的名称和状态。
rebase
1 | git rebase [-i | --interactive] [<options>] [--exec <cmd>] |
在另一个基地址的顶端应用提交。
如果指定了<branch>
, git rebase
会在做其他事情之前自动切换<branch>
。否则,它将保持在当前分支上。
当前分支中由提交所做的、但不在<upstream>
中的所有更改都被保存到一个临时区域。通过git log <upstream>..HEAD
命令可以进行显示。
如果提供了--onto
选项,则当前分支被重置为<upstream>
,或者<newbase>
。这与git reset --hard <upstream>
(或<newbase>
)有完全相同的效果。在重置之前,ORIG_HEAD被设置为指向分支的顶端。
之前保存到临时区域的提交将依次重新应用到当前分支。请注意,在HEAD中任何提交都会引入与在HEAD中提交相同的文本更改。<upstream>
都省略了。
选项
--onto <newbase>
:创建新提交的起始点。--keep-base
:设置将新提交到<upstream> <branch>
的合并基的起点。这个选项在上游分支上开发特性的情况下非常有用。当这个特性正在开发的时候,上游分支可能会向前推进,而保持在上游的顶部重基可能不是最好的主意,而是保持基本的提交。<upstream>
:进行比较的上游分支。可以是任何有效的提交,而不仅仅是现有的分支名称。默认为当前分支配置的上游。<branch>
:工作分支;默认为HEAD。--continue
:在解决合并冲突后重新启动重基流程。--abort
:中止重基操作并将HEAD重置到原始分支。如果在rebase操作开始时提供了<branch>
,那么HEAD将被重置为<branch>
。否则,HEAD将被重置到重基操作开始时的位置。--quit
:中止重基操作,但不会将HEAD重置回原始分支。因此,索引和工作树也保持不变。如果使用--autostash
创建了一个临时存储条目,那么它将被保存到stash
列表中。--apply
:使用应用策略来重基(在内部调用git-am)。一旦合并后端处理了应用程序所做的所有事情,这个选项可能在将来不会发生任何操作。--empty={drop,keep,ask}
:如何处理那些在启动时不是空的、也不是任何上游提交的干净的、但在重基之后变成空的提交(因为它们包含已经上游更改的子集)。
例子
假设存在以下历史记录,并且当前分支为“topic”:
A---B---C topic / D---E---F---G master
从这里开始,以下任意一个命令的结果:
1
2git rebase master
git rebase master topic其结构将会变为如下:
1
2
3A'--B'--C' topic
/
D---E---F---G master注意:后一种形式只是简单的
git checkout topic
后面跟着git rebase master
。当rebase
退出时,主题将仍然是签出的分支。如果是下面的结构
1
2
3
4
5G---H---I dev1
/
A---B---C dev
/
D---E---A'---F master那么执行
git rebase --onto master dev dev1
将会得到结果
1
2
3
4
5A---B---C dev
/
D---E---A'---F master
\
G---H---I dev1此时dev1线上就包括master的最新代码。
去除分支中的一些提交。
1
A---B---C---D---E dev1
执行以下命令后,B和C将会从dev1分支的提交记录中去除。
1
git rebase --onto dev1~4 dev1~1 dev1
其结构如下
1
A---D---E dev1
如果发生冲突,git rebase会在第一个有问题的提交时停止,并在树中留下冲突标记。您可以使用git diff来定位标记(<<<<<<)并进行编辑以解决冲突。
revert
1 | git revert [--[no-]edit] [-n] [-m parent-number] [-s] [-S[<keyid>]] <commit>… |
给定一个或多个现有提交,恢复相关补丁引入的更改,并记录一些记录这些更改的新提交。这需要您的工作树是干净的(没有来自HEAD提交的修改)。
注意:git revert用来记录一些新的提交,以逆转之前的一些提交的效果(通常是一个错误的提交)。如果希望丢弃工作目录中所有未提交的更改,应该看到git-reset
,特别是--hard
选项。如果您想提取在另一个提交中的特定文件,您应该看到git-restore
,特别是--source
选项。要注意这些选项,因为它们都会丢弃工作目录中未提交的更改。
选项
<commit>…
:要逆转的提交。-e; --edit
:有了这个选项,git revert将允许你在提交恢复之前编辑提交消息。默认是从命令行读取。-m parent-number;--mainline parent-number
:通常您不能恢复合并,因为您不知道合并的哪一边应该被视为主线。此选项指定主线的父节点号(从1开始),并允许恢复到反转相对于指定父节点的更改。-n; --no-commit
:通常,该命令会自动创建一些提交,并使用提交日志消息来说明哪些提交被还原。此标志应用将命名提交恢复到工作树和索引所需的更改,但不进行提交。此外,当使用这个选项时,您的索引不必与HEAD提交匹配。恢复是针对索引的开始状态进行的。
例子
git revert HEAD~3
:恢复HEAD中第四次提交所指定的更改,并使用恢复的更改创建一个新提交。git revert -n master~5..master~2
:将主系统中最后一次提交(包括)的第五次提交的修改恢复到主系统中最后一次提交(包括)的第三次提交,但不要使用恢复后的修改创建任何提交。恢复操作只修改工作树和索引。