###分布式版本控制系统:
客户端并不只是提取最新版本的文件快照,而是把代码仓库完整的镜像下来。这样一来,任何一处协同工作的服务器发生故障,时候都可以用任何一个镜像出来本地仓库恢复。因为每一次的克隆操作,实际上都是一次对代码 仓库的完整备份。
###基础
git把数据看作是对小型文件系统的一组快照。每次提交更新,或在git中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。为了高效,如果没有文件修改,git不在重新存储该文件,而是保留一个链接只想之前存储的文件。git对待数据更像是一个快照流。
###三种状态:
已提交(committed):表示数据已经安全的保存在本地数据库中。
已修改(modified):表示修改了文件,但还没有保存到数据库中。
已暂存(staged):表示对一个已经修改文件的当前版本做了标记,使之包含在下次提交的快照中。
###三种状态对应的三个工作区域:
git仓库:用来保存项目的元数据和对象数据库的地方。从其他计算机克隆仓库时,拷贝的就是这里的数据。
工作目录:是对项目的某个版本独立提取出来的内容。这些从Git仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用和修改。
暂存区域:是一个文件,保存了下次将提交的文件信息列表,一般在Git仓库目录中。
###git的命令行:
配置用户信息:
git config --global user.name "Roger"
git config --global user.email "123456@qq.com"
使用–global配置,该命令只需要运行一次。如果想针对不同的项目使用不同的用户名与邮箱地址,可以在那么项目目录下运行没有–global选项额命令来配置。
检查配置信息:
//列出git所有的配置
git config --list
//检查git的某一项配置
git config <key>
//git config user.name
获取Git仓库:
1.在现有目录中初始化仓库:
//生成.git子目录,初始化git仓库所有必须的文件
git init
//将文件加入git仓库中,可以开始跟踪对应的文件
git add *.c
git add LICENSE
git commit -m "initial project version"
2.克隆现有的仓库:
//clone远程git仓库,并且使用默认的仓库名
git clone [url]
//clone远程git仓库,并且命名本地的仓库名为[name]的名字
git clone [url] [name]
检查当前文件状态:
git status
//简筒模式
git status -s / git status --short
//输出格式
$ git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt
??:表示新添加的未跟踪文件。
A:表示新添加到暂存区的文件。
右边M:表示该文件被修改了但是还没有放到暂存区。
左边M:表示该文件被修改了并放入了暂存区。
MM:表示文件在工作区被修改并提交到暂存区后又在工作区中被修改了,所以在暂存区和工作区都有该文件被修改的痕迹。
//查看未暂存的文件的更新了哪些部分。比较的是工作目录中当前文件和暂存区域快照之间的差异
git diff
//查看已暂存的将要添加到下次提交的更新内容
git diff --cached / git diff --staged
跟踪文件:
//多功能命令:可以用它开始跟踪新文件,或者把以跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态。
git add
提交更新:
//将暂存区的文件上传到git分支仓库
git commit -m "提交说明"
//跳过暂存区,直接将工作目录的文件提交到git分支仓库
git commit -a -m "提交说明"
移除文件:
//删除工作目录的文件
rm project.md
//删除已跟踪文件(就是暂存区文件)并且连带将工作目录中指定文件删除
git rm project.md
//删除修改过并放入暂存区的文件
git rm -f project.md
//删除git仓库中的文件或目录,但是仍希望保留在当前工作目录中。
git rm --cached project.md
移动文件:
//重命名某个文件
git mv file_from file_to
//相当于下面三条命令
mv file_from file_to
git rm file_from
git add file_to
查看提交历史:
//按提交时间列出所有的更新。
git log
//显示每次提交内容的差异,也可以加上-2来仅显示最近两次提交。
git log -p -2
//查看每次提交的简略统计信息
git log --stat
//一行显示log信息
git log --pretty=online
//格式化显示log信息
git log --pretty=format:"%h - %an,%cd : %s"
//添加一些ASCII字符串来形象的展示你的分支、合并历史。
git log --pretty=format:"%h %s" --graph
//条件性的输入log信息
//最近两周的提交
git log --since==2.weeks
//查找提交或删除某一个特定函数的引用提交
git log -S function_name
撤销操作:
//当我们发现漏掉了几个文件没有添加,或者提交信息写错了,可以使用这个命令。
git commit --amend
//取消暂存的文件:加上HEAD会让这个命令成为一个危险的命令(可能导致工作目录中所有当前进度丢失)。不加并不危险,只会修改暂存区域。
git reset HEAD <file>
//撤销文件在工作目录的修改
git checkout - <file>
###远程仓库的使用
管理远程仓库包括了解如何添加远程仓库、移除无效的远程仓库、管理不同的远程分支并定义他们是否被跟踪等等。
查看远程仓库:
//列出指定的每一个远程服务器的简写。origin是git给clone的仓库服务器的默认名字。
git remote
origin
//查看远程仓库的更多信息
git remote show [remote_name]
//列出需要读写的远程仓库git保存的简写和其对应的URL
git remote -v
//添加远程仓库,同时指定一个你可以轻松引用的简写[shortname].
git remote add [shortname] [url]
//从远程仓库中拉取,但不会自动合并和修改当前的工作,需要手动合并。
git fetch [remote_name]
//从远程拉取并自动合并到当前分支
git pull
//推送到远程分支
git push [remote_name] [branch_name]
//重命名远程仓库的简写
git remote rename [origin_name] [new_name]
//移除远程仓库
git remote rm [remote_name]
###打标签
1.创建标签:
Git使用两种主要主要类型标签:轻量标签(lightweight)与附注标签(annotated)。
一个轻量标签很像一个不会改表的分支-它只是一个特定提交的引用。如果想创建一个临时标签或者因为默写原因保存附注标签的那些信息,就可以使用这个标签。本质上是将提交验证和存储到一个文件中,没有保存任何其他信息。
附注标签是存储在Git仓库中的一个完整对象。它可以被校验的;其中包含打标签者的名字、电子邮箱地址、日期时间;还有一个标签信息;并且可以使用GPU Privacy Guard(GPG)签名与验证。
//以字母顺序列出标签
git tag
//特定模式查找标签
git tag -l 'v1.8.5*'
//打附注标签
git tag -a v1.4 -m "标签信息"
//查看标签信息和对应的提交信息
git show v1.4
//打轻量标签:
git tag v1.4-1w
//后期打标签:git tag -a v1.2 9fcebo2
git tag -a [tag_name] [校验和(或部分校验和)]
//共享标签:默认情况下,git push命令并不会传送标签到远程仓库服务器上,必须要显示的推送标签到共享服务器上。git push origin [tag_name]
git push origin v1.5
//一次推送多个标签
git push origin --tags
//删除标签
//这个命令不会从远程仓库中移除一个标签,需要用git push <ogirin> :refs/tags/<tagname>
git tag -d v1.2
git push origin :refs/tags/v1.2
//检出标签:会使仓库处于"分离头指针(detacthed HEAD)"状态(有些不好的副作用)
git checkout v1.2
//在“分离头指针”状态下,如果你做了某些更改然后提交它们,标签不会发生变化,但你的新提交将不属于任何分支,并且将无法访问,除非确切的提交哈希。因此,如果你需要进行更改——比如说你正在修复旧版本的错误——这通常需要创建一个新分支
git checkout -b version2.0 v1.2
###分支简介
创建分支是开发工作从主线分离开来,以免影响主线开发。
git保存的不是文件的变化或者差异,而是一系列不同时刻的文件快照。
//创建testing分支
git branch testing
//查看各个分支当前所指的对象
git log --online --decorate
//切换分支
git checkout testing
//查看分叉历史
git log --online --decorate --graph --all
//新建分支,并切换到新建的分支上
git checkout -b dev
//合并分支
//切换到主线
git checkout master
//合并分支内容到主线上
git merge dev
//删除没用的分支
git branch -d dev
//查看所有分支:*代表当前所在的分支
git branch
//查看所有分支的最后一次提交信息
git branch -v
//查看已经merge的分支
git branch --merged
//查看还没有merge的分支
git branch --no-merged
远程分支:
//获取远程引用的完整列表
git ls-remot (remote)
//获取远程分支的更多信息
git remot show (remote)
//公开分享分支serverfix
git push origin serverfix
//跟踪分支:git checkout -b [branch] [remotename]/[branch]
git checkout --track origin/serverfix
//设置本地的分支跟踪一个远程分支,使用-u
git branch -u origin/serverfix
//查看设置的所有分支和分支跟踪的远程分支信息
git branch -vv
//删除远程分支:这个明恋只是从服务器上移除这个指针。git服务器通常会保留数据一段时间指导垃圾回收运行。
git push origin --delete serverfix
变基:
//将一个分支变基到另一个目标分支上,再将目标分支merge到主线上
git checkout server
git rebase master
git checkout master
git merge server
//讲一个分支的子分支变基到目标分支上(client是server的分支)
//意思:取出client分支,找出处于client分支和server分支的共同祖先之后的修改,然后把它们在master分支重放一遍。
git rebase --onto master server client
//快速的将一个分支变基到目标分支:git rebase [basebrach] [topicbranch]
git rebase master server
变基的风险:不要对在你的仓库外有副本的分支执行变基。
###Git分布式
1.分布式工作流程的三种方式:
集中式工作流
集中管理者工作流
司令官与副官工作流
###向一个私有团队贡献
git clone [short_name] [remote_url]
git checkout -b [branch_name]
git add .
git commit -m ""
git checkout master
git fetch origin
git merge origin/master
git merge [branch_name]
git push origin master
###向私有管理团队贡献
git clone [short_name] [remote_url]
git chckout -b [branch_name]
git add .
git commit -m ""
//将本地分支推送到服务器,通知管理员合并分支
git push -u origin/master [branch_name]
###派生的公开项目
git clone [remote_url]
git checkout -b featureA
//在分支完成工作后,需要将完成的工作贡献给维护者,去原始项目fork一个自己可以写的项目派生仓库。然后添加这个新仓库的url为第二个远程仓库。
git remote add myfork [fork_url]
//将分支推送到派生仓库上
git push -u myfork featureA
//拉取请求(git request-pull),通知维护者合并分支
git request-pull origin/master myfork
//将基于maste的分支变基到origin/master上
git checkout featureA
git rebase origin/master
//变基后必须使用-f推送,这样才能将服务器上有一个不是它的后代的提交分支featureA分支替换掉。
git push -f myfork featureA
//--squash选项接受被合并的分支的所有工作,并将其压缩至一个变更集,是仓库变成一个真正的合并并发的状态,而不会真的生成一个合并提交。
//将featureB分支合并到featureBv2分支上
git checkout -b featureBv2 origin/master
git merge --squash featureB
###通过邮件的公开项目
//git format-patch生成可以邮寄到列表的mbox格式的文件。生成的邮件保留了所有的提交信息。
//-M开头告诉Git查找重命名。
git format-patch -M origin/master
//通过IMAP服务发送邮件:使用git imap-send将补丁序列放到IMAP服务器的Drafts文件夹中。
cat *.patch |git imap-send
//或者使用SMTP服务器发送补丁。
git send-email *.patch
##项目维护
###在特性分支中工作
git checkout -b sc/ruby_client master
###使用apply命令应用补丁
接受使用git diff创建的补丁。
//apply与patch -p1命令几乎是等效的,但是apply更加严谨,能够接受的模糊匹配更少,能够处理git diff格式文件所描述的文件添加、删除和重命名操作。并且apply采用“全部应用,否则就全部撤销”的模型。在运行后,需要手动暂存并提交补丁所引入的更新。
git apply /tmp/patch-ruby-client.patch
//对补丁进行检查
git apply -check 0001-seeing-if-this-helps-the-gem.patch
###使用am命令应用补丁
接受format-patch生成的补丁。是为了读取mbox文件而构建的。mbox是一种用来在单个文本文件中存储一个或多个电子邮件信息的简单纯文本格式
$ git am 0001-limit-log-function.patch
##git工具
###选择修订版本
//为SHA-1值生成简短且唯一的缩写。
git log --abbrev-commit --pretty=online
//引用日志
//查看引用日志
git reflog
//查看HEAD前五次的所指向的提交
git show HEAD@{5}
//提交区间
//双点:git选出在一个分支中而不在另一个分支中的提交。
git log master..experiment
//多点.下面三个命令相同
git log master..experiment
git log ^master experiment
git log experiment -not master
//查看超过两个引用
git log refA refB ^refC
git log refA refB -not refC
//三点:选出被两个引用中的一个包含但又不被两者同时包含的提交。
git log master...experiment
//--left-right:显示每个提交到底处于那一侧的分支
$ git log --left-right master...experiment
###储藏与清理
//储藏修改
git stash / git stash save
//查看储藏的东西
git stash list
//重新应用最近一次的储藏
git stash apply
//重新应用某一次的储藏
git stash apply stash@{2}
//移除某一个储藏:git stash drop 加上要移除的储藏的名字
git stash drop stash{1}
//应用储藏然后立即从栈上移除
git stash pop
//不储藏任何通过git add命令暂存的东西
git stash --keep-index
//使用--include-untracked或-u储藏新建的为跟踪的文件
git stash --include-untracked / git stash -u
//--patch告诉git不会储藏所有修改过的东西,但是会交互式地提示哪些改动想要储藏、哪些改动需要保存在工作目录中。
git stash --patch
//从储藏创建一个分支
git stash branch testchanges
//移除每一样东西并放入栈中
git stash --all
//移除工作目录中所有未跟踪的文件以及空的子目录。-f意味着强制或"确定移除"
git clean -f -d
//演练将要移除那些内容
git clean -d -n