转自:http://java.dzone.com/articles/useful-subversion-pre-commit

  1. Checks whether the commit message is not empty
  2. Checks whether the commit message consists of at least 5 characters
  3. Checks if the committed files are UTF-8 compliant
  4. Checks whether the svn:eol-style property is set to LF on newly added files
  5. Checks if the committed files have no TAB characters

The UTF-8 and TAB checks are performed on the following file suffixes

  • *.java
  • *.js
  • *.xhtml
  • *.css
  • *.xml
  • *.properties (only check for TABs here, no check for UTF-8 compliance)

翻译一下:

  1. 检查提交日志是否为空
  2. 检查提交日志最少需要N个字符
  3. 检查提交文件是否是UTF-8格式
  4. 检查新文件的换行模式是否为LF
  5. 检查提交的文件是否含有TABs换行符

检查UTF-8编码和TABs换行符只针对以下后缀文件:

  • *.java
  • *.js
  • *.xhtml
  • *.css
  • *.xml
  • *.properties (只检查TABs,不检查UTF-8)

以下是代码

注意:针对Linux

#!/bin/bash

REPOS="$1"
TXN="$2"


# Make sure that the log message contains some text.
SVNLOOK=/usr/bin/svnlook
ICONV=/usr/bin/iconv

SVNLOOKOK=1
LOGMSG=`$SVNLOOK log -t "$TXN" "$REPOS" | wc -c` 
if [ "$LOGMSG" -lt 2 ];
then
   echo -e "\t That logmessage contains at least 2 alphanumeric characters. Commit aborted!" 1>&2
  exit 1
fi


# Make sure that all files to be committed are encoded in UTF-8.
while read changeline; 
do

  # Get just the file (not the add / update / etc. status).
  file=${changeline:4}

  # Only check source files.
  if [[ $file == *.java || $file == *.xhtml || $file == *.css || $file == *.xml || $file == *.js ]] ; then
    $SVNLOOK cat -t "$TXN" "$REPOS" "$file" | $ICONV -f UTF-8 -t UTF-8 -o /dev/null
    if [ "${PIPESTATUS[1]}" != 0 ] ; then
      echo "Only UTF-8 files can be committed ("$file")" 1>&2
      exit 1
    fi
  fi
done < <($SVNLOOK changed -t "$TXN" "$REPOS")

# Check files for svn:eol-style property
# Exit on all errors.
set -e
EOL_STYLE="LF"
echo "`$SVNLOOK changed -t "$TXN" "$REPOS"`" | while read REPOS_PATH
do
 if [[ $REPOS_PATH =~ A[[:blank:]]{3}(.*)\.(java|css|properties|xhtml|xml|js) ]]
 then
  if [ ${#BASH_REMATCH[*]} -ge 2 ]
    then
  FILENAME=${BASH_REMATCH[1]}.${BASH_REMATCH[2]};

  # Make sure every file has the right svn:eol-style property set
   if [ $EOL_STYLE != "`$SVNLOOK propget -t \"$TXN\" \"$REPOS\" svn:eol-style \"$FILENAME\" 2> /dev/null`" ]
    then
    ERROR=1;
      echo "svn ps svn:eol-style $EOL_STYLE \"$FILENAME\"" >&2
   fi
  fi
 fi
 test -z $ERROR || (echo "Please execute above commands to correct svn property settings. EOL Style LF must be used!" >& 2; exit 1)
done



# Block commits with tabs
# This is coded in python
# Exit on all errors
set -e

$SVNLOOK diff -t "$TXN" "$REPOS" | python /dev/fd/3 3<<'EOF'
import sys
ignore = True
SUFFIXES = [ ".java", ".css", ".xhtml", ".js", ".xml", ".properties" ]
filename = None

for ln in sys.stdin:

    if ignore and ln.startswith("+++ "):
        filename = ln[4:ln.find("\t")].strip()
        ignore = not reduce(lambda x, y: x or y, map(lambda x: filename.endswith(x), SUFFIXES))

    elif not ignore:
        if ln.startswith("+"):
        
           if ln.count("\t") > 0:
              sys.stderr.write("\n*** Transaction blocked, %s contains tab character:\n\n%s" % (filename, ln))
              sys.exit(1)

        if not (ln.startswith("@") or \
           ln.startswith("-") or \
           ln.startswith("+") or \
           ln.startswith(" ")):

           ignore = True

sys.exit(0)
EOF

# All checks passed, so allow the commit.
exit 0

如何使用

  1. 重命名hooks文件夹下pre-commit.tmplpre-commit
  2. 修改文件内容
  3. 将文件变为可执行 chmod +x pre-commit

提交完代码自动更新

vim hooks/post-commit

#!/bin/sh
export LANG=zh_CN.UTF-8  # 设置UTF-8编码
SVN=/usr/bin/svn         # 这里配置的是svn安装bin目录下的svn文件
WEB=/var/www/html      # 要更新的目录
$SVN update $WEB --username xxxx --password xxxx

转自: http://openwares.net/linux/python_os_version_platform.html

platform模块提供了底层系统平台的相关信息

系统架构

32位还是64位

>>> import platform
>>> platform.architecture()
('64bit', 'ELF') # python 3.3.2+ 64 bits on debian jessie 64 bits
('32bit', 'WindowsPE') # python 3.3.2 32 bits on windows 8.1 64 bits
('64bit', 'WindowsPE') # python 3.3.2 64 bits on wndows 8.1 64 bits
('64bit', '') # python 3.4.1 64 bits on mac os x 10.9.4
ELF和WindowsPE是可执行文件格式

操作系统

linux,mac还是windows

>>> platform.system()
'Linux' # python 3.3.2+ 64 bits on debian jessie 64 bits
'Windows' # python 3.3.2 32 bits on windows 8.1 64 bits
'Windows' # python 3.3.2 64 bits on windows 8.1 64 bits
'Darwin' # python 3.4.1 64 bits on mac os x 10.9.4

系统版本

>>> platform.version()
'#1 SMP Debian 3.10.11-1 (2013-09-10)' # python 3.3.2+ 64 bits on debian jessie 64 bits
'6.2.9200' # python 3.3.2 32 bits on windows 8.1 64 bits
'6.2.9200' # python 3.3.2 64 bits on windows 8.1 64 bits
'Darwin Kernel Version 13.3.0: Tue Jun  3 21:27:35 PDT 2014; root:xnu-2422.110.17~1/RELEASE_X86_64' # python 3.4.1 64 bits on mac os x 10.9.4

CPU平台

>>> platform.machine()
'x86_64' # python 3.3.2+ 64 bits on debian jessie 64 bits
'AMD64' # python 3.3.2 32 bits on windows 8.1 64 bits
'AMD64' # python 3.3.2 64 bits on windows 8.1 64 bits
'x86_64' # python 3.4.1 64 bits on mac os x 10.9.4

linux发行版

>>> platform.dist()
('debian', 'jessie/sid', '') # python 3.3.2+ 64 bits on debian jessie 64 bits

节点名

也就是机器名

>>> platform.node()
'work' # python 3.3.2+ 64 bits on debian jessie 64 bits
'work-xxx' # python 3.3.2 32 bits on windows 8.1 64 bits

系统信息

>>> platform.uname()
uname_result(system='Linux', node='work', release='3.10-3-amd64', version='#1 SMP Debian 3.10.11-1 (2013-09-10)', machine='x86_64', processor='') # python 3.3.2+ 64 bits on debian jessie 64 bits
 
uname_result(system='Windows', node='work-xxx', release='8', version='6.2.9200', machine='AMD64', processor='Intel64 Family 6 Model 58 Stepping 9,
GenuineIntel') # python 3.3.2 32 bits on windows 8.1 64 bits
 
uname_result(system='Darwin', node='mba', release='13.3.0', version='Darwin Kernel Version 13.3.0: Tue Jun  3 21:27:35 PDT 2014; root:xnu-2422.110.17~1/RELEASE_X86_64', machine='x86_64', processor='i386') # python 3.4.1 64 bits on mac os x 10.9.4

python版本

>>> platform.python_verison()
'3.3.2+' # python 3.3.2+ 64 bits on debian jessie 64 bits
'3.3.3' # python 3.3.2 32 bits on windows 8.1 64 bits

python中浅拷贝和深拷贝

今天写python脚本,遇到了一个问题。先贴代码:

#coding=utf-8
new_list = []               # 声明一个list
tmp = {'a':123,'b':'ccc'}   # 新建一个dict
new_list.append(tmp)        # 追加
print tmp
print new_list
tmp['a'] = 456              # 修改tmp
tmp['b'] = 'ddd'
new_list.append(tmp)        # 追加
print tmp
print new_list

# 执行结果:

{'a': 123, 'b': 'ccc'}
[{'a': 123, 'b': 'ccc'}]    # 当改变了tmp,list中的值也会变化
{'a': 456, 'b': 'ddd'}
[{'a': 456, 'b': 'ddd'}, {'a': 456, 'b': 'ddd'}]

如果是PHP会发生什么?

$b = array();
$a = array('b'=>123);
array_push($b , $a);
$a = array('b'=>456);
array_push($b , $a);
var_dump($b);

$a = new ArrayObject(array('b'=>123));
$arr = new ArrayObject();
$arr->append($a);
$a['b'] = 456;
$arr->append($a);
var_dump($arr);

# 执行结果

array(2) {
  [0]=>
  array(1) {
    ["b"]=>
    int(123)
  }
  [1]=>
  array(1) {
    ["b"]=>
    int(456)
  }
}
object(ArrayObject)#2 (1) {
  ["storage":"ArrayObject":private]=>
  array(2) {
    [0]=>
    object(ArrayObject)#1 (1) {
      ["storage":"ArrayObject":private]=>
      array(1) {
        ["b"]=>
        int(456)
      }
    }
    [1]=>
    object(ArrayObject)#1 (1) {
      ["storage":"ArrayObject":private]=>
      array(1) {
        ["b"]=>
        int(456)
      }
    }
  }
}

由结果看,PHP中array_push方法和array_object的结果也不同。

为什么会这样呢?

这里就要讲讲浅拷贝和深拷贝了。

以python为例,当执行new_list.append(tmp)方法时,append方法仅仅把tmp变量的内存地址交给了new_list,而不是新建了一个与tmp一模一样的变量(内存中的地址不同,属性几乎一样),即浅拷贝。这就解释了,当改变了tmp的值后new_list中保存的tmp也会随之改变,因为他们都是一样一样的。

需要注意的是,python中非容器类没有拷贝这一说,还有一些坑在这里可以看到。

引用的能省下不少内存空间,但是会给新手造成迷惑。

PHP中的array_push方法,就会做一次深拷贝,创建了新的变量,所以不论怎么修改传入的$a,都不会影响最终得到两个不同的数组。而使用了数组对象做同样的事,就会出现和python一样的浅拷贝现象。

那么如何解决之前的问题呢?

python的做法是引入标准库中的copy模块。

import copy

copy.copy(x)
# 返回一个x的浅复制。

copy.deepcopy(x)
# 返回一个x的深复制。

exception copy.error
# copy异常

将之前的python代码改为:

#coding=utf-8
import copy
new_list = []               # 声明一个list
tmp = {'a':123,'b':'ccc'}   # 新建一个dict
new_list.append(tmp)        # 追加
print tmp
print new_list
tmp = copy.deepcopy(tmp)
tmp['a'] = 456              # 修改tmp
tmp['b'] = 'ddd'
new_list.append(tmp)        # 追加
print tmp
print new_list

PHP5中对象的赋值和传值都是以“引用”的方式,解决对象深拷贝采用的clone语言结构,有兴趣的TX可以参考php深复制和浅复制

扩展阅读:

http://blog.csdn.net/dizzthxl/article/details/7688744 http://bbs.chinaunix.net/thread-1787290-1-1.html http://www.jb51.net/article/54266.htm http://blog.csdn.net/dizzthxl/article/details/7688744 http://www.cnblogs.com/windlaughing/archive/2013/05/26/3100362.html

  1. 调用phpcms/modules/member/index.php中login。

  2. 读取caches/configs/system.php中phpsso的配置。

  3. 调用phpcms/modules/member/classes/client.class.php的_ps_post()发送登录信息。

  4. 该请求被发送到phpsso_server/phpcms/modules/phpsso/index.php的login方法。

  5. phpsso读取数据库配置phpsso_server/caches/configs/database.php,连接数据库,执行登陆逻辑

  6. 返回登录结果

GIT虽然概念比较难理解,但不得不说他是一款开发利器。

老高总结出了一些GIT中很常见的操作命令,分享给大家。但由于GIT命令繁多,所以我将分为基础和进阶两部分。

基础篇:

帮助

git help # 获取帮助,内容如下

usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path]
           [-p|--paginate|--no-pager] [--no-replace-objects]
           [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]
           [--help] COMMAND [ARGS]

The most commonly used git commands are:
   add        Add file contents to the index
   bisect     Find by binary search the change that introduced a bug
   branch     List, create, or delete branches
   checkout   Checkout a branch or paths to the working tree
   clone      Clone a repository into a new directory
   commit     Record changes to the repository
   diff       Show changes between commits, commit and working tree, etc
   fetch      Download objects and refs from another repository
   grep       Print lines matching a pattern
   init       Create an empty git repository or reinitialize an existing one
   log        Show commit logs
   merge      Join two or more development histories together
   mv         Move or rename a file, a directory, or a symlink
   pull       Fetch from and merge with another repository or a local branch
   push       Update remote refs along with associated objects
   rebase     Forward-port local commits to the updated upstream head
   reset      Reset current HEAD to the specified state
   rm         Remove files from the working tree and from the index
   show       Show various types of objects
   status     Show the working tree status
   tag        Create, list, delete or verify a tag object signed with GPG

配置git

# 查看配置
git config -l/--list

# 以下是可能出现的配置
core.symlinks=false
core.autocrlf=true
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=true
pack.packsizelimit=2g
help.format=html
...
...

# 配置全局信息
git config --global user.name=phpgao

# 配置局部信息
git config --system [email protected]

# 查看某一个配置信息
git config user.email

初始化仓库

git init # 在当前目录初始化一个git仓库

git init --bare # 在当前目录初始化一个git裸仓库

查看

git status # 显示工作流中的状态

git diff # 显示工作目录(Working tree)和暂存区域快照(index)之间的差异

git diff --stat # 简报

git diff --cached # 显示已经暂存起来的文件(staged)和上次提交时的快照之间(HEAD)的差异

git diff --staged # 下一次commit时会提交到HEAD的内容(不带-a情况下)

git diff dev # 比较当前目录和dev分支 

git diff HEAD # 工作目录和HEAD的差别

git diff HEAD^ HEAD # 比较上次和上上次提交的不同

git diff dev master # 比较两个分支最新提交

git diff dev..master # 同上

git diff dev...master # 比较从分支开始时至今所有的修改

git log --pretty=oneline # 显示日志

### 美化格式一

git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short

### 美化格式二

git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative 

增删提

先读懂这个图

提交关系图

git add # 添加工作区修改的文件提交至Stage(index)

git commit -m "comment" # 将Stage(index)中的文件提交至本地库中(commit),并添加注释

git commit -am "comment" # 省略了add步骤,直接提交Working Directory和Stage(index)中的内容

git rm <文件名> # 删除库中的文件

git reset --hard # 恢复最近一次提交过的状态,即放弃上次提交后的所有本次修改

git reset -- . # 从暂存区恢复到工作文件

分支与合并

git branch <分支名> <老分支名># 根据分支创建新分支

git branch -r # 查看远程分支

git branch -v # 查看各分支最近的提交

git branch -d <分支名> # 删除一个分支

git br -D <分支名> # 强制删除某个分支 (未被合并的分支被删除的时候需要强制)

git branch -m <分支名> <新分支名> # 重命名一个分支

git checkout <分支名> # 切换至某分支

git checkout -b <分支名> # 创建并切换至新分支

git merge dev # 将当前分支与dev分支合并

git merge dev --no-ff # 不使用Fast-Foward合并,为了保持项目的清晰的轨迹,推荐合并时使用此选项

这里前者到一个概念叫分支策略,可以参考这篇文章Git分支管理策略

远程操作

clone

git clone /xx/xxx/xxx.git # 克隆某个项目

git支持很多协议,如ssh、git、https等。

remote

git remote -v # 查看远程库

git remote add origin xxxx.git # 添加一个远程主机

git remote rm # 删除一个远程主机

fetch

git fetch <远程主机名> # 取回所有信息

git fetch <远程主机名> <分支名> # 只取回某分支

git branch -a # 查看所有分支

git branch -r # 查看远程分支

pull

git push 

push


jetbrains系列软件问题

GIT Remotes "Can't push, because no remotes are defined"

软件中没有添加remote的功能,所以如果你要新加入一个远程库就需要在terminal中使用以下命令

git remote add origin "path to .git" 

fatal: No existing author found with 'john doe'

先使用git config -l查看配置,得到name和email如下

user.name=aaa user.email=[email protected]

软件配置里填入

aaa [email protected]

这样软件转化的命令就变成

git commit --author="aaa " -m "Note"

参考:

https://ruby-china.org/topics/939

Error:Execution failed for task ':app:processDebugManifest'. > Manifest merger failed : uses-sdk:minSdkVersion 8 cannot be smaller than version L declared in library com.android.support:support-v4:21.0.0-rc1

解决方式: 1、Change compile 'com.android.support:support-v4:+' to compile 'com.android.support:support-v4:20.+' in build.gradle. This will prevent gradle from using v4:21.0.0 that requires version L. 2、Remove/Comment 21.0.0-rc1 in your file /extras/android/m2repository/com/android/support-v4/maven-metadata.xml

Failed to import Gradle project: Could not fetch model of type 'IdeaProject' using Gradle distribution 'http://services.gradle.org/distributions/gradle-1.6-bin.zip'.

解决方法:先从网页上将其下载下来,然后将其解压到任何位置,在环境变量path下配置路径(到gradle的bin目录),可通过cmd命令 gradle -v验证是否成功。

"Could not find any version that matches com.android.support:support-v4:13.0.+"

解决方法:通过SDK Manage 安装Android Support Repository

Connection to https://dl-ssl.google.com refused

解决方法:找到C:\WINDOWS\system32\drivers\etc中的hosts文件,添加74.125.237.1 dl-ssl.google.com保存退出

通过菜单help->install update ,无法更新 Android Studio

解决办法:找到其目录下bin-studio.exe.vmoptions,添加:

-Didea.updates.url=https://dl.google.com/android/studio/patches/updates.xml
-Didea.patches.url=https://dl.google.com/android/studio/patches/

错误:svn: E175002: handshake alert: unrecognized_name

解决方法:在Studio程序bin文件夹下的studio.vmoptions添加

-Dsvnkit.http.sslProtocols=SSLv3
-Djsse.enableSNIExtension=false

Manifest merging failed

解决方法:在build.gradle文件中 将AndroidMainfest.xml对应的版本号,版本名补充完整

转自:http://waychel.com/shi-yong-android-studioke-neng-hui-yu-dao-de-wen-ti/