Loading...
墨滴

jqc8438

2021/05/20  阅读:43  主题:极客黑

git使用入门

写在前面

偶尔也会使用git,不过大部分就是执行一下git clone,上传blog也就是照着网上的命令打一打,出现什么错误了也不知道什么意思。对git的运行原理,如何版本控制,以及对git与github之间的操作不是很了解。

下定决心,花了点时间,学习了一个教程,记了一点点小笔记,以供自查。

教程:廖雪峰的Git教程

首发于:jqc8438.top

一、创建版本库

1.1 刚开始设置名字邮箱

安装完成后设置一个全局量,说明这个机子上的仓库都是这个人的。

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"

1.2 在需要git管理的目录下使用git init命令把这个目录变成可以管理的仓库。

$ git init
#文件夹中会出现一个.git的文件夹,用来管理仓库

1.3 新建一个文件,或者修改一个文件后

用命令git add告诉Git,把文件添加到仓库:

$ git add readme.md
#这个文件需要添加到仓库

用命令git commit告诉Git,把文件提交到仓库:

$ git commit -m "wrote a readme file"
##-m 命令后面写上本次操作做了啥,用于后续查看

个人感觉:在写代码的过程中,git add命令可以多次一直用,git commit最好在实现一个功能什么的之后再使用,不然会形成居多的版本,后期也不利于版本管理。

至此,已经创建好一个仓库了。

二、历史版本回溯

2.1 使用git status命令掌握仓库当前的状态

比如说进行修改后没有add,就会提醒你还没推到仓库。

image-20210515214925205
image-20210515214925205

add后再git status

image-20210515214951775
image-20210515214951775

commit后再git status

image-20210515215025448
image-20210515215025448

可以看出三步情况下status不同的状态。

2.2 可以使用git diff查看difference,修改了什么内容

image-20210515214024101
image-20210515214024101

这里就可以看到红色行是原来的,绿色行是改后的

2.3 使用git log命令显示从最近到最远的提交日志(commmit次数)

使用后,可以看到每次的提交时间,以及加的备注。

image-20210515215919505
image-20210515215919505

这里进行了两次改变,共有三个版本。其中,最上面的是当前版本,git中一般用HEAD来表示。上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本可以写成HEAD~100

2.4 使用git reset命令退回到上一个版本

$ git reset --hard HEAD^
HEAD is now at e475afc add distributed

git reset命令的本质是一个,Git在内部有个指向当前版本的HEAD指针,这个指针往不同的地方指。

使用了git reset命令之后,再使用git log命令会发现原来的不见了。可以通过commit代码号找回来

$ git reset --hard 7a09ed
HEAD is now at 83b0afe append GPL

如果找不到了,可以使用git reflog命令,git reflog用来记录你的每一次命令,可以找到执行某一次commit的commit号

2.5 工作区和暂存区

image-20210516112216201
image-20210516112216201

目前文件所放置的区域就是工作区,工作区有一个隐藏目录.git,里面装的是Git的版本库。

Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

  • git add把文件添加进去,实际上就是把文件修改添加到暂存区;
image-20210516112239117
image-20210516112239117
  • git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支(如果没有新建分支,那默认的分支就是git给我们默认创建的master分支)。
image-20210516112250620
image-20210516112250620

当不明确,目前的版本是否已经推送到分支,可以使用git diff HEAD -- readme.txt命令可以查看工作区和版本库里面最新版本的区别

2.6 撤销修改

想要撤销修改存在三种情况。

  1. 已经在文件中改了,却还没有git add
  2. 已经git add到暂存区了,还没有git commit
  3. 已经git commit了

①已经在文件中改了,却还没有git add

  • 直接手动删了相关修改即可
  • 或者使用git checkout -- file命令可以丢弃工作区的修改

②已经git add到暂存区了,还没有git commit

分两步,第一步用命令git reset HEAD <file>,以把暂存区的修改撤销掉(unstage),重新放回工作区。然后再进行暂存区的修改,即使用git checkout -- file命令

③已经git commit了

直接版本回退到上一个版本,git reset --hard HEAD^

2.7 命令git rm用于删除一个文件

如果删错了,可以使用git checkout -- test.txt把误删的文件恢复到最新版本:

git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

三、远程仓库

可以使用git remote命令,查看远程库的情况

3.1 配置本地和远程端的传输协议

本地Git仓库和GitHub仓库之间的传输是通过SSH加密的

本地端设置

需要创建SSH Key ssh-keygen -t rsa -C "youremail@example.com"。之后,可以在用户主目录里找到.ssh目录,里面有id_rsaid_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。

远程端设置

在github的SSH keys中添加ssh key

因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。

3.2添加到远程端

在github上创建好一个新的仓库。

在本地的learngit仓库下运行命令:

$ git remote add origin git@github.com:username/learngit.git

这个username是自己的github用户名。

添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。

下一步,就可以把本地库的所有内容推送到远程库上:

$ git push -u origin master
#把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。

由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。

之后,只要本地做了提交,就可以通过命令,把本地master分支的最新修改推送至GitHub

$ git push origin master

删除远程库

如果添加的时候地址写错了,或者就是想删除远程库,可以用git remote rm <name>命令。使用前,建议先用git remote -v查看远程库信息:

然后,根据名字删除,比如删除origin

$ git remote rm origin

此处的“删除”其实是解除了本地和远程的绑定关系,并不是物理上删除了远程库。远程库本身并没有任何改动。要真正删除远程库,需要登录到GitHub,在后台页面找到删除按钮再删除。

3.3 从远程库克隆

要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。

Git支持多种协议,包括https,但ssh协议速度最快。

四、分支管理

分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。

4.1 分支的创建和合并

图的形式理解分支

master分支是主分支,事实上他是一个指针。HEAD严格来说不是指向提交,而是指向mastermaster才是指向提交的,所以,HEAD指向的就是当前分支。

一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:

image-20210516154652551
image-20210516154652551

现在创建一个新的分支,例如dev时,也就是Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示此时的当前分支在dev上:

image-20210516154810991
image-20210516154810991

接下来,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:

image-20210516154844115
image-20210516154844115

之后,如果我们在dev上的工作完成了,想把dev合并到master上。最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:

image-20210516154950474
image-20210516154950474

合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:

image-20210516155021674
image-20210516155021674

分支的代码实现

可以将上面的步骤代码实现:

1.创建dev分支,然后切换到dev分支:

$ git checkout -b dev或者使用$ git switch -c dev#Switched to a new branch 'dev'#git checkout命令加上-b参数表示创建并切换

可以使用git branch命令查看当前分支

2.对内容进行更改后add,commit。并切换回master主分支

如果这个时候查看文件,发现是修改之前的内容。因为是在master主分支上并没有进行过修改

3.把dev分支的工作成果合并到master分支上

$ git merge dev#git merge命令用于合并指定分支到当前分支

4.合并完成后,删除dev分支:

git branch -d dev#Deleted branch dev

switch命令

最新版本的Git提供了新的git switch命令来切换分支:

创建并切换到新的dev分支,可以使用:

$ git switch -c dev

直接切换到已有的master分支,可以使用:

$ git switch master

使用新的git switch命令,比git checkout要更容易理解。

命令总结

查看分支:git branch

创建分支:git branch <name>

切换分支:git checkout <name>或者git switch <name>

创建+切换分支:git checkout -b <name>或者git switch -c <name>

合并某分支到当前分支:git merge <name>

删除分支:git branch -d <name>

4.2 分支合并中的冲突

如果出现不同的分支都进行的提交,分支都往前进了,这时候合并就可能会有冲突。(比如对同一个地方做不同的更改)

image-20210516163125472
image-20210516163125472

这样使用合并命令后,需要手动去修改。

image-20210516163638666
image-20210516163638666

git log --graph命令可以看到分支合并图。

最后,删除子分支。

4.3 禁用Fast forward模式的分支合并

之前fast forward的分支合并是这样的:

image-20210516154950474
image-20210516154950474

禁用fast forward的分支合并是这样的:

image-20210516164753525
image-20210516164753525

使用的命令是

git merge --no-ff -m "merge with no-ff" dev#因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。

合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。

4.4 利用git stash命令保存现场

暂时不想提交当前分支正在做的工作,又需要去其他分支工作。可以利用git stash命令保存现场

git stash##该分支里的内容就被藏起来了

git stash list命令查看藏起来的内容

git stash pop,恢复的同时把stash内容也删了

4.5 多人协作

  • 查看远程库信息,使用git remote -v
  • 本地新建的分支如果不推送到远程,对其他人就是不可见的;
  • 从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;
  • 在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
  • 建立本地分支和远程分支的关联,使用git branch --set-upstream branch-name origin/branch-name
  • 从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。

五、标签管理

标签也是一个指针,可以理解为commit号的简化版。比如发布不同的版本时候,可以有不同的标签。

5.1创建标签

敲命令git tag <name>就可以打一个新标签:

$ git tag v1.0

可以用命令git tag查看所有标签:

$ git tagv1.0

默认标签是打在最新提交的commit上的。如果想给历史commit打标签,找到历史提交的commit id,然后打上就可以了。

比方说要对某次提交打标签,它对应的commit id是f52c633,敲入命令:

$ git tag v0.9 f52c633

还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:

$ git tag -a v0.1 -m "version 0.1 released" 1094adb

可以用git show <tagname>查看标签信息

5.2 操作标签

如果标签打错了,也可以删除:

$ git tag -d v0.1

如果要推送某个标签到远程,使用命令git push origin <tagname>

或者,一次性推送全部尚未推送到远程的本地标签git push origin --tags

六、 Git的可配置项

6.1显示颜色

比如,让Git显示颜色,会让命令输出看起来更醒目:

$ git config --global color.ui true

6.2 配置别名

如果敲git st就表示git status那就简单多了,当然这种偷懒的办法我们是极力赞成的。

我们只需要敲一行命令,告诉Git,以后st就表示status

$ git config --global alias.st status

当然还有别的命令可以简写,很多人都用co表示checkoutci表示commitbr表示branch

$ git config --global alias.co checkout$ git config --global alias.ci commit$ git config --global alias.br branch

配置一个git last,让其显示最后一次提交信息:

$ git config --global alias.last 'log -1'

甚至可以把lg配置成了:

git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
image-20210516175625448
image-20210516175625448

就有这样的效果

七、Git的GUI工具SourceTree

SourceTree里可以add,commit等

八、vscode中git的使用

因为平时写代码还是会在一些平台上写的,每次都打开git的页面版本控制肯定会很麻烦。不过这些这些软件一般都会提供版本控制的。vscode和pycharm本身也有可以支持git。可以寻找各种帖子,有详细解释。

jqc8438

2021/05/20  阅读:43  主题:极客黑

作者介绍

jqc8438