1.下载
通过镜像网站下载git-for-windows Mirror (taobao.org),本教程使用版本为2.17.0.安装过程使用默认选项,在选择path选项时不改变环境变量,只通过git Bash使用即可(如下图)。
安装成功后,在任意目录(如桌面)右键可以看到git Bash。
2.git简介
git是一款版本控制工具,可以帮助我们进行代码的历史记录维护以及团队协作。
2.1 git的目录结构
工作区:写代码的地方。
暂存区:将要提交的代码暂时放在这。
本地库:存储历史提交版本
2.2 代码托管中心
用于维护远程库,比如github,码云。远程库和本地库有两种交互方式。
团队类协作。
团队间合作。
3.本地仓库操作
3.1 初始化仓库
git的命令与linux系统的命令兼容,我们创建工作目录gitworkspace ,从工作目录下右键git bash,即可使用linux 与git 命令。
在工作目录新建gitvideo\wechat ,在该目录下执行gitinstall .可以看到生成了.git 目录。
3.2 设置签名
签名命令如下。--global 参数设置的签名为系统级别签名。
git config [--global] user.name wz
git config [--global] user.email wz@qq.com
看下配置。
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
[user]
name = wz
email = wz@qq.com
如果配置了--global 选项则在~ 目录下查看。
3.3 添加提交
$ git status
On branch master
No commits yet
nothing to commit (create/copy files and use "git add" to track)
可以看到每页提交过的内容,说明本地库是空的,也没有需要被提交的内容,说明暂存库是空的。
来一次提交吧。
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ vim hello,world.txt
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git add hello,world.txt
warning: LF will be replaced by CRLF in hello,world.txt.
The file will have its original line endings in your working directory.
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: hello,world.txt
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git commit -m "hello,world!"
[master (root-commit) 8262451] hello,world!
1 file changed, 1 insertion(+)
create mode 100644 hello,world.txt
3.4 版本穿梭
怎么执行版本回退呢?先看下提交日志。Head 是一个指针,指向当前的提交操作。如果信息很多,需要多屏显示,↓ ,b 翻页。
$ git log
commit 826245132989264cfa91b6350195413bfb219826 (HEAD -> master)
Author: wz <wz@qq.com>
Date: Wed Oct 20 21:38:40 2021 +0800
hello,world!
当提交信息很多,可以使用git log --pretty=oneline ,每次提交以一行显示。git reflog 还可以显示回退到各个版本指针需要移动的次数,而且显示所有的提交版本数(包括当前版本之前和之后的)。
$ git reflog
23d261d (HEAD -> master) HEAD@{0}: commit: hello
8262451 HEAD@{1}: commit (initial): hello,world!
回退的方式很简单。
git reset --hard commitid
也可以使用^ 表示回退的版本个数,回退两步走起。
git reset --hard^^
注意到--hard 参数。reset还有两个同等级别的参数--soft ,--mixed 工作中后两个参数用的不多。这里做简单介绍。
--soft 仅仅会移动本地库的指针。--mixed 会移动本地库的指针,同时也会重置暂存区。--hard 会移动本地库的指针,同时会重置暂存区和工作区。
3.5 删除文件找回
3.5.1 永久删除文件找回
如果一个文件被永久的删除了,但是创建这个文件时提交到了本地版本库,那么这个添加文件的记录将一直被保存,我们使用git reset --hard commitid 回退到文件添加的版本就可以把对应的文件找回了。
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ vim deletetest.txt
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git add .
warning: LF will be replaced by CRLF in deletetest.txt.
The file will have its original line endings in your working directory.
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git commit -m "add deletedtest.txt"
[master 34615c1] add deletedtest.txt
1 file changed, 1 insertion(+)
create mode 100644 deletetest.txt
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ ls
deletetest.txt hello,world.txt hello.txt
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ rm deletetest.txt
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git add deletetest.txt
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git commit -m "delete deletedtest.txt"
[master e83281c] delete deletedtest.txt
1 file changed, 1 deletion(-)
delete mode 100644 deletetest.txt
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ ls
hello,world.txt hello.txt
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git reflog
e83281c (HEAD -> master) HEAD@{0}: commit: delete deletedtest.txt
34615c1 HEAD@{1}: commit: add deletedtest.txt
dc1a70c HEAD@{2}: reset: moving to dc1a70c
dc1a70c HEAD@{3}: reset: moving to HEAD
dc1a70c HEAD@{4}: reset: moving to dc1a70c
8262451 HEAD@{5}: reset: moving to 8262451
dc1a70c HEAD@{6}: commit: hello add again
23d261d HEAD@{7}: commit: hello
8262451 HEAD@{8}: commit (initial): hello,world!
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git reset --hard 34615c1
HEAD is now at 34615c1 add deletedtest.txt
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ ls
deletetest.txt hello,world.txt hello.txt
3.5.2 暂存区删除文件找回
如果一个创建的文件删除了,但是还没有将文件删除的记录提交到本地库,可以用git reset --hard HEAD 来恢复(前提是创建文件已经commit 了)。
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ vim apple.txt
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git add .
warning: LF will be replaced by CRLF in apple.txt.
The file will have its original line endings in your working directory.
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git reset --hard HEAD
HEAD is now at 34615c1 add deletedtest.txt
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ ls
deletetest.txt hello,world.txt hello.txt
3.6 比较文件
git diff [filename] 将工作区的文件将暂存区的进行比较。git diff HEAD 可以将工作区的文件和本地库的文件进行比较,甚至使用git diff HEAD^ 等和历史版本中的文件进行比较。
3.7分支管理
分支管理就是业务可以在多个分支上进行。
分支管理的好处有:
- 不同的功能的代码可以在不同的分支上进行,避免各个分支的代码混在一起,并行进行各个功能,推进项目进度。
- 降低试错成本,对于一些新功能的实现,可以在非主分支上进行,完成开发后再增加到主分支,如果开发失败可以直接删除该分支,而不会影响到主分支。
查看当前所有分支。
$ git branch -v
* master 34615c1 add deletedtest.txt
新建一个分支。
$ git status
On branch master
nothing to commit, working tree clean
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git branch hot_fix
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git branch -v
hot_fix ed1955a test
* master ed1955a test
切换分支。
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git checkout hot_fix
Switched to branch 'hot_fix'
合并分支。下面再hot_fix 上做一个修改,并将其合并到master 分支。
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (hot_fix)
$ vim demo01
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (hot_fix)
$ git add .
warning: LF will be replaced by CRLF in demo01.
The file will have its original line endings in your working directory.
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (hot_fix)
$ git commit .
warning: LF will be replaced by CRLF in demo01.
The file will have its original line endings in your working directory.
[hot_fix 07a3656] hot_fix
1 file changed, 1 insertion(+)
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (hot_fix)
$ git branch -v
* hot_fix 07a3656 hot_fix
master ed1955a test
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (hot_fix)
$ git checkout master
Switched to branch 'master'
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git merge hot_fix
Updating ed1955a..07a3656
Fast-forward
demo01 | 1 +
1 file changed, 1 insertion(+)
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (master)
$ git branch -v
hot_fix 07a3656 hot_fix
* master 07a3656 hot_fix
3.8 解决冲突
git是以行记录变化的,如果两个分支同时改了同一行,git就拿不定主意了,需要程序员手动解决冲突。
主分支master上编辑文件 hello.txt .
vim hello.txt
在第二行加了点东西。并提交。
切换到hot_fix ,在同一文件第二行加点东西,提交。
现在将主分支的修改merge 到hot_fix .
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (hot_fix)
$ git branch -v
* hot_fix af35b02 conflict test on hot_fix
master 112e833 confict test master
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (hot_fix)
$ git merge 112e833
Auto-merging hello.txt
CONFLICT (content): Merge conflict in hello.txt
Automatic merge failed; fix conflicts and then commit the result.
冲突产生了,我们修复下。
vim hello.txt
发现了没有,git把冲突的地方做了标记。我们决定最后的版本后,修改,并删除它的标记。就解决了冲突。
最后看看状态,根据提示进行收尾工作。注意下面的commit 不要加文件名。
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (hot_fix|MERGING)
$ git status
On branch hot_fix
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: hello.txt
no changes added to commit (use "git add" and/or "git commit -a")
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (hot_fix|MERGING)
$ git add .
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (hot_fix|MERGING)
$ git status
On branch hot_fix
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: hello.txt
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/wechat (hot_fix|MERGING)
$ git commit
[hot_fix b9b5928] Merge commit '112e833' into hot_fix
3.9 哈希算法
哈希算法是从明文到密文的加密算法。它具有以下特点。
- 同一个明文,经同一个算法转换得到的密文一样。
- 输入数据变化,输出的结果一定变化,并且通常变化很大,即使你的输入数据只是稍微变化。
- 不可以逆推。
- 同一哈希算法的输出密文长度一定
由于以上特性,哈希算法可以用于数据校验。git就是用哈希算法保证数据的完整性的。
3.10 版本控制原理
svn等集中式的版本控制工具通过增量方式进行版本变化的记录,当需要某一个版本时,就把该文件的初始文件以及所有增量拼合成一个文件。如下图。
git把数据看作是小型文件系统的一组快照,每次提交都会保存所有文件的快照,如果该文件较前一个版本没有变化,就用指针指向前一个版本。
git在提交时,每一个文件都会生成一个hash值,然后所有的文件生成一个树对象,树对象也会生成一个hash值,最后提交时提交的对象会生成一个commit id,指向树对象。
而不同的提交对象之间会形成一个链条。
你是不是有一个疑惑,保存文件的快照有什么好处?试想svn要新建一个分支,要怎么做?答案是需要复制所有的文件。而git则可以通过指针移动轻松的建立一个新的分支。
而且在切换分支时,也只需要移动head指针就可以了。速度杠杠的。
4.远程仓库操作
回顾下本地库与远程库的交互过程。
具体要怎么做呢?
4.1 创建一个远端库
(1)github官网注册账号。(进不去可以命令行输入ipconfig /flushdns )。
(2)在本地新建一个本地库huashan ,执行git init ,新建文件huashanjianfa.txt ,提交。
(3)github上创建一个远程仓库gitsdemo ,点右上角的+ 就可以创建,这里不赘述。创建成功就是下面这样。
注意到上面有一个https 的地址,这就是我们远程库的地址了。将这个地址在本地取个别名origin。(注意origin 与https 之间的空格删掉手打,否则后面可能报错 I don’t handle protocol ‘https’)
$ git remote add origin https://github.com/banjiubanjiu/gitsdemo.git
查看下配置的结果。
$ git remote -v
origin https://github.com/banjiubanjiu/gitsdemo.git (fetch)
origin https://github.com/banjiubanjiu/gitsdemo.git (push)
做一提交吧。
git push origin master
可能会出现点小问题。
(1) github打不开或者很慢。参考博客修改hosts文件。
GitHub经常打不开或者访问慢究极解决方法,真实有效哦! - 云+社区 - 腾讯云 (tencent.com)
如何修改Hosts文件-百度经验 (baidu.com)
(2) Support for password authentication was removed …
解决方式是曲线救国,注册码云,在码云中加入github的仓库,然后将origin更新为码云上的远端仓库地址。重新提交。
$ git remote rm origin
$ git remote add origin https://gitee.com/banjiu518/gitsdemo.git
4.2 从远端库拉取代码
先做准备工作:在码云上将远端库文件内容做一点点修改。
执行代码的拉取操作,发现拉取失败,提示:could not read from remote repository 。
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo
$ mkdir pull-demo
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo
$ cd ./pull-demo/
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/pull-demo
$ git init
Initialized empty Git repository in E:/gitworkspace/gitviedo/pull-demo/.git/
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/pull-demo (master)
$ git pull pull-demo origin
fatal: 'pull-demo' does not appear to be a git repository
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
根据提示,原来是拉取代码的命令错了,命令是git pull 远端主机名 远端分支名:[本地分支名] 。其实理解了就不难记住了,从远端主机将远端分支的内容合并到本地分支,如果是当前分支,本地分支可以省略。主机在前,分支在后,从xx到yy,xx在前yy在后,同样的push 命令也是类似的git push 远端库名 本地分支名:远端分支名 。
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/pull-demo (master)
$ git pull origin master
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (6/6), done.
From https://gitee.com/banjiu518/gitsdemo
* branch master -> FETCH_HEAD
* [new branch] master -> origin/master
4.3 克隆远程库
克隆远端库不需要密码。将电脑的密码凭据删除验证下。
克隆也不需要做git init ,直接走你。
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/pull-demo (master)
$ cd ..
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo
$ mkdir git-lhc
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo
$ cd git-lhc/
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/git-lhc
$ git clone https://gitee.com/banjiu518/gitsdemo.git
Cloning into 'gitsdemo'...
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (6/6), done.
实际上git clone 还帮我们将远程库的别名取好了。
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/git-lhc/gitsdemo (master)
$ git remote -v
origin https://gitee.com/banjiu518/gitsdemo.git (fetch)
origin https://gitee.com/banjiu518/gitsdemo.git (push)
小结一下,git clone 会帮我们做三个事情。
(1)复制远端库的代码
(2)初始化本地仓库
(3)将远端库取别名origin
4.4 团队内合作
再在gitee注册一个账号,在仓库的创建账号邀请新账号称为仓库的成员。
接下来就可以用这个新账户对仓库进行操作了。修改文件并提交到库里。
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/git-lhc/gitsdemo (master)
$ vim huashanjianfa.txt
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/git-lhc/gitsdemo (master)
$ git add .
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/git-lhc/gitsdemo (master)
$ git commit .
[master 68b0a41] linghuchongyaochenggong
1 file changed, 1 insertion(+)
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/git-lhc/gitsdemo (master)
$ git push origin master
Counting objects: 3, done.
Delta compression using up to 16 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 339 bytes | 339.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.1]
To https://gitee.com/banjiu518/gitsdemo.git
88e137a..68b0a41 master -> master
这是修改的内容。
在远端库里看看,nice。
4.5 跨团队协作
如果需要团队外的成员大神X协作开发,可以把羡慕的链接发给大神x一份。大神x打开项目后可以将代码fork一份,相当于创建了一个副本仓库。
大神x对fork的代码修改后,要怎么让原来的仓库A也能看到大神在副本仓库A-copy的改动呢?当然是pull request。
看到没,就是大神x做个pull request。
然后原来仓库的管理员就可以review代码,满意就merge。
4.5 ssh免密
SSH 是较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。对仓库代码操作除了使用https 的链接,也可以使用ssh 链接。
参考链接生成配置ssh公钥,使我们使用ssh方式操作仓库中的代码时,可以免密进行。git ssh配置、密钥创建 - 简书 (jianshu.com)。注意要提交代码需要添加个人公钥,而不是教程中的部署公钥。
拉取代码。
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/pull-demo (master)
$ git pull git@gitee.com:banjiu518/gitsdemo.git master
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From gitee.com:banjiu518/gitsdemo
* branch master -> FETCH_HEAD
Updating 68b0a41..32ab95c
Fast-forward
huashanjianfa.txt | 1 +
1 file changed, 1 insertion(+)
提交代码。
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/pull-demo (master)
$ git push git@gitee.com:banjiu518/gitsdemo.git master
Counting objects: 3, done.
Delta compression using up to 16 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 265 bytes | 265.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.1]
To gitee.com:banjiu518/gitsdemo.git
32ab95c..795c86d master -> master
From gitee.com:banjiu518/gitsdemo
* branch master -> FETCH_HEAD
Updating 68b0a41..32ab95c
Fast-forward
huashanjianfa.txt | 1 +
1 file changed, 1 insertion(+)
提交代码。
24724@LAPTOP-OCSC7S98 MINGW64 /e/gitworkspace/gitviedo/pull-demo (master)
$ git push git@gitee.com:banjiu518/gitsdemo.git master
Counting objects: 3, done.
Delta compression using up to 16 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 265 bytes | 265.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.1]
To gitee.com:banjiu518/gitsdemo.git
32ab95c..795c86d master -> master
|