[TOC]
基本概念
-
master
指针:指向最新的提交
资料
http://sfault-image.b0.upaiyun.com/37/92/37923f2478edc5709b36562b26c9e008
全局配置
$ git config --global user.name "kk"
$ git config --global user.email "xxx@gmail.com"
-
编辑模式查看全局设置:
git config --global -e
-
列表形式查看全局设置:
git config --global -l
使用GitHub时,在本地创建SSH Key
ssh-keygen -t rsa -C "youremail@example.com"
-
如果一切顺利的话,可以在用户主目录里(~/.ssh)找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
-
第2步:登陆GitHub,打开“Account settings”,“SSH Keys”页面:
然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容
远程仓库
-
克隆远程仓库到本地
git clone git@github.com:michaelliao/gitskills.git
-
克隆远程仓库某个分支到本地
git clone -b <branch> <remote_repo>
例如:git clone -b 指定的分支名字
-
给本地仓库指定远程仓库
-
关联GitHub仓库:
git remote add origin git@github.com:michaelliao/learngit.git
-
显示远程仓库:
git remote show origin
第一次推送使用:
git push -u origin 分支名称
之后推送使用:
git push origin maste
-
查看远程仓库地址
git remote -v
-
取消关联远程仓库
git remote rm origin
初始化git仓库
git init
git add .
git commit -m “xxxx"
文件操作
删除所有文件
git rm * -r
删除文件夹
git rm filename -r
忽略无需版本控制的文档
echo “*.txt” > .gitignore
日志
查看commit日志
git reflog
或
git log
分支管理
- 查看当前所在分支
git branch -a
- 切换到某个分支
git checkout 分支名字
- 创建本地分支并切换到创建的分支:
git checkout -b your_branch
- 提交该分支到远程仓库
git push origin dev
- 追踪远程分支
git branch --track release_2.3.0 origin/HEAD:refs/for/release_2.3.0
- 将本地分支push到远程分支,(远程会自动创建your_branch分支),并关联本地分支与远程分支
git push -u origin your_branch
- 删除远程分支
git push origin --delete <branchName>
- 删除本地分支
git branch -d your_branch
本地提交回滚
- 先重置本地在上次提交之后的修改(如果需要的话)
git checkout *.m
- 重置为远程仓库的最新版本
soft表示本地的修改还在本地文件中,不加的话那么本地的修改也没了
git reset HEAD^ --soft
拉取远程代码时冲突
- 保存本地修改到暂存区
git stash
- 拉取远程代码
git pull
- 将暂存区内容恢复到本地,有冲突时先解决冲突
git stash pop
git stash 的使用
- 列出所有暂时保存的工作
git stash list
- 恢复某个暂时保存的工作
git stash apply stash@{1}
-
保存stash时设置stash名称
git stash save "my_stash"
-
丢弃最近一次stash的文件
git stash drop
合并某次提交 merge a specific commit in Git
git cherry-pick d42c389f
git merge 后 push 到 Gerrit 失败,提示 no new changes
- 在
git merge
的时候,加上--no-ff
参数,是为了让它生成一个新的 commit,这样就可以提交了~(不过生成的 gerrit change 是看不到改动信息的)
tag 操作
- 查看tag
git tag
- 创建 本地 tag
git tag 1.0.0
或者
git tag -m "first release" 0.1.0
- 推送 本地 tag 到远程服务器
git push origin 1.0.0
- 或者推送所有tags到远程服务器
git push --tags
- 删除本地 tag
git tag -d 1.0.0
- 删除远程 tag
- 先删除本地 tag
git tag -d 1.0.0
- 然后push
git push origin --delete tag 1.0.0
fatal: remote origin already exists.
错误解决
- 先删除远程 Git 仓库
git remote rm origin
2 再添加远程 Git 仓库
git remote add origin git@github.com:FBing/Java-code-generator
git ignore
- 创建
.gitignore文件
touch .gitignore
忽略规则示例
# 这是注释行,将被忽略
*.a # 忽略所有以.a为扩展名的文件
!lib.a # 但是名为lib.a的文件或目录不要忽略,即使前面设置了对*.a的忽略
/TODO # 只忽略此目录下的TODO文件,子目录中的TODO文件不忽略
build/ # 忽略所有build目录下的文件,但如果是名为build的文件则不忽略
doc/*.txt # 忽略文件如doc/notes.txt,但是文件如doc/server/arch.txt不忽略
例如忽略下图的GPUImage.framework框架
SystemVedio/GPUImage/GPUImage.framework
6218590.png
只追踪某几个文件
#忽略所有文件,注意放在开头
/*
#除src文件夹外
!/src
#除bin文件夹外
!/bin
#总的效果就是git只跟踪src和bin两个文件夹
merge 与 rebase 的区别
参考:https://www.zhihu.com/question/36509119/answer/131513261
搞清楚这个问题首先要搞清楚merge和rebase背后的含义。
merge:会产生一次合并提交
先看merge,官方文档给的说明是:
git-merge - Join two or more development histories together
顾名思义,当你想要两个分支交汇的时候应该使用merge。
根据官方文档给的例子,是master merge topic,如图:
A---B---C topic
/
D---E---F---G---H master
然而在实践中,在H这个commit上的merge经常会出现merge conflict。为了避免解决冲突的时候引入一些不必要的问题,工程中一般都会规定no conflict merge。比如你在github上发pull request,如果有conflict就会禁止merge。
所以才会有题主问的问题:在当前的topic分支,想要引入master分支的F、G commit上的内容以避免merge conflict,方便最终合并到master。
这种情况下用merge当然是一个选项。用merge代表了topic分支与master分支交汇,并解决了所有合并冲突。然而merge的缺点是引入了一次不必要的history join。如图:
A--B--C-X topic
/ /
D---E---F---G---H master
其实仔细想一下就会发现,在引入master分支的F、G commit这个问题上,我们并没有要求两个分支必须进行交汇(join),我们只是想避免最终的merge conflict而已。
rebase:将其他分支的内容整合到当前分支,改变当前分支branch out的位置
rebase是另一个选项。rebase的含义是改变当前分支branch out的位置。这个时候进行rebase其实意味着,将topic分支branch out的位置从E改为G,如图:
A---B---C topic
/
D---E---F---G master
在这个过程中会解决引入F、G导致的冲突,同时没有多余的history join。但是rebase的缺点是,改变了当前分支branch out的节点。如果这个信息对你很重要的话,那么rebase应该不是你想要的。rebase过程中也会有多次解决同一个地方的冲突的问题,不过可以用squash之类的选项解决。个人并不认为这个是rebase的主要问题。
综上,其实选用merge还是rebase取决于你到底是以什么意图来避免merge conflict。实践上个人还是偏爱rebase。一个是因为branch out节点不能改变的情况实在太少。另外就是频繁从master merge导致的冗余的history join会提高所有人的认知成本。
网友评论