내가 사용하는 운영 체제 클래스의 경우 Freebsd5.4를 실행해야했습니다. git이 출시되기 전에 출시 된 bsd 버전에서 git을 빌드하려고 시도하고 싶지 않기 때문에 git
Arch over에서 사용하는 것이 깔끔하다고 생각했습니다 sshfs
.
어쨌든 나는 옵션 을 제안 하는 해결 방법 을 찾았습니다 .sshfs
-o workaround=rename
git
행복해 보이지만 방금 일어난 일에 대해 다소 혼란 스럽습니다 …
모든 매뉴얼 페이지 에서 해결 방법에 대해 말합니다.
fix renaming to existing file
그러나 나는 그것이 의미하는 바에 대해 완전히 당황합니다 …
그 옵션은 정확히 무엇입니까?
답변
sshfs는 SFTP (SSH File Transfer Protocol)를 사용합니다. 활성화 한 해결 방법은 “새”이름이 이미 존재하는 경우 해당 프로토콜에 대한 rename () 작업의 의미를 해결하는 것입니다.
이 경우 rename ()의 POSIX 동작은 기존 파일을 제거하고 이름 바꾸기를 완료하는 것입니다.
SFTP 프로토콜에서 SSH_FXP_RENAME 조작으로 파일 이름을 바꿀 수 있습니다. 그러나 대상 이름이 이미 존재할 때의 동작은 사용중인 프로토콜의 버전과 전달하는 플래그에 따라 달라집니다. SFTP 프로토콜 의 Wikipedia 페이지 에는 다양한 버전의 프로토콜에 대한 다양한 초안 RFC 링크가 있습니다. 에서 초안 00 동작은 다음과 같이 표시됩니다 :
newpath에 의해 지정된 이름의 파일이 이미 존재하면 오류입니다.
년 초안 (13) , 동작은 다음과 같이 표시됩니다
플래그가 SSH_FXP_RENAME_OVERWRITE를 포함하지 않고 newpath에 의해 지정된 이름의 파일이 이미 존재하는 경우, 서버는 SSH_FX_FILE_ALREADY_EXISTS로 응답해야합니다.
플래그에 SSH_FXP_RENAME_ATOMIC이 포함되어 있고 대상 파일이 이미 존재하는 경우 원자 방식으로 대체됩니다. 즉, 이름이 이전 파일이나 새 파일을 참조하지 않는 시점에는 관찰 가능한 순간이 없습니다. SSH_FXP_RENAME_ATOMIC은 SSH_FXP_RENAME_OVERWRITE를 의미합니다.
대상 이름이 존재할 때 rename () 작업의 가능한 실패를 처리하기 위해 sshfs는 다음과 같은 해결 방법을 제공합니다 (활성화 된 경우) .
if (err == -EPERM && sshfs.rename_workaround) {
size_t tolen = strlen(to);
if (tolen + RENAME_TEMP_CHARS < PATH_MAX) {
int tmperr;
char totmp[PATH_MAX];
strcpy(totmp, to);
random_string(totmp + tolen, RENAME_TEMP_CHARS);
tmperr = sshfs_do_rename(to, totmp);
if (!tmperr) {
err = sshfs_do_rename(from, to);
if (!err)
err = sshfs_unlink(totmp);
else
sshfs_do_rename(totmp, to);
}
}
}
이 코드에서 “from”은 이름을 바꾸려는 파일의 기존 이름이고 “to”는 원하는 새 이름입니다. 약간의 경로 길이와 오류 부기를 제외 하고이 문제를 해결합니다.
- “to”를 “totmp”로 이름을 바꿉니다.
- “에서”로 이름을 바꿉니다.
- “totmp”링크 해제 (삭제)
이렇게하면 “파일이 이미 존재합니다”충돌을 피할 수 있지만 rename () 작업의 의미도 변경되므로 기본적으로 원하지 않습니다.