- 自己的猜想
- 文件名比对
- 文本行比对
- 事实是什么
- 提交计划
- 提交数据
- 更新客户端版本库数据时,同名文件中文本行的数据比对规则
假设SVN服务端就存在一份最新版的文件 HF,客户端检出这份文件后再提交,当前用户提交的文件称为 NF。
首先比对文件名,如果文件名不同,则比对文件属性的元数据,文件 ID 是相同的,说明属于同一个文件,则比对文件名称的版本号,发现 NF 文件名的版本号为 Undefined,说明 NF 文件修改了文件名,于是从客户端的缓存库中获取 NF 文件旧名称的版本号与 HF 文件的名称的版本号比对,发现相同或者 NF 文件旧名称的版本号更大,则保留 NF 文件的文件名;若 NF 文件旧名称的版本号比 HF 名称的版本号小,说明什么问题?说明 HF 文件也曾修改了文件名并且提交了更新;其二当前用户没有更新最新版的数据,而是在旧版本基础上进行更新和提交。所以现在冲突就产生了,保留谁的文件名,两位提交者相互协商后手动解决冲突了。
文件名不同,比对文件属性的元数据,发现文件 ID 也不同,说明不属于同一个文件,而是新增的文件,此时 SVN 会在客户端的缓存库中追溯版本数据(客户端会缓存文件的各种历史版本),试图寻找到 HF 文件的相关数据,结果找到了,发现原来的文件被删除了,于是会比对被删除文件的版本和 HF 文件的版本,如果被删除文件的版本大于等于 HF 的版本号,则遵从提交的数据包,不再保留 HF 文件;如果被删除文件的版本号小于 HF 文件的版本号,说明两个问题,其一 HF 文件是后来有人更新后提交的;其二当前用户没有更新最新版的数据,而是在旧版本基础上进行更新和提交。因此这样的删除行为 SVN 服务器是不会直接通过的,所以冲突产生了。被删除的文件是否保留,两位提交者相互协商后手动解决冲突了。
如果 SVN 在追溯版本数据的时候没有找到 HF 文件相关的数据,则说明当前用户提交的是新增数据,于是保留 NF 和 HF 两份文件到 HEAD 片段中,而原来的 HF 文件会被归档到旧版本片段中。此时其他用户从 SVN 检出或导出或更新就会得到两份文件了。
如果 NF 和 HF 的文件名相同但是文件 ID 不同,也就是说实际是两个不同的文件,但是取名相同(例如,当前用户下载了 HF 文件,后来删除了,又重新创建了一份同名的文件),文件系统是不允许同个目录下存在两份同名的文件的,所以此时 SVN 也是在客户端的缓存库中追溯版本数据,如果发现当前用户删除了与 HF 同 ID 的文件,而且版本相同,则 SVN 会遵从当前用户的提交只保留当前用户的提交的文件;如果当前用户删除的与 HF 同 ID 的文件版本更小,则 SVN 不会直接通过,所以冲突产生了。保留哪个文件,两位提交者相互协商后手动解决冲突。
文本行比对如果文件名和 ID 都相同的情况下,则逐行比对文件内容。
NF 的第 1 行与 HF 的第 1 行比对,先比对内容,内容相同则 NF 的第 1 行内容保留下来,内容不同则比对行的版本号,如果 NF 的第 1 行的版本号是 Undefined,则追溯该行的旧版本数据,如果发现 NF 文件的第 1 行的旧版本号等于 HF 文件的第 1 行的版本号,则保留 NF 第 1 行的数据,如果 NF 文件的第1行的旧版本号小于 HF 文件的第 1 行的版本号,则产生冲突,需要手动解决。所以基于这样的逻辑,多人同时修改同一位置的数据最先提交的数据顺利通过,但是后面提交的数据都会产生冲突,因为从客户端缓存库中提取到的版本数据肯定比 SVN 服务器 HEAD 片段的数据的版本小。这里说的 HEAD 片段其实就是所谓的“集中式版本库”,SVN 用户都是从这个版本库中下载最新版本的数据资源。
NF 的第 1 行与 H F的第 1 行比对,内容不同,则比对版本号,如果可以直接取到 NF 文件第 1 行的版本号,则说明 NF 文件的第 1 行没有修改过,如果版本号相同,则直接保留 NF 的第1行文本内容,如果 NF 文件的第 1 行的版本号低于 HF 文件的第 1 行的版本号,这说明当前用户在提交的时候没有更新最新版的数据直接提交了,但是没有关系,SVN 知道 NF 文件中的第 1 行文本是旧数据,所以会保留 HF 文件的第 1 行数据。
按上述的逻辑比对后面的所有文本行…
事实是什么在提交的时候,SVN 并不是按以上的逻辑和规则来比对数据,中央版本库中原来的数据会移入历史版本池中,然后备份一份到 head
分区中(即主分支 /trunk
),接着简单判断同名文件内容是否一致,一致则保留 head 的数据,否则被新提交的文件替换掉。
在客户端版本库的缓存数据中,有保存客户端版本库的文件的实际路径与 SVN 服务端版本库中的对应路径的映射关系。只要有修改客户端版本库中的数据,都会把被修改文件的客户端路径和相对应的 SVN 服务端版本库的路径写入到提交计划中。
所谓 versioned
就是每个客户端版本库的文件都在这个路径映射表中,如果你改了客户端版本库中的文件名或者删除了,SVN 客户端就无法找到对应的映射关系,就会提示文件丢失、无法识别等。
客户端版本库的文件只要修改了内容,或者通过命令 svn add
添加的文件,相关文件的路径都会写入提交计划中(schedule)
- 只要客户端版本库的版本号和服务端版本库的版本号不同,就无法正常提交,提示“过期”
- 如果提交数据成功,是将工作副本的数据完全覆盖服务端的数据,没有进入文件内容进行文本行的数据比对
注:服务端文本是否修改过,是针对客户端文本行的版本而言。