Git学习&踩坑记录
官方用户手册https://git-scm.com/docs/user-manual
准备知识
工作区和暂存区

git版本库包含暂存区(stage或index),add从工作区到index,commit从index到分支master
准备工作
查看帮助
1 | $ man git-log |
1 | $ git help log |
进行任何操作前
1 | $ git config --global user.name "Your Name Comes Here" |
查看远程库的url
1 | $ git config --get remote.origin.url #不一定是origin:远程库简写具体情况分析 |
本地库和远程库
创建版本库(本地库)
选择一个合适的地方创建一个空目录myprogram

在git-bash界面打开该目录并使用初始化为可管理仓库
1
2
3
4
5shade@LAPTOP-UUSGVNLB MINGW64 d/shade/WYrepo/myprogram/myprogram
$ git init
Initialized empty Git repository in ...
shade@LAPTOP-UUSGVNLB MINGW64 d/shade/WYrepo/myprogram/myprogram(main)此时仓库建好了,
myprogram目录下有.git目录
添加远程库
在本地已经创建一个Git仓库,希望在GitHub或Gitee创建一个远程库使两个仓库远程同步
在GitHub上新建一个仓库learngit(仓库 名建议与本地库名同,其它选项默认)
在本地的learngit仓库下运行命令,使本地库与远程库关联
1
$ git remote add origin git@github.com:Luluy233/learngit.git
添加后,远程库的名字就是origin(默认),也可改为其它名字
把本地库的所有内容推送到远程库上:
1
2
3$ git push -u origin main #第一次
$ git push origin main
$ git push <远程库简称> <远程库分支名>注意:push的是已经commit的内容(若当前没有任何commit会报错)
可以再GitHub网站上看到对应内容

远程库克隆
远程库:GitHub或Gitee上的仓库
本地库:本地的git仓库
从零开发,选择现在GitHub或Gitee上创建远程库,然后从远程库克隆到本地
- 登录GitHub,创建新的仓库(选择
initialize with a README) - 用命令
git clone克隆一个本地库(在本地库希望的文件夹下克隆)
如希望在WYrepo下建立仓库gitskills,则不用自行新建gitskills文件夹
1 | #d/shade/Wyrepo |
删除远程库
此处删除的实际是本地库与远程库的关联,因此删除前可先查看与本地库关联的远程库信息;若要真正删除远程库则需登录对应Gitee或GitHub后台直接删除
查看远程库信息
1 | $ git remote -v |
然后根据名字删除(origin/orgin)
删除远程库关联
1 | $ git remote rm origin |
删除版本库(本地.git文件夹)
1 | $ find .-name ".git" | xargs rm -Rf |
则对应文件夹中.git文件夹被删除
基本使用
git init
在本地库project文件夹下初始化git仓库
1 | $ git init |
文件夹下出现.git文件夹
git add
将修改过的指定文件添加到暂存区index
1 | $ git add file1 file2 |
将所有更改过的内容快照暂存到index中
1 | $ git add . |
git commit
永久保存内容的index作为项目的一个版本
1 | $ git commit -m "版本信息" |
将所有修改内容add到index,再commit到分支
1 | $ git commit -a #等价于git add . 加上 git commit |
(commit规范)
https://zhuanlan.zhihu.com/p/90281637
https://zhuanlan.zhihu.com/p/182553920
https://www.conventionalcommits.org/zh-hans/v1.0.0-beta.4/
git diff
查看在工作区做出修改但未git add到暂存区index的内容
1 | $ git diff |
查看即将commit的内容(已经add但未commit)
1 | $ git diff --cached |
git status
查看当前修改过的内容
1 | $ git status |
git log
查看commit的信息
1 | $ git log |
查看每个commit的具体代码修改(每一行)
1 | $ git log -p |
查看每个commit的修改小节(对哪些文件修改、增添的行数)
1 | $ git log --stat --summary |
分支管理
git branch
新建名为
dev的分支1
$ git branch dev
查看现存本地工作区的分支列表
1
2
3$ git branch
dev
*master #自动创建追中远程分支
1
$ git branch -u origin/main #在当前分支main下执行
让本地的main分支追踪远程名为
origin仓库的main分支
其中origin需使用如下命令
1 | $ git remote add origin <远程仓库URL> #将本地仓库与远程仓库建立连接 |
删除分支dev
必须在其它分支(非dev)下执行删除分支命令
1
2$ git branch -d dev #某些情况下无法删除
$ git branch -D dev #强制删除分支
git switch
切换到指定分支dev
1 | $ git switch dev |
git checkout
可以通过更新工作树的文件使其与索引或指定的树版本相匹配
git checkout <分支名>/<提交哈希值>/<树对象>/<路径参数>
基本用法
1
$ git checkout <branch>
若本地库不存在
<branch>但远程库·<remote>存在同名的<branch>,则会在本地库新建分支<branch>并自动追踪远程分支<remote>/<branch>若本地和远程库都不存在分支
<branch>,则报错,如下:1
2$ git checkout bbb
error: pathspec 'bbb' did not match any file(s) known to git省略分支名
1
$ git checkout
会自动检测当前分支的信息(追踪的远程库等),如果没有追踪的远程库则返回空
如:
1
2
3#当前本地的dev-BuyerCenter
Your branch is ahead of 'origin/dev-BuyerCenter' by 3 commits.
(use "git push" to publish your local commits)参数
-b/-B1
$ git checkout -b|-B <new-branch> [<start-point>]
若远程库和本地库都不存在,则
-b会新建分支<branch>
git merge
若master分支和dev分支修改了不同的内容,在master分支下运行如下命令,可将dev分支合并到master,如果没有冲突,则合并成功
没有冲突:没有对同一个文件修改
1 | $ git merge dev #当前为master分支 |
发生冲突,会提示需要解决冲突再合并,进入如下界面(main|MERGING):
1 | shade@LAPTOP-UUSGVNLB MINGW64 /d/mycreate/gitlearn (main) |
可以使用
git diff命令显示分支差异1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17shade@LAPTOP-UUSGVNLB MINGW64 /d/mycreate/gitlearn (main|MERGING)
$ git diff
diff --cc file1.txt
index b0e228e,0112b68..0000000
--- a/file1.txt
+++ b/file1.txt
@@@ -1,3 -1,2 +1,7 @@@
this is file1
-hello,dev,is conflict
++<<<<<<< HEAD
+modified by branch-dev
- hello, this is master
++hello, this is master
++=======
++hello,dev,is conflict
++>>>>>>> dev打开冲突文件夹会显示
@@@ -1,3 -1,2 +1,7 @@@下的内容<<<<<<< HEAD和=======之间是当前分支main的修改,而=======和>>>>>>> dev之间是分支dev的修改,此时需要手动编辑这部分代码。手动编辑解决冲突后,可以使用
git add+git commit来讲结果合并到merge的结果使用
gitk图形化显示合并结果
git mv
若文件夹发生重命名,则使用如下命令进行移动
1 | $ git mv <old-location> <new-location> |
gitk
图形化显示各个分支merge的结果:
1 | $ gitk |
结果如下:

团队合作
git clone
从远程库克隆到本地
1 | $ git clone <远程库的ssh或http> <可选:本地库名称/否则与远程库同名> |
git pull
pull = fetch + merge
从远程分支fetch,并merge到本地分支;
1 | $ git pull <远程库> master #从<远程库>的master分支pull到当前分支 |
如果发生冲突,则git仍旧执行fetch但不执行merge,此时本地需要先消除更改,再重新pull
(背景:Alice要pull来自Bob的更改)
如果Bob的工作与Alice的工作发生冲突,那么Alice将使用她的工作树和索引来解决冲突,并且现有的本地更改将干扰冲突解决过程(Git仍然会执行fetch,但会拒绝merge)。
一种常见方法(poe):
git stash:将当前本地更改保存到一个临时的存储区域,使工作树和索引树干净,再执行git pull获取远程分支最新更改,并解决冲突,完成冲突解决后,可以使用git stash pop将之前保存的本地更改重新应用到工作树另一种方法
将本地更改提交到当前分支,并在冲突解决后再次进行提交。这种方法要求Alice首先使用
git add和git commit命令将本地更改提交到当前分支。然后,执行git pull来获取远程分支的最新更改并进行冲突解决。完成冲突解决后,Alice可以再次使用git add和git commit命令来提交合并后的更改。pull策略查看当前git的pull策略:
1
git config --get pull.rebase
返回值可能为:
true:表示pull使用的是 rebase 策略。false:表示pull使用的是 merge 策略(默认值)。未设置或不存在该配置项:表示使用 Git 的默认行为,即根据 Git 版本和配置文件中的设置决定使用的策略。
配置为
rebase策略1
git config --global pull.rebase true
当你在 Git 中执行
git pull命令时,它会从远程仓库拉取最新的提交,并尝试将这些提交合并到你的本地分支。默认情况下,Git 使用合并(merge)策略来将远程提交与本地提交合并在一起。然而,通过设置
pull.rebase为true,你告诉 Git 在执行git pull时使用 rebase(变基)策略而不是合并策略。Rebase 策略将会执行以下操作:
- 从远程仓库拉取最新的提交。
- 将当前分支上的本地提交按顺序逐个应用在这些最新提交之上。
- 如果在应用本地提交的过程中发生冲突,Git 会让你解决冲突,并在解决完冲突后继续应用剩余的本地提交。
- 完成后,你的本地分支将指向一个新的提交,其中包含了最新的远程提交和你的本地提交。
git fetch
通过fetch命令,Alice可以在不合并的情况下看到Bob做了什么;
(安全:即使Alice本地修改未commit)
这允许Alice检查Bob做了什么,使用一个特殊的符号FETCH_HEAD,以确定他是否有值得提取的东西,如下:
1 | alice$ git fetch /home/bob/myrepo master |
下面的命令显示在Bob的分支中但不在Alice的分支中的内容
1 | alice$ git log -p HEAD..FETCH_HEAD |
还可以使用如下命令查看Bob在分叉后做了什么(两个点)
1 | $ gitk HEAD..FETCH_HEAD #远程库的内容 |
使用如下命令查看两人在分支后都做了什么(三个点)
1 | $ gitk HEAD...FETCH_HEAD |
在一个小而紧密的团队中工作时,经常与同一个仓库进行交互是很常见的。通过定义远程仓库的简写,可以使这一过程更加简便:
1 alice$ git remote add bob /home/bob/myrepo
通过这样的设置,Alice可以使用
git fetch命令单独执行拉取操作的第一部分,而不将其与自己的分支合并,使用以下命令:
1 alice$ git fetch bob
这样,Alice 就可以从 Bob 的仓库中获取最新的更改,但不会自动合并到她自己的分支中。通过这种方式,Alice 可以获取 Bob 的更新,然后根据需要进一步处理。
Alice使用如下命令显示Bob所做的一切修改(与Alice的master区别)
1 alice$ git log -p master..bob/master接着Alice可以将这些修改合并到自己的分支
1 alice$ git merge bob/master
上述的merge操作等同于如下:
1 >alice$ git pull . remotes/bob/master #合并到当前分支接着Bob可以更新他的分支(与alice修改一致)
1 >bob$ git pull
git remote
用于管理远程库的相关操作(poe)
查看
显示当前仓库中配置的所有远程库简写名称
1
$ git remote
显示当前仓库中配置的所有远程库的简写名称及其对应的远程仓库URL
1
$ git remote -v
添加
添加一个新的远程仓库,指定简写名称和对应的仓库URL
1
$ git remote add <name> <url>
如
$ git remote add bob /home/bob/myrepo重命名
重命名一个已存在的远程库简写
1
$ git remote rename <old-name> <new-name>
删除
删除已存在远程仓库简写
1
2$ git remote remove <name>
$ git remote rm <name>
提交历史
git log其它用法
1 | $ git log v2.5..v2.6 # commits between v2.5 and v2.6 |
1 | $ git log master..stable #在分支stable提交但是不在分支master提交 |
git show
查看具体某个版本修改的内容(具体修改)
版本号不一定要完整的,只要可识别(可前几位)
1 | $ git show <对应版本号/哈希值> |
可以查看当前分支的父母级别
1 | $ git show HEAD^ |
1 | $ git show HEAD^1 #等同HEAD^ |
git tag
给分支版本号标签名
1 | $ git tag <标签名> <版本号> |
git reset
版本回溯,回溯到指定版本号
1 | $ git reset --hard <版本号/HEAD相关> |
1 | $ git reset --hard HEAD^ |
git revert
撤销提交:创建新的提交来撤销之前的提交
1 | $ git revert <版本号> |
git grep
在指定版本中搜索代码中的关键词,若不指定版本号则默认在当前版本下搜索
1 | $ git grep "关键词" <版本号/标签名> |
对象数据库object database
对象数据库类型
https://eagain.net/articles/git-for-computer-scientists/
git对象存储一个对象的DAG,由SHA-1哈希标识;
数据类型包括blob、tree、commit、tag
blob:
文件内容,最简单(一堆字节)
tree:
目录结构,(引用blob、其它tree子目录)
在DAG中指向其它结点的任一结点,都要依赖于另一个结点;否则可以用命令**git gc** 收集垃圾;如果文件系统中有很多个结点都没有指向他们的(parent),则可以用 git fsck --lost-found 命令来回收
commit:
提交对象。commit引用tree,被其它n多个commit引用(它的parent)
若commit没有parent,则是init commit;
若commit有多个直接parent,则是merge的结果;
git commit会添加1个commit结点到DAG中,并将对应refs便利贴移动到该结点
refs(黄色):heads或branches,向DAG结点上的便利贴
remote refs(蓝色):远程分支
tag:
标签对象:既是DAG结点也是post-it note(便利贴),指向一个commit
cat-file
获取git对象的类型:
1 | $ git cat-file -t <哈希值> |
显示与哈希值对应的提交对象具体信息
1 | $ git cat-file commit <哈希值> |
显示blob对应的信息
1 | $ git cat-file blob 3b18e512 |
ls-tree
查看git的文件和目录结构以及与各个版本之间的关系;
输出:文件模式(权限、类型)、类型、对象哈希、文件路径
文件模式100644、文件类型(blob 3b18e512)、路径名(file.txt)
1 | $ git ls-tree <哈希值> |
find .git/…
查看SHA-1名称存储的git目录
1 | $ find .git/objects/ |
cat .git/…
显示当前所在分支:main
1 | $ cat .git/HEAD |
显示
索引文件index
git add:存储一个新的blob,将对其的引用放入索引文件中。
git clone
从远程库remotes/MYSERVER/master克隆到本地

git fetch
从远程库拉取(fetch)新提交,但是还没合并(merge)
此时本地master指向a,远程master指向b

git merge
执行命令git merge remotes/MYSERVER/master
若本地没有领先远程的新提交,则本地便利贴master指向b,

若远程新提交c、若本地新提交d,git merge前结构如下

git merge后结构如下:
新建结点e合并结点c和d,本地master指向e

实践问题
2023.08.21
合并远程分支和本地分支
本地dev-BuyerCenter有新提交,远程dev也有新提交,要合并远程和本地
git fetchgit merge,显示如下,此时进入(BuyerCenter | MERGING)
- CONFLICT(content):对同一文件修改,则点开提示的文件
src/router/index.js查看本地和远程的区别并修改 - CONFLICT(file location):远程对目录进行重命名,此时不需要进行任何修改(默认用远程的)
- CONFLICT(content):对同一文件修改,则点开提示的文件
解决冲突后
git add+git commit提交合并即可
2023.8.24
在git push之前忘记先git fetch了会怎么样吗
操作:先git push,push完了发现忘记fetch了,再fetch,然后信息如下
1 | remote: Enumerating objects: 6, done. |
无大事发生
2023.12.26
本地已做了修改,又想从远程拉取代码,报错
1 | $ git pull |
先暂时丢弃本地操作,pull后再恢复
1 | #逐步执行下述命令 |
2025.4.20
在执行git push时报错为:
1 | remote: error: Trace: ef2fe96bd712c1155b8f7d643d9376c04ad805e4973277460183326d89650b07 |
考虑到原因是上传文件超出容量限制,并且是数据集文件,因此修改.gitigore忽略test/data/文件夹,保存.gitignore文件后,因为之前已将该文件夹添加到版本控制中,需要先将其从暂存区移除,使用如下命令
1 | git rm -r --cached test/data/ |
然后提交修改
1 | git commit -m "fix: 忽略test/data/文件夹" |
test/data/文件夹就会被git忽略,不再参与版本控制
- 标题: Git学习&踩坑记录
- 作者: LuluyLand
- 创建于 : 2025-04-14 19:23:45
- 更新于 : 2025-04-20 23:49:03
- 链接: https://luluy233.github.io/2025/04/14/GitLearn/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。






