Peter Anvin 2005-09-28 23:20:08 -07:00
Родитель a23cd8ece7 bf7960eb51
Коммит 0542f48c89
16 изменённых файлов: 124 добавлений и 83 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -25,6 +25,7 @@ git-diff-stages
git-diff-tree
git-fetch
git-fetch-pack
git-fmt-merge-msg
git-format-patch
git-fsck-objects
git-get-tar-commit-id
@ -86,6 +87,7 @@ git-tar-tree
git-unpack-file
git-unpack-objects
git-update-index
git-update-ref
git-update-server-info
git-upload-pack
git-var

Просмотреть файл

@ -30,7 +30,7 @@ static void objreport(struct object *obj, const char *severity,
fputs("\n", stderr);
}
int objerror(struct object *obj, const char *err, ...)
static int objerror(struct object *obj, const char *err, ...)
{
va_list params;
va_start(params, err);
@ -39,7 +39,7 @@ int objerror(struct object *obj, const char *err, ...)
return -1;
}
int objwarning(struct object *obj, const char *err, ...)
static int objwarning(struct object *obj, const char *err, ...)
{
va_list params;
va_start(params, err);

Просмотреть файл

@ -108,9 +108,10 @@ fi
tree=$(git-write-tree) || exit 1
echo Wrote tree $tree
commit=$(git-commit-tree $tree -p $(cat "$GIT_DIR"/HEAD) < "$final") || exit 1
parent=$(git-rev-parse --verify HEAD) &&
commit=$(git-commit-tree $tree -p $parent <"$final") || exit 1
echo Committed: $commit
echo $commit > "$GIT_DIR"/HEAD
git-update-ref HEAD $commit $parent || exit
if test -x "$GIT_DIR"/hooks/post-applypatch
then

Просмотреть файл

@ -159,7 +159,9 @@ if [ ! -r "$GIT_DIR/HEAD" ]; then
exit 1
fi
PARENTS=""
current=
else
current=$(git-rev-parse --verify HEAD)
if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"`
fi
@ -220,7 +222,7 @@ if test -s .cmitchk
then
tree=$(git-write-tree) &&
commit=$(cat .cmitmsg | git-commit-tree $tree $PARENTS) &&
echo $commit > "$GIT_DIR/HEAD" &&
git-update-ref HEAD $commit $current &&
rm -f -- "$GIT_DIR/MERGE_HEAD"
else
echo >&2 "* no commit message? aborting commit."

Просмотреть файл

@ -54,6 +54,10 @@ append_fetch_head () {
remote_name_="$3"
remote_nick_="$4"
local_name_="$5"
case "$6" in
t) not_for_merge_='not-for-merge' ;;
'') not_for_merge_= ;;
esac
# remote-nick is the URL given on the command line (or a shorthand)
# remote-name is the $GIT_DIR relative refs/ path we computed
@ -78,10 +82,11 @@ append_fetch_head () {
if git-cat-file commit "$head_" >/dev/null 2>&1
then
headc_=$(git-rev-parse --verify "$head_^0") || exit
echo "$headc_ $note_" >>$GIT_DIR/FETCH_HEAD
echo "$headc_ $not_for_merge_ $note_" >>$GIT_DIR/FETCH_HEAD
echo >&2 "* committish: $head_"
echo >&2 " $note_"
else
echo "$head_ not-for-merge $note_" >>$GIT_DIR/FETCH_HEAD
echo >&2 "* non-commit: $head_"
echo >&2 " $note_"
fi
@ -105,14 +110,16 @@ fast_forward_local () {
else
echo >&2 "* $1: storing $3"
fi
echo "$2" >"$GIT_DIR/$1" ;;
git-update-ref "$1" "$2"
;;
refs/heads/*)
# NEEDSWORK: use the same cmpxchg protocol here.
echo "$2" >"$GIT_DIR/$1.lock"
if test -f "$GIT_DIR/$1"
# $1 is the ref being updated.
# $2 is the new value for the ref.
local=$(git-rev-parse --verify "$1^0" 2>/dev/null)
if test "$local"
then
local=$(git-rev-parse --verify "$1^0") &&
# Require fast-forward.
mb=$(git-merge-base "$local" "$2") &&
case "$2,$mb" in
$local,*)
@ -120,34 +127,34 @@ fast_forward_local () {
;;
*,$local)
echo >&2 "* $1: fast forward to $3"
git-update-ref "$1" "$2" "$local"
;;
*)
false
;;
esac || {
echo >&2 "* $1: does not fast forward to $3;"
case "$force,$single_force" in
t,* | *,t)
case ",$force,$single_force," in
*,t,*)
echo >&2 " forcing update."
git-update-ref "$1" "$2" "$local"
;;
*)
mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1.remote"
echo >&2 " leaving it in '$1.remote'"
echo >&2 " not updating."
;;
esac
}
else
echo >&2 "* $1: storing $3"
echo >&2 "* $1: storing $3"
git-update-ref "$1" "$2"
fi
test -f "$GIT_DIR/$1.lock" &&
mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1"
;;
esac
}
case "$update_head_ok" in
'')
orig_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null)
orig_head=$(git-rev-parse --verify HEAD 2>/dev/null)
;;
esac
@ -157,6 +164,13 @@ do
# These are relative path from $GIT_DIR, typically starting at refs/
# but may be HEAD
if expr "$ref" : '\.' >/dev/null
then
not_for_merge=t
ref=$(expr "$ref" : '\.\(.*\)')
else
not_for_merge=
fi
if expr "$ref" : '\+' >/dev/null
then
single_force=t
@ -184,7 +198,7 @@ do
rsync://*)
TMP_HEAD="$GIT_DIR/TMP_HEAD"
rsync -L -q "$remote/$remote_name" "$TMP_HEAD" || exit 1
head=$(git-rev-parse TMP_HEAD)
head=$(git-rev-parse --verify TMP_HEAD)
rm -f "$TMP_HEAD"
test "$rsync_slurped_objects" || {
rsync -av --ignore-existing --exclude info \
@ -216,7 +230,8 @@ do
continue ;;
esac
append_fetch_head "$head" "$remote" "$remote_name" "$remote_nick" "$local_name"
append_fetch_head "$head" "$remote" \
"$remote_name" "$remote_nick" "$local_name" "$not_for_merge"
done
@ -241,16 +256,27 @@ http://* | https://* | rsync://* )
case "$ref" in
+$remote_name:*)
single_force=t
not_for_merge=
found="$ref"
break ;;
.+$remote_name:*)
single_force=t
not_for_merge=t
found="$ref"
break ;;
.$remote_name:*)
not_for_merge=t
found="$ref"
break ;;
$remote_name:*)
not_for_merge=
found="$ref"
break ;;
esac
done
local_name=$(expr "$found" : '[^:]*:\(.*\)')
append_fetch_head "$sha1" "$remote" "$remote_name" "$remote_nick" "$local_name"
append_fetch_head "$sha1" "$remote" \
"$remote_name" "$remote_nick" "$local_name" "$not_for_merge"
done || exit
;;
esac
@ -261,10 +287,10 @@ case ",$update_head_ok,$orig_head," in
*,, | t,* )
;;
*)
curr_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null)
curr_head=$(git-rev-parse --verify HEAD 2>/dev/null)
if test "$curr_head" != "$orig_head"
then
echo "$orig_head" >$GIT_DIR/HEAD
git-update-ref HEAD "$orig_head"
die "Cannot fetch into the current branch."
fi
;;

Просмотреть файл

@ -31,6 +31,8 @@ while (<>) {
my ($bname, $tname, $gname, $src);
chomp;
s/^[0-9a-f]* //;
next if (/^not-for-merge/);
s/^ //;
if (s/ of (.*)$//) {
$src = $1;
} else {
@ -86,7 +88,7 @@ for my $src (@src) {
$src{$src}{GENERIC});
my $this = join(', ', @this);
if ($src ne '.') {
$this .= " from $src";
$this .= " of $src";
}
push @msg, $this;
}

Просмотреть файл

@ -24,7 +24,9 @@ dropsave() {
}
savestate() {
git diff -r -z --name-only $head | cpio -0 -o >"$GIR_DIR/MERGE_SAVE"
# Stash away any local modifications.
git-diff-index -r -z --name-only $head |
cpio -0 -o >"$GIR_DIR/MERGE_SAVE"
}
restorestate() {
@ -114,8 +116,9 @@ case "$#,$common" in
# Again the most common case of merging one remote.
echo "Updating from $head to $1."
git-update-index --refresh 2>/dev/null
git-read-tree -u -m $head "$1" || exit 1
git-rev-parse --verify "$1^0" > "$GIT_DIR/HEAD"
git-read-tree -u -m $head "$1" &&
new_head=$(git-rev-parse --verify "$1^0") &&
git-update-ref HEAD "$new_head" "$head" || exit 1
summary "$1"
dropsave
exit 0
@ -149,12 +152,7 @@ esac
# we use, it would operate on the index, possibly affecting the
# working tree, and when resolved cleanly, have the desired tree
# in the index -- this means that the index must be in sync with
# the $head commit.
files=$(git-diff-index --cached --name-only $head) || exit
if [ "$files" ]; then
echo >&2 "Dirty index: cannot merge (dirty: $files)"
exit 1
fi
# the $head commit. The strategies are responsible to ensure this.
case "$use_strategies" in
?*' '?*)
@ -218,9 +216,9 @@ then
do
parents="$parents -p $remote"
done
result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree $parents)
result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree $parents) || exit
echo "Committed merge $result_commit, made by $wt_strategy."
echo $result_commit >"$GIT_DIR/HEAD"
git-update-ref HEAD $result_commit $head
summary $result_commit
dropsave
exit 0

Просмотреть файл

@ -86,5 +86,5 @@ esac
result_commit=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD" |
git-commit-tree $MRT $PARENT)
echo "Committed merge $result_commit"
echo $result_commit >"$GIT_DIR"/HEAD
git-update-ref HEAD $result_commit $head
git-diff-tree -p $head $result_commit | git-apply --stat

Просмотреть файл

@ -65,8 +65,11 @@ get_remote_default_refs_for_push () {
esac
}
# Subroutine to canonicalize remote:local notation
# Subroutine to canonicalize remote:local notation.
canon_refs_list_for_fetch () {
# Leave only the first one alone; add prefix . to the rest
# to prevent the secondary branches to be merged by default.
dot_prefix=
for ref
do
force=
@ -91,7 +94,8 @@ canon_refs_list_for_fetch () {
heads/* | tags/* ) local="refs/$local" ;;
*) local="refs/heads/$local" ;;
esac
echo "${force}${remote}:${local}"
echo "${dot_prefix}${force}${remote}:${local}"
dot_prefix=.
done
}
@ -107,6 +111,9 @@ get_remote_default_refs_for_fetch () {
echo "refs/heads/${remote_branch}:refs/heads/$1"
;;
remotes)
# This prefixes the second and later default refspecs
# with a '.', to signal git-fetch to mark them
# not-for-merge.
canon_refs_list_for_fetch $(sed -ne '/^Pull: */{
s///p
}' "$GIT_DIR/remotes/$1")

Просмотреть файл

@ -6,10 +6,10 @@
. git-sh-setup || die "Not a git archive"
orig_head=$(cat "$GIT_DIR/HEAD") || die "Pulling into a black hole?"
orig_head=$(git-rev-parse --verify HEAD) || die "Pulling into a black hole?"
git-fetch --update-head-ok "$@" || exit 1
curr_head=$(cat "$GIT_DIR/HEAD")
curr_head=$(git-rev-parse --verify HEAD)
if test "$curr_head" != "$orig_head"
then
# The fetch involved updating the current branch.
@ -24,7 +24,9 @@ then
die "You need to first update your working tree."
fi
merge_head=$(sed -e 's/ .*//' "$GIT_DIR"/FETCH_HEAD | tr '\012' ' ')
merge_head=$(sed -e '/ not-for-merge /d' \
-e 's/ .*//' "$GIT_DIR"/FETCH_HEAD | \
tr '\012' ' ')
case "$merge_head" in
'')
@ -38,4 +40,4 @@ case "$merge_head" in
esac
merge_name=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD")
git-resolve "$(cat "$GIT_DIR"/HEAD)" $merge_head "$merge_name"
git-resolve "$curr_head" $merge_head "$merge_name"

Просмотреть файл

@ -33,7 +33,8 @@ test "$different1$different2" = "" ||
die "Your working tree does not match $ours_symbolic."
git-read-tree -m -u $ours $upstream &&
git-rev-parse --verify "$upstream^0" >"$GIT_DIR/HEAD" || exit
new_head=$(git-rev-parse --verify "$upstream^0") &&
git-update-ref HEAD "$new_head" || exit
tmp=.rebase-tmp$$
fail=$tmp-fail
@ -50,7 +51,7 @@ do
continue ;;
esac
echo >&2 "* Applying: $msg"
S=`cat "$GIT_DIR/HEAD"` &&
S=$(git-rev-parse --verify HEAD) &&
git-cherry-pick --replay $commit || {
echo >&2 "* Not applying the patch and continuing."
echo $commit >>$fail

Просмотреть файл

@ -60,7 +60,7 @@ then
else
rm -f "$GIT_DIR/ORIG_HEAD"
fi
echo "$rev" >"$GIT_DIR/HEAD"
git-update-ref HEAD "$rev"
case "$reset_type" in
--hard )

Просмотреть файл

@ -45,7 +45,7 @@ case "$common" in
"$head")
echo "Updating from $head to $merge."
git-read-tree -u -m $head $merge || exit 1
echo $merge > "$GIT_DIR"/HEAD
git-update-ref HEAD "$merge" "$head"
git-diff-tree -p $head $merge | git-apply --stat
dropheads
exit 0
@ -99,6 +99,6 @@ if [ $? -ne 0 ]; then
fi
result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree -p $head -p $merge)
echo "Committed merge $result_commit"
echo $result_commit > "$GIT_DIR"/HEAD
git-update-ref HEAD "$result_commit" "$head"
git-diff-tree -p $head $result_commit | git-apply --stat
dropheads

Просмотреть файл

@ -27,7 +27,7 @@ struct alt_base
struct alt_base *next;
};
struct alt_base *alt = NULL;
static struct alt_base *alt = NULL;
static SHA_CTX c;
static z_stream stream;
@ -36,6 +36,10 @@ static int local;
static int zret;
static int curl_ssl_verify;
static char *ssl_cert;
static char *ssl_key;
static char *ssl_capath;
static char *ssl_cainfo;
struct buffer
{
@ -350,7 +354,7 @@ static int fetch_pack(struct alt_base *repo, unsigned char *sha1)
return 0;
}
int fetch_object(struct alt_base *repo, unsigned char *sha1)
static int fetch_object(struct alt_base *repo, unsigned char *sha1)
{
char *hex = sha1_to_hex(sha1);
char *filename = sha1_file_name(sha1);
@ -522,6 +526,21 @@ int main(int argc, char **argv)
curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
#endif
if ((ssl_cert = getenv("GIT_SSL_CERT")) != NULL) {
curl_easy_setopt(curl, CURLOPT_SSLCERT, ssl_cert);
}
if ((ssl_key = getenv("GIT_SSL_KEY")) != NULL) {
curl_easy_setopt(curl, CURLOPT_SSLKEY, ssl_key);
}
#if LIBCURL_VERSION_NUM >= 0x070908
if ((ssl_capath = getenv("GIT_SSL_CAPATH")) != NULL) {
curl_easy_setopt(curl, CURLOPT_CAPATH, ssl_capath);
}
#endif
if ((ssl_cainfo = getenv("GIT_SSL_CAINFO")) != NULL) {
curl_easy_setopt(curl, CURLOPT_CAINFO, ssl_cainfo);
}
alt = xmalloc(sizeof(*alt));
alt->base = url;
alt->got_indices = 0;

Просмотреть файл

@ -158,49 +158,33 @@ test_expect_success \
We have so far tested only empty index and clean-and-matching-A index
case which are trivial. Make sure index requirements are also
checked. The table also lists alternative semantics which is not
currently implemented.
checked.
"git-diff-tree -m O A B"
"git-read-tree -m O A B"
O A B result index requirements
-------------------------------------------------------------------
1 missing missing missing - must not exist.
------------------------------------------------------------------
2 missing missing exists no merge must not exist.
------------------------------------
(ALT) take B* must match B, if exists.
2 missing missing exists take B* must match B, if exists.
------------------------------------------------------------------
3 missing exists missing no merge must match A and be
up-to-date, if exists.
------------------------------------
(ALT) take A* must match A, if exists.
3 missing exists missing take A* must match A, if exists.
------------------------------------------------------------------
4 missing exists A!=B no merge must match A and be
up-to-date, if exists.
------------------------------------------------------------------
5 missing exists A==B no merge must match A and be
up-to-date, if exists.
------------------------------------
(ALT) take A must match A, if exists.
5 missing exists A==B take A must match A, if exists.
------------------------------------------------------------------
6 exists missing missing no merge must not exist.
------------------------------------
(ALT) remove must not exist.
6 exists missing missing remove must not exist.
------------------------------------------------------------------
7 exists missing O!=B no merge must not exist.
------------------------------------------------------------------
8 exists missing O==B no merge must not exist.
------------------------------------
(ALT) remove must not exist.
8 exists missing O==B remove must not exist.
------------------------------------------------------------------
9 exists O!=A missing no merge must match A and be
up-to-date, if exists.
------------------------------------------------------------------
10 exists O==A missing no merge must match A and be
up-to-date, if exists.
------------------------------------
(ALT) remove ditto
10 exists O==A missing remove ditto
------------------------------------------------------------------
11 exists O!=A O!=B no merge must match A and be
A!=B up-to-date, if exists.
@ -210,10 +194,7 @@ currently implemented.
------------------------------------------------------------------
13 exists O!=A O==B take A must match A, if exists.
------------------------------------------------------------------
14 exists O==A O!=B take B must match A and be
be up-to-date, if exists.
------------------------------------
(ALT) take B if exists, must either (1)
14 exists O==A O!=B take B if exists, must either (1)
match A and be up-to-date,
or (2) match B.
------------------------------------------------------------------
@ -223,9 +204,9 @@ currently implemented.
*multi* in one in another
-------------------------------------------------------------------
Note: if we want to implement 2ALT and 3ALT we need to be careful.
The tree A may contain DF (file) when tree B require DF to be a
directory by having DF/DF (file).
Note: we need to be careful in case 2 and 3. The tree A may contain
DF (file) when tree B require DF to be a directory by having DF/DF
(file).
END_OF_CASE_TABLE

Просмотреть файл

@ -6,7 +6,7 @@ static const char git_update_ref_usage[] = "git-update-ref <refname> <value> [<o
#define MAXDEPTH 5
const char *resolve_ref(const char *path, unsigned char *sha1)
static const char *resolve_ref(const char *path, unsigned char *sha1)
{
int depth = MAXDEPTH, len;
char buffer[256];