[TOC]
git 常用概念和基础
git 分支的概念
该对象包含一个指向暂存内容快照的指针,包含本次提交的作者等相关附属信息,包含零个或多个指向该提交对象的父对象指针:首次提交是没有直接祖先的,普通提交有一个祖先,由两个或多个分支合并产生的提交则有多个祖先
每次commit 生成一个hash value,对应这次提交的内容.
Git 原理图
git 常用命令
git branch 管理分支
git branch -l 查看分支列表;
git branch -m <old_branch> <new_branch> 修改分支名称;
git checkout -b new_branch 切换到一个新建的分支; ()
git branch <shortname> 新建分支;
git branch --no-merged 查看未合并的分支;
git branch --merged 查看已合并的分支
git branch -d shortname(分支名称) 删除一个分支;
git branch -v 查看最后一个提交对象
git branch -a -a参数可以查看远程分支,远程分支会用红色表示出来; (fetch 后可以直接checkout 到远程的某一个分支)
git push origin —delete <branchname> 删除远程分支;
-
git push origin —delete tag <tagname> 删除远程的标签;
git add
暂存已经修改的文件, 跟踪文件,.通配符暂存所有已修改的文件
git status
状态简览, 加 -s 可以让格式更加紧凑
git commit
提交暂存区的文件到仓库
git pull
从远端仓库拉取文件到本地并与本地分支合并.例子: git pull origin master, 从origin仓库拉取master分支到本地并合并;
git push
推送本地分支的修改文件到origin仓库(其实是一个链接的代称)的master分支,并合并代码,例子: git push origin master;
git log 查看记录
查看提交内容
- git log -n 1 -stat #查看到最近一次提交所有更改过的文件
- git log -n 1 -p #查看最近一次提交所有更改的细节
- git log -p — 文件路径 #查看这个这个文件的所有提交记录
- git show (commit 哈希值) 文件路径 #查看单个文件在某一个提交的修改
- git log [—author=Wenhao] #查看特定人员的提交
比较两个分支
git log master ^fix_branch # 比较两个分支的不同的地方,例子是 master 中有,而fix_branch 中没有的commit.同理,查看fix_branch 中有而master 中没有的commit
git log fix_branch ^master
;git log dev…master #不知道谁提交的多谁提交的少,单纯比较两个分支的不同;
-
git —left-right dev…master #在上述情况下,在显示每个提交在那个分支上;
给事话输出历史提交
-
git log —pretty=oneline #输出的提交记录分行显示,更有条理
![](/Users/sks/Desktop/屏幕快照 2017-03-14 下午2.55.34.png)
git tag -标签
git tag v0.4.0 -light #创建轻标签
**git tag -a v1.0.8(3) -m ** #创建附注标签
git tag -l #查看标签列表;
git tag -d v0.4.0 #删除指定标签;
git tag -a v1.0 9fbe3.. (commit 的hash value) # 给指定的提交打标签
git push origin v1.0.8 #提交标签v1.0.8 到git 服务器
-
git push origin -tags #将本地所有标签一次都提交到服务器
git reset and revert — 查看历史记录
git 中用HEAD
表示当前版本,其实就是一个指向某一次commit的指针.HEAD^
就是上一次commit,HEAD^^
上一次提交,HEAD~100
前一百次的commit
git reset 用于代码回滚.git reset —hard HEAD^回滚到当前的前一次提交. git reset —hard 34434ef(commit id) 回滚到某一次提交.
bogon:Show sks$ git reset --hard 44e62d03aeb4fdc9e3b84f7b51fe8720c8b9f2e6
HEAD is now at 44e62d0 Merge remote-tracking branch 'origin/master'
checkout 到远程分支
git branch -a 查看远程分支;
git fetch origin fetch远程分支到本地
git checkout [branch-name] (注: 不需要加上remote origin, 如 origin/develop)
git rebase 分支的衍合
衍和基本使用
在主分支上gitcheckout -b experiment 生成一个测试分支,修改文件条件后生成快照C3
![](file:////Users/sks/Library/Group%20Containers/UBF8T346G9.Office/msoclip1/01/DD084AEC-84B4-A845-8BB7-B6C0488FAE94.png)
之前介绍过,最容易的整合分支的方法是 merge 命令,它会把两个分支最新的快照(C3和 C4)以及二者最新的共同祖先(C2)进行三方合并,合并的结果是产生一个新的提交对象(C5)
![](file:////Users/sks/Library/Group%20Containers/UBF8T346G9.Office/msoclip1/01/81371B41-EBD9-D94E-8A3C-0DA730CF6B77.png)
还有另一合并方法-衍和.
你可以把在 C3 里产生的变化补丁在 C4 的基础上重新打一遍。在 Git 里,这种操作叫做衍合(rebase)。有了 rebase 命令,就可以把在一个分支里提交的改变移到另一个分支里重放一遍。
![](file:////Users/sks/Library/Group%20Containers/UBF8T346G9.Office/msoclip1/01/B3A77D28-5EFD-2143-B9ED-B6F0D0D6667B.png)
![](file:////Users/sks/Library/Group%20Containers/UBF8T346G9.Office/msoclip1/01/E60BDAFD-E375-074F-8129-596B7243D570.png)
Gitcheckout experiment
Gitrebase master
First,rewinding head to replay your work on top of it... Applying: added stagedcommand
他们的原理是,回到两个分支最近的共同祖先 ,根据当前分支(也就是也就是进行衍和的experiment分支)后续历次提交对象(这里只有C3),生成一系列补丁文件,然后以基底分支(也就是主干分支master)的最后一次提交对象为新的出发点,逐个应用之前的准备好的补丁文件,生成一个新的合并提交对象C3',从而改变experiment的提交历史
使它成为master的直接下游.让提交记录变得干净. 最后的C3'和C5的结果是一样的
衍和的进阶使用- 在其他分支上进行衍和
![](file:////Users/sks/Library/Group%20Containers/UBF8T346G9.Office/msoclip1/01/024EA003-ACA7-184E-A342-39BDA45CC6FE.png)
在一个特性分支是在分出一个特性分支的历史
将设我们先把客户端的修改并入到主分支,暂缓服务端的并入(因为还需要进一步测试).这个时候,我们可以把基于client分支而非server分支的改变(C8,C9),跳过server分支直接在master分支里重演一遍.但这需要gitrebase 的 onto 指令指定新的基底分支master
Git rebase --onto master server client
这好比在说:“取出 client 分支,找出 client 分支和 server 分支的共同祖先之后的变化,然后把它们在 master 上重演一遍”。是不是有点复杂?不过它的结果如图3-32 所示,非常酷(译注:虽然 client 里的 C8, C9 在 C3 之后,但这仅表明时间上的先后,而非在 C3修改的基础上进一步改动,因为 server 和 client 这两个分支对应的代码应该是两套文件,虽然这么说不是很严格,但应理解为在C3 时间点之后,对另外的文件所做的 C8,C9 修改,放到主干重演。):
![](file:////Users/sks/Library/Group%20Containers/UBF8T346G9.Office/msoclip1/01/C6A5DF5B-3AA6-1142-82C4-BE8C463E0152.png)
将特性分支上的另一个特性分支衍和到其他分支
现在可以快进maste分支了
Git checkout master;
Git merge client;
快进master分支,使之包含client的变化
把server分支的变化也包含进来,可以直接把server衍和到master,而不用手动切换到server分支再进行衍和— git rebase [主分支] [特性分支] 命令会先取出特性分支 server,然后在主分支 master 上重演:
Gitrebase master server;
Gitrebase master server;
于是server的变化被包含到master
然后快进master分支
Gitcheckout master;
Git mergeserver;
现在client和server的变化都合并到master分支,可以删除特性分支了
Gitbranch -d client;
Gitbranch -d server;
最终我们的提交历史会是这样
![](file:////Users/sks/Library/Group%20Containers/UBF8T346G9.Office/msoclip1/01/64F901D7-AB61-124C-8550-E3D3C609BEA6.png)
衍和的风险
必须遵守一条准则: 一旦分支中的修改对象提交到公共仓库,就不要对该分支进行衍和操作.
原因 :
在进行衍合的时候,实际上抛弃了一些现存的提交对象而创造了一些类似但不同的新的提交对象。如果你把原来分支中的提交对象发布出去,并且其他人更新下载后在其基础上开展工作,而稍后你又用 gitrebase 抛弃这些提交对象,把新的重演后的提交对象发布出去的话,你的合作者就不得不重新合并他们的工作,这样当你再次从他们那里获取内容时,提交历史就会变得一团糟。
git diff
git diff 查看已暂存和未暂存的更新
git remote 相关的命令
- git remote 查看当前的远程库;
- git remote add <shortname> <url> : 添加远程仓库;
- git remote show [remote-name] 查看某个远程仓库的详细信息
- git remote rename 命令修改某个远程仓库在本地的简称
- git remote rm 移除对应的远端仓库
git 其他命令
git reflog
Git提供了一个命令git reflog
用来记录你的每一次命令
bogon:Show sks$ git reflog
0b7e40c HEAD@{0}: commit: 郭华兵
594d9ef HEAD@{1}: commit: 郭华兵
045cb6e HEAD@{2}: commit: 郭华兵
e4b50cf HEAD@{3}: commit: 郭华兵
44e62d0 HEAD@{4}: merge origin/master: Merge made by the 'recursive' strategy.
d934ed9 HEAD@{5}: commit: 郭华兵
5c8fbc7 HEAD@{6}: merge origin/master: Merge made by the 'recursive' strategy.
mac 生成ssh 公钥私钥
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
ssh-keygen -t rsa -C "xxxxx@xxxxx.com"
git 注意事项
- 对一个新的文件使用git进行管理时,一定要添加.gitignore 文件;
参考链接
(http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html)