Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git提交带有预提交钩子,为什么会得到不同的结果?_Git_Git Commit_Pre Commit Hook - Fatal编程技术网

Git提交带有预提交钩子,为什么会得到不同的结果?

Git提交带有预提交钩子,为什么会得到不同的结果?,git,git-commit,pre-commit-hook,Git,Git Commit,Pre Commit Hook,我有一个pre-commit钩子来运行python脚本,该脚本将修改暂存文件,并在脚本末尾使用git add.重新添加这些文件 预提交过程如下所示: #!/bin/sh python2.7 .git/hooks/editfile.py import os import mmap import sys import subprocess def getmodifiedfiles(): files = [] args = ['git', 'diff', 'HEAD', '--name-o

我有一个pre-commit钩子来运行python脚本,该脚本将修改暂存文件,并在脚本末尾使用
git add.
重新添加这些文件

预提交过程如下所示:

#!/bin/sh
python2.7 .git/hooks/editfile.py
import os
import mmap
import sys
import subprocess

def getmodifiedfiles():
  files = []
  args = ['git', 'diff', 'HEAD', '--name-only', '-r', '--diff-filter=M']
  with open(os.devnull, 'w') as b:
     files = subprocess.check_output(args, stderr=b).splitlines()

  files = [i for i in files if os.path.isfile(i)]
  return files

def updaterevision(line):
    strVer = line.split("$Revision: ")[1].split()[0]
    version = [x for x in strVer.split('.')]
    ver = [int(i) for i in version]

    if ver[1] == 99:
      ver[0] += 1
      ver[1] = 0
    else:
      ver[1] += 1

    strVer = "%d.%02d" % (ver[0], ver[1])
    return str.replace(line, line.split("$Revision: ")[1].split()[0], strVer)

def main(args):
  filelist = getmodifiedfiles()  
  
  for file in filelist :
    lines = open(file).readlines()

    i = 0
    for line in lines:
        if '$Revision:' in line:
          lines[idx] = updaterevision(line)
        
        i += 1

  with open(file, 'w') as r:
    r.writelines(lines)          

  args = ['git', 'add', '.']
  subprocess.call(args)
  
if __name__ == '__main__':
    main(sys.argv)
python脚本如下所示:

#!/bin/sh
python2.7 .git/hooks/editfile.py
import os
import mmap
import sys
import subprocess

def getmodifiedfiles():
  files = []
  args = ['git', 'diff', 'HEAD', '--name-only', '-r', '--diff-filter=M']
  with open(os.devnull, 'w') as b:
     files = subprocess.check_output(args, stderr=b).splitlines()

  files = [i for i in files if os.path.isfile(i)]
  return files

def updaterevision(line):
    strVer = line.split("$Revision: ")[1].split()[0]
    version = [x for x in strVer.split('.')]
    ver = [int(i) for i in version]

    if ver[1] == 99:
      ver[0] += 1
      ver[1] = 0
    else:
      ver[1] += 1

    strVer = "%d.%02d" % (ver[0], ver[1])
    return str.replace(line, line.split("$Revision: ")[1].split()[0], strVer)

def main(args):
  filelist = getmodifiedfiles()  
  
  for file in filelist :
    lines = open(file).readlines()

    i = 0
    for line in lines:
        if '$Revision:' in line:
          lines[idx] = updaterevision(line)
        
        i += 1

  with open(file, 'w') as r:
    r.writelines(lines)          

  args = ['git', 'add', '.']
  subprocess.call(args)
  
if __name__ == '__main__':
    main(sys.argv)
当git status I得到以下结果时,它可以使用
git commit-m“msg”
命令正常工作:

On branch master
Your branch is ahead of 'origin/master' by 1 commit.

nothing to commit (working directory clean)
但是如果使用
git commit
git commit-m“msg”
进行提交,我会得到以下我不想要的结果:

On branch master
Changes to be committed:
   (use "git reset HEAD <file>..." to unstage)

   modified:   filename.py

Changes not staged for commit:
   (use "git add <file>..." to update what will be committed)
   (use "git checkout -- <file>..." to discard changes in working directory)

   modified:   filename.py
分支主机上的

要提交的更改:
(使用“git重置磁头…”取消分级)
修改:filename.py
未为提交而暂存的更改:
(使用“git add…”更新将提交的内容)
(使用“git签出--…”放弃工作目录中的更改)
修改:filename.py

有什么不同?我不想让用户只使用第一个命令进行提交。有什么想法吗?

不幸的是,使用文件重写预提交钩子,您唯一能做的就是远离
git commit
,只使用
git add
-然后-
git commit

也就是说,你并没有完全失去希望。由于钩子脚本用于重写文件(设置“版本信息”),因此使用过滤器是一个更好的主意

请查看以下答案:


基本上,您可以将脚本设置为“干净过滤器”,以便在匹配文件被暂存时应用它。这包括您的
git提交的用例

您能提供钩子脚本吗?这很重要。按照@iBug所说的,你能提供完整的脚本吗?我不太愿意将其作为副本关闭,但请看。我尝试了git config--global filter.updateHeader.clean editfile.py,然后我遇到了以下错误:无法fork运行外部过滤器“editfile.py”和外部过滤器“editfile.py”失败。我应该将editfile.py放置在哪里?@hexacool路径应该相对于“项目根目录”,即
.git
目录所在的位置。如果您不确定,请使用绝对路径。我将脚本文件放在项目根目录下,它无法工作。尝试了绝对路径,它显示致命:cannot exec:/home/username/projectname/editfile.py”:运行脚本时权限被拒绝。@很明显您忘记了
chmod 755
或类似内容。