Git学习 笔记

Git基础 学习总结

什么是版本控制,版本迭代,新的版本!版本管理器

为什么学习使用Git?

版本控制(Revisoin control)是一种在开发的过程中用于管理我们的文件,目录或工程的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术。

  • 实现跨区域多人协同开发
  • 追踪和记载一个或多个文件的历史记录
  • 组织和保护你的源代码和文档
  • 统计工作量
  • 并行开发,提高工作效率
  • 跟踪记录整个软件的开发过程
  • 减轻开发人员的负担,节省时间,同时降低人为错误

简单一点来说就是用于管理多人协同开发项目的技术

Git使用场景
  • 命令行

    在我们的CMD终端(Powershell)可以使用Git.

  • 代码编辑器和IDE(现在大多数IDE会为我们提供git功能)

    IDE

  • 图形用户界面(专门为Git提供,可以在Git官网进行下载 Git官网)

    在这里插入图片描述

如何打开git

在新建的文件夹目录(Git仓库相当于一个文件目录)下点击鼠标右键 点击 open GIt bash here

![外链图片转存失败,源站可能有防盗链在这里插入图片描述
也可以在开始菜单里找到Git -> Git Bash,弹出一个类似命令行的东西,但是需要在该目录下新建一个文件夹进行下一步操作

在这里插入图片描述

查看Git版本

在命令提示符下输入如下命令可查看当前GIt的版本

git --version

在这里插入图片描述

Git的第一步

因为Git是分布式版本控制系统,所以,每个机器都是要自报家门:你的名字和Email地址

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

注意git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。

创建版本库

什么是版本库呢?版本库又名仓库(Repository),你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

如果是按上述第一种方法打开git,直接通过git init命令把这个目录变成Git可以管理的仓库

$ git init
Initialized empty Git repository in /d/learngit/.git/

瞬间Git就把仓库建好了,而且告诉你是一个空的仓库(empty Git repository),细心的读者可以发现当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。

如果你没有看到.git目录,那是因为这个目录默认是隐藏的,用ls -ah命令就可以看见。

如果是第二种方法打开git,需要找个合适的地方,创建一个空目录

$ mkdir learngit
$ cd learngit
$ pwd
/d/learngit

pwd命令用于显示当前目录。在我的电脑上,这个仓库位于/d/learngit

之后再进行前者操作

设置编辑器和行结束符
  • 设置默认编辑器(git的默认编辑器是vim,为了更舒服的编辑效果,将vs code设为默认编辑器)

    git Bash中输入如下命令

    $ git config --global core.editor "code --wait"
    

    这会将 VS Code 设置为 Git 的全局默认编辑器。当你使用 Git 进行操作时(如提交信息、合并冲突等),VS Code 将会作为编辑器打开。

    检查设置

    你可以通过如下命令来检查是否成功设置

    $ git config --global --get core.editor
    

    如果显示code --wait,说明设置成功。

    使用如下命令可以查看我们的配置文件

    $ git config --global -e
    

    !在这里插入图片描述
    打开该文件后,会出现一个等待提示

在这里插入图片描述.gitconfig文件关闭后可执行下一步操作

  • 设置行结束符

    在使用 Git 时,Windows 和 macOS(以及 Linux)之间的行结束符(EOL, End of Line)处理有一些不同。了解这些差异对于跨平台开发和版本控制非常重要

先来解释一下Windows和macOS|Linux系统的行结束符的差异

  • 在windows系统下:使用的是回车符加换行符(CRLF),具体表现为\r\n

  • 在macOS和Linux系统下:使用的是换行符(LF),具体表现为\n

    因此,当一个项目在不同操作系统之间共享时,行结束符的不同可能会导致不必要的文件变更,即使文件内容并没有真正改变。

为了处理这种差异,Git提供了core.autorlf选项,可以自动处理行结束符转换。

Git的自动行结束符转换

  • 在Windiws上设置:

    $ git config --global core.autocelf true
    

    这会在你提交文件时将 CRLF 转换为 LF,并在检出文件时将 LF 转换回 CRLF。这样,Git 仓库中的文件将始终使用 LF,而工作目录中的文件则使用 CRLF

  • 在macOS|Linux上设置:

    $ git config --global core.autocrlf input
    

    这会在你提交文件时将 CRLF 转换为 LF,但在检出文件时不做任何转换。工作目录和仓库中的文件都使用 LF

  • 关闭自动转换(如果希望自己手动控制):

    $ git config --global core.autocrlf false
    

    这种设置下,Git 不会自动转换行结束符,你需要确保自己管理好行结束符的使用。

注意:如果你的项目中已经存在行结束符的问题,比如因为开发者使用了不同的操作系统导致的混乱,可以使用以下步骤进行修复:

在仓库中强制统一行结束符

  • 首先,配置.gitattributes文件来确保文件类型的行结束符一致性,如:

    * text = auto
    

    这样会自动根据操作系统处理文本文件的行结束符。

重新格式化文件

  • 执行以下命令,强制Git重新规范文件的行结束符:

    $ git rm --cached -r
    $ git reset --hard
    

    这会移除暂存区的所有文件,然后重新使用新的配置重新添加

提交变更

  • 最后,将规范后的文件提交到仓库:

    $ git add .
    $ git commit -m "Normalize line endings"
    

通过上述操作,我们已经做好预备工作了,接下来就是Git的常用操作

提交文件到仓库
  • 首先我们使用如下命令创建两个新文件并且写入内容

    $ echo hello > file1.txt
    $ echo hello > file2.txt
    

    echo命令不是git命令,它是用于将内容写入文件的标准Unix或Linux命令

    上面这两个文件一定要放到Learngit目录下(子目录也行),因为这是一个Git仓库,放到其他地方Git再厉害也找不到这个文件

    因为在第一次在目录中初始化Git仓库时,Git不会自动跟踪文件,所以我们必须指示它跟踪它们,所以我们先运行git status产看工作状态

    $ git status
    On branch master
    
    No commits yet
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
            file1.txt
            file2.txt
    
    nothing added to commit but untracked files present (use "git add" to track)
    
    

    我们可以发现标红的文件还未跟踪,因为它们还不在暂存区

    和把大象放进冰箱需要三步相比,把一个文件或多个文件放入Git仓库只需要两步

  • 第一步,用git add告诉GIt,把文件添加到暂存区:

    #可以将文件一个一个放入仓库
    $ git add file1.txt
    $ git add file2.txt
    
    #也可以将所有满足通配符匹配的文件放入仓库
    $ git add *.txt
    

    执行上面的命令,发现没有任何显示,这就对了,Unix的哲学就是**“没有消息就是好消息”**,说明已经添加成功了

  • 第二步,用git commit告诉Git,把文件提交到仓库:

    $ git commit -m "add file1 and file2"
    [master (root-commit) 96f35b2] add file1 and file2
     2 files changed, 2 insertions(+)
     create mode 100644 file1.txt
     create mode 100644 file2.txt
    

    简单解释一下git commit命令,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。

    git commit命令执行成功之后会告示你,2 files change:2个文件被改动(我们新添加的file.txt和file2.txt文件);2 instertions: 插入了两行内容(file1.txt和file2.txt中各有一行内容)

    为什么Git添加文件需要addcommit一共两步呢?因为commit可以一次提交很多文件,所以你可以多次add不同的文件,比如:

    $ git add file1.txt
    $ git add file2.txt file3.txt
    $ git commit -m "add 3 files."
    
文件差异

我们已经成功发添加并且提交了file1.txt和file2.txt文件,当我们修改目录下file1.txt的内容:

$ echo World! >> file1.txt

现在,运行git status命令看看结果:

$ git status
On branch master
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:   file1.txt

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

git status命令可以让我们时刻掌握仓库当前的状态,上面的命令输出告诉我们,file1.txt被修改过了,但还没有准备提交的修改。

虽然Git告诉我们file1.txt文件被修改了,但如果能看看具体修改了什么内容,自然是更改的。比如你休假两周从国外回来,第一天上班,已经记不清上次修改了什么,需要用git diff这个命令看看:

$ git diff file1.txt
warning: in the working copy of 'file1.txt', LF will be replaced by CRLF the next time Git touches it
diff --git a/file1.txt b/file1.txt
index ce01362..2043f18 100644
--- a/file1.txt
+++ b/file1.txt
@@ -1 +1,2 @@
 hello
+World!

此命令用于查看工作区中文件与暂存区中文件的差异、暂存区中文件与仓库区中文件的差异 (此时需要使用 --staged 参数)。

如上所示,输入 git diff 命令后,它就指出工作区中 file1.txt 与暂存区中 file1.txt 的差异 ( diff 命令输出中,使用 a/b/ 标识不同区内的文件,a 用于标识具有较旧内容的文件,b 用于标识具有较新内容的文件)。

知道了对file1.txt文件做了什么修改,再将它提交到仓库就放心多了,提交修改和提交新文件是一样的两步,第一步是git add

$ git add file1.txt

同样没有任何输出。在执行第二步git commit之前,我们再运行git status看看当前仓库的状态:

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   file1.txt

git status告诉我们,将要被提交的修改包括file1.txt,下一步,就可以放心地提交了:

$ git commit -m"add World!"
[master b14e175] add World!
 1 file changed, 1 insertion(+)

提交后,我们再用git status命令查看仓库当前状态:

$ git status
On branch master
nothing to commit, working tree clean

Git告诉我们当前没有需要提交的修改,而且,工作目录是干净的。

回退版本

在弄明白版本回退前,我们先再次修改file1.txt文件

$ cat file1.txt
hello
World!
test

然后提交修改:

$ git add file1.txt
$ git commit -m "add test"
[master 580055a] add test
 1 file changed, 1 insertion(+)

像这样,你不断对文件进行修改,然后不断提交修改到版本库里,就好比玩RPG游戏时,每通过一关就会自动把游戏状态存盘,如果某一关没过去,你还可以选择读取前一关的状态。有些时候,在打Boss之前,你会手动存盘,以便万一打Boss失败了,可以从最近的地方重新开始。Git也是一样,每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为commit。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit恢复,然后继续工作,而不是把几个月的工作成果全部丢失。

让咱们来回顾一下file1.txt文件一共有几个版本被提交到Git仓库里了:

版本1:add file1 and add file2

Hello

版本2:add World!

Hello
World!

版本3:add test

Hello
World
test

在实际工作中,我们怎么可能记住一个一千多行的文件每次都修改了哪些内容,不然要版本控制系统干啥,版本控制系统 肯定有某个命令可以告诉我们历史记录,在Git中,我们用git log命令查看:

$ git log
commit 580055a992098e39908a055baf83e3bc499066fa (HEAD -> master)
Author: Jay <wenyangzheng669@gmail.com>
Date:   Fri Aug 16 09:05:59 2024 +0800

    add test

commit b14e1753944a5e2551a3e50dd61de9addc43a429
Author: Jay <wenyangzheng669@gmail.com>
Date:   Thu Aug 15 16:54:55 2024 +0800

    add World!

commit 96f35b2622fbe957c8c1876fddf96dc5bc451a35
Author: Jay <wenyangzheng669@gmail.com>
Date:   Thu Aug 15 15:40:36 2024 +0800

git log 命令显示从最近到最远的提交日志,我们可以看到3次提交,最近的一次是add test,上一次是add World!最早一次是add file1 and file2

如果觉得眼花缭乱,可以试试加上--petty=oneline参数:

$ git log --pretty=oneline
580055a992098e39908a055baf83e3bc499066fa (HEAD -> master) add test
b14e1753944a5e2551a3e50dd61de9addc43a429 add World!
96f35b2622fbe957c8c1876fddf96dc5bc451a35 add file1 and file2

好了,我们开始讲解重头戏部分了,准备把file1.txt回退到上个版本,也就是add World!的那个版本

在这之前,我们必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新提交的580055a...(每个人的提交ID都是不一样的),上个版本就是HEAD^上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100

现在,我们要把当前版本add test回退到上一个版本add World!,就可以使用git reset命令:

$ git reset --hard HEAD^
HEAD is now at b14e175 add World!

--hard参数有啥意义?--hard会回退到上个版本的已提交状态,而--soft会回退到上个版本的未提交状态,--mixed会回退到上个版本已添加但未提交的状态。现在,先放心使用--hard

看看file1.txt的内容是不是版本add World!:

$ cat file1.txt
hello
World!

果然还是被还原了。

我们还可以继续回到上一个版本file1 and file2,可以一直进行往前面回退,先让我们用git log再看看现在版本库的状态:

$ git log
commit b14e1753944a5e2551a3e50dd61de9addc43a429 (HEAD -> master)
Author: Jay <wenyangzheng669@gmail.com>
Date:   Thu Aug 15 16:54:55 2024 +0800

    add World!

commit 96f35b2622fbe957c8c1876fddf96dc5bc451a35
Author: Jay <wenyangzheng669@gmail.com>
Date:   Thu Aug 15 15:40:36 2024 +0800

    add file1 and file2

可以发现,我们最新修改的那个add test版本不见了,好比你从21世纪坐着哆啦A梦的时光穿梭机来到了19世纪,想再回去已经回不去了,怎么办?

其实还是有办法的,只要我们的窗口没被关掉,就可以一直顺着上面找,找回add testcommit id580055a...,于是就可以指定回到未来的某个版本:

$ git reset --hard 58005
HEAD is now at 580055a add test

版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写一两位,因为Git可以能找到多个版本号,就无法确定是哪一个了。

我们再查看file1.txt的内容:

$ cat file1.txt
hello
World!
test

果然,还原到了最新修改了版本。

Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向add test:

┌────┐
│HEAD│
└────┘
   │
   └──▶ ○ add test
        │
        ○ add World!
        │
        ○ add file1 and file2

刚刚我们做的回退操作其实都是在改变HEAD指针的指向,有点C语言的味了,现在我们改为指向`add World!:

┌────┐
│HEAD│
└────┘
   │
   │    ○ add test
   │    │
   └──▶ ○ add World!
        │
        ○ add file1 and file2

然后顺便把工作区的文件更新了。所以你让HEAD指向哪个版本,你就把当前版本定位在哪。

现在,你回退到了某个版本,关掉电脑,第二天早上就后悔了,想恢复到新版本怎么办?找不到新版本的commit id怎么办?

在Git中,总是有后悔药可以吃的。当你用$ git reset --hard HEAD^回退到add World!版本时,再想恢复到append GPL,就必须找到add test的commit id。Git提供了一个命令git reflog用来记录你的每一次命令

$ git reflog
580055a (HEAD -> master) HEAD@{0}: reset: moving to 58005
b14e175 HEAD@{1}: reset: moving to HEAD^
3fb928e HEAD@{2}: commit (amend): add test
580055a (HEAD -> master) HEAD@{3}: commit: add test
b14e175 HEAD@{4}: commit: add World!
96f35b2 HEAD@{5}: commit (initial): add file1 and file2
工作区和暂存区

Git工作区和暂存区:

  • 工作区:
工作区是本地计算机上的项目目录,你在这里进行文件的创建,修改和删除操作。工作区包含了当前项目的所有文件和子目录。
  • 暂存区:
英文叫stage或insex。一般放在 `.git`目录下的index文件(,git/index)中,所以我们把暂存区有时也叫索引
  • 版本库:
工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。

下面这个图简单说明了工作区和版本库之间的关系:

在这里插入图片描述

撤销修改

如果我们不小心在文件中添加了错误信息,但是好险及时被我们发现了,例如我们在file1.txt文件中添加了这么一行内容:

$ cat file1.txt
hello
World!
test
Jay
I am a strong boy

如果发现得及时,就可以很容易纠正它,可以删除最后一行,手动把文件恢复到上一个版本的状态。用git status查看一下:

$ git status
On branch master
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:   file1.txt

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

可以发现,Git会告诉我们,git restore -- file可以丢弃工作区的修改:

$ git restore -- file1.txt

命令git restore -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:

一种是file1.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

一种是file1.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

总之,就是让这个文件回到最近一次git commitgit add时的状态。

再看看file1.txt的文件内容:

$ cat file1.txt
hello
World!
test
Jay

如果我们不小心把错误信息还git add到暂存区了:

$ cat file1.txt
hello
World!
test
Jay
I am a strong boy

$ git add

git commit之前我们发现了这个问题

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   file1.txt

Git告诉我们,用命令git restore --staged <file>可以把暂存区的修改撤销掉(unstage),重新返回工作区:

$ git restore --staged file1.txt

git restore命令既可以回退版本,也可以把暂存区的修改回退到工作区

再用git status查看,现在暂存区是干净的,工作区有修改:

$ git status
On branch master
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:   file1.txt

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

再重复上一阶段撤销修改的操作:

$ git restore -- file1.txt

$ git status
On branch master
nothing to commit, working tree clean

这就OK了!

注意:这些操作只是在你没有将文件发生的修改推送到远程,如果推送到远程仓库就麻烦了。

远程仓库

远程仓库是指托管在因特网或其他网络中你的项目的版本库。借助于远程仓库,我们可方便实现多人合作项目开发。

为完成协作开发,我们需要管理此远程仓库。此节首先给出管理仓库命令之间的关系,随后详细介绍他们。

在这里插入图片描述

  • git remote [-v]

    此命令用于查看你所配置的远程服务器名。如果使用参数 -v,则不仅可看到远程服务器名,也可看到远程服务器的具体 URL。

在这里插入图片描述

git remote 命令除查看配置的远程服务器信息外,也可执行与远程服务器配置相关的若干功能。

  1. git remote add :添加远程服务器。
  2. git remote show :显示指定远程服务器的详细信息。
  3. git remote rm :删除指定远程服务器。
  4. git remote rename :指定远程服务器重命名。
  • git fetch

    此命令用于从远程服务器 serverName 中拉取本地仓库中所没有的数据。需要注意的是:该命令只会拉取数据至本地仓库,而不会将其合并至工作区

    git pull 命令不仅会拉取数据至本地仓库,同时将其合并至工作区。

  • git push

    此命令用于将本地仓库当前分支推送至远程服务器 serverNamebranch 分支。

从远程仓库克隆
  • git colne

    该命令会将远程仓库克隆到本地

    $ $ git clone git@github.com:wyz609/gitkill.git
    Cloning into 'gitkill'...
    remote: Enumerating objects: 3, done.
    remote: Counting objects: 100% (3/3), done.
    remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
    Receiving objects: 100% (3/3), done.
    

    进入gitkill目录瞅瞅,可以看见只有一个单调的README.md文件

    $ cd gitkill/
    
    $ ls
    README.md
    
    

    如果有多个人协作开发,那么每个人各自从远程克隆一份就可以了。

    你也许还注意到,GitHub给出的地址不止一个,还可以用https://github.com/wyz609/gitskill.git这样的地址。实际上,Git支持多种协议,默认的git://使用ssh,但也可以使用https等其他协议。

    使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值