pos*_*eid 254 git diff git-diff
手册页git-diff很长,并解释了许多初学者似乎不需要的案例.例如:
git diff origin/master
Run Code Online (Sandbox Code Playgroud)
Jak*_*ski 465
让我们看看git历史中的示例高级差异(在git.git存储库中的commit 1088261f中):
diff --git a/builtin-http-fetch.c b/http-fetch.c
similarity index 95%
rename from builtin-http-fetch.c
rename to http-fetch.c
index f3e63d7..e8f44ba 100644
--- a/builtin-http-fetch.c
+++ b/http-fetch.c
@@ -1,8 +1,9 @@
#include "cache.h"
#include "walker.h"
-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
+int main(int argc, const char **argv)
{
+ const char *prefix;
struct walker *walker;
int commits_on_stdin = 0;
int commits;
@@ -18,6 +19,8 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix)
int get_verbosely = 0;
int get_recover = 0;
+ prefix = setup_git_directory();
+
git_config(git_default_config, NULL);
while (arg < argc && argv[arg][0] == '-') {
Run Code Online (Sandbox Code Playgroud)
让我们逐行分析这个补丁.
第一行
diff --git a/builtin-http-fetch.c b/http-fetch.c是表单中的"git diff"标题
diff --git a/file1 b/file2.该a/和b/,除非重命名/复制参与(如在我们的例子中)的文件名是相同的.这--git意味着diff是"git"diff格式.接下来是一个或多个扩展标题行.前三个
similarity index 95% rename from builtin-http-fetch.c rename to http-fetch.c告诉我们该文件已重命名为
builtin-http-fetch.c,http-fetch.c并且这两个文件的95%相同(用于检测此重命名).index f3e63d7..e8f44ba 100644告诉我们给定文件的模式(
100644意味着它是普通文件,而不是如符号链接,并且它不具有可执行权限位),以及约缩短原像和postimage(文件中给出更改之前的版本)的哈希值(在更改后的文件版本).git am --3way如果无法自行应用补丁,则使用此行尝试执行3向合并.接下来是两行统一差异标头
--- a/builtin-http-fetch.c +++ b/http-fetch.c与
diff -U结果相比,它在源(preimage)和目标(postimage)文件名之后没有from-file-modification-time和to-file-modification-time.如果创建了文件,则源为/dev/null; 如果文件被删除,目标是/dev/null.diff.mnemonicPrefix配置变量设置为true,代替a/和b/前缀在此两行标题,你可以有替代c/,i/,w/和o/作为前缀,分别你比较什么; 看git-config(1)接下来是一个或多个差异; 每个块显示文件不同的一个区域.统一格式的帅哥从像线一样开始
@@ -1,8 +1,9 @@要么
@@ -18,6 +19,8 @@ int cmd_http_fetch(int argc, const char **argv, ...它的格式
@@ from-file-range to-file-range @@ [header].from-file-range的形式是-<start line>,<number of lines>,to-file-range是+<start line>,<number of lines>.起始行和行数分别表示前像和后像中的大块的位置和长度.如果未显示行数,则表示它为0.
可选标题显示每次更改发生的C函数,如果它是C文件(如-pGNU diff中的选项),或其他类型文件的等效项(如果有).
接下来是文件不同的描述.两个文件共有的行以空格字符开头.两个文件之间实际不同的行在左侧打印列中具有以下指示符之一:
所以,例如,第一块
#include "cache.h"
#include "walker.h"
-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
+int main(int argc, const char **argv)
{
+ const char *prefix;
struct walker *walker;
int commits_on_stdin = 0;
int commits;
Run Code Online (Sandbox Code Playgroud)
意味着cmd_http_fetch被替换为main,并const char *prefix;添加了该行.
换句话说,在更改之前,'builtin-http-fetch.c'文件的相应片段如下所示:
#include "cache.h"
#include "walker.h"
int cmd_http_fetch(int argc, const char **argv, const char *prefix)
{
struct walker *walker;
int commits_on_stdin = 0;
int commits;
Run Code Online (Sandbox Code Playgroud)
在更改之后,现在'http-fetch.c'文件的这个片段看起来像这样:
#include "cache.h"
#include "walker.h"
int main(int argc, const char **argv)
{
const char *prefix;
struct walker *walker;
int commits_on_stdin = 0;
int commits;
Run Code Online (Sandbox Code Playgroud)可能有
\ No newline at end of file行存在(它不是示例差异).
正如Donal Fellows所说,最好在实际例子中练习阅读差异,在那里你知道你改变了什么.
参考文献:
Cir*_*四事件 59
@@ -1,2 +3,4 @@差异的一部分
这部分花了一些时间来理解,所以我创建了一个最小的例子.
@@ -1,2 +3,4 @@统一差异的格式基本相同.
例如:
diff -u <(seq 16) <(seq 16 | grep -Ev '^(2|3|14|15)$')
Run Code Online (Sandbox Code Playgroud)
这里我们删除了第2,3,14和15行.输出:
@@ -1,6 +1,4 @@
1
-2
-3
4
5
6
@@ -11,6 +9,4 @@
11
12
13
-14
-15
16
Run Code Online (Sandbox Code Playgroud)
diff -u 手段:
@@ -1,6 +1,4 @@:此部分对应于第一个文件的第1行到第6行:
1
2
3
4
5
6
Run Code Online (Sandbox Code Playgroud)
-1,6意思是"旧",因为我们通常称之为-.
diff -u old new 说这件作品对应第二档的第1到第4行.
+1,4 意思是"新".
我们只有4行代替6行,因为删除了2行!新的大块头只是:
1
4
5
6
Run Code Online (Sandbox Code Playgroud)+ 对于第二个大块是类似的:
在旧文件中,我们有6行,从旧文件的第11行开始:
11
12
13
14
15
16
Run Code Online (Sandbox Code Playgroud)在新文件中,我们有4行,从新文件的第9行开始:
11
12
13
16
Run Code Online (Sandbox Code Playgroud)
请注意,该行@@ -11,6 +9,4 @@是新文件的第9行,因为我们已经删除了前一个块上的2行:2和3.
Hunk标头
根据您的git版本和配置,您还可以在该行旁边获取代码11行,例如@@:
@@ -4,7 +4,6 @@ func1() {
Run Code Online (Sandbox Code Playgroud)
这也可以通过func1() {plain 的旗帜获得-p.
示例:旧文件:
func1() {
1;
2;
3;
4;
5;
6;
7;
8;
9;
}
Run Code Online (Sandbox Code Playgroud)
如果我们删除行diff,diff会显示:
@@ -4,7 +4,6 @@ func1() {
3;
4;
5;
- 6;
7;
8;
9;
Run Code Online (Sandbox Code Playgroud)
请注意,这不是正确的行6:它跳过行func1和1.
这个很棒的功能通常可以准确地告诉每个hunk属于哪个函数或类,这对于解释diff非常有用.
选择标题的算法如何正常工作在下面讨论:git diff hunk标题中的摘录来自哪里?
iru*_*yak 22
这是一个简单的例子.
diff --git a/file b/file
index 10ff2df..84d4fa2 100644
--- a/file
+++ b/file
@@ -1,5 +1,5 @@
line1
line2
-this line will be deleted
line4
line5
+this line is added
Run Code Online (Sandbox Code Playgroud)
这是一个解释(详见此处).
--git 不是命令,这意味着它是diff的一个git版本(不是unix)a/ b/是目录,它们不是真实的.当我们处理同一个文件时,这只是一个方便(在我的情况下,a /在索引中,而b /在工作目录中)10ff2df..84d4fa2 是这两个文件的blob ID100644 是"模式位",表示这是一个常规文件(不可执行,不是符号链接)--- a/file +++ b/file减号表示a /版本中的行但b /版本中缺少; 和加号显示a /但缺少b /(但在我的情况下---表示删除的行,+++表示在b /中添加行,这是工作目录中的文件)@@ -1,5 +1,5 @@为了理解这一点,最好使用大文件; 如果你在不同的地方有两个变化,你会得到两个条目,如@@ -1,5 +1,5 @@; 假设你有文件line1 ... line100并删除了line10并添加了新的line100 - 你会得到:Run Code Online (Sandbox Code Playgroud)@@ -7,7 +7,6 @@ line6 line7 line8 line9 -this line10 to be deleted line11 line12 line13 @@ -98,3 +97,4 @@ line97 line98 line99 line100 +this is new line100
Don*_*ows 14
默认输出格式(最初来自一个程序,diff如果您想要查找更多信息),称为"统一差异".它基本上包含4种不同类型的线:
+,-,和我建议您练习在文件的两个版本之间读取差异,在那里您确切地知道您所改变的内容.就像那样,你会发现当你看到它时会发生什么.
在我的Mac上:
info diff然后选择:Output formats- > Context- > Unified format- > Detailed Unified:
或者在同一部分的相同路径上的在线人类差异 gnu:
文件:diff.info,节点:详细统一,下一页:示例统一,上行:统一格式
统一格式的详细说明......................................
统一输出格式以两行标题开头,如下所示:
Run Code Online (Sandbox Code Playgroud)--- FROM-FILE FROM-FILE-MODIFICATION-TIME +++ TO-FILE TO-FILE-MODIFICATION-TIME时间戳看起来像"2002-02-21 23:30:39.942229878 -0800"以表示日期,小数秒的时间和时区.
您可以使用`--label = LABEL'选项更改标题的内容; 请参阅*备注替代名称::.
接下来是一个或多个差异; 每个块显示文件不同的一个区域.统一格式帅哥看起来像这样:
Run Code Online (Sandbox Code Playgroud)@@ FROM-FILE-RANGE TO-FILE-RANGE @@ LINE-FROM-EITHER-FILE LINE-FROM-EITHER-FILE...两个文件共有的行以空格字符开头.两个文件之间实际不同的行在左侧打印列中具有以下指示符之一:
`+'这里添加了一行到第一个文件.
` - '从第一个文件中删除了一行.
| 归档时间: |
|
| 查看次数: |
89100 次 |
| 最近记录: |