程序员面试之必考题(四):版本控制工具Git基础

来自微信公众账号:开点工作室(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是否正常工作。

$ git --version

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

更多计算机专业技术文章、笔试面试资料尽在微信公众账号:开点工作室。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,997评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,603评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,359评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,309评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,346评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,258评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,122评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,970评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,403评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,596评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,769评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,464评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,075评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,705评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,848评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,831评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,678评论 2 354

推荐阅读更多精彩内容

  • 本文为 Git教程的学习笔记,教程源自廖雪峰的博客。这是一个由浅入深,学完后能立刻上手的Git教程。另,附上另一本...
    七弦桐语阅读 6,245评论 5 47
  • GIT分布式版本控制系统最佳实践 这篇文章来自于老男孩教育高级架构师班12期的徐亮偉同学。 首先感谢老男孩架构师班...
    meng_philip123阅读 3,409评论 4 36
  • 1. 安装 Github 查看是否安装git: $ git config --global user.name "...
    Albert_Sun阅读 13,661评论 9 163
  • “徒弟,以后行走江湖,千万小心那些背后背着刀的人。” “师傅,是因为他们都是习武之人吗?” “放屁!你不是习武之人...
    江大桥阅读 799评论 0 1
  • 表姐在北邮读研 忙里偷闲跑来休假 就一起去吃自助餐啦 吃到一半被我强行摆拍 总体来说还是好吃哒 不过在所有吃过的店...
    Chromatophore阅读 703评论 0 0