diff --git a/git-remote-rclone b/git-remote-rclone index 0b30902..5226be9 100755 --- a/git-remote-rclone +++ b/git-remote-rclone @@ -130,10 +130,22 @@ class RCloneRemote(object): synced = self.workdir / 'synced' repo_hash = self.get_remote_state() - if synced.exists() and not repo_hash: - # we had it sync'ed before, but now it is gone from the remote - # remove sync stamp, but leave any local mirror untouched as it's the only copy - synced.unlink() + if not repo_hash: + remote_refs = self.get_remote_refs() + if not remote_refs: + # The remote is empty. Any local mirror and mark files are cache + # from an earlier state and must not constrain a new push. + self.log('Remote repository is empty; resetting local mirror cache') + rmtree(str(self.workdir), ignore_errors=True) + self.workdir.mkdir(parents=True, exist_ok=True) + self.marks_git.touch() + self.marks_rclone.touch() + return + + if synced.exists(): + # The archive disappeared but refs remain. Keep the local mirror + # as the only possible copy, but invalidate the sync stamp. + synced.unlink() return if synced.exists(): diff --git a/tests/test.sh b/tests/test.sh index d8db292..5b33c00 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -170,6 +170,31 @@ test_conflict() reset_repo "${SECOND_REPO}" } +test_recreate_empty_remote() +{ + set -xe + local remote_url="${1?missing remote_url}" + + setup_remote_repo + setup_repo "${remote_url}" + append_data "${FIRST_REPO}" "${TEST_FILE1}" "first history" + create_commit "${FIRST_REPO}" + push_repo "${FIRST_REPO}" + + # Remove the remote contents while retaining the helper's local cache. + rm -rf "${REMOTE_REPO}" + mkdir -p "${REMOTE_REPO}" + + # Replace the local branch with unrelated history and push to the now-empty + # remote. A stale mirror cache must not cause fast-import to reject it. + git -C "${FIRST_REPO}" checkout --orphan replacement + git -C "${FIRST_REPO}" rm -rf . + append_data "${FIRST_REPO}" "${TEST_FILE1}" "replacement history" + create_commit "${FIRST_REPO}" + git -C "${FIRST_REPO}" branch -M master + push_repo "${FIRST_REPO}" +} + print_test_started() { local test="${1?missing test}" @@ -215,6 +240,9 @@ tests() run_test test_3way_merge "${remote_type}" run_test test_conflict "${remote_type}" run_test test_pull_repo "${remote_type}" + if [ "${remote_type}" = "plain" ]; then + run_test test_recreate_empty_remote "${remote_type}" "${remote_url}" + fi } main()