From d106a17ca1c103ced2c8eb493b048c291515e434 Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Tue, 9 Jun 2020 16:45:48 -0700 Subject: [PATCH] taskd/clone.sh: persistently attempt git-svn clones During the initial clone, git-svn has a nasty habit of dropping out with an error before the clone has completed, especially if the source repository is large. However, git-svn fetch will pick up where it left off if it's just run again. As long as we continue to make progress, keep restarting the fetch until the clone has fully completed. Initial svn clones of large repositories will now succeed much more reliably than before. Signed-off-by: Kyle J. McKay --- taskd/clone.sh | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/taskd/clone.sh b/taskd/clone.sh index 736c982..1434e93 100755 --- a/taskd/clone.sh +++ b/taskd/clone.sh @@ -329,8 +329,45 @@ case "$url" in git config --replace-all svn-remote.svn.fetch ':refs/heads/master' fi; } test $? -eq 0 - # Again, be careful to use GIT_DIR=. here or else new .git subdirectory! - GIT_DIR=. git svn fetch --log-window-size=$var_log_window_size --username="$svnuser" --quiet <"$mtlinesfile" + # git svn fetch on a very large repo can take some time and the + # remote server may interrupt the connection from time to time. + # keep retrying (after a brief pause) as long as we are making progress. + # however, we do limit the total number of retries to 1000 + # we will, however, retry up to 5 times even if we're not making progress + v_get_svn_progress_fingerprint() { + eval "$1="'"$({ GIT_DIR=. git svn info <"$mtlinesfile" 2>&1; git show-ref --head 2>&1; } | + git hash-object -t blob --stdin )"' || : + } + svn_ret_err() { return "${1:-1}"; } + svn_retries=1000 + svn_progress= + v_get_svn_progress_fingerprint svn_progress + svn_progress_retries="$svn_retries" + svn_err=0 + while [ "$svn_retries" -gt 0 ]; do + svn_retries="$(( $svn_retries - 1 ))" + svn_err=0 + # Again, be careful to use GIT_DIR=. here or else new .git subdirectory! + GIT_DIR=. git svn fetch --log-window-size=$var_log_window_size --username="$svnuser" --quiet <"$mtlinesfile" || svn_err="$?" + [ "${svn_err:-1}" -ne 0 ] || break # success! + # Check to see if we made any progress + v_get_svn_progress_fingerprint svn_progress_now + if [ "$svn_progress_now" != "$svn_progress" ]; then + # we made progress, continue the loop + svn_progress="$svn_progress_now" + svn_progress_retries="$svn_retries" + else + # no progress, but we only give up after + # 5 no-progress attempts in a row + [ "$(( $svn_progress_retries - $svn_retries ))" -lt 5 ] || break # failure + fi + # Pause briefly before retrying to be friendly to the server + echo 'Pausing for 120 seconds before retrying' + sleep 120 + echo 'Retrying fetch' + done + [ "${svn_err:-1}" -eq 0 ] || svn_ret_err "$svn_err" + test ${svn_err:-1} -eq 0 # git svn does not preserve group permissions in the svn subdirectory chmod -R ug+rw,o+r svn # git svn also leaves behind ref turds that end with @nnn -- 2.11.4.GIT