一、安装git
下载地址:https://git-scm.com/download/win
默认安装即可。
二、Git基本概念
2.1 总括
- Workspace:工作区,平时放代码的地方。
- Index/stage:暂存区,用于临时存放代码的改动,实际上它只是一个文件,保存即将提交的文件列表信息。
- Repositoty:仓库区,安全存放数据的位置,里面包含提交的所有版本数据,其中HEAD指向最新版本。
- Remote:远程仓库,托管代码的服务器。
如果修改暂存区的文件,将会产生两个副本,一个继续在暂存区等待git commit操作,另一个在工作区等待git add 操作。
2.2 仓库/数据库(Repository)
2.2.1 基本概念
仓库 (Repository) :是记录文件或目录状态的地方,存储着内容修改的历史记录。在仓库的管理下,把文件和目录修改的历史记录放在对应的目录下。
- 远程仓库:配有专用的服务器,为了多人共享而建立的仓库;
- 本地仓库:为了方便个人使用,在自己的机器上配置的仓库。
仓库分为远程和本地两种。平时在本地仓库上操作就可以了,如果想要公开在本地仓库中修改的内容,把内容上传到远程仓库就可以了。另外,通过远程仓库还可以取得其他人修改的内容。
2.2.2 创建仓库
创建本地仓库的方法有两种:
-
一种是创建全新的数据库
在任意example目录下使用
git init
命令,将该目录移动到本地Git仓库中。 -
另一种是复制远程仓库
使用命令
git clone url
url是git远程仓库地址。
2.3 工作区(Workspace)和索引区(Index/stage)
索引区又叫暂存区。
在Git管理下,大家实际操作的目录被称为工作区。在仓库和工作区之间有索引,索引是为了向仓库提交作准备的区域。
Git在执行提交的时候,不是直接将工作区的状态保存到仓库,而是将设置在中间索引区域的状态保存到仓库。因此,要提交文件,首先需要把文件加入到索引区域中。
我们以一个例子说明,一个文件从 未追踪 —> 索引区 —> 本地仓库 的过程。
-
在example目录新建一个文件readme.txt,然后将文件添加到本地仓库中。
-
在添加文件到索引区之前,我们可以使用
git status
查看,当前项目的状态。git status
untracked files:未追踪的文件,这种文件不参与git的版本控制。使用
git add
可以将其添加到索引区。
-
将文件加入到索引,要使用
git add
命令。在指定加入索引的文件。用空格分割可以指定多个文件。git add <file> … # 将当前目录下所有的文件添加到索引区中 git add . # 再次使用 git status 命令,查看状态 git status
-
readme.txt已加入到索引区,此时我们就可以使用
git commit
将该文件提交到本地仓库中。git commit -m '说明' git status
-
使用
git log
可以看到历史提交记录。
2.4 提交
若要把文件或目录的添加和变更保存到仓库,就需要进行提交。执行提交后,仓库中会生成上次提交的状态与当前状态的差异记录(也被称为revision)。
如下图(来自https://backlog.com/git-tutorial/cn/intro/intro1_3.html),提交是以时间顺序排列状态被保存到仓库中的。凭借该提交和最新的文件状态,就可以知道过去的修改记录以及内容。
系统会根据修改的内容计算出没有重复的40位英文及数字来给提交命名。指定这个命名,就可以在数据库中找到对应的提交。
2.5 远程仓库
2.5.1 本地仓库与远程仓库
为了将本地数据库的修改记录共享到远程仓库,必须上传本地仓库中存储的修改记录。
为此,需要在Git执行推送(Push)操作。执行Push之后,本地的修改记录会被上传到远程仓库。所以远程仓库的修改记录就会和本地仓库的修改记录保持同步。
2.5.2 本地Git与Github进行关联
首先,本地Git仓库和GitHub仓库之间的传输是通过SSH加密,因此,我们需要在本地生成SSH密钥,然后将公钥添加到Github上。
密钥存放在C盘的管理员目录下.ssh
文件中。
# 查看是否已经存在密钥
ls -al ~/.ssh
# -t 表示密钥类型 -C密钥的描述
ssh-keygen -t rsa -C '密钥说明'
打开Github进入用户设置界面
![image-20221012223831300](https://s2.loli.net/2022/10/13/oDNx9sy8gkAUwP3.png)
![image-20221012224011411](https://s2.loli.net/2022/10/13/LcgzClYfu8TKSen.png)
验证是否关联成功
在本地命令行中执行ssh -T git@github.com
, 输入yes
。
2.5.3 本地仓库链接远程仓库
我们在前面创建了名为example
的本地仓库,并且已经将readme.txt
文件添加到了本地仓库中,那我们应该如何将readme.txt
上传到远程仓库呢?
如果我们直接执行git push
命令会是怎样的结果?
出现这样的结果,也是可以预料的。我们在2.4.2
小节中,执行的是本地git和github进行关联,也就是身份认证部分,而一个github用户可以拥有多个远程仓库,我们还没有为example
仓库链接到一个具体的远程仓库。
使用git remote add 远程名称 远程URL
命令为本地仓库链接远程仓库。
# 将本地仓库example与远程仓库链接
git remote add origin https://github.com/NorthWind2000/example.git
# 列出现有远程仓库名称
git remote -v
# 更改远程仓库名称与URL映射
git remote set-url origin https://github.com/NorthWind2000/hello-world.git
# 重命名远程仓库名称
git remote rename origin newname
# 删除远程仓库
git remote rm origin
到目前为止,我们已经将本地仓库和github远程仓库链接了。
但是我们现在还是无法将执行git pull或git push
命令,因为我们还没有将本地仓库中的分支和远程仓库的分支进行关联。
同样的原因,一个仓库中可能包括多个分支,我们需要指定本地仓库的当前分支和远程仓库的哪一个分支进行关联。
下面是两种情况的输出信息:
在下一小节介绍,如何关联本地分支和远程分支。
2.5.4 本地分支关联远程分支
在2.4.3小节中,我们将本地文件更新到远程仓库中失败了,原因我们已经了解了。
其实输出信息已经告诉我们该如何执行命令:git pull <remote> <branch>
命令说的很明白,告诉git你想要将当前分支与哪一个remote仓库的哪一个branch关联。
但是,这个命令每次执行都需要说明和
执行git branch --set-upstream-to=<remote>/<branch> <localbranch>
命令,可以将本地分支与远程分支永久关联。
我们接下来执行 git push
,发现输出下面信息:
原因是:我们的本地仓库和远程仓库是分别建立的,两个分支是两个不同的版本,具有不同的提交历史。
允许不相关历史提交,强制合并,可以解决了这个问题。
我们执行git pull --allow-unrelated-histories
后,需要我们填写合并提交的说明。通过git branch -v
可以看到每一个分支的最近一次提交。
说明:
- 上面几个小节展示的
example
案例的流程是:我们在本地仓库建立一个,然后在远程仓库又建立一个,之后进行身份验证,本地与远程仓库的链接,本地与远程分支的链接。还遇到了因为分别建立的分支提交历史不同,需要强制合并。- 其实,我们可以采用仓库建立的第二种方式:首先在github上可视化的方式建立仓库,之后通过
git clone
将其克隆到本地即可,这种方式我们无需进行2.4.3
和2.4.4
操作。
三、常用git命令
-
查看系统config:git config --system --list
-
查看用户config:git config --global --list
用户配置文件在:C:\Users\每个人电脑名字不同\.gitconfig
-
设置用户名和邮箱:git config --global user.name “名字”、git config --global user.email “邮箱”
-
在当前目录新建一个代码库:git init
-
克隆远程项目:git clone [url]
-
git add 将工作区或未追踪的文件添加到索引区。
-
git commit -m ‘xxx’ 将索引区文件提交到本地仓库。
-
git push 将本地仓库的变更同步到远程仓库。
-
git pull 来取远程仓库的变更,并且本地仓库进行合并,如果本地仓库和远程仓库都分别有不同于对方的变更,则需要进行强制合并,填写合并说明。
-
git fetch 拉去远程仓库的变更,注意不进行
git mergin
操作。git pull 相当于 git fetch + git mergin
四、git文件操作
文件的4种状态:
- Untracked:未跟踪,此文件在文件夹中,但并没有加入到git仓库,不参与版本控制,通过git add状态变为Staged。
- Unmodify:文件已经入库,未修改,即版本库中的文件快照内容与文件夹中的一致,这种文件有两种去处。
- 1、被修改变成Modified.
- 2、使用 git rm 移除版本库,变成Untracked.
- Modified:文件已经修改,仅仅是修改未进行其他操作,这种文件有两种去处。
- 1、使用git add 可进入暂存staged状态。
- 2、使用git checkout – 文件名,丢弃修改过的,返回Unmodify状态。
- Staged:暂存状态,执行git commit,将修改同步到本地库中,这时本地库中的文件与本地文件一致,文件为Unmodify状态。执行git reset HEAD filename取消暂存,文件变为Modified。
git status [filename]#查看文件状态
git status #查看所有文件状态
五、删除文件
通常直接在文件管理器中把没用的文件删了,或者用rm
命令删了:
$ rm readme.txt
这个时候,Git知道你删除了文件,因此,工作区和版本库就不一致了。
现在你有两个选择,一是确实要从版本库中删除该文件,那就用命令git rm
删掉,并且git commit
:
$ git rm readme.txt
rm 'readme.txt'
$ git commit -m "remove readme.txt"
[master d46f35e] remove readme.txt
1 file changed, 1 deletion(-)
delete mode 100644 readme.txt
现在,文件就从版本库中被删除了。
另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:
$ git checkout -- readme.txt
git checkout
其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
注意:从来没有被添加到版本库就被删除的文件,是无法恢复的!
六、git版本控制
- git log:查看版本列表;
- 在Git中,用
HEAD
表示当前版本,上一个版本就是HEAD^
,上上一个版本就是HEAD^^
。 - git reset --hard HEAD^
- git reset --hard 版本号
- 回到未来版本(比如,从第一版本—>第三版本),只要找到该版本的版本号就可以回去
- 在回退到过去版本后还没有关闭命令行的情况下,可以顺着命令行往上找到版本号;
- 在关闭命令行或清除屏幕后,使用git reflog找到操作记录,在记录中找到版本号。
![002](https://s2.loli.net/2022/10/13/ivMysIJZnKWHUAT.png)
git reset --hard ‘版本哈希’ 可以用来回退版本,但是如果不带–hard参数,即git reset可以用来从暂存区回到工作区。
七、git分支(branch)
Git的分支功能可以支持同时进行多个功能的开发和版本管理。
为了不受其他开发人员的影响,可以在主分支上建立自己专用的分支。完成工作后,将自己分支上的修改合并到主分支。因为每一次提交的历史记录都会被保存,所以当发生问题时,定位和修改造成问题的提交就容易多了。
在仓库进行最初的提交后, Git会创建一个名为master的分支。因此之后的提交,在切换分支之前都会添加到master分支里。
7.1 创建分支
使用git branch <branchname>
命令,在当前仓库中创建一个新的分支。
# 创建一个名为one的分支
git branch one
# 展示所有分支
git branch
7.2 切换分支
使用git chechout <branch>
命令,切换到指定的分支。
# 切换到名为one分支
git checkout one
我们在不同分支下修改内容,在合并之前,只影响当前分支。
我们进入one
分支,修改example/readme.txt
在里面添加一个hello world
。
7.3 合并分支
执行merge命令以合并分支。
该命令将指定分支导入到HEAD指定的分支。先切换main分支,然后把one分支导入到main分支。
# 将one分支合并到当前分支中
git merge one
当我们在不同分支中同时修改一个文件时,会存在自动合并失败的情况,此时需要我们手动完成合并工作,重新提交。
7.4 删除分支
在branch命令指定-d选项执行,以删除分支。
# 删除one分支
git branch -d one
八、git增加代理
github不使用代理就可以访问,但克隆源码会非常慢。就算你电脑挂的科学上网也不行,因为git并不会自动使用代理。
这里说明Clash for Windows科学上网工具,如何在git中添加代理。
HTTP
在命令行里输入下面两条指令即可:
git config --global http.proxy http://localhost:7890
git config --global https.proxy http://localhost:7890
有两个注意点:
- 无论是
http.proxy
还是https.proxy
,后面写的都是http://...
; - 7890只是Clash的默认端口,根据需求将
:7890
改为自己电脑上的实际端口。
完成
清除代理
git config --global --unset http.proxy
注意:时间长了,git还是可能连不上github,这个时候清除代理,重新打开软件,再重新添加代理。
只对Github代理(推荐)
#使用socks5代理(推荐)
git config --global http.https://github.com.proxy socks5://127.0.0.1:7890
#使用http代理(不推荐)
git config --global http.https://github.com.proxy http://127.0.0.1:7890
git config --global https.https://github.com.proxy http://127.0.0.1:7890