Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
李少辉-开发者
git
提交
22943f1a
G
git
项目概览
李少辉-开发者
/
git
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
git
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
22943f1a
编写于
10月 14, 2005
作者:
J
Junio C Hamano
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Update git-apply to use C-style quoting for funny pathnames.
Signed-off-by:
N
Junio C Hamano
<
junkio@cox.net
>
上级
4f6fbcdc
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
186 addition
and
46 deletion
+186
-46
apply.c
apply.c
+184
-44
git-am.sh
git-am.sh
+2
-2
未找到文件。
apply.c
浏览文件 @
22943f1a
...
...
@@ -8,12 +8,13 @@
*/
#include <fnmatch.h>
#include "cache.h"
#include "quote.h"
// --check turns on checking that the working tree matches the
// files that are being modified, but doesn't apply the patch
// --stat does just a diffstat, and doesn't actually apply
// --show-files shows the directory changes
// --
show-
index-info shows the old and new index info for paths if available.
// --index-info shows the old and new index info for paths if available.
//
static
int
check_index
=
0
;
static
int
write_index
=
0
;
...
...
@@ -23,8 +24,9 @@ static int check = 0;
static
int
apply
=
1
;
static
int
show_files
=
0
;
static
int
show_index_info
=
0
;
static
int
line_termination
=
'\n'
;
static
const
char
apply_usage
[]
=
"git-apply [--stat] [--summary] [--check] [--index] [--apply] [--show-files] [--
show-index-info
] <patch>..."
;
"git-apply [--stat] [--summary] [--check] [--index] [--apply] [--show-files] [--
index-info] [-z
] <patch>..."
;
/*
* For "diff-stat" like behaviour, we keep track of the biggest change
...
...
@@ -135,6 +137,35 @@ static char * find_name(const char *line, char *def, int p_value, int terminate)
const
char
*
start
=
line
;
char
*
name
;
if
(
*
line
==
'"'
)
{
/* Proposed "new-style" GNU patch/diff format; see
* http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2
*/
name
=
unquote_c_style
(
line
,
NULL
);
if
(
name
)
{
char
*
cp
=
name
;
while
(
p_value
)
{
cp
=
strchr
(
name
,
'/'
);
if
(
!
cp
)
break
;
cp
++
;
p_value
--
;
}
if
(
cp
)
{
/* name can later be freed, so we need
* to memmove, not just return cp
*/
memmove
(
name
,
cp
,
strlen
(
cp
)
+
1
);
free
(
def
);
return
name
;
}
else
{
free
(
name
);
name
=
NULL
;
}
}
}
for
(;;)
{
char
c
=
*
line
;
...
...
@@ -224,37 +255,29 @@ static int gitdiff_hdrend(const char *line, struct patch *patch)
*/
static
char
*
gitdiff_verify_name
(
const
char
*
line
,
int
isnull
,
char
*
orig_name
,
const
char
*
oldnew
)
{
int
len
;
const
char
*
name
;
if
(
!
orig_name
&&
!
isnull
)
return
find_name
(
line
,
NULL
,
1
,
0
);
name
=
"/dev/null"
;
len
=
9
;
if
(
orig_name
)
{
int
len
;
const
char
*
name
;
char
*
another
;
name
=
orig_name
;
len
=
strlen
(
name
);
if
(
isnull
)
die
(
"git-apply: bad git-diff - expected /dev/null, got %s on line %d"
,
name
,
linenr
);
}
if
(
*
name
==
'/'
)
goto
absolute_path
;
for
(;;)
{
char
c
=
*
line
++
;
if
(
c
==
'\n'
)
break
;
if
(
c
!=
'/'
)
continue
;
absolute_path:
if
(
memcmp
(
line
,
name
,
len
)
||
line
[
len
]
!=
'\n'
)
break
;
another
=
find_name
(
line
,
NULL
,
1
,
0
);
if
(
!
another
||
memcmp
(
another
,
name
,
len
))
die
(
"git-apply: bad git-diff - inconsistent %s filename on line %d"
,
oldnew
,
linenr
);
free
(
another
);
return
orig_name
;
}
die
(
"git-apply: bad git-diff - inconsistent %s filename on line %d"
,
oldnew
,
linenr
);
return
NULL
;
else
{
/* expect "/dev/null" */
if
(
memcmp
(
"/dev/null"
,
line
,
9
)
||
line
[
9
]
!=
'\n'
)
die
(
"git-apply: bad git-diff - expected /dev/null on line %d"
,
linenr
);
return
NULL
;
}
}
static
int
gitdiff_oldname
(
const
char
*
line
,
struct
patch
*
patch
)
...
...
@@ -378,29 +401,124 @@ static int gitdiff_unrecognized(const char *line, struct patch *patch)
return
-
1
;
}
static
char
*
git_header_name
(
char
*
line
)
static
const
char
*
stop_at_slash
(
const
char
*
line
,
int
llen
)
{
int
i
;
for
(
i
=
0
;
i
<
llen
;
i
++
)
{
int
ch
=
line
[
i
];
if
(
ch
==
'/'
)
return
line
+
i
;
}
return
NULL
;
}
/* This is to extract the same name that appears on "diff --git"
* line. We do not find and return anything if it is a rename
* patch, and it is OK because we will find the name elsewhere.
* We need to reliably find name only when it is mode-change only,
* creation or deletion of an empty file. In any of these cases,
* both sides are the same name under a/ and b/ respectively.
*/
static
char
*
git_header_name
(
char
*
line
,
int
llen
)
{
int
len
;
char
*
name
,
*
second
;
const
char
*
name
;
const
char
*
second
=
NULL
;
/*
* Find the first '/'
*/
name
=
line
;
for
(;;)
{
char
c
=
*
name
++
;
if
(
c
==
'\n'
)
line
+=
strlen
(
"diff --git "
);
llen
-=
strlen
(
"diff --git "
);
if
(
*
line
==
'"'
)
{
const
char
*
cp
;
char
*
first
=
unquote_c_style
(
line
,
&
second
)
;
if
(
!
first
)
return
NULL
;
if
(
c
==
'/'
)
break
;
/* advance to the first slash */
cp
=
stop_at_slash
(
first
,
strlen
(
first
));
if
(
!
cp
||
cp
==
first
)
{
/* we do not accept absolute paths */
free_first_and_fail:
free
(
first
);
return
NULL
;
}
len
=
strlen
(
cp
+
1
);
memmove
(
first
,
cp
+
1
,
len
+
1
);
/* including NUL */
/* second points at one past closing dq of name.
* find the second name.
*/
while
((
second
<
line
+
llen
)
&&
isspace
(
*
second
))
second
++
;
if
(
line
+
llen
<=
second
)
goto
free_first_and_fail
;
if
(
*
second
==
'"'
)
{
char
*
sp
=
unquote_c_style
(
second
,
NULL
);
if
(
!
sp
)
goto
free_first_and_fail
;
cp
=
stop_at_slash
(
sp
,
strlen
(
sp
));
if
(
!
cp
||
cp
==
sp
)
{
free_both_and_fail:
free
(
sp
);
goto
free_first_and_fail
;
}
/* They must match, otherwise ignore */
if
(
strcmp
(
cp
+
1
,
first
))
goto
free_both_and_fail
;
free
(
sp
);
return
first
;
}
/* unquoted second */
cp
=
stop_at_slash
(
second
,
line
+
llen
-
second
);
if
(
!
cp
||
cp
==
second
)
goto
free_first_and_fail
;
cp
++
;
if
(
line
+
llen
-
cp
!=
len
+
1
||
memcmp
(
first
,
cp
,
len
))
goto
free_first_and_fail
;
return
first
;
}
/*
* We don't accept absolute paths (/dev/null) as possibly valid
*/
if
(
name
==
line
+
1
)
/* unquoted first name */
name
=
stop_at_slash
(
line
,
llen
);
if
(
!
name
||
name
==
line
)
return
NULL
;
name
++
;
/* since the first name is unquoted, a dq if exists must be
* the beginning of the second name.
*/
for
(
second
=
name
;
second
<
line
+
llen
;
second
++
)
{
if
(
*
second
==
'"'
)
{
const
char
*
cp
=
second
;
const
char
*
np
;
char
*
sp
=
unquote_c_style
(
second
,
NULL
);
if
(
!
sp
)
return
NULL
;
np
=
stop_at_slash
(
sp
,
strlen
(
sp
));
if
(
!
np
||
np
==
sp
)
{
free_second_and_fail:
free
(
sp
);
return
NULL
;
}
np
++
;
len
=
strlen
(
np
);
if
(
len
<
cp
-
name
&&
!
strncmp
(
np
,
name
,
len
)
&&
isspace
(
name
[
len
]))
{
/* Good */
memmove
(
sp
,
np
,
len
+
1
);
return
sp
;
}
goto
free_second_and_fail
;
}
}
/*
* Accept a name only if it shows up twice, exactly the same
* form.
...
...
@@ -448,7 +566,7 @@ static int parse_git_header(char *line, int len, unsigned int size, struct patch
* or removing or adding empty files), so we get
* the default name from the header.
*/
patch
->
def_name
=
git_header_name
(
line
+
strlen
(
"diff --git "
)
);
patch
->
def_name
=
git_header_name
(
line
,
len
);
line
+=
len
;
size
-=
len
;
...
...
@@ -785,11 +903,18 @@ static void show_stats(struct patch *patch)
{
const
char
*
prefix
=
""
;
char
*
name
=
patch
->
new_name
;
char
*
qname
=
NULL
;
int
len
,
max
,
add
,
del
,
total
;
if
(
!
name
)
name
=
patch
->
old_name
;
if
(
0
<
(
len
=
quote_c_style
(
name
,
NULL
,
NULL
,
0
)))
{
qname
=
xmalloc
(
len
+
1
);
quote_c_style
(
name
,
qname
,
NULL
,
0
);
name
=
qname
;
}
/*
* "scale" the filename
*/
...
...
@@ -827,6 +952,8 @@ static void show_stats(struct patch *patch)
printf
(
" %s%-*s |%5d %.*s%.*s
\n
"
,
prefix
,
len
,
name
,
patch
->
lines_added
+
patch
->
lines_deleted
,
add
,
pluses
,
del
,
minuses
);
if
(
qname
)
free
(
qname
);
}
static
int
read_old_data
(
struct
stat
*
st
,
const
char
*
path
,
void
*
buf
,
unsigned
long
size
)
...
...
@@ -1197,8 +1324,13 @@ static void show_index_list(struct patch *list)
name
);
else
sha1_ptr
=
sha1
;
printf
(
"%06o %s %s
\n
"
,
patch
->
old_mode
,
sha1_to_hex
(
sha1_ptr
),
name
);
printf
(
"%06o %s "
,
patch
->
old_mode
,
sha1_to_hex
(
sha1_ptr
));
if
(
line_termination
&&
quote_c_style
(
name
,
NULL
,
NULL
,
0
))
quote_c_style
(
name
,
NULL
,
stdout
,
0
);
else
fputs
(
name
,
stdout
);
putchar
(
line_termination
);
}
}
...
...
@@ -1301,12 +1433,16 @@ static void patch_stats(struct patch *patch)
if
(
lines
>
max_change
)
max_change
=
lines
;
if
(
patch
->
old_name
)
{
int
len
=
strlen
(
patch
->
old_name
);
int
len
=
quote_c_style
(
patch
->
old_name
,
NULL
,
NULL
,
0
);
if
(
!
len
)
len
=
strlen
(
patch
->
old_name
);
if
(
len
>
max_len
)
max_len
=
len
;
}
if
(
patch
->
new_name
)
{
int
len
=
strlen
(
patch
->
new_name
);
int
len
=
quote_c_style
(
patch
->
new_name
,
NULL
,
NULL
,
0
);
if
(
!
len
)
len
=
strlen
(
patch
->
new_name
);
if
(
len
>
max_len
)
max_len
=
len
;
}
...
...
@@ -1603,11 +1739,15 @@ int main(int argc, char **argv)
show_files
=
1
;
continue
;
}
if
(
!
strcmp
(
arg
,
"--
show-
index-info"
))
{
if
(
!
strcmp
(
arg
,
"--index-info"
))
{
apply
=
0
;
show_index_info
=
1
;
continue
;
}
if
(
!
strcmp
(
arg
,
"-z"
))
{
line_termination
=
0
;
continue
;
}
fd
=
open
(
arg
,
O_RDONLY
);
if
(
fd
<
0
)
usage
(
apply_usage
);
...
...
git-am.sh
浏览文件 @
22943f1a
...
...
@@ -35,10 +35,10 @@ fall_back_3way () {
mkdir
"
$dotest
/patch-merge-tmp-dir"
# First see if the patch records the index info that we can use.
if
git-apply
-
-show
-index-info
"
$dotest
/patch"
\
if
git-apply
-
z
-
-index-info
"
$dotest
/patch"
\
>
"
$dotest
/patch-merge-index-info"
2>/dev/null
&&
GIT_INDEX_FILE
=
"
$dotest
/patch-merge-tmp-index"
\
git-update-index
--index-info
<
"
$dotest
/patch-merge-index-info"
&&
git-update-index
-
z
-
-index-info
<
"
$dotest
/patch-merge-index-info"
&&
GIT_INDEX_FILE
=
"
$dotest
/patch-merge-tmp-index"
\
git-write-tree
>
"
$dotest
/patch-merge-base+"
&&
# index has the base tree now.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录