Fix bugs with gitception://<giturl> related to concurrency with git
Make sure we do not overwrite FETCH_HEAD. Using stacked gitception:// URLs was useful to make sure we handle our temporaries in a safe way.
This commit is contained in:
parent
b9501e5b25
commit
08ad287a0c
1 changed files with 60 additions and 35 deletions
|
@ -22,7 +22,8 @@ pack_hash()
|
||||||
LOCALDIR="${GIT_DIR:-.git}/remote-gcrypt"
|
LOCALDIR="${GIT_DIR:-.git}/remote-gcrypt"
|
||||||
DID_FIND_REPO= # yes for connected, no for no repo
|
DID_FIND_REPO= # yes for connected, no for no repo
|
||||||
PACKPFX="pack :SHA224:"
|
PACKPFX="pack :SHA224:"
|
||||||
GREF="refs/gcrypt/togit"
|
export GITCEPTION="$GITCEPTION+" # Reuse $GREF except when stacked
|
||||||
|
GREF="refs/gcrypt/gitception.$GITCEPTION"
|
||||||
|
|
||||||
isurl() { test -z "${2%%$1://*}" ; }
|
isurl() { test -z "${2%%$1://*}" ; }
|
||||||
|
|
||||||
|
@ -33,33 +34,23 @@ splitcolon()
|
||||||
suffix_=${1#*:}
|
suffix_=${1#*:}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Fetch repo $1, file $2
|
## gitception part
|
||||||
GET()
|
# Fetch giturl $1, file $2
|
||||||
|
gitception_get()
|
||||||
{
|
{
|
||||||
local REPO
|
# Take care to preserve FETCH_HEAD
|
||||||
if isurl ssh "$1"
|
local FHEAD
|
||||||
then
|
local RETVAL
|
||||||
splitcolon "${1#ssh://}"
|
FHEAD="$GIT_DIR/FETCH_HEAD"
|
||||||
(exec 0>&-; ssh "$prefix_" "cat $suffix_/$2")
|
[ -e "$FHEAD" ] && command mv -f "$FHEAD" "$FHEAD.$$~" || :
|
||||||
elif isurl sftp "$1"
|
git fetch -q -f "$1" HEAD:"$GREF" 2>/dev/tty >/dev/null && \
|
||||||
then
|
OBJID=$(git ls-tree "$GREF" | xgrep -E "\b$2$" |
|
||||||
(exec 0>&-; curl -s -S -k "$1/$2")
|
awk '{print $3}') && [ -n "$OBJID" ] && \
|
||||||
elif isurl gitception "$1"
|
git cat-file blob "$OBJID" && RETVAL=: || \
|
||||||
then
|
{ RETVAL=false && : ; }
|
||||||
REPO=${1#gitception://}
|
[ -e "$FHEAD.$$~" ] && command mv -f "$FHEAD.$$~" "$FHEAD" && $RETVAL
|
||||||
git fetch "$REPO" 2>/dev/null >&2 && \
|
|
||||||
OBJID=$(git ls-tree FETCH_HEAD | xgrep -E "\b$2$" | \
|
|
||||||
awk '{print $3}') && [ -n "$OBJID" ] && \
|
|
||||||
git cat-file blob "$OBJID"
|
|
||||||
git update-ref "$GREF" FETCH_HEAD
|
|
||||||
else
|
|
||||||
cat "$1/$2"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Fetch repo $1, file $2 or return encrypted empty message
|
|
||||||
GET_OR_EMPTY() { GET "$@" 2>/dev/null || (printf "" | ENCRYPT) ; }
|
|
||||||
|
|
||||||
anon_commit()
|
anon_commit()
|
||||||
{
|
{
|
||||||
GIT_AUTHOR_NAME="root" GIT_AUTHOR_EMAIL="root@localhost" \
|
GIT_AUTHOR_NAME="root" GIT_AUTHOR_EMAIL="root@localhost" \
|
||||||
|
@ -77,6 +68,38 @@ update_tree()
|
||||||
printf "100644 blob %s\t%s" "$3" "$2") | git mktree
|
printf "100644 blob %s\t%s" "$3" "$2") | git mktree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Put giturl $1, file $2
|
||||||
|
# depends on previous GET to set $GREF and depends on PUT_FINAL later
|
||||||
|
gitception_put()
|
||||||
|
{
|
||||||
|
OBJID=$(git hash-object -w --stdin) && \
|
||||||
|
TREEID=$(update_tree "$GREF" "$2" "$OBJID") &&
|
||||||
|
COMMITID=$(anon_commit "$TREEID" -m "x") && \
|
||||||
|
git update-ref "$GREF" "$COMMITID"
|
||||||
|
}
|
||||||
|
## end gitception
|
||||||
|
|
||||||
|
# Fetch repo $1, file $2
|
||||||
|
GET()
|
||||||
|
{
|
||||||
|
if isurl ssh "$1"
|
||||||
|
then
|
||||||
|
splitcolon "${1#ssh://}"
|
||||||
|
(exec 0>&-; ssh "$prefix_" "cat $suffix_/$2")
|
||||||
|
elif isurl sftp "$1"
|
||||||
|
then
|
||||||
|
(exec 0>&-; curl -s -S -k "$1/$2")
|
||||||
|
elif isurl gitception "$1"
|
||||||
|
then
|
||||||
|
gitception_get "${1#gitception://}" "$2"
|
||||||
|
else
|
||||||
|
cat "$1/$2"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fetch repo $1, file $2 or return encrypted empty message
|
||||||
|
GET_OR_EMPTY() { GET "$@" 2>/dev/null || (printf "" | ENCRYPT) ; }
|
||||||
|
|
||||||
# Put repo $1, file $2 or fail
|
# Put repo $1, file $2 or fail
|
||||||
PUT()
|
PUT()
|
||||||
{
|
{
|
||||||
|
@ -89,10 +112,7 @@ PUT()
|
||||||
curl -s -S -k --ftp-create-dirs -T - "$1/$2"
|
curl -s -S -k --ftp-create-dirs -T - "$1/$2"
|
||||||
elif isurl gitception "$1"
|
elif isurl gitception "$1"
|
||||||
then
|
then
|
||||||
OBJID=$(git hash-object -w --stdin) && \
|
gitception_put "${1#gitception://}" "$2"
|
||||||
TREEID=$(update_tree "$GREF" "$2" "$OBJID") &&
|
|
||||||
COMMITID=$(anon_commit "$TREEID" -m "x") && \
|
|
||||||
git update-ref "$GREF" "$COMMITID"
|
|
||||||
else
|
else
|
||||||
cat > "$1/$2"
|
cat > "$1/$2"
|
||||||
fi
|
fi
|
||||||
|
@ -101,11 +121,9 @@ PUT()
|
||||||
# Put all PUT changes for repo $1 at once
|
# Put all PUT changes for repo $1 at once
|
||||||
PUT_FINAL()
|
PUT_FINAL()
|
||||||
{
|
{
|
||||||
local REPO
|
|
||||||
if isurl gitception "$1"
|
if isurl gitception "$1"
|
||||||
then
|
then
|
||||||
REPO=${1#gitception://}
|
git push --quiet -f "${1#gitception://}" "$GREF":master
|
||||||
git push --quiet -f "$REPO" "$GREF":master
|
|
||||||
else
|
else
|
||||||
:
|
:
|
||||||
fi
|
fi
|
||||||
|
@ -130,6 +148,11 @@ PUTREPO()
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CLEAN_FINAL()
|
||||||
|
{
|
||||||
|
isurl gitception "$1" && git update-ref -d "$GREF" || :
|
||||||
|
}
|
||||||
|
|
||||||
ENCRYPT()
|
ENCRYPT()
|
||||||
{
|
{
|
||||||
# Security protocol:
|
# Security protocol:
|
||||||
|
@ -289,7 +312,8 @@ do_fetch()
|
||||||
trap 'rm -f "$TMPPACK_ENCRYPTED"' EXIT
|
trap 'rm -f "$TMPPACK_ENCRYPTED"' EXIT
|
||||||
|
|
||||||
# Needed packs is REMOTE - (HAVE & REMOTE)
|
# Needed packs is REMOTE - (HAVE & REMOTE)
|
||||||
PHAVE="$(cat "$LOCALDIR/have_packs" 2>/dev/null || :)"
|
# The `+` for $GITCEPTION is pointless but we will be safe for stacking
|
||||||
|
PHAVE="$(cat "$LOCALDIR/have_packs+" 2>/dev/null || :)"
|
||||||
PBOTH="$(printf "%s\n%s" "$PACKLIST" "$PHAVE" | sort_C | uniq -d)"
|
PBOTH="$(printf "%s\n%s" "$PACKLIST" "$PHAVE" | sort_C | uniq -d)"
|
||||||
PNEED="$(printf "%s\n%s" "$PACKLIST" "$PBOTH" | sort_C | uniq -u)"
|
PNEED="$(printf "%s\n%s" "$PACKLIST" "$PBOTH" | sort_C | uniq -u)"
|
||||||
|
|
||||||
|
@ -306,7 +330,7 @@ do_fetch()
|
||||||
DECRYPT < "$TMPPACK_ENCRYPTED" | \
|
DECRYPT < "$TMPPACK_ENCRYPTED" | \
|
||||||
git index-pack -v --stdin >/dev/null
|
git index-pack -v --stdin >/dev/null
|
||||||
# add to local pack list
|
# add to local pack list
|
||||||
printf "$PACKPFX%s\n" "$PACK" >> "$LOCALDIR/have_packs"
|
printf "$PACKPFX%s\n" "$PACK">>"$LOCALDIR/have_packs$GITCEPTION"
|
||||||
done
|
done
|
||||||
|
|
||||||
rm -f "$TMPPACK_ENCRYPTED"
|
rm -f "$TMPPACK_ENCRYPTED"
|
||||||
|
@ -407,7 +431,7 @@ mkdir -p "$LOCALDIR"
|
||||||
|
|
||||||
while read INPUT
|
while read INPUT
|
||||||
do
|
do
|
||||||
#echo_info "Got: $INPUT"
|
#echo_info "Got: $INPUT ($GITCEPTION)"
|
||||||
case "$INPUT" in
|
case "$INPUT" in
|
||||||
capabilities)
|
capabilities)
|
||||||
do_capabilities
|
do_capabilities
|
||||||
|
@ -452,6 +476,7 @@ do
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
#echo_info "Blank line, we are done"
|
#echo_info "Blank line, we are done"
|
||||||
|
CLEAN_FINAL "$URL"
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
Loading…
Reference in a new issue