Is there a way to write a pre-commit git binding to stop commits with the same name, with the only difference being upper and lower case.
eg,
branch name 1: firstBranch
branch name 2: FirstBrancH
branch name 3: firsTbranch
but branch name: firstbranchname must be resolved.
if the commit is performed at time T for the firstBranch branch name, then in T + n, Commit with the branch name "FirstBrancH" or any combination, git pre-hook does not allow the commit. This should be a server hook, as client hooks can be easily pypassed.
so my thoughts are:
so I get the $ NAME of the branch that is assigned, and then compare it with ALL branches that ignore CASE, and DENY it with the message if the match passes.
I have a pre-receive hook setting on the gitlab server:
#!/bin/bash check_dup_branch=`git branch -a | sed 's; remotes/origin/;;g' | tr '[:upper:]' '[:lower:]' | uniq -d` if [ check_dup_branch ] then echo "Duplicate CaseInsensitive Branch Name Detected" exit 1 fi exit 0
according to instructions:
Select a project that requires a custom git hook.
On the GitLab server, navigate to the project repository directory. For installation from the source, the path is usually / home / git / repositories //. Git. To install Omnibus, the path is usually / var / opt / gitlab / git -data / repositories //. Git.
Create a new directory in this place called custom_hooks.
Inside the new custom_hooks directory, create a file with a name that matches the hook type. For pre-reception, the file name must be pre-obtained without the extension.
Make the hook executable and make sure it belongs to git.
Write code to make the hook git function as expected. Hooks can be in any language. Make sure the "shebang" at the top correctly reflects the type of language. For example, if the script is in Ruby, shebang will probably be #! / Usr / bin / env ruby.
But it does not work as expected.
if I click aaa when AAA is already in gitlab, it gives me an error:
remote: Duplicate CaseInsensitive Branch Name Detected
but it also gives me the same βduplicateβ message when I try to push the bbb branch
I expect it to not commit if the branch name is duplicated), ignoring case)
After a bit more study on git hooks:
ref: If you want to accept or reject branches in each case, you need to use the update hook instead.
when hook update:
#!/usr/bin/python import sys print "Testing pre-receive Hook in Python" branch = sys.argv[1] print "Branch '%s' pushing" %(branch) sys.exit(0)
git push origin AAA
Total 0 (delta 0), reused 0 (delta 0) remote: Testing pre-receive Hook in Python remote: Branch 'refs/heads/AAA' pushing
now we need to compare how grep -i, git branch -a and make uniq -d with aaa, after the lower ALL casing
and then comparing, and IF there is MATCH, call sys.exit (1)
DO NOT allow click
python update hook:
#!/usr/bin/python import sys import subprocess #print "Testing pre-receive Hook" branch = sys.argv[1] old_commit = sys.argv[2] new_commit = sys.argv[3] #print "Moving '%s' from %s to %s" % (branch, old_commit, new_commit) #print "Branch '%s' pushing" %(branch) #print "old_commit '%s' pushing" %(old_commit) #print "new_commit '%s' pushing" %(new_commit) def git(*args): return subprocess.check_call(['git'] + list(args)) if __name__ == "__main__": #git("status") #git("for-each-ref" , "refs/heads/" , "--format='%(refname:short)'") git("for-each-ref" , "--format='%(refname:short)'") sys.exit(0)
further improvement in python update cache:
#!/usr/bin/python import sys import subprocess #print "Testing pre-receive Hook" branch = sys.argv[1] old_commit = sys.argv[2] new_commit = sys.argv[3] # order is important, for update hook: refname oldsha1 newsha1 print "Moving '%s' from %s to %s" % (branch, old_commit, new_commit) print "Branch '%s' " %(branch) print "old_commit '%s' " %(old_commit) print "new_commit '%s' " %(new_commit) def git(*args): return subprocess.check_call(['git'] + list(args)) #if %(branch).lower() in []array of results from the git for-each-ref #sys.exit(1) def get_name(target): p = subprocess.Popen(['git', 'for-each-ref', 'refs/heads/'], stdout=subprocess.PIPE) for line in p.stdout: sha1, kind, name = line.split() if sha1 != target: continue return name return None if __name__ == "__main__": #git("status") #git("for-each-ref" , "refs/heads/" , "--format='%(refname:short)'") #cmd = git("for-each-ref" , "--format='%(refname:short)'") cmd = git("for-each-ref" , "--format='%(refname:short)'") #print cmd #print get_name(branch) #print get_name(old_commit) print get_name(new_commit) sys.exit(0)
therefore, the rejection case, of course, compares the current% (branch) or% (refname: short) and compares it with all existing names in the IgnoreCase method, and if it is found (1 or many), then run the sys.exit (1) command with message "Duplicate branch name"
but currently i am getting:
remote: Moving 'refs/heads/IIII' from 0000000000000000000000000000000000000000 to 4453eb046fe11c8628729d74c3bec1dd2018512e remote: Branch 'refs/heads/IIII' remote: old_commit '0000000000000000000000000000000000000000' remote: new_commit '4453eb046fe11c8628729d74c3bec1dd2018512e' remote: refs/heads/10B
and somehow remote: refs / heads / 10B remains static. so I'm not sure how I can convert the result:
cmd = git("for-each-ref" , "--format='%(refname:short)'")
to a list or array, and then perform a string comparison between each element and remote: Branch 'refs / heads / IIII'