1. git client与远程仓库的2种通信方式
1) https
a) 设置remote仓库的url: git remote set-url origin https://github.com/{username}/{ProjectName}.git
这里的username指的是github的用户名,而非git config的用户名,实际上github使用email作为用户身份的标识
b) 设置免密输入: 使用 credential.helper
+ $ vi ~/.git-credentials
+ 添加内容 https://{username}:{passwd}@github.com
+ $ git config --global credential.helper store
+ 查看 ~/.gitconfig的变化: $ vi ~/.gitconfig
取消免密输入: git config --global --unset credetial.helper
注意切换到ssh时要取消免密输入
2) ssh
a) 设置remote仓库的url: git remote set-url origin git@github.com:{username}/{ProjectName}.git
b) 设置免密输入,使用公钥凭证
+ 在本地产生一对公钥和私钥: ssh-keygen -t rsa -C “baoshanw@foxmail.com”
+ 进入 ~/.ssh文件夹,查看产生的公钥和私钥: id_rsa.pub, id_rsa
+ 将公钥的内容复制到github的git server: settings/SSH and GPG keys
+ 验证通信: ssh -T git@github.com,即验证能否登录进github提供的git账户
2. 常见问题:
- 访问远程仓库提示 failed to connect to 127.0.0.1 port 46759: 拒绝连接
原因: 本地端口46759被当做代理占用了
解决: unset该代理
$ env | grep -i proxy
$ unset 对应的环境变量
3. git的原理
git用于文件的版本管理,存储的是文件的快照,而非差异比较,属于分布式的VCS,通过单个节点的git仓库即可完整恢复整个项目;
git的提交在本地进行,不需要与server通信;
git保证数据的完整性,数据存储前均会计算校验和,因此不可能在git不知情时更改任何文件或目录,git使用SHA-1散列计算校验和
由git管理的文件的三种状态: 已修改(modified), 已暂存(staged), 已提交(committed)
因此git项目有三个阶段: 工作区, 暂存区(索引), git仓库
基本git工作流程:
- 在工作区修改文件
- 选择性的暂存某些文件
- 提交暂存区的文件到git仓库
4. git操作
git配置:
- 配置文件: /etc/gitconfig(全局), ~/.gitconfig(当前用户), .git/config(具体项目)
- 配置命令:
git config [–system] [–global] [–local] [–list]
帮助信息: git help ; git --help; man git
获取git仓库
- 本地目录转换: git init
- 从外部clone: git clone {repository}
clone执行的操作:
a) 在当前文件夹创建同名的目录
b) 在该目录下初始化.git目录
c) 从远程仓库拉取所有数据存放到.git
d) 将本地分支master指向origin/master,该origin/master指向远程仓库的master分支
e) 从中读取最新版本文件的拷贝
记录更新到仓库
git add {file}: 开始跟踪,存放到暂存区
git status [-s]: 查看状态
.gitignore 忽略跟踪列表
git diff 已修改文件和上次暂存文件的对比
git diff --staged 已暂存的文件和上次提交文件的对比
git diff --check 提交前检查是否存在空白错误
git commit [-m] 提交暂存区文件到仓库,加入comment(详细?简略)
git commit -a 跳过暂存把所有跟踪的文件暂存起来一并提交
git rm --cached {file} 从暂存区移除,不再跟踪
git rm [-f] {file} 从暂存区移除,并从磁盘上删除
git mv {file_from} {file_to} 改名并在磁盘上操作
实际执行: mv {file_from} {file_to}; git rm {file_from}; git add {file_to}
查看提交历史
git log -p 显示每次提交引入的差异
git log --stat 简略的统计信息
git log --pretty=oneline 将每个提交放在一行显示
git log --pretty=format:"%h - %an, %ar : %s" 格式化log
git log --graph 显示分支及其合并历史
git log --since --until 指定时间范围内的历史
git log --author {name} 匹配作者名字
撤销操作
git commit --amend 对上次提交做修补,只记录一次提交,避免因小失误弄乱提交历史
git reset HEAD {file} 撤销暂存,危险命令(工作区文件已修改却撤销上一次暂存恢复到工作区,覆盖修改)
git checkout – {file} 撤销对文件的所有修改,恢复到上次提交时的状态,危险命令
git已提交的东西几乎总是可以恢复的,未提交的东西丢失后可能就找不到了.
远程仓库
git remote 查看远程仓库的名字
git remote -v 查看名字及url
git remote show 查看远程仓库的信息
git remote add {name} {url} 添加远程仓库
git remote rename 重命名远程仓库
git remote remove 移除远程仓库
git fetch 从远程仓库获取本地仓库还没有的数据,获得远程仓库中所有分支的引用
git push 推送本地提交到远程branch分支
打标签: 标签常表示版本号
标签分为轻量标签和附注标签,轻量标签临时使用,只是某个特定提交的引用;附注标签时存储在git数据库中
的完整对象,且可以被校验,包含打标签者的名字,邮件地址,时间等,推荐使用附注标签
git tag [-l] [{pattern}] 列出已有的标签,匹配标签
git tag -a {tag_name} -m {comment} 创建附注标签
git show {tag_name} 查看标签信息和与之对应的提交信息
git tag {tag_name} 创建轻量标签
git tag -a {tag_name} {hash} 给已有的提交打标签
git push {tag_name} 推送标签到远程仓库
git push origin --tags 推送本地的所有标签
git tag -d {tag_name} 删除标签
git push --delete {tag_name} 删除远程仓库的标签
别名: 简化git命令的敲击, 如git config --global alias.ci commit
分支 详见 https://www.git-scm.com/book/zh/v2/Git-分支
分支的原理
分支通过指针实现,其指向的对象时提交对象(记录一次提交时的快照),提交对象指向前一次提交,构成链式结构,
创建新分支时,该链条即出现分叉,不同的分支用不同的指针表示,该指针随着该分支上新的提交自动向后移动.
另有一个head指针指向当前分支
分支操作
git branch {name} 创建新分支
git checkout {name} 切换分支
git chechout -b {name} 创建并切换分支
git branch -d {name} 删除分支,如果有分支尚未合并到当前分支,则删除那个分支会出错
git log --decorate 查看分支指向的提交
+ 最好在切换分支前使得当前分支已全部提交,否则暂存区还未提交的修改可能和检出的分支冲突
+ git会自动添加,删除,修改文件以确保当前工作目录和这个分支上次提交的内容一致
git merge {name} 把name分支合并到当前分支上
合并操作有两种:
1) 快进合并: 待合并分支和当前分支在一条链上
2) 三方合并: 待合并分支和当前分支不在一条链上,git创建一个新的提交,合并冲突解决后该提交指向两个父提交
git branch 查看分支
git branch -v 查看分支和分支的最后一次提交
git branch [–merged] [–no-merged] 查看已合并/未合并到当前分支的分支列表
分支开发工作流:
- 长期分支(master分支稳定,dev分支不稳定,测试后合并进master)
- 主题分支(短期分支), 应对不断出现的临时任务
git checkout -b / 创建分支并设置跟踪分支
git checkout --track / 设置跟踪分支并创建同名分支
git checkout 如果检出的分支不存在且刚好只有一个名字匹配的远程分支,则创建并跟踪
git branch -u / 设置已有的分支跟踪远程分支
git branch -vv 查看本地分支,并查看正在跟踪哪个远程分支,领先还是落后
git push --delete 删除服务器上的分支
注意: 跟踪远程分支只是跟踪拉取到本地的远程分支,如果要保持远程分支的最新状态,需要手动拉取
变基(rebase)
三方合并的替代方案,结果是一致的,方法变为取差异然后回放,git log与实际的提交记录不一致
git rebase {to} {from} 将from变基到to上
git checkout {from}; git rebase {to} 将from变基到to上
注意: 变基只能在本地进行,如果已经发布了提交(git push),则该提交不能执行变基操作,否则其他用户的提交记录会混乱
5. 分布式git
5.1 工作流程:
- 集中式工作流(公司)
- 集成管理者工作流(github开源项目)
- 主管与副主管工作流(超大型协作项目)