-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
os: Rename error behavior changed from Go 1.7 to Go 1.8 when source file doesn't exist #19647
Comments
Yes, this was intentional. https://golang.org/doc/go1.8#os says:
The fix that works on both Go 1.7 and Go 1.8 is to write instead: err := os.Rename("doesnt-exist", "destination/doesnt-exist") |
You misunderstand. The difference is that in go1.7 the error that is returned is that the source does not exist, and in go1.8 the error that is returned is that the destination already exists. That semantic change caused bugs for me, and so I was hoping to maintain the property that if you attempt to rename with a source that doesn't exist, that check is performed first. The mv command has this property, for example. |
To be clear, I'm fine with go1.8 erroring because the destination already exists, it would just be good if it errored that the source does not exist first to maintain compatibility with go1.7. |
Gotcha. But now that the behavior has changed in a released version of Go, I'm not sure how much good (or harm) it does to change it again. We've never documented the precedence of errors between the two possible failure cases. The only reliable thing to do is stat your source file first, before the rename. I can reopen for a decision, but I don't see a great answer. |
/cc @rsc @ianlancetaylor |
Doesn't sound very reliable due to potential race condition, though. |
Then do it afterwards, or afterwards also to disambiguate between the two possible errors. Like I said, we've never documented which of the src error vs dest error is returned first if both are bogus. |
I think this is not important enough to fix for Go 1.8.1. I don't mind if someone feels strongly and wants to add an Lstat of oldname for Go 1.9. |
CL https://golang.org/cl/40577 mentions this issue. |
This slightly clarifies the just-submitted CL 40577. Updates #19647 Change-Id: I5584ad0e1abbc31796e3e5752351857f2a13d6d7 Reviewed-on: https://go-review.googlesource.com/43625 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
What version of Go are you using (
go version
)?go1.8
What operating system and processor architecture are you using (
go env
)?GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH=""
GORACE=""
GOROOT="/Users/jeff/external/golang"
GOTOOLDIR="/Users/jeff/external/golang/pkg/tool/darwin_amd64"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/tn/09dglcts0b9gc5111hnf0_dm0000gn/T/go-build647286002=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
What did you do?
run this program under go1.7 and go1.8
https://play.golang.org/p/v4gGML3VCP
What did you expect to see?
the same output
What did you see instead?
Fixing issue #14527 in CL https://golang.org/cl/31358 caused this (it checks if the destination is a directory before attempting the rename). There are many places in my code base where I optimistically attempt to migrate some old directory path to a new one, and all of them will have to include a check that the old directory exists first to maintain idempotency.
The text was updated successfully, but these errors were encountered: