Установка бита выполнения Mercurial в Windows

Я работаю над репозиторием Mercurial, который размещён в файловой системе Unix, такой как ext3 на некоторых машинах и FAT32 на других.

В Subversion я могу установить свойство svn:executable, чтобы контролировать, следует ли помечать файл как исполняемый при извлечении на платформе, которая поддерживает такой бит. Я могу сделать это независимо от платформы, на которой я запускаю SVN, или файловой системы, содержащей мою рабочую копию.

В Mercurial я могу chmod +x получить тот же эффект, если клон находится в файловой системе Unix. Но как я могу установить (или удалить) исполняемый бит в файле в файловой системе FAT?


person Community    schedule 24.04.2010    source источник


Ответы (3)


Mercurial отслеживает бит выполнения как часть метаданных файла. Невозможно явно установить его в mercurial, но он отслеживает изменения, сделанные chmod в unix. Файлы, добавленные в Windows, будут иметь установленный по умолчанию бит выполнения, но команда атрибута Windows не позволяет вам установить их.

Если вы сделаете hg log -p --git, вы увидите формат патча, который показывает изменение бита выполнения, который выглядит следующим образом:

$ hg log --git -p
changeset:   1:0d9a70aadc0a
tag:         tip
user:        Ry4an Brase <[email protected]>
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 <[email protected]>
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 его, но это определенно неоптимально.

person Ry4an Brase    schedule 24.04.2010
comment
Я пытался использовать эту технику при добавлении файла, и это не сработало. Я добавил файл, создал патч, восстановил репозиторий, удалил файл, отредактировал патч, заменив 0644 на 0755, и импортировал патч. При использовании системы Unix режим по-прежнему 0644. Mercurial 1.9.1. - person Jason R. Coombs; 09.08.2011
comment
Вытягивание не создает файл, это делает обновление. После того, как вы вытащили и сделали «hg log --git -p», вы видите 100755 в патче? Когда вы обновляете, этот бит выполнения может быть сброшен, если umask запрещает это, файловая система монтируется без выполнения или несколько других маловероятных вещей. - person Ry4an Brase; 09.08.2011
comment
При просмотре лога он показывает мод 0644, значит мод из отредактированного патча почему-то не принял. - person Jason R. Coombs; 09.08.2011
comment
Хм, и вы использовали настоящую команду «hg import», верно? Не инструмент командной строки «исправление»? - person Ry4an Brase; 09.08.2011
comment
Правильный. Надо будет попробовать воспроизвести. - person Jason R. Coombs; 09.08.2011
comment
@ Ry4an: я пробовал это решение некоторое время назад. К сожалению, Mercurial в Windows просто игнорирует изменения режима файла в патчах, на самом деле нет возможности установить исполняемый бит. - person Wladimir Palant; 13.09.2011
comment
Вот доказательство в виде расшифровки, подтверждающее мои выводы о том, что этот метод не работает. - person Jason R. Coombs; 31.07.2012

В настоящее время вы не можете изменить бит выполнения, если файловая система его не поддерживает (я планирую поддерживать его в будущем).

person tonfa    schedule 24.04.2010
comment
Проблема 3659 была закрыта как дубликат, более старая: bz.mercurial-scm .org/show_bug.cgi?id=2020 - person maxschlepzig; 24.04.2016
comment
Это шоу-стоппер с сотрудничеством Windows + Linux, и я нахожу ошеломляющим, что никто не написал расширение для решения этой проблемы. Даже этому вопросу шесть лет... - person joonas.fi; 16.06.2016

Для Windows вам нужно создать файл исправления, а затем применить его, как сказал Ry4an, но с аргументом --bypass для hg import . Это можно сделать, создав файл сценария Powershell с именем SetFileExecutable.ps1 с приведенным ниже текстом внутри него.

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"

В нем используется решение, предоставленное Мэттом Харбисоном в Mercurial Bugzilla.

person WhiteKnight    schedule 18.07.2016
comment
У вас в скрипте опечатка, нужно поменять filePathRelativeTo -> fileRelativePath, а то со своей задачей справляется, спасибо :) - person joonas.fi; 28.08.2018
comment
@joonas.fi извините, я забыл обновить это после того, как исправил эту проблему. - person WhiteKnight; 28.08.2018
comment
Не переживайте, со всеми бывает :) p.s. в выполнении его следующим образом все еще неправильно (fileRelativePathTo против filePathRelativeTo в сценарии) - person joonas.fi; 28.08.2018