GitHub版本管理之你不得不学的命令

目录

1. 前提

2. 克隆项目

3. 查看分支

3.1 查看本地分支

3.2 查看远程分支

3.3 查看所有分支

4. 本地新建分支

4.1 新建分支

4.2 查看新建的分支

4.3 切换到新分支

4.4 创建+切换新分支

4.5 删除本地分支

5. 修改并提交分支

5.1 修改分支文件

5.2 新增分支文件

6. 合并分支到主干

6.1 合并分支到主干

6.2 查看合并冲突

6.3 解决合并冲突

7. 分支同步主干

8. 本地分支同步远程主机

8.1 修改远程分支

8.2 新增远程分支

8.3 删除远程分支

9 查看变更历史

9.1 查看所有变更历史

9.2 查看变更历史详情

9.3 查看最新n条变更

10. 撤销修改

10.1 commit之前的撤销

10.2 恢复删除的文件

10.3 git reset:更强大的回退


这里主要记录以下GitHub的基本用法,其他一些高级的用法有机会再做补充,未必完全正确,欢迎纠正

1. 前提

避免误导,有几个前提说明一下:

  • 本地已经安装了git(我是之前已经在Mac上安装了git,所以可以直接使用该命令,按照Git网上应该有很多资料)
  • 按照GitHub官网的指导,创建了一个hello-world项目:https://guides.github.com/activities/hello-world/
  • 了解GitHub的基本概念:repositoriesbranchescommits, and Pull Requests. 以及本地项目、远程主机,暂存区等

如果本地已经有项目想要上传GitHub,可以按如下操作: 

先在GitHub上面创建一个远程仓库,具体的操作参考GitHub网站说明,创建之后可以看到GitHub给我们提供了几种创建新的远程仓库的指导。我们按照第一种操作,将其中的命令稍加修改即可:

cd /project
echo "# walle" >> README.md
git init
git add .
git commit -m "first commit"
git remote add origin https://github.com/pengyongjun/walle.git
git push -u origin master

2. 克隆项目

我的项目地址是:https://github.com/pengyongjun/hello-world.git

现在我想把项目克隆到本地,以便于本地编辑

克隆的步骤:

  • 在本地新建一个存放项目的目录(如temp)
  • 进入上一步新建的目录
  • 执行clone命令:
$ git clone https://github.com/pengyongjun/hello-world.git

完成以上步骤之后,可以看到temp目录下新增了一个hello-world目录

之后的git命令就要在hello-world目录下执行了

3. 查看分支

3.1 查看本地分支

查看本地分支的命令是:

git branch

说明:前面带*星号的分支名称即本地当前所指向的分支

3.2 查看远程分支

查看远程分支的命令是:

git branch -r

3.3 查看所有分支

查看所有分支的命令是:

git branch -a

4. 本地新建分支

4.1 新建分支

本地新建分支的命令(新建分支:experimental):

$ git branch experimental

4.2 查看新建的分支

使用上一届的 git branch 命令,可以看到新建的分支——experimental

4.3 切换到新分支

切换到新分支的命令:

$ git checkout experimental

其中 experimental 是需要切换到的分支名,命令执行后会提示切换到新分支

4.4 创建+切换新分支

创建分支和切换到新创建的分支可以一步完成,命令如下:

git checkout -b [branch name]

4.5 删除本地分支

git checkout -d [branch name]

5. 修改并提交分支

5.1 修改分支文件

在分支experimental中做了一些修改之后,这些修改只是保存在了 暂存区

需要将修改进行提交(commit)才能将变更更新到 分支上

commit命令的用法:

git commit -a

执行以上命令,回车之后需要输入一些描述信息(基于vim命令编写即可),描述编辑完成后保存并退出

5.2 新增分支文件

如果是新增了文件,那么不能直接commit,需要先执行:git add命令

例如,在本地master分支新建了一个newFile.txt,那么需要执行以下命令:

$ git add newFile.txt
$ git commit

6. 合并分支到主干

6.1 合并分支到主干

经过上一步修改分支experimental,如果再切换到master(git checkout master),可以看到master中的对应内容并没有修改

此时如果想要将分支experimental中的修改同步到master,就需要进行合并分支操作

将experimental分支合并到master的命令:

$ git merge experimental

6.2 查看合并冲突

上一节是只在experimental中做了修改,所以合并没有任何问题

但是如果在experimental和master中对同一个文件都做了修改,那么合并时就会产生冲突

假如:

  • 既在experimental中修改了README.md文件,也在master中修改了该文件
  • experimental和master中的修改都已经commit完成
  • 当前指向master分支

那么再次执行合并分支命令时,就会提示如下报错:

执行 git status 命令,Git 会告诉你存在一个 “未合并的路径(unmerged paths)”

这只是用另外一个方式告诉你,存在一个或多个冲突:

执行以下命令可以查看具体的冲突详情:

git diff

6.3 解决合并冲突

既然冲突已经存在,那么就需要解决冲突之后才能成功合并;如果有多个文件存在冲突,那就需要一个一个解决

当然,有很多工具可以解决迅速解决合并冲突,需要的自行搜索好了

而且IDEA中也可以快速解决冲突,所以不必担心,我主要是学习这个过程

我当前冲突的文件是README.md,vim命令打开文件,可以看到已经存在关于冲突的说明

现在要做的就是按照实际需要来编辑这个文件(增删改来自两个分支的内容,直到变想要的样子),然后保存

编辑好所有的冲突文件,再次执行命令:$ git commit -a

这次的commit也就是提交合并的结果

至此,有冲突的合并也就完成了

7. 分支同步主干

已有分支有一段时间没有更新过,再次编辑之前,可能需要先将其内容同步为主干最新的内容,操作如下:

  • checkout 到 master
  • git pull (git pull fetches from origin by default and merges into the current branch.) 获取最新master
  • checkout 到 分支
  • merge master & 解决合并冲突

8. 本地分支同步远程主机

8.1 修改远程分支

本地分支修改后同步到远程主机的命令格式为:

$ git push <远程主机名> <本地分支名>:<远程分支名>

例如,要将本地的master分支同步远程主机,操作如下:

git push origin master:master

8.2 新增远程分支

同样的,experimental分支只在本地存在,通过下面的方式同步到远程主机之后,远程主机会新建该分支:

8.3 删除远程分支

删除远程分支同样使用push命令,只是将本地分支名称留空

即用一个空白的分支同步远程主机,这样就实现了删除远程分支的目的

9 查看变更历史

9.1 查看所有变更历史

git log

9.2 查看变更历史详情

git show <commit id>

命令行里面的commit id即是git log查询出来的commit值

9.3 查看最新n条变更

git log <-n>

10. 撤销修改

10.1 commit之前的撤销

如果修改了某文件,但是没有commit,现在期望还原到修改之前,则可以用git checkout实现:

10.2 恢复删除的文件

假设我们从本地存储库中删除一个文件,我们想要恢复这个文件。那么可以通过使用git checkout命令来实现

如下操作即是删除文件之后恢复的操作:

10.3 git reset:更强大的回退

在介绍git reset的用法之前,需要先说明比较重要的一点:

在分支中,有一个HEAD指针指向我们所做的commit, merge 、push 等操作都是针对 HEAD 指针所指向的这个 commit

简单的示例图如下:

而 git reset 命令可以让我们修改 HEAD 指针所指向的 commit,这样就可以达到一个 修改、撤销修改的目的:

通过 git log -[number] 命令结合起来理解上面的内容:

git reset 有三个选项(--soft, --mix 和 --hard,分别适用于三种不同的具体场景):

  • git reset --soft <commit id>
  • git reset --mix <commit id>
  • git reset --hard <commit id>

下面针对这三个选项分别做一个说明:

【git reset --soft <commit id>】

顾名思义,soft是柔软、柔和的意思,git reset --soft <commit id> 即只修改 HEAD 指针

而不会对已 commit 的操作执行回滚,也不会清除暂存区所做的修改

举个具体的例子:

  • 对newFile.txt做了第一次修改,并做了commit,记为 commit 1
  • 对newFile.txt做了第二次修改,并做了commit,记为 commit 2
  • 对newFile.txt做了第三次修改,未提交,这时暂存区记录了这次变更, git status 命令可以查看到未提交的修改
  • 这时,HEAD 指针指向 commit 2
  • 执行 git reset --soft <commit 1> 命令
  • 这时,HEAD 指针指向 commit 1
  • 而且 commit 2 所做的变更依然是 commit 的
  • 不仅如此,第三次所做的修改也依然记录在暂存区!

.git/logs/HEAD

【git reset --mix <commit id>】

--mix 是 git reset 的默认选项

它与 --soft 的不同之处在于,--mix 会从缓存区回退 commit,即 commit 的内容会回退到 暂存区

还是以上面的例子进行说明:

  • 对newFile.txt做了第一次修改,并做了commit,记为 commit 1
  • 对newFile.txt做了第二次修改,并做了commit,记为 commit 2
  • 对newFile.txt做了第三次修改,未提交,这时暂存区记录了这次变更, git status 命令可以查看到未提交的修改
  • 这时,HEAD 指针指向 commit 2
  • 执行 git reset --mix <commit 1> 命令
  • 这时,HEAD 指针指向 commit 1
  •  commit 2 所做的变更是非 commit 的,但是已经被记录在 暂存区
  • 同样,第三次所做的修改也依然记录在暂存区!

由于修改被记录在暂存区,所以如果用 vim 命令来查看文件的修改,会发现它和 --soft 的结果一样

因为第二次和第三次所做的修改都在 暂存区中

但是如果这时使用 git chechout newFile.txt 将暂存区的内容 撤销, 再 vim 查看 newFile.txt,就会发现只有第一的修改保留下来

第二次和第三次的修改都不复存在了

【git reset --hard <commit id>】

--hard 选项是破坏力最大的,它既回退已经 commit 的内容,也会清除暂存区的内容

所以应该慎用 --hard选项,除非你十分明确你想要做的变更

依然是上面的例子:

  • 对newFile.txt做了第一次修改,并做了commit,记为 commit 1
  • 对newFile.txt做了第二次修改,并做了commit,记为 commit 2
  • 对newFile.txt做了第三次修改,未提交,这时暂存区记录了这次变更, git status 命令可以查看到未提交的修改
  • 这时,HEAD 指针指向 commit 2
  • 执行 git reset --hard <commit 1> 命令
  • 这时,HEAD 指针指向 commit 1
  • 这时,变更完全回退到 commit 1 时候的样子,暂存区也是空的

关于 git reset 三个选项更深入的理解,可以参考:

https://www.cnblogs.com/kidsitcn/p/4513297.html

猜你喜欢

转载自blog.csdn.net/weixin_42534940/article/details/82896770