1

The title says it all, but for example, if the HEAD of a Git repository points to ref/heads/master on any well-used Git implementation for Windows, which of the following is the content of the file .git/HEAD ... oops, .git\HEAD:

  • ref: refs/heads/master, or
  • ref: refs\heads\master ?

Either way, I need to calculate the absolute path <git project>\.git\refs\heads\master, but I don't have Windows environment and I can't get to know which form is used! Answer is greatly appreciated.

Background: I'm modifying a Haskell library implementing a macro that embeds the Git revision hashes of Haskell projects into their source codes right on compilation (very nice for implementing --version option!). When we compile the program invocating that macro, git is called; however even before that, when a build tool is checking whether recompilation is required, we cannot call git and all that's done is simple file update check! Therefore, at the time of each compilation, we must compute and save the path of reference file at which HEAD is pointing, so that the reference file would be checked for update next time. The problem is that I would like to make the library cross-platform but that I don't know how to compute the path of a reference file on Windows, for I don't know the original form.

gksato
  • 368
  • 1
  • 10
  • 2
    The HEAD file uses a forward slash `/` on windows. `ref: refs/heads/master` – Ben W May 14 '20 at 00:04
  • As [bk2204 said](https://stackoverflow.com/a/61787157/1256452), that's not a *path name*, it's just a *name*. (Git does turn it into a path name at times. Having been developed on Linux originally, Git rather cavalierly assumes that nearly any string is valid when turned into a path name, but having been ported to Windows, Git is now a little less cavalier about these things.) – torek May 14 '20 at 00:39
  • The revision hash ID *may not be in the file you compute*. In particular if the references have recently been *packed*, the hash ID will be in `.git/packed-refs` and not in `.git/refs/heads/master`. Use `git rev-parse refs/heads/master`, or more simply, `git rev-parse HEAD`, to find the hash ID. (If you can't run `git -C rev-parse`, of course, there's a big problem here, but just reaching into the file system for a branch file isn't really the right answer.) – torek May 14 '20 at 00:41
  • @torek Ah, that's Okay, we also check `.git/packed-refs` for update. – gksato May 14 '20 at 00:44
  • 1
    OK. Be aware that the hash can be in both places; if so, the individual file value overrides the packed-refs file value. Also, be aware that all of this could potentially change in the future, It really *should* change as Git's handling of branch names on case-insensitive file systems is ... not good, right now. – torek May 14 '20 at 00:50

1 Answers1

2

HEAD uses a reference name and not a path separator. Git always uses forward slashes in reference names, even on Windows. Backslashes are never allowed in a reference name on any platform, ever.

Since Windows will also allow forward slash path separators (unless you're using UNC paths), it's usually safe to just use forward slashes everywhere unless you know you have special needs.

bk2204
  • 64,793
  • 6
  • 84
  • 100