push
command is executed on the server, then the update
file in the hooks
subdirectory of the repository directory is responsible for this. This file is launched by the system for each branch pushed to the server.update
takes the following parameters:push
going;push
occurs;push
; 1 — disable push
. In this case, the entire output of the script to the standard output stream is returned to the client. projectName-taskId action annotation detailsString1 detailsString2 ... detailsStringN
projectName-taskId
- link to the issue in Jira;action
- short designation of the essence of the commit using words from the list of valid options: feature, fix, style, refactor, etc. If two or more variants fit the commit, words are separated by a slash (for example, fix / refactor);annotation
- a brief description of changes in commit;details
is an optional section. This is a detailed description of changes in commit (maximum length of lines - 80 characters). This section of the message can be divided into blocks, between which an empty line is put;annotation
and details
.push
command (this can be done using the git rev-list
command);git cat-file
and the sed text flow editor) and checking the format (using a regular expression and checking the strings for length);push
was rejected. import sys ... if __name__ == "__main__": sys.exit(main())
__name__
is a built-in attribute of the module; in the case of running the script from the command line, this attribute is set to the special value __main__
. If a module is imported by another module, __name__
will contain the name of the file being imported. Due to the above conditional expression, the file can be used both as a module and as a stand-alone script. sys.exit()
returns the sys.exit()
code of the script, which in turn is returned by the main()
function that contains the main logic. import subprocess ... def runBash(commandLine): process = subprocess.Popen(commandLine, shell=True, stdout=subprocess.PIPE) out = process.stdout.read().strip() return out
subprocess.Popen()
creates a child process by launching a program, information about which is passed in arguments. In this case, the standard command shell is started (bash by default for Unix systems), the commandLine
string is sent to it for execution, the text result of the command execution is sent to the channel opened by the child process, the contents of which are returned by the function. strip()
returns a copy of the string without leading and trailing whitespace.runBash()
function, you just need to get a list of commits: import sys ... COMMAND_LIST = "git rev-list {}..{}" ... def main(): refOld = sys.argv[2] revNew = sys.argv[3] commits = runBash(COMMAND_LIST.format(refOld, revNew)).split("\n") ... for commit in commits: ...
sys.argv
array contains command line arguments passed to Git. Using the powerful function format()
in this case, the substitution of arguments into a string takes place.git config --add project.name HABR
command git config --add project.name HABR
COMMAND_PROJECT_NAME = "git config project.name" ... def getProjectName(): return runBash('git config project.name')
COMMAND_COMMIT_MESSAGE = "git cat-file commit {} | sed '1,/^$/d'" ... def checkCommit(hash): commitMessage = runBash(COMMAND_COMMIT_MESSAGE.format(hash)) return checkMessage(commitMessage)
import re ... def checkFirstLine(line): ... expression = r"^({0}\-\d+ )?({1})(\/({1}))* .*".format( getProjectName(), AVAILABLE_ACTIONS ) if not re.match(expression, line): ...
#!/usr/local/bin/python # -*- coding: utf-8 -*-
decode()
: if len(line.decode("utf-8")) > LENGTH_MAX: ...
push
, the following error message was received: fatal: Invalid revision range 0000000000000000000000000000000000000000..b12e460740edf4ea41984a676834bee71479aa52
git rev-list
command is not designed for this, it was necessary to handle the situation in a special way: import sys ... COMMAND_LIST = "git rev-list {}..{}" COMMAND_FOR_EACH = "git for-each-ref --format='%(objectname)' 'refs/heads/*'" COMMAND_LOG = "git log {} --pretty=%H --not {}" ... ref = sys.argv[1] refOld = sys.argv[2] revNew = sys.argv[3] if refOld == REF_EMPTY: headList = runBash(COMMAND_FOR_EACH) heads = headList.replace(ref + "\n", "").replace("\n", " ") commits = runBash(COMMAND_LOG.format(revNew, heads)).split("\n") else: commits = runBash(COMMAND_LIST.format(refOld, revNew)).split("\n")
usage: git cat-file (-t|-s|-e|-p|<type>|--textconv) <object> or: git cat-file (--batch|--batch-check) < <list_of_objects>
for commit in commits: if len(commit) == 0: sys.exit(0)
# -*- coding: utf-8 -*-
and calls to decode()
?).Source: https://habr.com/ru/post/192190/
All Articles