Git是一个开源的分布式版本控制系统,而Github是全球最大的代码托管平台。下面对Git和Github的使用方法进行说明
Git
初始化
首先进入要进行版本控制的目录。
git init
让这个文件夹变为一个 git 文件夹
添加文档让git管理跟踪
git status
查看目前这个文件夹的状态
可以看到目前没有被跟踪的文件
这里需要了解的是 Git 中的三个区域:工作区、暂存区、仓库,初始文件都在工作区内。
git add
添加文件git跟踪,即将文件放入暂存区
git commit
将暂存区的内容上传至仓库 git commit -a
直接将工作区内容上传至仓库。
然后会出现下面界面,这里是要输入你对这个版本的介绍。
查看日志
git log
查看日志
未 git commit
之前是没有记录的。当进行 git commit
会生成当前版本的快照,再进行 git log
输出如下:
commit 后面的黄色乱码就是这个快照的编号
回到原来版本
我们可以使用 git checkout [commit-id]
切换到之前提交的仓库的版本,
当然这样只是查看之前版本的代码,要是想将当前工作目录回滚到之前版本,可以使用 git reset --hard <commitId>
比较差别
我们可以用 git diff
对比不同版本或者不同区域的区别
git diff对比工作区与暂存区的区别
输出格式详解
- 第一行
diff --git a/test1.txt b/test1.txt
表示进行比较的是a版本的test1.txt 与 b版本的test1.txt - 第二行
index 00c1016..8ed93c1 100644
表示两个版本的git哈希值(index区域的00c1016对象与工作目录区域8ed93c1对象进行比较),最后的六位数字是对象的模式(普通文件,644权限) - 第三行第四行
--- a/test1.txt
+++ b/test1.txt
---
表示变动前的版本
+++
表示变动后的版本
-
第五行
@@ -1,2 +1,3 @@
-
表示第一个文件,1,2
表示这个文件是从第1行开始的连续2行,+
表示第二个文件,1,3
表示这个文件是从第1行开始的连续3行。 -
之后是具体变动内容
-
表示去掉了什么内容,+
表示加上了什么内容。
git diff --staged 对比暂存区和最新提交的区别
git diff 对比两次提交的区别
这里只需给出版本 ID 的前四位即可
分支
有时可能会需要对项目创建一个分支,因为你可能会有一个idea,但不想破坏原来的项目文件,就可以创建一个分支。
git branch
查看目前都有哪些分支
git branch <branch>
创建新的分支,这里的*
表示当前所在的分支
git checkout <branch>
切换到指定分支
git branch -d <branch>
删除本地分支,可能会提示未合并完毕,可以改为-D
强制删除
合并分支
Git 中有两个命令可以合并分支:
git merge <branch>
合并指定分支到当前分支git rebase <branch>
衍合指定分支到当前分支
假如从 develop 的 Base 处分出一个 feature 分支,其之后分别进行了 C、D、E提交,而 develop 之后进行了 A、B提交
那么使用 merge
合并分支之后,会记录所有的提交历史并生成一个新的 F 提交
可以看到其有一个 merge
的记录,且其排列是按时间顺序的。
而 git rebase develop
合并分支后,相当于将基点从 Base 移动到 B,删除 C、D、E,创建 C‘、D’、E’。
可以看到 Master 下的 testc.txt
虽然比 testa.txt
要新,却在它的下面。且没有 rebase
记录。
rebase
会产生更简洁的历史信息,但是麻烦的是,由于基底发生改变就无法知道当前分支是从哪次提交分出来的。且在公共开发时,容易篡改历史信息,比如 A 提交新代码之后,B也完成了新代码,其将 A分支 pull 下来,git rebase B
,会导致 B代码明明是最新的,结果成为A之后的代码了。
所以,merge
和 rebase
要根据实际需求使用。
如果 merge
合并产生冲突,比如修改了同一文件的同一区域,需要手动解决后,git add <file>
说明冲突已解决。
rebase
合并产生冲突,既要 git add <file>
,还需要 git rebase --continue
继续合并。
标签
我们可以看到之前的提交都是一堆乱码,根本不知道什么是什么,那么我们可以给这些提交打标签,可以一目了然地了解哪个提交对应哪个版本等,且也可以通过标签查找到对应的 commit_id
。
git tag -a v1.0
表示对最新的提交增加 v1.0
标签,之后会让你输入注解,与提交注解类似,这样就给最新提交打上标签了。
当我们想给之前的提交打上标签,可以指定 commit_id
。
可以使用 git tag
查看目前已有的标签
git tag -d <tag>
删除标签
远程控制
除了本地化控制,我们一般都会选择将代码上传到远程仓库进行管理,这也可以方便多开发人员协同开发,而一般使用的远程代码仓库就是 Github,下面就对如何使用 Github 以及使用 Git 远程控制进行说明。
这里默认你已经注册完 github 账号了,并且这里以 windows系统为例。
本地配置
使用命令 git config --list
或 git config -l
查看当前的 git 配置
git config --list
刚安装 git 时,配置里是没有 user.name
和 user.email
的,但是向远程仓库提交代码需要使用 user.name
和 user.email
,所以要先进行配置。
- 配置用户名
git config --global user.name "yourusername"
- 配置邮箱
git config --global user.email "xxx@xxx.com"
这里填上自己的用户名和邮箱,--global
表示配置的用户名和邮箱是全局的,表示当前环境中所有分支都可以使用,也可以不指定 --global
配置完用户名和邮箱后,要生成 ssh 的RSA公钥和私钥
- 生成RSA公钥和私钥
ssh-keygen
在执行的过程中,会询问生成的公钥和私钥存放在哪,确认生成等,一直回车就可以,运行结束结果如下图
生成的公钥和私钥默认保存在当前登录系统的用户的家目录下。里面有一个 .ssh
隐藏文件夹,里面的 id_rsa
文件是私钥,id_rsa.pub
文件是公钥。
打开 id_rsa.pub
文件,复制公钥,之后需要将公钥配置到远程代码仓库中。
配置远程公钥
-
点击右上方的个人头像,再点击 Settings 进入设置页面
-
在 Settings 页面点击 SSH and GPG keys 进入 SSH keys 设置页面。
-
点击 New SSH key 添加 SSH key,SSH key 是可以配置很多个,即使同一环境中,也可以配置多个 SSH key。
-
将前面生成的公钥粘贴到 Key 里,可以给这个公钥定义一个标题,然后点击 Add SSH key 按钮。
-
如下图,则表示公钥已经添加成功,我们可以使用这个公钥来提交和拉取代码。
建立远程代码仓库
远程代码仓库是帮助我们存放和托管代码的,当我们配置好公钥后,就可以在 Github 上创建项目了。
每一个项目文件夹相当于一个代码仓库。所以新建仓库可以理解为新建一个项目。
- 下面新建一个
Test
项目,Description
可填也可不填,Public
和Private
选择Public
公开。初始化README
文件可选可不选,.gitIgnore
文件里面写的是本地向远程仓库提交代码时忽略的文件,如 Python 中的.pyc
文件, 也是可填可不填。
填写好项目的设置后,点击 Create repository 创建项目。
- 创建好项目后,就相当于在 Github 上有了一个叫
Test
的代码仓库。现在这个仓库是新创建的,我们还未提交任何的代码,所以里面只有一个README
文件。为例使远程仓库和本地仓库建立连接,我们需要将远程仓库的代码克隆到本地。点击右方的 Clone or download,然后在下拉的菜单中点击 SSH 切换成 Clone with SSH,然后点击右下方的复制按钮,复制克隆代码的路径,后面的步骤会clone
这个仓库的代码到本地。
建立本地代码仓库
git clone <ssh地址>
拉取在 Github 上创建的Test
项目的代码到本地仓库。这里的ssh地址
就是在 Github 复制的 Clone with SSH 地址。
可以看到把 Test
目录拉取了下来,ls
之后可以看到 README.md
。
除了拉取 Test
建立之外,我们还可以 git init
初始化,然后添加远程地址。
git remote add origin git@github.com:yourName/yourRepo.git
推送改动
当我们的改动已经在本地仓库的 HEAD 中了,执行如下命令可以将这些改动提交到远程仓库:
git push <remote> <branch> # 上传代码及快速合并
还可以删除远程分支或标签
git push <remote> :<branch/tag-name>
还能上传所有标签
git push --tags
从远程库获取代码
master
和 origin/main
都是本地分支,不同的是 origin/main
指向远程仓库且无“实体”,相当于远程仓库 orign
的 main
分支在本地的一个代理人,orign main
则很清晰,其中 origin
表示远程仓库名字,main
远程仓库中的分支名字。
当使用 git fetch origin main
时,本地的 origin/main
仓库会更新至最新,但是 main
分支无变化,此时再用 git merge origin/main
即可将最新代码合并至main
,main
也就是最新代码了,也可使用 git pull origin master
直接代替 git fetch
+ git merge
。
不填默认 origin
和 main