版本控制系统-Git 学习 《progit》电子书学习记录 第一章 (仅隔个人学习记录用)

Git 是一种分布式版本控制系统,即依靠任何一个拷贝了这个项目的设备都可以进行恢复到任何一个版本,每一次克隆都是对项目的完整备份。

Git 的三种状态

  • 已提交(committed)表示数据已经安全地保存在本地数据库中
  • 已修改(modified)表示修改了文件,但还没保存到数据库中
  • 已暂存(staged)表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中

Git 的三个区域

  • 工作区 是对项目的某个版本提取出来的内容。通常是用 git clone拷贝下来的,放在磁盘上供修改或者使用。
  • 暂存区 是一个文件,用于保存下一次需要提交的文件列表信息。
  • Git 仓库目录是 Git 用来保存项目的元数据和对象数据库的地方。这是 Git 中最重要的部分,从其它计算机克隆仓库时,复制的就是这里的数据。

初次运行Git的配置 配置用户名和邮箱

js 复制代码
git config --global user.name "BoLin"
git config --global user.email szwtsdsoftware@163.com

使用了--global的情况下,这个配置是全局生效的。

Git 基础

获取Git仓库

方式 1 将本地的尚未进行版本控制的本地目录转换为Git仓库

  1. 进入尚未进行版本管理的但准备要进行版本管理的目录,例: cd my_project
  2. 在命令行执行 git init
  3. 如果这个文件夹是一个非空文件夹,里面有*.c文件和LICENSE.txt文件,那么我们可以执行命令将文件加入暂存区 ,例:git add *.c git | add LICENSE.txt | git commit -m 'initial project version'
  4. 现在已经得到了一个存在被追踪文件与初始提交的 Git 仓库

方式 2 从服务器中克隆(clone)一个已经存在的Git仓库(如我们平时使用的一些GitHub上面的库)

git clone https://github.com/libgit2/libgit2 这个命令的作用是将github上面的这个项目克隆到本地,执行完成会在执行这个命令的目录创建一个文件夹libgit2 git clone https://github.com/libgit2/libgit2 mylibgit这个命令和上面命令的作用相同,但是会将libgit2文件夹名称改成mylibgit

记录每次更新到仓库

工作目录下的文件都是这两种状态

  1. 已跟踪 指这个文件被纳入了版本控制,上一次快照中有它们的记录,工作一段时间后,状态可能是未修改或者已经修改或者已暂存区。(从服务器中拷贝下来的所有文件都已经被纳入了版本控制,都属于未修改状态)
  2. 未跟踪 未纳入版本控制的其它文件。

检查当前文件的状态

git status 可以查看当前文件的状态,输出如下:

js 复制代码
On branch main  // 指明分支
No commits yet  
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
new file:   main.cpp
new file:   readme.txt
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
modified:   readme.txt
Untracked files:
  (use "git add <file>..." to include in what will be committed)
a.out

git status -s命令的输出会更简洁,输出如下:

js 复制代码
A  main.cpp
AM readme.txt
?? a.out
  1. A代表已经暂存
  2. M代表已经修改
  3. AM代表已经有暂存版本同时也有修改版本,修改版本还没有添加到暂存
  4. ??表示新添加没有跟踪的文件

跟踪新文件

git add README.txt可以将README.txt 这个文件纳入跟踪 git add .可以将这个文件下的所有文件和文件夹递归纳入跟踪

忽略文件

我们有一些文件不需要进行版本管理,也不希望它们总出现在未跟踪文件列表,那么我们可以创建一个名为 .gitignore 的文件,告诉Git忽视掉一些文件。

例子:

js 复制代码
*.out
*~

第一行的作用是忽视后缀为.out的文件,我们再执行git status -s会显示如下:

js 复制代码
A  main.cpp
AM readme.txt
?? .gitignore

这时候?? a.out就不见了

文件 .gitignore 的规范:

  1. 所有空行或者以 # 开头的行都会被 Git 忽略。
  2. 可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。
  3. 匹配模式可以以(/)开头防止递归。
  4. 匹配模式可以以(/)结尾指定目录。
  5. 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反。

例子:

js 复制代码
# 忽略所有的 .a 文件
*.a
# 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件
!lib.a
# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO
# 忽略任何目录下名为 build 的文件夹
build/
# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt
# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf

查看已暂存和未暂存的修改

git diff可以查看暂存版本和未暂存版本的差异,输出如下:

js 复制代码
**diff --git a/readme.txt b/readme.txt******
**index f7cd3bf..cdaabc9 100644******
**--- a/readme.txt******
**+++ b/readme.txt******
@@ -1 +1,3 @@
 这一个Git测试项目
+
+修改测试

此命令比较的是工作目录中当前文件和暂存区域快照之间的差异。 也就是修改之后还没有暂存起来的变化内容。

git diff --staged可以查看已暂存的将要添加到下次提交里的内容和现在已经提交的内容的差异。输出如下:

js 复制代码
****new file mode 100644******
**index 0000000..2443569******
**--- /dev/null******
**+++ b/main.cpp******
@@ -0,0 +1,6 @@
+#include <iostream>
+
+int main(int argc,char * argv[]){
+       std::cout << "hello,world";
+       return 0;
+}

**diff --git a/readme.txt b/readme.txt******
**new file mode 100644******
**index 0000000..f7cd3bf******
**--- /dev/null******
**+++ b/readme.txt******
@@ -0,0 +1 @@
+这一个Git测试项目**

git diff --cached 查看已经暂存起来的变化

提交更新

最后使用 git commit 进行提交。直接使用这个命令的情况下会跳转到vim编辑器里面让你输入提交的内容,如果不希望这样的情况下可以直接使用命令git commit -m "第一次提交"。输出如下:

js 复制代码
[main (root-commit) c64f7ea] 第一次提交
 2 files changed, 7 insertions(+)
 create mode 100644 main.cpp
 create mode 100644 readme.txt

请记住,提交时记录的是放在暂存区域的快照。 任何还未暂存文件的仍然保持已修改状态,可以在下次提交时纳入版本管理。 每一次运行提交操作,都是对你项目作一次快照,以后可以回到这个状态,或者进行比较。

跳过使用暂存区域

我们可以使用命令一次性将已经跟踪过的但是做了修改但是还没有提交的文件一次进行提交,不用执行git add [FILE_NAME],git commit -a -m '提交信息'

移除文件

假设说我们不想在跟踪readme.txt 文件了,那么我们可以执行git rm readme.txt将readme.txt文件从跟踪列表中移除。

如果说readme.txt 文件是已修改,未暂存,已跟踪的状态,那么我们需要执行git rm -f readme.txt才可以将文件进行移除。

如果我们想把一个文件从暂存区+仓库中移除,那么我们可以执行git rm --cached README

如果说我们不小心把log目添加到暂存区里面了,那么我们可以执行git rm log/\*.log

练习+测试 :

  1. 假设1.0 版本将readme.txt 文件添加到了暂存区,但是1.1 版本将readme.txt 文件删除 了,那么还可以恢复吗?

移动文件

执行git mv main.cpp app.cpp命令可以将本地文件main.cpp 重命名为app.cpp,并且添加到暂存区。

相当于三条命令

js 复制代码
mv README.md README
git rm README.md
git add README

这是我们执行git status,输出如下:

js 复制代码
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
renamed:    main.cpp -> app.cpp
deleted:    readme.txt
Untracked files:
  (use "git add <file>..." to include in what will be committed)
.gitignore

查看提交记录

通过 git log 命令我们可以看到提交记录,输出如下:

js 复制代码
commit c64f7ea1cdd302bb1819fa388d21c89fd59156d5 (**HEAD ->** **main**)
Author: wtbolin <szwtsdsoftware@163.com>
Date:   Sun Aug 17 12:17:44 2025 +0800
    第一次提交

查看最近两次的提交,git log -p -2

提交的简略统计信息,git log --stat

DIY显示提交,git log --pretty=format:"%h - %an, %ar : %s"

DIY的表:

选项 说明
%H 提交的完整哈希值
%h 提交的简写哈希值
%T 树的完整哈希值
%t 树的简写哈希值
%P 父提交的完整哈希值
%p 父提交的简写哈希值
%an 作者名字
%ae 作者的电子邮件地址
%ad 作者修订日期(可以用 --date=选项 来定制格式)
%ar 作者修订日期,按多久以前的方式显示
%cn 提交者的名字
%ce 提交者的电子邮件地址
%cd 提交日期
%cr 提交日期(距今多长时间)
%s 提交说明

撤销操作

假设我们进行了一次提交,但是有一个文件我们没有添加到这次提交中,我们可以使用git commit --amend合并到这次提交。

js 复制代码
git commit -m 'initial commit'
git add forgotten_file
git commit --amend

最终你只会看到一次提交结果,这相当于用新的提交覆盖旧的提交,保证你的历史的干净,不至于出现"啊,忘了添加一个文件"之类的历史。

取消暂存的文件

我们可以使用 git restore --staged [FILE] 来撤销一个操作,以撤销删除操作为例:

执行 git status

js 复制代码
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
renamed:    main.cpp -> app.cpp
deleted:    readme.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)
.gitignore

执行 git restore --staged readme.txt 执行 git status

js 复制代码
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
renamed:    main.cpp -> app.cpp

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
deleted:    readme.txt
Untracked files:
  (use "git add <file>..." to include in what will be committed)
.gitignore

执行git restore readme.txt,这时候被删除的readme.txt文件就被恢复了

撤销对文件的修改

我们修改一下 app.cpp 文件,然后执行 git status

js 复制代码
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
modified:   app.cpp

no changes added to commit (use "git add" and/or "git commit -a")

这时候我们如果想撤销之前所做的修改,可以执行 git checkout app.cpp ,这是后git会拿最近的提交去覆盖这个文件。

注意:执行git checkout app.cpp 之后,原来对这个文件做的修改就彻底找不回来了,所以要慎重

远程仓库的使用

git remote -v命令可以显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL

js 复制代码
origin https://github.com/-/-.git (fetch)
origin https://github.com/-/-.git (push)

我们可以执行 git remote add pb https://github.com/paulboone/ticgit 添加一个远程仓库

从远程仓库中获取数据

执行 git fetch <remote>,这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。这个命令只会将文件下载到你的本地仓库,但是不会修改你的工作区,你需要手动合并

如果希望拉去远程分支并且和本地分支进行合并的情况下,请执行git pull

推送到远程分支

git push <remote> <branch> 命令可以将本地分支推送到远程分支。但是这个命令需要你对仓库有写权限+在你提交之前没有别的用户进行提交,如果有别的用户进行提交,那么你需要去拉取最新的仓库进行合并,然后再执行push命令进行推送。

查看某个远程仓库

git remote show <remote> 可以查看远程仓库信息

js 复制代码
* remote origin

  Fetch URL: https://github.com/-/-.git
  Push  URL: https://github.com/-/-.git
  HEAD branch: main
  Remote branches:
    main              tracked
    newComputorBranch tracked

  Local branches configured for 'git pull':
    main              merges with remote main
    newComputorBranch merges with remote newComputorBranch

  Local refs configured for 'git push':
    main              pushes to main              (fast-forwardable)
    newComputorBranch pushes to newComputorBranch (up to date)

远程仓库的重命名与移除

git remote rename pb paul 可以对remote进行重命名,这同样也会修改你所有远程跟踪的分支名字。 那些过去引用 pb/master 的现在会引用paul/master。

git remote remove paul可以移除一个远程仓库。一旦你使用这种方式删除了一个远程仓库,那么所有和这个远程仓库相关的远程跟踪分支以及配置信息也会一起被删除。

打标签 先忽视,暂时可能不会用到

git tag可以显示标签。

如果只对 1.8.5 系列感兴趣,可以运行:git tag -l "v1.8.5*"

Git别名

主要是简化命令

我们执行 git config --global alias.st status之后,git st 就和git status 等价了

Git 分支

分支简介

相关推荐
裸奔的大金毛6 小时前
Tekton - 自定义镜像配置git仓库克隆
git·ci/cd·devops·tekton
Adorable老犀牛9 小时前
可遇不可求的自动化运维工具 | 2 | 实施阶段一:基础准备
运维·git·vscode·python·node.js·自动化
xiaok11 小时前
把代码上传到gitee的时候,怎么忽略node_modules文件夹
git·gitlab·github
唐叔在学习11 小时前
听说有老哥分不清Git branch和tag?这不看看嘛
git·后端
雁于飞21 小时前
vscode中使用git、githup的基操
笔记·git·vscode·学习·elasticsearch·gitee·github
小毛驴8501 天前
所有微服务部署都使用一个git地址,并且通过docker部署各个服务的情况下,如何编写mvn指令来处理各个服务。
git·docker·微服务
国王不在家1 天前
git 切换仓库后清理分支缓存
git
柯南二号1 天前
【Gitlab】Ubuntu 20.04服务器部署Gitlab
git·gitlab
phac1231 天前
git 如何直接拉去远程仓库的内容且忽略本地与远端不一致的commit
大数据·git·elasticsearch
ficker132 天前
git常用命令
git