【问题标题】:Setting Mercurial's execute bit on Windows在 Windows 上设置 Mercurial 的执行位
【发布时间】:2011-02-11 18:26:55
【问题描述】:

我在一个 Mercurial 存储库上工作,该存储库被检出到 Unix 文件系统上,例如某些机器上的 ext3 和其他机器上的 FAT32。

在 Subversion 中,我可以设置 svn:executable 属性来控制在支持此类位的平台上签出文件时是否应将文件标记为可执行。无论我在哪个平台上运行 SVN 或包含我的工作副本的文件系统,我都可以做到这一点。

在 Mercurial 中,如果克隆位于 Unix 文件系统上,我可以 chmod +x 获得相同的效果。但是如何设置(或删除)FAT 文件系统上文件的可执行位?

【问题讨论】:

    标签: windows mercurial cross-platform filesystems fat32


    【解决方案1】:

    如果文件系统不支持,暂时不能更改执行位(我计划将来支持它)。

    【讨论】:

    • 问题 3659 已作为重复问题关闭,较旧的问题是:bz.mercurial-scm.org/show_bug.cgi?id=2020
    • 这是一个与 Windows + Linux 合作的精彩绝伦,我发现没有人编写扩展来解决这个问题令人难以置信。连这个问题都六岁了……
    【解决方案2】:

    Mercurial 将执行位作为文件元数据的一部分进行跟踪。没有办法在 mercurial 中明确设置它,但它会跟踪 chmod 在 unix 上所做的更改。 windows上添加的文件默认会设置执行位,但是windows attrib命令不允许你设置。

    如果您执行hg log -p --git,您将看到显示执行位更改的补丁格式,如下所示:

    $ hg log --git -p
    changeset:   1:0d9a70aadc0a
    tag:         tip
    user:        Ry4an Brase <ry4an-hg@ry4an.org>
    date:        Sat Apr 24 10:05:23 2010 -0500
    summary:     added execute
    
    diff --git a/that b/that
    old mode 100644
    new mode 100755
    
    changeset:   0:06e25cb66089
    user:        Ry4an Brase <ry4an-hg@ry4an.org>
    date:        Sat Apr 24 10:05:09 2010 -0500
    summary:     added no execute
    
    diff --git a/that b/that
    new file mode 100644
    --- /dev/null
    +++ b/that
    @@ -0,0 +1,1 @@
    +this
    

    如果您无法进入 unix 系统来设置它们,您可能会伪造一个类似的补丁并 hg import 它,但这绝对不是最佳的。

    【讨论】:

    • 我在添加文件时尝试使用此技术,但它不起作用。我添加了文件,创建了补丁,恢复了 repo,删除了文件,编辑了将 0644 替换为 0755 的补丁,然后导入了补丁。在 Unix 系统上拉取时,模式仍然是 0644。Mercurial 1.9.1。
    • 拉取不会创建文件,更新会。在您拉动并执行“hg log --git -p”后,您是否在补丁中看到 100755?当您更新时,如果 umask 禁止执行位,则该执行位可能会被取消设置,文件系统会以非执行方式挂载,或其他一些不太可能发生的事情。
    • 查看日志显示为0644模式,故不接受编辑补丁的模式。
    • Hrm,您使用了实际的“hg import”命令,对吧?不是命令行“补丁”工具?
    • 正确。我将不得不尝试重现它。
    【解决方案3】:

    对于 Windows,您需要创建一个补丁文件然后应用它,例如 Ry4an has said,但使用 --bypass 参数到 hg import。这可以通过创建一个名为 SetFileExecutable.ps1 的 Powershell 脚本文件来完成,其中包含以下文本

    param (
      [String]$comment = "+execbit",
      [Parameter(Mandatory=$true)][string]$filePathRelativeTo,
      [Parameter(Mandatory=$true)][string]$repositoryRoot
    )
    
    if( Test-Path -Path "$($repositoryRoot)\.hg" -PathType Container )
    {
      if( Test-Path -Path "$($repositoryRoot)\$($filePathRelativeTo)" -PathType Leaf )
      {
        $filePathRelativeTo = $filePathRelativeTo.Replace( '\', '/' )
    
        $diff = "$comment" + [System.Environment]::NewLine +
          [System.Environment]::NewLine +
          "diff --git a/$filePathRelativeTo b/$filePathRelativeTo" + [System.Environment]::NewLine +
          "old mode 100644" + [System.Environment]::NewLine +
          "new mode 100755"
    
        Push-Location
        cd $repositoryRoot
        $diff | Out-File -Encoding 'utf8' $env:tmp\exebit.diff
        hg import --bypass -m "$comment" $env:tmp\exebit.diff
        Pop-Location
      }
      else
      {
        Write-Host "filePathRelativeTo must the location of a file relative to repositoryRoot"
      }
    }
    else
    {
      Write-Host "repositoryRoot must be the location of the .hg folder"
    }
    

    执行如下:

    .\SetFileExecutable.ps1" -comment "Marking file as executable" -filePathRelativeTo mvnw -repositoryRoot "c:\myrepo"
    

    使用Matt Harbison in Mercurial's Bugzilla提供的解决方案

    【讨论】:

    • 你的脚本有错别字,需要更改filePathRelativeTo -> fileRelativePath,否则它可以正常工作,谢谢:)
    • @joonas.fi 抱歉,我在解决该问题后忘记更新此内容。
    • 别担心,发生在我们所有人身上:) p.s.在“按如下方式执行”中,它仍然是错误的方式(fileRelativePathTo vs filePathRelativeTo 在脚本中)
    猜你喜欢
    • 2011-01-08
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-23
    相关资源
    最近更新 更多