mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
gitcommit.cmake: work around Windows pathname aliasing.
The cmake script that determines the current git head commit, in order to bake it into the binaries for development builds from a git checkout, wasn't working reliably on Windows: sometimes it reported that the source directory didn't seem to be a git repository, when in fact it was. This occurred because gitcommit.cmake starts by trying to work out _whether_ the source directory is the top level of a git worktree at all, by the technique of running `git rev-parse --show-toplevel` (to print the top-level path of the git worktree _containing_ $PWD, if any) and comparing it with ${CMAKE_SOURCE_DIR}. But the comparison was done as a plain string, which leads to problems if more than one string can represent the same actual directory. On Windows, this can occur for two reasons that I know of. One reason is related to Windows itself: if you map a network file server path to a local drive letter, then the same directory is accessible as a UNC path (e.g. \\hostname\share\subdir) and via the drive letter (e.g. N:\subdir). And it can happen that CMAKE_SOURCE_DIR and git's output disagree on which representation to use, causing the string comparison to return a false negative. (This can also affect filesystems in a WSL instance, accessed from native Windows via \\wsl$\instance\path, because Windows implements that as a network file share even though the network in question is purely in the imagination of that one machine.) The other reason is related more specifically to git, because some versions of Windows git are built on top of MSYS or MINGW or that kind of shim layer, and model Windows drive letters as subdirectories of a Unixlike VFS root. So you might also find that the two strings disagree on whether you're in C:\Users\alice\src\putty or /c/Users/alice/src/putty. I think this commit should work around both of these problems. Reading the man page for `git rev-parse` more carefully, it has an option `--show-cdup`, which returns a _relative_ path from $PWD to the top-level directory of the worktree: that is, it will be a sequence of `../../..` as long as necessary, including length zero. So you can use that to directly query whether you're at the top of a git worktree: if `git rev-parse --show-cdup` returns the empty string and a success status, then you are. (If you're deeper in a worktree it will return a non-empty string, and if you're not in a worktree at all it will return a failure status and print an error message to stderr.)
This commit is contained in:
parent
193e2ec063
commit
d96a4983be
@ -6,34 +6,32 @@ set(commit "${DEFAULT_COMMIT}")
|
||||
set(TOPLEVEL_SOURCE_DIR ${CMAKE_SOURCE_DIR})
|
||||
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} rev-parse --show-toplevel
|
||||
OUTPUT_VARIABLE git_worktree
|
||||
COMMAND ${GIT_EXECUTABLE} rev-parse --show-cdup
|
||||
OUTPUT_VARIABLE path_to_top
|
||||
ERROR_VARIABLE stderr
|
||||
RESULT_VARIABLE status)
|
||||
string(REGEX REPLACE "\n$" "" git_worktree "${git_worktree}")
|
||||
string(REGEX REPLACE "\n$" "" path_to_top "${path_to_top}")
|
||||
|
||||
if(status EQUAL 0)
|
||||
if(git_worktree STREQUAL CMAKE_SOURCE_DIR)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
|
||||
OUTPUT_VARIABLE git_commit
|
||||
ERROR_VARIABLE stderr
|
||||
RESULT_VARIABLE status)
|
||||
if(status EQUAL 0)
|
||||
string(REGEX REPLACE "\n$" "" commit "${git_commit}")
|
||||
else()
|
||||
if(commit STREQUAL "unavailable")
|
||||
message("Unable to determine git commit: 'git rev-parse HEAD' returned status ${status} and error output:\n${stderr}\n")
|
||||
endif()
|
||||
endif()
|
||||
# If we're at the top of a git repository, --show-cdup will print the
|
||||
# empty string (followed by a newline) and return success. If we're
|
||||
# lower down, it will return a sequence of "../../" that leads to the
|
||||
# top; if we're higher up it will fail with an error.
|
||||
if(status EQUAL 0 AND path_to_top STREQUAL "")
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
|
||||
OUTPUT_VARIABLE git_commit
|
||||
ERROR_VARIABLE stderr
|
||||
RESULT_VARIABLE status)
|
||||
if(status EQUAL 0)
|
||||
string(REGEX REPLACE "\n$" "" commit "${git_commit}")
|
||||
else()
|
||||
if(commit STREQUAL "unavailable")
|
||||
message("Unable to determine git commit: top-level source dir ${CMAKE_SOURCE_DIR} is not the root of a repository")
|
||||
message("Unable to determine git commit: 'git rev-parse HEAD' returned status ${status} and error output:\n${stderr}\n")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
if(commit STREQUAL "unavailable")
|
||||
message("Unable to determine git commit: 'git rev-parse --show-toplevel' returned status ${status} and error output:\n${stderr}\n")
|
||||
message("Unable to determine git commit: top-level source dir ${CMAKE_SOURCE_DIR} is not the root of a repository")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user