团队合作开发中少不了版本控制管理工具,由于近期公司项目从 SVN
更换成 Git
,这里主要做一个复习总结。 SVN
和 Git
最主要要的区别: SVN
是集中式的, Git
是分布式的。 Git
的优势在于易于本地增加分支和分布式的特性,可离线提交,解决了异地团队协同开发等 SVN
不能解决的问题。
Git
最核心的一个概念就是工作流。
- 工作区(Workspace) 是电脑中实际的目录。
- 暂存区(Index) 类似于缓存区域,临时保存你的改动。
- 仓库区(Repository) ,分为本地仓库和远程仓库。
常用命令速查
先来偷个图(图片来源于网络):
初始化
# 在当前目录新建一个Git代码库
$ git init
# 新建一个目录,将其初始化为Git代码库
$ git init [project-name]
# 下载一个项目和它的整个代码历史 [Git only]
$ git clone [url]
配置
# 列举所有配置
$ git config -l
# 为命令配置别名
$ git config --global alias.co checkout
$ git config --global alias.ci commit
$ git config --global alias.st status
$ git config --global alias.br branch
# 设置提交代码时的用户信息
$ git config [--global | --local] user.name "[name]"
$ git config [--global | --local] user.email "[email address]"
增加/删除/修改文件
# 添加指定文件到暂存区
$ git add [file1] [file2] ...
# 添加指定目录到暂存区,包括子目录
$ git add [dir]
# 添加当前目录所有文件到暂存区
$ git add .
# 删除工作区文件,并将这次删除放入暂存区
$ git rm [file1] [file2] ...
# 停止追踪指点文件,但不删除
$ git rm --cached [file]
# 文件改名,并放入暂存区
$ git mv [old] [new]
提交
# 提交暂存区到仓库区
$ git commit -m [message]
# 提交暂存区的指定文件到仓库区
$ git commit [file1] [file2] ... -m [message]
# 提交工作区自上次commit之后变化,直接到仓库区
$ git commit -a
# 提交时显示所有diff信息
$ git commit -v
# 使用一次新的commit,代替上一次提交;若代码无变化,则改写上次commit的提交信息
$ git commit --amend -m [message]
# 重做上一次commit,并包括指定文件的新变化
$ git commit --amend [file1] [file2]
分支
# 显示所有本地分支
$ git branch
# 列出所有远程分支
$ git branch -r
# 列出所有本地分支和远程分支
$ git branch -a
# 新建分支,但停留在当前分支
$ git branch [branch-name]
# 新建分支,与指定远程分支建立追踪关系
$ git branch --track [branch] [remote-branch]
# 删除分支
$ git branch -d [branch-name]
# 删除远程分支
$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]
# 新建分支,并切换到该分支
$ git checkout -b [branch-name]
# 切换到指定分支,并更新工作区
$ git checkout [branch-name]
# 切换到上一个分支
$ git checkout -
# 建立追踪关系,在现有分支与指定的远程分支之间
$ git branch --set-upstream [branch] [remote-branch]
# 合并指定分支到当前分支
$ git merge [branch]
# 衍合指定分支到当前分支
$ git rebase [branch]
# 合并一个commit到当前分支
$ git cherry-pick [commit]
标签
# 列出所有本地标签
$ git tag
# 基于最新提交创建标签
$ git tag [tag]
# 删除标签
$ git tag -d [tag]
# 删除远程标签
$ git push origin :refs/tags/[tag]
# 查看标签信息
$ git show [tag]
# 提交指定标签
$ git push [remote] [tag]
# 提交所有标签
$ git push [remote] --tags
# 新建一个分支,指向某个标签
$ git checkout -b [branch] [tag]
查看信息
# 显示状态
$ git status
# 显示当前分支的版本历史
$ git log
# 显示commit历史,以及每次commit发生变更的文件
$ git log --stat
# 搜索提交历史,根据关键词
$ git log -S [keyword]
# 显示某个文件的版本历史,包裹文件改名
$ git log --follow [file]
$ git whatchanged [file]
# 显示指定文件相关的每一次diff
$ git log -p [file]
# 显示过去5次提交
$ git log -5 --pretty --oneline
# 显示所有提交过的用户,按提交次数排序
$ git shortlog -sn
# 显示指定文件是什么人在什么时间修改过
$ git blame [file]
# 查看某人提交记录
$ git log --author=[username]
# 显示暂存区和工作区差异
$ git diff
# 显示暂存区和上一个commit差异
$ git diff --cached [file]
# 显示工作区和当前分支最新commit之间的差异
$ git diff HEAD
# 查看某次提交具体修改内容
$ git show [commit]
# 显示某次提交发生变化的文件
$ git show --name-only [commit]
# 显示某次提交,某个文件的内容
$ git show [commit]:[file]
# 显示当前分支最近几次提交
$ git reflog
远程操作
# 下载远程仓库的所有变动
$ git fetch [remote]
# 取回远程仓库变化,并与本地分支合并
$ git pull [remote] [branch]
# 取回远程仓库的变化,并与本地分支变基合并
$ git pull --rebase [remote] [branch]
# 显示所有远程仓库
$ git remote -v
# 显示某个远程仓库的信息
$ git remote show [remote]
# 增加一个新的远程仓库,并命名
$ git remote add [remote-name] [url]
# 上传本地指定分支到远程仓库
$ git push [remote] [branch]
# 强行推送当前分支到远程仓库,即使有冲突
$ git push [remote] --force
# 推送所有分支到远程仓库
$ git push [remote] -all
撤销
# 恢复暂存区的指定文件到工作区
$ git checkout [file]
# 恢复暂存区当前目录的所有文件到工作区
$ git checkout .
# 恢复工作区到指定 commit
$ git checkout [commit]
# 重置暂存区的指定文件,与上一次 commit 保持一致,但工作区不变
$ git reset [file]
# 重置暂存区与工作区,与上一次 commit 保持一致
$ git reset --hard
# 重置当前分支的指针为指定 commit,同时重置暂存区,但工作区不变
$ git reset [commit]
# 重置当前分支的HEAD为指定 commit,同时重置暂存区和工作区,与指定 commit 一致
$ git reset --hard [commit]
# 撤销工作目录中所有未提交文件的修改内容
$ git reset --hard HEAD
# 新建一个 commit,用于撤销指定 commit,后者所有变化将被前者抵消,并应用到当前分支
$ git revert [commit]
# 将未提交的变化放在储藏区
$ git stash
# 将储藏区的内容恢复到当前工作区
$ git stash pop
多账号配置
有时候我们自己有 github
的账号作为个人使用,公司团队使用 gitlab
另一账号,这时我们就需要对同一设备配置多账号。
一、生成 ssh 密钥
分别对 github
和 gitlab
生成对应的密钥(默认情况下本地生成的秘钥位于 /Users/用户名/.ssh/
),并且配置 git
访问不同 host
时访问不同的密钥,流程如下:
- 在 gitbash 中使用
ssh-keygen -t rsa -C "公司邮箱地址"
生成对应的 gitlab 密钥:id_rsa
和id_rsa.pub
。 - 将 gitlab 公钥即
id_rsa.pub
中的内容配置到公司的 gitlab 上 - 在 gitbash 中使用
ssh-keygen -t rsa -C "github 邮箱地址" -f ~/.ssh/id_rsa.github
生成对应的 github 密钥:id_rsa.github
和id_rsa.github.pub
- 将 github 公钥即
/id_rsa.github.pub
中的内容配置到自己的 github 上 进入密钥生成的位置,创建一个
config
文件,添加配置:Host gitlab #域名地址的别名 HostName gitlab.com #这个是真实的域名地址 User gitlab #配置使用用户名 IdentityFile ~/.ssh/id_rsa.github #这里是id_rsa的地址 Host github HostName github.com User github IdentityFile ~/.ssh/id_rsa
二、测试
在密钥的生成位置 /Users/用户名/.ssh/
下使用 gitbash
运行 ssh -T git@hostName
命令测试 sshkey
对 gitlab
与 github
的连接:
ssh -T git@gitlab
# 如果配置正确会提示
Welcome to GitLab, @gitlab!
ssh -T git@gihub
# 如果配置正确会提示
Hi github! You've successfully authenticated, but GitHub does not provide shell access.
三、配置 git 仓库
git
的 config
文件记录了用户的基本信息,我们的账号信息也在里面,这里我们要做的就行在不同的本地仓库配置不同的用户信息来访问不同的远程仓库
config 文件通常有三个位置:
- system (系统级别) 位于 Windows 下在 git 的安装目录, 包含了适用于系统所有用户和所有库的值。如果你传递参数选项
--system
给git config
,它将明确的读和写这个文件。 - global(用户级别) 位于
~/.gitconfig
,具体到你的用户。你可以通过传递--global
选项使Git 读或写这个特定的文件。 - local(仓库级别) 位于
.git/config
,无论你当前在用的库是什么,特定指向该单一的库优先级最高。
用户级别配置
因为公司的代码使用频率较高,所以将 git
配置文件的 global
(用户级别)设置为公司的 gitlab
账号:
$ git config --global user.name "gitlab" // 公司账号名称
$ git config --global user.email "[email protected]" // 公司账号邮箱
仓库级别配置
将 local
(仓库级别)配置成 github
的账号。此时需要先 init
一个 git
的仓库并进入里面后执行如下命令:
$ git config --local user.name "github" // github 账号名称
$ git config --local user.email "[email protected]" // github 账号邮箱
四、使用
# 之前的方式:单个账号
git clone [email protected]:xxxx/xxx.git #缺省config配置时
git clone git@github:xxxx/xxx.git #config配置后,等价于第一条语句
# 现在要改为,git clone git@域名别称:xxxx/xxx.git
# 就是使用域名地址的别名来区分
git clone git@github:xxxx/xxx.git
git clone git@gitlab:xxxx/xxx.git