Skip to content

Commit

Permalink
git-remote-vault copies blobs and tags
Browse files Browse the repository at this point in the history
Signed-off-by: Denis Zalevskiy <denis.zalevskiy@jolla.com>
  • Loading branch information
Denis Zalevskiy committed Oct 8, 2015
1 parent c6c23bf commit 4e3d6ce
Show file tree
Hide file tree
Showing 6 changed files with 460 additions and 119 deletions.
1 change: 1 addition & 0 deletions rpm/vault.spec
Expand Up @@ -91,6 +91,7 @@ rm -rf $RPM_BUILD_ROOT
%{_bindir}/vault
%{_bindir}/vault-sync
%{_bindir}/vault-resolve
%{_bindir}/git-remote-vault
%dir %{tools_dir}
%{tools_dir}/*
%if 0%{?_with_usersession:1}
Expand Down
11 changes: 10 additions & 1 deletion tools/CMakeLists.txt
Expand Up @@ -8,11 +8,20 @@ install(
DESTINATION ${TOOLS_DIR}
)

install(
PROGRAMS
git-remote-vault
DESTINATION bin
)

install(
FILES
git-vault-rebase-generate.awk git-vault-rebase-prepare.awk
git-vault-rebase-generate.awk
git-vault-rebase-prepare.awk
git-vault-split-refs.awk
vault-misc
vault-unit-common
git-vault-helpers-remote
DESTINATION
${TOOLS_DIR}
)
220 changes: 103 additions & 117 deletions tools/git-remote-vault
@@ -1,174 +1,161 @@
#!/bin/bash

function error {
echo "`basename $0`: Error: ${@:1}" 1>&2;
src=$(dirname $0)
src=$(cd $src;pwd)
util_file=
if [ "x$VAULT_LIB_DIR" != "x" ]; then
util_file=$VAULT_LIB_DIR/git-vault-helpers-remote
else
util_file=$src/git-vault-helpers-remote
fi
if ! [ -f $util_file ]; then
echo "Set VAULT_LIB_DIR $src" >&2
exit 1
}

function log {
echo "`basename $0`: ${@}" 1>&2
}
fi
source $util_file $src

log "Args: $# is $@"
trace "Args: $# is $@"
alias=$1
url=$2
proto=vault

marks_path() {
echo "$GIT_DIR/$proto/marks"
}

obj_id() {
echo "$1" | md5sum | cut -d ' ' -f1
}

obj_list_path() {
echo "$url/.objects.$1"
}

head_path() {
echo "$url/.head.$1"
}

print_caps() {
trace_if 2 "Caps $cmd"
echo "push"
echo "fetch"
echo "refspec refs/heads/*:refs/$proto/$alias/branches/*"
echo "*import-marks $(marks_path)"
echo "*export-marks $(marks_path)"
echo "option"
echo
}

save_option() {
log "Option $@"
trace_if 2 "GIT: Save option $@"
echo "unsupported"
}

list_refs() {
log "List"
if ! [[ -f $(marks_path) ]]; then
[[ -d $GIT_DIR/$proto ]] || mkdir $GIT_DIR/$proto
touch $(marks_path)
fi

if ! find $url -name '.head.*' -exec cat {} \; ; then
echo "? /refs/heads/master"
echo "? /refs/notes/commits"
fi
echo "@refs/heads/master HEAD"
#git for-each-ref --format='? %(refname)' 'refs/heads/'
#echo "@master master"
echo
}

files_to_remove=

on_normal_exit() {
if [ "x$files_to_remove" != "x" ]; then
log "removing"
rm $files_to_remove
fi
}
on_failure() {
on_normal_exit
}
trap on_failure TERM
trap on_normal_exit EXIT

get_temp_file() {
local res=$(mktemp)
files_to_remove="$files_to_remove $res"
echo $res
}

get_saved_object() {
ls $url | sed -e 's/\.\(tree\|blob\|commit\|note\)$//' | sort
}

get_ref_objects() {
git rev-list --objects $1 | cut -d ' ' -f1 | sort
}

add_object() {
local obj_type=$(git cat-file -t $1)
git cat-file $obj_type $1 > $url/$1.$obj_type
}

do_push() {
log "Push $2"
trace_if 2 "GIT: Push $@"
local refs=$2
if [[ ${refs:0:1} == "+" ]]; then
refs=${refs:1}
fi
local delim=$(expr index "$refs" ':')
local from=${refs:0:$(expr delim-1)}
local to=${refs:$delim}
log "$from -> $to"
local obj=$(obj_id $to)
local is_update_head=true

if [ "x$from" == "x" ]; then
log "delete"
warn "TODO: delete $to"
is_update_head=false
else
([[ -d $url ]] || mkdir $url) || error "Can't mkdir $url"
local from_id=$(git rev-parse $from)
trace_if 3 "$from ($from_id) -> $to"
([[ -d $url ]] || mkdir -p $url) || error 15 "Can't mkdir $url"
if [[ $to =~ notes/.* ]]; then
log "Pushing notes"
local notes=$(get_temp_file)
for n in $(git notes list | cut -d ' ' -f1); do
add_object $n
trace_if 3 "Pushing notes"
is_update_head=false
local notes=$(tmp_path notes)
git notes list > $notes
for n in $(cat $notes | cut -d ' ' -f1); do
# TODO remove also notes
push_object $n
done
git notes list > $url/.notes
mv $notes $(notes_list_path)
elif [ "x$(remote_head_id)" == "x$from_id" ]; then
trace_if 3 "Skip $from_id, already taken"
else
local actual_objects=$(get_temp_file)
get_ref_objects $from > $actual_objects
local saved_objects=$(get_temp_file)
get_saved_object > $saved_objects

local obj_type=
for i in $(comm -13 $saved_objects $actual_objects); do
log "add $i "
add_object $i
trace_if 3 "Processing $from_id"
local src_list_prefix=$(save_graph $from)

# objects
local actual_objects=$src_list_prefix.objects
local saved_objects=$(tmp_path objects.saved)
write_saved_objects $saved_objects
process_sorted_ranges $saved_objects $actual_objects \
push_object rm_remote_object

# blobs
local actual_blobs=$src_list_prefix.blobs
local saved_blobs=$(tmp_path blobs.saved)
write_saved_blobs $saved_blobs
process_sorted_ranges $saved_blobs $actual_blobs \
push_vault_blob rm_remote_blob

# tags
local tags_file=$(tmp_path tags)
for tag in $(git tag); do
echo "$tag $(git rev-parse $tag)" >> $tags_file
done
cat $actual_objects > $(obj_list_path $obj)
echo "$(git rev-parse $from) $from" > $(head_path $obj)
mv $tags_file $(tags_list_path)

# record saved objects
rm -f $url/*.objects
rm -f $url/*.blobs
cp $src_list_prefix.blobs $url/
cp $src_list_prefix.objects $url/
fi
fi
if $is_update_head; then
echo "$from_id $from" > $(head_path $obj)
fi
tar cf $url/metadata.tar .git/info/exclude .git/vault.version
echo
}

tag_object() {
git tag $1 $2 || warn "Can't tag $1 $2"
}

do_fetch() {
log "Fetch $@"
# TODO ignore params, just fetch everything
local obj_type=
local obj_id=
for i in $(ls $url); do
obj_id=$(echo "$i" | cut -d '.' -f1)
if ! git cat-file -e $obj_id; then
log "add $i $obj_type"
obj_type=$(echo "$i" | cut -d '.' -f 2)
obj_id=$(git hash-object -t $obj_type -w $url/$i)
fi
trace_if 2 "GIT: Fetch $@"
# TODO now it ignores params, just fetches everything
local saved_objects=$(tmp_path objects.saved)
write_saved_objects_filenames $saved_objects
local obj=
for obj in $(cat $saved_objects); do
fetch_object $obj
done
if [ -f $url/.notes ]; then
for n in $(cat $url/.notes | tr ' ' ':'); do

[ -d .git/blobs ] || (trace_if 2 "Creating blobs dir"; mkdir .git/blobs)
local saved_blobs=$(tmp_path blobs.saved)
write_saved_blobs $saved_blobs
local actual_blobs=$(tmp_path blobs.actual)
write_actual_blobs $actual_blobs

process_sorted_ranges $actual_blobs $saved_blobs \
fetch_vault_blob rm_vault_blob

apply_remote_tags tag_object
local metadata_file=$url/metadata.tar
[ -f $metadata_file ] && (trace_if 2 "Extracting metadata"; tar xf $metadata_file)
local notes_list=$(notes_list_path)
if [ -f $notes_list ]; then
for n in $(cat $notes_list | tr ' ' ':'); do
local delim=$(expr index "$n" ':')
local note=$url/${n:0:$(expr delim-1)}.blob
local note=$(remote_object_path ${n:0:$(expr delim-1)} "blob")
local commit=${n:$delim}
if [ -f $note ]; then
git notes add -f -F $note $commit
else
log "Can't find note $note"
warn "Can't find note $note"
fi
done
else
warn "No notes"
fi
x echo
echo
}

list_for_push() {
log "for push $@"
trace_if 2 "for push $@"
list_refs $@
}

while read cmd; do
trace "GIT CMD: $cmd"
case $cmd in
capabilities)
log "Caps $cmd"
print_caps
#break
;;
Expand All @@ -189,8 +176,7 @@ while read cmd; do
;;
*)
[[ "x$cmd" == "x" ]] && break
log "Cmd: $cmd"
trace "Cmd: $cmd"
;;
esac
done

0 comments on commit 4e3d6ce

Please sign in to comment.