由于OS X升级到了最新,cornerStone在我的mac上无法使用,正版又太贵,所以选择使用XCode8自带的SVN,下面介绍一下集成SVN过程,以及遇到的坑。
使用Xcode自带的SVN管理工具会遇到一个坑,建议阅读本篇内容之前先跳到文章末尾的补充部分,先看完补充部分的内容,了解一下这个坑再回来。可以直接跳到文章末尾看最新的集成方法,或者是安装cornerstone的方法。
1.打开需要上传SVN的工程
选择菜单栏的Source Control
按钮,在弹出的子菜单中选择check out
,如图一所示。
在仓库地址的输入框中填入SVN的地址,如图二所示。
2.checkout项目到本地
在checkout之前,要确保你的工程的根目录下有个三个空文件夹(图三),XCode采用git的文件架构,如果想要使用XCode的branch、tag、trunk相关功能,就需要进行文件夹绑定(后面会讲到)。
选择目标后(空工程只有trunk分支)点击next,出现图四
点击next,选择保存到本地的路径如图五
最后会在上一步所选的文件夹中生成一个.svn文件夹(图六)
3.忽略文件
找到config.文件(图七),将下面内容覆盖即可,或者百度一下:"xcode svn忽略文件"
### This file configures various client-side behaviors.
###
### The commented-out examples below are intended to demonstrate
### how to use this file.
### Section for authentication and authorization customizations.
[auth]
### Set password stores used by Subversion. They should be
### delimited by spaces or commas. The order of values determines
### the order in which password stores are used.
### Valid password stores:
### gnome-keyring (Unix-like systems)
### kwallet (Unix-like systems)
### keychain (Mac OS X)
### windows-cryptoapi (Windows)
# password-stores = keychain
### To disable all password stores, use an empty list:
# password-stores =
###
### The rest of the [auth] section in this file has been deprecated.
### Both 'store-passwords' and 'store-auth-creds' can now be
### specified in the 'servers' file in your config directory
### and are documented there. Anything specified in this section
### is overridden by settings specified in the 'servers' file.
# store-passwords = no
# store-auth-creds = no
### Section for configuring external helper applications.
[helpers]
### Set editor-cmd to the command used to invoke your text editor.
### This will override the environment variables that Subversion
### examines by default to find this information ($EDITOR,
### et al).
# editor-cmd = editor (vi, emacs, notepad, etc.)
### Set diff-cmd to the absolute path of your 'diff' program.
### This will override the compile-time default, which is to use
### Subversion's internal diff implementation.
# diff-cmd = diff_program (diff, gdiff, etc.)
### Diff-extensions are arguments passed to an external diff
### program or to Subversion's internal diff implementation.
### Set diff-extensions to override the default arguments ('-u').
# diff-extensions = -u -p
### Set diff3-cmd to the absolute path of your 'diff3' program.
### This will override the compile-time default, which is to use
### Subversion's internal diff3 implementation.
# diff3-cmd = diff3_program (diff3, gdiff3, etc.)
### Set diff3-has-program-arg to 'yes' if your 'diff3' program
### accepts the '--diff-program' option.
# diff3-has-program-arg = [yes | no]
### Set merge-tool-cmd to the command used to invoke your external
### merging tool of choice. Subversion will pass 5 arguments to
### the specified command: base theirs mine merged wcfile
# merge-tool-cmd = merge_command
### Section for configuring tunnel agents.
[tunnels]
### Configure svn protocol tunnel schemes here. By default, only
### the 'ssh' scheme is defined. You can define other schemes to
### be used with 'svn+scheme://hostname/path' URLs. A scheme
### definition is simply a command, optionally prefixed by an
### environment variable name which can override the command if it
### is defined. The command (or environment variable) may contain
### arguments, using standard shell quoting for arguments with
### spaces. The command will be invoked as:
### <command> <hostname> svnserve -t
### (If the URL includes a username, then the hostname will be
### passed to the tunnel agent as <user>@<hostname>.) If the
### built-in ssh scheme were not predefined, it could be defined
### as:
# ssh = $SVN_SSH ssh -q
### If you wanted to define a new 'rsh' scheme, to be used with
### 'svn+rsh:' URLs, you could do so as follows:
# rsh = rsh
### Or, if you wanted to specify a full path and arguments:
# rsh = /path/to/rsh -l myusername
### On Windows, if you are specifying a full path to a command,
### use a forward slash (/) or a paired backslash (\\) as the
### path separator. A single backslash will be treated as an
### escape for the following character.
### Section for configuring miscelleneous Subversion options.
[miscellany]
### Set global-ignores to a set of whitespace-delimited globs
### which Subversion will ignore in its 'status' output, and
### while importing or adding files and directories.
### '*' matches leading dots, e.g. '*.rej' matches '.foo.rej'.
global-ignores=build*~.nib*.so*.pbxuser*.mode*.perspective*.DS_Store*.xcuserstate
# *.rej *~ #*# .#* .*.swp *.DS_Store Pods
### Set log-encoding to the default encoding for log messages
# log-encoding = latin1
### Set use-commit-times to make checkout/update/switch/revert
### put last-committed timestamps on every file touched.
# use-commit-times = yes
### Set no-unlock to prevent 'svn commit' from automatically
### releasing locks on files.
# no-unlock = yes
### Set mime-types-file to a MIME type registry file, used to
### provide hints to Subversion's MIME type auto-detection
### algorithm.
# mime-types-file = /path/to/mime.types
### Set preserved-conflict-file-exts to a whitespace-delimited
### list of patterns matching file extensions which should be
### preserved in generated conflict file names. By default,
### conflict files use custom extensions.
# preserved-conflict-file-exts = doc ppt xls od?
### Set enable-auto-props to 'yes' to enable automatic properties
### for 'svn add' and 'svn import', it defaults to 'no'.
### Automatic properties are defined in the section 'auto-props'.
enable-auto-props = yes
### Set interactive-conflicts to 'no' to disable interactive
### conflict resolution prompting. It defaults to 'yes'.
# interactive-conflicts = no
### Set memory-cache-size to define the size of the memory cache
### used by the client when accessing a FSFS repository via
### ra_local (the file:// scheme). The value represents the number
### of MB used by the cache.
# memory-cache-size = 16
### Section for configuring automatic properties.
global-ignores=*.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.pyc *.pyo *.rej *~ #*# .#* .*.swp *.DS_Store *.apk *.ap_ *.dex *.class bin/ gen/ .gradle/ build/ local.properties proguard/ *.log .navigation/ captures/ Pods
[auto-props]
*.mode*=svn:mime-type=text/X-xcode
*.pbxuser=svn:mime-type=text/X-xcode
*.perspective*=svn:mime-type=text/X-xcode
*.pbxproj=svn:mime-type= text/X-xcode
### The format of the entries is:
### file-name-pattern = propname[=value][;propname[=value]...]
### The file-name-pattern can contain wildcards (such as '*' and
### '?'). All entries which match (case-insensitively) will be
### applied to the file. Note that auto-props functionality
### must be enabled, which is typically done by setting the
### 'enable-auto-props' option.
# *.c = svn:eol-style=native
# *.cpp = svn:eol-style=native
# *.h = svn:keywords=Author Date Id Rev URL;svn:eol-style=native
# *.dsp = svn:eol-style=CRLF
# *.dsw = svn:eol-style=CRLF
# *.sh = svn:eol-style=native;svn:executable
# *.txt = svn:eol-style=native;svn:keywords=Author Date Id Rev URL;
# *.png = svn:mime-type=image/png
# *.jpg = svn:mime-type=image/jpeg
# Makefile = svn:eol-style=native
4.配置项目
将项目目录下四个文件夹拖入到sskeychain目录下,如图八
双击sskeychain.xcodeproj用xcode打开,然后点击source control ,选择commit,就可以将项目上传到svn的trunk目录下(图九)(空项目默认提交到trunk目录下)
5.分支与主干
通过选择创建branch可以创建一个新的分支(图十)
New Branch 创建新的分支
Switch to Branch 切换到其它分支
Merge from Branch 从另外的分支合并代码到当前分支
Merge into Branch 将当前分支的代码合并到其它分支中去
6.烦人的UserInterfaceState.xcuserstate
UserInterfaceState.xcuserstate这个东西虽然我在上面设置了忽略它,但是svn依旧不会放过它。由于UserInterfaceState.xcuserstate在你每次改动代码的时候都会更新一次,所以每次要切换分支或者合并的时候就会提示需要先提交代码,不然让继续操作,所以我们需要让svn忽略UserInterfaceState.xcuserstate。
1. cd ~/工程目录/工程名字.xcodeproj/project.xcworkspace/xcuserdata/用户名.xcuserdatad
2. svn rm --force UserInterfaceState.xcuserstate
3. svn update
4. svn commit -m UserInterfaceState.xcuserstate
5. export EDITOR=nano
6. svn propedit svn:ignore . (注意最后面有个点号)
第5步执行之后会出现如下界面(图十一),将UserInterfaceState.xcuserstate粘贴进去之后,按 control + X,然后输入Y确定保存即可
怎么测试成功与否?将上面的指令从头开始执行,到6的时候如果出现的界面和图十三一样,说明UserInterfaceState.xcuserstate已经保存好了,配置了两个项目,其中一个项目会在UserInterfaceState.xcuserstate原本路径下生成一个"svn-prop.tmp.save"文件,另外一个项目没有生成,但是两个项目都达到了忽略UserInterfaceState.xcuserstate文件的效果。
如果通过上面的配置还不能忽略UserInterfaceState.xcuserstate文件,那么就出最后一招了:不要将UserInterfaceState.xcuserstate上传到服务器,没有对比那么就不会有"M",只会显示"?问号是不妨碍切换分支的。
补充一下,可能有的小伙伴在commit的时候会提示权限不够,无法commit成功(我之前采用另一种配置方式的时候就遇到这个问题),我们步奏一填入的SVN地址是https://192.168.1.100/svn/test/jlc/wristband/src/com
,在我们的工程中选择工程SVN的配置信息时,如图十二、十三所示
我们的地址被Xcode自动裁剪剩下https://192.168.1.100/svn/test
,所以SVN在提交的时候是需要登录的,然后Xcode连接的仓库地址便是裁剪之后的地址,如果登录用户没有这个目录级别的访问权限,那么commit就会失败(就是这么坑)。解决方法有两个:
- 请求上级给你一个二级目录访问权限。
- 请求上级将SVN上该工程的文件目录限制在不多于二级,类似(
https://192.168.1.100/svn/test
)。
当然,只是可能,因为我现在这篇文章的配置方法和我之前的方法略有不同,所以可能不会出现这个权限不足的问题,所以如果你想使用Xcode自带的SVN,那么可以回到文章的开头,逐步配置,若最后在commit的时候出现了权限问题,那么再参考我的解决方案解决就好。
----------------2017-09-14新增----------------
在Xcode -> Preferences -> Accounts直接增加SVN地址确实依旧如上述般只能用二级目录,但是如果通过以下方式,则可以创建多级目录。
通过上述步奏,点击保存,便会checkout出svn上的项目。
最后补充一下,还是使用cornerstone吧,之前装不上是因为这个原因