5 Git
5.1 基本概念
常用的远程仓库有GitHub
和GitLab
,此外,y总还提供了基于GitLab
的AcGit。
工作区:仓库的目录,独立于各个分支。
暂存区:数据暂时存放的区域,可看做工作区写入版本库之前的缓冲区,它独立于各个分支。
版本库:存放所有已经提交到本地仓库的代码版本。
版本结构:树结构,树中每个结点代表一个代码版本。
5.2 本地命令
5.2.1 配置git账户
配置文件位于~/.gitconfig
中
git config --global user.name xxx # 全局用户名
git config --global user.email xxx@xxx.com # 全局邮箱
5.2.2 初始化
git init
5.2.3 暂存区操作
查看暂存区状态,红色表示被修改的文件,绿色表示被修改,但已添加到暂存区。
git status
添加文件到暂存区
git add filename # 添加文件filename到暂存区
git add . # 添加所有文件到暂存区
提交到本地版本库,同时HEAD
指针指向该版本结点
git commit -m "备注"
对比暂存区的文件版本,如果一致,则不显示。
git diff filename
删除暂存区中文件,让该文件不被管理,此时不会删除工作区的文件
git rm --cached filename
git restore --staged filename # 相同效果
工作区文件filename
回滚到暂存区版本,如果暂存区没有版本,则回滚到HEAD
版本
git restore filename
5.2.4 版本库操作
查看版本库,最上边是最新版本,最下边是最旧的版本。如果版本过多,需要按q
才能退出。
git log
也可用参数--pretty=oneline
设置为单行显示,此时每一行只有版本号和版本信息。
git log --pretty=oneline
恢复以前版本,版本号可这么指定。
HEAD^
表示上一个版本,HEAD^^
表示上上个版本,以此类推HEAD~100
表示上100个版本xxxxx
表示特定版本,可通过git log
查看版本号,只需填入前6位就能回滚。实际上不一定是旧版本,也可是新版本
git reset --hard HEAD^
注意,回滚后,并不会删除新版本结点,依然可以通过新版本号恢复到较新的版本,若不记得新版本号,可通过以下命令查看HEAD
移动过的结点
git reflog
5.3 远程版本库操作
在AC Git
注册账号,然后创建项目,填写项目名称、项目描述,取消勾选“使用自述文件初始化仓库”。
在AC Git
配置SSH,填入AC终端的SSH公钥,位于~/.ssh/id_rsa.pub
。
绑定远程仓库
git remote add origin git@git.acwing.com:xxx/project.git
其中git@git.acwing.com:xxx/project.git
可解读为服务器用户名@服务器域名:你的用户名/项目名.git
,使用ssh
方式连接与传输。
推送到远程版本库
git push -u origin branch_name # 首次推送分支branch_name到服务器,例如master分支
git push origin branch_name # 非首次推送分支branch_name到服务器,例如master分支
云端可通过”历史“浏览以前的代码,比本地浏览方便。
克隆版本库,几乎一样,只是缺少了引用记录,即git reflog
找不到曾经的引用记录
git clone git@git.acwing.com:xxx/project.git
5.4 分支命令
5.4.1 创建分支
在HEAD
指针方向创建分支dev
,但没有产生新结点,但commit
和push
会到新分支上
git checkout -b dev
用branch
命令可以查看所有分支,*
号对应的是当前分支。
git branch
5.4.2 分支操作
切换分支
git checkout branch_name
合并分支
把分支branch_name
的最新版本合并到当前分支的当前结点上(HEAD
指向的结点),默认为快速合并,即让HEAD
直接指向分支branch_name
的最新版本,分支branch_name
的所有结点归属于当前分支。
git merge branch_name
如果不想执行快速合并,可用参数-no-ff
。
如果出现冲突,则会提示合并失败,此时可通过git status
查看冲突情况,冲突部分会用both
提示,然后打开该文件,<<<<<<
和======
包围的部分是当前分支的内容,======
和>>>>>>
包围的是被合并分支的内容,根据实际情况,修改当前文件,包括删除<<<<<<
、======
和>>>>>>
,使得文件正常即可。然后再commit
,就能产生一个合并的版本。
删除分支
删除分支,并把其结点后继到HEAD
之后,但不影响云端的分支。一般合并完后可以选择删除分支。
git branch -d branch_name
5.4.3 云端分支操作
提交分支到云端
如果云端没有分支branch_name
,则不能省略branch_name
而直接git push
,这样需要用参数--set-upstream
。
git push --set-upstream origin branch_name
当然也可以直接指定branch_name
。
git push origin branch_name
删除云端分支
git branch -d origin branch_name
下载云端分支
方式1
假设云端分支叫dev
,需要下载到本地的分支dev
。
首先需要绑定二者
git branch --set-upstream-to=origin/dev dev
然后下载
git pull
方式2
直接pull
,但不能修改下载后的分支名
git pull origin branch_name
5.5 栈命令
如果遇到bug,需要创建新分支修bug,但目前的工作区和暂存区都已经修改,又不想提交到版本库了,这时可以先将工作区和暂存区保存到stash
里,并清空当前工作区和暂存区。
git stash
获取栈顶内容,但不删除栈顶,类似top()
操作
git stash apply
获取栈顶内容,同时删除栈顶
git stash pop
只删除栈顶
git stash drop
查看栈中所有元素
git stash list
5.6 作业核心代码
task1
mkdir homework
cd homework
git init
task2
vim readme.txt
i
111
[ESC]
:wq
git add .
git commit -m "add readme.txt"
task3
vim readme.txt
o
222
[ESC]
:wq
git add .
git commit -m "readme.txt append 222"
task4
mkdir problem1 problem2
vim problem1/main.cpp
:set paste
i
[shift]+[insert]
[ESC]
:wq
vim problem2/main.cpp
:set paste
i
[shift]+[insert]
[ESC]
:wq
git add .
git commit -m "add problem1/main.cpp problem2/main.cpp"
task5
rm -r problem2
mkdir problem3
vim problem3/main.cpp
:set paste
i
[shift]+[insert]
[ESC]
:wq
vim readme.txt
G
dd
o
333
[ESC]
:wq
git add .
git commit -m "add problem3/main.cpp and modify readme.txt"
task6
git remote add origin git@git.acwing.com:moyu/homework.git
git push -u origin master
task7
git checkout -b dev
git checkout dev
vim readme.txt
G
o
444
[ESC]
:wq
git add .
git commit -m "modify readme.txt"
git push origin dev
task8
git checkout master
vim readme.txt
G
o
555
[ESC]
:wq
git add .
git commit -m "modify readme.txt"
task9
git checkout master
git merge dev
vim readme.txt
...
git add .
git commit -m "fix conflict"
task10
git push origin master
ssh myserver
ssh-keygen
cat .ssh/id_rsa.pub # 配置公钥到AC Git账户中
mkdir -p ~/homework/lesson_5/
cd ~/homework/lesson_5/
git clone git@git.acwing.com:moyu/homework.git
exit