Git
…
Git 的介绍与安装
Git具有版本控制与合作开发的特点。它是一个分布式的版本控制系统,代码不仅在服务器上保存代码的完整版,还在各个客户端保存完整代码的副本。这个服务器可以是Github,也可以是自己搭建的代码管理系统,如Gitlab,码云等。
GIT的基本结构
工作区
工作区就是当前的Git目录。
版本库
版本库就是该目录下的.git
目录。
暂存区
暂存区就是用户执行add
操作后,临时修改被放置的位置。暂存区的文件经过commit
命令可以被提交到分支中(创建一个版本)。
GIT本地仓库的基本操作
本节将介绍:Git仓库的初始化,版本切换,版本日志的查看,工作区修改情况查看,撤销等命令,命令如下:
1 | git init resp_name # 代码仓库初始化 |
本地仓库的创建与提交
新建一个目录,之后我们要在这里开发一个项目(编写代码)。首先使用Git Bash
在该目录下执行,初始化一个Git仓库:
1 | git init |
或
1 | git init repository_name |
完毕后,Git将创建一个版本控制系统在该目录下。之后我们创建一个文件,简单的编写一些内容,用于验证后面的版本控制的功能。例如,我们创建一个code.txt
文件。内容如下:
code.txt
1 | Hello |
保存退出,在Git Bash
中执行以下命令,添加修改到工作区,并提交修改:
1 | git add . |
这里的.
表示该目录下的所有文件,也可以写某一个文件,还可以使用*.txt
等格式书写;add
操作表示将相应文件加入到版本控制系统中;commit
命令表示提交修改,-m
的参数表示相应的备注。
版本的切换
输入如下命令,可以查看当前所有的代码版本。
1 | git log |
或使log以简短形式呈现
1 | git log --pretty=oneline |
下面我们创建第二个版本。修改刚刚的code.txt
文件,内容如下
code.txt
1 | Hello |
再次执行
1 | git add . |
则我们添加了一个新的版本到我们的版本库中。执行git log
即可查看到两个版本。
图中的commit 后的 1f96fe… 与 2f88a26… 则是对应的两个版本的版本代号。
那么如何回退到某一个版本?Git的版本是后一个版本依赖于前一个版本的,也就是后面的版本只记录修改的部分。所有的版本组成了一个链表,而HEAD
指针永远指向的最新的版本。如果想找到上一个版本,可以使用HEAD^
或HEAD~1
;上两个版本,可以使用HEAD^^
或HEAD~2
。
Tips:HEAD实际上会指向master,而master才指向最新的版本。关于分支的部分可以到下一节查看。这里可以暂时理解为HEAD指向最新的版本。
回退到上一个版本,可以使用命令
1 | git reset --hard HEAD^ |
打开文件code.txt
可以看到,文件内容已经恢复到最初的版本了。
如果又想切换到最新的版本,则可以使用命令
1 | git reset --hard 版本编号 |
版本编号可以使用git reflog
命令,通过查看操作记录寻找版本编号。
恢复工作区的文件
当工作区被编辑后,如果不知道已经做过哪些修改了,可以通过下面的命令查看当前工作区被修改的情况。
1 | git status |
如果想撤销工作区中某一个文件的修改,可以使用如下命令
1 | git checkout -- 文件名 |
如果想撤销暂存区中某一个文件的修改,可以使用如下命令,使修改回归暂存区。回归暂存区后,再使用checkout
命令使其回到工作区。
1 | git reset HEAD 文件名 |
如何对比文件与文件的不同?
对比工作区与版本库中的文件的不同:
使用diff命令,需要给出被对比的版本和文件名。1
git diff HEAD -- 文件名
会输出
其中的
---
表示版本库中的文件,+++
表示工作区中的文件。下方的红色部分表示工作区中的文件相对于版本库删掉的部分,绿色的是添加的部分。对比版本库中两个版本的文件的不同:
使用diff命令,并给出被对比的两个版本和文件名。1
git diff HEAD HEAD^ -- 文件名
这里输出的时候,
---
表示版本库中的HEAD
版本,+++
表示HEAD^
版本。如果命令写成git diff HEAD^ HEAD
,则---
与+++
所表示的内容也相反。
其他命令
如果想删除某一个文件,并将这一改动添加到暂存区,可以使用git add
命令,表示添加改动到暂存区;也可以使用git rm
命令,表示添加删除操作到暂存区。示例如下:
1 | git rm 文件名 |
Git 的分支管理
在Git中,所谓分支就是一个指针。例如master分支,就是一个master指针指向了该版本链表的某一个节点。如果是其他分支,例如dev分支,则是在这个链表上添加一个叫dev的指针,指向某一个版本节点。最终再由HEAD指针指向当前编辑的分支指针,也就是HEAD指向了当前编辑的分支。
分支的合并,就是将master指针指向dev所指节点,即图中第四个节点。这样就将dev分支合并到master分支当中了。
分支的删除,就是直接删除dev指针,这样就删掉了该分支。
分支的基本操作如下:
1 | git branch # 查看所有分支 |
分支的查看,创建与切换
使用下述命令,可以查看当前的所有分支。
1 | git branch |
如果要创建某一分支,可以使用这个命令(dev为分支名称)。
1 | git branch dev |
进行分支切换,可以直接使用如下命令。
1 | git checkout master |
或创建并切换分支,可以一步到位,使用这个命令。
1 | git checkout -b dev |
切换的过程,就是由HEAD指向master指针变为了HEAD指向dev指针。新建的分支保留了原有分支的所有版本,也就是版本链表前边的部分,dev与master是共同享有的。这时,我们不论是add
与commit
操作,还是log
操作,均是在dev分支上进行的。
分支的合并与分支管理
当要进行分支合并,使用如下命令,但是分支合并,必须要在被合并的分支上进行,例如要将dev分支合并到master上,需要先切换到master分支上再执行合并操作。
1 | git merge dev |
合并分为三种情况:有冲突的合并;没有冲突的快速合并;没有冲突的普通合并。
- 快速合并:只修改新的分支,原有分支不动。例如master指针可以直接指向dev指针的位置上,无需产生新的版本,也不会留下分支创建的记录。
- 没有冲突的普通合并(recursive合并):两个分支上都有新版本产生,但是没有修改同一个文件。这种情况会在合并后产生一个新的版本。在执行合并操作后会提示提交新版本需要填写的信息。
- 有冲突的合并:两个分支上都有新版本产生,且修改了同一个文件。这会在合并后先产生合并失败,需要待手动修改冲突后再手动提交新的版本。
对于有冲突的合并,合并失败后,有冲突的文件会产生类似于如下内容的部分。通过手动修改这部分的内容,可以解决合并冲突。修改后,再次执行add
与commit
操作即可完成合并。
1 | <<<<<< HEAD # 删除多余部分,保留需要的部分 |
有时为了保留分支的创建与合并的记录,我们会在合并时候禁用快速合并模式。执行方式如下:
1 | git merge --no-ff -m "提交信息" dev |
合并后,就可以删除dev分支了。这里使用如下命令删除dev分支。
1 | git branch -d dev |
Bug 分支与 stash 功能
当我们遇到紧急Bug需要修复时,但又不能将当前的工作区提交到版本控制系统中,就可以使用stash功能。
1 | git stash |
stash功能可以将我们的工作区临时存储起来,存储完成后,工作区恢复到最近版本,就可以先去完成修复Bug的工作了。
修复bug时,首先创建bug分支,其次完成bug修复工作,完成后将bug分支合并到master分支即可。
待完成修复Bug的工作后,再去将我们原来的工作区恢复,继续进行工作。使用如下命令可以看到我们保存的所有的工作现场。
1 | git stash list |
使用如下命令可以恢复工作现场。
1 | git stash pop |
Github 的使用
之前的操作都是在本地计算机上所做的。但是我们合作开发的时候,往往需要借用Github之类的代码托管系统。Github的使用,与我们在本地使用Git类似,只是多了拉取与推送等操作。
创建代码仓库
首先需要有一个Github账号,登录后点击New repository
,输入仓库名称,配置相应设置后,点击Create repository
即可。
.gitignore
文件:保存了不需要同步的文件列表。
添加SSH
如果是初次使用Github,需要配置SSH。
点击用户头像
->settings
->ssh and gpg keys
->new ssh key
,在这里添加SSH标题与电脑的SSH公钥。
电脑的SSH公钥生成方式:
1 | cd ~/.ssh/ # 如果提示`No such file or directory`,可以手动的创建一个.ssh文件夹 |
之后按提示输入两遍密码,这个密码可以自己设置一个。也可以什么都不写,直接两次回车键。
用记事本打开.ssh目录下的id_rsa.pub文件,复制里面的内容,到github添加即可。这个公钥也可以移动到其他电脑上使用,用于用户在push时登录Github账号使用,这里建议每台计算机一个公钥。
使用这个命令可以测试SSH是否配置正确。
1 | ssh -T git@github.com |
使用这两个命令填写用户的用户名和用户邮箱,这里主要是为了在commit时显示是谁提交的代码。这个配置会被保存到用户目录/.gitconfig
文件中。
1 | git config --global user.name "account" |
后面的Push操作中,还会需要输入一次Github账号密码,这个账号密码与上面的邮箱和账号并不冲突,这个信息只会显示在commit记录上,而Push时输入的账号密码则是用来保证用户访问Github使用的。如果要修改本机上用于Push代码的Github账号密码,可到控制面板
->用户账户
->管理Windows凭据
->普通凭据
->git:https://user_name@github.com
下修改。
Clone 代码
我们先找到放置项目的目录,使用clone命令将项目克隆到本地。
1 | git clone git@github.com:user_name/repo_name |
或
1 | git clone https://github.com/user_name/repo_name |
如果在克隆的过程中出现错误,可以使用如下命令修复。
1 | eval "$(ssh-agent -s)" |
Push 代码
当代码克隆下来后,首先创建一个自己的分支进行开发。开发完成后,再提交到本地代码库。
1 | git add . |
积累到一定的开发量,如果要推送到远程服务器,则使用如下命令进行远程推送。
1 | git push origin dev |
其中origin是远程分支(这个名字固定),dev为本地的分支(这个名字随便起)。执行完毕后,远程仓库将创建dev分支。
首次Push时,可能会提示填写Github账号与密码。
如果本地仓库和远程仓库都有代码,且不是一套代码,这里可以使用强推操作。这样的强制操作应该尽量慎重使用。
1 | git push -f |
也可以先将远程仓库代码与本地代码合并再推送。
1 | git fetch |
跟踪远程分支
将本地分支跟踪服务器分支。跟踪后,Git将智能提示用户当前分支与服务器分支的进度差别。
1 | git branch --set-upstream-to=origin/远程分支名称 本地分支名称 |
跟踪后,可以直接使用如下代码推送代码。
1 | git push |
拉去远程分支
1 | git pull origin 远程分支名 |
拉去后,分支会默认进行跟踪。
管理远程分支 Remote 命令
查看远程已存在的分支:
1 | git remote |
添加远程仓库,将远程仓库绑定到origin上:
1 | git remote add origin 远程仓库 |
查看远程仓库:
1 | git remote -v |
可以删除远程主机:
1 | git remote rm 主机名 |
可以修改主机名:
1 | git remote rename 原主机名 新主机名 |
工作中使用Git
- 项目经理搭建项目框架,并放入代码管理工具。
- 普通员工在自己电脑上生成SSH公钥,交给项目经理。项目经理将SSH公钥上传至服务器。
- 项目经理给组员分发代码的克隆地址。组员将代码克隆到自己的电脑上。
- 普通员工创建自己的分支,在分支中进行每天的开发。
- 注意Master分支要保持发布的代码,Dev分支用于保存开发中的代码。
- 组员要把自己的Dev分支发布到远程Dev分支当中,但是发布之前需要确认代码可用,需要经过经理确认。
VS Code GIT
在VS Code中可以看到如下图标,这个图标就是VS Code的Git可视化管理工具。
点击该按钮(源代码管理),点击+
,选择当前文件夹,初始化Git本地仓库。这时,Git本地仓库就建立好了。
修改文件夹中的文件,再切换到源代码管理中,将鼠标移动到被修改的文件,可以看到右侧出现了+
,点击+
可以将操作暂存到暂存区。如果想取消暂存,可以再点-
即可。如果选中了某个文件,可以在右侧预览该文件与工作区文件的区别。
最上方有一个√
,这个是提交按钮,点击√
后即可提交该版本到版本控制中。
如果想回退到某版本,还是需要借助命令行来实现。这里可以使用插件Git History
查看某个版本,复制其ID,方便在命令行操作。
如果想添加远程仓库,也需要借助命令行。可以先执行初始化本地仓库操作,在本地版本库还是空的时候去pull远程代码。也可以跳过初始化操作,直接克隆远程代码。如果在本地版本库不是空的时候直接去pull代码,会出现下面的错误。
1 | fatal: refusing to merge unrelated histories |
这时可以使用下面的命令强行拉取,这样Git就会不论之前的版本库是否一致,都会去拉去远程分支。
1 | git pull https://github.com/用户名/仓库名.git master --allow-unrelated-histories |
Visual Studio 2017(待更新)
PyCharm GIT(待更新)
创建本地Git仓库。VCS
->VCS Operation Popup
->Create Git Repositry
再次点击VCS,会与之前有所区别。左侧的文件菜单,文件名也会有颜色的变换。
右键左侧某文件或文件夹->Git
->Add
,将选中文件添加到版本控制中;或者在提交的时候,可以在上方的文件管理器中勾选。
查看版本历史VCS
->Browse VCS Repository
->Show Git Repository Log
如果想回退到某一个版本,可以右键一个版本,选择Checkout Revision
。
如果想切换分支VCS
->Git
->Branches
使用远程仓库
添加远程仓库:VCS
->Checkout from Version Control
填写远程仓库地址与本地目录:https://github.com/用户名/仓库名.git
会有提示:Would you like to open ...
这样就可以打开下载的代码了。
右键左侧某文件或文件夹->Git
->Repository
->Push
推送代码到远程仓库。
PyCharm 其他技巧
PyCharm中没有暂存库的概念,因此代码修改编辑后直接提交即可。
VCS
->Git
->Annotate
可以看到每一行代码的作者和日期。
自带版本控制VCS
->Local History
,可以查看本地代码版本。在这里可以直接切换代码版本。
使用Github
配置Git:File
-> Settings
-> Version Control
-> Git
配置Github账号:Version Control
-> Github
创建仓库:VCS
-> Import into Version Control
-> Share Project on Github
,填写仓库名称和信息,完成后点share。之后选择要提交的文件。
更新仓库:右键项目 -> Git -> Commit Directory -> Commit
代码回滚:在左下角的Version Control中可以看到提交记录。右键项目 -> Local History
-> Show History
-> 某一版本右键 -> Revert
参考视频
- Git 版本管理
链接:https://pan.baidu.com/s/1ua94DTk1MkUBlILNDN7LHQ
提取码:m4un - Git 练习网:https://learngitbranching.js.org/
- Git 练习网 Github:https://github.com/pcottle/learnGitBranching
Git 使用
1 | # 添加到暂存区 |
暂存区:本质是一个文件,保存即将提交的文件列表信息。
仓库区:HEAD文件,保存当前指向的分支;index实际存储内容。
分支操作
1 | git branch # 所有分支 |
1 | # fetch 会从远程仓库取新的提交,但是不会修改本地的文件。 |