这篇文章是基于之前的《Git 入门》文章写的,主要是因为我在尝试将一些资源文件上传到 GitHub 时遇到了不少问题。

我认为目前可以实现的建立连接的方式有 两种

在描述实现方法之前,我认为我们应该了解 远程操作命令

常用 Git 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
git init                    //初始化本地仓库,生成 .git 文件夹,这是 git 的核心

git add [target] //将目标文件添加到暂存区

git rm -f <filename> //该命令将文件从暂存区和工作目录中删除

git rm --cached <filename> //当你添加了不想要的文件时,该命令可以从暂存区删除文件,但保留在工作目录中

git commit //提交暂存区的文件,使用 -m [message] 添加必要信息(如果没有添加也可以自动弹出)

git status //查看 git 状态

git clone [url or ssh]
//非常重要的一点是直接克隆远程仓库,默认会自动连接到克隆的远程仓库,命名为 origin

git pull origin master
//将远程仓库 "origin" 中对应的分支拉取到本地仓库的 master,通常在 push 之前需要先拉取最新的仓库

git pull origin master --allow-unrelated-histories
//如果本地和远程是两个独立的仓库,拉取时需要指定 "allow unrelated histories merge",否则会失败

git push origin master
//将本地仓库的内容提交到远程仓库(origin 是远程分支名称,master 是当前分支名称。注意该命令并不完全完整,实际使用中,如果是第一次提交到远程,应该使用 [git push -u origin master],如果不是第一次,则直接使用 git push)

git remote add origin [url or ssh]
//添加一个远程仓库连接并命名为 "origin",当然也可以自定义其他名称,但一般命名为 origin

git remote rm origin //删除名为 "origin" 的远程仓库连接

git remote set-url origin [url or ssh]
//修改 "origin" 的 url(结合上面的命令,有两种修改远程仓库连接的方法:一种是删除再添加,另一种是直接修改)

URL 和 SSH 可以从仓库界面的代码按钮中查看和复制,SSH 更加安全。

原理

git add . 和 git add * 的区别

git add . 会添加所有文件、文件夹和子文件夹,包括 .gitignore 和任何其他以点开头的内容;

git add * 会添加任何文件、文件夹和子文件夹,但不包括以点开头的文件。

git add . 也会遵循 .gitignore,而 git add * 在任何非点文件被 gitignore 时会抛出错误。使用 git add . 比 git add * 要好得多

* 不是 git 的一部分,它是由 shell 解释的通配符。 * 扩展为当前目录中的所有文件,然后传递给 git,git 添加所有文件。 . 是当前目录本身,git add 会添加它及其下的所有文件。

add * 意味着添加当前目录中的所有文件,除了名称以点开头的文件。这是一个 shell 特性,Git 只接收文件列表。

add . 在 shell 中没有特殊含义,因此 git 会递归添加整个目录,几乎是一样的,但包括名称以点开头的文件。

删除远程仓库文件的方法

删除时需要注意的一点是,暂存区中的文件 在提交后不会被清除。同样,你删除的文件仍在暂存区,你需要 从暂存区移除已删除的文件,才能提交。

从当前工作目录和暂存区删除文件或目录。

git rm <file> git rm -r <path>

仅从暂存区删除文件或目录。

git rm --cached <file> git rm -r --cached <path>

直接删除方法

直接删除指定的文件或目录。适合需要删除的文件数量相对较少的情况。

git rm -r --cached demo git commit -m '删除 demo 文件夹' git push -u origin master

过滤删除方法

在项目根目录添加 .gitignore 文件以过滤掉不需要的文件,然后执行命令。该操作的原理是删除暂存区中的所有文件,然后通过 git add . 命令将 .gitignore 文件过滤的文件添加到暂存区。此方法适合批量删除文件。

git rm -r --cached . git add . git commit git push -u origin master

无论是直接删除还是过滤删除,目的是删除暂存区中已删除文件的记录。

PS:注意命令行提示中的各种信息

第一个实现方法 (git clone)

步骤1:在 GitHub 上创建一个名为 git_test 的仓库

步骤2:进入一个文件夹并使用 git clone

此时,git clone 完全克隆了整个仓库到本地。它会生成一个与仓库同名的文件夹。进入该文件夹,你可以直接看到 .git 文件。

步骤3:无需远程连接,自动建立连接(默认是 origin)

使用 git remote -v 查看远程连接信息

步骤4:创建测试文件并提交到远程仓库

测试完成!

第二个实现方法 (初始化本地仓库 + 手动添加连接)

步骤1:在 GitHub 上创建一个新仓库,同时初始化本地仓库

创建新仓库:

进入文件夹 ~/Desktop/git_freely 并使用 git init 初始化本地仓库

可以看到本地仓库尚未建立远程连接。

步骤2:建立远程连接

此时可以看到已经建立了远程连接,给远程仓库的名称其实可以随意(通常是 origin),我命名为 lixiang。

提问:此时我们可以直接根据第一个实现方法创建测试文件,然后 git add、commit、push 吗?

既然我提问了,那肯定是不可以的😄,如果你不相信我们来试试。

为什么?

这可能需要理解一些 git 的基本原理。我相信大家都听说过它被称为分布式版本控制。我们只关注“版本控制”这四个字。你的本地仓库是否有远程仓库的任何版本?你需要知道,当你在 GitHub 上创建一个新仓库时,它有一个名为 initial commit 的第一个版本(可能不叫这个),但总之,我想说的是创建伴随着第一次初始化提交,但本地没有。你可能会问,为什么没有,你怎么知道?我们来用 git log 检查一下😜

让我解释一下,这是我为了演示我提到的反例而做的提交。实际上,应该是 git log 后没有任何内容。

解决方案:

只需拉取远程仓库的初始化版本,作为本地的基础版本,这就是版本控制的意义。git pull 是非常直观的

它提示该操作不成功,因为我有一个 test.txt 文件,而本地仓库的第一次提交与远程仓库的初始版本不同,因此提示我有分歧的分支,等等,正如它的提示所说,你可以使用 git pull --rebase lixiang main

你可能不知道这个 --rebase 是做什么的,它实际上是分支合并提交,直接将远程仓库和本地仓库合并,而不管它,生成一个提交。

成功了!让我们用 git log 检查一下……

可以看到远程仓库的 Initial commit 已经与我第一次的本地提交合并,但此时远程和本地仓库并不同步!需要上传到远程仓库。

步骤3:git push

成功了,有一个小问题是分支已经改变。这里的原因是本地初始化的默认分支是 master,而远程仓库的默认分支是 main。但这不是大问题。

修改默认分支的命令

1
git config --global init.defaultBranch <default branch name>

如果你不理解上述过程,也没关系,我把它写得复杂了,实际上应该简单得多,没问题,让我写一个简单版本。

第二种方法的简化

步骤1:创建远程仓库并初始化本地仓库

步骤2:手动建立远程连接

步骤3:拉取(git pull)远程仓库的初始版本

如果你看过我之前的解释,你会发现 --rebase 参数并不需要,因为初始化后我什么都没做,提交记录是空的,空仓库当然在拉取任何东西时不会产生任何分歧。对于空仓库,根本不存在合并的问题!

让我们用 git log 检查一下

正是如此!最后一步!😬

步骤4:创建测试文件后,git push 上传到远程仓库

让我们在 GitHub 上检查一下

总结

我认为我所说的只是冰山一角,逐步教你如何连接本地和远程仓库并提交你想上传的文件。实际上,GitHub 支持直接文件上传,见上图中的 Add File。我学习这个并没有特别的目的,只是觉得很有趣。如果你想更深入地了解,可以参考我之前的 博客文章

顺便提一下,这篇文章基本上都是我自己写的,但我确实阅读了很多其他人的观点,并且自己不断犯错,但这就是学习的过程。我会在这里附上我参考的一些原创文章。

知乎_Git 使用(连接远程仓库)

CSDN_删除远程仓库文件

CSDN_Git 本地文件上传到远程仓库

CSDN_删除 Git 远程仓库文件

仔细看看他们写的内容,可能比我写的更清晰。我的目的仍然是通过我对原理和过程的理解,逐步建立连接。这可以说是我第一篇也有点像教程的博客文章。感谢观看!