0

语境:

我正在开发一个大型 UE4 项目。目前我们使用 SVN 作为我们的 VCS,但我一直是一名 git 开发人员,并且拥有本地 repo、本地分支和存储是我不愿意放弃的东西。

所以,我已经开始使用 SubGit 来处理 repo 的 git 版本,而 subgit 进行 git 到 svn 的转换。到目前为止,我喜欢它,除了我被迫使用 rebase 而不是合并这一事实之外,其他一切都像普通的 git。

编辑 1:我的 subgit 存储库是本地的,因为我无权访问远程 SVN 存储库。这意味着工具喜欢svnadminsvnlook不适合我。

问题:

现在,我的团队通过锁定他们在 SVN 中工作的二进制文件来工作。我想要一种自动加入该工作流程的方式。所以我想到了一个预提交挂钩来检查我即将提交的文件是否被锁定。如果没有,则立即锁定它们。如果是,请检查我是否是锁的所有者。如果我不是,请中止提交。

有没有人知道如何实现这样的目标?

4

2 回答 2

1

经过大量研究,反复试验终于得到了可行的东西!我添加了所有这些评论,以便人们能够理解我的逻辑,因为我仍然相信它可以改进。

编辑 1:创建了一个 gist 来托管文件,以跟踪对其进行的任何改进pre-commit gist

例如,我每个文件访问一次远程仓库。当往返时间很长时,如果提交包含多个 .uasset 文件,那将是非常低效的。相反,在单个 svn 信息请求上批处理所有文件信息请求会很酷。我不知道这是否可能。

此外,我获取 Lock owner 用户名的方式太老套了,但至少它对我的情况有用。无法成功从第二个 grep 的两个单引号之间获取字符串。相反,我匹配的用户名模式当然只适用于我公司使用的所有 svn 用户名格式为 name.lastname 的场景

### Parameters

# Change SVN_USER to the SVN username you configured in subgit
SVN_USER="Firstname.Lastname"
# Remote url. Should end with trunk/ or branches/ . Assumes same folder name on svn and git
SVN_REPO="https://url/path/to/remote/trunk/"
# Currently only checks locks for files with .uasset extension
GREP_FILE_PATTERN_TO_INSPECT="\.uasset$"
# Pattern to match usernames other than your own on the lock error msg
GREP_USERNAME_PATTERN="[[:alpha:]]\+\.[[:alpha:]]\+"

### Start of the hook

# Only to be used for the lock msg. Not necessary...
CURRENT_BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)
# leave as 0, used for aborting the commit if a non-owned lock is found
COMMIT_SHOULD_FAIL=0
# Array of relative file paths (to git project) from staged files that should be locked
FILES_TO_LOCK=$(git diff --cached --name-only | grep $GREP_FILE_PATTERN_TO_INSPECT)

for FILE in $FILES_TO_LOCK
do
    PATH_TO_FILE_IN_SVN=$SVN_REPO$FILE
    # Try to apply a lock. If the file is already locked, grab the lock owner's username
    # 2>&1 redirects stderr to stdout, to pipe the error msg into grep for parsing it
    # 1st grep would grab part of the error msg printed if the file is already locked
    # 2nd grep would grab the lock owner's username with format GREP_USERNAME_PATTERN
    LOCK_OWNER=$(svn lock $PATH_TO_FILE_IN_SVN -m "working on ${CURRENT_BRANCH_NAME}" 2>&1 \
        | grep -o "already locked by user .\+'" \
        | grep -o $GREP_USERNAME_PATTERN)
    if [ $LOCK_OWNER ] && [ $LOCK_OWNER != $SVN_USER ] # If someone else locked it
    then
      echo "Error: File ${FILE} locked by ${LOCK_OWNER}"
        COMMIT_SHOULD_FAIL=1
    fi
done

if [ $COMMIT_SHOULD_FAIL -eq 1 ] # If at least 1 file was locked by another user
then
  echo '--Commit ABORTED--'
  exit 1 # Exiting with exit-code 1 makes the entire commit process abort
fi

超级开放的改进!请在评论中建议他们

于 2020-04-01T15:49:47.447 回答
0

关于锁定,您可以使用“ What is the best way to see what files are locked in Subversion? ”,意思svnadmin lslocks是列出锁定的文件及其所有者。(也,本地,svn status --show-updates

在您的pre-commit 钩子中将其与git diff --cached --name-status.
对于任何未锁定的文件,asvn proplist -v将显示其所有者。

于 2020-04-01T04:16:32.937 回答