来自微信公众账号:开点工作室(ID:kaidiancs)
软件版本控制工具提供了源码的版本管理、提交历史追踪、多分支以及多人协同开发的功能。对于个人开发者,版本控制工具可以帮助查看每次代码提交的时间以及代码的更改,方便用户回滚到某个历史版本查看代码或者建立新的代码开发分支。对于团队开发者,版本控制工具可以自动合并多人的代码提交,提高了多人协同开发的效率,也可以帮助定位具体代码的修改者和修改内容等。
常用的开源软件版本控制软件有SVN(Subversion)和Git,这两种版本控制工具使用方式比较相似,但是架构区别较大。
SVN将代码版本信息集中存放在一个中央仓库内,用户使用SVN客户端(如TortoiseSVN)从中央仓库拉取代码更新,或者将本地代码更改提交到中央仓库。有个比较大的问题是,当中央代码仓库无法访问时,无法对代码进行提交或者更新等操作。
Git与SVN有所不同,它是分布式的版本控制系统。Git也可以使用共享的远程代码仓库, Git工具(git命令)可以将远程代码仓库拷贝到本地。用户将代码修改提交到本地仓库,与远程代码仓库的交互操作本质上是分支的合并操作,即提交操作是将本地分支合并到远程分支、更新操作是将远程分支合并到本地分支。这样即使共享代码仓库无法访问时,也可以将代码暂时提交到本地进行管理。
具体版本控制软件的选择要根据用户自己的需要以及实际的开发环境要求而决定。
版本控制工具提供的基础功能大致相同,比如代码的提交、更新、撤销,代码文件的追踪、对比,版本的历史查看、切换、标签,代码分支的创建、合并等。下面介绍这些功能的具体含义。
(1)代码提交。当对代码进行修改后,将代码的更改同步到代码仓库。提交的信息包括代码的修改、提交者信息、提交时间以及提交的注释描述。
(2)代码更新。从代码仓库拉取代码更新到本地。更新的信息包括更新的代码文件列表,以及每个文件的代码修改内容。
(3)代码撤销。对代码文件修改后,可以放弃所做的更改将代码文件恢复到修改前的状态。
(4)代码文件追踪。将新的代码文件添加到版本控制,以后对该文件的修改都会被版本控制工具追踪。
(5)代码文件对比。将当前的代码文件内容与最新的代码版本内容进行对比,以确认所做的更改。或者对比代码文件的不同历史版本,以确认每次提交记录中代码文件中被修改的内容。
(6)版本历史查看。查看代码文件或目录的所有的提交历史,确认代码文件或目录发生的所有变化。
(7)版本切换。切换代码的某个历史版本,查看历史代码内容,或者在历史版本处创建代码分支。
(8)版本标签。可以为某次的代码提交打上版本标签,以方便代码版本的切换查看。
(9)代码分支创建。当在某个代码版本处需要提交不同的代码修改时,可以使用代码分支对代码的内容独立管理。尤其是在需要对某个版本的代码进行新功能开发或调试时,可以创建一个独立于当前代码分支的新的分支。
(10)代码分支合并。将一个分支的代码合并到另一个分支上去。比如在新的代码分支开发测试完毕新的功能模块后,可以将所有的代码更改同步到主开发分支。
版本控制工具拥有但不仅限于以上功能,不同的版本控制工具提供了更多的高级功能。当对一个版本控制工具熟悉后,可以尝试这些高级功能提高代码管理的效率。
版本控制工具Git的使用
Git起初是由LinusTorvalds为帮助Linux内核开发者进行代码版本控制而开发的开源软件,目前已经被开源社区普遍作为代码版本控制工具。Git提供了分布式的代码版本控制,允许每一个开发者拥有完整的代码仓库,解除了传统版本控制工具中心代码仓库的全局依赖,使得任何一个开发者的本地仓库都可以被其他开发者当作代码仓库使用。另外,Git的代码分支管理功能允许开发者可以多人协同、多分支并行的对代码进行开发管理。
1.安装配置Git
使用Git版本控制工具,可以从Git官网(www.git-scm.com)下载不同操作系统的安装包安装即可。对于使用yum包管理器的Linux操作系统,使用如下命令安装即可。
$ yum install git
安装结束后,使用Windows操作系统的GitBash命令行工具或者Linux系统中命令行工具输入命令检测Git是否正常工作。
gitversion 2.3.2 (Apple Git-55)
在正式使用Git前需要对Git的提交用户信息进行配置。
$ git config --globaluser.name "My Name"
$ git config --globaluser.email "My Email"
2.初始化Git仓库
在工程目录下执行init命令初始化Git仓库。
~/myproject $ git init
该命令会在myproject目录下创建一个隐藏的目录“.git”保存Git仓库信息。
3.代码提交
新初始化的Git仓库没有任何需要提交的内容。新建一个代码文件sum.c后,Git可以检测到可能需要进行版本控制的文件。
~/myproject $ touch sum.c
~/myproject $ git status
On branch master
Initial commit
Untracked files:
(use "git add ..." toinclude in what will be committed)
sum.c
nothing added to commitbut untracked files present (use "git add" to track)
将sum.c添加到Git版本控制。
~/myproject $ git addsum.c
~/myproject $ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached..." to unstage)
new file: sum.c
Git检测到sum.c文件是一个新文件,可以将该文件提交到仓库。首次提交后,Git会将当前代码分支命名为master。commit命令的选项“-a”表示提交所有的更改,“-m”选项表示提交时带注释。如果不使用该选项,Git会打开编辑器让提交者输入注释内容。
~/myproject $ git commit-am "create sum.c"
[master (root-commit)f9f6129] create sum.c
1 file changed, 0 insertions(+), 0deletions(-)
create mode 100644 sum.c
提交结束后,可以查看Git仓库的状态。Git检测到工作区目录没有需要提交的内容。
~/myproject $ git status
On branch master
nothing to commit,working directory clean
通过log命令查看Git的提交历史。
~/myproject $ git log
commitf9f612943b37c437e8e3d48ea079ba9545d8c50f
Author: My Name
Date: Sun Jul 12 23:11:52 2015 +0800
createsum.c
Git的提交记录中commit表示提交记录的ID、Author为提交者的信息、Date为提交时间。
如果修改了sum.c文件,Git会检测到该文件内容的改变。
~/myproject $ cat sum.c
sum#include
void main()
{
int a, b, sum; //定义变量a、b、sum
printf("please input two valus a and b :");
scanf("%d %d", &a, &b); //输入整数到a、b
sum=a + b; //对整数求和存入sum
printf("sum = %d\n", sum); //输出结果
}
~/myproject $ git status
On branch master
Changes not staged forcommit:
(use "git add ..." toupdate what will be committed)
(use "git checkout --..." to discard changes in working directory)
modified: sum.c
no changes added tocommit (use "git add" and/or "git commit -a")
提交代码的更改后,Git会检测到sum.c改变的内容。如sum.c文件被添加了9行数据。
~/myproject $ git commit-am "sum code"
[master 7027466] sum code
1 file changed, 9insertions(+)
再次运行log命令,可以发现版本历史多了一个记录,并且拥有不同的commitID。
~/myproject $ git log
commit7027466fce09533adbded6636fcf8cea41d48281
Author: My Name
Date: Sun Jul 12 23:21:49 2015 +0800
sum code
commitf9f612943b37c437e8e3d48ea079ba9545d8c50f
Author: My Name
Date: Sun Jul 12 23:11:52 2015 +0800
createsum.c
4.代码比较
每当文件发生改变时,使用diff命令可以查看代码发生的变化。
~/myproject $ echo"// new line" >>sum.c
~/myproject $ git diff
diff --git a/sum.cb/sum.c
index d8d3e33..5df12d7100644
--- a/sum.c
+++ b/sum.c
@@ -4,3 +4,4 @@ voidmain() {
sum=a + b; //对整数求和存入sum
printf("sum = %d\n", sum); //输出结果
}
+// new line
当对sum.c添加了一行注释后,Git可以比较出新增行的信息。
如果需要比较任意两个版本的差别,只需要将版本的commitID作为参数即可,版本历史记录的commitID可以进行简写。
~/myproject $ git difff9f61 70274
diff --git a/sum.cb/sum.c
index e69de29..d8d3e33100644
--- a/sum.c
+++ b/sum.c
@@ -0,0 +1,9 @@
+#include
+void main()
+{
+ int a, b, sum; //定义变量a、b、sum
+ printf("please input two valus a and b :");
+ scanf("%d %d", &a, &b); //输入整数到a、b
+ sum=a + b; //对整数求和存入sum
+ printf("sum = %d\n", sum); //输出结果
+}
Git提供了快捷命令方便版本的比较,比如比较当前代码内容与最新版本提交记录的差别。
~/myproject $ git diffHEAD
如果比较当前代码内容与上次版本提交记录的差别。
~/myproject $ git diffHEAD~
如果比较最新版本提交记录与上次版本提交记录的差别。
~/myproject $ git diffHEAD~ HEAD
HEAD是Git中比较重要的概念,它是一个指针,默认指向当前代码分支的最新的提交记录。HEAD后紧跟波浪线表示当前代码分支的倒数第二次提交记录,以此类推。
5.代码切换
在代码开发中,经常需要回到代码的某个历史状态检查代码,甚至回滚代码到一个历史状态。Git的checkout命令会修改HEAD指针的位置,Git会根据HEAD指向的版本记录将代码文件的内容切换到任意的一个版本状态。
比如将代码切换到上次提交的版本,sum.c文件恢复到刚创建的状态。
~/myproject $ gitcheckout HEAD~
Previous HEAD positionwas 7027466... sum code
HEAD is now at f9f6129...create sum.c
如果需要切换回来,则直接切换到master分支即可,此时sum.c代码已还原。
~/myproject $ gitcheckout master
Previous HEAD positionwas f9f6129... create sum.c
Switched to branch'master'
除了切换到某个历史版本查看代码外,有时候需要将代码的提交信息回滚到某个历史版本,而放弃该版本后的所有提交。使用reset命令可以重置代码的提交记录。
比如放弃代码的最后一次提交,使用如下命令。此时代码回到最后一次提交前的状态,Git会检测到sum.c被修改。
~/myproject $ g reset--soft HEAD~
如果不仅放弃代码的最后一次提交,而且放弃代码的所有修改内容,使用如下命令。此时代码的内容被还原到最后一次编辑前的状态。一般尽量避免这样的操作,否则会丢失所有的代码修改。
~/myproject $ g reset--hard HEAD~
6.代码文件追踪
Git中可以自由地对文件进行版本控制。
如果需要对文件进行版本控制,使用add命令即可。
~/myproject $ git addsum.c
如果需要将文件移出版本控制,使用rm命令
~/myproject $ git rmsum.c
在实际开发过程中,经常在工程目录中出现各种临时文件,如果不希望这些文件被Git提示添加到版本控制,可以在工程目录内创建“.gitignore”文件,并在文件内配置被Git忽略的文件。
~/myproject $ ls
sum.c main.o
~/myproject $ cat.gitignore
.gitignore
*.o
~/myproject $ git status
On branch master
nothing to commit,working directory clean
在“.gitignore”内忽略了该文件本身以及所有以“.o”结尾的文件,这样Git就不会提示这些文件需要添加到版本控制了。
7.代码标签
当代码提交了一个比较重要的版本时,可以为提交的版本打上标签。
~/myproject $ git tag 1.0
~/myproject $ git tag -l
1.0
上述Git的tag命令为当前版本打上了1.0的标签,并可以使用“-l”选项查看所有的标签。
标签和commitID有同样的地位,可以出现在diff、checkout、reset等命令中。
8.代码分支
代码分支是Git中比较重要的功能,它使得代码开发可以并行化。
使用brach命令可以创建代码分支。
~/myproject $ git branchnew
~/myproject $ git branch
* master
new
~/myproject $ gitcheckout new
Switched to branch 'new'
此处创建了分支new,由于创建分支时HEAD指针指向master分支的最新提交,因此分支new拥有master分支的所有提交记录。
~/myproject $ echo"// new line" >>sum.c
~/myproject $ git commit-am "add new line"
[new ee74954] add newline
1 file changed, 1 insertion(+)
~/myproject $ gitcheckout master
Switched to branch'master'
~/myproject $ git mergenew
Updating 7027466..ee74954
Fast-forward
sum.c | 1 +
1 file changed, 1 insertion(+)
在分支new上,向sum.c添加了一行数据并提交。然后切换到master分支,使用merge命令将new分支上的提交合并到master分支。可以发现master做了new分支上的修改。
如果HEAD指针指向master的某个历史版本,那么执行branch命令创建的分支将拥有master分支部分的提交。
~/myproject $ gitcheckout HEAD~
HEAD is now at f9f6129...create sum.c
~/myproject $ git branchtest
~/myproject $ gitcheckout test
Switched to branch 'test'
添加一行数据到空的sum.c文件,并提交。最后在合并test分支到master分支时出现合并冲突。
~/myproject $ echo"// test branch" >>sum.c
~/myproject $ git commit-am "new sum.c in test brach"
[test 2463fdf] new sum.cin test brach
1 file changed, 1 insertion(+)
Switched to branch'master'
~/myproject $ git mergetest
Auto-merging sum.c
CONFLICT (content): Mergeconflict in sum.c
Automatic merge failed;fix conflicts and then commit the result.
打开sum.c文件,可以看到Git生成的冲突标志。
<<<<<<<HEAD
#include
void main()
{
int a, b, sum; //定义变量a、b、sum
printf("please input two valus a and b :");
scanf("%d %d", &a, &b); //输入整数到a、b
sum=a + b; //对整数求和存入sum
printf("sum = %d\n", sum); //输出结果
}
=======
// test branch
>>>>>>>test
根据冲突标记的提示修改sum.c文件,由于合并分支操作希望将test分支的sum.c的内容追加到master分支的sum.c文件内,因此这里移出分支标记即可。修改完毕后,将修改后的内容提交。
~/myproject $ git commit-am "merge test"
[master e413b69] mergetest
更多计算机专业技术文章、笔试面试资料尽在微信公众账号:开点工作室。