简体   繁体   中英

SubGit: Git hook to lock a svn file if non locked, or reject commit if locked by another user

Context:

I'm working on a big UE4 project. Currently we're using SVN as our VCS, but I've always been a git developer and having a local repo, local branches, and stashes are things I'm not willing to loose.

So, I've started using SubGit to work on a git version of the repo, while subgit does the git to svn conversion. So far I love it, aside from the fact that I'm forced to use rebase instead of merge, everything else is like normal git.

EDIT 1: My subgit repo is bare local one, as I don't have access to the remote SVN repo. This means tools like svnadmin or svnlook don't work for me.

Question:

Now, my team works by locking the binary files they work on in SVN. I want an automatic way to join that workflow. So I thought about a pre-commit hook to check if the files I'm about to commit are locked. If not, then lock them immediately. If they are though, check if I'm the lock owner. If I'm not, abort the commit.

Does anyone have any clues of how to achieve something like this?

After a lot of research, trial and error finally got something that WORKS!! 😀 I added all these comments so ppl can understand my logic, as I still believe it can be improved.

EDIT 1: created a gist to host the file, to keep track of any improvements made to it pre-commit gist

For instance, I'm accessing the remote repo once per file. When the round-trip is long that's quite inefficient if the commit contains several .uasset files. Instead, it would be cool to batch all files info request on a single svn info request. I don't know if that's possible.

Also, the way I'm grabbing the Lock owner username is too hacky, but at least it does the trick for my case. Couldn't succeed to grab a string from between two single quotes on the second grep. Instead, I'm matching the username pattern which of course only works in my scenario where all svn usernames used in my company are of the form 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

Super open to improvements! Please suggest them in the comments

Regarding locking, you can use " What is the best way to see what files are locked in Subversion? ", meaning svnadmin lslocks which does list locked files and their owner. (also, locally, svn status --show-updates )

Compare it, in your pre-commit hook , to the list given by git diff --cached --name-status .
For any file not locked, a svn proplist -v would display its owner.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM