git总结

文章目录

git相对svn好处

直接记录快照,而非差异比较

svn记录方式:

aa1.jpg

git记录方式:

aa2.jpg

这样做的好处是以空间换时间,当我们提交时,不用去计算差异;当checkout时,直接拉取快照,而svn对每个文件要进行大量的合并操作.

git在本地就可以用

svn缺点是中央服务器的单点故障。若是宕机一小时,那么在这一小时内,谁都无法提交更新、还原、对比等,也就无法协同工作。如果中央服务器的磁盘发生故障,并且没做过备份或者备份得不够及时的话,还会有丢失数据的风险。
而由于git每个人的clone都相当于一次完整的备份,所以要恢复很容易.
可以进行各种无脑的提交,防止由于考虑到影响别人而不能提交导致的各种问题(需求到一半,觉得另一种实现更好,删除代码重新实现,结果发现行不通,想恢复,就悲剧了)

git比svn快,用起来更流畅

相对于svn,由于整个库都是保存在本地,近乎所有操作都是本地执行,所以操作基本上可以忽略时间.

git拉branch和在branch之间切换都非常简单

通过git checkout branchname来切换分支,并且由于代码也在当前目录下,所以对于开发工具可能更方便(在svn中eclipse切换分支可能会引起很个依赖项的更改,像xiaoji中的依赖).

git的submodule可以方便的定义依赖

submodule把分散的项目集合在一起,并且能够保存它们之间依赖的版本.

SVN没有后悔药,git有一堆后悔药

由于每次提交对其它人都是可见的,所以有时会给自己造成一种心理负担(没有开发完成的功能不敢提交,怕影响到其它人编译不通过),这对对于一个长线任务来说很不好,因为如果不提交,任务的过程以后就不能很好的回顾。
svn的每次操作都会记录到服务器上,所以一旦提交,没有办法撤销,可能进行回滚。但是git对于不同情况下提供了不同的撤销方法:

修正最后一个 commit 消息:

git commit –amend 会用一个新的 commit 更新并替换最近的 commit ,这个新的 commit 会把任何修改内容和上一个 commit 的内容结合起来。

撤销“本地的”修改

git checkout 会把工作目录里的文件修改到 Git 之前记录的某个状态。你可以提供一个你想返回的分支名或特定 SHA .

重置“本地的”修改

git reset 会把你的代码库历史返回到指定的 SHA 状态。 这样就像是这些提交从来没有发生过。缺省情况下, git reset 会保留工作目录。这样,提交是没有了,但是修改内容还在磁盘上。这是一种安全的选择,但通常我们会希望一步就“撤销”提交以及修改内容 — 这就是 –hard 选项的功能。

svn软连接的问题

在默认情况下,向svn中提交软连接文件向,再checkout出来,软连接文件会失效,对于存在大量相同配置文件的项目来说很麻烦。但是git不会.

git基本使用

git安装

下载git客户端:http://git-scm.com/ ;

选择git图形工具

  • Tortoise Git – Windows平台下的开源Git图形界面
  • Tower – 号称osx上最好用的git工具
  • GitX(L) – Mac OS X下的开源Git客户端
  • SourceTree – Windows和Mac下的免费Git或Mecurial界面

    aa3.png

  • github desktop

    aa4.png

git配置

有三种配置:
版本库级别,全局(用户目录下),系统级(/etc下)

他们的配置是 git config, git config –global, git config –system,形式是 git config 〈section〉.〈key〉 〈value〉,如果没有 value ,就会显示已经配置的值。

也可以通过git config -e 打开配置文件直接编辑。

aa7.png

git的几个概念

工作区,暂缓区,版本库

aa8.png

git命令

git clone

完整克隆整个版本库, git clone https://192.168.1.5:8433/r/test.git ,如果觉得太大,可以加-depth=1选项,这样,它的版本库中,就不会有历史的快照

git pull

从其他的版本库(既可以是远程的也可以是本地的)将代码更新到本地,例如:’git pull origin master’就是将origin这个版本库的代码更新到本地的master主枝,该功能类似于SVN的update

git add

是将当前更改或者新增的文件加入到Git的索引中,加入到Git的索引中就表示记入了版本历史中,这也是提交之前所需要执行的一步,例如’git add test.cc’就会增加test.cc文件到Git的索引中,该功能类似于SVN的add

git rm

从当前的工作空间中和索引中删除文件,例如’git rm test.cc’,该功能类似于SVN的rm、del

git commit

提交当前工作空间的修改内容,类似于SVN的commit命令,例如’git commit -m init’,提交的时候必须用-m来输入一条提交信息,该功能类似于SVN的commit

git push

将本地commit的代码更新到远程版本库中

格式git push <repository> <refspec>

<repository>是远程仓库,是push操作的目的地,<repository>可以是一个URL,也可以是远程仓库的名字。

<refspec>的格式是:+src:dst,其中“+”是可选的,src是想要push的分支的名字,dst是用push更新的远程端的ref的名字。使用空的<src>进行更新会删除远程仓库中的内容。如果”:dst”被省略,那么就会提交到和 src 一样的引用上,如常见的 git push orgin master。

git log

查看历史日志,该功能类似于SVN的log

git revert

还原一个版本的修改,必须提供一个具体的Git版本号,例如’git revert bbaf6fb5060b4875b18ff9ff637ce118256d6f20’,Git的版本号都是生成的一个哈希值

git branch

对分支的增、删、查等操作,例如’git branch newbranch’会从当前的工作版本创建一个叫做newbranch的新分支,’git branch -D newbranch’就会强制删除叫做newbranch的分支,’git branch’就会列出本地所有的分支

git checkout

Git的checkout有两个作用,其一是在不同的branch之间进行切换,例如’git checkout new_branch’就会切换到new_branch的分支上去;另一个功能是还原代码的作用,例如’git checkout test.cc’就会将test.cc文件从上一个已提交的版本中更新回来,未提交的内容全部会回滚

git reset

将当前的工作目录完全回滚到指定的版本号,假设如下图,我们有A-G五次提交的版本,其中C的版本号是

aa9.png

git config

利用这个命令可以新增、更改Git的各种设置

git tag

可以将某个具体的版本打上一个标签,这样你就不需要记忆复杂的版本号哈希值了,例如你可以使用’git tag revert_version bbaf6fb5060b4875b18ff9ff637ce118256d6f20’来标记这个被你还原的版本,那么以后你想查看该版本时,就可以使用 revert_version标签名,而不是哈希值了

git stash

经常有这样的事情发生,当你正在进行项目中某一部分的工作,里面的东西处于一个比较杂乱的状态,而你想转到其他分支上进行一些工作。问题是,你不想提交进行了一半的工作,否则以后你无法回到这个工作点。解决这个问题的办法就是git stash命令。

aa10.png

现在你想切换master,但是你还不想提交你正在进行中的工作;所以可以储藏这些变更。为了往堆栈推送一个新的储藏,只要运行 git stash:

aa11.png

你的工作目录就干净了:

aa12.png

这时,你可以方便地切换到其他分支工作;你的变更都保存在栈上。要查看现有的储藏,你可以使用 git stash list:

aa13.png

现在,如果想回到刚才的状态,可以通过git stash apply,也可以指定名称:

aa14.png

git merge

在本地开发完成之后,要合并到develop分支:

aa15.png

开发完成之后,再删除本地分支:

aa16.png

当git push, git pull时,都会发生merge操作,冲突的处理

aa17.png

aa18.png

git submodule

在git项目中可以引入其它git项目作为子模块,在提交时git会记录下我们引入项目的版本号,这样子项目不会随着由于对方的修改而出现问题:

D9FC06EE-7F86-4FA0-A7FF-E84CB28DC7A7.png

增加子模块

git submodule add git://github.com/sails/sails.git sails

7B0D239F-7B1A-47E9-92EA-4B892FE05015.png

493E60BA-D46E-41ED-9A4D-B1C306127AE4.png

增加的子项目可以是其它git服务器上的。

2DBAA06F-EC44-4640-A9A5-053108B804A2.png

1537390B-405C-4C88-B879-52A2B58414B6.png

修改子模块版本

默认它是在我们增加子模块时它的最新版本,如果我们想要修改它,可以通过到子模块的目录中执行git pull,git checkout进行修改:

A7309B43-3E20-42A4-9687-D89BCF53C794.png

FF185CD7-ADB0-4480-801B-21F405F021FA.png

可以看到服务器上的版本也变成了12014d

73B685D6-299B-4F03-A920-06C3330087B9.png

删除子模块

git要删除子模块稍微复杂一些,分成4步:

  • git submodule deinit sails 它的作用是把submodule从配置文件中删除;
  • git rm sails 它把submodule的文件删除;
  • git rm –cached sails
  • rm -rf .git/modules/sails 从版本库中删除

80603A3D-E882-4F05-87D3-F2C9020B3C8A.png

82342FC8-877F-4A3D-8DD8-4B2F5D6138FD.png

clone一个带子模块的项目

git clone --recursive https://sailsxu@192.168.1.5:8433/r/test.git

因为每次clone会把整个项目都复制下来,包含它所有的历史版本,所以有时如果觉得一个项目太大,可以通过在clone时加上-depth=1来设置clone的深度:

git clone --depth=1 --recursive https://sailsxu@192.168.1.5:8433/r/test.git

5F4D2894-04CA-401F-BBB0-5845ECA009E3.png

查看项目历史,可以看到它只有两次提交:

F98444CC-7519-40A1-A099-840577DE1F74.png

而如果是完整clone的项目,通过git log可以看到所以的提交:

11B4E0EF-419A-4B99-94F5-F9449E7AFC9A.png

git协同开发模式

由于git很灵活,开发模式也很多,这里介绍一种:

aa5.png

master:主分支从项目一开始便存在,它用于存放经过测试,已经完全稳定代码;在项目开发以后的任何时刻当中,master存放的代码应该是可作为产品供用户使用的代码。所以,应该随时保持master仓库代码的清洁和稳定,确保入库之前是通过完全测试和代码reivew的。master分支是所有分支中最不活跃的,大概每个月或每两个月更新一次,每一次master更新的时候都应该用git打上tag,说明你的产品有新版本发布了。

develop:开发分支,一开始从master分支中分离出来,用于开发者存放基本稳定代码。每个开发者的仓库相当于源仓库的一个镜像,每个开发者自己的仓库上也有master和develop。开发者把功能做好以后,是存放到自己的develop中,当测试完以后,可以向管理者发起一个pull request,请求把自己仓库的develop分支合并到源仓库的develop中。这里为什么要develop分支,而不直接使用master是因为需要一个分支用来接收非稳定代码,比如虽然没有开发完成,但也可以push(为了防止自己不小心把整个git库删除,最好经常进行同步)

任何人不应该向master直接进行无意义的合并、提交操作。正常情况下,master只应该接受develop的合并,也就是说,master所有代码更新应该源于合并develop的代码。

feature:功能性分支,是用于开发项目的功能的分支,是开发者主要战斗阵地。开发者在本地仓库从develop分支分出功能分支,在该分支上进行功能的开发,开发完成以后再合并到develop分支上,这时候功能性分支已经完成任务,可以删除。功能性分支的命名一般为feature-*,*为需要开发的功能的名称。

aa6.png

svn导入git

git svn clone http://my-project.googlecode.com/svn/ --authors-file=users.txt --no-metadata

users.txt文件格式:

schacon = Scott Chacon <schacon@geemail.com>
selse = Someo Nelse <selse@geemail.com>

前面是svn的用户名,后面是git的用户名和邮箱.

选项no-metadata 来阻止 git svn 包含那些 Subversion 的附加信息

sourcetree 介绍

git和svn在使用方式上的不同导致了工具展示方式的差异;在svn上,我们关注的是提交,更新,日志等,它的一个侧重点在于一个版本中的变化;并且由于每次操作都是联网的,所以像tortoisesvn这样的工具比较流行,它们显示的信息尽量少,这样才能比较快;但是git所有的内容都在本地,使用者关注的点在不同版本库之间的变化,日志,每次提交的差异,并且由于这些信息都是本地的,所以可以很方便的做到一个窗口中显示出来,给开发者一个全貌;所以git比较流行的gui工具都是像sourcetree这样的;

F32A2972-9F9E-442B-902A-0D713AA25B6A.png

它规范了我们的开发模式:

CD5B5C59-90FC-4016-A5F0-0CF4CB5D4CC7.png

当我们新建一个开发分支时:

EE88F944-6968-441F-97F1-CDE7D5E951E0.png

创建一个release分支:

A6E86139-82D1-4AE6-A991-B9E48E046E67.png

从它的界面中,我们可以清楚的看到分支是从哪里来的,什么时候合并的,这些功能在svn上很难看出来;

原文链接:,转发请注明来源!

发表评论