文章详情 学习记录

Git 学习笔记

发布时间:2026-05-14 11:24 浏览次数:53 最后更新:2026-05-14 13:30

git相关操作

正文内容

简介

图片描述

工作流程

Git是分布式版本控制系统(Distributed Version Control System,简称 DVCS),分为两种类型的仓库:
本地仓库和远程仓库
工作流程如下
    1.从远程仓库中克隆或拉取代码到本地仓库(clone/pull)
    2.从本地进行代码修改
    3.在提交前先将代码提交到暂存区
    4.提交到本地仓库。本地仓库中保存修改的各个历史版本
    5.修改完成后,需要和团队成员共享代码时,将代码push到远程仓库

图片描述

命令如下:

  1. clone(克隆):从远程仓库中克隆代码到本地仓库
  2. chechout(检出):从本地仓库中检出一个仓库分支然后进行修订
  3. add(添加):在提交前先将代码提交到暂存区
  4. commit(提交):提交本地仓库。本地仓库中保存修改的各个历史版本
  5. fetch(抓取):从远程库中抓取到本地仓库,不进行任何的合并动作,一般此操作比较少
  6. pull(拉取):从远程库拉到本地库,自动进行合并(merge),然后放到工作区,相当于ftech+merge
  7. push(推送):修改完成后,需要和团队成员共享代码时,将代码推送到远程仓库

备注:

  • Git GUI:提供图形界面
  • Git Bash:提供命令行工具

基本配置

安装

下载地址:https://git-scm.com/download

环境配置

当安装Git后首先要做的事情是设置用户名称和email地址。这是非常重要的,因为每次Git提交都会使用该用户信息

#设置用户信息 
   git config --global user.name “itcast”
   git config --global user.email “itcast@itcast.cn”
#查看配置信息
   git config --list
   git config user.name
#通过上面的命令设置的信息会保存在~/.gitconfig文件中

为常用指令配置别名

  1. 在用户目录下,创建.bashrc文件
touch ~/.bashrc
  1. .bashrc文件中输入如下内容
#用于输出git提交日志
alias git-log='git log --pretty=oneline --all --graph --abbrev-commit'
  1. 打开gitBash执行如下代码
source ~/.bashrc

基本操作

初始化本地仓库

要使用Git对我们代码进行版本控制,首先需要获得本地仓库

  1. 在电脑任意位置创建一个空目录,作为本地仓库
  2. 进入这个目录中,右键点击卡开Git bash窗口
  3. 执行命令git init
  4. 如果创建成功则可以在文件夹下看到隐藏的.git目录
# 初始化仓库带工作区
git init
# 初始化仓库不带工作区
git init --bare  

图片描述

基本操作指令中文件的状态变化

图片描述

  1. git add (工作区 -> 暂存区)
  2. git commit (暂存区 -> 本地仓库)

查看状态 status

# 查看状态
git status 
#查看状态 使输出信息更加简洁
git status –s 

查看提交记录 log

# 查看提交记录
git log
# 也可使用之前配置的别名来进行格式化的提交记录查询
git-log

log命令参数:

  • --all 显示所有分支
  • --pretty=oneline 将提交信息显示为一行
  • --abbrev-commit 使得输出的commitID更简短
  • --graoh 以图的形式显示
  • --decorate(此参数为MAC版本过低时可以加上以达到高版本效果)

查看操作记录 reflog

#此命令会查询整个操作记录,例如版本回滚操作、更新操作、删除操作并 附带版本号
git reflog

添加到暂存区 add

# 将未跟踪的文件加入暂存区
git add  <文件名>  
# 将暂存区的文件取消暂存 (取消 add )
git reset  <文件名>  
# 使用通配符“.”将所有文件添加到暂存区
git add .

版本回退 reset

#commitID可以用git log或git-log查看
git reset --hard commitID

提交工作区 commit

# git commit 将暂存区的文件修改提交到本地仓库
git commit -m "日志信息" <文件名> 

删除文件 rm

# 从本地工作区 删除文件
git rm <文件名>  
# 如果本工作区库误删, 想要回退
git checkout head <文件名>  

隐藏更改 stash

隐藏更改:

#隐藏当前工作区的更改
git stash

#代码可在存储的时候增加一个备注
git stash save "备注"  

还原隐藏

git stash pop stash@{0}

#说明:
命令恢复之前缓存的工作目录,将缓存堆栈中的对应stash删除,并将对应修改应用到当前的工作目录下
默认为第一个stash,即stash@{0},如果要应用并删除其他stash,命令:git stash pop stash@{$num} ,比如应用并删除第二个:git stash pop stash@{1}

其他命令:

  1. git stash save "save message" :执行存储时,添加备注,方便查找,只有git stash 也要可以的,但查找时不方便识别。

  2. git stash list :查看stash了哪些存储

  3. git stash show :显示做了哪些改动,默认show第一个存储,如果要显示其他存贮,后面加stash@{$num},比如第二个 git stash show stash@{1}

  4. git stash show -p :显示第一个存储的改动,如果想显示其他存存储,命令:git stash show stash@{$num} -p ,比如第二个:git stash show stash@{1} -p

  5. git stash apply :应用某个存储,但不会把存储从存储列表中删除,默认使用第一个存储,即stash@{0},如果要使用其他个,git stash apply stash@{$num} , 比如第二个:git stash apply stash@{1}

  6. git stash pop :命令恢复之前缓存的工作目录,将缓存堆栈中的对应stash删除,并将对应修改应用到当前的工作目录下,默认为第一个stash,即stash@{0},如果要应用并删除其他stash,命令:git stash pop stash@{$num} ,比如应用并删除第二个:git stash pop stash@{1}

  7. git stash drop stash@{$num} :丢弃stash@{$num}存储,从列表中删除这个存储

  8. git stash clear :删除所有缓存的stash

添加文件到忽略列表

一般我们总是有一些文件不需要交给git管理,也不希望他们出现在未跟踪文件列表。在这种情况下,我们可以在工作目录中创建一个名为.gitignore的文件(文件名称必须为这个),列出要忽略的文件模式。

git忽略列表规则:

只要写了路径,即/左右两边都有字符,那么就是指的“绝对路径”(相对仓库的,仓库.git文件夹所在目录为根目录),但可以用*来指定层级,指定第几层子目录下的某个文件夹。

空格不匹配任意文件,可作为分隔符,可用反斜杠转义

#开头的模式标识注释,可以使用反斜杠进行转义

!开头的模式标识否定,该文件将会再次被包含,如果排除了该文件的父级目录,则使用!也不会再次被包含。可以使用反斜杠进行转义

**匹配多级目录,可在开始,中间,结束

?通用匹配单个字符

[]通用匹配单个字符列表

例如:

#表示以.a为后缀名的文件都不需要管理
*.a
#强制跟踪lib.a文件,即使你在上面使用*.a忽略了所有.a后缀名的文件
!lib.a
#只忽略当前目录下的TODO文件,而不是忽略子目录/TODO
/TODO
#忽略build/目录中的所有文件
build/
#忽略doc/notes.txt,但不忽略doc/server/arch.txt
doc/*.txt
#忽略doc/目录以及子目录下的所有.pdf文件
doc/**/*.pdf

关于忽略规则不生效的问题:

.gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。解决方法就是先把本地缓存删除(改变成未track状态),然后再提提交。

git rm -r --cached .
git add .
git commit -m 'update .gitignore'

定义全局的忽略文件列表:

除了可以在项目中定义 .gitignore 文件外,还可以设置全局的 git .gitignore 文件来管理所有Git项目的行为。这种方式在不同的项目开发者之间是不共享的,是属于项目之上Git应用级别的行为。这种方式也需要创建相应的.gitignore文件,可以放在C:/Users/用户名/目录下。然后使用以下命令配置Git。

git config --global core.excludesfile ~/.gitignore

进阶操作

修改Commit信息

修改最近的一次提交比较简单

#此命令会进入vim,编辑完成后:wq保存退出即可
git commit --amend

修改历史commit message

 #此命令会使其修改你所输入的commitID之后的所有提交信息
git rebase -i commitID

进入vim之后有如下的几种常用操作

  • pick:保留该 commit
  • reword:保留该 commit,但我需要修改该commit的 Message
  • edit:保留该 commit, 但我要停下来修改该提交(包括修改文件) squash:将该 commit 和前一个 commit 合并
  • fixup:将该 commit 和前一个 commit 合并,但我不要保留该提交的注释信息
  • exec:执行 shell 命令
  • drop:丢弃这个 commit

只需要将你所需要修改的commitID前的状态改为指定状态后,:wq保存,即可进入对应的状态界面。

此处为进入提交2修改commit meassage界面,修改完提交信息后保存即可。

checkout到某个指定版本

  • git checkout <commitID>:把整个git仓库文件回退到 commit 参数指定的版本
  • git checkout <commitID> [--] <filepath>:回退 filepath 文件为 commit 参数指定的版本

对于git checkout <commitID>命令:

#git checkout <commitID> 命令把整个git仓库回退到 commitID 参数指定的版本,该参数值可以是具体的commit hash值,也可以通过HEAD index来指定。
#例如,HEAD^ 对应最新版本的上一个版本,那么 git checkout HEAD^ 命令回退git仓库下的文件内容到上一个版本,同时从当前分支脱离,处在一个未命名分支下面
#此时用 git log 命令查看log信息,最新的log已经变成前面 HEAD^ 指定的commitID信息。
#由于脱离了原先的分支,修改本地文件,并执行 git commit 进行提交,不会影响原先分支。
#即,如果想在从某个版本另起一个分支,则使用这个命令。
#在这个未命名分支上执行git checkout -b new_branch_name即可将这个指定版本切换到新分支上。
$ git checkout HEAD^
Note: checking out 'HEAD^'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 8ba05ec...
$ git branch
* (detached from 8ba05ec)
  master

对于git checkout <commitID> [--] <filepath>命令:

#git checkout <commitID> [--] <filepath> 命令只回退 filepath指定的单个文件到 commitID 参数指定的版本,不影响其他文件

# [--] 表示 – 是可选参数,用于指定后面跟着的参数只是文件路径,而不是branch分支名或者commit信息。(如果当前有一个branch分支名是 hello.c,且当前目录下有一个 hello.c 文件,那么不加 – 参数时,git checkout hello.c 表示切换到 hello.c 分支,而不是覆盖 hello.c 文件的改动。这种场景下,必须用 git checkout – hello.c 指定覆盖 hello.c 文件的改动,-- 参数可以消除歧义)

git checkout <commitID> [--] <filepath> 命令的行为跟 git checkout <commitID> 命令有所差异,具体说明如下:

  1. git checkout <commitID> 回退整个git仓库的文件。而git checkout <commitID> [--] <filepath>命令只回退指定的单个文件

  2. git checkout <commitID> 会从原先分支脱离,并影响git log显示的commit信息。而git checkout <commitID> [--] <filepath>命令会停留在原先分支下,不影响git log显示的commit信息

  3. git checkout <commitID> 切换之后,用git status查看,会提示"nothing to commit, working directory clean";而git checkout <commitID> [--] <filepath>命令切换后,用git status查看,提示"Changes to be committed",指示回退的文件被添加到了git的staged区域,当执行git commit时,会多出一条新的commit信息

reset到某个指定版本

  • git reset <commitID>:把git的HEAD指针指向到 commit 对应的版本,本地文件内容不会被回退
  • git reset --hard <commitID>:把git的HEAD指针指向到 commit 对应的版本,本地文件内容也会被回退

对于git reset <commitID>命令:

#git reset <commitID> 命令把git的HEAD指针指向到commitID对应的版本,本地文件内容不会被回退,会停留在原先分支下。
#此时,用 git log 命令查看log信息,最新的log已经变成commitID版本对应的信息。

#用 git status 命令查看,一般会提示有些文件被改动,即本地文件内容和git的staged区域内容不一致,类似于本地文件在当前git仓库的版本上进行了一些修改

$ git reset HEAD^
Unstaged changes after reset:
M       hello.c
$ git status
On branch new_branch_name
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   hello.c

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

#在执行这个 git reset 命令之后,如果想让本地文件也回退到指定的版本,可以再使用 git checkout [--] <filepath> 命令来覆盖本地文件内容。

#执行 git reset 命令后不会从当前分支脱离,如果想在当前分支上将本地代码回退,就可以使用这种方法

对于git reset --hard <commitID>命令:

#git reset --hard <commitID> 命令把git的HEAD指针指向到 commitID 对应的版本,本地文件内容也会被回退,不需要再执行 git checkout 命令来回退本地文件内容。

#由于 git reset 会回退 git log 显示的commit信息,使用 git log 命令看不到原先最新的commit hash值,无法使用该commit hash值来恢复成原先最新的版本

#此时若想恢复原本最新的commit,可以使用 git log -g 命令来看到所有操作过程的commit信息,就能看到原先最新的commit hash值,然后再次恢复

分支

基本命令

注意:工作区只能同时为一个分支服务,HEAD所指向的为当前所在分支

# 默认分支名称为 master

# 列出所有本地分支
git branch
# 列出所有远程分支
git branch -r
# 列出所有本地分支和远程分支
git branch -a
# 查看本地分支和远程分支的关联关系
git branch -vv
# 创建分支
git branch <分支名>
# 切换分支 
git checkout <分支名>
# 切换到一个不存在的分支(创建加切换)
git checkout -b <分支名>
#切换到远程的develop分支,在本地起名为develop分支,并切换到本地的develop分支,origin为远程仓库名
git checkout -b develop origin/develop
# 删除分支(如果分支已经修改过,则不允许删除)
git branch -d <分支名>
# 强制删除分支
git branch -D <分支名>
#更改分支名
git branch -m 旧分支名 新分支名
# 合并分支 将其他分支合并至当前工作区
git merge <分支名称>
# 合并分支,需要合并的分支是远程分支,则需要如下形式
git merge <远程仓库名/远程分支名称>
#中止合并
git merge --abort
#撤销合并
git reset --merge
#新建远程分支
git push origin <本地分支名:远程分支名>
# 删除远程仓库分支
git push <主机名> -d <分支名>
或者
git push <主机名> --delete <分支名>
或者
git push <主机名> :<分支名>
  1. 查看分支

  1. 创建分支

  1. 切换分支

  1. 合并分支



解决分支冲突

当两个不同的分支对同一个文件做了修改后合并时,会提示合并失败,出现冲突



此时合并后会提示出现冲突

并且文件会变为如下形式:

此时只需要将文件改为最终想要的样子(不需要的可以删去),然后在主分支中add和commit即可

过程中会提示合并已经解决的说明,保存并退出即可

使用git-log查看分支树

分支使用流程及规范

几乎所有的版本控制系统都以某种形式来支持分支。开发中分支有如下的使用原则与流程:

  • master(生产)分支

​ 线上分支,主分支,中小规模项目作为线上运行的应用对应的分支

  • develop(开发)分支

​ 是从master创建的分支,一般作为开发部门的主要开发分支,如果没有其他并行开发不同期上线要求,都可以在此版本进行开发,开发阶段完成后,需要合并到master分支,准备上线

  • feature/xxxx分支

​ 从develop创建的分支,一般是同期并行开发,但不同期上线时创建的分支,分支上的研发任务完成后合并到develop分支

  • fotfix/xxxx分支

​ 从master派生的分支,一般作为线上bug修复使用,修复完成后需要合并到master、test、develop分支

  • 还有一些其他分支,例如test分支(用于代码测试)、pre分支(预上线分支)等等

图片描述

删除分支存在的问题

# 删除分支(如果分支已经修改过,则不允许删除)
git branch -d <分支名>
# 强制删除分支
git branch -D <分支名>

git远程仓库

简介

除了自己搭建服务器,以及本地仓库外,其实我们可以使用一些免费的远程仓库,远程仓库有很多,常见的免费互联网远程仓库托管服务如下:

www.github.com
www.gitee.com
www.gitlab.com

github	是一个基于git实现在线代码托管的仓库,向互联网开放,企业版要收钱。
gitee	即码云,是oschina 免费给企业用的,不用自己搭建环境。
gitlab	类似github,一般用于在企业内搭建git私服,要自己搭环境。

GitHub(gitee)、GitLab 不同点:
1、GitHub如果使用私有仓库是需要付费的,(2019年开始私有仓库也是免费的但是只能3个人协同开发,想要更多需要收费),GitLab可以在上面搭建私人的免费仓库。
2、GitLab让开发团队对他们的代码仓库拥有更多的控制,相对于GitHub,它有不少的特色:
    (1)允许免费设置仓库权限
    (2)允许用户选择分享一个project的部分代码
    (3)允许用户设置project的获取权限,进一步提升安全性
    (4)可以设置获取到团队整体的改进进度
    (5)通过innersourcing让不在权限范围内的人访问不到该资源

注册码云

鉴于国内用户可能网络不好,这里我们使用gitee(码云) 来进行演示。

网址为:https://gitee.com/signup

图片描述

创建远程仓库

图片描述

配置SSH公钥

  • 生成SSH公钥

    • ssh-keygen -t rsa
    • 不断回车(注:如果公钥已经存在,则会自动覆盖)
  • Gitee设置账户公钥

    • 获取公钥:cat ~/.ssh/id_rsa.pub

    • 将查询到的公钥复制

    • 其中标题可以随意填写,然后将查询到的公钥粘贴到指定位置即可

    • 输入密码即可配置成功

图片描述

图片描述

  • 验证是否配置成功:ssh -T git@gitee.com,此处提示为第一次访问确认,输入yes回车即可

  • 此处显示为授权成功


本地仓库推送至远程仓库


  1. 告诉本地仓库远程仓库的地址:git remote add 远程仓库名称(自定义,便于识别) 远程仓库的地址


  1. 查看是否添加了远程仓库:git remote,出现远程仓库名称则添加成功

  1. 将本地代码同步到远程仓库:git push [-f] [--set-upstream] [远端名称] [本地分支名称][:远端分支名称]

    • 如果远程分支名和本地分支名相同,则可以只写本地分支,如此处:git push origin master
    • --set-upstream表示推送到远端的同时建立起和远端分支的关联关系,如:git push --set-upstream origin master
    • 如果当前分支已经和远端分支关联,则可以省略分支名和远端名,如:git push是将master分支推送到已关联的远端分支
    • -f表示当远端和本地仓库同同一文件出现冲突时,以本地仓库为准强制覆盖到远程仓库(一般不使用)

注意:

  • 本地仓库必须有分支存在,否则会出现提交错误警告

  • 本地仓库当前更新状态必须和远端完全一致,否则会提示先进行更新本地仓库


  1. 此时查看仓库则会发现远程仓库中已经同步的本地仓库的内容



查看远程仓库和本地仓库的对应关系

  • 使用git branch -vv来查看仓库对应关系

此处表示本地的master对应于远程仓库origin的master分支

远程仓库克隆clone到本地仓库

如果已经有一个远端仓库,我们可以直接clone到本地

命令为:git clone <仓库路径> [本地目录]

其中本地目录可以省略,会自动在git bash当前所在位置生成一个目录。

clone通常只会使用一次,将代码克隆到本地,之后都用抓取和拉取。

从远程仓库抓取fetch和拉取pull

抓取命令为:git fetch [远程仓库名] [分支名]

  • 抓取指令就是将仓库的修改都抓取到本地,不会进行合并
  • 如果不指定远端名称和分支名,则抓取所有分支。
  • 需要额外使用merge命令来将远端仓库合并到本地

拉取命令为:git pull [远程仓库名] [<远程分支名>:<本地分支名>]

  • 拉取指令就是将远端仓库的更新拉到本地并自动进行合并,等同于fetch+merge
  • 如果不指定远端名和分支名,则抓取所有分支并更新当前分支

解决远程合并冲突

远程分支也是分支,解决方法和本地冲突解决方法相同

图片描述

强制覆盖本地文件

重要提示:如果有任何本地更改,将会丢失。无论是否有--hard选项,任何未被推送的本地提交都将丢失。

git fetch --all

#然后你有两个选择

#将覆盖主分支内容
git reset --hard origin/master

#覆盖其他分支内容
git reset --hard origin/<branch_name>

说明:

git fetch从远程下载最新的,而不尝试合并或rebase任何东西。

然后git reset将主分支重置为您刚刚获取的内容。

--hard选项更改工作树中的所有文件以匹配origin/master中的文件

在重置之前可以通过从master创建一个分支来维护当前的本地提交:

git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard origin/master

最佳解决方案:

# Fetch the newest code
git fetch

# Delete all files which are being added, so there
# are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    rm -f -- "$file"
done

# Checkout all files which were locally modified
for file in `git diff --name-status | awk '/^[CDMRTUX]/ {print $2}'`
do
    git checkout -- "$file"
done

# Finally pull all the changes
# (you could merge as well e.g. 'merge origin/master')
git pull


说明:
第一个命令获取最新的数据。

第二个命令检查是否有任何正在添加到存储库的文件,并从本地存储库中删除那些会导致冲突的未跟踪文件。

第三个命令checks-out所有在本地修改的文件。

最后,我们将更新到最新版本,但是这次没有任何冲突,因为repo中的未跟踪文件不再存在,所有本地修改的文件已经与存储库中的相同

强制覆盖云端文件

git push -f origin master

问题解决

远程仓库问题

#问题复现:
在A电脑上创建了新远程仓库并将A电脑中的文件夹同步至远程仓库,
然后在B电脑上fetch这个远程仓库,再合并到本地已有的仓库中出现此错误。
#报错:
git merge origin/master
fatal: refusing to merge unrelated histories
#解决:
如果git merge合并的时候出现refusing to merge unrelated histories的错误,原因是两个仓库不同而导致的,需要在后面加上--allow-unrelated-histories进行允许合并,即可解决问题。

如果还不能解决问题,就把本地的remote删除,重新git remote add添加远程仓库,再按上面的方法来,问题解决。
#问题复现:
本地仓库在想做同步远程仓库到本地,为之后本地仓库推送到远程仓库做准备时报错了
远程push 的时候出现refusing to merge unrelated histories 
#报错:
fatal: refusing to merge unrelated histories(拒绝合并不相关的历史)
#解决:
出现这个问题的最主要原因在于本地仓库和远程仓库实际上是独立的两个仓库。
假如我之前是直接clone的方式在本地建立起远程github仓库的克隆本地仓库就不会有这问题了。
可以在pull命令后紧接着使用--allow-unrelated-history选项来解决问题(该选项可以合并两个独立启动仓库的历史)。

正文内容已启用复制保护,代码块与行内代码仍支持复制。

评论区

欢迎参与讨论,评论提交与展示状态会在下方同步更新。

发表评论

提交后将进入人工审核,审核通过后才会展示。

邮箱仅用于必要的联系与基础风控,不会在页面中公开展示。

请文明发言,避免发布广告、链接或敏感内容;短时间内频繁提交会被限制。

隐私提示:提交评论即表示你同意站点为评论展示、审核、防刷与安全风控目的处理你填写的昵称、邮箱和评论内容。

其中邮箱不会公开展示,也不会用于与评论无关的公开用途。

读者留言

还没有评论,来发表第一条评论吧。

共 0 条评论 已展示 0 / 0 条评论
当前还没有评论,来发表第一条评论吧。若评论需要审核,通过后会展示在这里。