Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
李少辉-开发者
git
提交
79a9d8ea
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,发现更多精彩内容 >>
提交
79a9d8ea
编写于
10月 03, 2005
作者:
P
Peter Anvin
浏览文件
操作
浏览文件
下载
差异文件
Merge with master.kernel.org:/pub/scm/git/git.git
上级
039c6f16
baaac6a7
变更
44
展开全部
隐藏空白更改
内联
并排
Showing
44 changed file
with
1360 addition
and
451 deletion
+1360
-451
.gitignore
.gitignore
+1
-0
Documentation/git-clone.txt
Documentation/git-clone.txt
+14
-1
Documentation/git-ls-files.txt
Documentation/git-ls-files.txt
+8
-1
Makefile
Makefile
+48
-19
apply.c
apply.c
+13
-0
cache.h
cache.h
+5
-0
debian/changelog
debian/changelog
+6
-0
diff-files.c
diff-files.c
+0
-1
diff.c
diff.c
+1
-2
fsck-objects.c
fsck-objects.c
+10
-18
git-archimport.perl
git-archimport.perl
+7
-1
git-bisect.sh
git-bisect.sh
+4
-3
git-branch.sh
git-branch.sh
+4
-2
git-checkout.sh
git-checkout.sh
+2
-1
git-commit.sh
git-commit.sh
+8
-9
git-cvsimport.perl
git-cvsimport.perl
+11
-7
git-fetch.sh
git-fetch.sh
+24
-1
git-merge-recursive.py
git-merge-recursive.py
+601
-185
git-merge.sh
git-merge.sh
+21
-1
git-sh-setup.sh
git-sh-setup.sh
+5
-2
git-status.sh
git-status.sh
+3
-3
git.sh
git.sh
+44
-11
http-fetch.c
http-fetch.c
+168
-24
index.c
index.c
+1
-1
init-db.c
init-db.c
+5
-5
ls-files.c
ls-files.c
+5
-1
mailsplit.c
mailsplit.c
+1
-1
read-cache.c
read-cache.c
+9
-5
read-tree.c
read-tree.c
+12
-6
refs.c
refs.c
+153
-34
setup.c
setup.c
+9
-7
sha1_file.c
sha1_file.c
+2
-0
sha1_name.c
sha1_name.c
+1
-16
show-branch.c
show-branch.c
+9
-4
symbolic-ref.c
symbolic-ref.c
+34
-0
t/Makefile
t/Makefile
+1
-0
t/t3002-ls-files-dashpath.sh
t/t3002-ls-files-dashpath.sh
+69
-0
t/t5000-tar-tree.sh
t/t5000-tar-tree.sh
+3
-3
t/t5400-send-pack.sh
t/t5400-send-pack.sh
+3
-3
t/t6002-rev-list-bisect.sh
t/t6002-rev-list-bisect.sh
+13
-16
tar-tree.c
tar-tree.c
+2
-0
update-index.c
update-index.c
+17
-7
update-ref.c
update-ref.c
+1
-48
usage.c
usage.c
+2
-2
未找到文件。
.gitignore
浏览文件 @
79a9d8ea
...
...
@@ -82,6 +82,7 @@ git-ssh-push
git-ssh-upload
git-status
git-stripspace
git-symbolic-ref
git-tag
git-tar-tree
git-unpack-file
...
...
Documentation/git-clone.txt
浏览文件 @
79a9d8ea
...
...
@@ -9,7 +9,7 @@ git-clone - Clones a repository.
SYNOPSIS
--------
'git clone' [-l
] [-u <upload-pack>] [-q
] <repository> <directory>
'git clone' [-l
[-s]] [-q] [-n] [-u <upload-pack>
] <repository> <directory>
DESCRIPTION
-----------
...
...
@@ -17,6 +17,7 @@ Clones a repository into a newly created directory.
OPTIONS
-------
--local::
-l::
When the repository to clone from is on a local machine,
this flag bypasses normal "git aware" transport
...
...
@@ -25,10 +26,22 @@ OPTIONS
The files under .git/objects/ directory are hardlinked
to save space when possible.
--shared::
-s::
When the repository to clone is on the local machine,
instead of using hard links automatically setup
.git/objects/info/alternatives to share the objects
with the source repository
--quiet::
-q::
Operate quietly. This flag is passed to "rsync" and
"git-clone-pack" commands when given.
-n::
No checkout of HEAD is performed after the clone is complete.
--upload-pack <upload-pack>::
-u <upload-pack>::
When given, and the repository to clone from is handled
by 'git-clone-pack', '--exec=<upload-pack>' is passed to
...
...
Documentation/git-ls-files.txt
浏览文件 @
79a9d8ea
...
...
@@ -13,7 +13,7 @@ SYNOPSIS
(-[c|d|o|i|s|u|k|m])\*
[-x <pattern>|--exclude=<pattern>]
[-X <file>|--exclude-from=<file>]
[--exclude-per-directory=<file>]
[--exclude-per-directory=<file>]
[--] [<file>]\*
DESCRIPTION
-----------
...
...
@@ -77,6 +77,13 @@ OPTIONS
K to be killed
? other
--::
Do not interpret any more arguments as options.
<file>::
Files to show. If no files are given all files which match the other
specified criteria are shown.
Output
------
show files just outputs the filename unless '--stage' is specified in
...
...
Makefile
浏览文件 @
79a9d8ea
...
...
@@ -50,7 +50,7 @@
# DEFINES += -DUSE_STDEV
GIT_VERSION
=
0.99.
7
.GIT
GIT_VERSION
=
0.99.
8
.GIT
CFLAGS
=
-g
-O2
-Wall
ALL_CFLAGS
=
$(CFLAGS)
$(PLATFORM_DEFINES)
$(DEFINES)
...
...
@@ -103,25 +103,29 @@ SIMPLE_PROGRAMS = \
# ... and all the rest
PROGRAMS
=
\
git-apply
$X
git-cat-file
$X
git-checkout-index
$X
\
git-clone-pack
$X
git-commit-tree
$X
git-convert-objects
$X
\
git-diff-files
$X
git-diff-index
$X
git-diff-stages
$X
\
git-diff-tree
$X
git-fetch-pack
$X
git-fsck-objects
$X
\
git-hash-object
$X
git-init-db
$X
git-local-fetch
$X
\
git-ls-files
$X
git-ls-tree
$X
git-merge-base
$X
\
git-merge-index
$X
git-mktag
$X
git-pack-objects
$X
\
git-patch-id
$X
git-peek-remote
$X
git-prune-packed
$X
\
git-read-tree
$X
git-receive-pack
$X
git-rev-list
$X
\
git-rev-parse
$X
git-send-pack
$X
git-show-branch
$X
\
git-show-index
$X
git-ssh-fetch
$X
git-ssh-upload
$X
\
git-tar-tree
$X
git-unpack-file
$X
git-unpack-objects
$X
\
git-update-index
$X
git-update-server-info
$X
\
git-upload-pack
$X
git-verify-pack
$X
git-write-tree
$X
\
git-update-ref
$X
$(SIMPLE_PROGRAMS)
git-apply
$X
git-cat-file
$X
\
git-checkout-index
$X
git-clone-pack
$X
git-commit-tree
$X
\
git-convert-objects
$X
git-diff-files
$X
\
git-diff-index
$X
git-diff-stages
$X
\
git-diff-tree
$X
git-fetch-pack
$X
git-fsck-objects
$X
\
git-hash-object
$X
git-init-db
$X
\
git-local-fetch
$X
git-ls-files
$X
git-ls-tree
$X
git-merge-base
$X
\
git-merge-index
$X
git-mktag
$X
git-pack-objects
$X
git-patch-id
$X
\
git-peek-remote
$X
git-prune-packed
$X
git-read-tree
$X
\
git-receive-pack
$X
git-rev-list
$X
git-rev-parse
$X
\
git-send-pack
$X
git-show-branch
$X
\
git-show-index
$X
git-ssh-fetch
$X
\
git-ssh-upload
$X
git-tar-tree
$X
git-unpack-file
$X
\
git-unpack-objects
$X
git-update-index
$X
git-update-server-info
$X
\
git-upload-pack
$X
git-verify-pack
$X
git-write-tree
$X
\
git-update-ref
$X
git-symbolic-ref
$X
\
$(SIMPLE_PROGRAMS)
# Backward compatibility -- to be removed after 1.0
PROGRAMS
+=
git-ssh-pull
$X
git-ssh-push
$X
GIT_LIST_TWEAK
=
PYMODULES
=
\
gitMergeCommon.py
...
...
@@ -131,6 +135,8 @@ endif
ifdef
WITH_SEND_EMAIL
SCRIPT_PERL
+=
git-send-email.perl
else
GIT_LIST_TWEAK
+=
-e
'/^send-email$$/d'
endif
LIB_FILE
=
libgit.a
...
...
@@ -181,6 +187,10 @@ endif
ifneq
(,$(findstring arm,$(shell uname -m)))
ARM_SHA1
=
YesPlease
endif
ifeq
($(shell uname -s),OpenBSD)
NEEDS_LIBICONV
=
YesPlease
PLATFORM_DEFINES
+=
-I
/usr/local/include
-L
/usr/local/lib
endif
ifndef
NO_CURL
ifdef
CURLDIR
...
...
@@ -206,18 +216,32 @@ endif
ifndef
NO_OPENSSL
LIB_OBJS
+=
epoch.o
OPENSSL_LIBSSL
=
-lssl
ifdef
OPENSSLDIR
# Again this may be problematic -- gcc does not always want -R.
CFLAGS
+=
-I
$(OPENSSLDIR)
/include
OPENSSL_LINK
=
-L
$(OPENSSLDIR)
/lib
-R
$(OPENSSLDIR)
/lib
else
OPENSSL_LINK
=
endif
else
DEFINES
+=
'-DNO_OPENSSL'
MOZILLA_SHA1
=
1
OPENSSL_LIBSSL
=
endif
ifdef
NEEDS_SSL_WITH_CRYPTO
LIB_4_CRYPTO
=
-lcrypto
-lssl
LIB_4_CRYPTO
=
$(OPENSSL_LINK)
-lcrypto
-lssl
else
LIB_4_CRYPTO
=
-lcrypto
LIB_4_CRYPTO
=
$(OPENSSL_LINK)
-lcrypto
endif
ifdef
NEEDS_LIBICONV
LIB_4_ICONV
=
-liconv
ifdef
ICONVDIR
# Again this may be problematic -- gcc does not always want -R.
CFLAGS
+=
-I
$(ICONVDIR)
/include
ICONV_LINK
=
-L
$(ICONVDIR)
/lib
-R
$(ICONVDIR)
/lib
else
ICONV_LINK
=
endif
LIB_4_ICONV
=
$(ICONV_LINK)
-liconv
else
LIB_4_ICONV
=
endif
...
...
@@ -273,8 +297,13 @@ all:
git
:
git.sh Makefile
rm
-f
$@
+
$@
sed
-e
'1s|#!.*/sh|#!
$(SHELL_PATH)
|'
\
<<<<<<
< Makefile
-
e
's/@@GIT_VERSION@@/
$(GIT_VERSION)
/g'
\
-e
's/@@X@@/
$(X)
/g'
<
$@
.sh
>
$@
+
=======
-e
's/@@GIT_VERSION@@/$(GIT_VERSION)/g'
\
$(GIT_LIST_TWEAK)
<$@.sh
>$@+
>>>>>>>
.merge_file_3QHyD4
chmod
+x
$@+
mv
$@+
$@
...
...
apply.c
浏览文件 @
79a9d8ea
...
...
@@ -723,6 +723,16 @@ static int parse_single_patch(char *line, unsigned long size, struct patch *patc
return
offset
;
}
static
inline
int
metadata_changes
(
struct
patch
*
patch
)
{
return
patch
->
is_rename
>
0
||
patch
->
is_copy
>
0
||
patch
->
is_new
>
0
||
patch
->
is_delete
||
(
patch
->
old_mode
&&
patch
->
new_mode
&&
patch
->
old_mode
!=
patch
->
new_mode
);
}
static
int
parse_chunk
(
char
*
buffer
,
unsigned
long
size
,
struct
patch
*
patch
)
{
int
hdrsize
,
patchsize
;
...
...
@@ -733,6 +743,9 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
patchsize
=
parse_single_patch
(
buffer
+
offset
+
hdrsize
,
size
-
offset
-
hdrsize
,
patch
);
if
(
!
patchsize
&&
!
metadata_changes
(
patch
))
die
(
"patch with only garbage at line %d"
,
linenr
);
return
offset
+
hdrsize
+
patchsize
;
}
...
...
cache.h
浏览文件 @
79a9d8ea
...
...
@@ -189,6 +189,7 @@ extern char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)
extern
char
*
sha1_file_name
(
const
unsigned
char
*
sha1
);
extern
char
*
sha1_pack_name
(
const
unsigned
char
*
sha1
);
extern
char
*
sha1_pack_index_name
(
const
unsigned
char
*
sha1
);
extern
const
unsigned
char
null_sha1
[
20
];
int
git_mkstemp
(
char
*
path
,
size_t
n
,
const
char
*
template
);
...
...
@@ -228,6 +229,10 @@ extern int has_pack_index(const unsigned char *sha1);
extern
int
get_sha1
(
const
char
*
str
,
unsigned
char
*
sha1
);
extern
int
get_sha1_hex
(
const
char
*
hex
,
unsigned
char
*
sha1
);
extern
char
*
sha1_to_hex
(
const
unsigned
char
*
sha1
);
/* static buffer result! */
extern
int
read_ref
(
const
char
*
filename
,
unsigned
char
*
sha1
);
extern
const
char
*
resolve_ref
(
const
char
*
path
,
unsigned
char
*
sha1
,
int
);
extern
int
create_symref
(
const
char
*
git_HEAD
,
const
char
*
refs_heads_master
);
extern
int
validate_symref
(
const
char
*
git_HEAD
);
/* General helper functions */
extern
void
usage
(
const
char
*
err
)
NORETURN
;
...
...
debian/changelog
浏览文件 @
79a9d8ea
git-core (0.99.8-0) unstable; urgency=low
* GIT 0.99.8
-- Junio C Hamano <junkio@cox.net> Sun, 2 Oct 2005 12:54:26 -0700
git-core (0.99.7-0) unstable; urgency=low
* GIT 0.99.7
...
...
diff-files.c
浏览文件 @
79a9d8ea
...
...
@@ -34,7 +34,6 @@ static void show_modified(int oldmode, int mode,
int
main
(
int
argc
,
const
char
**
argv
)
{
static
const
unsigned
char
null_sha1
[
20
]
=
{
0
,
};
const
char
**
pathspec
;
const
char
*
prefix
=
setup_git_directory
();
int
entries
,
i
;
...
...
diff.c
浏览文件 @
79a9d8ea
...
...
@@ -10,7 +10,6 @@
#include "diffcore.h"
static
const
char
*
diff_opts
=
"-pu"
;
static
unsigned
char
null_sha1
[
20
]
=
{
0
,
};
static
int
use_size_cache
;
...
...
@@ -414,7 +413,7 @@ void diff_free_filespec_data(struct diff_filespec *s)
static
void
prep_temp_blob
(
struct
diff_tempfile
*
temp
,
void
*
blob
,
unsigned
long
size
,
unsigned
char
*
sha1
,
const
unsigned
char
*
sha1
,
int
mode
)
{
int
fd
;
...
...
fsck-objects.c
浏览文件 @
79a9d8ea
...
...
@@ -402,25 +402,17 @@ static void fsck_object_dir(const char *path)
static
int
fsck_head_link
(
void
)
{
int
fd
,
count
;
char
hex
[
40
];
unsigned
char
sha1
[
20
];
static
char
path
[
PATH_MAX
],
link
[
PATH_MAX
];
const
char
*
git_dir
=
get_git_dir
();
snprintf
(
path
,
sizeof
(
path
),
"%s/HEAD"
,
git_dir
);
if
(
readlink
(
path
,
link
,
sizeof
(
link
))
<
0
)
return
error
(
"HEAD is not a symlink"
);
if
(
strncmp
(
"refs/heads/"
,
link
,
11
))
return
error
(
"HEAD points to something strange (%s)"
,
link
);
fd
=
open
(
path
,
O_RDONLY
);
if
(
fd
<
0
)
return
error
(
"HEAD: %s"
,
strerror
(
errno
));
count
=
read
(
fd
,
hex
,
sizeof
(
hex
));
close
(
fd
);
if
(
count
<
0
)
return
error
(
"HEAD: %s"
,
strerror
(
errno
));
if
(
count
<
40
||
get_sha1_hex
(
hex
,
sha1
))
const
char
*
git_HEAD
=
strdup
(
git_path
(
"HEAD"
));
const
char
*
git_refs_heads_master
=
resolve_ref
(
git_HEAD
,
sha1
,
1
);
int
pfxlen
=
strlen
(
git_HEAD
)
-
4
;
/* strip .../.git/ part */
if
(
!
git_refs_heads_master
)
return
error
(
"HEAD is not a symbolic ref"
);
if
(
strncmp
(
git_refs_heads_master
+
pfxlen
,
"refs/heads/"
,
11
))
return
error
(
"HEAD points to something strange (%s)"
,
git_refs_heads_master
+
pfxlen
);
if
(
!
memcmp
(
null_sha1
,
sha1
,
20
))
return
error
(
"HEAD: not a valid git pointer"
);
return
0
;
}
...
...
git-archimport.perl
浏览文件 @
79a9d8ea
...
...
@@ -228,10 +228,12 @@ END
# skip commits already in repo
#
if
(
ptag
(
$ps
->
{
id
}))
{
$opt_v
&&
print
"
Skipping already imported:
$ps
->{id}
\n
";
$opt_v
&&
print
"
*
Skipping already imported:
$ps
->{id}
\n
";
next
;
}
print
"
* Starting to work on
$ps
->{id}
\n
";
#
# create the branch if needed
#
...
...
@@ -675,6 +677,10 @@ sub find_parents {
# that branch.
#
foreach my
$branch
(keys %branches) {
# check that we actually know about the branch
next unless -e
"
$git_dir
/refs/
heads
/
$branch
"
;
my
$mergebase
= `git-merge-base
$branch
$ps
->{branch}`;
die
"
Cannot
find
merge
base
for
$branch
and
$ps
->
{
branch
}"
if $?;
chomp
$mergebase
;
...
...
git-bisect.sh
浏览文件 @
79a9d8ea
...
...
@@ -38,7 +38,8 @@ bisect_start() {
# Verify HEAD. If we were bisecting before this, reset to the
# top-of-line master first!
#
head
=
$(
readlink
$GIT_DIR
/HEAD
)
||
die
"Bad HEAD - I need a symlink"
head
=
$(
GIT_DIR
=
"
$GIT_DIR
"
git-symbolic-ref HEAD
)
||
die
"Bad HEAD - I need a symbolic ref"
case
"
$head
"
in
refs/heads/bisect
*
)
git checkout master
||
exit
...
...
@@ -46,7 +47,7 @@ bisect_start() {
refs/heads/
*
)
;;
*
)
die
"Bad HEAD - strange sym
link
"
die
"Bad HEAD - strange sym
bolic ref
"
;;
esac
...
...
@@ -135,7 +136,7 @@ bisect_next() {
echo
"
$rev
"
>
"
$GIT_DIR
/refs/heads/new-bisect"
git checkout new-bisect
||
exit
mv
"
$GIT_DIR
/refs/heads/new-bisect"
"
$GIT_DIR
/refs/heads/bisect"
&&
ln
-sf
refs/heads/bisect
"
$GIT_DIR
/HEAD"
GIT_DIR
=
"
$GIT_DIR
"
git-symbolic-ref HEAD refs/heads/bisect
git-show-branch
"
$rev
"
}
...
...
git-branch.sh
浏览文件 @
79a9d8ea
...
...
@@ -14,7 +14,8 @@ If two arguments, create a new branch <branchname> based off of <start-point>.
delete_branch
()
{
option
=
"
$1
"
branch_name
=
"
$2
"
headref
=
$(
readlink
"
$GIT_DIR
/HEAD"
|
sed
-e
's|^refs/heads/||'
)
headref
=
$(
GIT_DIR
=
"
$GIT_DIR
"
git-symbolic-ref HEAD |
sed
-e
's|^refs/heads/||'
)
case
",
$headref
,"
in
",
$branch_name
,"
)
die
"Cannot delete the branch you are on."
;;
...
...
@@ -67,7 +68,8 @@ done
case
"$#"
in
0
)
headref
=
$(
readlink
"
$GIT_DIR
/HEAD"
|
sed
-e
's|^refs/heads/||'
)
headref
=
$(
GIT_DIR
=
"
$GIT_DIR
"
git-symbolic-ref HEAD |
sed
-e
's|^refs/heads/||'
)
git-rev-parse
--symbolic
--all
|
sed
-ne
's|^refs/heads/||p'
|
sort
|
...
...
git-checkout.sh
浏览文件 @
79a9d8ea
...
...
@@ -71,7 +71,8 @@ if [ "$?" -eq 0 ]; then
echo
$new
>
"
$GIT_DIR
/refs/heads/
$newbranch
"
branch
=
"
$newbranch
"
fi
[
"
$branch
"
]
&&
ln
-sf
"refs/heads/
$branch
"
"
$GIT_DIR
/HEAD"
[
"
$branch
"
]
&&
GIT_DIR
=
"
$GIT_DIR
"
git-symbolic-ref HEAD
"refs/heads/
$branch
"
rm
-f
"
$GIT_DIR
/MERGE_HEAD"
else
exit
1
...
...
git-commit.sh
浏览文件 @
79a9d8ea
...
...
@@ -153,15 +153,8 @@ if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
fi
>>
.editmsg
PARENTS
=
"-p HEAD"
if
[
!
-r
"
$GIT_DIR
/HEAD"
]
;
then
if
[
-z
"
$(
git-ls-files
)
"
]
;
then
echo
Nothing to commit 1>&2
exit
1
fi
PARENTS
=
""
current
=
else
current
=
$(
git-rev-parse
--verify
HEAD
)
if
GIT_DIR
=
"
$GIT_DIR
"
git-rev-parse
--verify
HEAD
>
/dev/null 2>&1
then
if
[
-f
"
$GIT_DIR
/MERGE_HEAD"
]
;
then
PARENTS
=
"-p HEAD "
`
sed
-e
's/^/-p /'
"
$GIT_DIR
/MERGE_HEAD"
`
fi
...
...
@@ -194,6 +187,12 @@ else
export
GIT_AUTHOR_EMAIL
export
GIT_AUTHOR_DATE
fi
else
if
[
-z
"
$(
git-ls-files
)
"
]
;
then
echo
Nothing to commit 1>&2
exit
1
fi
PARENTS
=
""
fi
git-status
>>
.editmsg
if
[
"
$?
"
!=
"0"
-a
!
-f
$GIT_DIR
/MERGE_HEAD
]
...
...
git-cvsimport.perl
浏览文件 @
79a9d8ea
...
...
@@ -510,7 +510,7 @@ ($$)
my $state = 0;
my($patchset,$date,$author,$branch,$ancestor,$tag,$logmsg);
my($patchset,$date,$author
_name,$author_email
,$branch,$ancestor,$tag,$logmsg);
my(@old,@new);
my $commit = sub {
my $pid;
...
...
@@ -591,11 +591,11 @@ ($$)
}
exec("env",
"GIT_AUTHOR_NAME=$author",
"GIT_AUTHOR_EMAIL=$author",
"GIT_AUTHOR_NAME=$author
_name
",
"GIT_AUTHOR_EMAIL=$author
_email
",
"GIT_AUTHOR_DATE=".strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date)),
"GIT_COMMITTER_NAME=$author",
"GIT_COMMITTER_EMAIL=$author",
"GIT_COMMITTER_NAME=$author
_name
",
"GIT_COMMITTER_EMAIL=$author
_email
",
"GIT_COMMITTER_DATE=".strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date)),
"git-commit-tree", $tree,@par);
die "Cannot exec git-commit-tree: $!\n";
...
...
@@ -638,7 +638,7 @@ ($$)
print $out "object $cid\n".
"type commit\n".
"tag $xtag\n".
"tagger $author
<$author
>\n"
"tagger $author
_name <$author_email
>\n"
or die "Cannot create tag object $xtag: $!\n";
close($out)
or die "Cannot create tag object $xtag: $!\n";
...
...
@@ -683,7 +683,11 @@ ($$)
$state=3;
} elsif($state == 3 and s/^Author:\s+//) {
s/\s+$//;
$author = $_;
if (/^(.*?)\s+<(.*)>/) {
($author_name, $author_email) = ($1, $2);
} else {
$author_name = $author_email = $_;
}
$state = 4;
} elsif($state == 4 and s/^Branch:\s+//) {
s/\s+$//;
...
...
git-fetch.sh
浏览文件 @
79a9d8ea
...
...
@@ -5,6 +5,7 @@
_x40
=
'[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
_x40
=
"
$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40
"
tags
=
append
=
force
=
update_head_ok
=
...
...
@@ -17,6 +18,9 @@ do
-f
|
--f
|
--fo
|
--for
|
--forc
|
--force
)
force
=
t
;;
-t
|
--t
|
--ta
|
--tag
|
--tags
)
tags
=
t
;;
-u
|
--u
|
--up
|
--upd
|
--upda
|
--updat
|
--update
|
--update-
|
--update-h
|
\
--update-he
|
--update-hea
|
--update-head
|
--update-head-
|
\
--update-head-o
|
--update-head-ok
)
...
...
@@ -158,7 +162,26 @@ case "$update_head_ok" in
;;
esac
for
ref
in
$(
get_remote_refs_for_fetch
"
$@
"
)
# If --tags (and later --heads or --all) is specified, then we are
# not talking about defaults stored in Pull: line of remotes or
# branches file, and just fetch those and refspecs explicitly given.
# Otherwise we do what we always did.
reflist
=
$(
get_remote_refs_for_fetch
"
$@
"
)
if
test
"
$tags
"
then
taglist
=
$(
git-ls-remote
--tags
"
$remote
"
|
awk
'{ print "."$2":"$2 }'
)
if
test
"$#"
-gt
1
then
# remote URL plus explicit refspecs; we need to merge them.
reflist
=
"
$reflist
$taglist
"
else
# No explicit refspecs; fetch tags only.
reflist
=
$taglist
fi
fi
for
ref
in
$reflist
do
refs
=
"
$refs
$ref
"
...
...
git-merge-recursive.py
浏览文件 @
79a9d8ea
此差异已折叠。
点击以展开。
git-merge.sh
浏览文件 @
79a9d8ea
...
...
@@ -123,10 +123,30 @@ case "$#,$common" in
dropsave
exit
0
;;
1,
*
)
1,
?
*
"
$LF
"
?
*
)
# We are not doing octopus and not fast forward. Need a
# real merge.
;;
1,
*
)
# We are not doing octopus, not fast forward, and have only
# one common. See if it is really trivial.
echo
"Trying really trivial in-index merge..."
git-update-index
--refresh
2>/dev/null
if
git-read-tree
--trivial
-m
-u
$common
$head
"
$1
"
&&
result_tree
=
$(
git-write-tree
)
then
echo
"Wonderful."
result_commit
=
$(
echo
"
$merge_msg
"
|
git-commit-tree
$result_tree
-p
HEAD
-p
"
$1
"
)
||
exit
git-update-ref HEAD
$result_commit
$head
summary
$result_commit
dropsave
exit
0
fi
echo
"Nope."
;;
*
)
# An octopus. If we can reach all the remote we are up to date.
up_to_date
=
t
...
...
git-sh-setup.sh
浏览文件 @
79a9d8ea
...
...
@@ -13,10 +13,13 @@
unset
CDPATH
die
()
{
echo
"
$@
"
>
&2
echo
>
&2
"
$@
"
exit
1
}
[
-h
"
$GIT_DIR
/HEAD"
]
&&
case
"
$(
GIT_DIR
=
"
$GIT_DIR
"
git-symbolic-ref HEAD 2>/dev/null
)
"
in
refs/
*
)
:
;;
*
)
false
;;
esac
&&
[
-d
"
$GIT_DIR
/refs"
]
&&
[
-d
"
$GIT_OBJECT_DIRECTORY
/00"
]
git-status.sh
浏览文件 @
79a9d8ea
...
...
@@ -31,15 +31,15 @@ report () {
[
"
$header
"
]
}
branch
=
`
readlink
"
$GIT_DIR
/HEAD"
`
branch
=
$(
GIT_DIR
=
"
$GIT_DIR
"
git-symbolic-ref HEAD
)
case
"
$branch
"
in
refs/heads/master
)
;;
*
)
echo
"# On branch
$branch
"
;;
esac
git-update-index
-
-refresh
>
/dev/null 2>&1
git-update-index
-
q
--unmerged
--refresh
||
exit
if
test
-f
"
$GIT_DIR
/HEAD"
if
GIT_DIR
=
"
$GIT_DIR
"
git-rev-parse
--verify
HEAD
>
/dev/null 2>&1
then
git-diff-index
-M
--cached
HEAD |
sed
's/^://'
|
...
...
git.sh
浏览文件 @
79a9d8ea
...
...
@@ -26,17 +26,50 @@ esac
echo
"Usage: git COMMAND [OPTIONS] [TARGET]"
if
[
-n
"
$cmd
"
]
;
then
echo
" git command '
$cmd
' not found: commands are:"
else
echo
" git commands are:"
echo
"git command '
$cmd
' not found."
fi
echo
"git commands are:"
cat
<<
\
EOF
add apply archimport bisect branch checkout cherry clone
commit count-objects cvsimport diff fetch format-patch
fsck-cache get-tar-commit-id init-db log ls-remote octopus
pack-objects parse-remote patch-id prune pull push rebase
relink rename repack request-pull reset resolve revert
send-email shortlog show-branch status tag verify-tag
whatchanged
fmt
<<
\
EOF
| sed -e 's/^/ /'
add
apply
archimport
bisect
branch
checkout
cherry
clone
commit
count-objects
cvsimport
diff
fetch
format-patch
fsck-objects
get-tar-commit-id
init-db
log
ls-remote
octopus
pack-objects
parse-remote
patch-id
prune
pull
push
rebase
relink
rename
repack
request-pull
reset
resolve
revert
send-email
shortlog
show-branch
status
tag
verify-tag
whatchanged
EOF
http-fetch.c
浏览文件 @
79a9d8ea
#include "cache.h"
#include "commit.h"
#include "pack.h"
#include "fetch.h"
#include <curl/curl.h>
...
...
@@ -13,8 +13,12 @@
#define curl_global_init(a) do {
/* nothing */
} while(0)
#endif
#define PREV_BUF_SIZE 4096
#define RANGE_HEADER_SIZE 30
static
CURL
*
curl
;
static
struct
curl_slist
*
no_pragma_header
;
static
struct
curl_slist
*
no_range_header
;
static
char
curl_errorstr
[
CURL_ERROR_SIZE
];
static
char
*
initial_base
;
...
...
@@ -87,12 +91,37 @@ void prefetch(unsigned char *sha1)
{
}
int
relink_or_rename
(
char
*
old
,
char
*
new
)
{
int
ret
;
ret
=
link
(
old
,
new
);
if
(
ret
<
0
)
{
/* Same Coda hack as in write_sha1_file(sha1_file.c) */
ret
=
errno
;
if
(
ret
==
EXDEV
&&
!
rename
(
old
,
new
))
return
0
;
}
unlink
(
old
);
if
(
ret
)
{
if
(
ret
!=
EEXIST
)
return
ret
;
}
return
0
;
}
static
int
got_alternates
=
0
;
static
int
fetch_index
(
struct
alt_base
*
repo
,
unsigned
char
*
sha1
)
{
char
*
filename
;
char
*
url
;
char
tmpfile
[
PATH_MAX
];
int
ret
;
long
prev_posn
=
0
;
char
range
[
RANGE_HEADER_SIZE
];
struct
curl_slist
*
range_header
=
NULL
;
CURLcode
curl_result
;
FILE
*
indexfile
;
...
...
@@ -108,7 +137,8 @@ static int fetch_index(struct alt_base *repo, unsigned char *sha1)
repo
->
base
,
sha1_to_hex
(
sha1
));
filename
=
sha1_pack_index_name
(
sha1
);
indexfile
=
fopen
(
filename
,
"w"
);
snprintf
(
tmpfile
,
sizeof
(
tmpfile
),
"%s.temp"
,
filename
);
indexfile
=
fopen
(
tmpfile
,
"a"
);
if
(
!
indexfile
)
return
error
(
"Unable to open local file %s for pack index"
,
filename
);
...
...
@@ -119,13 +149,36 @@ static int fetch_index(struct alt_base *repo, unsigned char *sha1)
curl_easy_setopt
(
curl
,
CURLOPT_HTTPHEADER
,
no_pragma_header
);
curl_easy_setopt
(
curl
,
CURLOPT_ERRORBUFFER
,
curl_errorstr
);
if
(
curl_easy_perform
(
curl
))
{
/* If there is data present from a previous transfer attempt,
resume where it left off */
prev_posn
=
ftell
(
indexfile
);
if
(
prev_posn
>
0
)
{
if
(
get_verbosely
)
fprintf
(
stderr
,
"Resuming fetch of index for pack %s at byte %ld
\n
"
,
sha1_to_hex
(
sha1
),
prev_posn
);
sprintf
(
range
,
"Range: bytes=%ld-"
,
prev_posn
);
range_header
=
curl_slist_append
(
range_header
,
range
);
curl_easy_setopt
(
curl
,
CURLOPT_HTTPHEADER
,
range_header
);
}
/* Clear out the Range: header after performing the request, so
other curl requests don't inherit inappropriate header data */
curl_result
=
curl_easy_perform
(
curl
);
curl_easy_setopt
(
curl
,
CURLOPT_HTTPHEADER
,
no_range_header
);
if
(
curl_result
!=
0
)
{
fclose
(
indexfile
);
return
error
(
"Unable to get pack index %s
\n
%s"
,
url
,
curl_errorstr
);
}
fclose
(
indexfile
);
ret
=
relink_or_rename
(
tmpfile
,
filename
);
if
(
ret
)
return
error
(
"unable to write index filename %s: %s"
,
filename
,
strerror
(
ret
));
return
0
;
}
...
...
@@ -306,6 +359,12 @@ static int fetch_pack(struct alt_base *repo, unsigned char *sha1)
struct
packed_git
**
lst
;
FILE
*
packfile
;
char
*
filename
;
char
tmpfile
[
PATH_MAX
];
int
ret
;
long
prev_posn
=
0
;
char
range
[
RANGE_HEADER_SIZE
];
struct
curl_slist
*
range_header
=
NULL
;
CURLcode
curl_result
;
if
(
fetch_indices
(
repo
))
return
-
1
;
...
...
@@ -325,7 +384,8 @@ static int fetch_pack(struct alt_base *repo, unsigned char *sha1)
repo
->
base
,
sha1_to_hex
(
target
->
sha1
));
filename
=
sha1_pack_name
(
target
->
sha1
);
packfile
=
fopen
(
filename
,
"w"
);
snprintf
(
tmpfile
,
sizeof
(
tmpfile
),
"%s.temp"
,
filename
);
packfile
=
fopen
(
tmpfile
,
"a"
);
if
(
!
packfile
)
return
error
(
"Unable to open local file %s for pack"
,
filename
);
...
...
@@ -336,7 +396,24 @@ static int fetch_pack(struct alt_base *repo, unsigned char *sha1)
curl_easy_setopt
(
curl
,
CURLOPT_HTTPHEADER
,
no_pragma_header
);
curl_easy_setopt
(
curl
,
CURLOPT_ERRORBUFFER
,
curl_errorstr
);
if
(
curl_easy_perform
(
curl
))
{
/* If there is data present from a previous transfer attempt,
resume where it left off */
prev_posn
=
ftell
(
packfile
);
if
(
prev_posn
>
0
)
{
if
(
get_verbosely
)
fprintf
(
stderr
,
"Resuming fetch of pack %s at byte %ld
\n
"
,
sha1_to_hex
(
target
->
sha1
),
prev_posn
);
sprintf
(
range
,
"Range: bytes=%ld-"
,
prev_posn
);
range_header
=
curl_slist_append
(
range_header
,
range
);
curl_easy_setopt
(
curl
,
CURLOPT_HTTPHEADER
,
range_header
);
}
/* Clear out the Range: header after performing the request, so
other curl requests don't inherit inappropriate header data */
curl_result
=
curl_easy_perform
(
curl
);
curl_easy_setopt
(
curl
,
CURLOPT_HTTPHEADER
,
no_range_header
);
if
(
curl_result
!=
0
)
{
fclose
(
packfile
);
return
error
(
"Unable to get pack file %s
\n
%s"
,
url
,
curl_errorstr
);
...
...
@@ -344,11 +421,18 @@ static int fetch_pack(struct alt_base *repo, unsigned char *sha1)
fclose
(
packfile
);
ret
=
relink_or_rename
(
tmpfile
,
filename
);
if
(
ret
)
return
error
(
"unable to write pack filename %s: %s"
,
filename
,
strerror
(
ret
));
lst
=
&
repo
->
packs
;
while
(
*
lst
!=
target
)
lst
=
&
((
*
lst
)
->
next
);
*
lst
=
(
*
lst
)
->
next
;
if
(
verify_pack
(
target
,
0
))
return
-
1
;
install_packed_git
(
target
);
return
0
;
...
...
@@ -360,14 +444,33 @@ static int fetch_object(struct alt_base *repo, unsigned char *sha1)
char
*
filename
=
sha1_file_name
(
sha1
);
unsigned
char
real_sha1
[
20
];
char
tmpfile
[
PATH_MAX
];
char
prevfile
[
PATH_MAX
];
int
ret
;
char
*
url
;
char
*
posn
;
int
prevlocal
;
unsigned
char
prev_buf
[
PREV_BUF_SIZE
];
ssize_t
prev_read
=
0
;
long
prev_posn
=
0
;
char
range
[
RANGE_HEADER_SIZE
];
struct
curl_slist
*
range_header
=
NULL
;
CURLcode
curl_result
;
snprintf
(
tmpfile
,
sizeof
(
tmpfile
),
"%s.temp"
,
filename
);
snprintf
(
prevfile
,
sizeof
(
prevfile
),
"%s.prev"
,
filename
);
if
(
unlink
(
prevfile
)
&&
(
errno
!=
ENOENT
))
return
error
(
"Failed to unlink %s (%s)"
,
prevfile
,
strerror
(
errno
));
if
(
rename
(
tmpfile
,
prevfile
)
&&
(
errno
!=
ENOENT
))
return
error
(
"Failed to rename %s to %s (%s)"
,
tmpfile
,
prevfile
,
strerror
(
errno
));
snprintf
(
tmpfile
,
sizeof
(
tmpfile
),
"%s/obj_XXXXXX"
,
get_object_directory
());
local
=
open
(
tmpfile
,
O_WRONLY
|
O_CREAT
|
O_EXCL
,
0666
);
/* Note: if another instance starts now, it will turn our new
tmpfile into its prevfile. */
local
=
mkstemp
(
tmpfile
);
if
(
local
<
0
)
return
error
(
"Couldn't create temporary file %s for %s: %s
\n
"
,
tmpfile
,
filename
,
strerror
(
errno
));
...
...
@@ -396,8 +499,57 @@ static int fetch_object(struct alt_base *repo, unsigned char *sha1)
curl_easy_setopt
(
curl
,
CURLOPT_URL
,
url
);
if
(
curl_easy_perform
(
curl
))
{
unlink
(
filename
);
/* If a previous temp file is present, process what was already
fetched. */
prevlocal
=
open
(
prevfile
,
O_RDONLY
);
if
(
prevlocal
!=
-
1
)
{
do
{
prev_read
=
read
(
prevlocal
,
prev_buf
,
PREV_BUF_SIZE
);
if
(
prev_read
>
0
)
{
if
(
fwrite_sha1_file
(
prev_buf
,
1
,
prev_read
,
NULL
)
==
prev_read
)
{
prev_posn
+=
prev_read
;
}
else
{
prev_read
=
-
1
;
}
}
}
while
(
prev_read
>
0
);
close
(
prevlocal
);
}
unlink
(
prevfile
);
/* Reset inflate/SHA1 if there was an error reading the previous temp
file; also rewind to the beginning of the local file. */
if
(
prev_read
==
-
1
)
{
memset
(
&
stream
,
0
,
sizeof
(
stream
));
inflateInit
(
&
stream
);
SHA1_Init
(
&
c
);
if
(
prev_posn
>
0
)
{
prev_posn
=
0
;
lseek
(
local
,
SEEK_SET
,
0
);
ftruncate
(
local
,
0
);
}
}
/* If we have successfully processed data from a previous fetch
attempt, only fetch the data we don't already have. */
if
(
prev_posn
>
0
)
{
if
(
get_verbosely
)
fprintf
(
stderr
,
"Resuming fetch of object %s at byte %ld
\n
"
,
hex
,
prev_posn
);
sprintf
(
range
,
"Range: bytes=%ld-"
,
prev_posn
);
range_header
=
curl_slist_append
(
range_header
,
range
);
curl_easy_setopt
(
curl
,
CURLOPT_HTTPHEADER
,
range_header
);
}
/* Clear out the Range: header after performing the request, so
other curl requests don't inherit inappropriate header data */
curl_result
=
curl_easy_perform
(
curl
);
curl_easy_setopt
(
curl
,
CURLOPT_HTTPHEADER
,
no_range_header
);
if
(
curl_result
!=
0
)
{
return
error
(
"%s"
,
curl_errorstr
);
}
...
...
@@ -413,20 +565,11 @@ static int fetch_object(struct alt_base *repo, unsigned char *sha1)
unlink
(
tmpfile
);
return
error
(
"File %s has bad hash
\n
"
,
hex
);
}
ret
=
link
(
tmpfile
,
filename
);
if
(
ret
<
0
)
{
/* Same Coda hack as in write_sha1_file(sha1_file.c) */
ret
=
errno
;
if
(
ret
==
EXDEV
&&
!
rename
(
tmpfile
,
filename
))
goto
out
;
}
unlink
(
tmpfile
);
if
(
ret
)
{
if
(
ret
!=
EEXIST
)
return
error
(
"unable to write sha1 filename %s: %s"
,
filename
,
strerror
(
ret
));
}
out:
ret
=
relink_or_rename
(
tmpfile
,
filename
);
if
(
ret
)
return
error
(
"unable to write sha1 filename %s: %s"
,
filename
,
strerror
(
ret
));
pull_say
(
"got %s
\n
"
,
hex
);
return
0
;
}
...
...
@@ -519,6 +662,7 @@ int main(int argc, char **argv)
curl
=
curl_easy_init
();
no_pragma_header
=
curl_slist_append
(
no_pragma_header
,
"Pragma:"
);
no_range_header
=
curl_slist_append
(
no_range_header
,
"Range:"
);
curl_ssl_verify
=
getenv
(
"GIT_SSL_NO_VERIFY"
)
?
0
:
1
;
curl_easy_setopt
(
curl
,
CURLOPT_SSL_VERIFYPEER
,
curl_ssl_verify
);
...
...
index.c
浏览文件 @
79a9d8ea
...
...
@@ -29,7 +29,7 @@ int hold_index_file_for_update(struct cache_file *cf, const char *path)
signal
(
SIGINT
,
remove_lock_file_on_signal
);
atexit
(
remove_lock_file
);
}
return
open
(
cf
->
lockfile
,
O_RDWR
|
O_CREAT
|
O_EXCL
,
06
00
);
return
open
(
cf
->
lockfile
,
O_RDWR
|
O_CREAT
|
O_EXCL
,
06
66
);
}
int
commit_index_file
(
struct
cache_file
*
cf
)
...
...
init-db.c
浏览文件 @
79a9d8ea
...
...
@@ -166,6 +166,7 @@ static void create_default_files(const char *git_dir,
{
unsigned
len
=
strlen
(
git_dir
);
static
char
path
[
PATH_MAX
];
unsigned
char
sha1
[
20
];
if
(
len
>
sizeof
(
path
)
-
50
)
die
(
"insane git directory %s"
,
git_dir
);
...
...
@@ -186,15 +187,14 @@ static void create_default_files(const char *git_dir,
/*
* Create the default symlink from ".git/HEAD" to the "master"
* branch
* branch
, if it does not exist yet.
*/
strcpy
(
path
+
len
,
"HEAD"
);
if
(
symlink
(
"refs/heads/master"
,
path
)
<
0
)
{
if
(
errno
!=
EEXIST
)
{
perror
(
path
);
if
(
read_ref
(
path
,
sha1
)
<
0
)
{
if
(
create_symref
(
path
,
"refs/heads/master"
)
<
0
)
exit
(
1
);
}
}
path
[
len
]
=
0
;
copy_templates
(
path
,
len
,
template_path
);
}
...
...
ls-files.c
浏览文件 @
79a9d8ea
...
...
@@ -530,7 +530,7 @@ static void verify_pathspec(void)
static
const
char
ls_files_usage
[]
=
"git-ls-files [-z] [-t] (--[cached|deleted|others|stage|unmerged|killed|modified])* "
"[ --ignored ] [--exclude=<pattern>] [--exclude-from=<file>] "
"[ --exclude-per-directory=<filename> ]"
;
"[ --exclude-per-directory=<filename> ]
[--] [<file>]*
"
;
int
main
(
int
argc
,
const
char
**
argv
)
{
...
...
@@ -544,6 +544,10 @@ int main(int argc, const char **argv)
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
const
char
*
arg
=
argv
[
i
];
if
(
!
strcmp
(
arg
,
"--"
))
{
i
++
;
break
;
}
if
(
!
strcmp
(
arg
,
"-z"
))
{
line_terminator
=
0
;
continue
;
...
...
mailsplit.c
浏览文件 @
79a9d8ea
...
...
@@ -128,7 +128,7 @@ int main(int argc, char **argv)
unsigned
long
len
=
parse_email
(
map
,
size
);
assert
(
len
<=
size
);
sprintf
(
name
,
"%04d"
,
++
nr
);
fd
=
open
(
name
,
O_WRONLY
|
O_CREAT
|
O_EXCL
,
06
00
);
fd
=
open
(
name
,
O_WRONLY
|
O_CREAT
|
O_EXCL
,
06
66
);
if
(
fd
<
0
)
{
perror
(
name
);
exit
(
1
);
...
...
read-cache.c
浏览文件 @
79a9d8ea
...
...
@@ -464,11 +464,15 @@ int read_cache(void)
errno
=
EBUSY
;
if
(
active_cache
)
return
error
(
"more than one cachefile"
);
return
active_nr
;
errno
=
ENOENT
;
fd
=
open
(
get_index_file
(),
O_RDONLY
);
if
(
fd
<
0
)
return
(
errno
==
ENOENT
)
?
0
:
error
(
"open failed"
);
if
(
fd
<
0
)
{
if
(
errno
==
ENOENT
)
return
0
;
die
(
"index file open failed (%s)"
,
strerror
(
errno
));
}
size
=
0
;
// avoid gcc warning
map
=
MAP_FAILED
;
...
...
@@ -480,7 +484,7 @@ int read_cache(void)
}
close
(
fd
);
if
(
map
==
MAP_FAILED
)
return
error
(
"mmap failed"
);
die
(
"index file mmap failed (%s)"
,
strerror
(
errno
)
);
hdr
=
map
;
if
(
verify_hdr
(
hdr
,
size
)
<
0
)
...
...
@@ -501,7 +505,7 @@ int read_cache(void)
unmap:
munmap
(
map
,
size
);
errno
=
EINVAL
;
return
error
(
"verify header failed
"
);
die
(
"index file corrupt
"
);
}
#define WRITE_BUFFER_SIZE 8192
...
...
read-tree.c
浏览文件 @
79a9d8ea
...
...
@@ -13,6 +13,8 @@
static
int
merge
=
0
;
static
int
update
=
0
;
static
int
index_only
=
0
;
static
int
nontrivial_merge
=
0
;
static
int
trivial_merges_only
=
0
;
static
int
head_idx
=
-
1
;
static
int
merge_size
=
0
;
...
...
@@ -275,6 +277,9 @@ static int unpack_trees(merge_fn_t fn)
if
(
unpack_trees_rec
(
posns
,
len
,
""
,
fn
,
&
indpos
))
return
-
1
;
if
(
trivial_merges_only
&&
nontrivial_merge
)
die
(
"Merge requires file-level merging"
);
check_updates
(
active_cache
,
active_nr
);
return
0
;
}
...
...
@@ -460,6 +465,8 @@ static int threeway_merge(struct cache_entry **stages)
verify_uptodate
(
index
);
}
nontrivial_merge
=
1
;
/* #2, #3, #4, #6, #7, #9, #11. */
count
=
0
;
if
(
!
head_match
||
!
remote_match
)
{
...
...
@@ -629,9 +636,9 @@ int main(int argc, char **argv)
continue
;
}
if
(
!
strcmp
(
arg
,
"--
head
"
))
{
head_idx
=
stage
-
1
;
fn
=
threeway_merg
e
;
if
(
!
strcmp
(
arg
,
"--
trivial
"
))
{
trivial_merges_only
=
1
;
continu
e
;
}
/* "-m" stands for "merge", meaning we start in stage 1 */
...
...
@@ -657,7 +664,8 @@ int main(int argc, char **argv)
}
if
((
update
||
index_only
)
&&
!
merge
)
usage
(
read_tree_usage
);
if
(
merge
&&
!
fn
)
{
if
(
merge
)
{
if
(
stage
<
2
)
die
(
"just how do you expect me to merge %d trees?"
,
stage
-
1
);
switch
(
stage
-
1
)
{
...
...
@@ -674,9 +682,7 @@ int main(int argc, char **argv)
fn
=
threeway_merge
;
break
;
}
}
if
(
head_idx
<
0
)
{
if
(
stage
-
1
>=
3
)
head_idx
=
stage
-
2
;
else
...
...
refs.c
浏览文件 @
79a9d8ea
...
...
@@ -2,19 +2,157 @@
#include "cache.h"
#include <errno.h>
#include <ctype.h>
static
int
read_ref
(
const
char
*
refname
,
unsigned
char
*
sha1
)
/* We allow "recursive" symbolic refs. Only within reason, though */
#define MAXDEPTH 5
#ifndef USE_SYMLINK_HEAD
#define USE_SYMLINK_HEAD 1
#endif
int
validate_symref
(
const
char
*
path
)
{
int
ret
=
-
1
;
int
fd
=
open
(
git_path
(
"%s"
,
refname
),
O_RDONLY
);
struct
stat
st
;
char
*
buf
,
buffer
[
256
];
int
len
,
fd
;
if
(
lstat
(
path
,
&
st
)
<
0
)
return
-
1
;
/* Make sure it is a "refs/.." symlink */
if
(
S_ISLNK
(
st
.
st_mode
))
{
len
=
readlink
(
path
,
buffer
,
sizeof
(
buffer
)
-
1
);
if
(
len
>=
5
&&
!
memcmp
(
"refs/"
,
buffer
,
5
))
return
0
;
return
-
1
;
}
/*
* Anything else, just open it and try to see if it is a symbolic ref.
*/
fd
=
open
(
path
,
O_RDONLY
);
if
(
fd
<
0
)
return
-
1
;
len
=
read
(
fd
,
buffer
,
sizeof
(
buffer
)
-
1
);
close
(
fd
);
/*
* Is it a symbolic ref?
*/
if
(
len
<
4
||
memcmp
(
"ref:"
,
buffer
,
4
))
return
-
1
;
buf
=
buffer
+
4
;
len
-=
4
;
while
(
len
&&
isspace
(
*
buf
))
buf
++
,
len
--
;
if
(
len
>=
5
&&
!
memcmp
(
"refs/"
,
buffer
,
5
))
return
0
;
return
-
1
;
}
if
(
fd
>=
0
)
{
char
buffer
[
60
];
if
(
read
(
fd
,
buffer
,
sizeof
(
buffer
))
>=
40
)
ret
=
get_sha1_hex
(
buffer
,
sha1
);
const
char
*
resolve_ref
(
const
char
*
path
,
unsigned
char
*
sha1
,
int
reading
)
{
int
depth
=
MAXDEPTH
,
len
;
char
buffer
[
256
];
for
(;;)
{
struct
stat
st
;
char
*
buf
;
int
fd
;
if
(
--
depth
<
0
)
return
NULL
;
/* Special case: non-existing file.
* Not having the refs/heads/new-branch is OK
* if we are writing into it, so is .git/HEAD
* that points at refs/heads/master still to be
* born. It is NOT OK if we are resolving for
* reading.
*/
if
(
lstat
(
path
,
&
st
)
<
0
)
{
if
(
reading
||
errno
!=
ENOENT
)
return
NULL
;
memset
(
sha1
,
0
,
20
);
return
path
;
}
/* Follow "normalized" - ie "refs/.." symlinks by hand */
if
(
S_ISLNK
(
st
.
st_mode
))
{
len
=
readlink
(
path
,
buffer
,
sizeof
(
buffer
)
-
1
);
if
(
len
>=
5
&&
!
memcmp
(
"refs/"
,
buffer
,
5
))
{
path
=
git_path
(
"%.*s"
,
len
,
buffer
);
continue
;
}
}
/*
* Anything else, just open it and try to use it as
* a ref
*/
fd
=
open
(
path
,
O_RDONLY
);
if
(
fd
<
0
)
return
NULL
;
len
=
read
(
fd
,
buffer
,
sizeof
(
buffer
)
-
1
);
close
(
fd
);
/*
* Is it a symbolic ref?
*/
if
(
len
<
4
||
memcmp
(
"ref:"
,
buffer
,
4
))
break
;
buf
=
buffer
+
4
;
len
-=
4
;
while
(
len
&&
isspace
(
*
buf
))
buf
++
,
len
--
;
while
(
len
&&
isspace
(
buf
[
len
-
1
]))
buf
[
--
len
]
=
0
;
path
=
git_path
(
"%.*s"
,
len
,
buf
);
}
return
ret
;
if
(
len
<
40
||
get_sha1_hex
(
buffer
,
sha1
))
return
NULL
;
return
path
;
}
int
create_symref
(
const
char
*
git_HEAD
,
const
char
*
refs_heads_master
)
{
#if USE_SYMLINK_HEAD
unlink
(
git_HEAD
);
return
symlink
(
refs_heads_master
,
git_HEAD
);
#else
const
char
*
lockpath
;
char
ref
[
1000
];
int
fd
,
len
,
written
;
len
=
snprintf
(
ref
,
sizeof
(
ref
),
"ref: %s
\n
"
,
refs_heads_master
);
if
(
sizeof
(
ref
)
<=
len
)
{
error
(
"refname too long: %s"
,
refs_heads_master
);
return
-
1
;
}
lockpath
=
mkpath
(
"%s.lock"
,
git_HEAD
);
fd
=
open
(
lockpath
,
O_CREAT
|
O_EXCL
|
O_WRONLY
,
0666
);
written
=
write
(
fd
,
ref
,
len
);
close
(
fd
);
if
(
written
!=
len
)
{
unlink
(
lockpath
);
error
(
"Unable to write to %s"
,
lockpath
);
return
-
2
;
}
if
(
rename
(
lockpath
,
git_HEAD
)
<
0
)
{
unlink
(
lockpath
);
error
(
"Unable to create %s"
,
git_HEAD
);
return
-
3
;
}
return
0
;
#endif
}
int
read_ref
(
const
char
*
filename
,
unsigned
char
*
sha1
)
{
if
(
resolve_ref
(
filename
,
sha1
,
1
))
return
0
;
return
-
1
;
}
static
int
do_for_each_ref
(
const
char
*
base
,
int
(
*
fn
)(
const
char
*
path
,
const
unsigned
char
*
sha1
))
...
...
@@ -54,7 +192,7 @@ static int do_for_each_ref(const char *base, int (*fn)(const char *path, const u
break
;
continue
;
}
if
(
read_ref
(
path
,
sha1
)
<
0
)
if
(
read_ref
(
git_path
(
"%s"
,
path
)
,
sha1
)
<
0
)
continue
;
if
(
!
has_sha1_file
(
sha1
))
continue
;
...
...
@@ -71,7 +209,7 @@ static int do_for_each_ref(const char *base, int (*fn)(const char *path, const u
int
head_ref
(
int
(
*
fn
)(
const
char
*
path
,
const
unsigned
char
*
sha1
))
{
unsigned
char
sha1
[
20
];
if
(
!
read_ref
(
"HEAD"
,
sha1
))
if
(
!
read_ref
(
git_path
(
"HEAD"
)
,
sha1
))
return
fn
(
"HEAD"
,
sha1
);
return
0
;
}
...
...
@@ -101,33 +239,14 @@ static char *ref_lock_file_name(const char *ref)
return
ret
;
}
static
int
read_ref_file
(
const
char
*
filename
,
unsigned
char
*
sha1
)
{
int
fd
=
open
(
filename
,
O_RDONLY
);
char
hex
[
41
];
if
(
fd
<
0
)
{
return
error
(
"Couldn't open %s
\n
"
,
filename
);
}
if
((
read
(
fd
,
hex
,
41
)
<
41
)
||
(
hex
[
40
]
!=
'\n'
)
||
get_sha1_hex
(
hex
,
sha1
))
{
error
(
"Couldn't read a hash from %s
\n
"
,
filename
);
close
(
fd
);
return
-
1
;
}
close
(
fd
);
return
0
;
}
int
get_ref_sha1
(
const
char
*
ref
,
unsigned
char
*
sha1
)
{
char
*
filename
;
int
retval
;
c
onst
c
har
*
filename
;
if
(
check_ref_format
(
ref
))
return
-
1
;
filename
=
ref_file_name
(
ref
);
retval
=
read_ref_file
(
filename
,
sha1
);
free
(
filename
);
return
retval
;
filename
=
git_path
(
"refs/%s"
,
ref
);
return
read_ref
(
filename
,
sha1
);
}
static
int
lock_ref_file
(
const
char
*
filename
,
const
char
*
lock_filename
,
...
...
@@ -140,7 +259,7 @@ static int lock_ref_file(const char *filename, const char *lock_filename,
return
error
(
"Couldn't open lock file for %s: %s"
,
filename
,
strerror
(
errno
));
}
retval
=
read_ref
_file
(
filename
,
current_sha1
);
retval
=
read_ref
(
filename
,
current_sha1
);
if
(
old_sha1
)
{
if
(
retval
)
{
close
(
fd
);
...
...
setup.c
浏览文件 @
79a9d8ea
...
...
@@ -76,18 +76,20 @@ const char **get_pathspec(const char *prefix, const char **pathspec)
* Test it it looks like we're at the top
* level git directory. We want to see a
*
* - a HEAD symlink and a refs/ directory under ".git"
* - either a .git/objects/ directory _or_ the proper
* GIT_OBJECT_DIRECTORY environment variable
* - a refs/ directory under ".git"
* - either a HEAD symlink or a HEAD file that is formatted as
* a proper "ref:".
*/
static
int
is_toplevel_directory
(
void
)
{
struct
stat
st
;
return
!
lstat
(
".git/HEAD"
,
&
st
)
&&
S_ISLNK
(
st
.
st_mode
)
&&
!
access
(
".git/refs/"
,
X_OK
)
&&
(
getenv
(
DB_ENVIRONMENT
)
||
!
access
(
".git/objects/"
,
X_OK
))
;
if
(
access
(
".git/refs/"
,
X_OK
)
||
access
(
getenv
(
DB_ENVIRONMENT
)
?
getenv
(
DB_ENVIRONMENT
)
:
".git/objects/"
,
X_OK
)
||
validate_symref
(
".git/HEAD"
))
return
0
;
return
1
;
}
const
char
*
setup_git_directory
(
void
)
...
...
sha1_file.c
浏览文件 @
79a9d8ea
...
...
@@ -20,6 +20,8 @@
#endif
#endif
const
unsigned
char
null_sha1
[
20
]
=
{
0
,
};
static
unsigned
int
sha1_file_open_flag
=
O_NOATIME
;
static
unsigned
hexval
(
char
c
)
...
...
sha1_name.c
浏览文件 @
79a9d8ea
...
...
@@ -119,21 +119,6 @@ static int get_short_sha1(const char *name, int len, unsigned char *sha1)
return
-
1
;
}
static
int
get_sha1_file
(
const
char
*
path
,
unsigned
char
*
result
)
{
char
buffer
[
60
];
int
fd
=
open
(
path
,
O_RDONLY
);
int
len
;
if
(
fd
<
0
)
return
-
1
;
len
=
read
(
fd
,
buffer
,
sizeof
(
buffer
));
close
(
fd
);
if
(
len
<
40
)
return
-
1
;
return
get_sha1_hex
(
buffer
,
result
);
}
static
int
get_sha1_basic
(
const
char
*
str
,
int
len
,
unsigned
char
*
sha1
)
{
static
const
char
*
prefix
[]
=
{
...
...
@@ -150,7 +135,7 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
for
(
p
=
prefix
;
*
p
;
p
++
)
{
char
*
pathname
=
git_path
(
"%s/%.*s"
,
*
p
,
len
,
str
);
if
(
!
get_sha1_file
(
pathname
,
sha1
))
if
(
!
read_ref
(
pathname
,
sha1
))
return
0
;
}
...
...
show-branch.c
浏览文件 @
79a9d8ea
...
...
@@ -349,6 +349,7 @@ int main(int ac, char **av)
int
all_heads
=
0
,
all_tags
=
0
;
int
all_mask
,
all_revs
,
shown_merge_point
;
char
head_path
[
128
];
const
char
*
head_path_p
;
int
head_path_len
;
unsigned
char
head_sha1
[
20
];
int
merge_base
=
0
;
...
...
@@ -430,11 +431,15 @@ int main(int ac, char **av)
if
(
0
<=
extra
)
join_revs
(
&
list
,
&
seen
,
num_rev
,
extra
);
head_path_len
=
readlink
(
".git/HEAD"
,
head_path
,
sizeof
(
head_path
)
-
1
);
if
((
head_path_len
<
0
)
||
get_sha1
(
"HEAD"
,
head_sha1
))
head_path_p
=
resolve_ref
(
git_path
(
"HEAD"
),
head_sha1
,
1
);
if
(
head_path_p
)
{
head_path_len
=
strlen
(
head_path_p
);
memcpy
(
head_path
,
head_path_p
,
head_path_len
+
1
);
}
else
{
head_path_len
=
0
;
head_path
[
0
]
=
0
;
else
head_path
[
head_path_len
]
=
0
;
}
if
(
merge_base
)
return
show_merge_base
(
seen
,
num_rev
);
...
...
symbolic-ref.c
0 → 100644
浏览文件 @
79a9d8ea
#include "cache.h"
static
const
char
git_symbolic_ref_usage
[]
=
"git-symbolic-ref name [ref]"
;
static
int
check_symref
(
const
char
*
HEAD
)
{
unsigned
char
sha1
[
20
];
const
char
*
git_HEAD
=
strdup
(
git_path
(
"%s"
,
HEAD
));
const
char
*
git_refs_heads_master
=
resolve_ref
(
git_HEAD
,
sha1
,
0
);
if
(
git_refs_heads_master
)
{
/* we want to strip the .git/ part */
int
pfxlen
=
strlen
(
git_HEAD
)
-
strlen
(
HEAD
);
puts
(
git_refs_heads_master
+
pfxlen
);
}
else
die
(
"No such ref: %s"
,
HEAD
);
}
int
main
(
int
argc
,
const
char
**
argv
)
{
setup_git_directory
();
switch
(
argc
)
{
case
2
:
check_symref
(
argv
[
1
]);
break
;
case
3
:
create_symref
(
strdup
(
git_path
(
"%s"
,
argv
[
1
])),
argv
[
2
]);
break
;
default:
usage
(
git_symbolic_ref_usage
);
}
return
0
;
}
t/Makefile
浏览文件 @
79a9d8ea
...
...
@@ -5,6 +5,7 @@
#GIT_TEST_OPTS=--verbose --debug
SHELL_PATH
?=
$(SHELL)
TAR
?=
$(TAR)
T
=
$(
wildcard
t[0-9][0-9][0-9][0-9]-
*
.sh
)
...
...
t/t3002-ls-files-dashpath.sh
0 → 100755
浏览文件 @
79a9d8ea
#!/bin/sh
#
# Copyright (c) 2005 Junio C Hamano
#
test_description
=
'git-ls-files test (-- to terminate the path list).
This test runs git-ls-files --others with the following on the
filesystem.
path0 - a file
-foo - a file with a funny name.
-- - another file with a funny name.
'
.
./test-lib.sh
test_expect_success
\
setup
\
'echo frotz >path0 &&
echo frotz >./-foo &&
echo frotz >./--'
test_expect_success
\
'git-ls-files without path restriction.'
\
'git-ls-files --others >output &&
diff -u output - <<EOF
--
-foo
output
path0
EOF
'
test_expect_success
\
'git-ls-files with path restriction.'
\
'git-ls-files --others path0 >output &&
diff -u output - <<EOF
path0
EOF
'
test_expect_success
\
'git-ls-files with path restriction with --.'
\
'git-ls-files --others -- path0 >output &&
diff -u output - <<EOF
path0
EOF
'
test_expect_success
\
'git-ls-files with path restriction with -- --.'
\
'git-ls-files --others -- -- >output &&
diff -u output - <<EOF
--
EOF
'
test_expect_success
\
'git-ls-files with no path restriction.'
\
'git-ls-files --others -- >output &&
diff -u output - <<EOF
--
-foo
output
path0
EOF
'
test_done
t/t5000-tar-tree.sh
浏览文件 @
79a9d8ea
...
...
@@ -50,7 +50,7 @@ test_expect_success \
test_expect_success
\
'validate file modification time'
\
'TZ=GMT
tar
tvf b.tar a/a |
'TZ=GMT
$TAR
tvf b.tar a/a |
awk \{print\ \$4,\ \(length\(\$5\)\<7\)\ ?\ \$5\":00\"\ :\ \$5\} \
>b.mtime &&
echo "2005-05-27 22:00:00" >expected.mtime &&
...
...
@@ -63,7 +63,7 @@ test_expect_success \
test_expect_success
\
'extract tar archive'
\
'(cd b &&
tar
xf -) <b.tar'
'(cd b &&
$TAR
xf -) <b.tar'
test_expect_success
\
'validate filenames'
\
...
...
@@ -80,7 +80,7 @@ test_expect_success \
test_expect_success
\
'extract tar archive with prefix'
\
'(cd c &&
tar
xf -) <c.tar'
'(cd c &&
$TAR
xf -) <c.tar'
test_expect_success
\
'validate filenames with prefix'
\
...
...
t/t5400-send-pack.sh
浏览文件 @
79a9d8ea
...
...
@@ -20,12 +20,12 @@ test_expect_success setup '
commit=$(echo "Commit #$i" | git-commit-tree $tree -p $parent) &&
parent=$commit || return 1
done &&
echo "$commit" >.git/HEAD
&&
git-update-ref HEAD "$commit"
&&
git-clone -l ./. victim &&
cd victim &&
git-log &&
cd .. &&
echo $zero >.git/HEAD
&&
git-update-ref HEAD "$zero"
&&
parent=$zero &&
for i in $cnt
do
...
...
@@ -33,7 +33,7 @@ test_expect_success setup '
commit=$(echo "Rebase #$i" | git-commit-tree $tree -p $parent) &&
parent=$commit || return 1
done &&
echo "$commit" >.git/HEAD
&&
git-update-ref HEAD "$commit"
&&
echo Rebase &&
git-log'
...
...
t/t6002-rev-list-bisect.sh
浏览文件 @
79a9d8ea
...
...
@@ -7,20 +7,6 @@ test_description='Tests git-rev-list --bisect functionality'
.
./test-lib.sh
.
../t6000lib.sh
# t6xxx specific functions
bc_expr
()
{
bc
<<
EOF
scale=1
define abs(x) {
if (x>=0) { return (x); } else { return (-x); }
}
define floor(x) {
save=scale; scale=0; result=x/1; scale=save; return (result);
}
$*
EOF
}
# usage: test_bisection max-diff bisect-option head ^prune...
#
# e.g. test_bisection 1 --bisect l1 ^l0
...
...
@@ -35,8 +21,19 @@ test_bisection_diff()
_head
=
$1
shift
1
_bisection_size
=
$(
git-rev-list
$_bisection
"
$@
"
|
wc
-l
)
[
-n
"
$_list_size
"
-a
-n
"
$_bisection_size
"
]
||
error
"test_bisection_diff failed"
test_expect_success
"bisection diff
$_bisect_option
$_head
$*
<=
$_max_diff
"
"[
$(
bc_expr
"floor(abs(
$_list_size
/2)-
$_bisection_size
)"
)
-le
$_max_diff
]"
[
-n
"
$_list_size
"
-a
-n
"
$_bisection_size
"
]
||
error
"test_bisection_diff failed"
# Test if bisection size is close to half of list size within
# tolerance.
#
_bisect_err
=
`
expr
$_list_size
-
$_bisection_size
\*
2
`
test
"
$_bisect_err
"
-lt
0
&&
_bisect_err
=
`
expr
0 -
$_bisect_err
`
_bisect_err
=
`
expr
$_bisect_err
/ 2
`
;
# floor
test_expect_success
\
"bisection diff
$_bisect_option
$_head
$*
<=
$_max_diff
"
\
'test $_bisect_err -le $_max_diff'
}
date
>
path0
...
...
tar-tree.c
浏览文件 @
79a9d8ea
...
...
@@ -353,6 +353,8 @@ static void traverse_tree(void *buffer, unsigned long size,
if
(
size
<
namelen
+
20
||
sscanf
(
buffer
,
"%o"
,
&
mode
)
!=
1
)
die
(
"corrupt 'tree' file"
);
if
(
S_ISDIR
(
mode
)
||
S_ISREG
(
mode
))
mode
|=
(
mode
&
0100
)
?
0777
:
0666
;
buffer
=
sha1
+
20
;
size
-=
namelen
+
20
;
...
...
update-index.c
浏览文件 @
79a9d8ea
...
...
@@ -13,7 +13,7 @@
* like "git-update-index *" and suddenly having all the object
* files be revision controlled.
*/
static
int
allow_add
=
0
,
allow_remove
=
0
,
allow_replace
=
0
,
not_new
=
0
,
quiet
=
0
,
info_only
=
0
;
static
int
allow_add
=
0
,
allow_remove
=
0
,
allow_replace
=
0
,
allow_unmerged
=
0
,
not_new
=
0
,
quiet
=
0
,
info_only
=
0
;
static
int
force_remove
;
/* Three functions to allow overloaded pointer return; see linux/err.h */
...
...
@@ -135,7 +135,7 @@ static struct cache_entry *refresh_entry(struct cache_entry *ce)
changed
=
ce_match_stat
(
ce
,
&
st
);
if
(
!
changed
)
return
ce
;
return
NULL
;
if
(
ce_modified
(
ce
,
&
st
))
return
ERR_PTR
(
-
EINVAL
);
...
...
@@ -156,16 +156,20 @@ static int refresh_cache(void)
struct
cache_entry
*
ce
,
*
new
;
ce
=
active_cache
[
i
];
if
(
ce_stage
(
ce
))
{
printf
(
"%s: needs merge
\n
"
,
ce
->
name
);
has_errors
=
1
;
while
((
i
<
active_nr
)
&&
!
strcmp
(
active_cache
[
i
]
->
name
,
ce
->
name
))
i
++
;
i
--
;
if
(
allow_unmerged
)
continue
;
printf
(
"%s: needs merge
\n
"
,
ce
->
name
);
has_errors
=
1
;
continue
;
}
new
=
refresh_entry
(
ce
);
if
(
!
new
)
continue
;
if
(
IS_ERR
(
new
))
{
if
(
not_new
&&
PTR_ERR
(
new
)
==
-
ENOENT
)
continue
;
...
...
@@ -335,6 +339,10 @@ int main(int argc, const char **argv)
allow_remove
=
1
;
continue
;
}
if
(
!
strcmp
(
path
,
"--unmerged"
))
{
allow_unmerged
=
1
;
continue
;
}
if
(
!
strcmp
(
path
,
"--refresh"
))
{
has_errors
|=
refresh_cache
();
continue
;
...
...
@@ -383,9 +391,11 @@ int main(int argc, const char **argv)
update_one
(
buf
.
buf
,
prefix
,
prefix_length
);
}
}
if
(
write_cache
(
newfd
,
active_cache
,
active_nr
)
||
commit_index_file
(
&
cache_file
))
die
(
"Unable to write new cachefile"
);
if
(
active_cache_changed
)
{
if
(
write_cache
(
newfd
,
active_cache
,
active_nr
)
||
commit_index_file
(
&
cache_file
))
die
(
"Unable to write new cachefile"
);
}
return
has_errors
?
1
:
0
;
}
update-ref.c
浏览文件 @
79a9d8ea
...
...
@@ -4,53 +4,6 @@
static
const
char
git_update_ref_usage
[]
=
"git-update-ref <refname> <value> [<oldval>]"
;
#define MAXDEPTH 5
static
const
char
*
resolve_ref
(
const
char
*
path
,
unsigned
char
*
sha1
)
{
int
depth
=
MAXDEPTH
,
len
;
char
buffer
[
256
];
for
(;;)
{
struct
stat
st
;
int
fd
;
if
(
--
depth
<
0
)
return
NULL
;
/* Special case: non-existing file */
if
(
lstat
(
path
,
&
st
)
<
0
)
{
if
(
errno
!=
ENOENT
)
return
NULL
;
memset
(
sha1
,
0
,
20
);
return
path
;
}
/* Follow "normalized" - ie "refs/.." symlinks by hand */
if
(
S_ISLNK
(
st
.
st_mode
))
{
len
=
readlink
(
path
,
buffer
,
sizeof
(
buffer
)
-
1
);
if
(
len
>=
5
&&
!
memcmp
(
"refs/"
,
buffer
,
5
))
{
path
=
git_path
(
"%.*s"
,
len
,
buffer
);
continue
;
}
}
/*
* Anything else, just open it and try to use it as
* a ref
*/
fd
=
open
(
path
,
O_RDONLY
);
if
(
fd
<
0
)
return
NULL
;
len
=
read
(
fd
,
buffer
,
sizeof
(
buffer
)
-
1
);
close
(
fd
);
break
;
}
if
(
len
<
40
||
get_sha1_hex
(
buffer
,
sha1
))
return
NULL
;
return
path
;
}
static
int
re_verify
(
const
char
*
path
,
unsigned
char
*
oldsha1
,
unsigned
char
*
currsha1
)
{
char
buf
[
40
];
...
...
@@ -84,7 +37,7 @@ int main(int argc, char **argv)
if
(
oldval
&&
get_sha1
(
oldval
,
oldsha1
)
<
0
)
die
(
"%s: not a valid old SHA1"
,
oldval
);
path
=
resolve_ref
(
git_path
(
"%s"
,
refname
),
currsha1
);
path
=
resolve_ref
(
git_path
(
"%s"
,
refname
),
currsha1
,
!!
oldval
);
if
(
!
path
)
die
(
"No such ref: %s"
,
refname
);
...
...
usage.c
浏览文件 @
79a9d8ea
...
...
@@ -15,7 +15,7 @@ static void report(const char *prefix, const char *err, va_list params)
void
usage
(
const
char
*
err
)
{
fprintf
(
stderr
,
"usage: %s
\n
"
,
err
);
exit
(
1
);
exit
(
1
29
);
}
void
die
(
const
char
*
err
,
...)
...
...
@@ -25,7 +25,7 @@ void die(const char *err, ...)
va_start
(
params
,
err
);
report
(
"fatal: "
,
err
,
params
);
va_end
(
params
);
exit
(
1
);
exit
(
1
28
);
}
int
error
(
const
char
*
err
,
...)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录