Git:如何将[仅源码(zip)]与远端仓库关联

本文最后更新于:2023年12月16日 下午

前情提要

众所周知,大中华区信号不要太好,打不通Github是常态

git clone也是时常error

对于一个大仓库,还不如直接下载源码zip来得快

但是解压之后我们会发现,这个zip里没有.git文件夹,宛如一只离开蜂群的无人机,再也无法回家

没有.git文件夹就意味着没有加入版本控制,就无法与远端Github仓库产生联系,就是裸代码(raw codes),再也无法fetchpush了,哭

辣怎么办

辣就喝牛奶

不管怎么说,总得先创建一个本地git仓库吧

1
$ git init

ok,那么怎么和远端Github仓库产生关联呢

1
$ git remote add origin https://github.com/XXX/XXX.git

酱紫就添加了一个名为origin的远程仓库了

反映在.git\config文件中就是:

1
2
3
[remote "origin"]
url = https://github.com/XXX/XXX.git
fetch = +refs/heads/*:refs/remotes/origin/*

这段表明:

  • 声明了一个远端仓库,名为origin
  • url为:https://github.com/XXX/XXX.git
  • 执行 git fetch 操作时,远程仓库的所有分支会被抓取并强制更新到本地的 origin/* 引用上(简而言之就是用远端更新本地)

By the way

其实一个远程仓库也可以对应两个url(如:同时推送到gitee和github)

1
$ git remote set-url --add origin git@github.com:XXX/XXX.git
1
2
3
4
[remote "origin"]
url = https://gitee.com/XXX/XXX.git
url = git@github.com:XXX/XXX.git #这里用git或http协议都可以
fetch = +refs/heads/*:refs/remotes/origin/*

类似酱,那么问题来了,从哪个url fetch呢

答:默认是第一个url

push时会同时向两个url推送,可以用git remote -v查看

1
$ git remote -v
1
2
3
origin  https://gitee.com/XXX/XXX.git (fetch)
origin https://gitee.com/XXX/XXX.git (push)
origin git@github.com:XXX/XXX.git (push)

Okay back

现在,我们有了一个远程仓库origin,但也仅此而已

1
$ git log
1
$ git branch -a

可以发现什么都没有输出,甚至连一个本地分支都没有(主分支也没有)

啥也没有了属于是,no commit, no branch

那咋整啊,不管了,先fetch一下

1
$ git fetch #默认从origin拉取 因为只有一个仓库
1
2
3
$ git branch -a
remotes/origin/dev
remotes/origin/master

太好了,现在有了几个远程分支,但是仍然没有本地分支(git branch显示当前分支为空)

为什么没有本地分支,也没有当前分支呢?

因为没有commit,HEAD指针就不知道指向谁,也就没有分支了

所以这种情况下,我们其实还是没有和远端产生较好的关联(没有本地分支跟踪远程分支)

同时,由于没有活动分支,也无法进行merge(众所周知,pull = fetch + merge

那么,我们要怎么让本地拥有和远端master一样的commit记录呢?

其实就是检出(checkout)到远程分支嘛

1
2
3
$ git checkout -b master origin/master
# git checkout -b [branch-name] origin/[branch-name]
# 这会创建一个名为 [branch-name] 的新本地分支,该分支跟踪远程的 origin/[branch-name] 分支。

在较新Git版本中,如果本地不存在master分支,也可以简写为:

1
$ git checkout master

Git 会自动创建一个新的本地分支 master 并将其设置为跟踪远程的 master 分支,这在 Git 2.23 及以上版本中更常见

但是显然,无论是哪个命令,checkout都会失败

1
2
3
4
5
6
$ git checkout master 
error: The following untracked working tree files would be overwritten by checkout:
README.md
abc.txt
Please move or remove them before you switch branches.
Aborting

这是因为:工作目录中存在一些未跟踪的文件,这些文件在远程master 分支中也存在,因此Git 阻止了分支切换以避免这些未跟踪文件被覆盖

Solution:

  1. 删除所有未跟踪文件:git clean -f
  2. 暂存:git stash --include-untracked
  3. 提交:git add . & git commit -m "Add untracked files"
  4. 强制切换:git checkout -f master

好的,我们还是强制切换吧

1
2
3
$ git checkout -f master
Switched to a new branch 'master'
branch 'master' set up to track 'origin/master'.

Perfect

现在就跟直接执行git clone之后的仓库一毛一样了

好好好 再提一嘴 跟踪分支是怎么回事

branch ‘master’ set up to track ‘origin/master’.

注意这一句提示,checkout的时候本地master自动跟踪的远程的origin master分支

这个体现在.git\config就是:

1
2
3
[branch "master"]
remote = origin
merge = refs/heads/master

意味着,pull & merge的时候,自动合并origin仓库的master分支,也就是跟踪了远程分支嘛 差不多就酱

方法2

我们刚刚采用的是fetch + checkout -f法,那能不能直接pull

1
2
3
4
5
6
7
8
9
10
$ git pull origin master
...
error: The following untracked working tree files would be overwritten by merge:
README.md
abc.txt
Please move or remove them before you merge.
Aborting

$ git branch -a
remotes/origin/master

好的,显然是不行,但是从这里我们可以清晰地看到pull = fetch + merge

那么原因还是类似,有未跟踪文件存在,且有被覆盖的风险

那么pullmerge有没有类似-f的强制指令呢

答案是没有,因为checkout是切换分支,有覆盖的语义,但是mergepull是合并两个分支,是平等的

所以我们只能手动清理这些文件了

由于这些代码是直接下载的zip,我们也没有修改,所以删了也不心疼,待会儿pull就恢复了,所以直接

1
$ git clean -f

库擦一下,工作区空了 /哭

然后

1
2
3
$ git pull origin master
From https://github.com/Zulaikha12/git-test
* branch master -> FETCH_HEAD
1
2
3
$ git branch -a
* master
remotes/origin/master

直接完美成功,本地也有了master分支

但是聪明的小伙伴可能发现了,本地没有分支怎么能merge

根据GPT-4的说法:Git会自动帮我们checkout一个新分支并跟踪远程分支巴拉,反正就是噼里啪啦就好了

注:实测发现,nonono,并不会自动设置远程跟踪分支,需要手动设置
git branch --set-upstream-to=origin/master master

Tip

如果仓库实在太大,fetchclone其实压力是一样的

(只不过下载zip能让你更快地开始工作,之后再考虑fetch)& 玄学:说不定fetch网络更好

咳咳

其实我们可以只clone最近的几次提交(浅克隆)

1
$ git clone --depth 1 https://github.com/XXX/XXX

如果需要完整的历史记录,可以通过 git fetch --unshallow 将浅克隆的仓库转换为完整的仓库;这个命令会拉取剩余的历史记录。

Peace

Ref

GPT-4

加速几十倍 git clone 速度的 –depth 1,它的后遗症怎么解决? - 知乎 (zhihu.com)

git切换到指定远程分支_git 切换远程分支-CSDN博客


Git:如何将[仅源码(zip)]与远端仓库关联
https://mrbeancpp.github.io/2023/12/15/Git-如何将-仅源码-zip-与远端仓库关联/
作者
MrBeanC
发布于
2023年12月15日
许可协议