Git
# Git
- 工具
- 版本控制
- 分布式-基本不担心版本库的丢失
- 不用连接中央服务器,随地都可以工作
- 提交到github就可以保证多人协作
[TOC]
# 一、git的三个区
- 工作区
- 暂存区
- 作为过渡层
- 避免误操作
- 保护工作区和版本区
- 分支处理:等版本确定无误后,合并到主分支
- 版本区(库)
# 二、git命令
# 2.1 创建
创建命令 | 含义 | 其他 |
---|---|---|
git init | 创建版本库 | 初始化一个git仓库 |
touch <file.name> | 创建一个文件 |
# 2.2 查看
查看命令 | 含义 | 其他 |
---|---|---|
git status | 查看暂存区和工作区的状态 | |
git reflog 文件名 | 查看版本号 | 查看恢复的日志 上面有commit_id |
cat <file.name> | 显示文本内容 | |
git log | 查看提交的日志 | 只会显示部分,按回车往下查看,按键盘Q推出 |
git branch | 查看分支 | |
git branch --merged | 查看合并过的分支 | |
git branch --no-merged | 查看没有合并过的分支 | |
git config --list | 查看所有配置项 | |
git remote | 查看远程仓库的名字 | |
git remote -v | 查看仓库fetch和push的地址 |
# 2.3 配置
配置命令 | 含义 |
---|---|
git config --global user.name "Your Name" | 设置贡献者名字 |
git config --global user.email "email@example.com" | 设置贡献者邮箱 |
# 2.4 提交
提交命令 | 含义 | 其他 |
---|---|---|
git add <file.name> | 将文件提交到暂存区 | git add . 将所有文件提交到暂存区 |
git commit -m "注释" | 提交文件到本地库 | |
git commit '注释'--amend | 撤销回上一次提交,然后重新提交 | |
git -a -m '注释' | 工作区到缓存区再到版本库 | |
git push origin master | 同步到远程仓库的版本库中 | 从远程获取最新版本并merge到本地 |
不要用 git push --force,而要用 git push --force-with-lease 代替。在你上次提交之后,只要其他人往该分支提交给代码,git push --force-with-lease 会拒绝覆盖。
远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。
# 2.5 撤销
撤销命令 | 含义 | 其他 |
---|---|---|
git reset --hard HEAD^ | 回退一个版本 | 从暂存区撤销回工作区 |
git reset --hard HEAD~<num> | 回退n个版本 | 版本恢复到过去的前n个版本 |
git reset --hard commit_id | 到所指定的版本号的版本 | 复制commit的id号时只复制前一部分即可 |
git checkout <file.name> | 还原文件 | 将工作区的版本撤销回版本库的状态 |
git checkout commit_id <file.name> | 指定文件的恢复 | |
git reset <file.name> | 撤销某个文件暂存区的提交 |
git pull后想回退版本
git reflog master (查看本地master分支历史变动记录)
得到一下结果:
a1ed85e (master) master@{0}: commit: test
a7575f0 master@{1}: commit: add CHAME
9dafea8 master@{2}: commit: change
144aed6 master@{3}: commit (initial): first commit
git reset --hard <COMMIT_ID> (恢复到指定版本)
git reset --hard master@{0}
2
3
4
5
6
7
8
# 2.6 删除
删除命令 | 含义 | 其他 |
---|---|---|
git rm <file.name> | 只有工作区删了而暂存区没删的时候可以用,用来删除缓存区文件 | |
–git rm -f <file.name> | 强制删除工作区和暂存区的文件 | f就是force |
git rm --cached <file.name> | 去掉某个文件的版本追踪 | 只会删除暂存区的文件,不会删工作区的 |
# 2.7 分支
分支命令 | 含义 | 其他 |
---|---|---|
git branch 分支名 | 创建分支 | |
git checkout 分支名 | 切换分支 | |
git merge 分支名 | 合并分支 | 先切换到主干,版本改变,master指针往前移 |
git checkout -b 分支名 | 创建并切换到新建的分支 | |
git branch -d 分支名 | 删除分支 | 只有合并过的分支才能删除 |
git branch -D 分支名 | 强制删除没有合并过的分支 |
# 2.8 命令
对比命令 | 含义 |
---|---|
git diff | 工作区和暂存区的对比 |
git diff --cached | 暂存区和版本库的对比 |
git diff --staged | 暂存区和版本库的对比 |
git diff master | 工作区和版本库的对比 |
# 三、SSH keys
ssh是一种安全的传输模式,github要求推送代码的用户是合法的,所以每次推送时候都要输入账号密码,用以验证你是否为合法用户。
# 3.1 创建
- 省去每次都要输入密码的步骤
- 在你的电脑生成了一个唯一的ssh公钥和私钥,公钥放到github上面,私钥放在本机且无法截获。
- 当你推送的时候,git就会匹配你的私钥是否跟github上面的公钥是配对的,正确就认为你是合法的,允许推送。
# 3.1.1 给git加ssh-key
查看根目录下是否有.ssh目录
若没有则生成一个ssh-key
ssh-keygen -t rsa -C "email@mail.com"
连按三次回车将.~/ssh/id_rsa.pub内容加入你的github中
设置你的git用户名及邮箱
git config --global user.name "name"
git config --global user.email "email@mail.com"
2
- 测试你的ssh-key
ssh -T git@github.com
输入yes后若显示Hi xxx! You’ve successfully authenticated, but GitHub does not provide shell access.
则代表成功。
# 3.1.2 解决github上传ssh-key后仍须输入密码的问题
这种事情通常发生在更换机器后克隆自己仓库的时候,通常我们会使用
https
方式克隆git clone https://github.com/Name/project.git
这样便会在你git push时候要求输入用户名和密码
解决的方法是使用ssh方式克隆仓库
git clone git@github.com:Name/project.git
https方式克隆后改ssh方式
只需将 .git/config文件中的
url = <https://github.com/Name/project.git>
一行改为url = git@github.com:Name/project.git
# 四、一般操作
远程要先建仓库。
初始化一个Git仓库
git init
添加文件到Git仓库
git add <file.name>
可反复多次使用,添加多个文件git commit
随时掌握工作区的状
git status
1- 若修改过,查看修改内容
git diff
- 若修改过,查看修改内容
在版本的历史之间穿梭
- HEAD指向的版本就是当前版本
git reset --hard commit_id
git log
查看提交历史,确定回退版本git reflog
查看命令历史,确定重返版本
- HEAD指向的版本就是当前版本
关联一个远程库
git remote add origin git@server-name:path/repo-name.git
1- 示例:
$ git remote add origin git@github.com:michaelliao/learngit.git
- 示例:
第一次推送master分支的所有内容
git push -u origin master
1- 由于远程库是空的,我们第一次推送master分支时,加上了-u参数
- Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来
- 在以后的推送或者拉取时就可以简化命令。
以后的每次本地提交后,
git push origin master
推送最新修改创建新的分支,提交后合并分支
$ git checkout -b branchName $ git add . $ git commit -m 'XXX' $ git push origin branchName $ git checkout master $ git merge origin/branchName $ git push
1
2
3
4
5
6
7
# 五、多人协作解决冲突
– git fetch
相当于是从远程获取最新版本到本地,不会自动合并
git diff master origin/master
git merge orgin/master
# 5.1 开源项目协作
- fork
- pull request
# 六、报错案例
# 6.1 案例一
git push -u origin master
- 报错如下:
error: failed to push some refs to 'git@github.com:你的远程库名.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
2
3
4
5
- 由于两者不同步,因此需要先pull,进行合并然后在进行push。
- 将远程文件同步下来
git pull --rebase origin master
- 执行推送
git push -u origin master
- 将远程文件同步下来
# 6.2 案例二
remote add origin git@github.com:djqiang(github帐号名)/gitdemo(项目名).git
- 报错信息:
fatal: Could not read from remote repository
- 原因:remote origin already exists.
- 解决办法如下:
$ git remote rm origin
$ git remote add origin git@github.com:djqiang/gitdemo.git
2
# 七、Git钩子
# 7.1 启用及触发
# 7.1.1 启用
- 将
.git/hooks
下的文件名,去掉后缀.sample
即可启用。
# 7.1.2 触发
# 7.1.2.1 post-receive
- 在整个过程完结以后运行,可以用来更新其他系统服务或者通知用户。
- 即,当服务端收到一个push操作请求时触发,可用于检测push的内容。
# 7.1.2.2 update
- 与pre-receive相似,但当一次push想更新多个分支时,pre-receive只执行一次,而此钩子会为每一分支都执行一次。
# 八、其他
- 资源
- 官方镜像
- https://registry.npmjs.org/
- 淘宝镜像
npm --registry https://registry.npm.taobao.org
# 8.1 替换远程仓库关联
- 解除旧分支的关联
git remote remove origin
- 关联新分支
git remote add origin https://xxxxxxx/wangdong/helloworld.git
# 8.2 强制覆盖本地代码
git fetch --all && git reset --hard origin/master && git pull
第一个是:拉取所有更新,不同步; 第二个是:本地代码同步线上最新版本(会覆盖本地所有与远程仓库上同名的文件); 第三个是:再更新一次(其实也可以不用,第二步命令做过了其实)
备注: 命令连接符 && 的意思是 前一条命令执行成功才执行后一条命令。 扩展:命令连接符 ;; 的意思是 不论前一条是否执行成功都继续执行后一条命令。
# 8.3 禁止上传指定文件
# 8.3.1 规则
# 此为注释 – 将被 Git 忽略
*.a # 忽略所有 .a 结尾的文件
!lib.a # 但 lib.a 除外
/TODO # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/ # 忽略 build/ 目录下的所有文件
doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
2
3
4
5
6
7
8
9
10
11
# 8.3.2 已经推送(push)过的文件,想在以后的提交时忽略此文件,即使本地已经修改过,而且不删除git远程库中相应文件
- 忽略文件
git update-index --assume-unchanged Xml/config.xml
- 忽略目录
git update-index --assume-unchanged $(git ls-files | tr '\n' ' ')
# 8.3.3 已经推送(push)过的文件,想从git远程库中删除,并在以后的提交中忽略,但是却还想在本地保留这个文件
git rm --cached Xml/config.xml
# 8.4 修改分支名
对于未提交到远程的,直接
git branch -m oldName newName
而已经提交到远程的,其实就是删除远程的,再把本地的新分支推到远程去
- 删除远程分支
git push --delete origin oldName
1- 上传新命名的本地分支
git push origin newName
1- 本地分支和远程分支关联
git branch --set-upstream-to origin/newName
1