Git
基本用法
Reference https://www.liaoxuefeng.com/
配置
Git 一共分为三个级别的配置 system、global、local,分别是系统级、用户级、当前仓库
1 | # 查看配置文件 |
在 global 中需要配置提交的用户名和 Email 地址,
这是由于 Git 是分布式版本控制系统,在提交的时候需要自报家门。
1 | # 配置用户名 |
上述是对本机上所有的仓库进行了配置,也可以单独对某个仓库进行配置。
创建版本库 (repository)
1 | git init |
将当前目录变成 Git 可以管理的仓库,(为了避免出现错误,目录中不要出现中文)
创建版本库之后,当前目录下会多一个.git 目录,这个 Git 用于跟踪管理版本库
将文件添加到版本库
将文件添加到版本库需要两步
1 | # 将文件添加到仓库 |
版本回退
1 | # 查看修改记录,用于查看提交历史 |
文件状态
Git 控制系统分为工作区和暂存区
工作区便是当前建立仓库的目录
.git 文件夹为 Git 的版本库,版本库又分为暂存区以及分支
每次使用git add
命令,表示将工作区文件添加到暂存区,而使用git commit
命令是将暂存区的文件的添加到版本控制的分支上。
所以我们可以多次使用git add
命令将文件添加的暂存区,而使用git commit
一次性将暂存区文件添加到分支上
管理修改
Git 作为版本控制工具,用于跟踪并管理文件的修改,并非文件使用git diff HEAD -- <filename>
命令可以查看工作区和版本库里面的最新版本的区别
撤销修改
- 撤销工作区的修改
git checkout -- <filename>
,将工作区的修改全部撤销,这里有两种情况
- 文件被修改后还没有提交到暂存区,那么,撤销修改就会和分支最新版本一模一样
- 文件以及添加到暂存区,那么,撤销修改就是恢复到暂存区的状态
- 撤销暂存区的修改
git reset HEAD <filename>
,可以把暂存区的修改撤销掉,重新放回工作区,之后可以按照情况一撤销工作区的修改 - 撤销已提交到分支的修改,按照版本退回操作
删除文件
当已提交的文档在目录中被删除之后(rm <name>
),这时候工作区和版本库就不一致了,git status
会提醒改动
那么就有两种情况
- 确实要删除这个文件,使用
git rm <name>
从版本库中删除文件,并且git commit
提交改动 - 误删文件,那么可以从版本库中恢复出原来的文件
git checkout -- <name>
远程仓库
使用 github,实现本地仓库与远程仓库之间的连接
- 创建 SSH Key。 在 git bash 中输入
ssh-keygen -t ras -C "email_address"
。 - 在 github 网站个人设置页面添加 SSH Key
添加远程库
- 在 github 网站创建相应的 repository
- 本地仓库下运行
git remote add origin git@github.com:repository_address.git
- 将本地仓库下的文件推送到远程库上
git push -u origin master
,第一次推送master
分支时,加上-u
参数,Git 不但把本地的master
分支内容推送到远程新的master
分支,并且把本地master
分支和远程的master
分支关联起来,在以后的推送或者拉取时可以简化命令git push origin master
1 | # 添加远程仓库,origin是远程仓库的名字,Git的默认叫法,可以换为其他 |
从远程库克隆
1 | git clone git@github.com:repository_address.git |
分支管理
在 Git 中每一次提交所串联起来就是一条时间线,每条时间线都是一个分支,主分支即为master
分支,HEAD
并不是指向分支,而是指向master
分支,而master
分支指向提交,所以HEAD
指向的就是当前分支。
一开始的时候,master
分支是一条线,Git 用master
指向最新的提交,再用HEAD
指向master
,就能确定当前分支,以及当前分支的提交点:
每次提交,master
分支都会向前移动一步,这样,不断提交,master
分支的线也越来越长
创建分支
当我们创建新的分支的时候,Git 会新建一个指针,指向master
相同的提交,再把HEAD
指向这个新的指针,这就表示当前位于新的分支上,之后的提交会在新的分支上移动,即新的指针移动,而master
指向原来的提交位置不动。
在合并的时候也仅仅是master
指针的移动,删除去原来的指针,不涉及工作区内容的改变。
1 | # 创建一个新的dev分支,并切换到新的分支上 |
git merge
命令用于合并指定分支到当前分支
git branch -d dev
用于删除 dev 分支
解决冲突
当两个分支上都有新的提交的时候,再进行合并便会产生冲突,这时候 Git 没有办法进行“快速合并”,只能试图把各自的修改合并起来,使用git status
告诉我们冲突的文件,Git 会用<<<<<<<<<
、=======
、>>>>>>>>
标记处不同分支的内容
使用git log --graph
命令可以查看分支合并图
分支管理策略
合并分支时,如果可能,Git 会用Fast forward
模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward
模式,Git 就会在merge
时生成一个新的commit
,这样,从分支历史上就可以看出分支信息。
1 | # 创建新的分支 |
Bug 分支
stash
可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作
stash list
查看工作区保存目录,恢复时有两种方式
git stash apply
恢复后 stash 内容不删除,需要用git stash drop
来删除git stash pop
恢复的同时删除 stash 内容
当有多个 stash 内容的时候,先使用git stash list
查看,然后恢复到指定的 stash,使用git stash apply stash@{0}
命令
Feature 分支
在一个新的分支上开发某种功能,完成后再用于合并。
1 | # 新建分支 |
多人协作
当从远程仓库克隆的时候,Git 自动将本地master
分支与远程master
分支对应起来,远程仓库的默认名称是origin
查看远程库的信息用git remote
或者使用git remote -v
查看更加详细的信息
推送分支
将该分支上的所有本地提交推送到远程库,推送时要指定本地分支
1 | # 推送master分支 |
抓取分支
抓取 github 上的仓库git clone git@github.com:<path>.git
,在默认情况下只能看到本地的master
分支,如果要在其他的分支(dev)上开发,就必须创建远程origin
的dev
分支到本地git checkout -b dev origin/dev
多人协作中解决冲突
当本地分支提交了修改,而远程分支也提交了修改,再由本地向远程提交的时候就会产生冲突。
所以,多人协作的工作模式通常是这样:
- 首先,可以试图用
git push origin <branch-name>
推送自己的修改; - 如果推送失败,则因为远程分支比你的本地更新,需要先用
git pull
试图合并; - 如果合并有冲突,则解决冲突,并在本地提交;
- 没有冲突或者解决掉冲突后,再用
git push origin <branch-name>
推送就能成功!
如果git pull
提示no tracking information
,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name>origin/<branch-name>
。
Rebase 操作
将本地未 push 的分叉提交历史整理成直线,在查看历史提交变化的时候更加容易。
git rebase
标签管理
将某次提交打上标签,便于查找
创建标签
1 | # 查看分支 |
操作标签
1 | # 删除标签 |
专项
git submodule
用于在仓库下添加引用或发布的子模块,会在目录下添加.submodule文件,里面记录了子目录的 path 和 url
-
添加
1
git submodule add repository path
-
克隆
克隆带子模块的版本库
git clone url path --recursive
递归克隆带子模块的版本库 -
删除
删除
.git/config
和.gitsubmodules
里关于 submodule 相关部分,然后git rm --cached <local path>
git remote
-
查看本地仓库、远程仓库以及追踪关系
git branch -vv -a
-
添加远程仓库
git remote add <shortname> <url>
将远程仓库<url>影射为本地仓库中对远程仓库的别名 <shortname>,git remote add
只负责映射。 -
推送
git push <远程仓库名> <本地分支名>:<远程分支名>
在日常使用时可以为1
2
3
4
5
6
7
8
9
10# 第一次push 使用 -u 建立上游分支
git push -u <远程仓库名> <本地分支名>:<远程分支名>
# 之后即可缺省使用
git push
# 缺省使用远程分支名,默认用当前分支填充远程分支
git push <远程仓库名>
# 缺省远程分支名,用本地分支名填充远程分支名
git push <远程仓库名> <本地分支名>
# 长选项--set-upstream,等价于-u
git push --set-upstream <远程仓库名> <本地分支名>
Q&A
-
修改
commit
注释信息在提交了以后发现注释不合适需要修改的方法
commit
后没有push
1
git commit --amend
修改第一行注释信息即可
push
到远程仓库
将本地修改后的信息提交到 github,使用强制修改命令git push origin master --force
-
解决
error:failed to push some refs to 'remote'
出现原因:本地仓库与远程仓库不一致
解决方法:将远程仓库同步到本地仓库1
2git pull -- rebase origin master
git push origin mastergit pull --rebase origin master
的意思是把远程库中的更新合并到本地库中,–rebase
的作用是取消掉本地库中 z 最新的commit
,并把他们接到更新后的版本库之中。
注意:在使用这条命令之前需要使暂存区内没有文件,即搜所有的修改已经提交到分支或者舍弃。
图解:git pull –rebase origin master
意为先取消commit
记录,并且把它们临时 保存为补丁(patch)(这些补丁放到”.git/rebase”目录中),之后同步远程库到本地,最后合并补丁到本地库之中。本地库
push
到远程库