git学习5-补丁

补丁

apply

1
2
3
4
5
6
7
8
git apply [--stat] [--numstat] [--summary] [--check] [--index | --intent-to-add] [--3way]
[--apply] [--no-add] [--build-fake-ancestor=<file>] [-R | --reverse]
[--allow-binary-replacement | --binary] [--reject] [-z]
[-p<n>] [-C<n>] [--inaccurate-eof] [--recount] [--cached]
[--ignore-space-change | --ignore-whitespace]
[--whitespace=(nowarn|warn|fix|error|error-all)]
[--exclude=<path>] [--include=<path>] [--directory=<root>]
[--verbose | --quiet] [--unsafe-paths] [--allow-empty] [<patch>…]

将补丁应用于文件和/或索引。

读取提供的diff输出并将其应用到文件中。当从存储库中的子目录运行时,将忽略该目录外已修补的路径。

使用--index选项,补丁也会应用到索引。

而使用--cached选项,补丁只会应用到索引。

如果没有这些选项,该命令只将补丁应用于文件,而不要求它们存在于Git存储库中。

选项

  • <patch>…:要读取补丁的文件。-可用于从标准输入读取。
  • --stat:不应用补丁,而从输入中输出diffstat。。
  • --summary:不应用补丁,而是输出从git diff扩展头中获得的信息的压缩摘要,例如创建、重命名和模式更改。
  • --check:应用补丁,而是查看补丁是否适用于当前的工作树和/或索引文件,并检测错误。
  • --index:将补丁应用到索引和工作树中(或者只是检查它是否会干净地应用到这两个树中,如果--check有效的话)。注意,树副本--index预计索引条目和工作相关的路径是相同的(其内容和元数据等文件模式必须匹配),并将提高一个错误如果他们不是,即使补丁对双方都应用干净指数和隔离工作树。
  • --cached:只对索引应用补丁,而不触及工作树。如果--check生效,只需要检查它是否完全适用于索引项。
  • --allow-empty:可以应用空的补丁或者只含提交文本的补丁。

cherry-pick

1
2
3
git cherry-pick [--edit] [-n] [-m <parent-number>] [-s] [-x] [--ff]
[-S[<keyid>]] <commit>…
git cherry-pick (--continue | --skip | --abort | --quit)

给定一个或多个现有提交,应用每个提交引入的更改,为每个提交记录一个新提交。这需要你的工作树是干净的(没有来自HEAD提交的修改)。

选项

  • <commit>…:要提交给cherry-pick的提交。
  • e; --edit:通过这个选项,git cherry-pick将允许你在提交之前编辑提交消息。

例子

  • git cherry-pick master:在主分支的顶端应用提交引入的更改,并使用此更改创建一个新的提交。

  • git cherry-pick ..master
    git cherry-pick ^HEAD master
    
    1
    2
    3
    4
    5
    6

    应用由master的祖先(而不是HEAD的祖先)的所有提交引入的更改来产生新的提交。

    - ```bash
    git cherry-pick maint next ^master
    git cherry-pick maint master..next
    应用所有提交引入的更改,这些提交是维护或下一个的祖先,而不是master或它的任何祖先。
  • git 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
2
3
4
5
6
git diff [<options>] [<commit>] [--] [<path>…]
git diff [<options>] --cached [--merge-base] [<commit>] [--] [<path>…]
git diff [<options>] [--merge-base] <commit> [<commit>…] <commit> [--] [<path>…]
git diff [<options>] <commit>…<commit> [--] [<path>…]
git diff [<options>] <blob> <blob>
git diff [<options>] --no-index [--] <path> <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
2
3
4
5
git rebase [-i | --interactive] [<options>] [--exec <cmd>]
[--onto <newbase> | --keep-base] [<upstream> [<branch>]]
git rebase [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>]
--root [<branch>]
git rebase (--continue | --skip | --abort | --quit | --edit-todo | --show-current-patch)

在另一个基地址的顶端应用提交。

如果指定了<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}:如何处理那些在启动时不是空的、也不是任何上游提交的干净的、但在重基之后变成空的提交(因为它们包含已经上游更改的子集)。

例子

  1. 假设存在以下历史记录,并且当前分支为“topic”:

          A---B---C topic
         /
    D---E---F---G master
    

    从这里开始,以下任意一个命令的结果:

    1
    2
    git rebase master
    git rebase master topic

    其结构将会变为如下:

    1
    2
    3
                  A'--B'--C' topic
    /
    D---E---F---G master

    注意:后一种形式只是简单的git checkout topic后面跟着git rebase master。当rebase退出时,主题将仍然是签出的分支。

  2. 如果是下面的结构

    1
    2
    3
    4
    5
         G---H---I dev1
    /
    A---B---C dev
    /
    D---E---A'---F master

    那么执行git rebase --onto master dev dev1

    将会得到结果

    1
    2
    3
    4
    5
         A---B---C dev         
    /
    D---E---A'---F master
    \
    G---H---I dev1

    此时dev1线上就包括master的最新代码。

  3. 去除分支中的一些提交。

    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
2
git revert [--[no-]edit] [-n] [-m parent-number] [-s] [-S[<keyid>]] <commit>…
git revert (--continue | --skip | --abort | --quit)

给定一个或多个现有提交,恢复相关补丁引入的更改,并记录一些记录这些更改的新提交。这需要您的工作树是干净的(没有来自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:将主系统中最后一次提交(包括)的第五次提交的修改恢复到主系统中最后一次提交(包括)的第三次提交,但不要使用恢复后的修改创建任何提交。恢复操作只修改工作树和索引。

Powered by Hexo and Hexo-theme-hiker

Copyright © 2019 - 2024 My Wonderland All Rights Reserved.

UV : | PV :