git总结
Git 是一个分布式管理工具,通过指纹字符串来时刻保持数据的完整性,关心的是文件数据整体的变化,并不保存变化前后的差异数据;Git 在本地磁盘保存有关项目的历史更新,所有绝大多数操作只需要访问本地文件资源,并不需要Internet。当然可以使用GitHbub将代码托管,进行远程开发,方便团队比较分散的情况(这正体现Git分布式的优势);开发人员只需将项目clone到本地,进行相应的开发然后push上传到 GitHub(GitHub使用的是utf-8编码,所以上传的文件如若不是以utf-8编码,可能出现乱码),供别的开发人员更新即可。
任何文件在Git库中都有四种状态:未跟踪状态untracked、跟踪状态tracked(未修改状态unmodified、已修改状态modified、暂存状态staged),参考http://blog.csdn.net/u011384252/article/details/9406503
,由于文件的上述四种状态,在使用Git进行项目管理的时候涉及到三个区域:
(1)Git 本地数据目录:每个项目都有一个 git 目录,它是 Git 用来保存元数据和对象数据库的地方。该目录非常重要,每次克隆镜像仓库的时候,实际拷贝的就是这个目录里面的数据。
(2)工作目录(项目工作空间):从项目中取出某个版本的所有文件和目录,用以开始后续工作的叫做工作目录,即就是我们进行项目开发的目录。
(3)暂存区域:所谓的暂存区域只不过是个简单的文件,一般都放在 git 目录中。
Git本地仓库的基本用法:
① git init :初试化当前目录为一个Git本地仓库。
② git add : 如果一个文件是未被跟踪的,将 一个文件加入到Git版本控制当中,让Git对其进行跟踪;如果一个文件是已修改状态,则将一个文件放到暂存区中。
git add . : "."点表示当前目录下的所有内容
③ git status : 查看当前Git仓库中所有文件的状态,若是为跟踪状态 则用红色显示。
④ git diff:比较工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容。
⑤ git commit:提交暂存区域。
git commit -m <说明信息>
git commit -a 可以跳过暂存区域,直接将已跟踪的文件暂存起来一并提交。
⑥ git rm :从Git中删除一个文件。
git rm --cached :从暂存区删除一个文件,但是仍保留在工作目录中。也就是将文件变为未跟踪状态。
⑦ git log:查看项目提交历史记录。
git log -p 选项展开显示每次提交的内容差异
git log --stat 仅显示简要的增改行数统计
git log --pretty=
,其中option可以是:oneline(使每条历史信息在一行中显示),short,full,fuller,format(按指定的格式输出)gitk 可以打开历史记录的可视化查看窗口。
⑧ git commit --amend:修改最后一次提交。该命令是提交当前缓存区快照,并修改最后一次的说明。
⑨ git checkout -- :撤销对文件的修改,慎用!
⑩ git reset HEAD :撤销对文件的暂存,让文件回到暂存前的状态。
Git远程仓库的基本用法:
① git clone [url]:将一个远程仓库克隆到本地。
② git remote:查看当前配置的远程仓库,在克隆完某个项目后,至少可以看到一个名为origin的远程仓库,Git 默认使用这个名字来标识你所克隆的原始仓库。如git remote add origingit@github.com:usernmae/repositoryname.git
-v :显示对应的克隆地址。
git remote add [remote-name] [url]:添加一个新的远程仓库。
git remote show [remote-name]:查看远程仓库信息。
git remote rm [remote-name]:移除远程仓库。
git remote rename [old-remote-name] [new-remote-name]:重命名远程仓库。
③ git push [remote-name] [branch-name]:推送数据到远程仓库,remote-name指的是远程仓库简称,branch-name指的是分支名称。对于克隆的仓库默认分别为:origin,master
git push -u origin master //将本地的项目提交到远程仓库
Git将远程仓库GitHub取回本地:
① git [url] : 在git下切换到想要存放此项目的目录,运行这条命令就可以将项目克隆到本地磁盘的当前目录
②项目取回本地,远程仓库GitHub上有更新,取得更新
git fetch origin //开始取得更新
git merge origin /master //将更新内容合并到本地分支/master
======================================================================================================
Git基本概念
Git作为一个版本控制软件,相比其他版本控制软件有什么不同呢?
-
Git是一个分布式的版本控制系统,一般来讲,各个Git仓库没有主次之分;
-
大多数的操作可以在本地完成,事后方便时,再推送到中心服务器的仓库中;
-
采用“直接记录快照,而非差异比较”
的版本控制策略,内部只关心文件数据的整体是否发生改变,而不是文件内容的具体差异(Git内部被实现为一种微型的文件系统);
-
Git工作时就是在工作目录(工作区、work tree)、暂存区(索引、index file)、本地仓库
三者之间管理文件的变化情况,Git会监视工作目录中的文件变化(增加新文件,删除文件,修改文件等),需要我们自己手动将变化的文件添加(git add)到暂存区中(这就是文件快照),然后再提交(git commit)到本地仓库中;上述过程,涉及Git内部的三种对象:commit对象、tree对象和blob对象,blob对象会对应的文件快照中那些变化的文件内容,tree对象记录了文件快照中各个目录和文件的结构关系,从概念上讲,tree对象和blob对象组成了文件快照,commit对象则记录了这次要提交到本地仓库的文件快照,同时也会指向上次的commit对象,它也是Git内部进行版本控制的重点(Git内部会记录各个commit对象,并用HEAD来指示当前分支中最新的commit对象),很多重要的功能,如分支、版本回溯、Git仓库内部状态等都是在commit对象基础上实现的;上述的每一个对象都对应一个独一无二的ID,该ID是一个由40个字符组成的哈希码,由SHA-1算法计算而来;Git能够通过ID的前几个字符就识别出对应的对象;
-
Git的分支功能很强大,很灵活,切换速度非常快,并且实现成本很低,这也是Git比其他版本控制软件要受欢迎的原因之一;
-
Git拥有丰富的、功能强大的命令,一个命令通过配置不同的选项可以实现不同的功能;要学好Git,关键就是要掌握这些命令,并灵活使用它们;
Git常用命令解析
Git中有许多命令,并且每种命令都有一些功能选项可被选择,因此,在不熟悉Git这些命令的时候,查阅这些命令的使用说明是不错的选择。
要查询Git命令,可以使用git help 命令或者git 命令 –help的方式,它会自动打开浏览器来查看。
1. Git仓库创建
git init
在项目的开始,必须使用该命令来创建和初始化Git仓库,它会在项目的文件夹下生成一个隐藏的.git文件夹
,这就是这个项目的Git本地仓库,后面所有的Git命令操作都是针对该文件夹里的内容。执行过该命令后,原来的文件夹就成为了Git的工作目录。
Note:在一个已经初始化过的文件夹下再次执行git init
,Git并不会将之前的.git文件夹的内容清除,这应该是Git的一种保护。
.git文件夹的初始组成如下:
初始状态下,Git默认处于master分支,HEAD文件的内容为ref: refs/heads/master,但在refs/heads目录下却没有master文件;而objects文件夹下则没有文件。
在有过一次提交后,.git文件夹就会产生变化,如增加了logs文件夹,里面记录了git各种操作产生的log,我们通过git命令,如git log, git show, git reflog等可以查看这些log内容; 产生了一个index文件,这就是暂存区对应的文件; objects文件夹下新增了很多文件夹和文件,它们实际就是文件快照(tree对象和blob对象)存放的地方; refs/heads文件夹下这时生成了master文件,其内容就是master分支最新commit对象对应的ID;如果有其他分支,则在refs/heads文件夹下也会生成以分支名命名的文件,里面存储着该分支最新commit对象的ID。
2. 文件快照
git add .
在Git中,工作目录下文件的状态可以分为已跟踪和未跟踪两大类状态,其中,已跟踪的文件是指已经被提交到git仓库的那些文件,而未跟踪的文件是指还没被提交到Git仓库中的那些非Git忽略的文件(Git可以通过在项目根目录下产生一个.gitignore文件,在里面指定要忽略的文件类型,这样Git就不会去监视这些文件的变化),如果工作目录中已跟踪的文件被修改或者删除,或者有新的文件(包括非空文件夹)加入,则通过git status
可以查看到Git监视到文件变化情况,然后通过git add .
做一次文件快照,并将其存储到暂存区(index文件)中,等待被提交到Git仓库中。
3. 文件快照提交至仓库
git commit -m '本次提交文件变化的描述信息'
如果工作目录中的文件变化已经被暂存(也可以同git status
来查看),则说明这次的文件快照可以被提交到仓库中,并一直保存。
提交时,需要添加一些信息,这里最好要将这次的文件变化情况描述清楚,以便以后在版本回溯时能够了解到各版本之间的差别。
如果工作目录中仅是已跟踪的文件被修改或被删除,则可以不用先git add .
,直接使用git commit -am "描述信息"
即可。
4. 查看工作目录文件状态
git status
在git命令执行后,要养成通过git status
查看git状态的习惯,以便及时了解文件变化的情况。通过git status
可以知道文件的状态(已修改未暂存、已删除、已修改并已暂存等待提交、未跟踪)。
5. 查看提交历史
git log
通过git log
可以查看当前分支的所有提交历史,知道每次提交的commit对象的ID以及提交时附加的描述信息等。要显示更多的信息,需要使用其支持的选项,如git log -p
可以将每次提交的文件变化也显示出来。
Note : git log
显示的内容可能会比较多,但git bash上显示不下时,最下面会有一个冒号:,指示还有更多的内容,这是通过上下箭头就可以选择内容进行查看,要退出按q键即可,要查看其他命令,按h键。
6. 查看指定的提交对象
git show commit-id
通过git log
可以显示整个提交历史,而通过git show commit-id
则可以查看指定的某次提交内存,当然git show -all
也可以显示出提交历史,另外还可以格式化显示内容。具体请查看其help。
Note : commit-id可以是commit对象对应的ID,也可以是HEAD,分支名,tag等。
7. 查看工作目录/暂存区/仓库之间的差异
git diff
是比较工作目录与暂存区的差异
git diff HEAD
则是比较工作目录与仓库中最近一次的提交间的差异
git diff --cached
比较了暂存区与仓库中最近一次的提交间的差异。
8. 分支的创建、删除、切换、合并、查看
Git一个比较吸引人的功能就是其强大的分支和合并功能。初始状态下,Git默认的分支为master。
- 通过
git branch
可以查看目前Git仓库中已有的分支;
- 创建分支 :
git branch 新分支名 [分支起点]
,没有分支起点的话,则默认在当前分支的最新的提交上创建分支
- 切换分支 :
git checkout 分支名
- 创建同时切换到新分支 :
git checkout -b 新分支名 [分支起点]
- 合并分支到master分支 :
git checkout master
git merge 要被合并的分支名
,合并过程中如果发生冲突则需要自己手动解决冲突,然后再提交。有冲突时,Git会显示哪个文件有冲突,并在冲突的文件中加上特殊的标识符号,解决完冲突后,要手动去掉这些被添加的标识符号。如果冲突比较复杂的话,最好使用其他工具来协助,通过git mergetool来启动。冲突一般是在不同的分支上对同一文件的同一位置内容进行了改动,并已提交到仓库中,这样在合并的时候就会发生冲突。
- 删除已经被合并过的分支 :
git branch -d 要删除的分支
名,如果分支没有被合并过,该命令会执行失败
- 删除分支,不管有没有被合并过 :
git branch -D 要删除的分支名
- 用图形界面查看分支提交历史 :
gitk
充分利用好分支,可以帮助我们进行很好的版本控制与管理,如何用好分支其实是门艺术。
基于分支的版本控制模型有一篇文章进行了很好的阐述。
A succeddful Git branching model
中文翻译:Git分支管理是一门艺术
9. 标签的添加、删除、查看
标签可以在需要的地方,为某个提交对象创建别名,这样以后我们就可以通过标签来查看一些信息,创建分支等。
- 查看标签 :
git tag
- 创建简单的标签 :
git tag 标签名
- 创建附加信息的标签 :
git tag -a 标签名 -m '附加信息'
- 通过标签查看信息 :
git show 标签名
- 删除标签 :
git tag -d 标签名
10. 与远程仓库的交互
Git相比其他版本控制软件的一个优点就是大多数的操作都可以在本地进行,而不用管远程的仓库,因为操作是在本地,且操作的数据也是在本地,所以执行的速度就会比较快。 在多人协作的项目中,就需要涉及与远程仓库交互的问题,主要是如何从远程仓库抓取最新数据合并到自己的本地分支上,将自己的最新成果分享给其他人或让别人审查等 。
- 查看本地已经添加的远程仓库 :
git remote
仅显示已添加的远程仓库名,git remote -v
可以一并查看远程仓库的地址
- 在本添加远程仓库 :
git remote add 远程仓库名 远程仓库地址
- 删除本地添加的远程仓库 :
git remote rm 远程仓库名
- 重命名远程仓库名 :
git remote rename 原名 新名
- 克隆远程仓库到本地 :
git clone 远程仓库地址 [克隆到指定文件夹]
- 从远程仓库抓取最新数据到本地但不与本地分支进行合并 :
git fetch 远程仓库名
- 从远程仓库抓取最新数据并自动与本地分支进行合并 :
git pull 远程仓库名 本地要合并的分支名
- 将本地仓库推送到远程仓库中 :
git push 远程仓库名 本地分支名
- 查看远程仓库信息 :
git remote show 远程仓库名
- 将标签推送到远程仓库 :
git push 远程仓库名 标签名
, 默认Git是不会将标签推送到远程仓库的
11. 查看所有分支的所有的commit和reset操作记录(包括已删除的commit记录)
通过git reflog
可以帮助我们获得将工作目录恢复到某个状态所需的ID(可以用HEAD@{数字}来表示对应的ID)。
12. 撤销操作和版本回溯
有时候,由于我们的误操作,产生了一些错误,我们发现后希望能够及时纠正这些因为误操作而产生的结果,将工作目录恢复到某个正常状态。
- 撤销文件暂存,但还没有提交的文件:
git checkout -- filename
或git reset HEAD
,修改的文件会被恢复到上次提交时的状态,修改的内容会丢失
- 版本回溯 : [方法1] 根据分支或者标签将工作目录恢复到指定版本 :
git checkout 分支名或标签名
; [方法2] 先通过git reflog
找到某个版本的commit-ID,然后用git reset --hard commit-ID
将工作目录的文件恢复到指定的版本
- 恢复工作目录中被删除的文件 (文件之前被提交到仓库中):
git checkout -- filename
或 git checkout -f
或 git ls-files -d | xargs git checkout --
13. 备份工作目录
git stash
git stash list
git stash apply
git stash pop
git stash clear
如果正在一个develop分支上正在开发新功能,但这时master分支(稳定版本)突然发现了bug,并需要及时修复,而develop分支此时的工作还没有完成,且不希望将之前的工作就这样提交到仓库中时,这时就可以用git stash来暂时保存这些状态到Git内部栈中,并用当前分支上一次的提交内容来恢复工作目录,然后切换到master分支进行bug修复工作,等修复完毕并提交到仓库上后,再使用git stash apply [stash@{0}]
或者git stash pop
将工作目录恢复到之前的状态,继续之前的工作。
同时也可以多次使用git stash
将未提交的代码压入到Git栈中,但当多次使用’git stash’命令后,Git栈里将充满了未提交的代码,这时候到底要用哪个版本来恢复工作目录呢?git stash list
命令可以将当前的Git栈信息打印出来,我们只需要将找到对应的版本号,例如使用git stash apply stash@{1}
就可以用版本号为stash@{1}的内容来恢复工作目录。
当Git栈中所有的内容都被恢复后,可以使用git stash clear
来将栈清空。
14. 二分查找
git bisect
15. 垃圾回收
git gc
16. 将当前工作目录文件压缩归档(不包括.git目录)
git archive --format=zip -o arch.zip HEAD
或 git arch --format zip head>arch.zip
17. 跟上游分支同步
git rebase 上游分支名
假设master和develop是一个项目的两个分支,其中master是主分支,develop是从master而来的开发分支,如果在develop分支上提交过2次,之后又切换到master分支,做了一些修改并提交2次,这时,如果想将master分支的最新修改内容合并到develop分支,但同时也不能影响master分支时,就需要使用git rebase了,这时的上游分支为master。
18. 查看commit的次数
git shortlog -s -n
会显示出总的提交次数。
19. 查看仓库中commit对象、tree对象和blob对象
在我们将文件提交到Git仓库后,我们可以通过每次的commit对象的ID来查看文件快照的内容。
具体的方法就是:
-
先通过
git log
查看提交历史,选择需要查看的commit-id
-
git cat-file -t id
可以知道拥有该ID的对象是属于哪种类型:commit、tree、blob
-
git cat-file commit id
可以查看到该commit对象指向的tree对象的ID
-
git ls-tree tree-id
可以查看该tree中的blob对象的ID和其他tree对象的ID(如果有)
-
git cat-file blob blob-id
20. 查看仓库中index文件
通过git ls-files --stage
可以查看当前分支的index文件中有哪些文件,它列出了文件名及对应的blob对象的ID。
21. 查看仓库目录结构
find
可以列出.git目录下所有目录和文件,这样就可以清楚地知道当前仓库的目录结构。
22. 查看文件的修改历史
git blame filename
可以列出该文件每次被修改的时间和内容。
23. 常用的linux命令
- 创建文件夹
mkdir
- 删除文件夹
rmdir
- 查看文件列表
ls
- 查看文件内容
cat
- 回显 和 管道命令
echo "hello" >> file.txt