Linux基础知识(10)- Git 简单使用(二)
在 “Linux基础知识(9)- Git 简单使用(一)” 里,使用了 Gitee 作为远程仓库托管平台,创建了本地/远程仓库 myrepo,在 myrepo 仓库上演示了 HTTPS/SSH 方式访问 Gitee 和 Git 的一些简单操作。
本文继续在 myrepo 仓库基础上,讲解一些概念,演示一些常用的 Git 命令、Git 分支、Git 标签等。
Git:https://git-scm.com/
1. 一些概念
Git:分布式版本控制系统。
Git 仓库:repository(缩写 repo),我们将需要进行版本控制的文件目录叫做一个仓库(repository),每个仓库可以简单理解成一个目录,这个目录里面的所有文件都通过 Git 来实现版本管理,Git 都能跟踪并记录在该目录中发生的所有更新。
Git 工作区:是指在 Git 仓库内,电脑的文件浏览器和命令,可以显示的非隐藏目录和文件。
Git 暂存区:stage 或 index。一般存放在 Git 仓库内的 .git 目录下的 index 文件(.git/index)中,所以也可以把暂存区叫作索引(index)。
Git 版本库:一般指仓库的隐藏目录.git 下,objects、refs 等子目录里保存的东西。
Git 分支:branch,可以认为分支就是当前工作目录中代码的一份副本,使用分支,可以让我们从开发主线上分离出来,以免影响开发主线。
Git 标签:tag,是 Git 版本库的一个标记,指向某个 commit 的指针,tag 主要用于发布版本的管理。
Git 提交:commit,用于将暂存区里的改动内容提交到本地仓库中。
Git 提交日志:log,用于查看 Git 提交的日志。
2. 常用的 Git 命令
1) 创建仓库命令
命令 | 说明 |
git init | 初始化仓库 |
git clone | 拷贝一份远程仓库,也就是下载一个项目 |
2) 提交与修改
命令 | 说明 |
git add | 添加文件到暂存区 |
git status | 查看仓库当前的状态,显示有变更的文件 |
git diff | 比较文件的不同,即暂存区和工作区的差异 |
git commit | 提交暂存区到本地仓库 |
git clean | 将文件从工作区删除,文件不在暂存区内 |
git rm | 将文件从暂存区删除 |
git mv | 移动或重命名工作区文件 |
git reset | 回退版本 |
3) 提交日志
命令 | 说明 |
git log | 查看历史提交日志 |
git blame | 以列表形式查看指定文件的历史修改记录,它能显示文件中每行最后一次修改的提交记录 |
4)操作远程仓库
命令 | 说明 |
git remote | 远程仓库操作 |
git fetch | 从远程获取代码库,不自动合并 |
git pull | 下载远程代码并合并 |
git push | 上传远程代码并合并 |
示例:
# 进入 myrepo 仓库 $ cd myrepo # 创建新文件 test_3.txt、test_4.txt $ cat > test_3.txt << EOF test_3.txt for Git Repo. EOF $ cat > test_4.txt << EOF test_4.txt for Git Repo. EOF # 查看工作区状态 $ git status ./ # On branch master # Your branch is ahead of 'origin/master' by 4 commits. # (use "git push" to publish your local commits) # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # test_2.txt # test_3.txt # test_4.txt nothing added to commit but untracked files present (use "git add" to track) # 把 3 个文件加入暂存区 $ git add test_2.txt test_3.txt test_4.txt # 把 test_3.txt 从暂存区移除,在工作区保留 $ git rm --cached test_3.txt rm 'test_3.txt' # 把 test_4.txt 从暂存区移除,并从工作区删除 (物理上删除) $ git rm -f test_4.txt rm 'test_4.txt' # 列出哪些未被监控的文件会被删除 $ git clean -n # 删除全部未被监控的文件 $ git clean -f # 删除未被监控的 test_3.txt $ git clean -f test_3.txt Removing test_3.txt # 删除全部未被监控的文件夹和文件 $ git clean -df # 删除全部未被监控的文件夹和文件(包含隐藏文件) $ git clean -xf # 撤销最后一次 add 操作的所有文件 $ git reset HEAD # 撤销最后一次 add 操作中的 test_2.txt $ git reset HEAD test_2.txt # 回退版本到 5b3048a8 (commit ID 可以只取前几位,6 位以上应该可以保证唯一性) $ git reset --hard 5b3048a8 # 比较两个 commit $ git diff 5b3048a8 38da4918
# 比较两个 commit,只显示文件列表
$ git diff --name-only 5b3048a8 38da4918
3. Git 分支(Branch)
分支就是从主线上分离出来进行另外的操作(比如解决临时需求),不影响主线,分支做完事后合并到主线上,而且分支的任务完成了就可以把分支删掉。
Git 的分支功能特别的强大,它不需要将所有数据进行复制,只要重新创建一个分支的指针指向那个开始创建分支的提交(commit)。
1) 列出分支
# 进入 myrepo 仓库 $ cd myrepo # 没有参数时,git branch 会列出本地的分支 $ git branch * master # 创建本地 develop 分支 $ git branch develop $ git branch develop * master # 当前分支 # 切换到本地 develop 分支 $ git checkout develop $ git branch * develop master # 提交本地 develop 分支到远程仓库(远程仓库没有 develop 分支) $ git push origin develop # 查看所有分支 $ git branch -a # 切换到远程 develop2 分支 (本地没有 develop2 分支) $ git checkout -b develop2 origin/develop2
2) 分支合并
# 当前分支 develop, 修改 test_1.txt 添加 "hello git" $ vim test_1.txt test_1.txt for Git Repo. hello git # 把修改提交到 develop 分支 $ git add test_1.txt $ git commit -m "Add hello git to test_1.txt" $ cat test_1.txt test_1.txt for Git Repo. hello git # 切换到 master $ git checkout master $ cat test_1.txt test_1.txt for Git Repo. 注:master 分支的 test_1.txt 里没有 develop 分支添加的 "hello git" # 把 develop 分支合并到 master $ git merge develop $ cat test_1.txt test_1.txt for Git Repo. hello git
3) 合并冲突
# 切换到 develop 分支,修改如下 $ git checkout develop $ vim test_1.txt test_1.txt for Git Repo. hello git - develop $ git add test_1.txt $ git commit -m "Add '- develop' to test_1.txt" # 切换到 master 分支,修改如下 $ git checkout master $ vim test_1.txt test_1.txt for Git Repo. hello git - master $ git add test_1.txt $ git commit -m "Add '- master' to test_1.txt" # 把 develop 分支合并到 master $ git merge develop CONFLICT (content): Merge conflict in test_1.txt Automatic merge failed; fix conflicts and then commit the result. $ cat test_1.txt test_1.txt for Git Repo. <<<<<<< HEAD hello git - master ======= hello git - develop >>>>>>> develop # 手动修改,处理冲突 $ vim test_1.txt test_1.txt for Git Repo. hello git - fixed $ git add test_1.txt $ git commit -m "Merge fixed" [master fbd324e] Merge fixed
4) 删除分支
# 当前分支是 develop,尝试删除当前分支 $ git checkout develop $ git branch -d develop error: Cannot delete the branch 'develop' which you are currently on. # 切换到 master 后,再删除 develop 分支 $ git checkout master $ git branch -d develop Deleted branch develop (was 38da491).
4. Git 标签(Tag)
Git 的 tag 指向一次 commit,通常用来给开发分支做一个标记,如标记一个版本号、mailstone 描述、日期等。
使用 Git 创建一个 tag, 这个 tag 就代表了一个不可修改的代码历史版本,便于后期修改、运维、发布时方便的拉取代码。
Git tag 的两种类型:
(1) 轻量级的 tag:它是一个独立的分支,或者说是一个不可变的分支,指向某一次 commit 的引用;
(2) 带附注的 tag:它是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,标签说明,标签本身也允许使用 GNU Privacy Guard (GPG) 来签署或验证、电子邮件地址和日期。
1) 创建 tag
# 创建轻量标签 $ git tag v1.0-light # 查看所有的 tag,不显示附注信息 $ git tag v1.0-light # 创建带附注标签 $ git tag -a v1.1 -m "tag comments" $ git tag v1.0-light v1.1 # 查看指定 tag,显示 tag 附注信息和 commit 信息 $ git show v1.0-light tag v1.1 Tagger: xxx <xxx@123.com> Date: Wed Nov 9 11:04:44 2022 -0500 tag comments commit fbd324e5a1eb5c113561424877fd41b90aee0232 Merge: 4c90742 39b0edc Author: xxx <xxx@123.com> Date: Wed Nov 9 08:26:53 2022 -0500 Merge fixed diff --cc test_1.txt index 78eee56,8b25d17..519ae85 --- a/test_1.txt +++ b/test_1.txt @@@ -1,2 -1,2 +1,2 @@@ test_1.txt for Git Repo. - hello git - master -hello git - develop ++hello git - fixed # 可以把 tag 添加到指定的 commit 上,在命令中使用 commit ID (SHA值) 前 6 ~ 10 位 $ git tag -a v1.2 39b0ed -m "special comments to 39b0ed" $ git show v1.2 tag v1.2 Tagger: xxx <xxx@123.com> Date: Wed Nov 9 11:14:03 2022 -0500 special comments to 39b0ed commit 39b0edcaa6dc7735488ba570d182d07d734ce0b7 Author: xxx <xxx@123.com> Date: Wed Nov 9 08:20:31 2022 -0500 Add '- develop' to test_1.txt diff --git a/test_1.txt b/test_1.txt index 4889268..8b25d17 100644 --- a/test_1.txt +++ b/test_1.txt @@ -1,2 +1,2 @@ test_1.txt for Git Repo. -hello git +hello git - develop
2) 推送 tag
# 推送指定标签 $ git push origin v1.0-light Counting objects: 14, done. Delta compression using up to 2 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (12/12), 1.06 KiB | 0 bytes/s, done. Total 12 (delta 0), reused 0 (delta 0) remote: Powered by GITEE.COM [GNK-6.4] To https://gitee.com/xxx/myrepo.git * [new tag] v1.0-light -> v1.0-light # 推送所有标签 $ git push origin --tags Counting objects: 2, done. Delta compression using up to 2 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (2/2), 285 bytes | 0 bytes/s, done. Total 2 (delta 0), reused 0 (delta 0) remote: Powered by GITEE.COM [GNK-6.4] To https://gitee.com/xxx/myrepo.git * [new tag] v1.1 -> v1.1 * [new tag] v1.2 -> v1.2
3) 删除 tag
# 删除本地指定标签 $ git tag -d v1.0-light Deleted tag 'v1.0-light' (was fbd324e) # 删除远程指定标签 $ git push origin :refs/tags/v1.0-light remote: Powered by GITEE.COM [GNK-6.4] To https://gitee.com/xxx/myrepo.git - [deleted] v1.0-light # 批量删除远程标签 (取出本地标签列表,删除远程的同名标签) $ git tag | xargs -I {} git push origin :refs/tags/{} remote: Powered by GITEE.COM [GNK-6.4] To https://gitee.com/xxx/myrepo.git - [deleted] v1.1 remote: Powered by GITEE.COM [GNK-6.4] To https://gitee.com/xxx/myrepo.git - [deleted] v1.2 # 批量删除本地标签 $ git tag | xargs -I {} git tag -d {} Deleted tag 'v1.1' (was 3da4d00) Deleted tag 'v1.2' (was 0706435)
5. Git 提交历史(Log)
查看 Git 提交历史的两个命令:
git log - 查看历史提交记录。
git blame <file> - 以列表形式查看指定文件的历史修改记录。
1) git log 命令
# 查看提交历史 (全部) $ git log commit fbd324e5a1eb5c113561424877fd41b90aee0232 Merge: 4c90742 39b0edc Author: xxx <xxx@123.com> Date: Wed Nov 9 08:26:53 2022 -0500 Merge fixed commit 4c9074206d2dfd56b52f205ea0e1ea6f8e4d5cfc Author: xxx <xxx@123.com> Date: Wed Nov 9 08:21:54 2022 -0500 Add '- master' to test_1.txt ... # 查看提交历史 (简洁版) $ git log --oneline fbd324e Merge fixed 4c90742 Add '- master' to test_1.txt 39b0edc Add '- develop' to test_1.txt 5b3048a Add hello git to test_1.txt 38da491 Add test_1.txt to myrepo # 查看提交历史 (简洁版 + 倒序) $ git log --oneline --reverse 38da491 Add test_1.txt to myrepo 5b3048a Add hello git to test_1.txt 39b0edc Add '- develop' to test_1.txt 4c90742 Add '- master' to test_1.txt fbd324e Merge fixed # 查看提交历史 (简洁版 + 拓扑图) $ git log --oneline --graph * fbd324e Merge fixed |\ | * 39b0edc Add '- develop' to test_1.txt | * 5b3048a Add hello git to test_1.txt * | 4c90742 Add '- master' to test_1.txt |/ * 38da491 Add test_1.txt to myrepo # 查看指定用户的最后 3 个提交历史(简洁版) $ git log --oneline --author=xxx -3 fbd324e Merge fixed 4c90742 Add '- master' to test_1.txt 39b0edc Add '- develop' to test_1.txt # 查看某段时期内(最小单位:天)提交历史(简洁版 + 隐藏合并提交) $ git log --oneline --no-merges --before={1.weeks.ago} --after={2020-09-01} $ git log --oneline --no-merges --until={1.weeks.ago} --since={2020-09-01} 注:--before 和 --after 配对,--until 和 --since 配对,两个组合效果类似,因为最小单位是天,所以查询结果可能在时间边界上会有一些小误差。
2) git blame 命令
# 简洁版显示 test_1.txt 的提交历史 $ git log --oneline test_1.txt fbd324e Merge fixed 4c90742 Add '- master' to test_1.txt 39b0edc Add '- develop' to test_1.txt 5b3048a Add hello git to test_1.txt 38da491 Add test_1.txt to myrepo # 列表形式显示 test_1.txt 每行最后一次修改的提交记录 $ git blame test_1.txt ^38da491 (xxx 2022-11-08 08:36:53 -0500 1) test_1.txt for Git Repo. fbd324e5 (xxx 2022-11-09 08:26:53 -0500 2) hello git - fixed # 列表形式显示 test_1.txt 第 2 行最后一次修改的提交记录 $ git blame -L 2 test_1.txt fbd324e5 (xxx 2022-11-09 08:26:53 -0500 2) hello git - fixed