编辑推荐: |
本文来自csdn,本文简单介绍了git原理及相关命令的本地插件操作,希望对您的学习有帮助。 |
|
git原理及相关命令介绍
一、git代码状态转换图
1>>如图所示:未被git跟踪的状态为unstage状态,已经被git跟踪的状态为stage状态。【包括staging状态和staged状态】
2>>untrack files是指尚未被git所管理的文件;changed but
not updated是指文件被git管理,并且发生了改变,但改动还没被git管理;这两种状态,都可以看成是改动还没被git管理的状态,我们这里称非stage状态。
3>>changes to be commited是指进入stage状态的文件,stage是commit和未管理之间的一个状态,也有别名叫index状态,也就是git已经管理了这些改动,但是还没完成提交。【.gitignore中的文件,不会出现在以上三个状态中】
二,git的个人本地使用及操作
1, 创建Git库
cd 源码目录
git init #初始化 在源码目录内生成一个.git的目录
2, 注册用户信息
git config --global user.name XXX 用户名
git config --global user.email XXX 用户邮箱
git config –list #查看用户信息
3, 向git库中添加或删除文件
git add XX #加单个文件
git add . #加所有
git add [path]会把对应目录或文件,添加到stage状态
git add . 会把当前所有的untrack files和changed
but not updated添加到stage状态
4, 向版本库提交变化
git commit –m “XXXX” #直接添加简单提交信息,添加注释
git status #查看当前代码库的状态
git log #查看版本信息
git log –p #查看版本信息并显示每次修改的diff
git show sdjf974654dd…. #查看指定版本信息
#(show后面为每次提交系统自动生成的一串哈希值)
git show sdji97 #一般只使用版本号的前几个字符即可
5, 撤销与恢复
git reset
git reset --hard #回到原来编辑的地方,改动会丢失。
#(同样适用于团队对于其他人的修改恢复)
git reset --hard sdv143kvf…... #可回到指定的版本
#(hard后面为每次提交系统自动生成的一串哈希值)
git reset [path] 会改变path指定的文件或目录的stage状态,到非stage状
git reset 会将所有stage的文件状态,都改变成非stage状
回退1个change的写法就是git reset HEAD^,2个为HEAD^^,3个为HEAD~3,以此类推。
6, 向服务器提交变化
git push #向服务器提交
7, 暂存改动
git stash可以把当前的改动(stage和unstage,但不包括untrack的文件)暂存。然后通过git
stash list查看。并通过git stash apply重新取出来。但apply之前要保证worktree是干净的。
三,git的团队开发及操作
1, 获取项目
cd 本地工作目录(自定)
git clone 服务器帐户@IP:项目.根路经
这里具体操作为:
git clone git@192.168.20.22:android2.2.git
说明:这里假定服务器的用户名为git,服务器IP为192.168.20.22,项目名为android2.2,根路经为git的home(即根路径)
2, 团队开发的基本流程
git add 改动的文件
git commit #(提交至本地)
git pull #(将服务器项目与本地项目合并)
git push #(将本地项目上传至服务器)(在提交前要git
pull --rebase一下,确保当前的本地的代码为最新。)
四,git的分支管理
git分支操作在本地建立分支,然后与本地主枝合并,最终提交到服务器。有效的避免了因个人操作不当向服务器提交过多脏数据,避免频繁git
clone服务器来更新本地库。
分支操作指令:
1, 建立分支
git branch AAA #建立分支AAA
2,分支切换
git checkout AAA #从当前分支切换到AAA分支
3, 将分支与主枝master合并
git checkout master #(首先切换回主枝)
git merge AAA #(将分支AAA与主枝合并)
4, 当前分支查看
git branch #默认有master(也称为主枝)
git branch –a 查看当前所有分支
5, 删除分支
git branch –d AAA #删除分支AAA
备注:上面只是一些基本的操作命令,更多的命令可通过帮助文档查询。
帮助文档的使用:
man git-<需查询的指令> #(git后面有“-”
如commit的查询为 man git-commit
删除分支 ; 如果你要删除的分支并没有被merge到当前分支的话,将产生一个错误提示。
git bash和eclipse下git插件
gitbash
首先,下载gitbash桌面版的客户端:
http://code.google.com/p/msysgit/downloads/list
进入后寻找Git-1.8.1.2-preview20130201.exe,安装上。
安装的时候,一直默认下一步就ok了。
打开gitbash相当于打开一个命令行输入模式
其次:可以用git clone 命令行下载代码仓库的代码
在使用git来进行版本控制时,为了得一个项目的拷贝(copy),我们需要知道这个项目仓库的地址(Git
URL). Git能在许多协议下使用,所以Git URL可能以ssh://, http(s)://,
git://,或是只是以一个用户名(git 会认为这是一个ssh 地址)为前辍。
如上图所示,输入git clone命令后,输入用户名和密码验证成功后就会把代码check
out到本地,一般都在C:\Documents and Settings\Administrator目录下
常用命令:
git log 看记录
git diff 看与上一次的改变
建分支用git branch [分支名]
切换分支用 get checkout [分支名]
查看分支就用 git branch
想回到上一个不版本,不要这一次修改 get reset --hard HARD
具体一下文件 get checkout xxxxxx.xx文件
生成DIFF(patch)文件
HEAD是当前最新的版本,HEAD~是上一个版本,HEAD~~是上上一个版本,也可以
git diff HEAD HEAD~
update,更新版本
git pull 拉服务器的版本
commit ,提交代码
git commit 注意,这个提交只是在本地提交,真正想到服务器,commit后还需要使用git
push,推送到服务器
推送到服务器
git push把刚才提交的推送到服务器去
查看当前git地址下的所有分支:
我们想切换到第三个分支:
如上图所示,我们已经成功从master切换到了pinganbb_en的分支,使用ls
命令可以查看当前分支下的内容
那么,我们如何checkout 当前分支下的代码呢?(使用我们的git地址,默认会checkout
master主分支下的内容,而我们想checkout 分支下的内容)
在windows环境下,新创建一个文件夹:test
进入文件夹内,鼠标右键 --- Git Bash
如上图所示,直接git clone 分支名称 是无效的,提示没有找到,所以我们要加上 -b,也就是:
git clone -b 分支名 http://code.google.wdadwa/en.git
输入用户名和密码,成功后就可以checkout 到当前创建的test文件夹下了。
上传项目到代码仓库(服务器),(第一次上传,并非update)
找到要上传的项目的文件夹,右键- Git Bash 这个时候如果直接输入:
$ git remote add origin git@github.com:yourName/yourRepo.git
会发现当前git 不存在,因为我们还没有add 和commit(小白)
error: src refspec master does not match any.引起该错误的原因是,目录中没有文件,空目录是不能提交上去的
现在最简单的办法,在一个新的空白文件夹下,右键 Git Bash,输入下面的命令:
$ git clone http://dev.dbjtech.com/kaka/test.git
输入用户名和密码后,成功checkout后,会发现有一个空的.git文件夹(隐藏),把这个文件夹拷贝到我们要上传的项目里,这样项目中就有了.git了
在.git中的config文件,可以看到当前项目下的git origin地址
【注意,如果有不需要上传的文件,可以通过.gitignore文件屏蔽,也可以在add 的时候选择性的上传】
这个时候查看status,会发现没有任何的commit,所以我们需要先add 所要上传的文件到本地仓库,然后提交,最后才是push
$ git add .
如上图所示,现在我们需要commit到本地仓库了
$ git commit -m "this is first push "
成功提交本地后,就可以上传到服务器啦
$ git push 【默认回事master主分支】
等待上传,成功后我们再看一下log日志
$ git log
大功告成,项目已经成功提交到了服务器的代码仓库,我们在一个新建的文件夹下验证一下吧
$ git clone http://test.test.com/test.git
通过ls可以看到,checkout下来的就是我们之前上传的那些文件/文件夹
http://blog.csdn.net/code52/article/details/8807785
回退版本
首先输入命令:
git log
会看到当前所有的提交版本记录
2,git reset
git reset 5f0deba043dbfa96e5d27f8e43c1e13f9fd312e4
可能出现的error
error: RPC failed; result=22, HTTP
code = 411
fatal: The remote end hung up unexpectedly
fatal: The remote end hung up unexpectedly
Everything up-to-date
当使用git提交(push)比较大的文件的时候可能会出现411这个错误
解决办法:改一下git的传输字节限制(500M)
git config --global http.postBuffer
524288000
error: RPC failed; result=22, HTTP
code = 413
fatal: The remote end hung up unexpectedly
fatal: The remote end hung up unexpectedly
Everything up-to-date
这个错误是因为当前的account没有一个有效的SSH Key,这个时候需要你登录github去SSH配置一个私钥。
实际操作
现在只要cat ~/.ssh/id_rsa.pub 就可以看到以ssh-rsa开头和以account结尾的的长串私钥,复制这个到gitLab个人账户SSH配置项,添加到key中即可。
然后 git push origin master就可以了。
git pull时,commit your changes or stash
them before you can merge.
error: Your local changes to 'c/environ.c' would
be overwritten by merge. Aborting.
Please, commit your changes or stash them before you
can merge.
这个意思是说更新下来的内容和本地修改的内容有冲突(修改到同一文件同一位置),先提交你的改变或者先将本地修改暂时存储起来,前者是解决这种冲突,后者是先隐藏
处理的方式非常简单,主要是使用git stash命令进行处理,分成以下几个步骤进行处理。
1,先将本地修改存储起来
$ git stash
这样本地的所有修改就都被暂时存储起来 。是用git stash list可以看到保存的信息:
其中stash@{0}就是刚才保存的标记。
2,暂存了本地修改之后,就可以重新pull了。
3,还原暂存的内容
$ git stash pop stash@{0}
系统提示如下类似的信息:
Auto-merging c/environ.c
CONFLICT (content): Merge conflict in c/environ.c
意思就是系统自动合并修改的内容,但是其中有冲突,需要解决其中的冲突。
4,解决文件中冲突的的部分
打开冲突的文件,会看到类似如下的内容:
其中Updated upstream 和=====之间的内容就是pull下来的内容,====和stashed
changes之间的内容就是本地修改的内容。git不知道哪行内容是需要的,所以要自行确定需要的内容,二者取其一。
解决完成之后,就可以正常的提交了。
eclipse下 egit插件
打开eclipse-help-install new software
location输入如上地址,下载好egit插件后,选中项目(项目是从代码仓库checkout下来的,也就是说项目有.git文件),右键Team,就会显示egit菜单,和svn插件类似。
需要注意的是:需要查看diff文件,就Create Path,保存到指定位置;当需要提交代码时,需要先commit一下,然后pull,两个缺一不可,不pull,代码无法同步到仓库(当我们使用svn时,只需要commit,直接会提交到代码仓库)。
git和svn使用
svn
需要搭建一个svn服务器(HTTP/SVN),搭建svn服务器需要看一些手册
git
不需要git服务器,任何一台安装git的PC都可以是git服务器,其他人可以用任何现有的方式(SSH/HTTP/本地文件系统)更新上传代码
我有两台PC:A和B,他们在一个网段(192.168.6.0/24),为了使得这个git使用记录更加严谨,以下的每一个命令都在这两台PC上进行测试。其中A地址为192.168.6.1,
B地址为192.168.6.15, B可以通过ssh登录到A
1.初始化一个A机器上的git目录
最近在开始学习scala,在A机器上有一个目录是/home/le/workspace/scala_test,在这个目录下初始话一个git目录
$ git init
此时你在当前目录下会发现一个.git的目录
$ ls -la
2.向git库中提交文件
$ touch Test1.scala
$ vim Test1.scala
$ git status . #git会告诉你新的改动,接下来选择需要提交的文件
$ git add Test1.scala
$ git status . #再来看看,git会告诉你将要commit什么
$ git commit -m 'initial git repo'
#提交到本地branch
A可以作为git server了,接下来到B上操作。
2. 从A上克隆代码到B上,位于/home/le/workspace/git/repo1/
$ git clone le@192.168.6.1:/home/le/workspace/scala_test
3. 创建分支,切换分支,提交分支到远程git库
$ git branch scala_dev #创建分支
$ git checkout scala_dev #切换到该分支
$ git branch #查看本地当前的分支
$ git push origin scala_dev #提交scala_dev分支到远程git库
$ git branch -r #查看远程所有的分支
$ git branch -a #查看本地和远程所有的分支
4.修改文件,并且提交到远程库
$ touch Test2.scala
$ git add Test2.scala
$ git commit
$ git log #在push之前确认commit是否正确
$ git push
5.从远程git库克隆指定的分支,这次在B机器的/home/le/workspace/git/repo2/目录重新克隆一份代码
$ git clone -b scala_dev le@192.168.6.1:/home/le/workspace/scala_test
$ git branch #查看当前分支
#提交新的代码
$ touch Test3.scala
$ git add Test3.scala
$ git commit
$ git log #在push之前确认commit是否正确
$ git push
6.回到/home/le/workspace/git/repo2/更新代码
$ git pull #如果有错误,请按照错误提示修改.git/config文件
一些可能会遇到的问题
1.合并多个commit多一个commit
在本地的git库commit了多次,在push到远程的git库时,可以在本地合并这些commit。
每次合并两个commit
$ git reset --soft HEAD^1
$ git commit --amend
合并最后n个commit
$ git rebase -i HEAD~n
#替换第n个pick为s保存
2.取消本地的commit
有时候commit了代码到了本地git库中,之后某种原因想删掉最后1条commit,可以直接恢复到之前的commit
$git reset --hard HEAD~1
3.使用git stash
如果你跟我一样也使用gerrit做code review,那么有可能遇到这样问题:
在同一个分支上有多个bug需要fix,fix完一个bug然后就commit代码到gerrit server上等待code
review,在等待的过程中又开始fix另外一个bug,就在这个时候之前提交的代码被reviewer提示出错误,需要更新之前的代码,这个时候可以
使用git stash来保存当前本地的修改。
在一个分支上修改了代码但是不想commit到本地git库,需要切换一个分支去修改代码,这个时候也可以使用git
stash
$ git stash
# modify your code or checkout to another branch
# git commit --amend
$ git stash pop
4.从另外一个分支里面挑选一些commit到当前分支
假如你有两个分支,一个是dev分支,一个是release分支,在dev分支上已经有很了很多的commit,有时需要从dev分支上挑选一些commit到release分支上。
$ git log #查找到需要的commit id, 假设为5b531cb8c62cdb8b5f10c406e41824a6388e3a82
$ git checkout release
$ git log #看一下当前的commit log
$ git cherry-pick 5b531cb8c62cdb8b5f10c406e41824a6388e3a82
$ git log #此时可以看到commit log增加了
5. 出现error: The following untracked working tree files
would be overwritten by checkout
$ git clean -d -fx ""
6.我一次commit 5个文件到gerrit上面,然后发现有一个不需要提交,只要提交4个就好,我想重新提交一次在同一个commit
ID下面,我该怎么做?
前提代码还没有被merge进库
例如要取消文件2.txt, 那么先恢复2.txt到commit id 9a42e8e3f41dcf5029a11ce651f36cbdf37fc84d,你提交之前的那一个commit
id
git reset 9a42e8e3f41dcf5029a11ce651f36cbdf37fc84d
-- 2.txt
git checkout -- 2.txt
git add .
git commit --amend
转自:http://blog.chinaunix.net/uid-23366077-id-3581375.html
GIT和SVN之间的五个基本区别
GIT不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等。如果你是一个具有使用SVN背景的人,你需要做一定的思想转换,来适应GIT提供的一些概念和特征。所以,这篇文章的主要目的就是通过介绍GIT能做什么、它和SVN在深层次上究竟有什么不同来帮助你认识它。
那好,这就开始吧…
1.GIT是分布式的,SVN不是:
这是GIT和其它非分布式的版本控制系统,例如SVN,CVS等,最核心的区别。如果你能理解这个概念,那么你就已经上手一半了。需要做一点声明,GIT并不是目前第一个或唯一的分布式版本控制系统。还有一些系统,例如Bitkeeper,
Mercurial等,也是运行在分布式模式上的。但GIT在这方面做的更好,而且有更多强大的功能特征。
GIT跟SVN一样有自己的集中式版本库或服务器。但,GIT更倾向于被使用于分布式模式,也就是每个开发人员从中心版本库/服务器上chect
out代码后会在自己的机器上克隆一个自己的版本库。可以这样说,如果你被困在一个不能连接网络的地方时,就像在飞机上,地下室,电梯里等,你仍然能够提
交文件,查看历史版本记录,创建项目分支,等。对一些人来说,这好像没多大用处,但当你突然遇到没有网络的环境时,这个将解决你的大麻烦。
同样,这种分布式的操作模式对于开源软件社区的开发来说也是个巨大的恩赐,你不必再像以前那样做出补丁包,通过email方式发送出去,你只需要创建一个分支,向项目团队发送一个推请求。这能让你的代码保持最新,而且不会在传输过程中丢失。GitHub.com就是一个这样的优秀案例。
有些谣言传出来说subversion将来的版本也会基于分布式模式。但至少目前还看不出来。
2.GIT把内容按元数据方式存储,而SVN是按文件:
所有的资源控制系统都是把文件的元信息隐藏在一个类似.svn,.cvs等的文件夹里。如果你把.git目录的
体积大小跟.svn比较,你会发现它们差距很大。因为,.git目录是处于你的机器上的一个克隆版的版本库,它拥有中心版本库上所有的东西,例如标签,分
支,版本记录等。
3.GIT分支和SVN的分支不同:
分支在SVN中一点不特别,就是版本库中的另外的一个目录。如果你想知道是否合并了一个分支,你需要手工运行像这样的命令svn
propget svn:mergeinfo,来确认代码是否被合并。感谢Ben同学指出这个特征。所以,经常会发生有些分支被遗漏的情况。
然而,处理GIT的分支却是相当的简单和有趣。你可以从同一个工作目录下快速的在几个分支间切换。你很容易发现未被合并的分支,你能简单而快捷的合并这些文件。
4.GIT没有一个全局的版本号,而SVN有:
目前为止这是跟SVN相比GIT缺少的最大的一个特征。你也知道,SVN的版本号实际是任何一个相应时间的源代
码快照。我认为它是从CVS进化到SVN的最大的一个突破。因为GIT和SVN从概念上就不同,我不知道GIT里是什么特征与之对应。如果你有任何的线
索,请在评论里奉献出来与大家共享。
更新:有些读者指出,我们可以使用GIT的SHA-1来唯一的标识一个代码快照。这个并不能完全的代替SVN里容易阅读的数字版本号。但,用途应该是相同的。
5.GIT的内容完整性要优于SVN:
GIT的内容存储使用的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。这里有一个很好的关于GIT内容完整性的讨论
–http://stackoverflow.com/questions/964331/git-file-integrity |